[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Wed May 10 15:53:35 UTC 2017


The branch master has been updated
       via  bb01ef3f4ae3b54b20e0c3afc9b55e43a92fef8f (commit)
       via  21181889d78f95f10738813285f681acd3b32c6c (commit)
      from  cf53cbea5bbf9c3a1998e2ddd0173881a5a97475 (commit)


- Log -----------------------------------------------------------------
commit bb01ef3f4ae3b54b20e0c3afc9b55e43a92fef8f
Author: Matt Caswell <matt at openssl.org>
Date:   Wed May 10 10:54:18 2017 +0100

    Add a test for SNI in conjunction with custom extensions
    
    Test that custom extensions still work even after a change in SSL_CTX due
    to SNI. See #2180.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3425)

commit 21181889d78f95f10738813285f681acd3b32c6c
Author: Matt Caswell <matt at openssl.org>
Date:   Wed May 10 11:28:53 2017 +0100

    Copy custom extension flags in a call to SSL_set_SSL_CTX()
    
    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 at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/3425)

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

Summary of changes:
 ssl/ssl_lib.c                |  6 ++++
 ssl/ssl_locl.h               |  2 ++
 ssl/statem/extensions_cust.c | 20 ++++++++++++++
 test/sslapitest.c            | 66 +++++++++++++++++++++++++++++++++++++-------
 test/ssltestlib.c            |  5 ++--
 5 files changed, 87 insertions(+), 12 deletions(-)

diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index d1a1f02..a12800d 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3596,6 +3596,12 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
     if (new_cert == NULL) {
         return NULL;
     }
+
+    if (!custom_exts_copy_flags(&new_cert->custext, &ssl->cert->custext)) {
+        ssl_cert_free(new_cert);
+        return NULL;
+    }
+
     ssl_cert_free(ssl->cert);
     ssl->cert = new_cert;
 
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 1d3a207..0644c7f 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -2470,6 +2470,8 @@ __owur int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x,
 
 __owur int custom_exts_copy(custom_ext_methods *dst,
                             const custom_ext_methods *src);
+__owur int custom_exts_copy_flags(custom_ext_methods *dst,
+                                  const custom_ext_methods *src);
 void custom_exts_free(custom_ext_methods *exts);
 
 void ssl_comp_free_compression_methods_int(void);
diff --git a/ssl/statem/extensions_cust.c b/ssl/statem/extensions_cust.c
index 2a21ec4..e06fa9d 100644
--- a/ssl/statem/extensions_cust.c
+++ b/ssl/statem/extensions_cust.c
@@ -231,6 +231,26 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx,
     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->role,
+                                                     methsrc->ext_type, NULL);
+
+        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)
 {
diff --git a/test/sslapitest.c b/test/sslapitest.c
index bfa3a30..1522613 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -1793,6 +1793,7 @@ static int clntaddnewcb = 0;
 static int clntparsenewcb = 0;
 static int srvaddnewcb = 0;
 static int srvparsenewcb = 0;
+static int snicb = 0;
 
 #define TEST_EXT_TYPE1  0xff00
 
@@ -1886,16 +1887,30 @@ static int new_parse_cb(SSL *s, unsigned int ext_type, unsigned int context,
 
     return 1;
 }
+
+static int sni_cb(SSL *s, int *al, void *arg)
+{
+    SSL_CTX *ctx = (SSL_CTX *)arg;
+
+    if (SSL_set_SSL_CTX(s, ctx) == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        return SSL_TLSEXT_ERR_ALERT_FATAL;
+    }
+    snicb++;
+    return SSL_TLSEXT_ERR_OK;
+}
+
 /*
  * Custom call back tests.
  * Test 0: Old style callbacks in TLSv1.2
  * Test 1: New style callbacks in TLSv1.2
- * Test 2: New style callbacks in TLSv1.3. Extensions in CH and EE
- * Test 3: New style callbacks in TLSv1.3. Extensions in CH, SH, EE, Cert + NST
+ * Test 2: New style callbacks in TLSv1.2 with SNI
+ * Test 3: New style callbacks in TLSv1.3. Extensions in CH and EE
+ * Test 4: New style callbacks in TLSv1.3. Extensions in CH, SH, EE, Cert + NST
  */
 static int test_custom_exts(int tst)
 {
-    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL_CTX *cctx = NULL, *sctx = NULL, *sctx2 = NULL;
     SSL *clientssl = NULL, *serverssl = NULL;
     int testresult = 0;
     static int server = 1;
@@ -1906,18 +1921,27 @@ static int test_custom_exts(int tst)
     /* Reset callback counters */
     clntaddoldcb = clntparseoldcb = srvaddoldcb = srvparseoldcb = 0;
     clntaddnewcb = clntparsenewcb = srvaddnewcb = srvparsenewcb = 0;
+    snicb = 0;
 
     if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
                                        TLS_client_method(), &sctx,
                                        &cctx, cert, privkey)))
         goto end;
 
