[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Mon Jun 12 08:36:34 UTC 2017


The branch master has been updated
       via  8ea404fb3ad97a21456af4075a62ddf1bfa06652 (commit)
       via  193b5d769cdaa3bc0778f7b7ae354618097ca61e (commit)
      from  0e1e4045c469f03294e33c0344d882e71dbd0d07 (commit)


- Log -----------------------------------------------------------------
commit 8ea404fb3ad97a21456af4075a62ddf1bfa06652
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date:   Fri Mar 17 09:39:01 2017 -0500

    Add sslapitest for SSL_early_get1_extensions_present()
    
    Call it from the early callback used for testing these functions, and verify
    the expected contents of the ClientHello
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2976)

commit 193b5d769cdaa3bc0778f7b7ae354618097ca61e
Author: Benjamin Kaduk <bkaduk at akamai.com>
Date:   Thu Mar 16 17:17:16 2017 -0500

    Add SSL_early_get1_extensions_present()
    
    It is an API to be used from the early callback that indicates what
    extensions were present in the ClientHello, and in what order.
    This can be used to eliminate unneeded calls to SSL_early_get0_ext()
    (which itself scales linearly in the number of extensions supported
    by the library).
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2976)

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

Summary of changes:
 doc/man3/SSL_CTX_set_early_cb.pod | 17 ++++++++++++++---
 include/openssl/ssl.h             |  1 +
 ssl/ssl_lib.c                     | 32 ++++++++++++++++++++++++++++++++
 ssl/ssl_locl.h                    |  2 ++
 ssl/statem/extensions.c           |  2 ++
 test/sslapitest.c                 | 15 +++++++++++++++
 util/libssl.num                   |  1 +
 7 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/doc/man3/SSL_CTX_set_early_cb.pod b/doc/man3/SSL_CTX_set_early_cb.pod
index 771e4ca..c2b4650 100644
--- a/doc/man3/SSL_CTX_set_early_cb.pod
+++ b/doc/man3/SSL_CTX_set_early_cb.pod
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-SSL_CTX_set_early_cb, SSL_early_cb_fn, SSL_early_isv2, SSL_early_get0_legacy_version, SSL_early_get0_random, SSL_early_get0_session_id, SSL_early_get0_ciphers, SSL_early_get0_compression_methods, SSL_early_get0_ext - callback functions for early server-side ClientHello processing
+SSL_CTX_set_early_cb, SSL_early_cb_fn, SSL_early_isv2, SSL_early_get0_legacy_version, SSL_early_get0_random, SSL_early_get0_session_id, SSL_early_get0_ciphers, SSL_early_get0_compression_methods, SSL_early_get1_extensions_present, SSL_early_get0_ext - callback functions for early server-side ClientHello processing
 
 =head1 SYNOPSIS
 
@@ -14,6 +14,7 @@ SSL_CTX_set_early_cb, SSL_early_cb_fn, SSL_early_isv2, SSL_early_get0_legacy_ver
  size_t SSL_early_get0_session_id(SSL *s, const unsigned char **out);
  size_t SSL_early_get0_ciphers(SSL *s, const unsigned char **out);
  size_t SSL_early_get0_compression_methods(SSL *s, const unsigned char **out);
+ int SSL_early_get1_extensions_present(SSL *s, int **out, size_t *outlen);
  int SSL_early_get0_ext(SSL *s, int type, const unsigned char **out,
                         size_t *outlen);
 
@@ -53,6 +54,14 @@ from the ClientHello on a per-extension basis.  For the provided wire
 protocol extension type value, the extension value and length are returned
 in the output parameters (if present).
 
+SSL_early_get1_extensions_present() can be used prior to SSL_early_get0_ext(),
+to determine which extensions are present in the ClientHello before querying
+for them.  The B<out> and B<outlen> parameters are both required, and on
+success the caller must release the storage allocated for B<*out> using
+OPENSSL_free().  The contents of B<*out> is an array of integers holding the
+numerical value of the TLS extension types in the order they appear in the
+ClientHello.  B<*outlen> contains the number of elements in the array.
+
 =head1 NOTES
 
 The early callback provides a vast window of possibilities for application
@@ -88,6 +97,8 @@ assumed to be valid.
 SSL_early_get0_ext() returns 1 if the extension of type 'type' is present, and
 0 otherwise.
 
+SSL_early_get1_extensions_present() returns 1 on success and 0 on failure.
+
 =head1 SEE ALSO
 
 L<ssl(7)>, L<SSL_CTX_set_tlsext_servername_callback(3)>,
@@ -97,8 +108,8 @@ L<SSL_bytes_to_cipher_list>
 
 The SSL early callback, SSL_early_isv2(), SSL_early_get0_random(),
 SSL_early_get0_session_id(), SSL_early_get0_ciphers(),
