[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Wed May 2 22:34:49 UTC 2018


The branch master has been updated
       via  e401389a0cc8ce807aa52e30cf5aba080a62b2df (commit)
       via  6021d8ec5affe07116cdae81fa3db81d67996aac (commit)
       via  3bfa4756bd02659fa9f9a265550862c562749db6 (commit)
       via  f054160a1923845f40d15457d1009420827f4c88 (commit)
       via  a216df599a6076147c27acea6c976fb11f505b1a (commit)
      from  c7e10755fac1d8f4421aa60646d311ab2068752d (commit)


- Log -----------------------------------------------------------------
commit e401389a0cc8ce807aa52e30cf5aba080a62b2df
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Apr 27 12:20:04 2018 +0100

    Add a test for SSL_get_shared_ciphers()
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6113)

commit 6021d8ec5affe07116cdae81fa3db81d67996aac
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Apr 27 12:09:08 2018 +0100

    Fix a bug in create_ssl_ctx_pair()
    
    The max protocol version was only being set on the server side. It should
    have been done on both the client and the server.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6113)

commit 3bfa4756bd02659fa9f9a265550862c562749db6
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Apr 27 11:38:19 2018 +0100

    Add some documentation for SSL_get_shared_ciphers()
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6113)

commit f054160a1923845f40d15457d1009420827f4c88
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Apr 27 11:24:01 2018 +0100

    Fix comment in ssl_locl.h
    
    The ciphers field in a session contains the stack of ciphers offered by
    the client.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6113)

commit a216df599a6076147c27acea6c976fb11f505b1a
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Apr 27 11:20:52 2018 +0100

    Fix SSL_get_shared_ciphers()
    
    The function SSL_get_shared_ciphers() is supposed to return ciphers shared
    by the client and the server. However it only ever returned the client
    ciphers.
    
    Fixes #5317
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6113)

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

Summary of changes:
 doc/man3/SSL_get_ciphers.pod |  24 ++++++++--
 doc/man7/ssl.pod             |   2 +-
 include/openssl/ssl.h        |   2 +-
 ssl/ssl_lib.c                |  27 +++++++----
 ssl/ssl_locl.h               |   2 +-
 test/sslapitest.c            | 104 +++++++++++++++++++++++++++++++++++++++++++
 test/ssltestlib.c            |   4 +-
 7 files changed, 148 insertions(+), 17 deletions(-)

diff --git a/doc/man3/SSL_get_ciphers.pod b/doc/man3/SSL_get_ciphers.pod
index d91afc2..89d9461 100644
--- a/doc/man3/SSL_get_ciphers.pod
+++ b/doc/man3/SSL_get_ciphers.pod
@@ -2,9 +2,13 @@
 
 =head1 NAME
 
-SSL_get1_supported_ciphers, SSL_get_client_ciphers,
-SSL_get_ciphers, SSL_CTX_get_ciphers,
-SSL_bytes_to_cipher_list, SSL_get_cipher_list
+SSL_get1_supported_ciphers,
+SSL_get_client_ciphers,
+SSL_get_ciphers,
+SSL_CTX_get_ciphers,
+SSL_bytes_to_cipher_list,
+SSL_get_cipher_list,
+SSL_get_shared_ciphers
 - get list of available SSL_CIPHERs
 
 =head1 SYNOPSIS
@@ -19,6 +23,7 @@ SSL_bytes_to_cipher_list, SSL_get_cipher_list
                               int isv2format, STACK_OF(SSL_CIPHER) **sk,
                               STACK_OF(SSL_CIPHER) **scsvs);
  const char *SSL_get_cipher_list(const SSL *ssl, int priority);
+ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size);
 
 =head1 DESCRIPTION
 
@@ -58,6 +63,19 @@ listed for B<ssl> with B<priority>. If B<ssl> is NULL, no ciphers are
 available, or there are less ciphers than B<priority> available, NULL
 is returned.
 
+SSL_get_shared_ciphers() creates a colon separated and NUL terminated list of
+SSL_CIPHER names that are available in both the client and the server. B<buf> is
+the buffer that should be populated with the list of names and B<size> is the
+size of that buffer. A pointer to B<buf> is returned on success or NULL on
+error. If the supplied buffer is not large enough to contain the complete list
+of names then a truncated list of names will be returned. Note that just because
+a ciphersuite is available (i.e. it is configured in the cipher list) and shared
+by both the client and the server it does not mean that it is enabled (see the
+description of SSL_get1_supported_ciphers() above). This function will return
+available shared ciphersuites whether or not they are enabled. This is a server
+side function only and must only be called after the completion of the initial
+handshake.
+
 =head1 NOTES
 
 The details of the ciphers obtained by SSL_get_ciphers(), SSL_CTX_get_ciphers()
