TLS 1.3 PSK: add option to require only PSK with DHE

Can specify only PSK without DHE.
Add only PSK with DHE.
pull/6006/head
Sean Parkinson 2023-01-24 12:00:37 +10:00
parent 4b8ab2550d
commit b624fc8377
9 changed files with 198 additions and 14 deletions

View File

@ -1260,10 +1260,13 @@ static const char* client_usage_msg[][70] = {
#endif
#ifdef WOLFSSL_SYS_CA_CERTS
"--sys-ca-certs Load system CA certs for server cert verification\n", /* 72 */
#endif
#ifdef HAVE_SUPPORTED_CURVES
"--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 73 */
#endif
"\n"
"For simpler wolfSSL TLS client examples, visit\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 73 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 74 */
NULL,
},
#ifndef NO_MULTIBYTE_PRINT
@ -1475,11 +1478,17 @@ static const char* client_usage_msg[][70] = {
#endif
#ifdef WOLFSSL_SRTP
"--srtp <profile> (デフォルトは SRTP_AES128_CM_SHA1_80)\n", /* 71 */
#endif
#ifdef WOLFSSL_SYS_CA_CERTS
"--sys-ca-certs Load system CA certs for server cert verification\n", /* 72 */
#endif
#ifdef HAVE_SUPPORTED_CURVES
"--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 73 */
#endif
"\n"
"より簡単なwolfSSL TSL クライアントの例については"
"下記にアクセスしてください\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 72 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 74 */
NULL,
},
#endif
@ -1704,6 +1713,9 @@ static void Usage(void)
#ifdef WOLFSSL_SYS_CA_CERTS
printf("%s", msg[++msgid]); /* --sys-ca-certs */
#endif
#ifdef HAVE_SUPPORTED_CURVES
printf("%s", msg[++msgid]); /* --onlyPskDheKe */
#endif
#ifdef WOLFSSL_SRTP
printf("%s", msg[++msgid]); /* dtls-srtp */
#endif
@ -1840,6 +1852,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#endif /* WOLFSSL_DTLS_CID */
#ifdef WOLFSSL_SYS_CA_CERTS
{ "sys-ca-certs", 0, 263 },
#endif
#ifdef HAVE_SUPPORTED_CURVES
{ "onlyPskDheKe", 0, 264 },
#endif
{ 0, 0, 0 }
};
@ -1928,6 +1943,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
int onlyKeyShare = 0;
#ifdef WOLFSSL_TLS13
int noPskDheKe = 0;
#ifdef HAVE_SUPPORTED_CURVES
int onlyPskDheKe = 0;
#endif
int postHandAuth = 0;
#endif
int updateKeysIVs = 0;
@ -2658,6 +2676,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
loadSysCaCerts = 1;
break;
#endif
case 264:
#ifdef HAVE_SUPPORTED_CURVES
#ifdef WOLFSSL_TLS13
onlyPskDheKe = 1;
#endif
#endif
break;
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -3377,6 +3402,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifdef WOLFSSL_TLS13
if (noPskDheKe)
wolfSSL_CTX_no_dhe_psk(ctx);
#ifdef HAVE_SUPPORTED_CURVES
if (onlyPskDheKe)
wolfSSL_CTX_only_dhe_psk(ctx);
#endif
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
if (postHandAuth)

View File

