[openssl-commits] [openssl] OpenSSL_1_1_0-stable update

kaduk at mit.edu kaduk at mit.edu
Fri Sep 15 16:46:31 UTC 2017


The branch OpenSSL_1_1_0-stable has been updated
       via  af51a74ade8bbab5ed49a3560dcb70d89896dc29 (commit)
       via  a8b85c5ffee1f5adf7a27fcc5613b752b1a28b63 (commit)
      from  583d8f6342f1a6e01e72cf55bffabf5b90797317 (commit)


- Log -----------------------------------------------------------------
commit af51a74ade8bbab5ed49a3560dcb70d89896dc29
Author: Christian Heimes <christian at python.org>
Date:   Thu Sep 14 09:28:39 2017 +0200

    Provide getters for min/max proto version
    
    OpenSSL 1.1.0 made SSL_CTX and SSL structs opaque and introduced a new
    API to set the minimum and maximum protocol version for SSL_CTX with
    TLS_method(). Add getters to introspect the configured versions:
    
      int SSL_CTX_get_min_proto_version(SSL_CTX *ctx);
      int SSL_CTX_get_max_proto_version(SSL_CTX *ctx);
      int SSL_get_min_proto_version(SSL *ssl);
      int SSL_get_max_proto_version(SSL *ssl);
    
    NOTE: The getters do not resolv the version in case when the minimum or
    maxium version are configured as '0' (meaning auto-select lowest and
    highst version number).
    
    Signed-off-by: Christian Heimes <christian at python.org>
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    Reviewed-by: Ben Kaduk <kaduk at mit.edu>
    
    (cherry picked from commit 3edabd3ccb7aac89af5a63cfb2378e33a8be05d7)
    
    Updated for new manual page location and TLS 1.3.
    
    (Merged from https://github.com/openssl/openssl/pull/4376)

commit a8b85c5ffee1f5adf7a27fcc5613b752b1a28b63
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date:   Tue May 9 18:39:50 2017 -0500

    Error out when forcing an unsupported TLS version
    
    If the result of a SSL_{CTX_,}set_{min,max}_proto_version() call
    leaves the min and max version identical, and support for that version
    is compiled out of the library, return an error.  Such an object has
    no hope of successfully completing a handshake, and this error may
    be easier to decipher than the resulting handshake failure.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    
    (cherry picked from commit c8feba723a33e15201009d716d9ead02e653dfe6)
    
    Updated the cherry-pick to not reference TLS1_3_VERSION, which does
    not exist on this branch.
    
    (Merged from https://github.com/openssl/openssl/pull/4376)

-----------------------------------------------------------------------

Summary of changes:
 doc/ssl/SSL_CTX_set_min_proto_version.pod |  21 ++++-
 include/openssl/ssl.h                     |  10 +++
 ssl/ssl_lib.c                             | 127 ++++++++++++++++++++++++++++--
 3 files changed, 146 insertions(+), 12 deletions(-)

diff --git a/doc/ssl/SSL_CTX_set_min_proto_version.pod b/doc/ssl/SSL_CTX_set_min_proto_version.pod
index 3e9fe80..ff080e4 100644
--- a/doc/ssl/SSL_CTX_set_min_proto_version.pod
+++ b/doc/ssl/SSL_CTX_set_min_proto_version.pod
@@ -3,7 +3,9 @@
 =head1 NAME
 
 SSL_CTX_set_min_proto_version, SSL_CTX_set_max_proto_version,
-SSL_set_min_proto_version, SSL_set_max_proto_version - Set minimum
+SSL_CTX_get_min_proto_version, SSL_CTX_get_max_proto_version,
+SSL_set_min_proto_version, SSL_set_max_proto_version,
+SSL_get_min_proto_version, SSL_get_max_proto_version - Get and set minimum
 and maximum supported protocol version
 
 =head1 SYNOPSIS
@@ -12,12 +14,17 @@ and maximum supported protocol version
 
  int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
  int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version);
+ int SSL_CTX_get_min_proto_version(SSL_CTX *ctx);
+ int SSL_CTX_get_max_proto_version(SSL_CTX *ctx);
+
  int SSL_set_min_proto_version(SSL *ssl, int version);
  int SSL_set_max_proto_version(SSL *ssl, int version);
+ int SSL_get_min_proto_version(SSL *ssl);
+ int SSL_get_max_proto_version(SSL *ssl);
 
 =head1 DESCRIPTION
 
-The functions set the minimum and maximum supported protocol versions
+The functions get or set the minimum and maximum supported protocol versions
 for the B<ctx> or B<ssl>.
 This works in combination with the options set via
 L<SSL_CTX_set_options(3)> that also make it possible to disable
@@ -28,13 +35,18 @@ Setting the minimum or maximum version to 0, will enable protocol
 versions down to the lowest version, or up to the highest version
 supported by the library, respectively.
 
+Getters return 0 in case B<ctx> or B<ssl> have been configured to
+automatically use the lowest or highest version supported by the library.
+
 Currently supported versions are B<SSL3_VERSION>, B<TLS1_VERSION>,
 B<TLS1_1_VERSION>, B<TLS1_2_VERSION> for TLS and B<DTLS1_VERSION>,
 B<DTLS1_2_VERSION> for DTLS.
 
 =head1 RETURN VALUES
 
-These functions return 1 on success and 0 on failure.
+These setter functions return 1 on success and 0 on failure. The getter
+functions return the configured version or 0 for auto-configuration of
+lowest or highest protocol, respectively.
 
 =head1 NOTES
 
@@ -42,7 +54,8 @@ All these functions are implemented using macros.
 
 =head1 HISTORY
 
-The functions were added in OpenSSL 1.1.0
+The setter functions were added in OpenSSL 1.1.0. The getter functions
+were added in OpenSSL 1.1.1.
 
 =head1 SEE ALSO
 
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 2c694b4..940a5f0 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1158,6 +1158,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 # define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE     127
 # define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB       128
 # define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG   129
+# define SSL_CTRL_GET_MIN_PROTO_VERSION          130
+# define SSL_CTRL_GET_MAX_PROTO_VERSION          131
 # define SSL_CERT_SET_FIRST                      1
 # define SSL_CERT_SET_NEXT                       2
 # define SSL_CERT_SET_SERVER                     3
@@ -1289,10 +1291,18 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
         SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
 #define SSL_CTX_set_max_proto_version(ctx, version) \
         SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
+#define SSL_CTX_get_min_proto_version(ctx) \
+        SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, NULL, NULL)
+#define SSL_CTX_get_max_proto_version(ctx) \
+        SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, NULL, NULL)
 #define SSL_set_min_proto_version(s, version) \
         SSL_ctrl(s, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
 #define SSL_set_max_proto_version(s, version) \
         SSL_ctrl(s, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
+#define SSL_get_min_proto_version(s) \
+        SSL_ctrl(s, SSL_CTRL_GET_MIN_PROTO_VERSION, NULL, NULL)
+#define SSL_get_max_proto_version(s) \
+        SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, NULL, NULL)
 
 #if OPENSSL_API_COMPAT < 0x10100000L
 /* Provide some compatibility macros for removed functionality. */
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 3f49cfb..6908f16 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -432,6 +432,105 @@ static int dane_tlsa_add(SSL_DANE *dane,
     return 1;
 }
 
+/*
+ * Return 0 if there is only one version configured and it was disabled
+ * at configure time.  Return 1 otherwise.
+ */
+static int ssl_check_allowed_versions(int min_version, int max_version)
+{
+    int minisdtls = 0, maxisdtls = 0;
+
+    /* Figure out if we're doing DTLS versions or TLS versions */
+    if (min_version == DTLS1_BAD_VER
+        || min_version >> 8 == DTLS1_VERSION_MAJOR)
+        minisdtls = 1;
+    if (max_version == DTLS1_BAD_VER
+        || max_version >> 8 == DTLS1_VERSION_MAJOR)
+        maxisdtls = 1;
+    /* A wildcard version of 0 could be DTLS or TLS. */
+    if ((minisdtls && !maxisdtls && max_version != 0)
+        || (maxisdtls && !minisdtls && min_version != 0)) {
+        /* Mixing DTLS and TLS versions will lead to sadness; deny it. */
+        return 0;
+    }
+
+    if (minisdtls || maxisdtls) {
+        /* Do DTLS version checks. */
+        if (min_version == 0)
+            /* Ignore DTLS1_BAD_VER */
+            min_version = DTLS1_VERSION;
+        if (max_version == 0)
+            max_version = DTLS1_2_VERSION;
+#ifdef OPENSSL_NO_DTLS1_2
+        if (max_version == DTLS1_2_VERSION)
+            max_version = DTLS1_VERSION;
+#endif
+#ifdef OPENSSL_NO_DTLS1
+        if (min_version == DTLS1_VERSION)
+            min_version = DTLS1_2_VERSION;
+#endif
+	/* Done massaging versions; do the check. */
+	if (0
+#ifdef OPENSSL_NO_DTLS1
+            || (DTLS_VERSION_GE(min_version, DTLS1_VERSION)
+                && DTLS_VERSION_GE(DTLS1_VERSION, max_version))
+#endif
+#ifdef OPENSSL_NO_DTLS1_2
+            || (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION)
+                && DTLS_VERSION_GE(DTLS1_2_VERSION, max_version))
+#endif
+            )
+            return 0;
+    } else {
+        /* Regular TLS version checks. */
+	if (min_version == 0)
+	    min_version = SSL3_VERSION;
+	if (max_version == 0)
+	    max_version = TLS1_2_VERSION;
+#ifdef OPENSSL_NO_TLS1_2
+	if (max_version == TLS1_2_VERSION)
+	    max_version = TLS1_1_VERSION;
+#endif
+#ifdef OPENSSL_NO_TLS1_1
+	if (max_version == TLS1_1_VERSION)
+	    max_version = TLS1_VERSION;
+#endif
+#ifdef OPENSSL_NO_TLS1
+	if (max_version == TLS1_VERSION)
+	    max_version = SSL3_VERSION;
+#endif
+#ifdef OPENSSL_NO_SSL3
+	if (min_version == SSL3_VERSION)
+	    min_version = TLS1_VERSION;
+#endif
+#ifdef OPENSSL_NO_TLS1
+	if (min_version == TLS1_VERSION)
+	    min_version = TLS1_1_VERSION;
+#endif
+#ifdef OPENSSL_NO_TLS1_1
+	if (min_version == TLS1_1_VERSION)
+	    min_version = TLS1_2_VERSION;
+#endif
+	/* Done massaging versions; do the check. */
+	if (0
+#ifdef OPENSSL_NO_SSL3
+            || (min_version <= SSL3_VERSION && SSL3_VERSION <= max_version)
+#endif
+#ifdef OPENSSL_NO_TLS1
+            || (min_version <= TLS1_VERSION && TLS1_VERSION <= max_version)
+#endif
+#ifdef OPENSSL_NO_TLS1_1
+            || (min_version <= TLS1_1_VERSION && TLS1_1_VERSION <= max_version)
+#endif
+#ifdef OPENSSL_NO_TLS1_2
+            || (min_version <= TLS1_2_VERSION && TLS1_2_VERSION <= max_version)
+#endif
+            )
+            return 0;
+    }
+    return 1;
+}
+
 static void clear_ciphers(SSL *s)
 {
     /* clear the current cipher */
@@ -1739,11 +1838,17 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
         else
             return 0;
     case SSL_CTRL_SET_MIN_PROTO_VERSION:
-        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
-                                     &s->min_proto_version);
+        return ssl_check_allowed_versions(larg, s->max_proto_version)
+               && ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                        &s->min_proto_version);
+    case SSL_CTRL_GET_MIN_PROTO_VERSION:
+        return s->min_proto_version;
     case SSL_CTRL_SET_MAX_PROTO_VERSION:
