[openssl] master update

tomas at openssl.org tomas at openssl.org
Thu Feb 3 12:46:17 UTC 2022


The branch master has been updated
       via  13a53fbf13bc6fa09c95ad4bdc6ec70fa15aa16d (commit)
      from  27aca04e13ca8a9bead49de7bc380110ecb7064e (commit)


- Log -----------------------------------------------------------------
commit 13a53fbf13bc6fa09c95ad4bdc6ec70fa15aa16d
Author: Phus Lu <phus.lu at gmail.com>
Date:   Mon Oct 25 18:47:00 2021 +0800

    add SSL_get0_iana_groups() & SSL_client_hello_get_extension_order()
    
    The function/macro allow user get groups/extensions without memory allcations.
    So we could calculate the ssl fignerprint(ja3) in low cost.
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16910)

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

Summary of changes:
 CHANGES.md                               |  9 +++++++++
 doc/man3/SSL_CTX_set1_curves.pod         | 17 +++++++++++++---
 doc/man3/SSL_CTX_set_client_hello_cb.pod | 22 ++++++++++++++++++++-
 include/openssl/ssl.h.in                 |  5 +++++
 ssl/s3_lib.c                             |  8 ++++++++
 ssl/ssl_lib.c                            | 34 ++++++++++++++++++++++++++++++++
 util/libssl.num                          |  1 +
 util/other.syms                          |  1 +
 8 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 3799c28c97..212532bce2 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -24,6 +24,15 @@ OpenSSL 3.1
 
 ### Changes between 3.0 and 3.1 [xx XXX xxxx]
 
+ * Add new SSL APIs to aid in efficiently implementing TLS/SSL fingerprinting.  The
+   SSL_CTRL_GET_IANA_GROUPS control code, exposed as the SSL_get0_iana_groups()
+   function-like macro, retrieves the list of supported groups sent by the peer,
+   and the function SSL_client_hello_get_extension_order() populates a caller-supplied
+   array with the list of extension types present in the ClientHello, in order of
+   appearance.
+
+   *Phus Lu*
+
  * Fixed PEM_write_bio_PKCS8PrivateKey() and PEM_write_bio_PKCS8PrivateKey_nid()
    to make it possible to use empty passphrase strings.
 
diff --git a/doc/man3/SSL_CTX_set1_curves.pod b/doc/man3/SSL_CTX_set1_curves.pod
index cbd8f71346..d24db8f812 100644
--- a/doc/man3/SSL_CTX_set1_curves.pod
+++ b/doc/man3/SSL_CTX_set1_curves.pod
@@ -3,9 +3,10 @@
 =head1 NAME
 
 SSL_CTX_set1_groups, SSL_CTX_set1_groups_list, SSL_set1_groups,
-SSL_set1_groups_list, SSL_get1_groups, SSL_get_shared_group,
-SSL_get_negotiated_group, SSL_CTX_set1_curves, SSL_CTX_set1_curves_list,
-SSL_set1_curves, SSL_set1_curves_list, SSL_get1_curves, SSL_get_shared_curve
+SSL_set1_groups_list, SSL_get1_groups, SSL_get0_iana_groups,
+SSL_get_shared_group, SSL_get_negotiated_group, SSL_CTX_set1_curves,
+SSL_CTX_set1_curves_list, SSL_set1_curves, SSL_set1_curves_list,
+SSL_get1_curves, SSL_get_shared_curve
 - EC supported curve functions
 
 =head1 SYNOPSIS
@@ -19,6 +20,7 @@ SSL_set1_curves, SSL_set1_curves_list, SSL_get1_curves, SSL_get_shared_curve
  int SSL_set1_groups_list(SSL *ssl, char *list);
 
  int SSL_get1_groups(SSL *ssl, int *groups);
+ int SSL_get0_iana_groups(SSL *ssl, uint16_t **out);
  int SSL_get_shared_group(SSL *s, int n);
  int SSL_get_negotiated_group(SSL *s);
 
@@ -68,6 +70,13 @@ order. It can return zero if the client did not send a supported groups
 extension. If a supported group NID is unknown then the value is set to the
 bitwise OR of TLSEXT_nid_unknown (0x1000000) and the id of the group.
 
