From 1acf64a78254ca7bf57856473bc2d65cdccd6e1d Mon Sep 17 00:00:00 2001 From: TakayukiMatsuo Date: Tue, 10 Aug 2021 14:18:52 +0900 Subject: [PATCH] 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();