-    if (tst < 2) {
+    if (tst == 2
+            && !TEST_true(create_ssl_ctx_pair(TLS_server_method(), NULL, &sctx2,
+                                              NULL, cert, privkey)))
+        goto end;
+
+
+    if (tst < 3) {
         SSL_CTX_set_options(cctx, SSL_OP_NO_TLSv1_3);
         SSL_CTX_set_options(sctx, SSL_OP_NO_TLSv1_3);
+        if (sctx2 != NULL)
+            SSL_CTX_set_options(sctx2, SSL_OP_NO_TLSv1_3);
     }
 
-    if (tst == 3) {
+    if (tst == 4) {
         context = SSL_EXT_CLIENT_HELLO
                   | SSL_EXT_TLS1_2_SERVER_HELLO
                   | SSL_EXT_TLS1_3_SERVER_HELLO
@@ -1967,6 +1991,12 @@ static int test_custom_exts(int tst)
                                               new_add_cb, new_free_cb,
                                               &server, new_parse_cb, &server)))
             goto end;
+        if (sctx2 != NULL
+                && !TEST_true(SSL_CTX_add_custom_ext(sctx2, TEST_EXT_TYPE1,
+                                                     context, new_add_cb,
+                                                     new_free_cb, &server,
+                                                     new_parse_cb, &server)))
+            goto end;
     }
 
     /* Should not be able to add duplicates */
@@ -1980,6 +2010,13 @@ static int test_custom_exts(int tst)
                                                   new_parse_cb, &server)))
         goto end;
 
+    if (tst == 2) {
+        /* Set up SNI */
+        if (!TEST_true(SSL_CTX_set_tlsext_servername_callback(sctx, sni_cb))
+                || !TEST_true(SSL_CTX_set_tlsext_servername_arg(sctx, sctx2)))
+            goto end;
+    }
+
     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
                                       &clientssl, NULL, NULL))
             || !TEST_true(create_ssl_connection(serverssl, clientssl,
@@ -1992,11 +2029,13 @@ static int test_custom_exts(int tst)
                 || srvaddoldcb != 1
                 || srvparseoldcb != 1)
             goto end;
-    } else if (tst == 1 || tst == 2) {
+    } else if (tst == 1 || tst == 2 || tst == 3) {
         if (clntaddnewcb != 1
                 || clntparsenewcb != 1
                 || srvaddnewcb != 1
-                || srvparsenewcb != 1)
+                || srvparsenewcb != 1
+                || (tst != 2 && snicb != 0)
+                || (tst == 2 && snicb != 1))
             goto end;
     } else {
         if (clntaddnewcb != 1
@@ -2013,6 +2052,12 @@ static int test_custom_exts(int tst)
     SSL_free(clientssl);
     serverssl = clientssl = NULL;
 
+    if (tst == 3) {
+        /* We don't bother with the resumption aspects for this test */
+        testresult = 1;
+        goto end;
+    }
+
     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
                                       NULL, NULL))
             || !TEST_true(SSL_set_session(clientssl, sess))
@@ -2032,7 +2077,7 @@ static int test_custom_exts(int tst)
                 || srvaddoldcb != 1
                 || srvparseoldcb != 1)
             goto end;
-    } else if (tst == 1 || tst == 2) {
+    } else if (tst == 1 || tst == 2 || tst == 3) {
         if (clntaddnewcb != 2
                 || clntparsenewcb != 2
                 || srvaddnewcb != 2
@@ -2053,6 +2098,7 @@ end:
     SSL_SESSION_free(sess);
     SSL_free(serverssl);
     SSL_free(clientssl);
+    SSL_CTX_free(sctx2);
     SSL_CTX_free(sctx);
     SSL_CTX_free(cctx);
     return testresult;
@@ -2161,9 +2207,9 @@ int test_main(int argc, char *argv[])
 # endif
 #endif
 #ifndef OPENSSL_NO_TLS1_3
-    ADD_ALL_TESTS(test_custom_exts, 4);
+    ADD_ALL_TESTS(test_custom_exts, 5);
 #else
-    ADD_ALL_TESTS(test_custom_exts, 2);
+    ADD_ALL_TESTS(test_custom_exts, 3);
 #endif
     ADD_ALL_TESTS(test_serverinfo, 8);
 
diff --git a/test/ssltestlib.c b/test/ssltestlib.c
index 9bce0d3..1f74c95 100644
--- a/test/ssltestlib.c
+++ b/test/ssltestlib.c
@@ -518,7 +518,7 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
     SSL_CTX *clientctx = NULL;
 
     if (!TEST_ptr(serverctx = SSL_CTX_new(sm))
-            || !TEST_ptr(clientctx = SSL_CTX_new(cm)))
+            || (cctx != NULL && !TEST_ptr(clientctx = SSL_CTX_new(cm))))
         goto err;
 
     if (!TEST_int_eq(SSL_CTX_use_certificate_file(serverctx, certfile,
@@ -533,7 +533,8 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
 #endif
 
     *sctx = serverctx;
-    *cctx = clientctx;
+    if (cctx != NULL)
+        *cctx = clientctx;
     return 1;
 
  err:


More information about the openssl-commits mailing list