diff --git a/doc/man7/ssl.pod b/doc/man7/ssl.pod
index 7cf7d61..c1e4924 100644
--- a/doc/man7/ssl.pod
+++ b/doc/man7/ssl.pod
@@ -570,7 +570,7 @@ fresh handle for each connection.
 
 =item SSL_SESSION *B<SSL_get_session>(const SSL *ssl);
 
-=item char *B<SSL_get_shared_ciphers>(const SSL *ssl, char *buf, int len);
+=item char *B<SSL_get_shared_ciphers>(const SSL *ssl, char *buf, int size);
 
 =item int B<SSL_get_shutdown>(const SSL *ssl);
 
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 4b45ae7..4bd53fc 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1497,7 +1497,7 @@ __owur int SSL_get_fd(const SSL *s);
 __owur int SSL_get_rfd(const SSL *s);
 __owur int SSL_get_wfd(const SSL *s);
 __owur const char *SSL_get_cipher_list(const SSL *s, int n);
-__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size);
 __owur int SSL_get_read_ahead(const SSL *s);
 __owur int SSL_pending(const SSL *s);
 __owur int SSL_has_pending(const SSL *s);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 2a57831..3aefa34 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2549,28 +2549,37 @@ int SSL_set_cipher_list(SSL *s, const char *str)
     return 1;
 }
 
-char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
+char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size)
 {
     char *p;
-    STACK_OF(SSL_CIPHER) *sk;
+    STACK_OF(SSL_CIPHER) *clntsk, *srvrsk;
     const SSL_CIPHER *c;
     int i;
 
-    if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2))
+    if (!s->server
+            || s->session == NULL
+            || s->session->ciphers == NULL
+            || size < 2)
         return NULL;
 
     p = buf;
-    sk = s->session->ciphers;
+    clntsk = s->session->ciphers;
+    srvrsk = SSL_get_ciphers(s);
+    if (clntsk == NULL || srvrsk == NULL)
+        return NULL;
 
-    if (sk_SSL_CIPHER_num(sk) == 0)
+    if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0)
         return NULL;
 