-        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
-                                     &s->max_proto_version);
+        return ssl_check_allowed_versions(s->min_proto_version, larg)
+               && ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                        &s->max_proto_version);
+    case SSL_CTRL_GET_MAX_PROTO_VERSION:
+        return s->max_proto_version;
     default:
         return (s->method->ssl_ctrl(s, cmd, larg, parg));
     }
@@ -1869,11 +1974,17 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
     case SSL_CTRL_CLEAR_CERT_FLAGS:
         return (ctx->cert->cert_flags &= ~larg);
     case SSL_CTRL_SET_MIN_PROTO_VERSION:
-        return ssl_set_version_bound(ctx->method->version, (int)larg,
-                                     &ctx->min_proto_version);
+        return ssl_check_allowed_versions(larg, ctx->max_proto_version)
+               && ssl_set_version_bound(ctx->method->version, (int)larg,
+                                        &ctx->min_proto_version);
+    case SSL_CTRL_GET_MIN_PROTO_VERSION:
+        return ctx->min_proto_version;
     case SSL_CTRL_SET_MAX_PROTO_VERSION:
-        return ssl_set_version_bound(ctx->method->version, (int)larg,
-                                     &ctx->max_proto_version);
+        return ssl_check_allowed_versions(ctx->min_proto_version, larg)
+               && ssl_set_version_bound(ctx->method->version, (int)larg,
+                                        &ctx->max_proto_version);
+    case SSL_CTRL_GET_MAX_PROTO_VERSION:
+        return ctx->max_proto_version;
     default:
         return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg));
     }


More information about the openssl-commits mailing list