mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-10 19:00:51 +02:00
Fixes from review
This commit is contained in:
@@ -122,6 +122,20 @@ PR stands for Pull Request, and PR <NUMBER> references a GitHub pull request num
|
||||
|
||||
* **BREAKING (FIPS 205 SLH-DSA)**: `wc_SlhDsaKey_SignHash`, `wc_SlhDsaKey_SignHashDeterministic`, `wc_SlhDsaKey_SignHashWithRandom`, and `wc_SlhDsaKey_VerifyHash` now take the **caller-pre-hashed message digest** via `hash`/`hashSz` parameters (renamed from `msg`/`msgSz`), aligned with ML-DSA's `wc_dilithium_sign_ctx_hash` / `wc_dilithium_verify_ctx_hash` semantics, and NIST ACVP `signatureInterface=external` / `preHash=preHash` test vectors. `hashSz` must equal `wc_HashGetDigestSize(hashType)` (32 bytes for SHAKE128, 64 bytes for SHAKE256 per FIPS 205 Section 10.2.2); otherwise `BAD_LENGTH_E` is returned. Migration: hash the message yourself before the call (callers using positional arguments are source-compatible; only the parameter names changed). Caveat: callers who today pass a raw message whose length happens to equal the digest size for the chosen `hashType` (e.g., signing a 32-byte handle/IV/seed with `WC_HASH_TYPE_SHA256`) will not trip `BAD_LENGTH_E`; the resulting signature is syntactically valid but is over the wrong bytes. The pre-existing `wc_SlhDsaKey_SignMsgDeterministic` and `wc_SlhDsaKey_SignMsgWithRandom` retain their M'-supplied-directly contract (FIPS 205 internal interface, Algorithm 19); their input validation is hardened with the same NULL/length/`MISSING_KEY` checks as the `*Hash*` family. `wc_SlhDsaKey_VerifyMsg` is unchanged. All three gain doxygen coverage. (PR 10450, PR 10465)
|
||||
|
||||
* **Behavioral change (Raw Public Key fail-closed)**: With `HAVE_RPK`, a peer
|
||||
that presents a Raw Public Key (RFC 7250) is no longer silently accepted while
|
||||
it is being authenticated. Previously an RPK handshake always completed and
|
||||
the application validated the key out of band afterward (e.g. via
|
||||
`wolfSSL_get_verify_result()`); it now fails closed (with `RPK_UNTRUSTED_E`,
|
||||
reported as `WOLFSSL_X509_V_ERR_RPK_UNTRUSTED`) whenever the peer is being
|
||||
authenticated, i.e. any verify mode other than `WOLFSSL_VERIFY_NONE`. This
|
||||
applies to all `HAVE_RPK` builds, including those without `OPENSSL_EXTRA` (no
|
||||
prior untrusted-RPK handling) and `NO_SHA256` builds (no in-library pinning).
|
||||
To establish trust, pin the expected key with the new
|
||||
`wolfSSL_set_expected_rpk()` / `wolfSSL_CTX_set_expected_rpk()` APIs
|
||||
(requires SHA-256), install a verify callback that accepts the key, or set
|
||||
`WOLFSSL_VERIFY_NONE` to accept without authentication.
|
||||
|
||||
* **Behavioral change (RSA-PSS trailerField enforcement)**: `DecodeRsaPssParams`
|
||||
(and its public wrapper `wc_DecodeRsaPssParams`) now enforces RFC 8017 A.2.3,
|
||||
which mandates `trailerField == trailerFieldBC(1)`. In the default build
|
||||
|
||||
@@ -16104,7 +16104,8 @@ int wolfSSL_get_negotiated_server_cert_type(WOLFSSL* ssl, int* tp);
|
||||
the handshake fails closed unless the presented key matches a pin (or a verify
|
||||
callback accepts it). May be called more than once to pin several keys, up to
|
||||
WOLFSSL_MAX_RPK_PINS. The key is stored as its SHA-256 digest, so this API
|
||||
requires SHA-256. Pins are append-only for the lifetime of the CTX.
|
||||
requires SHA-256. Pins are append-only - there is no per-entry remove, but
|
||||
wolfSSL_CTX_clear_expected_rpk() empties the table so it can be repopulated.
|
||||
|
||||
\return WOLFSSL_SUCCESS on success
|
||||
\return BAD_FUNC_ARG if ctx or spki is NULL, or spkiSz is 0
|
||||
@@ -16118,13 +16119,14 @@ int wolfSSL_get_negotiated_server_cert_type(WOLFSSL* ssl, int* tp);
|
||||
\code
|
||||
int ret;
|
||||
WOLFSSL_CTX* ctx;
|
||||
const unsigned char* spki; /* DER SubjectPublicKeyInfo */
|
||||
const unsigned char* spki;
|
||||
unsigned int spkiSz;
|
||||
...
|
||||
|
||||
ret = wolfSSL_CTX_set_expected_rpk(ctx, spki, spkiSz);
|
||||
\endcode
|
||||
\sa wolfSSL_set_expected_rpk
|
||||
\sa wolfSSL_CTX_clear_expected_rpk
|
||||
\sa wolfSSL_set_client_cert_type
|
||||
\sa wolfSSL_set_server_cert_type
|
||||
*/
|
||||
@@ -16140,7 +16142,8 @@ int wolfSSL_CTX_set_expected_rpk(WOLFSSL_CTX* ctx, const unsigned char* spki,
|
||||
the handshake fails closed unless the presented key matches a pin (or a verify
|
||||
callback accepts it). May be called more than once to pin several keys, up to
|
||||
WOLFSSL_MAX_RPK_PINS. The key is stored as its SHA-256 digest, so this API
|
||||
requires SHA-256. Pins are append-only for the lifetime of the object.
|
||||
requires SHA-256. Pins are append-only - there is no per-entry remove, but
|
||||
wolfSSL_clear_expected_rpk() empties the table so it can be repopulated.
|
||||
|
||||
\return WOLFSSL_SUCCESS on success
|
||||
\return BAD_FUNC_ARG if ssl or spki is NULL, or spkiSz is 0
|
||||
@@ -16154,19 +16157,67 @@ int wolfSSL_CTX_set_expected_rpk(WOLFSSL_CTX* ctx, const unsigned char* spki,
|
||||
\code
|
||||
int ret;
|
||||
WOLFSSL* ssl;
|
||||
const unsigned char* spki; /* DER SubjectPublicKeyInfo */
|
||||
const unsigned char* spki;
|
||||
unsigned int spkiSz;
|
||||
...
|
||||
|
||||
ret = wolfSSL_set_expected_rpk(ssl, spki, spkiSz);
|
||||
\endcode
|
||||
\sa wolfSSL_CTX_set_expected_rpk
|
||||
\sa wolfSSL_clear_expected_rpk
|
||||
\sa wolfSSL_set_client_cert_type
|
||||
\sa wolfSSL_set_server_cert_type
|
||||
*/
|
||||
int wolfSSL_set_expected_rpk(WOLFSSL* ssl, const unsigned char* spki,
|
||||
unsigned int spkiSz);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
\brief Remove all pinned expected peer Raw Public Keys (RFC 7250) from the
|
||||
WOLFSSL_CTX object, emptying the table so it can be repopulated - for example
|
||||
across a peer key rotation, since the pinning APIs are otherwise append-only.
|
||||
Like other WOLFSSL_CTX setters this is not locked, so reconfigure the pins on a
|
||||
shared CTX while no handshakes are in flight (a WOLFSSL created with
|
||||
wolfSSL_new() copies the pin table by value at creation time).
|
||||
|
||||
\return WOLFSSL_SUCCESS on success
|
||||
\return BAD_FUNC_ARG if ctx is NULL
|
||||
|
||||
\param ctx WOLFSSL_CTX object pointer
|
||||
_Example_
|
||||
\code
|
||||
WOLFSSL_CTX* ctx;
|
||||
...
|
||||
|
||||
wolfSSL_CTX_clear_expected_rpk(ctx);
|
||||
\endcode
|
||||
\sa wolfSSL_CTX_set_expected_rpk
|
||||
\sa wolfSSL_clear_expected_rpk
|
||||
*/
|
||||
int wolfSSL_CTX_clear_expected_rpk(WOLFSSL_CTX* ctx);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
\brief Remove all pinned expected peer Raw Public Keys (RFC 7250) from the
|
||||
WOLFSSL object, emptying the table so it can be repopulated - for example
|
||||
across a peer key rotation, since the pinning APIs are otherwise append-only.
|
||||
|
||||
\return WOLFSSL_SUCCESS on success
|
||||
\return BAD_FUNC_ARG if ssl is NULL
|
||||
|
||||
\param ssl WOLFSSL object pointer
|
||||
_Example_
|
||||
\code
|
||||
WOLFSSL* ssl;
|
||||
...
|
||||
|
||||
wolfSSL_clear_expected_rpk(ssl);
|
||||
\endcode
|
||||
\sa wolfSSL_set_expected_rpk
|
||||
\sa wolfSSL_CTX_clear_expected_rpk
|
||||
*/
|
||||
int wolfSSL_clear_expected_rpk(WOLFSSL* ssl);
|
||||
|
||||
/*!
|
||||
|
||||
\brief Enable use of ConnectionID extensions for the SSL object. See RFC 9146
|
||||
|
||||
+16
-10
@@ -15216,6 +15216,7 @@ void DoCertFatalAlert(WOLFSSL* ssl, int ret)
|
||||
alertWhy = certificate_expired;
|
||||
}
|
||||
else if (ret == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E) ||
|
||||
ret == WC_NO_ERR_TRACE(RPK_UNTRUSTED_E) ||
|
||||
ret == WC_NO_ERR_TRACE(ASN_PATHLEN_INV_E) ||
|
||||
ret == WC_NO_ERR_TRACE(ASN_PATHLEN_SIZE_E)) {
|
||||
alertWhy = unknown_ca;
|
||||
@@ -17815,16 +17816,18 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
if (!rpkTrusted && !ssl->options.verifyNone) {
|
||||
WOLFSSL_MSG("Untrusted RPK and peer verification "
|
||||
"is on; failing handshake");
|
||||
/* ASN_NO_SIGNER_E ("no trusted signer/anchor") is
|
||||
* the closest existing error for an unpinned RPK.
|
||||
* It is set here in the parse-SUCCESS branch, so the
|
||||
* X.509 recovery that keys on this code (alternate
|
||||
* chains, CA hash-dir lookup, Apple native
|
||||
* validation) - all of which live in the
|
||||
* parse-FAILURE branch above - is not reachable for
|
||||
* RPK. The leaf verify callback is still invoked at
|
||||
* TLS_ASYNC_FINALIZE and may override. */
|
||||
ret = ASN_NO_SIGNER_E;
|
||||
/* Use a dedicated RPK error rather than an
|
||||
* X.509 one (e.g. ASN_NO_SIGNER_E) so the failure is
|
||||
* distinguishable: GetX509Error() maps it to
|
||||
* WOLFSSL_X509_V_ERR_RPK_UNTRUSTED, so a verify
|
||||
* callback that accepts X.509 issuer-lookup errors
|
||||
* (ASN_NO_SIGNER_E /
|
||||
* WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
|
||||
* cannot accidentally accept an unauthenticated RPK.
|
||||
* The leaf verify callback is still invoked at
|
||||
* TLS_ASYNC_FINALIZE and may deliberately override
|
||||
* this RPK-specific code. */
|
||||
ret = RPK_UNTRUSTED_E;
|
||||
WOLFSSL_ERROR_VERBOSE(ret);
|
||||
}
|
||||
}
|
||||
@@ -29023,6 +29026,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
||||
|
||||
case SEQUENCE_NUMBER_E:
|
||||
return "Record sequence number would wrap";
|
||||
|
||||
case RPK_UNTRUSTED_E:
|
||||
return "RFC 7250 Raw Public Key not trusted";
|
||||
}
|
||||
|
||||
return "unknown error number";
|
||||
|
||||
@@ -505,6 +505,38 @@ int wolfSSL_set_expected_rpk(WOLFSSL* ssl, const unsigned char* spki,
|
||||
ret = rpk_add_expected(&ssl->options.rpkConfig, spki, spkiSz);
|
||||
return (ret == 0) ? WOLFSSL_SUCCESS : ret;
|
||||
}
|
||||
|
||||
/* Remove all pinned expected peer Raw Public Keys from the SSL/TLS CTX object,
|
||||
* so the table can be repopulated (e.g. across a peer key rotation).
|
||||
*
|
||||
* @param [in] ctx SSL/TLS CTX object.
|
||||
* @return WOLFSSL_SUCCESS on success.
|
||||
* @return BAD_FUNC_ARG when ctx is NULL.
|
||||
*/
|
||||
int wolfSSL_CTX_clear_expected_rpk(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ctx->rpkConfig.expectedRpkCnt = 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Remove all pinned expected peer Raw Public Keys from the SSL/TLS object, so
|
||||
* the table can be repopulated (e.g. across a peer key rotation).
|
||||
*
|
||||
* @param [in] ssl SSL/TLS object.
|
||||
* @return WOLFSSL_SUCCESS on success.
|
||||
* @return BAD_FUNC_ARG when ssl is NULL.
|
||||
*/
|
||||
int wolfSSL_clear_expected_rpk(WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ssl->options.rpkConfig.expectedRpkCnt = 0;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif /* !NO_SHA256 */
|
||||
#endif /* HAVE_RPK */
|
||||
|
||||
|
||||
@@ -282,6 +282,12 @@ int GetX509Error(int e)
|
||||
case WC_NO_ERR_TRACE(ASN_NO_SIGNER_E):
|
||||
/* get issuer error if no CA found locally */
|
||||
return WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
|
||||
case WC_NO_ERR_TRACE(RPK_UNTRUSTED_E):
|
||||
/* RFC 7250 Raw Public Key not trusted out of band. Distinct from
|
||||
* the X.509 issuer-lookup error above so verify callbacks that
|
||||
* accept ASN_NO_SIGNER_E / UNABLE_TO_GET_ISSUER_CERT_LOCALLY do not
|
||||
* accidentally accept an unauthenticated RPK. */
|
||||
return WOLFSSL_X509_V_ERR_RPK_UNTRUSTED;
|
||||
case WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E):
|
||||
return WOLFSSL_X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
|
||||
case WC_NO_ERR_TRACE(ASN_PATHLEN_INV_E):
|
||||
|
||||
+6
-1
@@ -28912,7 +28912,12 @@ static int error_test(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
/* Guard matches the compilation condition of the OpenSSL-style reason
|
||||
* strings (wolfSSL_ERR_reason_error_string_OpenSSL), so the RPK string is
|
||||
* exercised in OPENSSL_EXTRA_X509_SMALL / webserver / memcached builds too,
|
||||
* not only OPENSSL_EXTRA. */
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
|
||||
/* WOLFSSL_X509_V_ERR_RPK_UNTRUSTED is >= WC_OSSL_V509_V_ERR_MAX, so it is
|
||||
* intentionally outside the contiguous sweep above. Check its reason string
|
||||
* explicitly so it cannot regress silently. error_test() is invoked as
|
||||
|
||||
@@ -3703,6 +3703,27 @@ static int test_rpk_accept_cb(int preverify, WOLFSSL_X509_STORE_CTX* store)
|
||||
(void)store;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mimics a real-world X.509 verify callback that accepts ONLY the "issuer not
|
||||
* found locally" errors (the pattern used elsewhere to allow an unchained or
|
||||
* self-signed leaf). It must NOT rescue an untrusted RPK: because the RPK
|
||||
* failure now reports WOLFSSL_X509_V_ERR_RPK_UNTRUSTED (not the X.509
|
||||
* issuer-lookup codes), these checks no longer match and the RPK stays rejected.
|
||||
* Returns 1 (accept) only for the X.509 issuer codes, otherwise rejects. */
|
||||
static int test_rpk_x509_issuer_accept_cb(int preverify,
|
||||
WOLFSSL_X509_STORE_CTX* store)
|
||||
{
|
||||
(void)preverify;
|
||||
if ((store->error == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E))
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
|| (store->error ==
|
||||
WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
|
||||
#endif
|
||||
) {
|
||||
return 1; /* would wrongly accept an RPK that reused these codes */
|
||||
}
|
||||
return 0; /* reject everything else, including WOLFSSL_X509_V_ERR_RPK_* */
|
||||
}
|
||||
#endif /* HAVE_RPK && WOLFSSL_TLS13 && client && server && !NO_SHA256 */
|
||||
|
||||
#if defined(HAVE_RPK) && \
|
||||
@@ -3926,6 +3947,31 @@ int test_tls13_rpk_trust(void)
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
|
||||
/* --- a callback that accepts only X.509 issuer-lookup errors must NOT
|
||||
* rescue an untrusted RPK: the RPK failure reports its own error code, so
|
||||
* the callback's X.509 checks do not match and the handshake fails closed.
|
||||
* (Would complete if the RPK reused ASN_NO_SIGNER_E / the issuer-lookup
|
||||
* verify-result code.) --- */
|
||||
ctx_c = ctx_s = NULL;
|
||||
ssl_c = ssl_s = NULL;
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_rpk_nopin_setup(&test_ctx, &ctx_c, &ctx_s,
|
||||
&ssl_c, &ssl_s, wolfTLSv1_3_client_method,
|
||||
wolfTLSv1_3_server_method), 0);
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_PEER,
|
||||
test_rpk_x509_issuer_accept_cb);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_PEER,
|
||||
test_rpk_x509_issuer_accept_cb);
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
ExpectIntEQ(wolfSSL_get_verify_result(ssl_c),
|
||||
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED);
|
||||
#endif
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
|
||||
/* --- SSL-level pin via wolfSSL_set_expected_rpk() -> V_OK --- */
|
||||
ctx_c = ctx_s = NULL;
|
||||
ssl_c = ssl_s = NULL;
|
||||
@@ -3995,9 +4041,37 @@ int test_tls13_rpk_trust(void)
|
||||
}
|
||||
ExpectIntEQ(wolfSSL_set_expected_rpk(ssl_c, svrSpki,
|
||||
(unsigned int)svrSpkiSz), WC_NO_ERR_TRACE(BUFFER_E));
|
||||
/* clear empties the (full) table so an add succeeds again */
|
||||
ExpectIntEQ(wolfSSL_clear_expected_rpk(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_clear_expected_rpk(ssl_c), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_expected_rpk(ssl_c, svrSpki,
|
||||
(unsigned int)svrSpkiSz), WOLFSSL_SUCCESS);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
|
||||
/* same argument/capacity errors for the CTX-level wrapper */
|
||||
ctx_c = NULL;
|
||||
ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||
ExpectIntEQ(wolfSSL_CTX_set_expected_rpk(NULL, svrSpki,
|
||||
(unsigned int)svrSpkiSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_CTX_set_expected_rpk(ctx_c, NULL,
|
||||
(unsigned int)svrSpkiSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_CTX_set_expected_rpk(ctx_c, svrSpki, 0),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
for (i = 0; i < WOLFSSL_MAX_RPK_PINS; i++) {
|
||||
ExpectIntEQ(wolfSSL_CTX_set_expected_rpk(ctx_c, svrSpki,
|
||||
(unsigned int)svrSpkiSz), WOLFSSL_SUCCESS);
|
||||
}
|
||||
ExpectIntEQ(wolfSSL_CTX_set_expected_rpk(ctx_c, svrSpki,
|
||||
(unsigned int)svrSpkiSz), WC_NO_ERR_TRACE(BUFFER_E));
|
||||
/* clear empties the (full) table so an add succeeds again */
|
||||
ExpectIntEQ(wolfSSL_CTX_clear_expected_rpk(NULL),
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_CTX_clear_expected_rpk(ctx_c), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_set_expected_rpk(ctx_c, svrSpki,
|
||||
(unsigned int)svrSpkiSz), WOLFSSL_SUCCESS);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
|
||||
XFREE(svrSpki, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cliSpki, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif /* HAVE_RPK && WOLFSSL_TLS13 && client && server && !NO_SHA256 */
|
||||
|
||||
+4
-1
@@ -247,7 +247,10 @@ enum wolfSSL_ErrorCodes {
|
||||
|
||||
SEQUENCE_NUMBER_E = -520, /* Record sequence number would wrap */
|
||||
|
||||
WOLFSSL_LAST_E = -520
|
||||
RPK_UNTRUSTED_E = -521, /* RFC 7250 Raw Public Key not trusted
|
||||
* out of band */
|
||||
|
||||
WOLFSSL_LAST_E = -521
|
||||
|
||||
/* codes -1000 to -1999 are reserved for wolfCrypt. */
|
||||
};
|
||||
|
||||
@@ -210,9 +210,8 @@
|
||||
#define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92
|
||||
#define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93
|
||||
#define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94
|
||||
/* wolfSSL-specific value: this header's numbering already diverges from
|
||||
* OpenSSL's for the higher X509_V_ERR_* codes, so RPK-untrusted takes the next
|
||||
* free wolfSSL slot (95) rather than any particular OpenSSL number. */
|
||||
/* 95 matches OpenSSL's X509_V_ERR_RPK_UNTRUSTED (OpenSSL 3.2+) for source
|
||||
* compatibility. */
|
||||
#define X509_V_ERR_RPK_UNTRUSTED 95
|
||||
#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
|
||||
#define X509_R_KEY_VALUES_MISMATCH WC_KEY_MISMATCH_E
|
||||
|
||||
+14
-6
@@ -2782,9 +2782,9 @@ enum {
|
||||
WOLFSSL_X509_V_ERR_IP_ADDRESS_MISMATCH = 64,
|
||||
WOLFSSL_X509_V_ERR_INVALID_CA = 79,
|
||||
WC_OSSL_V509_V_ERR_MAX = 80,
|
||||
/* wolfSSL-specific verify-result codes are assigned at or above
|
||||
* WC_OSSL_V509_V_ERR_MAX, intentionally outside the contiguous
|
||||
* OpenSSL-compatible range below it. */
|
||||
/* 95 matches OpenSSL's X509_V_ERR_RPK_UNTRUSTED (OpenSSL 3.2+). It is
|
||||
* deliberately at or above WC_OSSL_V509_V_ERR_MAX, i.e. outside the
|
||||
* contiguous block of verify-result codes below it. */
|
||||
WOLFSSL_X509_V_ERR_RPK_UNTRUSTED = 95,
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
@@ -6258,15 +6258,23 @@ WOLFSSL_API int wolfSSL_get_negotiated_server_cert_type(WOLFSSL* ssl, int* tp);
|
||||
* stored as its SHA-256 digest, so these APIs require SHA-256; without it,
|
||||
* express RPK trust through a verify callback. Returns WOLFSSL_SUCCESS, or a
|
||||
* negative error code (BAD_FUNC_ARG for a NULL argument or zero length, BUFFER_E
|
||||
* when the pin table is full). Pins are append-only for the lifetime of the
|
||||
* object/CTX; there is no clear/replace call, so a long-lived CTX that re-pins
|
||||
* across key rotations can exhaust the WOLFSSL_MAX_RPK_PINS-entry table. */
|
||||
* when the pin table is full). Pins are append-only: there is no per-entry
|
||||
* remove, but wolfSSL_clear_expected_rpk()/wolfSSL_CTX_clear_expected_rpk()
|
||||
* empties the WOLFSSL_MAX_RPK_PINS-entry table so it can be repopulated (e.g.
|
||||
* across a peer key rotation). */
|
||||
WOLFSSL_API int wolfSSL_CTX_set_expected_rpk(WOLFSSL_CTX* ctx,
|
||||
const unsigned char* spki,
|
||||
unsigned int spkiSz);
|
||||
WOLFSSL_API int wolfSSL_set_expected_rpk(WOLFSSL* ssl,
|
||||
const unsigned char* spki,
|
||||
unsigned int spkiSz);
|
||||
/* Remove all pinned expected peer Raw Public Keys, emptying the table so it can
|
||||
* be repopulated. Returns WOLFSSL_SUCCESS, or BAD_FUNC_ARG when the handle is
|
||||
* NULL. Like the set calls and other CTX setters these are unlocked, so
|
||||
* reconfigure pins on a shared CTX while no handshakes are in flight (each
|
||||
* WOLFSSL copies the pin table by value at wolfSSL_new()). */
|
||||
WOLFSSL_API int wolfSSL_CTX_clear_expected_rpk(WOLFSSL_CTX* ctx);
|
||||
WOLFSSL_API int wolfSSL_clear_expected_rpk(WOLFSSL* ssl);
|
||||
#endif /* !NO_SHA256 */
|
||||
#endif /* HAVE_RPK */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user