-SSL_early_get0_compression_methods(), and SSL_early_get0_ext() were
-added in OpenSSL 1.1.1.
+SSL_early_get0_compression_methods(), SSL_early_get0_ext(), and
+SSL_early_get1_extensions_present() were added in OpenSSL 1.1.1.
 
 =head1 COPYRIGHT
 
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 0eb41c9..2b83449 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1682,6 +1682,7 @@ size_t SSL_early_get0_random(SSL *s, const unsigned char **out);
 size_t SSL_early_get0_session_id(SSL *s, const unsigned char **out);
 size_t SSL_early_get0_ciphers(SSL *s, const unsigned char **out);
 size_t SSL_early_get0_compression_methods(SSL *s, const unsigned char **out);
+int SSL_early_get1_extensions_present(SSL *s, int **out, size_t *outlen);
 int SSL_early_get0_ext(SSL *s, unsigned int type, const unsigned char **out,
                        size_t *outlen);
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index e90c4b8..068df42 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -4598,6 +4598,38 @@ size_t SSL_early_get0_compression_methods(SSL *s, const unsigned char **out)
     return s->clienthello->compressions_len;
 }
 
+int SSL_early_get1_extensions_present(SSL *s, int **out, size_t *outlen)
+{
+    RAW_EXTENSION *ext;
+    int *present;
+    size_t num = 0, i;
+
+    if (s->clienthello == NULL || out == NULL || outlen == NULL)
+        return 0;
+    for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) {
+        ext = s->clienthello->pre_proc_exts + i;
+        if (ext->present)
+            num++;
+    }
+    present = OPENSSL_malloc(sizeof(*present) * num);
+    if (present == NULL)
+        return 0;
+    for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) {
+        ext = s->clienthello->pre_proc_exts + i;
+        if (ext->present) {
+            if (ext->received_order >= num)
+                goto err;
+            present[ext->received_order] = ext->type;
+        }
+    }
+    *out = present;
+    *outlen = num;
+    return 1;
+ err:
+    OPENSSL_free(present);
+    return 0;
+}
+
 int SSL_early_get0_ext(SSL *s, unsigned int type, const unsigned char **out,
                        size_t *outlen)
 {
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index fe6119b..85944ec 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -668,6 +668,8 @@ typedef struct raw_extension_st {
     int parsed;
     /* The type of this extension, i.e. a TLSEXT_TYPE_* value */
     unsigned int type;
+    /* Track what order extensions are received in (0-based). */
+    size_t received_order;
 } RAW_EXTENSION;
 
 typedef struct {
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index b4d85d9..d40c34c 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -462,6 +462,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context,
         return 0;
     }
 
+    i = 0;
     while (PACKET_remaining(&extensions) > 0) {
         unsigned int type, idx;
         PACKET extension;
@@ -518,6 +519,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context,
             thisex->data = extension;
             thisex->present = 1;
             thisex->type = type;
+            thisex->received_order = i++;
         }
     }
 
diff --git a/test/sslapitest.c b/test/sslapitest.c
index a2424cf..ecbb8b7 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -404,6 +404,7 @@ static int full_early_callback(SSL *s, int *al, void *arg)
 {
     int *ctr = arg;
     const unsigned char *p;
+    int *exts;
     /* We only configure two ciphers, but the SCSV is added automatically. */
 #ifdef OPENSSL_NO_EC
     const unsigned char expected_ciphers[] = {0x00, 0x9d, 0x00, 0xff};
@@ -411,6 +412,11 @@ static int full_early_callback(SSL *s, int *al, void *arg)
     const unsigned char expected_ciphers[] = {0x00, 0x9d, 0xc0,
                                               0x2c, 0x00, 0xff};
 #endif
+    const int expected_extensions[] = {
+#ifndef OPENSSL_NO_EC
+                                       11, 10,
+#endif
+                                       35, 13, 22, 23};
     size_t len;
 
     /* Make sure we can defer processing and get called back. */
@@ -422,6 +428,15 @@ static int full_early_callback(SSL *s, int *al, void *arg)
             || !TEST_size_t_eq(SSL_early_get0_compression_methods(s, &p), 1)
             || !TEST_int_eq(*p, 0))
         return 0;
+    if (!SSL_early_get1_extensions_present(s, &exts, &len))
+        return 0;
+    if (len != OSSL_NELEM(expected_extensions) ||
+        memcmp(exts, expected_extensions, len * sizeof(*exts)) != 0) {
+        printf("Early callback expected ClientHello extensions mismatch\n");
+        OPENSSL_free(exts);
+        return 0;
+    }
+    OPENSSL_free(exts);
     return 1;
 }
 
diff --git a/util/libssl.num b/util/libssl.num
index b4acb5d..4cf8227 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -450,3 +450,4 @@ SSL_set_block_padding                   450	1_1_1	EXIST::FUNCTION:
 SSL_set_record_padding_callback_arg     451	1_1_1	EXIST::FUNCTION:
 SSL_CTX_set_record_padding_callback_arg 452	1_1_1	EXIST::FUNCTION:
 SSL_CTX_use_serverinfo_ex               453	1_1_1	EXIST::FUNCTION:
+SSL_early_get1_extensions_present       454	1_1_1	EXIST::FUNCTION:


More information about the openssl-commits mailing list