@ -947,11 +947,14 @@ static const char* server_usage_msg[][65] = {
" Leave <curve> blank to list all curves.\n"
" Note: requires TLS1.3\n",
/* 63 */
#endif
#ifdef HAVE_SUPPORTED_CURVES
"--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 64 */
#endif
"\n"
"For simpler wolfSSL TLS server examples, visit\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n",
/* 64 */
/* 65 */
NULL,
},
#ifndef NO_MULTIBYTE_PRINT
@ -1134,11 +1137,14 @@ static const char* server_usage_msg[][65] = {
" Leave <curve> blank to list all curves.\n"
" Note: requires TLS1.3\n",
/* 63 */
#endif
#ifdef HAVE_SUPPORTED_CURVES
"--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 64 */
#endif
"\n"
"より簡単なwolfSSL TSL クライアントの例については"
"下記にアクセスしてください\n"
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 64 */
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 65 */
NULL,
},
#endif
@ -1291,6 +1297,9 @@ static void Usage(void)
#endif
#ifdef CAN_FORCE_CURVE
printf("%s", msg[++msgId]); /* force-curve */
#endif
#ifdef HAVE_SUPPORTED_CURVES
printf("%s", msg[++msgId]); /* --onlyPskDheKe */
#endif
printf("%s", msg[++msgId]); /* Examples repo link */
}
@ -1399,6 +1408,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#ifdef WOLFSSL_DTLS_CID
{"cid", 2, 263},
#endif /* WOLFSSL_DTLS_CID */
#ifdef HAVE_SUPPORTED_CURVES
{"onlyPskDheKe", 2, 264},
#endif /* HAVE_SUPPORTED_CURVES */
{ 0, 0, 0 }
};
#endif
@ -1491,6 +1503,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
char buffer[WOLFSSL_MAX_ERROR_SZ];
#ifdef WOLFSSL_TLS13
int noPskDheKe = 0;
#ifdef HAVE_SUPPORTED_CURVES
int onlyPskDheKe = 0;
#endif
#endif
int updateKeysIVs = 0;
#ifndef NO_CERTS
@ -2258,6 +2273,14 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
}
break;
#endif /* WOLFSSL_CID */
case 264:
#ifdef HAVE_SUPPORTED_CURVES
#ifdef WOLFSSL_TLS13
onlyPskDheKe = 1;
#endif
#endif
break;
default:
Usage();
XEXIT_T(MY_EX_USAGE);
@ -2807,6 +2830,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#ifdef WOLFSSL_TLS13
if (noPskDheKe)
wolfSSL_CTX_no_dhe_psk(ctx);
#ifdef HAVE_SUPPORTED_CURVES
if (onlyPskDheKe)
wolfSSL_CTX_only_dhe_psk(ctx);
#endif
#endif
#ifdef HAVE_SESSION_TICKET
#ifdef WOLFSSL_TLS13

View File

