From 01f4a7b5bdea2515461210fab147fcac15a23c67 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 18 Jan 2017 11:54:43 -0800 Subject: [PATCH 1/2] Added code to automatically populate supported ECC curve information, unless already provided by user via wolfSSL_CTX_UseSupportedCurve or wolfSSL_UseSupportedCurve. --- examples/client/client.c | 4 + src/internal.c | 3 + src/ssl.c | 4 + src/tls.c | 227 ++++++++++++++++++++++++++------------- wolfssl/internal.h | 6 ++ 5 files changed, 169 insertions(+), 75 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 68625f020..71c86da12 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1340,6 +1340,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_KeepArrays(ssl); #endif + #if 0 /* all enabled and supported ECC curves will be added automatically */ #ifdef HAVE_SUPPORTED_CURVES /* add curves to supported curves extension */ if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1) != SSL_SUCCESS) { @@ -1378,6 +1379,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("unable to set curve secp160r1"); } #endif + #endif #ifdef HAVE_SESSION_TICKET wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); @@ -1732,6 +1734,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB, (void*)"resumed session"); #endif + #if 0 /* all enabled and supported ECC curves will be added automatically */ #ifdef HAVE_SUPPORTED_CURVES /* add curves to supported curves extension */ if (wolfSSL_UseSupportedCurve(sslResume, WOLFSSL_ECC_SECP256R1) != SSL_SUCCESS) { @@ -1770,6 +1773,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("unable to set curve secp160r1"); } #endif + #endif #ifndef WOLFSSL_CALLBACKS if (nonBlocking) { diff --git a/src/internal.c b/src/internal.c index 1ee94d260..892515ec0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3487,6 +3487,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #ifdef HAVE_ALPN ssl->alpn_client_list = NULL; #endif +#ifdef HAVE_SUPPORTED_CURVES + ssl->options.userCurves = ctx->userCurves; +#endif #endif /* HAVE_TLS_EXTENSIONS */ /* default alert state (none) */ diff --git a/src/ssl.c b/src/ssl.c index 26a4bdb76..9d47257bf 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1401,6 +1401,8 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name) return BAD_FUNC_ARG; } + ssl->options.userCurves = 1; + return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap); } @@ -1431,6 +1433,8 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name) return BAD_FUNC_ARG; } + ctx->userCurves = 1; + return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap); } diff --git a/src/tls.c b/src/tls.c index 7fdb9ce03..27114aa60 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4479,99 +4479,176 @@ static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name) int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) { + int ret = 0; byte* public_key = NULL; word16 public_key_len = 0; - #ifdef HAVE_QSH - TLSX* extension; - QSHScheme* qsh; - QSHScheme* next; - #endif - int ret = 0; +#ifdef HAVE_QSH + TLSX* extension; + QSHScheme* qsh; + QSHScheme* next; - #ifdef HAVE_QSH - /* add supported QSHSchemes */ - WOLFSSL_MSG("Adding supported QSH Schemes"); + /* add supported QSHSchemes */ + WOLFSSL_MSG("Adding supported QSH Schemes"); +#endif - /* server will add extension depending on whats parsed from client */ - if (!isServer) { + /* server will add extension depending on whats parsed from client */ + if (!isServer) { - /* test if user has set a specific scheme already */ - if (!ssl->user_set_QSHSchemes) { - if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { - if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) { - WOLFSSL_MSG("Error creating ntru keys"); - return ret; - } - if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) { - WOLFSSL_MSG("Error creating ntru keys"); - return ret; - } - if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) { - WOLFSSL_MSG("Error creating ntru keys"); - return ret; - } +#ifdef HAVE_QSH + /* test if user has set a specific scheme already */ + if (!ssl->user_set_QSHSchemes) { + if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { + if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS743)) != 0) { + WOLFSSL_MSG("Error creating ntru keys"); + return ret; + } + if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS593)) != 0) { + WOLFSSL_MSG("Error creating ntru keys"); + return ret; + } + if ((ret = TLSX_CreateQSHKey(ssl, WOLFSSL_NTRU_EESS439)) != 0) { + WOLFSSL_MSG("Error creating ntru keys"); + return ret; + } - /* add NTRU 256 */ + /* add NTRU 256 */ + public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, + &public_key_len, WOLFSSL_NTRU_EESS743); + } + if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743, + public_key, public_key_len, ssl->heap) + != SSL_SUCCESS) + ret = -1; + + /* add NTRU 196 */ + if (ssl->sendQSHKeys) { public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, - &public_key_len, WOLFSSL_NTRU_EESS743); - } - if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS743, - public_key, public_key_len, ssl->heap) - != SSL_SUCCESS) - ret = -1; - - /* add NTRU 196 */ - if (ssl->sendQSHKeys) { - public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, - &public_key_len, WOLFSSL_NTRU_EESS593); - } - if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593, - public_key, public_key_len, ssl->heap) - != SSL_SUCCESS) - ret = -1; - - /* add NTRU 128 */ - if (ssl->sendQSHKeys) { - public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, - &public_key_len, WOLFSSL_NTRU_EESS439); - } - if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439, - public_key, public_key_len, ssl->heap) - != SSL_SUCCESS) - ret = -1; + &public_key_len, WOLFSSL_NTRU_EESS593); } - else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { - /* for each scheme make a client key */ - extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); - if (extension) { - qsh = (QSHScheme*)extension->data; + if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS593, + public_key, public_key_len, ssl->heap) + != SSL_SUCCESS) + ret = -1; - while (qsh) { - if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0) - return ret; + /* add NTRU 128 */ + if (ssl->sendQSHKeys) { + public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, + &public_key_len, WOLFSSL_NTRU_EESS439); + } + if (TLSX_UseQSHScheme(&ssl->extensions, WOLFSSL_NTRU_EESS439, + public_key, public_key_len, ssl->heap) + != SSL_SUCCESS) + ret = -1; + } + else if (ssl->sendQSHKeys && ssl->QSH_Key == NULL) { + /* for each scheme make a client key */ + extension = TLSX_Find(ssl->extensions, TLSX_QUANTUM_SAFE_HYBRID); + if (extension) { + qsh = (QSHScheme*)extension->data; - /* get next now because qsh could be freed */ - next = qsh->next; + while (qsh) { + if ((ret = TLSX_CreateQSHKey(ssl, qsh->name)) != 0) + return ret; - /* find the public key created and add to extension*/ - public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, - &public_key_len, qsh->name); - if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name, - public_key, public_key_len, - ssl->heap) != SSL_SUCCESS) - ret = -1; - qsh = next; - } + /* get next now because qsh could be freed */ + next = qsh->next; + + /* find the public key created and add to extension*/ + public_key = TLSX_QSHKeyFind_Pub(ssl->QSH_Key, + &public_key_len, qsh->name); + if (TLSX_UseQSHScheme(&ssl->extensions, qsh->name, + public_key, public_key_len, + ssl->heap) != SSL_SUCCESS) + ret = -1; + qsh = next; } } - } /* is not server */ - #endif + } +#else + #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) + if (!ssl->options.userCurves && !ssl->ctx->userCurves) { + #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP160R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_SECPR2 + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP160R2, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_KOBLITZ + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP160K1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + #if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP192R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_KOBLITZ + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP192K1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + #if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP224R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_KOBLITZ + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP224K1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP256R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_KOBLITZ + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP256K1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_BRAINPOOL + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP384R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #ifdef HAVE_ECC_BRAINPOOL + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + #if defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES) + #ifdef HAVE_ECC_BRAINPOOL + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + #if defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES) + #ifndef NO_ECC_SECP + ret = TLSX_UseSupportedCurve(&ssl->extensions, WOLFSSL_ECC_SECP521R1, ssl->heap); + if (ret != SSL_SUCCESS) return ret; + #endif + #endif + } + #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ +#endif + } /* is not server */ - (void)isServer; (void)public_key; (void)public_key_len; (void)ssl; + if (ret == SSL_SUCCESS) + ret = 0; + return ret; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 19195f675..0b9a97f29 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2034,6 +2034,9 @@ struct WOLFSSL_CTX { void* ticketEncCtx; /* session encrypt context */ int ticketHint; /* ticket hint in seconds */ #endif + #ifdef HAVE_SUPPORTED_CURVES + byte userCurves; /* indicates user called wolfSSL_CTX_UseSupportedCurve */ + #endif #endif #ifdef ATOMIC_USER CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */ @@ -2447,6 +2450,9 @@ typedef struct Options { #endif #endif word16 haveEMS:1; /* using extended master secret */ +#if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_SUPPORTED_CURVES) + word16 userCurves:1; /* indicates user called wolfSSL_UseSupportedCurve */ +#endif /* need full byte values for this section */ byte processReply; /* nonblocking resume */ From 784ce57f453ad906bb2987048668bcf2c64e684a Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 19 Jan 2017 09:23:07 -0800 Subject: [PATCH 2/2] Fix for TLSX_PopulateExtensions to not use #else HAVE_QSH case for populating supported curves. --- src/tls.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tls.c b/src/tls.c index 27114aa60..cfabb0cfe 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4493,7 +4493,6 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) /* server will add extension depending on whats parsed from client */ if (!isServer) { - #ifdef HAVE_QSH /* test if user has set a specific scheme already */ if (!ssl->user_set_QSHSchemes) { @@ -4564,8 +4563,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) } } } -#else - #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) +#endif + +#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) if (!ssl->options.userCurves && !ssl->ctx->userCurves) { #if defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP @@ -4638,8 +4638,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #endif #endif } - #endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ -#endif +#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ } /* is not server */ (void)public_key;