+SSL_get0_iana_groups() retrieves the list of groups sent by the
+client in the supported_groups extension.  The B<*out> array of bytes
+is populated with the host-byte-order representation of the uint16_t group
+identifiers, as assigned by IANA.  The group list is returned in the same order
+that was received in the ClientHello.  The return value is the number of groups,
+not the number of bytes written.
+
 SSL_get_shared_group() returns the NID of the shared group B<n> for a
 server-side SSL B<ssl>. If B<n> is -1 then the total number of shared groups is
 returned, which may be zero. Other than for diagnostic purposes,
@@ -108,6 +117,8 @@ SSL_set1_groups_list(), return 1 for success and 0 for failure.
 
 SSL_get1_groups() returns the number of groups, which may be zero.
 
+SSL_get0_iana_groups() returns the number of (uint16_t) groups, which may be zero.
+
 SSL_get_shared_group() returns the NID of shared group B<n> or NID_undef if there
 is no shared group B<n>; or the total number of shared groups if B<n>
 is -1.
diff --git a/doc/man3/SSL_CTX_set_client_hello_cb.pod b/doc/man3/SSL_CTX_set_client_hello_cb.pod
index f324647abc..dc882a12e6 100644
--- a/doc/man3/SSL_CTX_set_client_hello_cb.pod
+++ b/doc/man3/SSL_CTX_set_client_hello_cb.pod
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-SSL_CTX_set_client_hello_cb, SSL_client_hello_cb_fn, SSL_client_hello_isv2, SSL_client_hello_get0_legacy_version, SSL_client_hello_get0_random, SSL_client_hello_get0_session_id, SSL_client_hello_get0_ciphers, SSL_client_hello_get0_compression_methods, SSL_client_hello_get1_extensions_present, SSL_client_hello_get0_ext - callback functions for early server-side ClientHello processing
+SSL_CTX_set_client_hello_cb, SSL_client_hello_cb_fn, SSL_client_hello_isv2, SSL_client_hello_get0_legacy_version, SSL_client_hello_get0_random, SSL_client_hello_get0_session_id, SSL_client_hello_get0_ciphers, SSL_client_hello_get0_compression_methods, SSL_client_hello_get1_extensions_present, SSL_client_hello_get_extension_order, SSL_client_hello_get0_ext - callback functions for early server-side ClientHello processing
 
 =head1 SYNOPSIS
 
@@ -18,6 +18,8 @@ SSL_CTX_set_client_hello_cb, SSL_client_hello_cb_fn, SSL_client_hello_isv2, SSL_
                                                   const unsigned char **out);
  int SSL_client_hello_get1_extensions_present(SSL *s, int **out,
                                               size_t *outlen);
+ int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts,
+                                          size_t *num_exts);
  int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out,
                                size_t *outlen);
 
@@ -68,6 +70,20 @@ in the ClientHello.  B<*outlen> contains the number of elements in the array.
 In situations when the ClientHello has no extensions, the function will return
 success with B<*out> set to NULL and B<*outlen> set to 0.
 
+SSL_client_hello_get_extension_order() is similar to
+SSL_client_hello_get1_extensions_present(), without internal memory allocation.
+When called with B<exts> set to NULL, returns the number of extensions
+(e.g., to allocate storage for a subsequent call).  Otherwise, B<*exts> is populated
+with the ExtensionType values in the order that the corresponding extensions
+appeared in the ClientHello.  B<*num_exts> is an input/output parameter, used
+as input to supply the size of storage allocated by the caller, and as output to
+indicate how many ExtensionType values were written.  If the input B<*num_exts>
+is smaller then the number of extensions in question, that is treated as an error.
+A subsequent call with B<exts> set to NULL can retrieve the size of storage needed.
+A ClientHello that contained no extensions is treated as success, with B<*num_exts>
+set to 0.
+
+
 =head1 NOTES
 
 The ClientHello callback provides a vast window of possibilities for application
@@ -107,6 +123,8 @@ SSL_client_hello_get0_ext() returns 1 if the extension of type 'type' is present
 
 SSL_client_hello_get1_extensions_present() returns 1 on success and 0 on failure.
 
+SSL_client_hello_get_extension_order() returns 1 on success and 0 on failure.
+
 =head1 SEE ALSO
 
 L<ssl(7)>, L<SSL_CTX_set_tlsext_servername_callback(3)>,
