Loading ssl/s3_lib.c +27 −5 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ */ #include <stdio.h> #include <assert.h> #include <openssl/objects.h> #include "ssl_locl.h" #include <openssl/md5.h> Loading Loading @@ -4007,9 +4008,10 @@ long ssl_get_algorithm2(SSL *s) * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on * failure, 1 on success. */ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len) int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, DOWNGRADE dgrd) { int send_time = 0; int send_time = 0, ret; if (len < 4) return 0; Loading @@ -4022,9 +4024,29 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len) unsigned char *p = result; l2n(Time, p); /* TODO(size_t): Convert this */ return RAND_bytes(p, (int)(len - 4)); } else return RAND_bytes(result, (int)len); ret = RAND_bytes(p, (int)(len - 4)); } else { ret = RAND_bytes(result, (int)len); } #ifndef OPENSSL_NO_TLS13DOWNGRADE if (ret) { static const unsigned char tls11downgrade[] = { 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00 }; static const unsigned char tls12downgrade[] = { 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01 }; assert(sizeof(tls11downgrade) < len && sizeof(tls12downgrade) < len); if (dgrd == DOWNGRADE_TO_1_2) memcpy(result + len - sizeof(tls12downgrade), tls12downgrade, sizeof(tls12downgrade)); else if (dgrd == DOWNGRADE_TO_1_1) memcpy(result + len - sizeof(tls11downgrade), tls11downgrade, sizeof(tls11downgrade)); } #endif return ret; } int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, Loading ssl/ssl_locl.h +9 −2 Original line number Diff line number Diff line Loading @@ -1783,6 +1783,12 @@ typedef struct ssl3_comp_st { } SSL3_COMP; # endif typedef enum downgrade_en { DOWNGRADE_NONE, DOWNGRADE_TO_1_2, DOWNGRADE_TO_1_1 } DOWNGRADE; /* * Extension index values NOTE: Any updates to these defines should be mirrored * with equivalent updates to ext_defs in extensions.c Loading Loading @@ -2101,7 +2107,7 @@ __owur int ssl_verify_alarm_type(long type); void ssl_sort_cipher_list(void); void ssl_load_ciphers(void); __owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, size_t len); size_t len, DOWNGRADE dgrd); __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, int free_pms); __owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm); Loading Loading @@ -2167,7 +2173,8 @@ __owur int ssl_version_supported(const SSL *s, int version); __owur int ssl_set_client_hello_version(SSL *s); __owur int ssl_check_version_downgrade(SSL *s); __owur int ssl_set_version_bound(int method_version, int version, int *bound); __owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello); __owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd); __owur int ssl_choose_client_version(SSL *s, int version); int ssl_get_client_min_max_version(const SSL *s, int *min_version, int *max_version); Loading ssl/statem/statem_clnt.c +2 −1 Original line number Diff line number Diff line Loading @@ -1094,7 +1094,8 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) } else i = 1; if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)) <= 0) if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random), DOWNGRADE_NONE) <= 0) return 0; /*- Loading ssl/statem/statem_lib.c +20 −1 Original line number Diff line number Diff line Loading @@ -1295,6 +1295,7 @@ typedef struct { # error Code needs update for TLS_method() support beyond TLS1_3_VERSION. #endif /* Must be in order high to low */ static const version_info tls_version_table[] = { #ifndef OPENSSL_NO_TLS1_3 {TLS1_3_VERSION, tlsv1_3_client_method, tlsv1_3_server_method}, Loading Loading @@ -1328,6 +1329,7 @@ static const version_info tls_version_table[] = { # error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. #endif /* Must be in order high to low */ static const version_info dtls_version_table[] = { #ifndef OPENSSL_NO_DTLS1_2 {DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method}, Loading Loading @@ -1510,6 +1512,20 @@ int ssl_set_version_bound(int method_version, int version, int *bound) return 1; } static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd) { if (vers == TLS1_2_VERSION && ssl_version_supported(s, TLS1_3_VERSION)) { *dgrd = DOWNGRADE_TO_1_2; } else if (!SSL_IS_DTLS(s) && vers < TLS1_2_VERSION && (ssl_version_supported(s, TLS1_2_VERSION) || ssl_version_supported(s, TLS1_3_VERSION))) { *dgrd = DOWNGRADE_TO_1_1; } else { *dgrd = DOWNGRADE_NONE; } } /* * ssl_choose_server_version - Choose server (D)TLS version. Called when the * client HELLO is received to select the final server protocol version and Loading @@ -1519,7 +1535,7 @@ int ssl_set_version_bound(int method_version, int version, int *bound) * * Returns 0 on success or an SSL error reason number on failure. */ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) { /*- * With version-flexible methods we have an initial state with: Loading @@ -1544,6 +1560,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) if (!SSL_IS_TLS13(s)) { if (version_cmp(s, client_version, s->version) < 0) return SSL_R_WRONG_SSL_VERSION; *dgrd = DOWNGRADE_NONE; /* * If this SSL handle is not from a version flexible method we don't * (and never did) check min/max FIPS or Suite B constraints. Hope Loading Loading @@ -1620,6 +1637,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) return SSL_R_UNSUPPORTED_PROTOCOL; return 0; } check_for_downgrade(s, best_vers, dgrd); s->version = best_vers; s->method = best_method; return 0; Loading @@ -1646,6 +1664,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) continue; method = vent->smeth(); if (ssl_method_error(s, method) == 0) { check_for_downgrade(s, vent->version, dgrd); s->version = vent->version; s->method = method; return 0; Loading ssl/statem/statem_srvr.c +4 −3 Original line number Diff line number Diff line Loading @@ -1476,6 +1476,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) STACK_OF(SSL_CIPHER) *ciphers = NULL; STACK_OF(SSL_CIPHER) *scsvs = NULL; CLIENTHELLO_MSG *clienthello = s->clienthello; DOWNGRADE dgrd = DOWNGRADE_NONE; *al = SSL_AD_INTERNAL_ERROR; /* Finished parsing the ClientHello, now we can start processing it */ Loading Loading @@ -1516,7 +1517,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) * versions are potentially compatible. Version negotiation comes later. */ if (!SSL_IS_DTLS(s)) { protverr = ssl_choose_server_version(s, clienthello); protverr = ssl_choose_server_version(s, clienthello, &dgrd); } else if (s->method->version != DTLS_ANY_VERSION && DTLS_VERSION_LT((int)clienthello->legacy_version, s->version)) { protverr = SSL_R_VERSION_TOO_LOW; Loading Loading @@ -1565,7 +1566,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) s->d1->cookie_verified = 1; } if (s->method->version == DTLS_ANY_VERSION) { protverr = ssl_choose_server_version(s, clienthello); protverr = ssl_choose_server_version(s, clienthello, &dgrd); if (protverr != 0) { SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr); s->version = s->client_version; Loading Loading @@ -1722,7 +1723,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) { unsigned char *pos; pos = s->s3->server_random; if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE, dgrd) <= 0) { goto err; } } Loading Loading
ssl/s3_lib.c +27 −5 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ */ #include <stdio.h> #include <assert.h> #include <openssl/objects.h> #include "ssl_locl.h" #include <openssl/md5.h> Loading Loading @@ -4007,9 +4008,10 @@ long ssl_get_algorithm2(SSL *s) * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on * failure, 1 on success. */ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len) int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, DOWNGRADE dgrd) { int send_time = 0; int send_time = 0, ret; if (len < 4) return 0; Loading @@ -4022,9 +4024,29 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len) unsigned char *p = result; l2n(Time, p); /* TODO(size_t): Convert this */ return RAND_bytes(p, (int)(len - 4)); } else return RAND_bytes(result, (int)len); ret = RAND_bytes(p, (int)(len - 4)); } else { ret = RAND_bytes(result, (int)len); } #ifndef OPENSSL_NO_TLS13DOWNGRADE if (ret) { static const unsigned char tls11downgrade[] = { 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00 }; static const unsigned char tls12downgrade[] = { 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01 }; assert(sizeof(tls11downgrade) < len && sizeof(tls12downgrade) < len); if (dgrd == DOWNGRADE_TO_1_2) memcpy(result + len - sizeof(tls12downgrade), tls12downgrade, sizeof(tls12downgrade)); else if (dgrd == DOWNGRADE_TO_1_1) memcpy(result + len - sizeof(tls11downgrade), tls11downgrade, sizeof(tls11downgrade)); } #endif return ret; } int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, Loading
ssl/ssl_locl.h +9 −2 Original line number Diff line number Diff line Loading @@ -1783,6 +1783,12 @@ typedef struct ssl3_comp_st { } SSL3_COMP; # endif typedef enum downgrade_en { DOWNGRADE_NONE, DOWNGRADE_TO_1_2, DOWNGRADE_TO_1_1 } DOWNGRADE; /* * Extension index values NOTE: Any updates to these defines should be mirrored * with equivalent updates to ext_defs in extensions.c Loading Loading @@ -2101,7 +2107,7 @@ __owur int ssl_verify_alarm_type(long type); void ssl_sort_cipher_list(void); void ssl_load_ciphers(void); __owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, size_t len); size_t len, DOWNGRADE dgrd); __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, int free_pms); __owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm); Loading Loading @@ -2167,7 +2173,8 @@ __owur int ssl_version_supported(const SSL *s, int version); __owur int ssl_set_client_hello_version(SSL *s); __owur int ssl_check_version_downgrade(SSL *s); __owur int ssl_set_version_bound(int method_version, int version, int *bound); __owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello); __owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd); __owur int ssl_choose_client_version(SSL *s, int version); int ssl_get_client_min_max_version(const SSL *s, int *min_version, int *max_version); Loading
ssl/statem/statem_clnt.c +2 −1 Original line number Diff line number Diff line Loading @@ -1094,7 +1094,8 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) } else i = 1; if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)) <= 0) if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random), DOWNGRADE_NONE) <= 0) return 0; /*- Loading
ssl/statem/statem_lib.c +20 −1 Original line number Diff line number Diff line Loading @@ -1295,6 +1295,7 @@ typedef struct { # error Code needs update for TLS_method() support beyond TLS1_3_VERSION. #endif /* Must be in order high to low */ static const version_info tls_version_table[] = { #ifndef OPENSSL_NO_TLS1_3 {TLS1_3_VERSION, tlsv1_3_client_method, tlsv1_3_server_method}, Loading Loading @@ -1328,6 +1329,7 @@ static const version_info tls_version_table[] = { # error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. #endif /* Must be in order high to low */ static const version_info dtls_version_table[] = { #ifndef OPENSSL_NO_DTLS1_2 {DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method}, Loading Loading @@ -1510,6 +1512,20 @@ int ssl_set_version_bound(int method_version, int version, int *bound) return 1; } static void check_for_downgrade(SSL *s, int vers, DOWNGRADE *dgrd) { if (vers == TLS1_2_VERSION && ssl_version_supported(s, TLS1_3_VERSION)) { *dgrd = DOWNGRADE_TO_1_2; } else if (!SSL_IS_DTLS(s) && vers < TLS1_2_VERSION && (ssl_version_supported(s, TLS1_2_VERSION) || ssl_version_supported(s, TLS1_3_VERSION))) { *dgrd = DOWNGRADE_TO_1_1; } else { *dgrd = DOWNGRADE_NONE; } } /* * ssl_choose_server_version - Choose server (D)TLS version. Called when the * client HELLO is received to select the final server protocol version and Loading @@ -1519,7 +1535,7 @@ int ssl_set_version_bound(int method_version, int version, int *bound) * * Returns 0 on success or an SSL error reason number on failure. */ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) { /*- * With version-flexible methods we have an initial state with: Loading @@ -1544,6 +1560,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) if (!SSL_IS_TLS13(s)) { if (version_cmp(s, client_version, s->version) < 0) return SSL_R_WRONG_SSL_VERSION; *dgrd = DOWNGRADE_NONE; /* * If this SSL handle is not from a version flexible method we don't * (and never did) check min/max FIPS or Suite B constraints. Hope Loading Loading @@ -1620,6 +1637,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) return SSL_R_UNSUPPORTED_PROTOCOL; return 0; } check_for_downgrade(s, best_vers, dgrd); s->version = best_vers; s->method = best_method; return 0; Loading @@ -1646,6 +1664,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello) continue; method = vent->smeth(); if (ssl_method_error(s, method) == 0) { check_for_downgrade(s, vent->version, dgrd); s->version = vent->version; s->method = method; return 0; Loading
ssl/statem/statem_srvr.c +4 −3 Original line number Diff line number Diff line Loading @@ -1476,6 +1476,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) STACK_OF(SSL_CIPHER) *ciphers = NULL; STACK_OF(SSL_CIPHER) *scsvs = NULL; CLIENTHELLO_MSG *clienthello = s->clienthello; DOWNGRADE dgrd = DOWNGRADE_NONE; *al = SSL_AD_INTERNAL_ERROR; /* Finished parsing the ClientHello, now we can start processing it */ Loading Loading @@ -1516,7 +1517,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) * versions are potentially compatible. Version negotiation comes later. */ if (!SSL_IS_DTLS(s)) { protverr = ssl_choose_server_version(s, clienthello); protverr = ssl_choose_server_version(s, clienthello, &dgrd); } else if (s->method->version != DTLS_ANY_VERSION && DTLS_VERSION_LT((int)clienthello->legacy_version, s->version)) { protverr = SSL_R_VERSION_TOO_LOW; Loading Loading @@ -1565,7 +1566,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) s->d1->cookie_verified = 1; } if (s->method->version == DTLS_ANY_VERSION) { protverr = ssl_choose_server_version(s, clienthello); protverr = ssl_choose_server_version(s, clienthello, &dgrd); if (protverr != 0) { SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr); s->version = s->client_version; Loading Loading @@ -1722,7 +1723,7 @@ static int tls_early_post_process_client_hello(SSL *s, int *al) { unsigned char *pos; pos = s->s3->server_random; if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE, dgrd) <= 0) { goto err; } } Loading