Copy custom extension flags in a call to SSL_set_SSL_CTX()
authorMatt Caswell <matt@openssl.org>
Wed, 10 May 2017 10:28:53 +0000 (11:28 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 10 May 2017 13:06:58 +0000 (14:06 +0100)
The function SSL_set_SSL_CTX() can be used to swap the SSL_CTX used for
a connection as part of an SNI callback. One result of this is that the
s->cert structure is replaced. However this structure contains information
about any custom extensions that have been loaded. In particular flags are
set indicating whether a particular extension has been received in the
ClientHello. By replacing the s->cert structure we lose the custom
extension flag values, and it appears as if a client has not sent those
extensions.

SSL_set_SSL_CTX() should copy any flags for custom extensions that appear
in both the old and the new cert structure.

Fixes #2180

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3427)

ssl/ssl_lib.c
ssl/ssl_locl.h
ssl/t1_ext.c

index 4deae858f56d757a912d9ea4689a288a19472bcc..24be376c9fdf6e83a07d6c8fa01675dd78d0e089 100644 (file)
@@ -3194,6 +3194,9 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
         ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len;
         ocert->alpn_proposed = NULL;
         ssl->cert->alpn_sent = ocert->alpn_sent;
+
+        if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext))
+            return NULL;
 #endif
         ssl_cert_free(ocert);
     }
index 362c2b8a15dec456bd7f4ef9322f176a12a965ba..aeffc006347171e90c6d2afc6b165945b92f2132 100644 (file)
@@ -1482,6 +1482,8 @@ int custom_ext_add(SSL *s, int server,
                    unsigned char **pret, unsigned char *limit, int *al);
 
 int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src);
+int custom_exts_copy_flags(custom_ext_methods *dst,
+                           const custom_ext_methods *src);
 void custom_exts_free(custom_ext_methods *exts);
 
 # else
index 89099142e1f8c65cd69732326fc311397cacb9e8..0f4aba0226b423e07b7c46c4cfe982721111b4d6 100644 (file)
@@ -179,6 +179,25 @@ int custom_ext_add(SSL *s, int server,
     return 1;
 }
 
+/* Copy the flags from src to dst for any extensions that exist in both */
+int custom_exts_copy_flags(custom_ext_methods *dst,
+                           const custom_ext_methods *src)
+{
+    size_t i;
+    custom_ext_method *methsrc = src->meths;
+
+    for (i = 0; i < src->meths_count; i++, methsrc++) {
+        custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type);
+
+        if (methdst == NULL)
+            continue;
+
+        methdst->ext_flags = methsrc->ext_flags;
+    }
+
+    return 1;
+}
+
 /* Copy table of custom extensions */
 int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
 {