mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 09:20:55 +02:00
Merge pull request #10085 from Frauschi/rfc8773bis-cert-with-extern-psk
Add RFC8773(bis) cert_with_extern_psk support
This commit is contained in:
@@ -72,6 +72,7 @@ jobs:
|
||||
-DWOLFSSL_X963KDF:BOOL=yes -DWOLFSSL_DILITHIUM:BOOL=yes -DWOLFSSL_PKCS11:BOOL=yes \
|
||||
-DWOLFSSL_ECCSI:BOOL=yes -DWOLFSSL_SAKKE:BOOL=yes -DWOLFSSL_SIPHASH:BOOL=yes \
|
||||
-DWOLFSSL_WC_RSA_DIRECT:BOOL=yes -DWOLFSSL_PUBLIC_MP:BOOL=yes \
|
||||
-DWOLFSSL_CERT_WITH_EXTERN_PSK:BOOL=yes \
|
||||
-DWOLFSSL_EXTRA_PQC_HYBRIDS:BOOL=yes -DWOLFSSL_TLS_NO_MLKEM_STANDALONE:BOOL=no \
|
||||
..
|
||||
cmake --build .
|
||||
|
||||
@@ -18,6 +18,7 @@ jobs:
|
||||
matrix:
|
||||
config: [
|
||||
# Add new configs here
|
||||
'--enable-psk --enable-cert-with-extern-psk --disable-mlkem',
|
||||
'--enable-psk --disable-mlkem C_EXTRA_FLAGS="-DWOLFSSL_STATIC_PSK -DWOLFSSL_OLDTLS_SHA2_CIPHERSUITES"',
|
||||
'--enable-psk --disable-mlkem C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --disable-rsa --disable-ecc --disable-dh',
|
||||
'--disable-oldtls --disable-tls13 --enable-psk -disable-rsa --disable-dh -disable-ecc --disable-asn C_EXTRA_FLAGS=-DWOLFSSL_STATIC_PSK --enable-lowresource --enable-singlethreaded --disable-asm --disable-errorstrings --disable-pkcs12 --disable-sha3 --disable-sha224 --disable-sha384 --disable-sha512 --disable-sha --disable-md5 -disable-aescbc --disable-chacha --disable-poly1305 --disable-coding --disable-sp-math-all --disable-mlkem',
|
||||
|
||||
@@ -376,6 +376,24 @@ if(WOLFSSL_POSTAUTH)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Certificate Authentication with External PSK (RFC 8773bis)
|
||||
add_option("WOLFSSL_CERT_WITH_EXTERN_PSK"
|
||||
"Enable Certificate Authentication with External PSKs for TLS 1.3 (default: disabled)"
|
||||
"no" "yes;no")
|
||||
|
||||
if(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
if(NOT WOLFSSL_TLS13)
|
||||
message(WARNING "TLS 1.3 is disabled - disabling cert-with-extern-psk")
|
||||
override_cache(WOLFSSL_CERT_WITH_EXTERN_PSK "no")
|
||||
elseif(NOT WOLFSSL_PSK)
|
||||
message(WARNING "PSK is disabled - disabling cert-with-extern-psk")
|
||||
override_cache(WOLFSSL_CERT_WITH_EXTERN_PSK "no")
|
||||
else()
|
||||
list(APPEND WOLFSSL_DEFINITIONS
|
||||
"-DWOLFSSL_CERT_WITH_EXTERN_PSK")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Hello Retry Request Cookie
|
||||
add_option("WOLFSSL_HRR_COOKIE"
|
||||
"Enable the server to send Cookie Extension in HRR with state (default: disabled)"
|
||||
|
||||
+2
-1
@@ -308,6 +308,8 @@ extern "C" {
|
||||
#cmakedefine WOLFSSL_DTLS13
|
||||
#undef WOLFSSL_DTLS_CH_FRAG
|
||||
#cmakedefine WOLFSSL_DTLS_CH_FRAG
|
||||
#undef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
#cmakedefine WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
#undef WOLFSSL_EITHER_SIDE
|
||||
#cmakedefine WOLFSSL_EITHER_SIDE
|
||||
#undef WOLFSSL_ENCRYPTED_KEYS
|
||||
@@ -427,4 +429,3 @@ extern "C" {
|
||||
|
||||
|
||||
#endif /* WOLFSSL_OPTIONS_H */
|
||||
|
||||
|
||||
@@ -5146,6 +5146,27 @@ then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_PSK_ONE_ID"
|
||||
fi
|
||||
|
||||
# Certificate Authentication with External PSK (RFC 8773bis)
|
||||
AC_ARG_ENABLE([cert-with-extern-psk],
|
||||
[AS_HELP_STRING([--enable-cert-with-extern-psk],[Enable Certificate Authentication with External PSKs for TLS 1.3 (default: disabled)])],
|
||||
[ ENABLED_CERT_WITH_EXTERN_PSK=$enableval ],
|
||||
[ ENABLED_CERT_WITH_EXTERN_PSK=no ]
|
||||
)
|
||||
if test "$ENABLED_CERT_WITH_EXTERN_PSK" = "yes"
|
||||
then
|
||||
if test "$ENABLED_TLS13" = "no"
|
||||
then
|
||||
AC_MSG_NOTICE([TLS 1.3 is disabled - disabling cert-with-extern-psk])
|
||||
ENABLED_CERT_WITH_EXTERN_PSK="no"
|
||||
elif test "$ENABLED_PSK" = "no"
|
||||
then
|
||||
AC_MSG_NOTICE([PSK is disabled - disabling cert-with-extern-psk])
|
||||
ENABLED_CERT_WITH_EXTERN_PSK="no"
|
||||
else
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_WITH_EXTERN_PSK"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ERROR STRINGS
|
||||
AC_ARG_ENABLE([errorstrings],
|
||||
[AS_HELP_STRING([--enable-errorstrings],[Enable error strings table (default: enabled)])],
|
||||
|
||||
@@ -14721,6 +14721,75 @@ void wolfSSL_CTX_set_psk_server_tls13_callback(WOLFSSL_CTX* ctx,
|
||||
void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl,
|
||||
wc_psk_server_tls13_callback cb);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
\brief Enable or disable TLS 1.3 certificate authentication with external
|
||||
PSK (RFC8773bis) on a context.
|
||||
|
||||
When enabled, wolfSSL advertises and accepts the
|
||||
`tls_cert_with_extern_psk` extension for TLS 1.3 handshakes using external
|
||||
PSKs. Any non-zero \p state value enables the feature and zero disables it.
|
||||
|
||||
Availability:
|
||||
- Built with `--enable-tls13 --enable-psk --enable-cert-with-extern-psk`
|
||||
- Or with `WOLFSSL_TLS13` and `WOLFSSL_CERT_WITH_EXTERN_PSK` defined
|
||||
|
||||
\param [in,out] ctx a pointer to a WOLFSSL_CTX structure, created with
|
||||
wolfSSL_CTX_new().
|
||||
\param [in] state 0 to disable, non-zero to enable.
|
||||
|
||||
\return WOLFSSL_SUCCESS on success.
|
||||
\return WOLFSSL_FAILURE when \p ctx is NULL.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
|
||||
if (wolfSSL_CTX_set_cert_with_extern_psk(ctx, 1) != WOLFSSL_SUCCESS) {
|
||||
/* handle error */
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_set_cert_with_extern_psk
|
||||
\sa wolfSSL_CTX_set_psk_client_tls13_callback
|
||||
\sa wolfSSL_CTX_set_psk_server_tls13_callback
|
||||
*/
|
||||
int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx, int state);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
\brief Enable or disable TLS 1.3 certificate authentication with external
|
||||
PSK (RFC8773bis) on a connection.
|
||||
|
||||
This call applies to a single WOLFSSL object. Any non-zero \p state value
|
||||
enables the feature and zero disables it.
|
||||
|
||||
Availability:
|
||||
- Built with `--enable-tls13 --enable-psk --enable-cert-with-extern-psk`
|
||||
- Or with `WOLFSSL_TLS13` and `WOLFSSL_CERT_WITH_EXTERN_PSK` defined
|
||||
|
||||
\param [in,out] ssl a pointer to a WOLFSSL structure, created using
|
||||
wolfSSL_new().
|
||||
\param [in] state 0 to disable, non-zero to enable.
|
||||
|
||||
\return WOLFSSL_SUCCESS on success.
|
||||
\return WOLFSSL_FAILURE when \p ssl is NULL.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
WOLFSSL* ssl = wolfSSL_new(ctx);
|
||||
if (wolfSSL_set_cert_with_extern_psk(ssl, 1) != WOLFSSL_SUCCESS) {
|
||||
/* handle error */
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa wolfSSL_CTX_set_cert_with_extern_psk
|
||||
\sa wolfSSL_set_psk_client_tls13_callback
|
||||
\sa wolfSSL_set_psk_server_tls13_callback
|
||||
*/
|
||||
int wolfSSL_set_cert_with_extern_psk(WOLFSSL* ssl, int state);
|
||||
|
||||
/*!
|
||||
\ingroup Setup
|
||||
|
||||
|
||||
+63
-17
@@ -1206,7 +1206,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
|
||||
/* 4. add the same message into Japanese section */
|
||||
/* (will be translated later) */
|
||||
/* 5. add printf() into suitable position of Usage() */
|
||||
static const char* client_usage_msg[][80] = {
|
||||
static const char* client_usage_msg[][81] = {
|
||||
/* English */
|
||||
{
|
||||
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
|
||||
@@ -1451,24 +1451,28 @@ static const char* client_usage_msg[][80] = {
|
||||
#ifndef NO_PSK
|
||||
"--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 73 */
|
||||
#endif
|
||||
#ifdef HAVE_RPK
|
||||
"--rpk Use RPK for the defined certificates\n", /* 74 */
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 74 */
|
||||
#endif
|
||||
"--files-are-der Specified files are in DER, not PEM format\n", /* 75 */
|
||||
#ifdef HAVE_RPK
|
||||
"--rpk Use RPK for the defined certificates\n", /* 75 */
|
||||
#endif
|
||||
"--files-are-der Specified files are in DER, not PEM format\n", /* 76 */
|
||||
#ifdef WOLFSSL_SYS_CRYPTO_POLICY
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 76 */
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 77 */
|
||||
#endif
|
||||
#ifdef HAVE_ECC_BRAINPOOL
|
||||
"--bpKs Use Brainpool ECC group for key share\n", /* 77 */
|
||||
"--bpKs Use Brainpool ECC group for key share\n", /* 78 */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||
"--ech <base64> Use Encrypted Client Hello with base64 encoded "
|
||||
"ECH configs\n",
|
||||
/* 78 */
|
||||
/* 79 */
|
||||
#endif
|
||||
"\n"
|
||||
"For simpler wolfSSL TLS client examples, visit\n"
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 79 */
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 80 */
|
||||
NULL,
|
||||
},
|
||||
#ifndef NO_MULTIBYTE_PRINT
|
||||
@@ -1717,20 +1721,24 @@ static const char* client_usage_msg[][80] = {
|
||||
#ifndef NO_PSK
|
||||
"--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 73 */
|
||||
#endif
|
||||
#ifdef HAVE_RPK
|
||||
"--rpk Use RPK for the defined certificates\n", /* 74 */
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 74 */
|
||||
#endif
|
||||
"--files-are-der Specified files are in DER, not PEM format\n", /* 75 */
|
||||
#ifdef HAVE_RPK
|
||||
"--rpk Use RPK for the defined certificates\n", /* 75 */
|
||||
#endif
|
||||
"--files-are-der Specified files are in DER, not PEM format\n", /* 76 */
|
||||
#ifdef WOLFSSL_SYS_CRYPTO_POLICY
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 76 */
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 77 */
|
||||
#endif
|
||||
#ifdef HAVE_ECC_BRAINPOOL
|
||||
"--bpKs Use Brainpool ECC group for key share\n", /* 77 */
|
||||
"--bpKs Use Brainpool ECC group for key share\n", /* 78 */
|
||||
#endif
|
||||
"\n"
|
||||
"より簡単なwolfSSL TLS クライアントの例については"
|
||||
"下記にアクセスしてください\n"
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 78 */
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 79 */
|
||||
NULL,
|
||||
},
|
||||
#endif
|
||||
@@ -1966,6 +1974,10 @@ static void Usage(void)
|
||||
#ifndef NO_PSK
|
||||
printf("%s", msg[++msgid]); /* --openssl-psk */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
printf("%s", msg[++msgid]); /* --psk-with-certs */
|
||||
#endif
|
||||
#ifdef HAVE_RPK
|
||||
printf("%s", msg[++msgid]); /* --rpk */
|
||||
#endif
|
||||
@@ -2165,6 +2177,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||
{ "ech", 1, 271 },
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
{ "psk-with-certs", 0, 272 },
|
||||
#endif
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
@@ -2173,6 +2189,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
int minVersion = CLIENT_INVALID_VERSION;
|
||||
int usePsk = 0;
|
||||
int opensslPsk = 0;
|
||||
int usePskWithCerts = 0;
|
||||
int useAnon = 0;
|
||||
int sendGET = 0;
|
||||
int benchmark = 0;
|
||||
@@ -2412,6 +2429,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
(void)pqcAlg;
|
||||
(void)opensslPsk;
|
||||
(void)fileFormat;
|
||||
(void)usePskWithCerts;
|
||||
StackTrap();
|
||||
|
||||
/* Reinitialize the global myVerifyAction. */
|
||||
@@ -3067,6 +3085,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
echConfigs64 = myoptarg;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
case 272:
|
||||
usePskWithCerts = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
Usage();
|
||||
@@ -3077,6 +3101,18 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
myoptind = 0; /* reset for test cases */
|
||||
#endif /* !WOLFSSL_VXWORKS */
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
if (usePskWithCerts) {
|
||||
usePsk = 1;
|
||||
if (noPskDheKe) {
|
||||
LOG_ERROR("--psk-with-certs requires PSK key exchange with (EC)DHE");
|
||||
Usage();
|
||||
XEXIT_T(MY_EX_USAGE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (externalTest) {
|
||||
/* detect build cases that wouldn't allow test against wolfssl.com */
|
||||
int done = 0;
|
||||
@@ -3483,6 +3519,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
wolfSSL_CTX_set_psk_client_tls13_callback(ctx,
|
||||
my_psk_client_tls13_cb);
|
||||
}
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
if (usePskWithCerts) {
|
||||
if (wolfSSL_CTX_set_cert_with_extern_psk(ctx, 1) != WOLFSSL_SUCCESS) {
|
||||
wolfSSL_CTX_free(ctx); ctx = NULL;
|
||||
err_sys("client can't enable cert_with_extern_psk");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (defaultCipherList == NULL) {
|
||||
#if defined(HAVE_AESGCM) && !defined(NO_DH)
|
||||
@@ -3634,7 +3678,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!usePsk && !useAnon && !useVerifyCb && myVerifyAction != VERIFY_FORCE_FAIL) {
|
||||
if ((!usePsk || usePskWithCerts) && !useAnon && !useVerifyCb &&
|
||||
myVerifyAction != VERIFY_FORCE_FAIL) {
|
||||
#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
|
||||
(defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
|
||||
!defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
|
||||
@@ -3718,10 +3763,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
myVerifyAction == VERIFY_USE_PREVERIFY) {
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
|
||||
}
|
||||
else if (!usePsk && !useAnon && doPeerCheck == 0) {
|
||||
else if ((!usePsk || usePskWithCerts) && !useAnon && doPeerCheck == 0) {
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
|
||||
}
|
||||
else if (!usePsk && !useAnon && myVerifyAction == VERIFY_OVERRIDE_DATE_ERR) {
|
||||
else if ((!usePsk || usePskWithCerts) && !useAnon &&
|
||||
myVerifyAction == VERIFY_OVERRIDE_DATE_ERR) {
|
||||
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
|
||||
}
|
||||
#endif /* !NO_CERTS */
|
||||
|
||||
+61
-17
@@ -933,7 +933,7 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
|
||||
/* 4. add the same message into Japanese section */
|
||||
/* (will be translated later) */
|
||||
/* 5. add printf() into suitable position of Usage() */
|
||||
static const char* server_usage_msg[][70] = {
|
||||
static const char* server_usage_msg[][71] = {
|
||||
/* English */
|
||||
{
|
||||
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
|
||||
@@ -1123,25 +1123,28 @@ static const char* server_usage_msg[][70] = {
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
"--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 64 */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 65 */
|
||||
#endif
|
||||
#ifdef WOLFSSL_DUAL_ALG_CERTS
|
||||
"--altPrivKey <file> Generate alternative signature with this key.\n",
|
||||
/* 65 */
|
||||
"--altPrivKey <file> Generate alternative signature with this key.\n", /* 66 */
|
||||
#endif
|
||||
#ifdef WOLFSSL_SYS_CRYPTO_POLICY
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 66 */
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 67 */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||
"--ech <name> Generate Encrypted Client Hello config with "
|
||||
"public name <name>\n",
|
||||
/* 67 */
|
||||
/* 68 */
|
||||
"--ech-suite <KEM,KDF,AEAD> HPKE suite to use for ech config.\n"
|
||||
" Supplied as 3 integers (ex: 32,1,3)\n",
|
||||
/* 68 */
|
||||
/* 69 */
|
||||
#endif
|
||||
"\n"
|
||||
"For simpler wolfSSL TLS server examples, visit\n"
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n",
|
||||
/* 69 */
|
||||
/* 70 */
|
||||
NULL,
|
||||
},
|
||||
#ifndef NO_MULTIBYTE_PRINT
|
||||
@@ -1346,26 +1349,29 @@ static const char* server_usage_msg[][70] = {
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
"--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 64 */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 65 */
|
||||
#endif
|
||||
#ifdef WOLFSSL_DUAL_ALG_CERTS
|
||||
"--altPrivKey <file> Generate alternative signature with this key.\n",
|
||||
/* 65 */
|
||||
"--altPrivKey <file> Generate alternative signature with this key.\n", /* 66 */
|
||||
#endif
|
||||
#ifdef WOLFSSL_SYS_CRYPTO_POLICY
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 66 */
|
||||
"--crypto-policy <path to crypto policy file>\n", /* 67 */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||
"--ech <name> Generate Encrypted Client Hello config with "
|
||||
"public name <name>\n",
|
||||
/* 67 */
|
||||
/* 68 */
|
||||
"--ech-suite <KEM,KDF,AEAD> HPKE suite to use for ech config.\n"
|
||||
" Supplied as 3 integers (ex: 32,1,3)\n",
|
||||
/* 68 */
|
||||
/* 69 */
|
||||
#endif
|
||||
"\n"
|
||||
"より簡単なwolfSSL TSL クライアントの例については"
|
||||
"下記にアクセスしてください\n"
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n",
|
||||
/* 69 */
|
||||
/* 70 */
|
||||
NULL,
|
||||
},
|
||||
#endif
|
||||
@@ -1522,6 +1528,10 @@ static void Usage(void)
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
printf("%s", msg[++msgId]); /* --onlyPskDheKe */
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
printf("%s", msg[++msgId]); /* --psk-with-certs */
|
||||
#endif
|
||||
#ifdef WOLFSSL_DUAL_ALG_CERTS
|
||||
printf("%s", msg[++msgId]); /* --altPrivKey */
|
||||
#endif
|
||||
@@ -1654,6 +1664,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
|
||||
{ "ech", 1, 269 },
|
||||
{ "ech-suite", 1, 270 },
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
{ "psk-with-certs", 0, 271 },
|
||||
#endif
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
@@ -1671,6 +1685,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
word16 port = wolfSSLPort;
|
||||
int usePsk = 0;
|
||||
int usePskPlus = 0;
|
||||
int usePskWithCerts = 0;
|
||||
int useAnon = 0;
|
||||
int doDTLS = 0;
|
||||
int dtlsUDP = 0;
|
||||
@@ -1907,6 +1922,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
(void)pqcAlg;
|
||||
(void)usePqc;
|
||||
(void)altPrivKey;
|
||||
(void)usePskWithCerts;
|
||||
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
@@ -2597,6 +2613,12 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
case 271:
|
||||
usePskWithCerts = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case -1:
|
||||
default:
|
||||
@@ -2608,6 +2630,18 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
myoptind = 0; /* reset for test cases */
|
||||
#endif /* !WOLFSSL_VXWORKS */
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
if (usePskWithCerts) {
|
||||
usePsk = 1;
|
||||
if (noPskDheKe) {
|
||||
LOG_ERROR("--psk-with-certs requires PSK key exchange with (EC)DHE");
|
||||
Usage();
|
||||
XEXIT_T(MY_EX_USAGE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Can only use DTLS over UDP or SCTP, can't do both. */
|
||||
if (dtlsUDP && dtlsSCTP) {
|
||||
err_sys_ex(runWithErrors, "Cannot use DTLS with both UDP and SCTP.");
|
||||
@@ -2930,7 +2964,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
|
||||
#if !defined(NO_CERTS)
|
||||
if ((!usePsk || usePskPlus) && !useAnon && !(loadCertKeyIntoSSLObj == 1)) {
|
||||
if ((!usePsk || usePskPlus || usePskWithCerts) && !useAnon &&
|
||||
!(loadCertKeyIntoSSLObj == 1)) {
|
||||
#if defined(NO_FILESYSTEM) && defined(USE_CERT_BUFFERS_2048)
|
||||
if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
|
||||
server_cert_der_2048, sizeof_server_cert_der_2048,
|
||||
@@ -2974,7 +3009,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
pkCbInfo.ourKey = ourKey;
|
||||
#endif
|
||||
if ((!usePsk || usePskPlus) && !useAnon
|
||||
if ((!usePsk || usePskPlus || usePskWithCerts) && !useAnon
|
||||
&& !(loadCertKeyIntoSSLObj == 1)
|
||||
#if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
|
||||
&& !pkCallbacks
|
||||
@@ -3016,6 +3051,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
wolfSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
|
||||
#ifdef WOLFSSL_TLS13
|
||||
wolfSSL_CTX_set_psk_server_tls13_callback(ctx, my_psk_server_tls13_cb);
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
if (usePskWithCerts) {
|
||||
if (wolfSSL_CTX_set_cert_with_extern_psk(ctx, 1) != WOLFSSL_SUCCESS) {
|
||||
err_sys_ex(runWithErrors,
|
||||
"server can't enable cert_with_extern_psk");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (sendPskIdentityHint == 1)
|
||||
wolfSSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
|
||||
@@ -3304,7 +3347,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
|
||||
/* Support for loading private key and cert using WOLFSSL object */
|
||||
#if !defined(NO_CERTS)
|
||||
if ((!usePsk || usePskPlus) && !useAnon && loadCertKeyIntoSSLObj) {
|
||||
if ((!usePsk || usePskPlus || usePskWithCerts) && !useAnon &&
|
||||
loadCertKeyIntoSSLObj) {
|
||||
#if defined(NO_FILESYSTEM) && defined(USE_CERT_BUFFERS_2048)
|
||||
if (wolfSSL_use_certificate_chain_buffer_format(ssl,
|
||||
server_cert_der_2048, sizeof_server_cert_der_2048,
|
||||
@@ -3321,7 +3365,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((!usePsk || usePskPlus) && !useAnon &&
|
||||
if ((!usePsk || usePskPlus || usePskWithCerts) && !useAnon &&
|
||||
loadCertKeyIntoSSLObj
|
||||
#if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
|
||||
&& !pkCallbacks
|
||||
|
||||
@@ -2847,6 +2847,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
|
||||
#if defined(WOLFSSL_TLS13) && !defined(HAVE_SUPPORTED_CURVES)
|
||||
ctx->noPskDheKe = 1;
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
/* Disabled by default - opt in through API. */
|
||||
ctx->certWithExternPsk = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_QT) && !defined(NO_PSK)
|
||||
@@ -7961,6 +7965,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
ssl->options.onlyPskDheKe = ctx->onlyPskDheKe;
|
||||
#endif /* HAVE_SUPPORTED_CURVES */
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
ssl->options.certWithExternPsk = ctx->certWithExternPsk;
|
||||
#endif
|
||||
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
|
||||
#if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
ssl->options.postHandshakeAuth = ctx->postHandshakeAuth;
|
||||
|
||||
@@ -8087,6 +8087,27 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
||||
ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
|
||||
ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx, int state)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_set_cert_with_extern_psk");
|
||||
if (ctx == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
ctx->certWithExternPsk = (byte)(state != 0);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
int wolfSSL_set_cert_with_extern_psk(WOLFSSL* ssl, int state)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_set_cert_with_extern_psk");
|
||||
if (ssl == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
ssl->options.certWithExternPsk = (word16)(state != 0);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
/**
|
||||
* set call back function for psk session use
|
||||
|
||||
@@ -12378,6 +12378,89 @@ int TLSX_PreSharedKey_Use(TLSX** extensions, const byte* identity, word16 len,
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Certificate Authentication with External Pre-Shared Key */
|
||||
/******************************************************************************/
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
|
||||
static int TLSX_CertWithExternPsk_GetSize(byte msgType, word16* pSz)
|
||||
{
|
||||
(void)msgType;
|
||||
(void)pSz;
|
||||
/* Zero-length extension - nothing to add. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int TLSX_CertWithExternPsk_Write(byte* output, byte msgType,
|
||||
word16* pSz)
|
||||
{
|
||||
(void)output;
|
||||
(void)msgType;
|
||||
(void)pSz;
|
||||
/* Zero-length extension - nothing to write. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int TLSX_CertWithExternPsk_Parse(WOLFSSL* ssl, byte msgType)
|
||||
{
|
||||
if (msgType == client_hello) {
|
||||
/* Server has not opted in - treat the extension as unknown. */
|
||||
if (!ssl->options.certWithExternPsk)
|
||||
return 0;
|
||||
/* Record that the client offered the extension, leaving resp=0.
|
||||
* CheckPreSharedKeys() is the sole writer that flips resp to 1, and
|
||||
* only after confirming that a non-ticket PSK was matched. */
|
||||
if (TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) == NULL) {
|
||||
return TLSX_Push(&ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK,
|
||||
NULL, ssl->heap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msgType == server_hello) {
|
||||
if (TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) == NULL) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
ssl->options.certWithExternPsk = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||
return SANITY_MSG_E;
|
||||
}
|
||||
|
||||
int TLSX_CertWithExternPsk_Use(WOLFSSL* ssl)
|
||||
{
|
||||
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK);
|
||||
|
||||
if (extension == NULL) {
|
||||
int ret = TLSX_Push(&ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK, NULL,
|
||||
ssl->heap);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
extension = TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK);
|
||||
if (extension == NULL)
|
||||
return MEMORY_E;
|
||||
}
|
||||
extension->resp = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PSK_WITH_CERT_GET_SIZE TLSX_CertWithExternPsk_GetSize
|
||||
#define PSK_WITH_CERT_WRITE TLSX_CertWithExternPsk_Write
|
||||
#define PSK_WITH_CERT_PARSE TLSX_CertWithExternPsk_Parse
|
||||
|
||||
#else
|
||||
|
||||
#define PSK_WITH_CERT_GET_SIZE(a, b) 0
|
||||
#define PSK_WITH_CERT_WRITE(a, b, c) 0
|
||||
#define PSK_WITH_CERT_PARSE(a, b) 0
|
||||
|
||||
#endif /* WOLFSSL_TLS13 && WOLFSSL_CERT_WITH_EXTERN_PSK */
|
||||
|
||||
/******************************************************************************/
|
||||
/* PSK Key Exchange Modes */
|
||||
/******************************************************************************/
|
||||
@@ -14666,6 +14749,11 @@ void TLSX_FreeAll(TLSX* list, void* heap)
|
||||
case TLSX_PSK_KEY_EXCHANGE_MODES:
|
||||
WOLFSSL_MSG("PSK Key Exchange Modes extension free");
|
||||
break;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
case TLSX_CERT_WITH_EXTERN_PSK:
|
||||
WOLFSSL_MSG("Cert with external PSK extension free");
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -14862,6 +14950,11 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
|
||||
case TLSX_PSK_KEY_EXCHANGE_MODES:
|
||||
ret = PKM_GET_SIZE((byte)extension->val, msgType, &length);
|
||||
break;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
case TLSX_CERT_WITH_EXTERN_PSK:
|
||||
ret = PSK_WITH_CERT_GET_SIZE(msgType, &length);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
case TLSX_KEY_SHARE:
|
||||
@@ -15092,6 +15185,12 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
||||
ret = PKM_WRITE((byte)extension->val, output + offset, msgType,
|
||||
&offset);
|
||||
break;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
case TLSX_CERT_WITH_EXTERN_PSK:
|
||||
WOLFSSL_MSG("Cert with external PSK extension to write");
|
||||
ret = PSK_WITH_CERT_WRITE(output + offset, msgType, &offset);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
case TLSX_KEY_SHARE:
|
||||
@@ -15805,7 +15904,11 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
||||
TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET)
|
||||
if (ssl->options.resuming && ssl->session->ticketLen > 0) {
|
||||
if (ssl->options.resuming && ssl->session->ticketLen > 0
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
&& !ssl->options.certWithExternPsk
|
||||
#endif
|
||||
) {
|
||||
WOLFSSL_SESSION* sess = ssl->session;
|
||||
#ifdef WOLFSSL_32BIT_MILLI_TIME
|
||||
word32 now, milli;
|
||||
@@ -16000,15 +16103,31 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
|
||||
modes = 1 << PSK_KE;
|
||||
}
|
||||
#if !defined(NO_DH) || defined(HAVE_ECC) || \
|
||||
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
|
||||
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
|
||||
if (!ssl->options.noPskDheKe) {
|
||||
modes |= 1 << PSK_DHE_KE;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
if (ssl->options.certWithExternPsk) {
|
||||
/* RFC8773bis requires psk_dhe_ke with cert_with_extern_psk. */
|
||||
modes |= 1 << PSK_DHE_KE;
|
||||
}
|
||||
#endif
|
||||
ret = TLSX_PskKeyModes_Use(ssl, modes);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
if (usingPSK && ssl->options.certWithExternPsk) {
|
||||
ret = TLSX_CertWithExternPsk_Use(ssl);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
/* Require server confirmation before using cert-with-PSK path. */
|
||||
ssl->options.certWithExternPsk = 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
|
||||
if (!isServer && ssl->options.postHandshakeAuth) {
|
||||
@@ -16525,6 +16644,9 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
|
||||
@@ -16581,6 +16703,9 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
|
||||
@@ -16673,6 +16798,9 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -16729,6 +16857,9 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
|
||||
@@ -16901,6 +17032,8 @@ static word16 TLSX_GetMinSize_Client(word16* type)
|
||||
return WOLFSSL_CKE_MIN_SIZE_CLIENT;
|
||||
case TLSXT_PSK_KEY_EXCHANGE_MODES:
|
||||
return WOLFSSL_PKM_MIN_SIZE_CLIENT;
|
||||
case TLSXT_CERT_WITH_EXTERN_PSK:
|
||||
return WOLFSSL_CWEP_MIN_SIZE_CLIENT;
|
||||
case TLSXT_CERTIFICATE_AUTHORITIES:
|
||||
return WOLFSSL_CAN_MIN_SIZE_CLIENT;
|
||||
case TLSXT_POST_HANDSHAKE_AUTH:
|
||||
@@ -16970,6 +17103,8 @@ static word16 TLSX_GetMinSize_Server(const word16 *type)
|
||||
return WOLFSSL_CKE_MIN_SIZE_SERVER;
|
||||
case TLSXT_PSK_KEY_EXCHANGE_MODES:
|
||||
return WOLFSSL_PKM_MIN_SIZE_SERVER;
|
||||
case TLSXT_CERT_WITH_EXTERN_PSK:
|
||||
return WOLFSSL_CWEP_MIN_SIZE_SERVER;
|
||||
case TLSXT_CERTIFICATE_AUTHORITIES:
|
||||
return WOLFSSL_CAN_MIN_SIZE_SERVER;
|
||||
case TLSXT_POST_HANDSHAKE_AUTH:
|
||||
@@ -17010,6 +17145,11 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
|
||||
int pskDone = 0;
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
int secondClientHello = 0;
|
||||
int prevHasPskWithCert = 0;
|
||||
#endif
|
||||
byte seenType[SEMAPHORE_SIZE]; /* Seen known extensions. */
|
||||
|
||||
@@ -17018,6 +17158,15 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||
|
||||
/* No known extensions seen yet. */
|
||||
XMEMSET(seenType, 0, sizeof(seenType));
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
if (IsAtLeastTLSv1_3(ssl->version) && msgType == client_hello &&
|
||||
ssl->msgsReceived.got_client_hello == 2) {
|
||||
secondClientHello = 1;
|
||||
prevHasPskWithCert =
|
||||
TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (ret == 0 && offset < length) {
|
||||
word16 type;
|
||||
@@ -17463,6 +17612,29 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||
|
||||
ret = PKM_PARSE(ssl, input + offset, size, msgType);
|
||||
break;
|
||||
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
case TLSX_CERT_WITH_EXTERN_PSK:
|
||||
WOLFSSL_MSG("Cert with external PSK extension received");
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_BUFFER(input + offset, size);
|
||||
#endif
|
||||
|
||||
if (!IsAtLeastTLSv1_3(ssl->version))
|
||||
break;
|
||||
|
||||
if (msgType != client_hello && msgType != server_hello) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
if (size != 0) {
|
||||
WOLFSSL_ERROR_VERBOSE(BUFFER_ERROR);
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
|
||||
ret = PSK_WITH_CERT_PARSE(ssl, msgType);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
@@ -17710,6 +17882,71 @@ int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length, byte msgType,
|
||||
ssl->options.noPskDheKe = 1;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
int hasPskWithCert = !IS_OFF(seenType,
|
||||
TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
|
||||
if (hasPskWithCert && ssl->options.certWithExternPsk) {
|
||||
int hasPsk = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
|
||||
int hasPskModes = !IS_OFF(seenType,
|
||||
TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
|
||||
int hasKeyShare = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_KEY_SHARE));
|
||||
int hasSg = !IS_OFF(seenType,
|
||||
TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
|
||||
int hasSigAlg = !IS_OFF(seenType,
|
||||
TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
int hasEarlyData = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_EARLY_DATA));
|
||||
#endif
|
||||
|
||||
if (msgType == client_hello && isRequest) {
|
||||
TLSX* pskm;
|
||||
/* RFC8773bis: CH2 after HRR must keep CH1's extension set. */
|
||||
if (secondClientHello && !prevHasPskWithCert) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
/* RFC8773bis: cert_with_extern_psk depends on these extensions. */
|
||||
if (!hasPsk || !hasPskModes || !hasKeyShare || !hasSg ||
|
||||
!hasSigAlg) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_MISSING);
|
||||
return EXT_MISSING;
|
||||
}
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
/* External PSK + certificate mode forbids 0-RTT in CH.
|
||||
* When WOLFSSL_EARLY_DATA is not defined there is no parser
|
||||
* case for TLSX_EARLY_DATA, so an incoming early_data
|
||||
* extension is treated as unknown and ignored per RFC 8446
|
||||
* Sect. 4.2 - no additional check is needed in that case. */
|
||||
if (hasEarlyData) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
#endif
|
||||
pskm = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
|
||||
/* RFC8773bis requires client support for psk_dhe_ke mode. */
|
||||
if (pskm == NULL || (pskm->val & (1 << PSK_DHE_KE)) == 0) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
else if (msgType == server_hello && !isRequest) {
|
||||
/* SH confirming cert_with_extern_psk must also confirm PSK and KSE. */
|
||||
if (!hasPsk || !hasKeyShare) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_MISSING);
|
||||
return EXT_MISSING;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (msgType == client_hello && isRequest && secondClientHello &&
|
||||
prevHasPskWithCert) {
|
||||
/* RFC8773bis: reject dropping the extension in CH2 after HRR. */
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
|
||||
return EXT_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
|
||||
/* RFC 8446 Section 9.2: ClientHello with KeyShare must
|
||||
* contain SupportedGroups and vice-versa. */
|
||||
|
||||
+200
-23
@@ -4310,8 +4310,17 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
|
||||
}
|
||||
|
||||
if (!clientHello) {
|
||||
/* CLIENT: using PSK for peer authentication. */
|
||||
ssl->options.peerAuthGood = 1;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (ssl->options.certWithExternPsk) {
|
||||
/* Certificate authentication is still required. */
|
||||
ssl->options.peerAuthGood = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* CLIENT: using PSK for peer authentication. */
|
||||
ssl->options.peerAuthGood = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -5735,6 +5744,20 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (ssl->options.certWithExternPsk && psk->resumption) {
|
||||
/* RFC8773bis mode requires external PSK, not ticket resumption. */
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
if (ssl->options.certWithExternPsk && ssl->options.shSentKeyShare == 0) {
|
||||
/* RFC8773bis Sec. 3: cert_with_extern_psk requires psk_dhe_ke;
|
||||
* a ServerHello without a key_share confirms only psk_ke. */
|
||||
WOLFSSL_MSG("cert_with_extern_psk: ServerHello missing key_share");
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_MISSING);
|
||||
return EXT_MISSING;
|
||||
}
|
||||
#endif
|
||||
if ((ret = SetupPskKey(ssl, psk, 0)) != 0)
|
||||
return ret;
|
||||
ssl->options.pskNegotiated = 1;
|
||||
@@ -6079,10 +6102,15 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err)
|
||||
ret = FindPskSuite(ssl, psk, ssl->arrays->psk_key, &ssl->arrays->psk_keySz,
|
||||
suite, &found, foundSuite);
|
||||
if (ret == 0 && found) {
|
||||
/* This identity matched via external PSK callback, not ticket resume. */
|
||||
psk->resumption = 0;
|
||||
/* Default to ciphersuite if cb doesn't specify. */
|
||||
ssl->options.resuming = 0;
|
||||
/* Don't send certificate request when using PSK. */
|
||||
ssl->options.verifyPeer = 0;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (!ssl->options.certWithExternPsk)
|
||||
#endif
|
||||
ssl->options.verifyPeer = 0;
|
||||
|
||||
/* PSK age is always zero. */
|
||||
if (psk->ticketAge != 0) {
|
||||
@@ -6102,8 +6130,13 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err)
|
||||
if (ret == 0) {
|
||||
/* PSK negotiation has succeeded */
|
||||
ssl->options.isPSK = 1;
|
||||
/* SERVER: using PSK for peer authentication. */
|
||||
ssl->options.peerAuthGood = 1;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (!ssl->options.certWithExternPsk)
|
||||
#endif
|
||||
{
|
||||
/* SERVER: using PSK for peer authentication. */
|
||||
ssl->options.peerAuthGood = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6132,6 +6165,9 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
|
||||
byte binderKey[WC_MAX_DIGEST_SIZE];
|
||||
byte binder[WC_MAX_DIGEST_SIZE];
|
||||
word32 binderLen;
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(HAVE_SESSION_TICKET)
|
||||
int certWithExternOffered = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NO_PSK
|
||||
(void) suite; /* to avoid unused var warning when not used */
|
||||
@@ -6147,6 +6183,10 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
|
||||
ret = BAD_FUNC_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(HAVE_SESSION_TICKET)
|
||||
certWithExternOffered =
|
||||
TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) != NULL;
|
||||
#endif
|
||||
|
||||
/* Look through all client's pre-shared keys for a match. */
|
||||
for (current = (PreSharedKey*)ext->data; current != NULL;
|
||||
@@ -6192,6 +6232,27 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
|
||||
sizeof(psk_sess_free_cb_ctx));
|
||||
}
|
||||
if (ret == WOLFSSL_TICKET_RET_OK) {
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(HAVE_SESSION_TICKET)
|
||||
/* RFC 8773bis Sect. 5.1: all PSKs listed alongside
|
||||
* tls_cert_with_extern_psk MUST be external PSKs. A successfully
|
||||
* decrypted session ticket identity is a resumption PSK, so the
|
||||
* server MUST abort with illegal_parameter regardless of whether
|
||||
* the ticket would otherwise be acceptable. Check here, before
|
||||
* DoClientTicketFinalize, to avoid polluting ssl->session with
|
||||
* ticket state that will not be used. */
|
||||
if (certWithExternOffered) {
|
||||
if (current->sess_free_cb != NULL) {
|
||||
current->sess_free_cb(ssl, current->sess,
|
||||
¤t->sess_free_cb_ctx);
|
||||
current->sess = NULL;
|
||||
XMEMSET(¤t->sess_free_cb_ctx, 0,
|
||||
sizeof(psk_sess_free_cb_ctx));
|
||||
}
|
||||
ret = PSK_KEY_ERROR;
|
||||
WOLFSSL_ERROR_VERBOSE(ret);
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
ret = DoClientTicketCheck(ssl, current, ssl->timeout, suite);
|
||||
if (ret == 0)
|
||||
DoClientTicketFinalize(ssl, current->it, current->sess);
|
||||
@@ -6440,13 +6501,29 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
|
||||
if (*usingPSK != 0) {
|
||||
word32 modes;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
int usingCertWithExternPsk = 0;
|
||||
TLSX* certExt = NULL;
|
||||
TLSX* pskExt = NULL;
|
||||
PreSharedKey* chosenPsk = NULL;
|
||||
#endif
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
TLSX* extEarlyData;
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
int hasCertWithExternPsk = (TLSX_Find(ssl->extensions,
|
||||
TLSX_CERT_WITH_EXTERN_PSK) != NULL);
|
||||
#endif
|
||||
|
||||
extEarlyData = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
|
||||
if (extEarlyData != NULL) {
|
||||
/* Check if accepting early data and first PSK. */
|
||||
if (ssl->earlyData != no_early_data && first) {
|
||||
/* Check if accepting early data and first PSK.
|
||||
* RFC 8773bis: early_data is not compatible with
|
||||
* cert_with_extern_psk, so skip key derivation in that case. */
|
||||
if (ssl->earlyData != no_early_data && first
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
&& !hasCertWithExternPsk
|
||||
#endif
|
||||
) {
|
||||
extEarlyData->resp = 1;
|
||||
|
||||
/* Derive early data decryption key. */
|
||||
@@ -6473,14 +6550,76 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
}
|
||||
modes = ext->val;
|
||||
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
certExt = TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK);
|
||||
if (certExt != NULL) {
|
||||
pskExt = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
|
||||
if (pskExt != NULL)
|
||||
chosenPsk = (PreSharedKey*)pskExt->data;
|
||||
while (chosenPsk != NULL && !chosenPsk->chosen)
|
||||
chosenPsk = chosenPsk->next;
|
||||
if (chosenPsk == NULL || chosenPsk->resumption) {
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
if ((modes & (1 << PSK_DHE_KE)) == 0) {
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
usingCertWithExternPsk = 1;
|
||||
ssl->options.certWithExternPsk = 1;
|
||||
if (clSuites->hashSigAlgoSz == 0) {
|
||||
WOLFSSL_ERROR_VERBOSE(MISSING_HANDSHAKE_DATA);
|
||||
return MISSING_HANDSHAKE_DATA;
|
||||
}
|
||||
ret = PickHashSigAlgo(ssl, clSuites->hashSigAlgo,
|
||||
clSuites->hashSigAlgoSz, 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ssl->options.sendVerify = SEND_CERT;
|
||||
certExt->resp = 1;
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
/* RFC 8773bis: early_data is not compatible with
|
||||
* cert_with_extern_psk. TLSX_Parse already rejects the
|
||||
* combination in the ClientHello, but clear the response flag
|
||||
* here as a defense-in-depth measure. */
|
||||
if (extEarlyData != NULL) {
|
||||
extEarlyData->resp = 0;
|
||||
ssl->earlyData = no_early_data;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ssl->options.certWithExternPsk = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SUPPORTED_CURVES
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (usingCertWithExternPsk) {
|
||||
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
|
||||
return PSK_KEY_ERROR;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
|
||||
/* Use (EC)DHE for forward-security if possible. */
|
||||
if ((modes & (1 << PSK_DHE_KE)) != 0 && !ssl->options.noPskDheKe &&
|
||||
ext != NULL) {
|
||||
/* Only use named group used in last session. */
|
||||
ssl->namedGroup = ssl->session->namedGroup;
|
||||
|
||||
if (((modes & (1 << PSK_DHE_KE)) != 0 && !ssl->options.noPskDheKe &&
|
||||
ext != NULL)
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
|| usingCertWithExternPsk
|
||||
#endif
|
||||
) {
|
||||
if (ext == NULL) {
|
||||
WOLFSSL_ERROR_VERBOSE(EXT_MISSING);
|
||||
return EXT_MISSING;
|
||||
}
|
||||
/* Resumption path uses previous session group. */
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (!usingCertWithExternPsk)
|
||||
#endif
|
||||
ssl->namedGroup = ssl->session->namedGroup;
|
||||
*usingPSK = 2; /* generate new ephemeral key */
|
||||
}
|
||||
else if (ssl->options.onlyPskDheKe) {
|
||||
@@ -6500,16 +6639,20 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
|
||||
*usingPSK = 1;
|
||||
}
|
||||
}
|
||||
#ifdef WOLFSSL_PSK_ID_PROTECTION
|
||||
else {
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
TLSX_Remove(&ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK, ssl->heap);
|
||||
ssl->options.certWithExternPsk = 0;
|
||||
#endif
|
||||
#ifdef WOLFSSL_PSK_ID_PROTECTION
|
||||
#ifndef NO_CERTS
|
||||
if (ssl->buffers.certChainCnt != 0)
|
||||
return 0;
|
||||
#endif
|
||||
WOLFSSL_ERROR_VERBOSE(BAD_BINDER);
|
||||
return BAD_BINDER;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
WOLFSSL_LEAVE("CheckPreSharedKeys", ret);
|
||||
|
||||
@@ -7346,7 +7489,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
|
||||
#if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) && \
|
||||
defined(HAVE_TLS_EXTENSIONS)
|
||||
if (!args->usingPSK)
|
||||
if (!args->usingPSK
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
|| ssl->options.certWithExternPsk
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
{
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
@@ -12759,7 +12906,11 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
/* Server's authenticating with PSK must not send this. */
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||
ssl->options.serverState == SERVER_CERT_COMPLETE &&
|
||||
ssl->options.pskNegotiated) {
|
||||
ssl->options.pskNegotiated
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
&& !ssl->options.certWithExternPsk
|
||||
#endif
|
||||
) {
|
||||
WOLFSSL_MSG("Certificate received while using PSK");
|
||||
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||
return SANITY_MSG_E;
|
||||
@@ -12823,7 +12974,11 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
/* Server's authenticating with PSK must not send this. */
|
||||
if (ssl->options.pskNegotiated) {
|
||||
if (ssl->options.pskNegotiated
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
&& !ssl->options.certWithExternPsk
|
||||
#endif
|
||||
) {
|
||||
WOLFSSL_MSG("CertificateRequest received while using PSK");
|
||||
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||
return SANITY_MSG_E;
|
||||
@@ -12864,7 +13019,11 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
}
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
/* Server's authenticating with PSK must not send this. */
|
||||
if (ssl->options.pskNegotiated) {
|
||||
if (ssl->options.pskNegotiated
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
&& !ssl->options.certWithExternPsk
|
||||
#endif
|
||||
) {
|
||||
WOLFSSL_MSG("CertificateVerify received while using PSK");
|
||||
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
|
||||
return SANITY_MSG_E;
|
||||
@@ -12919,11 +13078,25 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
* using PSK. */
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
if (ssl->options.pskNegotiated) {
|
||||
if (ssl->options.serverState !=
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
if (ssl->options.certWithExternPsk) {
|
||||
if (ssl->options.serverState !=
|
||||
SERVER_CERT_VERIFY_COMPLETE) {
|
||||
WOLFSSL_MSG("Finished received out of order - "
|
||||
"cert_with_extern_psk");
|
||||
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
|
||||
return OUT_OF_ORDER_E;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (ssl->options.serverState !=
|
||||
SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
|
||||
WOLFSSL_MSG("Finished received out of order - PSK");
|
||||
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
|
||||
return OUT_OF_ORDER_E;
|
||||
WOLFSSL_MSG("Finished received out of order - PSK");
|
||||
WOLFSSL_ERROR_VERBOSE(OUT_OF_ORDER_E);
|
||||
return OUT_OF_ORDER_E;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -12961,7 +13134,11 @@ static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
if (!ssl->options.pskNegotiated)
|
||||
if (!ssl->options.pskNegotiated
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
|| ssl->options.certWithExternPsk
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
{
|
||||
/* Must have received a Certificate message from client if
|
||||
|
||||
@@ -868,6 +868,617 @@ int test_tls13_apis(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK)
|
||||
int test_tls13_cert_with_extern_psk_apis(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
WOLFSSL_CTX* ctx = NULL;
|
||||
WOLFSSL* ssl = NULL;
|
||||
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cert_with_extern_psk(NULL, 0), WOLFSSL_FAILURE);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(NULL, 0), WOLFSSL_FAILURE);
|
||||
|
||||
ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
|
||||
ExpectNotNull(ctx);
|
||||
ssl = wolfSSL_new(ctx);
|
||||
ExpectNotNull(ssl);
|
||||
|
||||
if (EXPECT_SUCCESS()) {
|
||||
/* Any non-zero value enables cert_with_extern_psk. */
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cert_with_extern_psk(ctx, -1),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cert_with_extern_psk(ctx, 2),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl, -1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl, 2), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_CTX_set_cert_with_extern_psk(ctx, 1),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl, 0), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl, 1), WOLFSSL_SUCCESS);
|
||||
}
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#else
|
||||
int test_tls13_cert_with_extern_psk_apis(void)
|
||||
{
|
||||
return TEST_SKIPPED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
/* 32-byte external PSK (SHA-256 digest size) used by cwep test callbacks. */
|
||||
static const unsigned char test_tls13_cwep_psk[32] = {
|
||||
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
|
||||
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
|
||||
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
|
||||
0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A
|
||||
};
|
||||
|
||||
static unsigned int test_tls13_cwep_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_cwep_psk))
|
||||
return 0;
|
||||
XSTRNCPY(identity, "cwep_client", id_max_len);
|
||||
XMEMCPY(key, test_tls13_cwep_psk, sizeof(test_tls13_cwep_psk));
|
||||
return (unsigned int)sizeof(test_tls13_cwep_psk);
|
||||
}
|
||||
|
||||
static unsigned int test_tls13_cwep_server_cb(WOLFSSL* ssl, const char* id,
|
||||
unsigned char* key, unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
if (key_max_len < sizeof(test_tls13_cwep_psk) || id == NULL)
|
||||
return 0;
|
||||
if (XSTRCMP(id, "cwep_client") != 0)
|
||||
return 0;
|
||||
XMEMCPY(key, test_tls13_cwep_psk, sizeof(test_tls13_cwep_psk));
|
||||
return (unsigned int)sizeof(test_tls13_cwep_psk);
|
||||
}
|
||||
#endif
|
||||
|
||||
int test_tls13_cert_with_extern_psk_handshake(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_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[] = "cert_with_extern_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);
|
||||
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_PEER, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM)
|
||||
#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);
|
||||
#elif !defined(NO_RSA)
|
||||
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
|
||||
#endif
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_cwep_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_cwep_server_cb);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_c, 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_s, 1), WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
ExpectIntEQ(ssl_c->options.pskNegotiated, 1);
|
||||
ExpectIntEQ(ssl_s->options.pskNegotiated, 1);
|
||||
ExpectIntEQ(ssl_c->options.certWithExternPsk, 1);
|
||||
ExpectIntEQ(ssl_s->options.certWithExternPsk, 1);
|
||||
ExpectIntEQ(ssl_c->msgsReceived.got_certificate, 1);
|
||||
ExpectIntEQ(ssl_c->msgsReceived.got_certificate_verify, 1);
|
||||
|
||||
/* Verify application data exchange works with the 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_cert_with_extern_psk_requires_key_share(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_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);
|
||||
|
||||
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, NULL);
|
||||
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM)
|
||||
#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);
|
||||
#elif !defined(NO_RSA)
|
||||
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
|
||||
#endif
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_cwep_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_cwep_server_cb);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_c, 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_s, 1), WOLFSSL_SUCCESS);
|
||||
/* Omit key_share in CH1 to force the server to send an HRR. */
|
||||
ExpectIntEQ(wolfSSL_NoKeyShares(ssl_c), WOLFSSL_SUCCESS);
|
||||
|
||||
/* CH1: client -> server (no key_share). */
|
||||
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
|
||||
/* HRR: server reads CH1, sends HRR requesting a key_share group. */
|
||||
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
ExpectIntEQ(ssl_s->options.serverState,
|
||||
SERVER_HELLO_RETRY_REQUEST_COMPLETE);
|
||||
|
||||
/* Complete the handshake: client sends CH2 (with key_share), server
|
||||
* responds with SH + cert + cert-verify + Finished, client finishes. */
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
|
||||
/* Verify that cert_with_extern_psk was negotiated end-to-end. */
|
||||
ExpectIntEQ(ssl_c->options.pskNegotiated, 1);
|
||||
ExpectIntEQ(ssl_s->options.pskNegotiated, 1);
|
||||
ExpectIntEQ(ssl_c->options.certWithExternPsk, 1);
|
||||
ExpectIntEQ(ssl_s->options.certWithExternPsk, 1);
|
||||
ExpectIntEQ(ssl_c->msgsReceived.got_certificate, 1);
|
||||
ExpectIntEQ(ssl_c->msgsReceived.got_certificate_verify, 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_rejects_resumption(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK) && defined(HAVE_SESSION_TICKET) && \
|
||||
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;
|
||||
WOLFSSL_SESSION *sess = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
byte readBuf[16];
|
||||
|
||||
/* Step 1: plain TLS 1.3 handshake to obtain a session ticket. The same
|
||||
* server CTX is reused below so the ticket encryption key matches. */
|
||||
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);
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
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: attempt to resume while also offering cert_with_extern_psk.
|
||||
* RFC 8773bis Sect. 5.1 requires all PSKs offered alongside
|
||||
* cert_with_extern_psk to be external PSKs. The client MUST therefore
|
||||
* suppress the resumption ticket identity from the pre_shared_key
|
||||
* extension. The handshake succeeds as a cert_with_extern_psk handshake
|
||||
* using only the external 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_cwep_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_cwep_server_cb);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_c, 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_s, 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
|
||||
|
||||
/* Handshake succeeds; the client correctly omits the resumption ticket. */
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 20, NULL), 0);
|
||||
/* Verify we got a cert_with_extern_psk handshake, not a resumption. */
|
||||
ExpectIntEQ(ssl_c->options.certWithExternPsk, 1);
|
||||
ExpectIntEQ(ssl_s->options.certWithExternPsk, 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();
|
||||
}
|
||||
|
||||
#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_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
/* Locate the extensions block of a TLS 1.3 ServerHello record. On success,
|
||||
* writes the offset of the 2-byte extensions_length field into *ext_len_off
|
||||
* and returns 0. Returns -1 on malformed input. Only the plaintext SH
|
||||
* record (type 0x16, handshake subtype 0x02) is supported. */
|
||||
static int test_cwep_sh_find_ext_block(const byte* sh, int sh_len,
|
||||
int* ext_len_off)
|
||||
{
|
||||
int idx;
|
||||
int sid_len;
|
||||
|
||||
/* 5 byte record hdr + 4 byte handshake hdr + 2 byte legacy_version
|
||||
* + 32 byte random + 1 byte legacy_session_id length. */
|
||||
if (sh_len < 5 + 4 + 2 + 32 + 1)
|
||||
return -1;
|
||||
if (sh[0] != 0x16 || sh[5] != 0x02)
|
||||
return -1;
|
||||
idx = 5 + 4 + 2 + 32;
|
||||
sid_len = sh[idx];
|
||||
idx += 1 + sid_len + 2 + 1; /* skip sid + cipher_suite + compression */
|
||||
if (idx + 2 > sh_len)
|
||||
return -1;
|
||||
*ext_len_off = idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Apply a delta to the record, handshake and extensions length fields of a
|
||||
* TLS 1.3 SH record. Negative values shrink the message. */
|
||||
static void test_cwep_sh_adjust_lengths(byte* sh, int ext_len_off, int delta)
|
||||
{
|
||||
int v;
|
||||
|
||||
v = (int)(((word32)sh[3] << 8) | sh[4]) + delta;
|
||||
sh[3] = (byte)(v >> 8);
|
||||
sh[4] = (byte)v;
|
||||
v = (int)(((word32)sh[6] << 16) | ((word32)sh[7] << 8) | sh[8]) + delta;
|
||||
sh[6] = (byte)(v >> 16);
|
||||
sh[7] = (byte)(v >> 8);
|
||||
sh[8] = (byte)v;
|
||||
v = (int)(((word32)sh[ext_len_off] << 8) | sh[ext_len_off + 1]) + delta;
|
||||
sh[ext_len_off] = (byte)(v >> 8);
|
||||
sh[ext_len_off + 1] = (byte)v;
|
||||
}
|
||||
|
||||
/* Remove the first extension of the given type from a TLS 1.3 SH record.
|
||||
* Returns the new record length, or -1 if the extension was not present. */
|
||||
static int test_cwep_sh_strip_extension(byte* sh, int sh_len, word16 ext_type)
|
||||
{
|
||||
int ext_len_off;
|
||||
int ext_base, ext_end;
|
||||
int p;
|
||||
word16 ext_total;
|
||||
|
||||
if (test_cwep_sh_find_ext_block(sh, sh_len, &ext_len_off) != 0)
|
||||
return -1;
|
||||
ext_total = (word16)(((word16)sh[ext_len_off] << 8) | sh[ext_len_off + 1]);
|
||||
ext_base = ext_len_off + 2;
|
||||
ext_end = ext_base + ext_total;
|
||||
if (ext_end > sh_len)
|
||||
return -1;
|
||||
|
||||
p = ext_base;
|
||||
while (p + 4 <= ext_end) {
|
||||
word16 t = (word16)(((word16)sh[p] << 8) | sh[p + 1]);
|
||||
word16 l = (word16)(((word16)sh[p + 2] << 8) | sh[p + 3]);
|
||||
int entry = 4 + (int)l;
|
||||
if (p + entry > ext_end)
|
||||
return -1;
|
||||
if (t == ext_type) {
|
||||
XMEMMOVE(sh + p, sh + p + entry,
|
||||
(size_t)(sh_len - p - entry));
|
||||
test_cwep_sh_adjust_lengths(sh, ext_len_off, -entry);
|
||||
return sh_len - entry;
|
||||
}
|
||||
p += entry;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET)
|
||||
/* Append a zero-length extension of the given type to a TLS 1.3 SH record.
|
||||
* The SH body must be the tail of the record, which is the normal case. */
|
||||
static int test_cwep_sh_append_empty_extension(byte* sh, int sh_len,
|
||||
int sh_cap, word16 ext_type)
|
||||
{
|
||||
int ext_len_off;
|
||||
int ext_base, ext_end;
|
||||
word16 ext_total;
|
||||
|
||||
if (test_cwep_sh_find_ext_block(sh, sh_len, &ext_len_off) != 0)
|
||||
return -1;
|
||||
ext_total = (word16)(((word16)sh[ext_len_off] << 8) | sh[ext_len_off + 1]);
|
||||
ext_base = ext_len_off + 2;
|
||||
ext_end = ext_base + ext_total;
|
||||
if (ext_end != sh_len)
|
||||
return -1;
|
||||
if (sh_len + 4 > sh_cap)
|
||||
return -1;
|
||||
|
||||
sh[sh_len + 0] = (byte)(ext_type >> 8);
|
||||
sh[sh_len + 1] = (byte)ext_type;
|
||||
sh[sh_len + 2] = 0;
|
||||
sh[sh_len + 3] = 0;
|
||||
test_cwep_sh_adjust_lengths(sh, ext_len_off, 4);
|
||||
return sh_len + 4;
|
||||
}
|
||||
#endif /* HAVE_SESSION_TICKET */
|
||||
#endif
|
||||
|
||||
int test_tls13_cert_with_extern_psk_sh_missing_key_share(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_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;
|
||||
byte sh_buf[4096];
|
||||
const char* sh_bytes = NULL;
|
||||
int sh_sz = 0;
|
||||
int new_sz;
|
||||
|
||||
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);
|
||||
#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
|
||||
wolfSSL_set_psk_client_callback(ssl_c, test_tls13_cwep_client_cb);
|
||||
wolfSSL_set_psk_server_callback(ssl_s, test_tls13_cwep_server_cb);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_c, 1), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_set_cert_with_extern_psk(ssl_s, 1), WOLFSSL_SUCCESS);
|
||||
|
||||
/* Drive the client to emit the ClientHello, then let the server produce
|
||||
* its flight. */
|
||||
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
|
||||
/* The first "message" recorded by memio may contain several concatenated
|
||||
* records (SH + CCS + first encrypted handshake record). Slice the
|
||||
* plaintext SH record out using its own length field. */
|
||||
ExpectIntEQ(test_memio_get_message(&test_ctx, 1, &sh_bytes, &sh_sz, 0), 0);
|
||||
if (sh_sz >= 5 && (byte)sh_bytes[0] == 0x16) {
|
||||
int rec_body = ((int)(byte)sh_bytes[3] << 8) | (byte)sh_bytes[4];
|
||||
sh_sz = 5 + rec_body;
|
||||
}
|
||||
ExpectTrue(sh_sz > 0 && sh_sz <= (int)sizeof(sh_buf));
|
||||
if (sh_sz > 0 && sh_sz <= (int)sizeof(sh_buf)) {
|
||||
XMEMCPY(sh_buf, sh_bytes, (size_t)sh_sz);
|
||||
/* Strip the key_share extension from the SH so the resulting SH
|
||||
* confirms cert_with_extern_psk without negotiating (EC)DHE. */
|
||||
new_sz = test_cwep_sh_strip_extension(sh_buf, sh_sz, 0x0033);
|
||||
ExpectIntGT(new_sz, 0);
|
||||
}
|
||||
else {
|
||||
new_sz = -1;
|
||||
}
|
||||
|
||||
/* Throw away the entire server flight and feed only the tampered SH. */
|
||||
test_memio_clear_buffer(&test_ctx, 1);
|
||||
if (new_sz > 0) {
|
||||
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
|
||||
(const char*)sh_buf, new_sz), 0);
|
||||
}
|
||||
|
||||
/* Client must reject the SH with EXT_MISSING. */
|
||||
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
EXT_MISSING);
|
||||
|
||||
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_sh_confirms_resumption(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(NO_PSK) && defined(HAVE_SESSION_TICKET) && \
|
||||
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;
|
||||
WOLFSSL_SESSION *sess = NULL;
|
||||
struct test_memio_ctx test_ctx;
|
||||
byte sh_buf[4096];
|
||||
const char* sh_bytes = NULL;
|
||||
byte drain[16];
|
||||
int sh_sz = 0;
|
||||
int new_sz;
|
||||
|
||||
/* Phase 1: plain handshake so the client gets a session ticket. The
|
||||
* server CTX is reused below to keep the ticket encryption key. */
|
||||
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);
|
||||
#if defined(HAVE_ECC)
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, eccCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, eccKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#else
|
||||
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
|
||||
CERT_FILETYPE) == WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
|
||||
/* Drain the NewSessionTicket post-handshake message. */
|
||||
ExpectIntEQ(wolfSSL_read(ssl_c, drain, sizeof(drain)), -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;
|
||||
|
||||
/* Phase 2: client resumes WITHOUT cert_with_extern_psk. The server
|
||||
* performs a normal resumption. We then tamper the SH to inject an
|
||||
* unsolicited cert_with_extern_psk extension. The client must reject
|
||||
* it because it never offered the extension. */
|
||||
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(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
|
||||
|
||||
/* Run client CH then server flight. */
|
||||
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
|
||||
WOLFSSL_ERROR_WANT_READ);
|
||||
|
||||
ExpectIntEQ(test_memio_get_message(&test_ctx, 1, &sh_bytes, &sh_sz, 0), 0);
|
||||
if (sh_sz >= 5 && (byte)sh_bytes[0] == 0x16) {
|
||||
int rec_body = ((int)(byte)sh_bytes[3] << 8) | (byte)sh_bytes[4];
|
||||
sh_sz = 5 + rec_body;
|
||||
}
|
||||
ExpectTrue(sh_sz > 0 && sh_sz <= (int)sizeof(sh_buf));
|
||||
if (sh_sz > 0 && sh_sz <= (int)sizeof(sh_buf)) {
|
||||
XMEMCPY(sh_buf, sh_bytes, (size_t)sh_sz);
|
||||
/* Append an unsolicited cert_with_extern_psk (0x0021) extension.
|
||||
* The client never offered this extension, so it must be rejected. */
|
||||
new_sz = test_cwep_sh_append_empty_extension(sh_buf, sh_sz,
|
||||
(int)sizeof(sh_buf), 0x0021);
|
||||
ExpectIntGT(new_sz, 0);
|
||||
}
|
||||
else {
|
||||
new_sz = -1;
|
||||
}
|
||||
|
||||
test_memio_clear_buffer(&test_ctx, 1);
|
||||
if (new_sz > 0) {
|
||||
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
|
||||
(const char*)sh_buf, new_sz), 0);
|
||||
}
|
||||
|
||||
/* Client must reject the unsolicited extension. */
|
||||
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
|
||||
!defined(NO_WOLFSSL_SERVER) && defined(HAVE_ECC) && \
|
||||
defined(BUILD_TLS_AES_128_GCM_SHA256) && \
|
||||
|
||||
+13
-1
@@ -52,6 +52,12 @@ int test_tls13_hrr_bad_cookie(void);
|
||||
int test_tls13_zero_inner_content_type(void);
|
||||
int test_tls13_downgrade_sentinel(void);
|
||||
int test_tls13_serverhello_bad_cipher_suites(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_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);
|
||||
|
||||
#define TEST_TLS13_DECLS \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_apis), \
|
||||
@@ -81,6 +87,12 @@ int test_tls13_serverhello_bad_cipher_suites(void);
|
||||
TEST_DECL_GROUP("tls13", test_tls13_hrr_bad_cookie), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_zero_inner_content_type), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_downgrade_sentinel), \
|
||||
TEST_DECL_GROUP("tls13", test_tls13_serverhello_bad_cipher_suites)
|
||||
TEST_DECL_GROUP("tls13", test_tls13_serverhello_bad_cipher_suites), \
|
||||
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_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)
|
||||
|
||||
#endif /* WOLFCRYPT_TEST_TLS13_H */
|
||||
|
||||
+12
-1
@@ -1548,7 +1548,7 @@ int SuiteTest(int argc, char** argv)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_TLS13
|
||||
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK)
|
||||
/* add psk extra suites */
|
||||
XSTRLCPY(argv0[1], "tests/test-tls13-psk.conf", sizeof(argv0[1]));
|
||||
printf("starting TLS 1.3 psk no identity extra cipher suite tests\n");
|
||||
@@ -1558,6 +1558,17 @@ int SuiteTest(int argc, char** argv)
|
||||
args.return_code = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
|
||||
/* add psk with certificates (cert_with_extern_psk) suites */
|
||||
XSTRLCPY(argv0[1], "tests/test-tls13-psk-certs.conf", sizeof(argv0[1]));
|
||||
printf("starting TLS 1.3 PSK with certificates extra suite tests\n");
|
||||
test_harness(&args);
|
||||
if (args.return_code != 0) {
|
||||
printf("error from script %d\n", args.return_code);
|
||||
args.return_code = EXIT_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_MD5) &&\
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# server TLSv1.3 PSK with certificates (cert_with_extern_psk)
|
||||
-v 4
|
||||
-s
|
||||
--psk-with-certs
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-d
|
||||
|
||||
# client TLSv1.3 PSK with certificates (cert_with_extern_psk)
|
||||
-v 4
|
||||
-s
|
||||
--psk-with-certs
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
@@ -2965,6 +2965,7 @@ typedef struct Options Options;
|
||||
#define TLSXT_SERVER_CERTIFICATE 0x0014 /* RFC8446 */
|
||||
#define TLSXT_ENCRYPT_THEN_MAC 0x0016 /* RFC 7366 */
|
||||
#define TLSXT_EXTENDED_MASTER_SECRET 0x0017 /* HELLO_EXT_EXTMS */
|
||||
#define TLSXT_CERT_WITH_EXTERN_PSK 0x0021 /* RFC 8773bis */
|
||||
#define TLSXT_SESSION_TICKET 0x0023
|
||||
#define TLSXT_PRE_SHARED_KEY 0x0029
|
||||
#define TLSXT_EARLY_DATA 0x002a
|
||||
@@ -3020,6 +3021,9 @@ typedef enum {
|
||||
TLSX_COOKIE = TLSXT_COOKIE,
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
TLSX_PSK_KEY_EXCHANGE_MODES = TLSXT_PSK_KEY_EXCHANGE_MODES,
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
TLSX_CERT_WITH_EXTERN_PSK = TLSXT_CERT_WITH_EXTERN_PSK,
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
|
||||
TLSX_CERTIFICATE_AUTHORITIES = TLSXT_CERTIFICATE_AUTHORITIES,
|
||||
@@ -3743,6 +3747,9 @@ WOLFSSL_LOCAL int TLSX_PreSharedKey_Use(TLSX** extensions, const byte* identity,
|
||||
void* heap);
|
||||
WOLFSSL_LOCAL int TLSX_PreSharedKey_Parse_ClientHello(TLSX** extensions,
|
||||
const byte* input, word16 length, void* heap);
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && defined(WOLFSSL_TLS13)
|
||||
WOLFSSL_LOCAL int TLSX_CertWithExternPsk_Use(WOLFSSL* ssl);
|
||||
#endif
|
||||
|
||||
/* The possible Pre-Shared Key key exchange modes. */
|
||||
enum PskKeyExchangeMode {
|
||||
@@ -3942,6 +3949,9 @@ struct WOLFSSL_CTX {
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
byte onlyPskDheKe:1; /* Only use (EC)DHE with PSK */
|
||||
#endif
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
byte certWithExternPsk:1; /* Use tls_cert_with_extern_psk extension */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
byte mutualAuth:1; /* Mutual authentication required */
|
||||
@@ -5068,6 +5078,9 @@ struct Options {
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
word16 onlyPskDheKe:1; /* Only use (EC)DHE with PSK */
|
||||
#endif
|
||||
#if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
word16 certWithExternPsk:1; /* Cert auth with external PSK */
|
||||
#endif
|
||||
#endif
|
||||
word16 partialWrite:1; /* only one msg per write call */
|
||||
word16 quietShutdown:1; /* don't send close notify */
|
||||
|
||||
@@ -3212,6 +3212,11 @@ enum { /* ssl Constants */
|
||||
wc_psk_server_tls13_callback cb);
|
||||
WOLFSSL_API void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl,
|
||||
wc_psk_server_tls13_callback cb);
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
|
||||
WOLFSSL_API int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx,
|
||||
int state);
|
||||
WOLFSSL_API int wolfSSL_set_cert_with_extern_psk(WOLFSSL* ssl, int state);
|
||||
#endif
|
||||
WOLFSSL_API void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl);
|
||||
WOLFSSL_API int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx);
|
||||
@@ -6300,6 +6305,12 @@ WOLFSSL_API const unsigned char* wolfSSL_dtls_cid_parse(const unsigned char* msg
|
||||
#ifndef WOLFSSL_PKM_MIN_SIZE_SERVER
|
||||
#define WOLFSSL_PKM_MIN_SIZE_SERVER 0
|
||||
#endif
|
||||
#ifndef WOLFSSL_CWEP_MIN_SIZE_CLIENT
|
||||
#define WOLFSSL_CWEP_MIN_SIZE_CLIENT 0
|
||||
#endif
|
||||
#ifndef WOLFSSL_CWEP_MIN_SIZE_SERVER
|
||||
#define WOLFSSL_CWEP_MIN_SIZE_SERVER 0
|
||||
#endif
|
||||
#ifndef WOLFSSL_CSR2_MIN_SIZE_CLIENT
|
||||
#define WOLFSSL_CSR2_MIN_SIZE_CLIENT 7
|
||||
#endif
|
||||
|
||||
@@ -5100,6 +5100,14 @@ extern void uITRON4_free(void *p) ;
|
||||
!defined(HAVE_SESSION_TICKET) && defined(NO_PSK)
|
||||
#error "Early data requires session tickets (HAVE_SESSION_TICKET) or PSK"
|
||||
#endif
|
||||
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
!defined(WOLFSSL_TLS13)
|
||||
#error "cert_with_extern_psk requires TLS 1.3 (WOLFSSL_TLS13)"
|
||||
#endif
|
||||
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
|
||||
defined(NO_PSK)
|
||||
#error "cert_with_extern_psk requires PSK support"
|
||||
#endif
|
||||
|
||||
/* DES3 TLS Suite Rule - auto-disable DES3 TLS suites when DES3 is disabled */
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_DES3_TLS_SUITES) && \
|
||||
|
||||
Reference in New Issue
Block a user