mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 03:30:49 +02:00
Merge pull request #10745 from Frauschi/mandatory_psk
Enable support for mandatory PSKs
This commit is contained in:
@@ -14134,6 +14134,80 @@ int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx);
|
||||
*/
|
||||
int wolfSSL_no_dhe_psk(WOLFSSL* ssl);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
\brief This function is called on a TLS v1.3 / DTLS v1.3 context to require
|
||||
that an external Pre-Shared Key is negotiated for the handshake to succeed.
|
||||
When set, a handshake that completes without negotiating an external PSK is
|
||||
aborted with PSK_MISSING_ERROR instead of falling back to a certificate
|
||||
handshake, so the PSK acts as an additional security factor. The requirement
|
||||
keys off the external-PSK callback (it has no effect unless one is
|
||||
registered) and session-ticket resumption is exempt. To preserve forward
|
||||
secrecy a mandatory external PSK must also use an (EC)DHE key exchange; a
|
||||
pure psk_ke handshake is rejected with PSK_KEY_ERROR. This applies to TLS 1.3
|
||||
and DTLS 1.3 only; in (D)TLS 1.2 the use of a PSK is determined by the
|
||||
negotiated cipher suite, so a mandatory PSK is instead configured by
|
||||
restricting the cipher suite list to (preferably (EC)DHE-)PSK suites.
|
||||
|
||||
\warning Because the requirement can only be enforced for (D)TLS 1.3, this
|
||||
function also disables version downgrade on the context so it cannot
|
||||
silently fall back to (D)TLS 1.2 and complete a handshake without a PSK. A
|
||||
peer that does not support (D)TLS 1.3 will therefore fail to connect.
|
||||
|
||||
\note In builds compiled without external-PSK and without session-ticket
|
||||
support (NO_PSK defined and HAVE_SESSION_TICKET undefined) the requirement
|
||||
cannot be enforced; the function still returns 0 but has no effect.
|
||||
|
||||
\param [in,out] ctx a pointer to a WOLFSSL_CTX structure, created using
|
||||
wolfSSL_CTX_new().
|
||||
|
||||
\return BAD_FUNC_ARG if ctx is NULL or not at least TLS v1.3.
|
||||
\return 0 if successful.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret;
|
||||
WOLFSSL_CTX* ctx;
|
||||
...
|
||||
ret = wolfSSL_CTX_require_psk(ctx);
|
||||
if (ret != 0) {
|
||||
// failed to make a PSK mandatory
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_require_psk
|
||||
*/
|
||||
int wolfSSL_CTX_require_psk(WOLFSSL_CTX* ctx);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
\brief This function is called on a TLS v1.3 / DTLS v1.3 wolfSSL object to
|
||||
require that an external Pre-Shared Key is negotiated for the handshake to
|
||||
succeed. See wolfSSL_CTX_require_psk() for the full behaviour.
|
||||
|
||||
\param [in,out] ssl a pointer to a WOLFSSL structure, created using
|
||||
wolfSSL_new().
|
||||
|
||||
\return BAD_FUNC_ARG if ssl is NULL or not at least TLS v1.3.
|
||||
\return 0 if successful.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
int ret;
|
||||
WOLFSSL* ssl;
|
||||
...
|
||||
ret = wolfSSL_require_psk(ssl);
|
||||
if (ret != 0) {
|
||||
// failed to make a PSK mandatory
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_CTX_require_psk
|
||||
*/
|
||||
int wolfSSL_require_psk(WOLFSSL* ssl);
|
||||
|
||||
/*!
|
||||
\ingroup IO
|
||||
|
||||
|
||||
@@ -7279,6 +7279,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
ssl->options.verifyNone = ctx->verifyNone;
|
||||
ssl->options.failNoCert = ctx->failNoCert;
|
||||
ssl->options.failNoCertxPSK = ctx->failNoCertxPSK;
|
||||
ssl->options.failNoPSK = ctx->failNoPSK;
|
||||
ssl->options.sendVerify = ctx->sendVerify;
|
||||
|
||||
ssl->options.partialWrite = ctx->partialWrite;
|
||||
@@ -27969,6 +27970,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
||||
case DUPE_ENTRY_E:
|
||||
return "duplicate entry error";
|
||||
|
||||
case PSK_MISSING_ERROR:
|
||||
return "psk missing error";
|
||||
|
||||
case GETTIME_ERROR:
|
||||
return "gettimeofday() error";
|
||||
|
||||
@@ -36224,6 +36228,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return missing_extension;
|
||||
case WC_NO_ERR_TRACE(MATCH_SUITE_ERROR):
|
||||
case WC_NO_ERR_TRACE(MISSING_HANDSHAKE_DATA):
|
||||
case WC_NO_ERR_TRACE(PSK_MISSING_ERROR):
|
||||
return handshake_failure;
|
||||
case WC_NO_ERR_TRACE(VERSION_ERROR):
|
||||
return wolfssl_alert_protocol_version;
|
||||
|
||||
+105
-2
@@ -4386,7 +4386,11 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
}
|
||||
else if (ssl->options.onlyPskDheKe) {
|
||||
else if (ssl->options.onlyPskDheKe ||
|
||||
(ssl->options.failNoPSK && !psk->resumption)) {
|
||||
/* A mandatory external PSK (failNoPSK) must be combined with
|
||||
* (EC)DHE for forward secrecy, so reject a pure psk_ke
|
||||
* negotiation. Session-ticket resumption is exempt. */
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
@@ -5925,6 +5929,18 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
while (psk != NULL && !psk->chosen)
|
||||
psk = psk->next;
|
||||
if (psk == NULL) {
|
||||
/* A mandatory PSK is satisfied by any PSK the server chose,
|
||||
* including a resumption PSK - this matches the server-side
|
||||
* failNoPSK semantics, where a negotiated PSK (external or
|
||||
* resumption) is accepted. The error only fires when no PSK was
|
||||
* chosen at all. havePSK is only set by an external-PSK callback,
|
||||
* so a peer relying solely on session-ticket resumption is
|
||||
* unaffected. */
|
||||
if (ssl->options.havePSK && ssl->options.failNoPSK) {
|
||||
WOLFSSL_MSG("Server did not negotiate a mandatory PSK");
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_MISSING_ERROR);
|
||||
return PSK_MISSING_ERROR;
|
||||
}
|
||||
ssl->options.resuming = 0;
|
||||
ssl->arrays->psk_keySz = 0;
|
||||
XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
|
||||
@@ -6688,6 +6704,16 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
#endif
|
||||
if (usingPSK)
|
||||
*usingPSK = 0;
|
||||
|
||||
/* No PSK extension at all: if a mandatory external PSK is configured,
|
||||
* refuse the connection rather than continue without one. havePSK is
|
||||
* only set by an external-PSK callback, so a peer relying solely on
|
||||
* session-ticket resumption is unaffected. */
|
||||
if (ssl->options.havePSK && ssl->options.failNoPSK) {
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_MISSING_ERROR);
|
||||
return PSK_MISSING_ERROR;
|
||||
}
|
||||
|
||||
/* Hash data up to binders for deriving binders in PSK extension. */
|
||||
ret = HashInput(ssl, input, (int)helloSz);
|
||||
return ret;
|
||||
@@ -6749,6 +6775,16 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
#endif
|
||||
|
||||
if (!*usingPSK) {
|
||||
/* No suitable PSK was negotiated. When a mandatory external PSK is
|
||||
* configured, fail with a dedicated error instead of falling back to a
|
||||
* certificate handshake. This must run before the no-certificate
|
||||
* BAD_BINDER check below so a PSK-only server (no cert) still reports
|
||||
* PSK_MISSING_ERROR. havePSK is only set by an external-PSK callback, so
|
||||
* a peer relying solely on session-ticket resumption is unaffected. */
|
||||
if (ssl->options.havePSK && ssl->options.failNoPSK) {
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_MISSING_ERROR);
|
||||
return PSK_MISSING_ERROR;
|
||||
}
|
||||
#ifndef NO_CERTS
|
||||
if (ssl->buffers.certificate == NULL
|
||||
#ifdef WOLFSSL_CERT_SETUP_CB
|
||||
@@ -6910,7 +6946,11 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
ssl->namedGroup = ssl->session->namedGroup;
|
||||
*usingPSK = 2; /* generate new ephemeral key */
|
||||
}
|
||||
else if (ssl->options.onlyPskDheKe) {
|
||||
else if (ssl->options.onlyPskDheKe ||
|
||||
(ssl->options.failNoPSK && !ssl->options.resuming)) {
|
||||
/* A mandatory external PSK (failNoPSK) must be combined with
|
||||
* (EC)DHE for forward secrecy, so reject a pure psk_ke
|
||||
* negotiation. Session-ticket resumption is exempt. */
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
else
|
||||
@@ -6929,6 +6969,8 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
/* If no PSK is found, we remove the extension to make sure it
|
||||
* is not sent back to the client */
|
||||
TLSX_Remove(&ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK, ssl->heap);
|
||||
ssl->options.certWithExternPsk = 0;
|
||||
#endif
|
||||
@@ -11874,6 +11916,21 @@ int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(NO_CERTS) && !defined(NO_PSK) && \
|
||||
defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
/* Verify the server sent a certificate if requested */
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.pskNegotiated &&
|
||||
ssl->options.failNoCert) {
|
||||
if ((TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) != NULL) &&
|
||||
(!ssl->options.havePeerCert || !ssl->options.havePeerVerify)) {
|
||||
ret = NO_PEER_CERT;
|
||||
WOLFSSL_MSG("TLS v1.3 server did not present peer cert");
|
||||
DoCertFatalAlert(ssl, ret);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check against totalSz */
|
||||
if (*inOutIdx + size > totalSz) {
|
||||
ret = BUFFER_E;
|
||||
@@ -14981,6 +15038,52 @@ int wolfSSL_only_dhe_psk(WOLFSSL* ssl)
|
||||
}
|
||||
#endif /* HAVE_SUPPORTED_CURVES */
|
||||
|
||||
/* Require that an external Pre-Shared Key is negotiated for the handshake to
|
||||
* succeed. TLS 1.3 / DTLS 1.3 only - in (D)TLS 1.2 the use of a PSK is
|
||||
* determined by the negotiated cipher suite, so a mandatory PSK is configured
|
||||
* there by restricting the cipher suite list to PSK suites.
|
||||
*
|
||||
* ctx The SSL/TLS CTX object.
|
||||
* returns BAD_FUNC_ARG when ctx is NULL or not at least TLS v1.3, 0 on success.
|
||||
*/
|
||||
int wolfSSL_CTX_require_psk(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
ctx->failNoPSK = 1;
|
||||
/* The requirement can only be enforced for (D)TLS 1.3, so keep it
|
||||
* fail-closed by disabling a version downgrade. Otherwise a
|
||||
* downgrade-capable context (e.g. from a v23 method) could silently fall
|
||||
* back to (D)TLS 1.2 and complete without any PSK. */
|
||||
ctx->method->downgrade = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Require that an external Pre-Shared Key is negotiated for the handshake to
|
||||
* succeed. See wolfSSL_CTX_require_psk().
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* returns BAD_FUNC_ARG when ssl is NULL or not at least TLS v1.3, 0 on success.
|
||||
*/
|
||||
int wolfSSL_require_psk(WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
ssl->options.failNoPSK = 1;
|
||||
/* See wolfSSL_CTX_require_psk() - keep the requirement fail-closed by
|
||||
* disabling a version downgrade to (D)TLS 1.2. */
|
||||
ssl->options.downgrade = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Tls13UpdateKeys(WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
|
||||
|
||||
+1
-1
@@ -28486,7 +28486,7 @@ static int error_test(void)
|
||||
#endif
|
||||
{ -9, WC_SPAN1_FIRST_E + 1 },
|
||||
{ -300, -300 },
|
||||
{ -335, -336 },
|
||||
{ -336, -336 },
|
||||
{ -346, -349 },
|
||||
{ -356, -356 },
|
||||
{ -358, -358 },
|
||||
|
||||
+746
-8
@@ -1038,6 +1038,49 @@ int test_tls13_cert_with_extern_psk_handshake(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_cert_with_extern_psk_client_requires_cert(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && !defined(NO_CERTS) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
/* The client requests cert_with_extern_psk and mandates a peer certificate
|
||||
* (WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT). The server negotiates the external
|
||||
* PSK but does NOT enable cert_with_extern_psk, so it completes a PSK-only
|
||||
* handshake without sending a Certificate/CertificateVerify. The client
|
||||
* must therefore reject in DoTls13Finished with NO_PEER_CERT instead of
|
||||
* accepting a PSK-only handshake. */
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_cwep_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_cwep_server_cb);
|
||||
/* Only the client requests cert_with_extern_psk. */
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_c, 1), WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(NO_PEER_CERT));
|
||||
ExpectIntEQ(ssl_c->options.pskNegotiated, 1);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_cert_with_extern_psk_requires_key_share(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@@ -1135,15 +1178,19 @@ int test_tls13_cert_with_extern_psk_rejects_resumption(void)
|
||||
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
/* Load on ssl_s, not ctx_s: ssl_s already exists (test_memio_setup created
|
||||
* it) and shares the CTX key buffers. Reloading on ctx_s would free those
|
||||
* buffers, leaving ssl_s with a dangling key that crashes when the server
|
||||
* decodes it for CertificateVerify. */
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, eccCertFile,
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, eccKeyFile,
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
@@ -1328,6 +1375,10 @@ int test_tls13_cert_with_extern_psk_sh_missing_key_share(void)
|
||||
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
/* Load on ssl_s, not ctx_s: ssl_s already exists (test_memio_setup created
|
||||
* it) and shares the CTX key buffers. Reloading on ctx_s would free those
|
||||
* buffers, leaving ssl_s with a dangling key that crashes when the server
|
||||
* decodes it for CertificateVerify. */
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
@@ -1423,15 +1474,19 @@ int test_tls13_cert_with_extern_psk_sh_confirms_resumption(void)
|
||||
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
/* Load on ssl_s, not ctx_s: ssl_s already exists (test_memio_setup created
|
||||
* it) and shares the CTX key buffers. Reloading on ctx_s would free those
|
||||
* buffers, leaving ssl_s with a dangling key that crashes when the server
|
||||
* decodes it for CertificateVerify. */
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, eccCertFile,
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, eccKeyFile,
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
@@ -1502,6 +1557,689 @@ int test_tls13_cert_with_extern_psk_sh_confirms_resumption(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_api(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT)
|
||||
WOLFSSL_CTX* ctx = NULL;
|
||||
WOLFSSL* ssl = NULL;
|
||||
|
||||
(void)ctx;
|
||||
(void)ssl;
|
||||
|
||||
/* NULL arguments are rejected. */
|
||||
ExpectIntEQ(wolfSSL_CTX_require_psk(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wolfSSL_require_psk(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
|
||||
/* The failNoPSK bit is only settable when external-PSK or session-ticket
|
||||
* support is compiled in; mirror the guard used by the API itself. */
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
/* wolfSSL_CTX_require_psk() sets the failNoPSK bit on the CTX, and a new
|
||||
* SSL object inherits it. */
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||
ExpectIntEQ(wolfSSL_CTX_require_psk(ctx), 0);
|
||||
ExpectIntEQ(ctx->failNoPSK, 1);
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(ssl->options.failNoPSK, 1);
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
wolfSSL_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
|
||||
/* wolfSSL_require_psk() sets the option directly on the SSL object. */
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(ssl->options.failNoPSK, 0);
|
||||
ExpectIntEQ(wolfSSL_require_psk(ssl), 0);
|
||||
ExpectIntEQ(ssl->options.failNoPSK, 1);
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
wolfSSL_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
|
||||
/* The requirement is fail-closed: on a downgrade-capable context (created
|
||||
* from a v23 method) require_psk() disables version downgrade so the
|
||||
* handshake cannot silently fall back to (D)TLS 1.2 without a PSK. */
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
||||
ExpectIntEQ(wolfSSL_CTX_require_psk(ctx), 0);
|
||||
ExpectIntEQ(ctx->method->downgrade, 0);
|
||||
ExpectNotNull(ssl = wolfSSL_new(ctx));
|
||||
ExpectIntEQ(ssl->options.downgrade, 0);
|
||||
wolfSSL_free(ssl);
|
||||
ssl = NULL;
|
||||
wolfSSL_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
/* The API is TLS 1.3 only - a TLS 1.2 context is rejected so users are not
|
||||
* misled into thinking the option applies to TLS 1.2. */
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
|
||||
ExpectIntEQ(wolfSSL_CTX_require_psk(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
wolfSSL_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
/* 32-byte external PSK used by the fail-if-no-PSK test callbacks. */
|
||||
static const unsigned char test_tls13_fnp_psk[32] = {
|
||||
0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
|
||||
0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
|
||||
0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
|
||||
0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A
|
||||
};
|
||||
|
||||
static unsigned int test_tls13_fnp_client_cb(WOLFSSL* ssl, const char* hint,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
(void)hint;
|
||||
if (id_max_len == 0 || key_max_len < sizeof(test_tls13_fnp_psk))
|
||||
return 0;
|
||||
XSTRNCPY(identity, "fnp_client", id_max_len);
|
||||
XMEMCPY(key, test_tls13_fnp_psk, sizeof(test_tls13_fnp_psk));
|
||||
return (unsigned int)sizeof(test_tls13_fnp_psk);
|
||||
}
|
||||
|
||||
static unsigned int test_tls13_fnp_server_cb(WOLFSSL* ssl, const char* id,
|
||||
unsigned char* key, unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
if (key_max_len < sizeof(test_tls13_fnp_psk) || id == NULL)
|
||||
return 0;
|
||||
if (XSTRCMP(id, "fnp_client") != 0)
|
||||
return 0;
|
||||
XMEMCPY(key, test_tls13_fnp_psk, sizeof(test_tls13_fnp_psk));
|
||||
return (unsigned int)sizeof(test_tls13_fnp_psk);
|
||||
}
|
||||
|
||||
/* Server PSK callback that finds no PSK for any offered identity (returns 0),
|
||||
* mirroring an application whose lookup misses. */
|
||||
static unsigned int test_tls13_fnp_reject_server_cb(WOLFSSL* ssl,
|
||||
const char* id, unsigned char* key, unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
(void)id;
|
||||
(void)key;
|
||||
(void)key_max_len;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int test_tls13_fail_if_no_psk_handshake(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
const char appMsg[] = "fail_if_no_psk test";
|
||||
char readBuf[sizeof(appMsg)];
|
||||
int readSz;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
/* Both endpoints require a PSK to be negotiated. */
|
||||
wolfSSL_require_psk(ssl_c);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
|
||||
/* A PSK is configured on both ends, so the handshake completes. */
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_c->options.failNoPSK, 1);
|
||||
ExpectIntEQ(ssl_s->options.failNoPSK, 1);
|
||||
ExpectIntEQ(ssl_c->options.pskNegotiated, 1);
|
||||
ExpectIntEQ(ssl_s->options.pskNegotiated, 1);
|
||||
|
||||
/* Application data flows over the PSK-derived keys. */
|
||||
ExpectIntEQ(wolfSSL_write(ssl_c, appMsg, (int)XSTRLEN(appMsg)),
|
||||
(int)XSTRLEN(appMsg));
|
||||
readSz = wolfSSL_read(ssl_s, readBuf, sizeof(readBuf));
|
||||
ExpectIntEQ(readSz, (int)XSTRLEN(appMsg));
|
||||
ExpectIntEQ(XMEMCMP(readBuf, appMsg, (size_t)readSz), 0);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_rejects_no_psk(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
|
||||
(defined(HAVE_ECC) || !defined(NO_RSA))
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
/* The server requires a PSK and has one configured, but the client offers
|
||||
* none. The server must abort the handshake with PSK_MISSING_ERROR rather
|
||||
* than fall back to a certificate-only handshake. */
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
/* Only the server installs a PSK callback; the client sends no PSK. */
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_MISSING_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_client_no_psk_configured(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
/* WOLFSSL_QT force-enables havePSK on every CTX (see wolfSSL_CTX_new), so the
|
||||
* "no PSK configured" precondition this test relies on cannot be set up there. */
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && !defined(WOLFSSL_QT) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
|
||||
(defined(HAVE_ECC) || !defined(NO_RSA))
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
/* The client requires a PSK but configures none. Because failNoPSK is gated
|
||||
* on havePSK, this must NOT hard-fail: a normal certificate handshake is
|
||||
* expected to succeed instead of raising PSK_MISSING_ERROR. */
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_PEER, NULL);
|
||||
wolfSSL_require_psk(ssl_c);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_load_verify_locations(ctx_c, caEccCertFile,
|
||||
NULL) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_load_verify_locations(ctx_c, caCertFile,
|
||||
NULL) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
ExpectIntEQ(ssl_c->options.failNoPSK, 1);
|
||||
ExpectIntEQ(ssl_c->options.havePSK, 0);
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_c->options.pskNegotiated, 0);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_client_rejects(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
|
||||
(defined(HAVE_ECC) || !defined(NO_RSA))
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
|
||||
/* The client requires a PSK and has one configured, but the server has no
|
||||
* PSK callback so it never selects one. The client must abort with
|
||||
* PSK_MISSING_ERROR rather than fall back to a cert-only handshake. */
|
||||
wolfSSL_require_psk(ssl_c);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
/* Only the client installs a PSK callback. */
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_MISSING_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_requires_dhe(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
/* Baseline: a pure psk_ke handshake (no DHE) succeeds when the PSK is
|
||||
* optional, confirming the setup itself is valid. */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_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_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
ExpectIntEQ(wolfSSL_no_dhe_psk(ssl_c), 0);
|
||||
ExpectIntEQ(wolfSSL_no_dhe_psk(ssl_s), 0);
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_s->options.pskNegotiated, 1);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
ssl_c = NULL; ssl_s = NULL; ctx_c = NULL; ctx_s = NULL;
|
||||
|
||||
/* With failNoPSK on the server, the same pure psk_ke negotiation (no
|
||||
* forward secrecy) must be rejected with PSK_KEY_ERROR. */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_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_NONE, NULL);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
ExpectIntEQ(wolfSSL_no_dhe_psk(ssl_c), 0);
|
||||
ExpectIntEQ(wolfSSL_no_dhe_psk(ssl_s), 0);
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_KEY_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_client_requires_dhe(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
/* Only the client mandates the PSK (failNoPSK). The server does NOT set
|
||||
* failNoPSK and is configured for pure psk_ke (wolfSSL_no_dhe_psk), so it
|
||||
* accepts the PSK and replies with a ServerHello that omits a key_share.
|
||||
* When the client processes that ServerHello in SetupPskKey, the mandatory
|
||||
* external PSK has no (EC)DHE for forward secrecy, so the client must
|
||||
* reject it with PSK_KEY_ERROR. This exercises the client-side branch that
|
||||
* the server-only requires_dhe test cannot reach (there the server rejects
|
||||
* the pure psk_ke negotiation first). */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
|
||||
wolfSSL_require_psk(ssl_c);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
/* Force the server to negotiate a pure psk_ke (no (EC)DHE) exchange. */
|
||||
ExpectIntEQ(wolfSSL_no_dhe_psk(ssl_s), 0);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_KEY_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_resumption_exempt_from_dhe(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && defined(HAVE_SESSION_TICKET) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
|
||||
(defined(HAVE_ECC) || !defined(NO_RSA))
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
WOLFSSL_SESSION *sess = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
byte readBuf[16];
|
||||
|
||||
/* Step 1: full TLS 1.3 handshake to obtain a session ticket. The server
|
||||
* cert/key are already loaded by test_memio_setup; the default ticket
|
||||
* encryption callback lets a fresh server CTX below decrypt the ticket. */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_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_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
/* Drain the NewSessionTicket post-handshake message. */
|
||||
ExpectIntEQ(wolfSSL_read(ssl_c, readBuf, sizeof(readBuf)), -1);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
|
||||
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
|
||||
wolfSSL_free(ssl_c); ssl_c = NULL;
|
||||
wolfSSL_free(ssl_s); ssl_s = NULL;
|
||||
|
||||
/* Step 2: resume with a pure psk_ke (no (EC)DHE) exchange while the server
|
||||
* has the mandatory-PSK requirement set. A session-ticket resumption is
|
||||
* exempt from the mandatory-(EC)DHE rule, so the handshake must succeed
|
||||
* (an external PSK in the same situation would be rejected). */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_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_NONE, NULL);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
ExpectIntEQ(wolfSSL_no_dhe_psk(ssl_c), 0);
|
||||
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_c->options.resuming, 1);
|
||||
ExpectIntEQ(ssl_s->options.resuming, 1);
|
||||
|
||||
wolfSSL_SESSION_free(sess);
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_server_rejects_offered_psk(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
/* Baseline: the client offers a PSK but the server's callback rejects it
|
||||
* (returns 0). Without failNoPSK the server (which has a certificate from
|
||||
* test_memio_setup) falls back to a normal certificate handshake, which
|
||||
* succeeds and negotiates no PSK. */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_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_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_reject_server_cb);
|
||||
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_s->options.pskNegotiated, 0);
|
||||
|
||||
wolfSSL_free(ssl_c); ssl_c = NULL;
|
||||
wolfSSL_free(ssl_s); ssl_s = NULL;
|
||||
wolfSSL_CTX_free(ctx_c); ctx_c = NULL;
|
||||
wolfSSL_CTX_free(ctx_s); ctx_s = NULL;
|
||||
|
||||
/* With failNoPSK the same rejected-PSK negotiation must abort with
|
||||
* PSK_MISSING_ERROR instead of falling back to the certificate handshake. */
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_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_NONE, NULL);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_reject_server_cb);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_MISSING_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_no_cert_server(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
|
||||
/* Build the CTXs manually so the server has NO certificate configured,
|
||||
* matching a PSK-only deployment. The client offers a PSK, the server's
|
||||
* callback rejects it, and failNoPSK is set: the server must report
|
||||
* PSK_MISSING_ERROR (not BAD_BINDER, and no certificate fallback). */
|
||||
ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
|
||||
wolfSSL_SetIORecv(ctx_c, test_memio_read_cb);
|
||||
wolfSSL_SetIOSend(ctx_c, test_memio_write_cb);
|
||||
/* PSK callbacks are set on the CTX so PSK cipher suites are available when
|
||||
* the (cert-less) SSL objects are created. */
|
||||
wolfSSL_CTX_set_psk_client_callback(ctx_c, test_tls13_fnp_client_cb);
|
||||
|
||||
ExpectNotNull(ctx_s = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
|
||||
wolfSSL_SetIORecv(ctx_s, test_memio_read_cb);
|
||||
wolfSSL_SetIOSend(ctx_s, test_memio_write_cb);
|
||||
wolfSSL_CTX_set_psk_server_callback(ctx_s, test_tls13_fnp_reject_server_cb);
|
||||
wolfSSL_CTX_require_psk(ctx_s);
|
||||
|
||||
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
|
||||
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
|
||||
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
|
||||
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
|
||||
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
|
||||
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_MISSING_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_dtls13_handshake(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DTLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
const char appMsg[] = "fail_if_no_psk dtls13 test";
|
||||
char readBuf[sizeof(appMsg)];
|
||||
int readSz;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
|
||||
|
||||
/* Both endpoints require a PSK to be negotiated over DTLS 1.3, exercising
|
||||
* the HRR/cookie flow through DoTls13ServerHello and CheckPreSharedKeys. */
|
||||
wolfSSL_require_psk(ssl_c);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_fnp_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
|
||||
/* A PSK is configured on both ends, so the handshake completes. */
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_c->options.failNoPSK, 1);
|
||||
ExpectIntEQ(ssl_s->options.failNoPSK, 1);
|
||||
ExpectIntEQ(ssl_c->options.pskNegotiated, 1);
|
||||
ExpectIntEQ(ssl_s->options.pskNegotiated, 1);
|
||||
|
||||
/* Application data flows over the PSK-derived keys. */
|
||||
ExpectIntEQ(wolfSSL_write(ssl_c, appMsg, (int)XSTRLEN(appMsg)),
|
||||
(int)XSTRLEN(appMsg));
|
||||
readSz = wolfSSL_read(ssl_s, readBuf, sizeof(readBuf));
|
||||
ExpectIntEQ(readSz, (int)XSTRLEN(appMsg));
|
||||
ExpectIntEQ(XMEMCMP(readBuf, appMsg, (size_t)readSz), 0);
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
int test_tls13_fail_if_no_psk_dtls13_rejects_no_psk(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DTLS13) && !defined(NO_PSK) && \
|
||||
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
|
||||
defined(HAVE_SUPPORTED_CURVES) && \
|
||||
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
|
||||
!defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
|
||||
(defined(HAVE_ECC) || !defined(NO_RSA))
|
||||
WOLFSSL_CTX *ctx_c = NULL;
|
||||
WOLFSSL_CTX *ctx_s = NULL;
|
||||
WOLFSSL *ssl_c = NULL;
|
||||
WOLFSSL *ssl_s = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
|
||||
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
|
||||
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
|
||||
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
|
||||
|
||||
/* The server requires a PSK and has one configured, but the client offers
|
||||
* none. Over DTLS 1.3 the server must still abort with PSK_MISSING_ERROR
|
||||
* rather than fall back to a certificate-only handshake. */
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_require_psk(ssl_s);
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_use_certificate_file(ssl_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_use_PrivateKey_file(ssl_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
/* Only the server installs a PSK callback; the client sends no PSK. */
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_fnp_server_cb);
|
||||
|
||||
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WC_NO_ERR_TRACE(PSK_MISSING_ERROR));
|
||||
|
||||
wolfSSL_free(ssl_c);
|
||||
wolfSSL_CTX_free(ctx_c);
|
||||
wolfSSL_free(ssl_s);
|
||||
wolfSSL_CTX_free(ctx_s);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
|
||||
!defined(NO_WOLFSSL_SERVER) && defined(HAVE_ECC) && \
|
||||
defined(BUILD_TLS_AES_128_GCM_SHA256) && \
|
||||
|
||||
@@ -70,10 +70,23 @@ int test_tls13_serverhello_bad_cipher_suites(void);
|
||||
int test_tls13_psk_no_cert_bad_binder(void);
|
||||
int test_tls13_cert_with_extern_psk_apis(void);
|
||||
int test_tls13_cert_with_extern_psk_handshake(void);
|
||||
int test_tls13_cert_with_extern_psk_client_requires_cert(void);
|
||||
int test_tls13_cert_with_extern_psk_requires_key_share(void);
|
||||
int test_tls13_cert_with_extern_psk_rejects_resumption(void);
|
||||
int test_tls13_cert_with_extern_psk_sh_missing_key_share(void);
|
||||
int test_tls13_cert_with_extern_psk_sh_confirms_resumption(void);
|
||||
int test_tls13_fail_if_no_psk_api(void);
|
||||
int test_tls13_fail_if_no_psk_handshake(void);
|
||||
int test_tls13_fail_if_no_psk_rejects_no_psk(void);
|
||||
int test_tls13_fail_if_no_psk_client_no_psk_configured(void);
|
||||
int test_tls13_fail_if_no_psk_client_rejects(void);
|
||||
int test_tls13_fail_if_no_psk_requires_dhe(void);
|
||||
int test_tls13_fail_if_no_psk_client_requires_dhe(void);
|
||||
int test_tls13_fail_if_no_psk_resumption_exempt_from_dhe(void);
|
||||
int test_tls13_fail_if_no_psk_server_rejects_offered_psk(void);
|
||||
int test_tls13_fail_if_no_psk_no_cert_server(void);
|
||||
int test_tls13_fail_if_no_psk_dtls13_handshake(void);
|
||||
int test_tls13_fail_if_no_psk_dtls13_rejects_no_psk(void);
|
||||
int test_tls13_ticket_peer_cert_reverify(void);
|
||||
int test_tls13_clear_preserves_psk_dhe(void);
|
||||
int test_tls13_cipher_fuzz_aes128_gcm_sha256(void);
|
||||
@@ -134,10 +147,23 @@ int test_tls13_AEAD_limit_KU_aes128_ccm_8_sha256(void);
|
||||
TEST_DECL_GROUP("tls13", test_tls13_psk_no_cert_bad_binder), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_apis), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_handshake), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_client_requires_cert), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_requires_key_share), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_rejects_resumption), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_sh_missing_key_share), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cert_with_extern_psk_sh_confirms_resumption), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_api), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_handshake), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_rejects_no_psk), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_client_no_psk_configured), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_client_rejects), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_requires_dhe), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_client_requires_dhe), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_resumption_exempt_from_dhe), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_server_rejects_offered_psk), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_no_cert_server), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_dtls13_handshake), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_fail_if_no_psk_dtls13_rejects_no_psk), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_ticket_peer_cert_reverify), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_clear_preserves_psk_dhe), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_cipher_fuzz_aes128_gcm_sha256), \
|
||||
|
||||
@@ -83,6 +83,7 @@ enum wolfSSL_ErrorCodes {
|
||||
SERVER_HINT_ERROR = -332, /* psk server hint error */
|
||||
PSK_KEY_ERROR = -333, /* psk key error */
|
||||
DUPE_ENTRY_E = -334, /* duplicate entry error */
|
||||
PSK_MISSING_ERROR = -335, /* psk missing */
|
||||
|
||||
GETTIME_ERROR = -337, /* gettimeofday failed ??? */
|
||||
GETITIMER_ERROR = -338, /* getitimer failed ??? */
|
||||
|
||||
@@ -3997,6 +3997,7 @@ struct WOLFSSL_CTX {
|
||||
byte verifyNone:1;
|
||||
byte failNoCert:1;
|
||||
byte failNoCertxPSK:1; /* fail if no cert with the exception of PSK*/
|
||||
byte failNoPSK:1; /* fail if no PSK is negotiated */
|
||||
byte sessionCacheOff:1;
|
||||
byte sessionCacheFlushOff:1;
|
||||
#ifdef HAVE_EXT_CACHE
|
||||
@@ -5138,6 +5139,7 @@ struct Options {
|
||||
word16 verifyNone:1;
|
||||
word16 failNoCert:1;
|
||||
word16 failNoCertxPSK:1; /* fail for no cert except with PSK */
|
||||
word16 failNoPSK:1; /* fail if no PSK is negotiated */
|
||||
word16 downgrade:1; /* allow downgrade of versions */
|
||||
word16 resuming:1;
|
||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||
|
||||
@@ -1499,6 +1499,8 @@ WOLFSSL_API int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx);
|
||||
WOLFSSL_API int wolfSSL_no_dhe_psk(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_CTX_only_dhe_psk(WOLFSSL_CTX* ctx);
|
||||
WOLFSSL_API int wolfSSL_only_dhe_psk(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_CTX_require_psk(WOLFSSL_CTX* ctx);
|
||||
WOLFSSL_API int wolfSSL_require_psk(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_update_keys(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_key_update_response(WOLFSSL* ssl, int* required);
|
||||
WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx);
|
||||
@@ -3191,6 +3193,8 @@ enum { /* ssl Constants */
|
||||
WOLFSSL_VERIFY_CLIENT_ONCE = 1 << 2,
|
||||
WOLFSSL_VERIFY_POST_HANDSHAKE = 1 << 3,
|
||||
WOLFSSL_VERIFY_FAIL_EXCEPT_PSK = 1 << 4,
|
||||
/* 1 << 5 reserved (previously WOLFSSL_VERIFY_FAIL_IF_NO_PSK; a mandatory
|
||||
* PSK is now requested with wolfSSL_[CTX_]require_psk()). */
|
||||
WOLFSSL_VERIFY_DEFAULT = 1 << 9,
|
||||
|
||||
WOLFSSL_SESS_CACHE_OFF = 0x0000,
|
||||
|
||||
Reference in New Issue
Block a user