-    for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
+    for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) {
         int n;
 
-        c = sk_SSL_CIPHER_value(sk, i);
+        c = sk_SSL_CIPHER_value(clntsk, i);
+        if (sk_SSL_CIPHER_find(srvrsk, c) < 0)
+            continue;
+
         n = strlen(c->name);
-        if (n + 1 > len) {
+        if (n + 1 > size) {
             if (p != buf)
                 --p;
             *p = '\0';
@@ -2579,7 +2588,7 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
         strcpy(p, c->name);
         p += n;
         *(p++) = ':';
-        len -= n + 1;
+        size -= n + 1;
     }
     p[-1] = '\0';
     return buf;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index d881458..b32b23b 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -550,7 +550,7 @@ struct ssl_session_st {
     const SSL_CIPHER *cipher;
     unsigned long cipher_id;    /* when ASN.1 loaded, this needs to be used to
                                  * load the 'cipher' structure */
-    STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
+    STACK_OF(SSL_CIPHER) *ciphers; /* ciphers offered by the client */
     CRYPTO_EX_DATA ex_data;     /* application specific data */
     /*
      * These are used to make removal of session-ids more efficient and to
diff --git a/test/sslapitest.c b/test/sslapitest.c
index 832746c..0aac80b 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -4452,6 +4452,109 @@ static int test_ssl_pending(int tst)
     return testresult;
 }
 
+static struct {
+    unsigned int maxprot;
+    const char *clntciphers;
+    const char *clnttls13ciphers;
+    const char *srvrciphers;
+    const char *srvrtls13ciphers;
+    const char *shared;
+} shared_ciphers_data[] = {
+    {
+        TLS1_2_VERSION,
+        "AES128-SHA:AES256-SHA",
+        NULL,
+        "AES256-SHA:DHE-RSA-AES128-SHA",
+        NULL,
+        "AES256-SHA"
+    },
+    {
+        TLS1_2_VERSION,
+        "AES128-SHA:DHE-RSA-AES128-SHA:AES256-SHA",
+        NULL,
+        "AES128-SHA:DHE-RSA-AES256-SHA:AES256-SHA",
+        NULL,
+        "AES128-SHA:AES256-SHA"
+    },
+    {
+        TLS1_2_VERSION,
+        "AES128-SHA:AES256-SHA",
+        NULL,
+        "AES128-SHA:DHE-RSA-AES128-SHA",
+        NULL,
+        "AES128-SHA"
+    },
+#ifndef OPENSSL_NO_TLS1_3
+    {
+        TLS1_3_VERSION,
+        "AES128-SHA:AES256-SHA",
+        NULL,
+        "AES256-SHA:AES128-SHA256",
+        NULL,
+        "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:"
+        "TLS_AES_128_GCM_SHA256:AES256-SHA"
+    },
+    {
+        TLS1_3_VERSION,
+        "AES128-SHA",
+        "TLS_AES_256_GCM_SHA384",
+        "AES256-SHA",
+        "TLS_AES_256_GCM_SHA384",
+        "TLS_AES_256_GCM_SHA384"
+    },
+#endif
+};
+
+static int test_ssl_get_shared_ciphers(int tst)
+{
+    SSL_CTX *cctx = NULL, *sctx = NULL;
+    SSL *clientssl = NULL, *serverssl = NULL;
+    int testresult = 0;
+    char buf[1024];
+
+    if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+                                       TLS_client_method(),
+                                       TLS1_VERSION,
+                                       shared_ciphers_data[tst].maxprot,
+                                       &sctx, &cctx, cert, privkey)))
+        goto end;
+
+    if (!TEST_true(SSL_CTX_set_cipher_list(cctx,
+                                        shared_ciphers_data[tst].clntciphers))
+            || (shared_ciphers_data[tst].clnttls13ciphers != NULL
+                && !TEST_true(SSL_CTX_set_ciphersuites(cctx,
+                                    shared_ciphers_data[tst].clnttls13ciphers)))
+            || !TEST_true(SSL_CTX_set_cipher_list(sctx,
+                                        shared_ciphers_data[tst].srvrciphers))
+            || (shared_ciphers_data[tst].srvrtls13ciphers != NULL
+                && !TEST_true(SSL_CTX_set_ciphersuites(sctx,
+                                    shared_ciphers_data[tst].srvrtls13ciphers))))
+        goto end;
+
+
+    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+                                             NULL, NULL))
+            || !TEST_true(create_ssl_connection(serverssl, clientssl,
+                                                SSL_ERROR_NONE)))
+        goto end;
+
+    if (!TEST_ptr(SSL_get_shared_ciphers(serverssl, buf, sizeof(buf)))
+            || !TEST_int_eq(strcmp(buf, shared_ciphers_data[tst].shared), 0)) {
+        TEST_info("Shared ciphers are: %s\n", buf);
+        goto end;
+    }
+
+    testresult = 1;
+
+ end:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    SSL_CTX_free(sctx);
+    SSL_CTX_free(cctx);
+
+    return testresult;
+}
+
 int setup_tests(void)
 {
     if (!TEST_ptr(cert = test_get_argument(0))
@@ -4544,6 +4647,7 @@ int setup_tests(void)
 #endif
     ADD_ALL_TESTS(test_info_callback, 6);
     ADD_ALL_TESTS(test_ssl_pending, 2);
+    ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data));
     return 1;
 }
 
diff --git a/test/ssltestlib.c b/test/ssltestlib.c
index ebd87cc..959e329 100644
--- a/test/ssltestlib.c
+++ b/test/ssltestlib.c
@@ -531,10 +531,10 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
         goto err;
     if (clientctx != NULL
         && ((min_proto_version > 0
-             && !TEST_true(SSL_CTX_set_min_proto_version(serverctx,
+             && !TEST_true(SSL_CTX_set_min_proto_version(clientctx,
                                                          min_proto_version)))
             || (max_proto_version > 0
-                && !TEST_true(SSL_CTX_set_max_proto_version(serverctx,
+                && !TEST_true(SSL_CTX_set_max_proto_version(clientctx,
                                                             max_proto_version)))))
         goto err;
 


More information about the openssl-commits mailing list