Factor out/change some of the legacy client version handling code.
authorjsing <jsing@openbsd.org>
Mon, 22 Feb 2021 15:59:10 +0000 (15:59 +0000)
committerjsing <jsing@openbsd.org>
Mon, 22 Feb 2021 15:59:10 +0000 (15:59 +0000)
This consolidates the version handling code and will make upcoming changes
easier.

ok tb@

lib/libssl/ssl_clnt.c
lib/libssl/ssl_locl.h
lib/libssl/ssl_versions.c

index bfff652..70bda98 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.83 2021/02/20 14:16:56 tb Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.84 2021/02/22 15:59:10 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -655,7 +655,7 @@ ssl3_send_client_hello(SSL *s)
        if (S3I(s)->hs.state == SSL3_ST_CW_CLNT_HELLO_A) {
                SSL_SESSION *sess = s->session;
 
-               if (ssl_supported_version_range(s, NULL, &max_version) != 1) {
+               if (!ssl_max_supported_version(s, &max_version)) {
                        SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
                        return (-1);
                }
@@ -852,7 +852,7 @@ ssl3_get_server_hello(SSL *s)
 {
        CBS cbs, server_random, session_id;
        uint16_t server_version, cipher_suite;
-       uint16_t min_version, max_version;
+       uint16_t max_version;
        uint8_t compression_method;
        const SSL_CIPHER *cipher;
        const SSL_METHOD *method;
@@ -896,12 +896,7 @@ ssl3_get_server_hello(SSL *s)
        if (!CBS_get_u16(&cbs, &server_version))
                goto decode_err;
 
-       if (ssl_supported_version_range(s, &min_version, &max_version) != 1) {
-               SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
-               goto err;
-       }
-
-       if (server_version < min_version || server_version > max_version) {
+       if (!ssl_check_version_from_server(s, server_version)) {
                SSLerror(s, SSL_R_WRONG_SSL_VERSION);
                s->version = (s->version & 0xff00) | (server_version & 0xff);
                al = SSL_AD_PROTOCOL_VERSION;
index fc61ffe..3a4d318 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.321 2021/02/20 09:43:29 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.322 2021/02/22 15:59:10 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -1123,12 +1123,14 @@ extern const SSL_CIPHER ssl3_ciphers[];
 const char *ssl_version_string(int ver);
 int ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
 int ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver);
-int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver);
 int ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
     uint16_t *out_ver, uint16_t *out_proto_ver);
 int ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
     uint16_t *out_ver, uint16_t *out_proto_ver);
 int ssl_downgrade_max_version(SSL *s, uint16_t *max_ver);
+int ssl_max_supported_version(SSL *s, uint16_t *max_ver);
+int ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver);
+int ssl_check_version_from_server(SSL *s, uint16_t server_version);
 int ssl_legacy_stack_version(SSL *s, uint16_t version);
 int ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher);
 int ssl_cipher_allowed_in_version_range(const SSL_CIPHER *cipher,
index 1ee5ed3..3c48019 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_versions.c,v 1.11 2021/02/20 09:43:29 jsing Exp $ */
+/* $OpenBSD: ssl_versions.c,v 1.12 2021/02/22 15:59:10 jsing Exp $ */
 /*
  * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
  *
@@ -162,6 +162,17 @@ ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
        return 1;
 }
 
+int
+ssl_max_supported_version(SSL *s, uint16_t *max_ver)
+{
+       *max_ver = 0;
+
+       if (!ssl_supported_version_range(s, NULL, max_ver))
+               return 0;
+
+       return 1;
+}
+
 int
 ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
 {
@@ -234,6 +245,22 @@ ssl_downgrade_max_version(SSL *s, uint16_t *max_ver)
        return 1;
 }
 
+int
+ssl_check_version_from_server(SSL *s, uint16_t server_version)
+{
+       uint16_t min_version, max_version;
+
+       /* Ensure that the version selected by the server is valid. */
+
+       if (SSL_is_dtls(s))
+               return (server_version == DTLS1_VERSION);
+
+       if (!ssl_supported_version_range(s, &min_version, &max_version))
+               return 0;
+
+       return (server_version >= min_version && server_version <= max_version);
+}
+
 int
 ssl_legacy_stack_version(SSL *s, uint16_t version)
 {