@@ -119,6 +137,8 @@ SSL_client_hello_get0_random(), SSL_client_hello_get0_session_id(),
 SSL_client_hello_get0_ciphers(), SSL_client_hello_get0_compression_methods(),
 SSL_client_hello_get0_ext(), and SSL_client_hello_get1_extensions_present()
 were added in OpenSSL 1.1.1.
+SSL_client_hello_get_extension_order()
+was added in OpenSSL 3.1.0.
 
 =head1 COPYRIGHT
 
diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
index 9c00eb3d13..47f277969c 100644
--- a/include/openssl/ssl.h.in
+++ b/include/openssl/ssl.h.in
@@ -1308,6 +1308,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 # define SSL_CTRL_GET_SIGNATURE_NID              132
 # define SSL_CTRL_GET_TMP_KEY                    133
 # define SSL_CTRL_GET_NEGOTIATED_GROUP           134
+# define SSL_CTRL_GET_IANA_GROUPS                135
 # define SSL_CERT_SET_FIRST                      1
 # define SSL_CERT_SET_NEXT                       2
 # define SSL_CERT_SET_SERVER                     3
@@ -1401,6 +1402,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
         SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
 # define SSL_get1_groups(s, glist) \
         SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist))
+# define SSL_get0_iana_groups(s, plst) \
+        SSL_ctrl(s,SSL_CTRL_GET_IANA_GROUPS,0,(uint16_t **)(plst))
 # define SSL_CTX_set1_groups(ctx, glist, glistlen) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(int *)(glist))
 # define SSL_CTX_set1_groups_list(ctx, s) \
@@ -1848,6 +1851,8 @@ size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out);
 size_t SSL_client_hello_get0_compression_methods(SSL *s,
                                                  const unsigned char **out);
 int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen);
+int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts,
+                                         size_t *num_exts);
 int SSL_client_hello_get0_ext(SSL *s, unsigned int type,
                               const unsigned char **out, size_t *outlen);
 
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 120b5cedeb..3b3cc8a32a 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3729,6 +3729,14 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             return (int)s->ext.peer_ecpointformats_len;
         }
 
+    case SSL_CTRL_GET_IANA_GROUPS:
+        {
+            if (parg != NULL) {
+                *(uint16_t **)parg = (uint16_t *)s->ext.peer_supportedgroups;
+            }
+            return (int)s->ext.peer_supportedgroups_len;
+        }
+
     default:
         break;
     }
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 655eac0b7c..cb7a52ab7e 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -5424,6 +5424,40 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen)
     return 0;
 }
 
+int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts, size_t *num_exts)
+{
+    RAW_EXTENSION *ext;
+    size_t num = 0, i;
+
+    if (s->clienthello == NULL || num_exts == 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++;
+    }
+    if (num == 0) {
+        *num_exts = 0;
+        return 1;
+    }
+    if (exts == NULL) {
+        *num_exts = num;
+        return 1;
+    }
+    if (*num_exts < num)
+        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)
+                return 0;
+            exts[ext->received_order] = ext->type;
+        }
+    }
+    *num_exts = num;
+    return 1;
+}
+
 int SSL_client_hello_get0_ext(SSL *s, unsigned int type, const unsigned char **out,
                        size_t *outlen)
 {
diff --git a/util/libssl.num b/util/libssl.num
index f055c967bf..c7afa8fdb0 100644
--- a/util/libssl.num
+++ b/util/libssl.num
@@ -520,3 +520,4 @@ SSL_load_client_CA_file_ex              520	3_0_0	EXIST::FUNCTION:
 SSL_set0_tmp_dh_pkey                    521	3_0_0	EXIST::FUNCTION:
 SSL_CTX_set0_tmp_dh_pkey                522	3_0_0	EXIST::FUNCTION:
 SSL_group_to_name                       523	3_0_0	EXIST::FUNCTION:
+SSL_client_hello_get_extension_order    ?	3_1_0	EXIST::FUNCTION:
diff --git a/util/other.syms b/util/other.syms
index da5f937c3f..ae675b78f4 100644
--- a/util/other.syms
+++ b/util/other.syms
@@ -532,6 +532,7 @@ SSL_clear_chain_certs                   define
 SSL_clear_mode                          define
 SSL_disable_ct                          define
 SSL_get0_chain_certs                    define
+SSL_get0_iana_groups                    define
 SSL_get0_session                        define
 SSL_get1_curves                         define
 SSL_get1_groups                         define


More information about the openssl-commits mailing list