@ -2358,9 +2358,11 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
ctx->maxEarlyDataSz = MAX_EARLY_DATA_SZ;
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#if defined(WOLFSSL_TLS13) && !defined(HAVE_SUPPORTED_CURVES)
ctx->noPskDheKe = 1;
#endif
#endif
#if defined(WOLFSSL_QT) && !defined(NO_PSK)
/* Qt retrieves supported cipher list at initialization
@ -6912,7 +6914,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#ifdef HAVE_SESSION_TICKET
ssl->options.noTicketTls13 = ctx->noTicketTls13;
#endif
ssl->options.noPskDheKe = ctx->noPskDheKe;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ssl->options.noPskDheKe = ctx->noPskDheKe;
ssl->options.onlyPskDheKe = ctx->onlyPskDheKe;
#endif
#if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
ssl->options.postHandshakeAuth = ctx->postHandshakeAuth;
ssl->options.verifyPostHandshake = ctx->verifyPostHandshake;

View File

@ -19662,7 +19662,10 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
ssl->options.haveSessionId = 0;
ssl->options.tls = 0;
ssl->options.tls1_1 = 0;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ssl->options.noPskDheKe = 0;
ssl->options.onlyPskDheKe = 0;
#endif
#ifdef HAVE_SESSION_TICKET
#ifdef WOLFSSL_TLS13
ssl->options.ticketsSent = 0;

View File

@ -12137,15 +12137,21 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
if (usingPSK)
#endif
{
byte modes;
byte modes = 0;
(void)usingPSK;
/* Pre-shared key modes: mandatory extension for resumption. */
modes = 1 << PSK_KE;
#ifdef HAVE_SUPPORTED_CURVES
if (!ssl->options.onlyPskDheKe)
#endif
{
modes = 1 << PSK_KE;
}
#if !defined(NO_DH) || defined(HAVE_ECC) || \
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
if (!ssl->options.noPskDheKe)
if (!ssl->options.noPskDheKe) {
modes |= 1 << PSK_DHE_KE;
}
#endif
ret = TLSX_PskKeModes_Use(ssl, modes);
if (ret != 0)
@ -12661,8 +12667,12 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore,
TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
#ifdef HAVE_SUPPORTED_CURVES
if (!ssl->options.noPskDheKe) {
#if defined(HAVE_SUPPORTED_CURVES)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (!ssl->options.noPskDheKe)
#endif
{
/* Expect KeyShare extension in ServerHello. */
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
}
#endif
@ -12691,8 +12701,13 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
#ifdef HAVE_SUPPORTED_CURVES
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (!ssl->options.noPskDheKe)
#endif
{
/* Expect KeyShare extension in HelloRetryRequest. */
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
}
#endif
#ifdef WOLFSSL_SEND_HRR_COOKIE
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
@ -12797,8 +12812,13 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
TURN_OFF(semaphore,
TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
#ifdef HAVE_SUPPORTED_CURVES
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (!ssl->options.noPskDheKe)
#endif
{
/* Write out KeyShare in ServerHello. */
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
}
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
@ -12825,8 +12845,13 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
#ifdef HAVE_SUPPORTED_CURVES
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (!ssl->options.noPskDheKe)
#endif
{
/* Write out KeyShare in HelloRetryRequest. */
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
}
#endif
/* Cookie is written below as last extension. */
break;

View File

@ -3564,7 +3564,7 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
/* Resumption PSK is master secret. */
ssl->arrays->psk_keySz = ssl->specs.hash_size;
if ((ret = DeriveResumptionPSK(ssl, ssl->session->ticketNonce.data,
ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) {
ssl->session->ticketNonce.len, ssl->arrays->psk_key)) != 0) {
return ret;
}
if (!clientHello) {
@ -5479,6 +5479,8 @@ static int FindPsk(WOLFSSL* ssl, PreSharedKey* psk, const byte* suite, int* err)
byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
Arrays* sa = ssl->arrays;
(void)suite;
if (ssl->options.server_psk_tls13_cb != NULL) {
sa->psk_keySz = ssl->options.server_psk_tls13_cb(ssl,
sa->client_identity, sa->psk_key, MAX_PSK_KEY_LEN, &cipherName);
@ -5571,6 +5573,8 @@ static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 inputSz,
WOLFSSL_ENTER("DoPreSharedKeys");
(void)suite;
ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
if (ext == NULL) {
WOLFSSL_MSG("No pre shared extension keys found");
@ -5904,6 +5908,7 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
}
modes = ext->val;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifdef HAVE_SUPPORTED_CURVES
ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
/* Use (EC)DHE for forward-security if possible. */
@ -5914,6 +5919,9 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
*usingPSK = 2; /* generate new ephemeral key */
}
else if (ssl->options.onlyPskDheKe) {
return PSK_KEY_ERROR;
}
else
#endif
{
@ -5927,6 +5935,7 @@ static int CheckPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
*usingPSK = 1;
}
#endif
}
#ifdef WOLFSSL_PSK_ID_PROTECTION
else {
@ -6586,8 +6595,10 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (!args->usingPSK)
#endif
{
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Not using PSK so don't require no KE. */
ssl->options.noPskDheKe = 0;
#endif
#ifndef NO_CERTS
if (TLSX_Find(ssl->extensions, TLSX_KEY_SHARE) == NULL) {
@ -11896,7 +11907,9 @@ int wolfSSL_CTX_no_dhe_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->noPskDheKe = 1;
#endif
return 0;
}
@ -11912,11 +11925,49 @@ int wolfSSL_no_dhe_psk(WOLFSSL* ssl)
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ssl->options.noPskDheKe = 1;
#endif
return 0;
}
#ifdef HAVE_SUPPORTED_CURVES
/* Only allow (EC)DHE key exchange when using pre-shared keys.
*
* ctx The SSL/TLS CTX object.
* returns BAD_FUNC_ARG when ctx is NULL and 0 on success.
*/
int wolfSSL_CTX_only_dhe_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->onlyPskDheKe = 1;
#endif
return 0;
}
/* Only allow (EC)DHE key exchange when using pre-shared keys.
*
* ssl The SSL/TLS object.
* returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3 and 0 on
* success.
*/
int wolfSSL_only_dhe_psk(WOLFSSL* ssl)
{
if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
return BAD_FUNC_ARG;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ssl->options.onlyPskDheKe = 1;
#endif
return 0;
}
#endif /* HAVE_SUPPORTED_CURVES */
int Tls13UpdateKeys(WOLFSSL* ssl)
{
@ -12735,13 +12786,15 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
FALL_THROUGH;
case TLS13_ACCEPT_THIRD_REPLY_DONE :
#ifdef HAVE_SUPPORTED_CURVES
if (!ssl->options.noPskDheKe) {
#if defined(HAVE_SUPPORTED_CURVES) && (defined(HAVE_SESSION_TICKET) || \
!defined(NO_PSK))
if (!ssl->options.noPskDheKe)
#endif
{
ssl->error = TLSX_KeyShare_DeriveSecret(ssl);
if (ssl->error != 0)
return WOLFSSL_FATAL_ERROR;
}
#endif
if ((ssl->error = SendTls13EncryptedExtensions(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error);

View File

@ -45,6 +45,36 @@
-s
-l TLS13-AES256-GCM-SHA384
# server TLSv1.3 PSK
# AES256-GCM and SHA384
-v 4
-s
-l TLS13-AES256-GCM-SHA384
-d
-K
# client TLSv1.3 PSK
# AES256-GCM and SHA384
-v 4
-s
-l TLS13-AES256-GCM-SHA384
-K
# server TLSv1.3 PSK
# AES256-GCM and SHA384
-v 4
-s
-l TLS13-AES256-GCM-SHA384
-d
--onlyPskDheKe
# client TLSv1.3 PSK
# AES256-GCM and SHA384
-v 4
-s
-l TLS13-AES256-GCM-SHA384
--onlyPskDheKe
# Disabling ChaCha20 results in failures.
# server TLSv1.3 PSK
# CHACHA20 only supported

View File

@ -3249,8 +3249,13 @@ struct WOLFSSL_CTX {
unsigned int maxTicketTls13; /* maximum number of tickets to send */
#endif
byte noTicketTls13:1; /* TLS 1.3 Server won't create new Ticket */
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
byte noPskDheKe:1; /* Don't use (EC)DHE with PSK */
#ifdef HAVE_SUPPORTED_CURVES
byte onlyPskDheKe:1; /* Only use (EC)DHE with PSK */
#endif
#endif
#endif /* WOLFSSL_TLS13 */
byte mutualAuth:1; /* Mutual authentication required */
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
byte postHandshakeAuth:1; /* Post-handshake auth supported. */
@ -4232,7 +4237,12 @@ typedef struct Options {
word16 havePeerVerify:1; /* and peer's cert verify */
word16 usingPSK_cipher:1; /* are using psk as cipher */
word16 usingAnon_cipher:1; /* are we using an anon cipher */
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
word16 noPskDheKe:1; /* Don't use (EC)DHE with PSK */
#ifdef HAVE_SUPPORTED_CURVES
word16 onlyPskDheKe:1; /* Only use (EC)DHE with PSK */
#endif
#endif
word16 partialWrite:1; /* only one msg per write call */
word16 quietShutdown:1; /* don't send close notify */
word16 certOnly:1; /* stop once we get cert */

View File

@ -1172,6 +1172,8 @@ WOLFSSL_API int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx);
WOLFSSL_API int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl);
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_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);