Skip to content

Commit 56b3f14

Browse files
committed
Add error when RPK is used with DANE stub
1 parent 00fe73b commit 56b3f14

4 files changed

Lines changed: 72 additions & 10 deletions

File tree

src/internal.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16757,6 +16757,36 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1675716757
if (ssl->peerVerifyRet == 0) /* Return first cert error here */
1675816758
ssl->peerVerifyRet = WOLFSSL_X509_V_OK;
1675916759
#endif
16760+
16761+
#if defined(HAVE_RPK) && (defined(OPENSSL_EXTRA) || \
16762+
defined(OPENSSL_EXTRA_X509_SMALL))
16763+
/* A Raw Public Key cert (RFC 7250) has no issuer and no
16764+
* signature, so ParseCertRelative performed no peer
16765+
* authentication. Unless an out-of-band trust mechanism
16766+
* (DANE, key pinning, etc.) has bound this key, report the
16767+
* peer as unauthenticated through wolfSSL_get_verify_result()
16768+
* rather than leaving it at WOLFSSL_X509_V_OK. The handshake
16769+
* is intentionally not failed here: per RFC 7250 the
16770+
* application is responsible for validating the key out of
16771+
* band. Applies to both peers - client checking the
16772+
* server's RPK and server checking the client's RPK.
16773+
* WOLFSSL_VERIFY_NONE leaves the result untouched. */
16774+
if (args->dCert->isRPK && !ssl->options.verifyNone) {
16775+
int rpkTrusted = 0;
16776+
#if defined(HAVE_DANE)
16777+
if (ssl->options.useDANE) {
16778+
/* DANE authentication should be added; set
16779+
* rpkTrusted = 1 on a successful match. */
16780+
}
16781+
#endif /* HAVE_DANE */
16782+
if (!rpkTrusted &&
16783+
ssl->peerVerifyRet == WOLFSSL_X509_V_OK) {
16784+
ssl->peerVerifyRet = (unsigned long)
16785+
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED;
16786+
}
16787+
}
16788+
#endif /* HAVE_RPK && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
16789+
1676016790
#if defined(SESSION_CERTS) && defined(WOLFSSL_ALT_CERT_CHAINS)
1676116791
/* if using alternate chain, store the cert used */
1676216792
if (ssl->options.usingAltCertChain) {
@@ -16775,17 +16805,10 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1677516805
if (ssl->options.side == WOLFSSL_SERVER_END) {
1677616806
#if defined(HAVE_RPK)
1677716807
if (args->dCert->isRPK) {
16778-
/* to verify Raw Public Key cert, DANE(RFC6698)
16779-
* should be introduced. Without DANE, no
16780-
* authentication is performed.
16781-
*/
16782-
#if defined(HAVE_DANE)
16783-
if (ssl->useDANE) {
16784-
/* DANE authentication should be added */
16785-
}
16786-
#endif /* HAVE_DANE */
16808+
/* RPK certs carry no X.509 version; the RPK trust
16809+
* check above already handled this cert. */
1678716810
}
16788-
else /* skip followingx509 version check */
16811+
else /* skip following x509 version check */
1678916812
#endif /* HAVE_RPK */
1679016813
if (args->dCert->version != WOLFSSL_X509_V3) {
1679116814
WOLFSSL_MSG("Peers certificate was not version 3!");
@@ -27474,6 +27497,9 @@ static const char* wolfSSL_ERR_reason_error_string_OpenSSL(unsigned long e)
2747427497
case WOLFSSL_X509_V_ERR_IP_ADDRESS_MISMATCH:
2747527498
return "IP address mismatch";
2747627499

27500+
case WOLFSSL_X509_V_ERR_RPK_UNTRUSTED:
27501+
return "raw public key not trusted";
27502+
2747727503
default:
2747827504
return NULL;
2747927505
}

tests/api/test_tls13.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,6 +2021,14 @@ int test_tls13_rpk_handshake(void)
20212021
WOLFSSL_SUCCESS);
20222022
ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN);
20232023

2024+
/* x509 handshake: peer cert was verified against a CA, so the verify
2025+
* result stays WOLFSSL_X509_V_OK. This is the contrast case for the
2026+
* RPK checks below. */
2027+
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2028+
ExpectIntEQ(wolfSSL_get_verify_result(ssl_c), WOLFSSL_X509_V_OK);
2029+
ExpectIntEQ(wolfSSL_get_verify_result(ssl_s), WOLFSSL_X509_V_OK);
2030+
#endif
2031+
20242032
(void)typeCnt_c;
20252033
(void)typeCnt_s;
20262034

@@ -2089,6 +2097,19 @@ int test_tls13_rpk_handshake(void)
20892097
WOLFSSL_SUCCESS);
20902098
ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);
20912099

2100+
/* TLS1.3 RPK: an RPK cert (RFC 7250) has no issuer and no signature
2101+
* chain, so no peer authentication was performed. With WOLFSSL_VERIFY_PEER
2102+
* set and no out-of-band trust mechanism, wolfSSL_get_verify_result() must
2103+
* report the peer as unauthenticated rather than WOLFSSL_X509_V_OK. The
2104+
* handshake itself still completes - validating the key is the
2105+
* application's responsibility per RFC 7250. */
2106+
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2107+
ExpectIntEQ(wolfSSL_get_verify_result(ssl_c),
2108+
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED);
2109+
ExpectIntEQ(wolfSSL_get_verify_result(ssl_s),
2110+
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED);
2111+
#endif
2112+
20922113
wolfSSL_free(ssl_c);
20932114
wolfSSL_CTX_free(ctx_c);
20942115
wolfSSL_free(ssl_s);
@@ -2158,6 +2179,15 @@ int test_tls13_rpk_handshake(void)
21582179
WOLFSSL_SUCCESS);
21592180
ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_RPK);
21602181

2182+
/* TLS1.2 RPK: same as the TLS1.3 case above - no chain of trust, so the
2183+
* verify result must report the peer as unauthenticated. */
2184+
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2185+
ExpectIntEQ(wolfSSL_get_verify_result(ssl_c),
2186+
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED);
2187+
ExpectIntEQ(wolfSSL_get_verify_result(ssl_s),
2188+
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED);
2189+
#endif
2190+
21612191
wolfSSL_free(ssl_c);
21622192
wolfSSL_CTX_free(ctx_c);
21632193
wolfSSL_free(ssl_s);

wolfssl/openssl/x509.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@
210210
#define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92
211211
#define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93
212212
#define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94
213+
/* OpenSSL numbers this 91; that slot is already taken in wolfSSL, so the
214+
* RPK-untrusted code is assigned the next free wolfSSL-specific value. */
215+
#define X509_V_ERR_RPK_UNTRUSTED 95
213216
#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
214217
#define X509_R_KEY_VALUES_MISMATCH WC_KEY_MISMATCH_E
215218

wolfssl/ssl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,9 @@ enum {
27082708
WOLFSSL_X509_V_ERR_IP_ADDRESS_MISMATCH = 64,
27092709
WOLFSSL_X509_V_ERR_INVALID_CA = 79,
27102710
WC_OSSL_V509_V_ERR_MAX = 80,
2711+
/* Codes at or above WC_OSSL_V509_V_ERR_MAX are intentionally outside the
2712+
* contiguous range swept by the error-string test in tests/api.c. */
2713+
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED = 95,
27112714

27122715
#ifdef HAVE_OCSP
27132716
/* OCSP Flags */

0 commit comments

Comments
 (0)