From b9942440110819bde928c11782cba1f7a069b80c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 9 Sep 2016 23:16:52 -0700 Subject: [PATCH] Revising the Extended Master Secret support. Removing the dynamic TLSX support for the extention and treating it like the Signature and Hash algorithms extension. It is to be enabled by default and the user can turn it off at run time or build time. --- configure.ac | 9 +-- examples/client/client.c | 12 +-- src/internal.c | 165 +++++++++++++++++++++++++++++++++------ src/sniffer.c | 4 + src/ssl.c | 31 +++++--- src/tls.c | 121 ++++++++++++---------------- tests/api.c | 12 +-- tests/suites.c | 38 +++++++-- wolfssl/internal.h | 17 ++-- wolfssl/ssl.h | 9 +-- 10 files changed, 271 insertions(+), 147 deletions(-) diff --git a/configure.ac b/configure.ac index 853e71a0b..ba4d2f3ef 100644 --- a/configure.ac +++ b/configure.ac @@ -1959,14 +1959,14 @@ fi # Extended Master Secret Extension AC_ARG_ENABLE([extended-master], - [AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: disabled)])], + [AS_HELP_STRING([--enable-extended-master],[Enable Extended Master Secret (default: enabled)])], [ ENABLED_EXTENDED_MASTER=$enableval ], - [ ENABLED_EXTENDED_MASTER=no ] + [ ENABLED_EXTENDED_MASTER=yes ] ) if test "x$ENABLED_EXTENDED_MASTER" = "xyes" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_EXTENDED_MASTER" + AM_CFLAGS="$AM_CFLAGS -DHAVE_EXTENDED_MASTER" fi # TLS Extensions @@ -1983,8 +1983,7 @@ then ENABLED_TRUNCATED_HMAC=yes ENABLED_SUPPORTED_CURVES=yes ENABLED_ALPN=yes - ENABLED_EXTENDED_MASTER=yes - AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN -DHAVE_EXTENDED_MASTER" + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT -DHAVE_TRUNCATED_HMAC -DHAVE_SUPPORTED_CURVES -DHAVE_ALPN" fi # PKCS7 diff --git a/examples/client/client.c b/examples/client/client.c index 2129f0247..14ef26245 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -495,7 +495,7 @@ static void Usage(void) printf("-T Use Truncated HMAC\n"); #endif #ifdef HAVE_EXTENDED_MASTER - printf("-n Use Extended Master Secret\n"); + printf("-n Disable Extended Master Secret\n"); #endif #ifdef HAVE_OCSP printf("-o Perform OCSP lookup on peer certificate\n"); @@ -613,7 +613,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) byte statusRequest = 0; #endif #ifdef HAVE_EXTENDED_MASTER - byte extMasterSecret = 0; + byte disableExtMasterSecret = 0; #endif @@ -865,7 +865,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) case 'n' : #ifdef HAVE_EXTENDED_MASTER - extMasterSecret = 1; + disableExtMasterSecret = 1; #endif break; @@ -1246,9 +1246,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("UseSessionTicket failed"); #endif #ifdef HAVE_EXTENDED_MASTER - if (extMasterSecret) - if (wolfSSL_CTX_UseExtendedMasterSecret(ctx) != SSL_SUCCESS) - err_sys("UseExtendedMasterSecret failed"); + if (disableExtMasterSecret) + if (wolfSSL_CTX_DisableExtendedMasterSecret(ctx) != SSL_SUCCESS) + err_sys("DisableExtendedMasterSecret failed"); #endif if (benchmark) { diff --git a/src/internal.c b/src/internal.c index e9556a142..2c3895f16 100755 --- a/src/internal.c +++ b/src/internal.c @@ -1401,6 +1401,20 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) } #endif +#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) + if (method->side == WOLFSSL_CLIENT_END) { + if ((method->version.major == SSLv3_MAJOR) && + (method->version.minor >= TLSv1_MINOR)) { + + ctx->haveEMS = 1; + } +#ifdef WOLFSSL_DTLS + if (method->version.major == DTLS_MAJOR) + ctx->haveEMS = 1; +#endif /* WOLFSSL_DTLS */ + } +#endif /* HAVE_EXTENDED_MASTER && !NO_WOLFSSL_CLIENT */ + #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT; #endif @@ -3375,6 +3389,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) ssl->cipher.ssl = ssl; +#ifdef HAVE_EXTENDED_MASTER + ssl->options.haveEMS = ctx->haveEMS; +#endif + #ifdef HAVE_TLS_EXTENSIONS #ifdef HAVE_MAX_FRAGMENT ssl->max_fragment = MAX_RECORD_SIZE; @@ -12681,6 +12699,7 @@ static void PickHashSigAlgo(WOLFSSL* ssl, ? ssl->session.sessionIDSz : 0; int ret; + word16 extSz = 0; if (ssl->suites == NULL) { WOLFSSL_MSG("Bad suites pointer in SendClientHello"); @@ -12714,11 +12733,19 @@ static void PickHashSigAlgo(WOLFSSL* ssl, if (QSH_Init(ssl) != 0) return MEMORY_E; #endif - length += TLSX_GetRequestSize(ssl); + extSz = TLSX_GetRequestSize(ssl); + if (extSz != 0) + length += extSz; #else - if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) { - length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ; - } + if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) + extSz += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ + + ssl->suites->hashSigAlgoSz; +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) + extSz += HELLO_EXT_SZ; +#endif + if (extSz != 0) + length += extSz + HELLO_EXT_SZ_SZ; #endif sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; @@ -12803,24 +12830,36 @@ static void PickHashSigAlgo(WOLFSSL* ssl, (void)idx; /* suppress analyzer warning, keep idx current */ #else - if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) - { - int i; - /* add in the extensions length */ - c16toa((word16)(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz), - output + idx); - idx += 2; + if (extSz != 0) { + c16toa(extSz, output + idx); + idx += HELLO_EXT_SZ_SZ; - c16toa(HELLO_EXT_SIG_ALGO, output + idx); - idx += 2; - c16toa((word16)(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz), - output+idx); - idx += 2; - c16toa(ssl->suites->hashSigAlgoSz, output + idx); - idx += 2; - for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) { - output[idx] = ssl->suites->hashSigAlgo[i]; + if (IsAtLeastTLSv1_2(ssl)) { + if (ssl->suites->hashSigAlgoSz) { + int i; + /* extension type */ + c16toa(HELLO_EXT_SIG_ALGO, output + idx); + idx += HELLO_EXT_TYPE_SZ; + /* extension data length */ + c16toa(HELLO_EXT_SIGALGO_SZ + ssl->suites->hashSigAlgoSz, + output + idx); + idx += HELLO_EXT_SZ_SZ; + /* sig algos length */ + c16toa(ssl->suites->hashSigAlgoSz, output + idx); + idx += HELLO_EXT_SIGALGO_SZ; + for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) { + output[idx] = ssl->suites->hashSigAlgo[i]; + } + } } +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_EXTMS, output + idx); + idx += HELLO_EXT_TYPE_SZ; + c16toa(0, output + idx); + idx += HELLO_EXT_SZ_SZ; + } +#endif } #endif @@ -13058,9 +13097,8 @@ static void PickHashSigAlgo(WOLFSSL* ssl, *inOutIdx = i; - - if ( (i - begin) < helloSz) { #ifdef HAVE_TLS_EXTENSIONS + if ( (i - begin) < helloSz) { if (TLSX_SupportExtensions(ssl)) { int ret = 0; word16 totalExtSz; @@ -13082,9 +13120,70 @@ static void PickHashSigAlgo(WOLFSSL* ssl, *inOutIdx = i; } else -#endif *inOutIdx = begin + helloSz; /* skip extensions */ } + else + ssl->options.haveEMS = 0; /* If no extensions, no EMS */ +#else + { + int allowExt = 0; + byte pendingEMS = 0; + + if ( (i - begin) < helloSz) { + if (ssl->version.major == SSLv3_MAJOR && + ssl->version.minor >= TLSv1_MINOR) { + + allowExt = 1; + } +#ifdef WOLFSSL_DTLS + if (ssl->version.major == DTLS_MAJOR) + allowExt = 1; +#endif + + if (allowExt) { + word16 totalExtSz; + + if ((i - begin) + OPAQUE16_LEN > helloSz) + return BUFFER_ERROR; + + ato16(&input[i], &totalExtSz); + i += OPAQUE16_LEN; + + if ((i - begin) + totalExtSz > helloSz) + return BUFFER_ERROR; + + while (totalExtSz) { + word16 extId, extSz; + + if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz) + return BUFFER_ERROR; + + ato16(&input[i], &extId); + i += OPAQUE16_LEN; + ato16(&input[i], &extSz); + i += OPAQUE16_LEN; + + if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz) + return BUFFER_ERROR; + + if (extId == HELLO_EXT_EXTMS) + pendingEMS = 1; + else + i += extSz; + + totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz; + } + + *inOutIdx = i; + } + else + *inOutIdx = begin + helloSz; /* skip extensions */ + } + + if (!pendingEMS && ssl->options.haveEMS) + ssl->options.haveEMS = 0; + } +#endif ssl->options.serverState = SERVER_HELLO_COMPLETE; @@ -15979,6 +16078,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, length -= (ID_LEN - sessIdSz); /* adjust ID_LEN assumption */ } #endif /* HAVE_SESSION_TICKET */ +#else + if (ssl->options.haveEMS) { + length += HELLO_EXT_SZ_SZ + HELLO_EXT_SZ; + } #endif /* check for avalaible size */ @@ -16052,6 +16155,18 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* last, extensions */ #ifdef HAVE_TLS_EXTENSIONS TLSX_WriteResponse(ssl, output + idx); +#else +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_SZ, output + idx); + idx += HELLO_EXT_SZ_SZ; + + c16toa(HELLO_EXT_EXTMS, output + idx); + idx += HELLO_EXT_TYPE_SZ; + c16toa(0, output + idx); + idx += HELLO_EXT_SZ_SZ; + } +#endif #endif ssl->buffers.outputBuffer.length += sendSz; @@ -18155,6 +18270,10 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX) clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX; } +#ifdef HAVE_EXTENDED_MASTER + else if (extId == HELLO_EXT_EXTMS) + ssl->options.haveEMS = 1; +#endif else i += extSz; diff --git a/src/sniffer.c b/src/sniffer.c index bcef1f9c5..d2d94e1a9 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -2130,6 +2130,10 @@ static int DoHandShake(const byte* input, int* sslBytes, free(session->hash); session->hash = NULL; } + else { + session->sslServer->options.haveEMS = 0; + session->sslClient->options.haveEMS = 0; + } #endif ret = ProcessClientKeyExchange(input, sslBytes, session, error); break; diff --git a/src/ssl.c b/src/ssl.c index 2e99b5b6e..c6cc0d696 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1749,27 +1749,34 @@ WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl, } #endif + #ifdef HAVE_EXTENDED_MASTER #ifndef NO_WOLFSSL_CLIENT -int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl) -{ - if (ssl == NULL) - return BAD_FUNC_ARG; - - return TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap); -} - -int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx) +int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx) { if (ctx == NULL) return BAD_FUNC_ARG; - return TLSX_UseExtendedMasterSecret(&ctx->extensions, ctx->heap); + ctx->haveEMS = 0; + + return SSL_SUCCESS; } -#endif /* NO_WOLFSSL_CLIENT */ -#endif /* HAVE_EXTENDED_MASTER */ + +int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + ssl->options.haveEMS = 0; + + return SSL_SUCCESS; +} + +#endif +#endif + #ifndef WOLFSSL_LEANPSK diff --git a/src/tls.c b/src/tls.c index 4e6511d38..648147c2a 100644 --- a/src/tls.c +++ b/src/tls.c @@ -3942,58 +3942,6 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, #endif /* HAVE_QSH */ -/******************************************************************************/ -/* TLS Extended Master Secret */ -/******************************************************************************/ - -#ifdef HAVE_EXTENDED_MASTER - -static int TLSX_EMS_Parse(WOLFSSL* ssl, byte* input, word16 length, - byte isRequest) -{ - (void)isRequest; - - if (length != 0 || input == NULL) - return BUFFER_ERROR; - -#ifndef NO_WOLFSSL_SERVER - if (isRequest) { - int r = TLSX_UseExtendedMasterSecret(&ssl->extensions, ssl->heap); - - if (r != SSL_SUCCESS) - return r; /* throw error */ - - TLSX_SetResponse(ssl, TLSX_EXTENDED_MASTER_SECRET); - } -#endif - - ssl->options.haveEMS = 1; - - return 0; -} - -int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap) -{ - int ret = 0; - - if (extensions == NULL) - return BAD_FUNC_ARG; - - if ((ret = TLSX_Push(extensions, TLSX_EXTENDED_MASTER_SECRET, NULL, - heap)) != 0) - return ret; - - return SSL_SUCCESS; -} - -#define EMS_PARSE TLSX_EMS_Parse - -#else - -#define EMS_PARSE(a, b, c, d) 0 - -#endif /* HAVE_EXTENDED_MASTER */ - /******************************************************************************/ /* TLS Extensions Framework */ /******************************************************************************/ @@ -4043,10 +3991,6 @@ void TLSX_FreeAll(TLSX* list, void* heap) CSR2_FREE_ALL(extension->data, heap); break; - case TLSX_EXTENDED_MASTER_SECRET: - /* Nothing to do. */ - break; - case TLSX_RENEGOTIATION_INFO: SCR_FREE_ALL(extension->data, heap); break; @@ -4124,10 +4068,6 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest) length += CSR2_GET_SIZE(extension->data, isRequest); break; - case TLSX_EXTENDED_MASTER_SECRET: - /* always empty. */ - break; - case TLSX_RENEGOTIATION_INFO: length += SCR_GET_SIZE(extension->data, isRequest); break; @@ -4207,10 +4147,6 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore, isRequest); break; - case TLSX_EXTENDED_MASTER_SECRET: - /* always empty. */ - break; - case TLSX_RENEGOTIATION_INFO: offset += SCR_WRITE(extension->data, output + offset, isRequest); @@ -4552,7 +4488,13 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl) length += TLSX_GetSize(ssl->ctx->extensions, semaphore, 1); if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) - length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN; + length += HELLO_EXT_SZ + HELLO_EXT_SIGALGO_SZ + + ssl->suites->hashSigAlgoSz; + +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) + length += HELLO_EXT_SZ; +#endif } if (length) @@ -4583,15 +4525,15 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output) offset += TLSX_Write(ssl->ctx->extensions, output + offset, semaphore, 1); - if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) - { + if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) { int i; /* extension type */ c16toa(HELLO_EXT_SIG_ALGO, output + offset); offset += HELLO_EXT_TYPE_SZ; /* extension data length */ - c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset); + c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, + output + offset); offset += OPAQUE16_LEN; /* sig algos length */ @@ -4603,6 +4545,15 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output) output[offset] = ssl->suites->hashSigAlgo[i]; } +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_EXTMS, output + offset); + offset += HELLO_EXT_TYPE_SZ; + c16toa(0, output + offset); + offset += HELLO_EXT_SZ_SZ; + } +#endif + if (offset > OPAQUE16_LEN) c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ } @@ -4629,13 +4580,18 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl) } #endif +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) + length += HELLO_EXT_SZ; +#endif + if (TLSX_SupportExtensions(ssl)) length += TLSX_GetSize(ssl->extensions, semaphore, 0); /* All the response data is set at the ssl object only, so no ctx here. */ if (length) - length += OPAQUE16_LEN; /* for total length storage */ + length += OPAQUE16_LEN; /* for total length storage. */ return length; } @@ -4652,6 +4608,15 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output) offset += TLSX_Write(ssl->extensions, output + offset, semaphore, 0); +#ifdef HAVE_EXTENDED_MASTER + if (ssl->options.haveEMS) { + c16toa(HELLO_EXT_EXTMS, output + offset); + offset += HELLO_EXT_TYPE_SZ; + c16toa(0, output + offset); + offset += HELLO_EXT_SZ_SZ; + } +#endif + if (offset > OPAQUE16_LEN) c16toa(offset - OPAQUE16_LEN, output); /* extensions length */ } @@ -4667,6 +4632,9 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, { int ret = 0; word16 offset = 0; +#ifdef HAVE_EXTENDED_MASTER + byte pendingEMS = 0; +#endif if (!ssl || !input || (isRequest && !suites)) return BAD_FUNC_ARG; @@ -4724,11 +4692,17 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, ret = CSR2_PARSE(ssl, input + offset, size, isRequest); break; - case TLSX_EXTENDED_MASTER_SECRET: +#ifdef HAVE_EXTENDED_MASTER + case HELLO_EXT_EXTMS: WOLFSSL_MSG("Extended Master Secret extension received"); - ret = EMS_PARSE(ssl, input + offset, size, isRequest); +#ifndef NO_WOLFSSL_SERVER + if (isRequest) + ssl->options.haveEMS = 1; +#endif + pendingEMS = 1; break; +#endif case TLSX_RENEGOTIATION_INFO: WOLFSSL_MSG("Secure Renegotiation extension received"); @@ -4779,6 +4753,11 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte isRequest, offset += size; } +#ifdef HAVE_EXTENDED_MASTER + if (!isRequest && ssl->options.haveEMS && !pendingEMS) + ssl->options.haveEMS = 0; +#endif + if (ret == 0) ret = SNI_VERIFY_PARSE(ssl, isRequest); diff --git a/tests/api.c b/tests/api.c index ef8f982f2..b5d348ca0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1927,7 +1927,7 @@ static void test_wolfSSL_UseALPN(void) #endif } -static void test_wolfSSL_UseExtendedMasterSecret(void) +static void test_wolfSSL_DisableExtendedMasterSecret(void) { #ifdef HAVE_EXTENDED_MASTER WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); @@ -1937,12 +1937,12 @@ static void test_wolfSSL_UseExtendedMasterSecret(void) AssertNotNull(ssl); /* error cases */ - AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseExtendedMasterSecret(NULL)); - AssertIntNE(SSL_SUCCESS, wolfSSL_UseExtendedMasterSecret(NULL)); + AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL)); + AssertIntNE(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL)); /* success cases */ - AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseExtendedMasterSecret(ctx)); - AssertIntEQ(SSL_SUCCESS, wolfSSL_UseExtendedMasterSecret(ssl)); + AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx)); + AssertIntEQ(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl)); wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); @@ -2151,7 +2151,7 @@ void ApiTest(void) test_wolfSSL_UseTruncatedHMAC(); test_wolfSSL_UseSupportedCurve(); test_wolfSSL_UseALPN(); - test_wolfSSL_UseExtendedMasterSecret(); + test_wolfSSL_DisableExtendedMasterSecret(); /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); diff --git a/tests/suites.c b/tests/suites.c index bc700d00e..f23c116cc 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -48,6 +48,7 @@ static WOLFSSL_CTX* cipherSuiteCtx = NULL; static char nonblockFlag[] = "-N"; static char noVerifyFlag[] = "-d"; +static char disableEMSFlag[] = "-n"; static char flagSep[] = " "; #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) static char portFlag[] = "-p"; @@ -153,7 +154,8 @@ static int IsValidCipherSuite(const char* line, char* suite) static int execute_test_case(int svr_argc, char** svr_argv, int cli_argc, char** cli_argv, - int addNoVerify, int addNonBlocking) + int addNoVerify, int addNonBlocking, + int addDisableEMS) { #ifdef WOLFSSL_TIRTOS func_args cliArgs = {0}; @@ -270,6 +272,18 @@ static int execute_test_case(int svr_argc, char** svr_argv, cliArgs.argc = cli_argc; } } + if (addDisableEMS) { + printf("repeating test without extended master secret\n"); + added += 4; /* -n plus terminator */ + if (added >= MAX_COMMAND_SZ) + printf("client command line too long\n"); + else { + cli_argv[cli_argc++] = disableEMSFlag; + strcat(commandLine, disableEMSFlag); + strcat(commandLine, flagSep); + cliArgs.argc = cli_argc; + } + } printf("trying client command line[%d]: %s\n", tests++, commandLine); InitTcpReady(&ready); @@ -437,12 +451,26 @@ static void test_harness(void* vargs) } if (do_it) { - ret = execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs,0,0); + ret = execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 0, 0); /* don't repeat if not supported in build */ if (ret == 0) { - execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 0, 1); - execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 0); - execute_test_case(svrArgsSz, svrArgs, cliArgsSz, cliArgs, 1, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 1, 0); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 0, 0); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 1, 0); +#ifdef HAVE_EXTENDED_MASTER + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 0, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 0, 1, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 0, 1); + execute_test_case(svrArgsSz, svrArgs, + cliArgsSz, cliArgs, 1, 1, 1); +#endif } svrArgsSz = 1; cliArgsSz = 1; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 49ca05821..5f67dc33e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -878,6 +878,7 @@ enum Misc { NO_COMPRESSION = 0, ZLIB_COMPRESSION = 221, /* wolfSSL zlib compression */ HELLO_EXT_SIG_ALGO = 13, /* ID for the sig_algo hello extension */ + HELLO_EXT_EXTMS = 0x0017, /* ID for the extended master secret ext */ SECRET_LEN = 48, /* pre RSA and all master */ #if defined(WOLFSSL_MYSQL_COMPATIBLE) ENCRYPT_LEN = 1024, /* allow larger static buffer with mysql */ @@ -939,10 +940,10 @@ enum Misc { REQ_HEADER_SZ = 2, /* cert request header sz */ HINT_LEN_SZ = 2, /* length of hint size field */ TRUNCATED_HMAC_SZ = 10, /* length of hmac w/ truncated hmac extension */ + HELLO_EXT_SZ = 4, /* base length of a hello extension */ HELLO_EXT_TYPE_SZ = 2, /* length of a hello extension type */ - HELLO_EXT_SZ = 8, /* total length of the lazy hello extensions */ - HELLO_EXT_LEN = 6, /* length of the lazy hello extensions */ - HELLO_EXT_SIGALGO_SZ = 2, /* length of signature algo extension */ + HELLO_EXT_SZ_SZ = 2, /* length of a hello extension size */ + HELLO_EXT_SIGALGO_SZ = 2, /* length of number of items in sigalgo list */ HELLO_EXT_SIGALGO_MAX = 32, /* number of items in the signature algo list */ DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */ @@ -1645,7 +1646,6 @@ typedef enum { TLSX_SUPPORTED_GROUPS = 0x000a, /* a.k.a. Supported Curves */ TLSX_APPLICATION_LAYER_PROTOCOL = 0x0010, /* a.k.a. ALPN */ TLSX_STATUS_REQUEST_V2 = 0x0011, /* a.k.a. OCSP stapling v2 */ - TLSX_EXTENDED_MASTER_SECRET = 0x0017, TLSX_QUANTUM_SAFE_HYBRID = 0x0018, /* a.k.a. QSH */ TLSX_SESSION_TICKET = 0x0023, TLSX_RENEGOTIATION_INFO = 0xff01 @@ -1899,14 +1899,6 @@ WOLFSSL_LOCAL int TLSX_ValidateQSHScheme(TLSX** extensions, word16 name); #endif /* HAVE_QSH */ -/* TLS Extended Master Secret, RFC 7627 */ -#ifdef HAVE_EXTENDED_MASTER - -WOLFSSL_LOCAL int TLSX_UseExtendedMasterSecret(TLSX** extensions, void* heap); - -#endif - - /* wolfSSL context type */ struct WOLFSSL_CTX { WOLFSSL_METHOD* method; @@ -1946,6 +1938,7 @@ struct WOLFSSL_CTX { byte quietShutdown; /* don't send close notify */ byte groupMessages; /* group handshake messages before sending */ byte minDowngrade; /* minimum downgrade version */ + byte haveEMS; /* have extended master secret extension */ #if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) byte dtlsSctp; /* DTLS-over-SCTP mode */ word16 dtlsMtuSz; /* DTLS MTU size */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index be86237ea..e83749cd2 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1705,14 +1705,9 @@ WOLFSSL_API int wolfSSL_UseSupportedQSH(WOLFSSL* ssl, unsigned short name); #endif /* TLS Extended Master Secret Extension */ -#ifdef HAVE_EXTENDED_MASTER -#ifndef NO_WOLFSSL_CLIENT +WOLFSSL_API int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx); -WOLFSSL_API int wolfSSL_UseExtendedMasterSecret(WOLFSSL* ssl); -WOLFSSL_API int wolfSSL_CTX_UseExtendedMasterSecret(WOLFSSL_CTX* ctx); - -#endif /* NO_WOLFSSL_CLIENT */ -#endif /* HAVE_EXTENDED_MASTER */ #define WOLFSSL_CRL_MONITOR 0x01 /* monitor this dir flag */ #define WOLFSSL_CRL_START_MON 0x02 /* start monitoring flag */