From 1acf64a78254ca7bf57856473bc2d65cdccd6e1d Mon Sep 17 00:00:00 2001 From: TakayukiMatsuo Date: Tue, 10 Aug 2021 14:18:52 +0900 Subject: [PATCH 1/6] Add support for value zero as version parameter for SSL_CTX_set_min/max_proto_version --- src/ssl.c | 188 ++++++++++++++++++++++++++++++++++++++++++++-------- tests/api.c | 44 +++++++++++- 2 files changed, 203 insertions(+), 29 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5cb2ff162..453053e1b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16840,14 +16840,17 @@ static int CheckSslMethodVersion(byte major, unsigned long options) } /** - * This function attempts to set the minimum protocol version to use by SSL - * objects created from this WOLFSSL_CTX. This API guarantees that a version - * of SSL/TLS lower than specified here will not be allowed. If the version - * specified is not compiled in then this API sets the lowest compiled in - * protocol version. CheckSslMethodVersion() is called to check if any - * remaining protocol versions are enabled. + * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol + * version to use by SSL objects created from this WOLFSSL_CTX. + * This API guarantees that a version of SSL/TLS lower than specified + * here will not be allowed. If the version specified is not compiled in + * then this API sets the lowest compiled in protocol version. + * This API also accept 0 as version, to set the minimum version automatically. + * CheckSslMethodVersion() is called to check if any remaining protocol versions + * are enabled. * @param ctx * @param version Any of the following + * * 0 * * SSL3_VERSION * * TLS1_VERSION * * TLS1_1_VERSION @@ -16858,9 +16861,9 @@ static int CheckSslMethodVersion(byte major, unsigned long options) * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no * protocol versions are left enabled. */ -int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) +static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version) { - WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version"); + WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex"); if (ctx == NULL) { return WOLFSSL_FAILURE; @@ -16941,15 +16944,51 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); } +int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) +{ + const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, + TLS1_2_VERSION, TLS1_3_VERSION,DTLS1_VERSION, + DTLS1_2_VERSION}; + int tblSz = sizeof(verTbl); + int i; + int ret; + + WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version"); + + (void)verTbl; + (void)tblSz; + (void)i; + (void)ret; + + if (ctx == NULL) { + return WOLFSSL_FAILURE; + } + if (version != 0) { + return Set_CTX_min_proto_version(ctx, version); + } + + /* when 0 is specified as version, try to find out the min version */ + for (i= 0; i < tblSz; i++) { + ret = Set_CTX_min_proto_version(ctx, verTbl[i]); + if (ret == WOLFSSL_SUCCESS) + break; + } + + return ret; +} + /** - * This function attempts to set the maximum protocol version to use by SSL - * objects created from this WOLFSSL_CTX. This API guarantees that a version - * of SSL/TLS higher than specified here will not be allowed. If the version - * specified is not compiled in then this API sets the highest compiled in - * protocol version. CheckSslMethodVersion() is called to check if any - * remaining protocol versions are enabled. + * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol + * version to use by SSL objects created from this WOLFSSL_CTX. + * This API guarantees that a version of SSL/TLS higher than specified + * here will not be allowed. If the version specified is not compiled in + * then this API sets the highest compiled in protocol version. + * This API also accept 0 as version, to set the maximum version automatically. + * CheckSslMethodVersion() is called to check if any remaining protocol versions + * are enabled. * @param ctx * @param version Any of the following + * * 0 * * SSL3_VERSION * * TLS1_VERSION * * TLS1_1_VERSION @@ -16960,9 +16999,9 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no * protocol versions are left enabled. */ -int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) +static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver) { - WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version"); + WOLFSSL_ENTER("Set_CTX_max_proto_version"); if (!ctx || !ctx->method) { WOLFSSL_MSG("Bad parameter"); @@ -17003,9 +17042,44 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver) return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); } -int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int ver) +int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) { - WOLFSSL_ENTER("wolfSSL_set_min_proto_version"); + const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, + TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, + SSL3_VERSION}; + int tblSz = sizeof(verTbl); + int i; + int ret; + + WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version"); + + (void)verTbl; + (void)tblSz; + (void)i; + (void)ret; + + if (ctx == NULL) { + return WOLFSSL_FAILURE; + } + if (version != 0) { + return Set_CTX_max_proto_version(ctx, version); + } + + /* when 0 is specified as version, try to find out the min version */ + for (i= 0; i < tblSz; i++) { + ret = Set_CTX_max_proto_version(ctx, verTbl[i]); + if (ret == WOLFSSL_SUCCESS) { + break; + } + } + + return ret; +} + + +static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver) +{ + WOLFSSL_ENTER("Set_SSL_min_proto_version"); if (ssl == NULL) { return WOLFSSL_FAILURE; @@ -17086,10 +17160,43 @@ int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int ver) return CheckSslMethodVersion(ssl->version.major, ssl->options.mask); } -int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int ver) +int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version) +{ + const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, + TLS1_2_VERSION, TLS1_3_VERSION,DTLS1_VERSION, + DTLS1_2_VERSION}; + int tblSz = sizeof(verTbl); + int i; + int ret; + + WOLFSSL_ENTER("wolfSSL_set_min_proto_version"); + + (void)verTbl; + (void)tblSz; + (void)i; + (void)ret; + + if (ssl == NULL) { + return WOLFSSL_FAILURE; + } + if (version != 0) { + return Set_SSL_min_proto_version(ssl, version); + } + + /* when 0 is specified as version, try to find out the min version */ + for (i= 0; i < tblSz; i++) { + ret = Set_SSL_min_proto_version(ssl, verTbl[i]); + if (ret == WOLFSSL_SUCCESS) + break; + } + + return ret; +} + +static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver) { - WOLFSSL_ENTER("wolfSSL_set_max_proto_version"); + WOLFSSL_ENTER("Set_SSL_max_proto_version"); if (!ssl) { WOLFSSL_MSG("Bad parameter"); @@ -17130,6 +17237,39 @@ int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int ver) return CheckSslMethodVersion(ssl->version.major, ssl->options.mask); } +int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version) +{ + const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, + TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, + SSL3_VERSION}; + int tblSz = sizeof(verTbl); + int i; + int ret; + + WOLFSSL_ENTER("wolfSSL_set_max_proto_version"); + + (void)verTbl; + (void)tblSz; + (void)i; + (void)ret; + + if (ssl == NULL) { + return WOLFSSL_FAILURE; + } + if (version != 0) { + return Set_SSL_max_proto_version(ssl, version); + } + + /* when 0 is specified as version, try to find out the max version */ + for (i= 0; i < tblSz; i++) { + ret = Set_SSL_max_proto_version(ssl, verTbl[i]); + if (ret == WOLFSSL_SUCCESS) + break; + } + + return ret; +} + static int GetMinProtoVersion(int minDowngrade) { int ret; @@ -43865,17 +44005,9 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) break; case SSL_CTRL_SET_MIN_PROTO_VERSION: WOLFSSL_MSG("set min proto version"); - if (opt == 0) { - /* do nothing */ - return WOLFSSL_SUCCESS; - } return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt); case SSL_CTRL_SET_MAX_PROTO_VERSION: WOLFSSL_MSG("set max proto version"); - if (opt == 0) { - /* do nothing */ - return WOLFSSL_SUCCESS; - } return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt); default: WOLFSSL_MSG("CTX_ctrl cmd not implemented"); diff --git a/tests/api.c b/tests/api.c index 43798fa50..c6b6c2360 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2035,6 +2035,47 @@ static void test_wolfSSL_CTX_ticket_API(void) #endif /* HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER */ } +static void test_wolfSSL_set_minmax_proto_version(void) +{ +#ifdef OPENSSL_EXTRA +WOLFSSL_CTX *ctx; +WOLFSSL *ssl; +int ret; +(void)ret; +(void)ssl; +printf(testingFmt, "test_wolfSSL_set_minmax_proto_version"); + +#ifndef NO_WOLFSSL_CLIENT + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + AssertNotNull(ssl = wolfSSL_new(ctx)); + + AssertIntEQ(wolfSSL_CTX_set_min_proto_version(NULL, 0), SSL_FAILURE); + AssertIntEQ(wolfSSL_CTX_set_max_proto_version(NULL, 0), SSL_FAILURE); + AssertIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, 0), SSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, 0), SSL_SUCCESS); + + AssertIntEQ(wolfSSL_set_min_proto_version(NULL, 0), SSL_FAILURE); + AssertIntEQ(wolfSSL_set_min_proto_version(ssl, 0), SSL_SUCCESS); + AssertIntEQ(wolfSSL_set_max_proto_version(NULL, 0), SSL_FAILURE); + AssertIntEQ(wolfSSL_set_max_proto_version(ssl, 0), SSL_SUCCESS); + + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); + +#else + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); + + AssertIntEQ(wolfSSL_CTX_set_min_proto_version(NULL, 0), SSL_FAILURE); + AssertIntEQ(wolfSSL_CTX_set_max_proto_version(NULL, 0), SSL_FAILURE); + AssertIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, 0), SSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, 0), SSL_SUCCESS); + + wolfSSL_CTX_free(ctx); +#endif + + printf(resultFmt, passed); +#endif +} /*----------------------------------------------------------------------------* | SSL @@ -16929,7 +16970,7 @@ static int test_wc_RsaPublicEncryptDecrypt (void) if (in == NULL || plain == NULL || cipher == NULL) { printf("test_wc_RsaPublicEncryptDecrypt malloc failed\n"); return MEMORY_E; - } +} #endif XMEMCPY(in, inStr, inLen); @@ -46936,6 +46977,7 @@ void ApiTest(void) test_wolfSSL_Tls12_Key_Logging_test(); test_wolfSSL_Tls13_Key_Logging_test(); test_wolfSSL_CTX_set_ecdh_auto(); + test_wolfSSL_set_minmax_proto_version(); test_wolfSSL_THREADID_hash(); test_wolfSSL_RAND_set_rand_method(); test_wolfSSL_RAND_bytes(); From f2bce42bbd213254d603ee3d2edd16f896d47559 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 16 Sep 2021 01:01:38 -0700 Subject: [PATCH 2/6] add function wolfSSL_CTX_get_max_proto_version and handling for edge cases --- src/ssl.c | 167 ++++++++++++++++++++++++++++++++---------- tests/api.c | 6 ++ wolfssl/openssl/ssl.h | 3 + wolfssl/ssl.h | 3 + 4 files changed, 139 insertions(+), 40 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 453053e1b..a852ff949 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16843,8 +16843,8 @@ static int CheckSslMethodVersion(byte major, unsigned long options) * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol * version to use by SSL objects created from this WOLFSSL_CTX. * This API guarantees that a version of SSL/TLS lower than specified - * here will not be allowed. If the version specified is not compiled in - * then this API sets the lowest compiled in protocol version. + * here will not be allowed. If the version specified is not compiled in + * then this API sets the lowest compiled in protocol version. * This API also accept 0 as version, to set the minimum version automatically. * CheckSslMethodVersion() is called to check if any remaining protocol versions * are enabled. @@ -16946,34 +16946,58 @@ static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version) int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) { - const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, - TLS1_2_VERSION, TLS1_3_VERSION,DTLS1_VERSION, + const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, + TLS1_2_VERSION, TLS1_3_VERSION, DTLS1_VERSION, DTLS1_2_VERSION}; int tblSz = sizeof(verTbl); - int i; int ret; + int proto; + int maxProto; + int i; + int idx = 0; WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version"); - (void)verTbl; - (void)tblSz; - (void)i; - (void)ret; - if (ctx == NULL) { return WOLFSSL_FAILURE; } if (version != 0) { - return Set_CTX_min_proto_version(ctx, version); + proto = version; + wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_MIN_PROTO); + for (i = 0; i < tblSz; i++) { + if (verTbl[i] == version) { + break; + } + } + } + else { + /* when 0 is specified as version, try to find out the min version */ + for (i = 0; i < tblSz; i++) { + ret = Set_CTX_min_proto_version(ctx, verTbl[i]); + if (ret == WOLFSSL_SUCCESS) { + proto = verTbl[i]; + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_MIN_PROTO); + break; + } + } } - /* when 0 is specified as version, try to find out the min version */ - for (i= 0; i < tblSz; i++) { - ret = Set_CTX_min_proto_version(ctx, verTbl[i]); - if (ret == WOLFSSL_SUCCESS) + /* check case where max > min , if so then clear the NO_* options + * i is the index into the table for proto version used, see if the max + * proto version index found is smaller */ + maxProto = wolfSSL_CTX_get_max_proto_version(ctx); + for (idx = 0; idx < tblSz; idx++) { + if (verTbl[idx] == maxProto) { break; + } + } + if (idx < i) { + wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 | + WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 | + WOLFSSL_OP_NO_TLSv1_3); } + ret = Set_CTX_min_proto_version(ctx, proto); return ret; } @@ -16981,8 +17005,8 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol * version to use by SSL objects created from this WOLFSSL_CTX. * This API guarantees that a version of SSL/TLS higher than specified - * here will not be allowed. If the version specified is not compiled in - * then this API sets the highest compiled in protocol version. + * here will not be allowed. If the version specified is not compiled in + * then this API sets the highest compiled in protocol version. * This API also accept 0 as version, to set the maximum version automatically. * CheckSslMethodVersion() is called to check if any remaining protocol versions * are enabled. @@ -17044,31 +17068,36 @@ static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver) int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) { - const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, - TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, + const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, + TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, SSL3_VERSION}; int tblSz = sizeof(verTbl); int i; int ret; + int minProto; WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version"); - (void)verTbl; - (void)tblSz; - (void)i; - (void)ret; - if (ctx == NULL) { return WOLFSSL_FAILURE; } + + /* clear out flags and reset min protocol version */ + minProto = wolfSSL_CTX_get_min_proto_version(ctx); + wolfSSL_CTX_clear_options(ctx, + WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 | + WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3); + wolfSSL_CTX_set_min_proto_version(ctx, minProto); if (version != 0) { + wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_MAX_PROTO); return Set_CTX_max_proto_version(ctx, version); } /* when 0 is specified as version, try to find out the min version */ for (i= 0; i < tblSz; i++) { ret = Set_CTX_max_proto_version(ctx, verTbl[i]); - if (ret == WOLFSSL_SUCCESS) { + if (ret == WOLFSSL_SUCCESS) { + wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_MAX_PROTO); break; } } @@ -17162,7 +17191,7 @@ static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver) int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version) { - const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, + const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,DTLS1_VERSION, DTLS1_2_VERSION}; int tblSz = sizeof(verTbl); @@ -17171,11 +17200,6 @@ int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version) WOLFSSL_ENTER("wolfSSL_set_min_proto_version"); - (void)verTbl; - (void)tblSz; - (void)i; - (void)ret; - if (ssl == NULL) { return WOLFSSL_FAILURE; } @@ -17239,8 +17263,8 @@ static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver) int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version) { - const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, - TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, + const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, + TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, SSL3_VERSION}; int tblSz = sizeof(verTbl); int i; @@ -17248,11 +17272,6 @@ int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version) WOLFSSL_ENTER("wolfSSL_set_max_proto_version"); - (void)verTbl; - (void)tblSz; - (void)i; - (void)ret; - if (ssl == NULL) { return WOLFSSL_FAILURE; } @@ -17315,9 +17334,14 @@ WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx) WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version"); if (ctx != NULL) { - ret = GetMinProtoVersion(ctx->minDowngrade); + if (wolfSSL_CTX_get_options(ctx) & WOLFSSL_OP_MIN_PROTO) { + ret = 0; + } + else { + ret = GetMinProtoVersion(ctx->minDowngrade); + } } - if (ret == 0) { + else { ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE); } @@ -17326,6 +17350,63 @@ WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx) return ret; } + +/* returns the maximum allowed protocol version given the 'options' used + * returns WOLFSSL_FATAL_ERROR on no match */ +static int GetMaxProtoVersion(long options) +{ +#ifdef WOLFSSL_TLS13 + if (!(options & WOLFSSL_OP_NO_TLSv1_3)) + return TLS1_3_VERSION; +#endif +#ifndef WOLFSSL_NO_TLS12 + if (!(options & WOLFSSL_OP_NO_TLSv1_2)) + return TLS1_2_VERSION; +#endif +#ifndef NO_OLD_TLS + if (!(options & WOLFSSL_OP_NO_TLSv1_1)) + return TLS1_1_VERSION; + #ifdef WOLFSSL_ALLOW_TLSV10 + if (!(options & WOLFSSL_OP_NO_TLSv1)) + return TLS1_VERSION; + #endif + #ifdef WOLFSSL_ALLOW_SSLV3 + if (!(options & WOLFSSL_OP_NO_SSLv3)) + return SSL3_VERSION; + #endif +#endif + + return WOLFSSL_FATAL_ERROR; +} + + +/* returns the maximum protocol version for 'ctx' */ +int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx) +{ + int ret = 0; + long options = 0; /* default to nothing set */ + + WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version"); + + if (ctx != NULL) { + options = wolfSSL_CTX_get_options(ctx); + } + + if (options & WOLFSSL_OP_MAX_PROTO) { + ret = 0; + } + else { + ret = GetMaxProtoVersion(options); + } + + WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret); + + if (ret == WOLFSSL_FATAL_ERROR) { + WOLFSSL_MSG("Error getting max proto version"); + ret = 0; /* setting ret to 0 to match compat return */ + } + return ret; +} #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ @@ -44009,6 +44090,12 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) case SSL_CTRL_SET_MAX_PROTO_VERSION: WOLFSSL_MSG("set max proto version"); return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt); + case SSL_CTRL_GET_MIN_PROTO_VERSION: + WOLFSSL_MSG("get min proto version"); + return wolfSSL_CTX_get_min_proto_version(ctx); + case SSL_CTRL_GET_MAX_PROTO_VERSION: + WOLFSSL_MSG("get max proto version"); + return wolfSSL_CTX_get_max_proto_version(ctx); default: WOLFSSL_MSG("CTX_ctrl cmd not implemented"); ret = WOLFSSL_FAILURE; diff --git a/tests/api.c b/tests/api.c index c6b6c2360..96a11f471 100644 --- a/tests/api.c +++ b/tests/api.c @@ -38962,6 +38962,12 @@ static void test_wolfSSL_CTX_ctrl(void) AssertIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, TLS1_3_VERSION, NULL), SSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_get_max_proto_version(ctx), TLS1_3_VERSION); + #ifndef WOLFSSL_NO_TLS12 + AssertIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, + TLS1_2_VERSION, NULL), SSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_get_max_proto_version(ctx), TLS1_2_VERSION); + #endif #endif /* Cleanup and Pass */ #if !defined(NO_DH) && !defined(NO_DSA) diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 14843fd2b..82ca9d88b 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1128,6 +1128,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_set_min_proto_version wolfSSL_set_min_proto_version #define SSL_set_max_proto_version wolfSSL_set_max_proto_version #define SSL_CTX_get_min_proto_version wolfSSL_CTX_get_min_proto_version +#define SSL_CTX_get_max_proto_version wolfSSL_CTX_get_max_proto_version #define SSL_get_tlsext_status_exts wolfSSL_get_tlsext_status_exts @@ -1154,6 +1155,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTRL_GET_SERVER_TMP_KEY SSL_CTRL_GET_PEER_TMP_KEY #define SSL_CTRL_SET_MIN_PROTO_VERSION 123 #define SSL_CTRL_SET_MAX_PROTO_VERSION 124 +#define SSL_CTRL_GET_MIN_PROTO_VERSION 125 +#define SSL_CTRL_GET_MAX_PROTO_VERSION 126 #define SSL_CTRL_SET_CURVES SSL_CTRL_SET_GROUPS #define SSL_CTRL_EXTRA_CHAIN_CERT 14 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 290737337..498e1130b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1955,6 +1955,8 @@ enum { SSL_OP_NO_COMPRESSION = 0x10000000, WOLFSSL_OP_NO_TLSv1_3 = 0x20000000, WOLFSSL_OP_NO_SSLv2 = 0x40000000, + WOLFSSL_OP_MAX_PROTO = 0x80000000, + WOLFSSL_OP_MIN_PROTO = 0x100000000, SSL_OP_ALL = (SSL_OP_MICROSOFT_SESS_ID_BUG | SSL_OP_NETSCAPE_CHALLENGE_BUG @@ -3854,6 +3856,7 @@ WOLFSSL_API int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX*, int); WOLFSSL_API int wolfSSL_set_min_proto_version(WOLFSSL*, int); WOLFSSL_API int wolfSSL_set_max_proto_version(WOLFSSL*, int); WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX*); +WOLFSSL_API int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX*); WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); From 989179a94a1d89a2d483bea5908306792e2ffa86 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 17 Sep 2021 14:04:42 -0700 Subject: [PATCH 3/6] set value for number of protocols in table --- src/ssl.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index a852ff949..ef79b1ba1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16944,15 +16944,20 @@ static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version) return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); } +/* number of protocol versions listed in table */ +#define NUMBER_OF_PROTOCOLS 7 + +/* Sets the min protocol version allowed with WOLFSSL_CTX + * returns WOLFSSL_SUCCESS on success */ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) { const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION, DTLS1_VERSION, DTLS1_2_VERSION}; - int tblSz = sizeof(verTbl); + int tblSz = NUMBER_OF_PROTOCOLS; int ret; - int proto; - int maxProto; + int proto = 0; + int maxProto = 0; int i; int idx = 0; @@ -17066,12 +17071,15 @@ static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver) return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); } + +/* Sets the max protocol version allowed with WOLFSSL_CTX + * returns WOLFSSL_SUCCESS on success */ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) { const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, SSL3_VERSION}; - int tblSz = sizeof(verTbl); + int tblSz = NUMBER_OF_PROTOCOLS; int i; int ret; int minProto; From f1ff3da47cd8c3d548092bbfdb80fa229dc79f01 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Sun, 19 Sep 2021 21:20:58 -0600 Subject: [PATCH 4/6] fix for case of long type on 32bit systems --- src/internal.c | 2 ++ src/ssl.c | 12 ++++++------ wolfssl/internal.h | 4 ++++ wolfssl/ssl.h | 2 -- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/internal.c b/src/internal.c index 5d6a8fe3a..76618b59f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5720,6 +5720,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->version = ctx->method->version; #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) ssl->options.mask = ctx->mask; + ssl->options.minProto = ctx->minProto; + ssl->options.maxProto = ctx->maxProto; #endif #ifdef OPENSSL_EXTRA #ifdef WOLFSSL_TLS13 diff --git a/src/ssl.c b/src/ssl.c index ef79b1ba1..6adfae966 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16968,7 +16968,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) } if (version != 0) { proto = version; - wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_MIN_PROTO); + ctx->minProto = 0; /* turn min proto flag off */ for (i = 0; i < tblSz; i++) { if (verTbl[i] == version) { break; @@ -16981,7 +16981,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) ret = Set_CTX_min_proto_version(ctx, verTbl[i]); if (ret == WOLFSSL_SUCCESS) { proto = verTbl[i]; - wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_MIN_PROTO); + ctx->minProto = 1; /* turn min proto flag on */ break; } } @@ -17097,7 +17097,7 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3); wolfSSL_CTX_set_min_proto_version(ctx, minProto); if (version != 0) { - wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_MAX_PROTO); + ctx->maxProto = 0; /* turn max proto flag off */ return Set_CTX_max_proto_version(ctx, version); } @@ -17105,7 +17105,7 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) for (i= 0; i < tblSz; i++) { ret = Set_CTX_max_proto_version(ctx, verTbl[i]); if (ret == WOLFSSL_SUCCESS) { - wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_MAX_PROTO); + ctx->maxProto = 1; /* turn max proto flag on */ break; } } @@ -17342,7 +17342,7 @@ WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx) WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version"); if (ctx != NULL) { - if (wolfSSL_CTX_get_options(ctx) & WOLFSSL_OP_MIN_PROTO) { + if (ctx->minProto) { ret = 0; } else { @@ -17400,7 +17400,7 @@ int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx) options = wolfSSL_CTX_get_options(ctx); } - if (options & WOLFSSL_OP_MAX_PROTO) { + if (ctx->maxProto) { ret = 0; } else { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 60ff15ab2..7f3242db2 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2885,6 +2885,8 @@ struct WOLFSSL_CTX { short minEccKeySz; /* minimum ECC key size */ #endif unsigned long mask; /* store SSL_OP_ flags */ + word16 minProto:1; /* sets min to min available */ + word16 maxProto:1; /* sets max to max available */ #ifdef OPENSSL_EXTRA byte sessionCtx[ID_LEN]; /* app session context ID */ word32 disabledCurves; /* curves disabled by user */ @@ -3566,6 +3568,8 @@ typedef struct Options { #endif /* NO_PSK */ #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL) unsigned long mask; /* store SSL_OP_ flags */ + word16 minProto:1; /* sets min to min available */ + word16 maxProto:1; /* sets max to max available */ #endif /* on/off or small bit flags, optimize layout */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 498e1130b..6790ff658 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1955,8 +1955,6 @@ enum { SSL_OP_NO_COMPRESSION = 0x10000000, WOLFSSL_OP_NO_TLSv1_3 = 0x20000000, WOLFSSL_OP_NO_SSLv2 = 0x40000000, - WOLFSSL_OP_MAX_PROTO = 0x80000000, - WOLFSSL_OP_MIN_PROTO = 0x100000000, SSL_OP_ALL = (SSL_OP_MICROSOFT_SESS_ID_BUG | SSL_OP_NETSCAPE_CHALLENGE_BUG From 5b3dfabc329ca495ece959f2f854513a8ef5c01f Mon Sep 17 00:00:00 2001 From: TakayukiMatsuo Date: Fri, 24 Sep 2021 16:05:55 +0900 Subject: [PATCH 5/6] Introduce global protoVerTbl for SSL_CTX_set_min/max_proto_version --- src/ssl.c | 71 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6adfae966..a8edc7fd8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16839,6 +16839,24 @@ static int CheckSslMethodVersion(byte major, unsigned long options) return WOLFSSL_SUCCESS; } +/** + * protoVerTbl holds (D)TLS version numbers in ascending order. + * Except DTLS versions, the newer version is located in the latter part of + * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and + * wolfSSL_CTX_set_max_proto_version. + */ +static const int protoVerTbl[] = { + SSL3_VERSION, + TLS1_VERSION, + TLS1_1_VERSION, + TLS1_2_VERSION, + TLS1_3_VERSION, + DTLS1_VERSION, + DTLS1_2_VERSION +}; +/* number of protocol versions listed in protoVerTbl */ +#define NUMBER_OF_PROTOCOLS sizeof(protoVerTbl)/sizeof(int) + /** * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol * version to use by SSL objects created from this WOLFSSL_CTX. @@ -16944,17 +16962,10 @@ static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version) return CheckSslMethodVersion(ctx->method->version.major, ctx->mask); } -/* number of protocol versions listed in table */ -#define NUMBER_OF_PROTOCOLS 7 - /* Sets the min protocol version allowed with WOLFSSL_CTX * returns WOLFSSL_SUCCESS on success */ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) { - const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, - TLS1_2_VERSION, TLS1_3_VERSION, DTLS1_VERSION, - DTLS1_2_VERSION}; - int tblSz = NUMBER_OF_PROTOCOLS; int ret; int proto = 0; int maxProto = 0; @@ -16969,18 +16980,18 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) if (version != 0) { proto = version; ctx->minProto = 0; /* turn min proto flag off */ - for (i = 0; i < tblSz; i++) { - if (verTbl[i] == version) { + for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) { + if (protoVerTbl[i] == version) { break; } } } else { /* when 0 is specified as version, try to find out the min version */ - for (i = 0; i < tblSz; i++) { - ret = Set_CTX_min_proto_version(ctx, verTbl[i]); + for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) { + ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]); if (ret == WOLFSSL_SUCCESS) { - proto = verTbl[i]; + proto = protoVerTbl[i]; ctx->minProto = 1; /* turn min proto flag on */ break; } @@ -16991,8 +17002,8 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version) * i is the index into the table for proto version used, see if the max * proto version index found is smaller */ maxProto = wolfSSL_CTX_get_max_proto_version(ctx); - for (idx = 0; idx < tblSz; idx++) { - if (verTbl[idx] == maxProto) { + for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) { + if (protoVerTbl[idx] == maxProto) { break; } } @@ -17076,10 +17087,6 @@ static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver) * returns WOLFSSL_SUCCESS on success */ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) { - const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, - TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, - SSL3_VERSION}; - int tblSz = NUMBER_OF_PROTOCOLS; int i; int ret; int minProto; @@ -17101,9 +17108,11 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version) return Set_CTX_max_proto_version(ctx, version); } - /* when 0 is specified as version, try to find out the min version */ - for (i= 0; i < tblSz; i++) { - ret = Set_CTX_max_proto_version(ctx, verTbl[i]); + /* when 0 is specified as version, try to find out the min version from + * the bottom to top of the protoverTbl. + */ + for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) { + ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]); if (ret == WOLFSSL_SUCCESS) { ctx->maxProto = 1; /* turn max proto flag on */ break; @@ -17199,10 +17208,6 @@ static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver) int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version) { - const int verTbl[] = {SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, - TLS1_2_VERSION, TLS1_3_VERSION,DTLS1_VERSION, - DTLS1_2_VERSION}; - int tblSz = sizeof(verTbl); int i; int ret; @@ -17216,8 +17221,8 @@ int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version) } /* when 0 is specified as version, try to find out the min version */ - for (i= 0; i < tblSz; i++) { - ret = Set_SSL_min_proto_version(ssl, verTbl[i]); + for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) { + ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]); if (ret == WOLFSSL_SUCCESS) break; } @@ -17271,10 +17276,6 @@ static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver) int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version) { - const int verTbl[] = {DTLS1_2_VERSION, DTLS1_VERSION, TLS1_3_VERSION, - TLS1_2_VERSION, TLS1_1_VERSION, TLS1_VERSION, - SSL3_VERSION}; - int tblSz = sizeof(verTbl); int i; int ret; @@ -17287,9 +17288,11 @@ int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version) return Set_SSL_max_proto_version(ssl, version); } - /* when 0 is specified as version, try to find out the max version */ - for (i= 0; i < tblSz; i++) { - ret = Set_SSL_max_proto_version(ssl, verTbl[i]); + /* when 0 is specified as version, try to find out the min version from + * the bottom to top of the protoverTbl. + */ + for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) { + ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]); if (ret == WOLFSSL_SUCCESS) break; } From 0bf832bd2a03ce576383e82e3694fcc94882a927 Mon Sep 17 00:00:00 2001 From: TakayukiMatsuo Date: Fri, 24 Sep 2021 23:22:04 +0900 Subject: [PATCH 6/6] fix uninitialized variables --- src/ssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index a8edc7fd8..cfa2a57b1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17209,7 +17209,7 @@ static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver) int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version) { int i; - int ret; + int ret = WOLFSSL_FAILURE;; WOLFSSL_ENTER("wolfSSL_set_min_proto_version"); @@ -17277,7 +17277,7 @@ static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver) int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version) { int i; - int ret; + int ret = WOLFSSL_FAILURE;; WOLFSSL_ENTER("wolfSSL_set_max_proto_version");