diff options
-rw-r--r-- | doc/man3/SSL_CTX_set_early_cb.pod | 17 | ||||
-rw-r--r-- | include/openssl/ssl.h | 1 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 32 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 2 | ||||
-rw-r--r-- | ssl/statem/extensions.c | 2 | ||||
-rw-r--r-- | util/libssl.num | 1 |
6 files changed, 52 insertions, 3 deletions
diff --git a/doc/man3/SSL_CTX_set_early_cb.pod b/doc/man3/SSL_CTX_set_early_cb.pod index 771e4ca0a7..c2b4650a06 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 0eb41c9574..2b8344956b 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 e90c4b8732..068df4200d 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 fe6119b2ff..85944ecfe7 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 b4d85d958c..d40c34cd1c 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/util/libssl.num b/util/libssl.num index b4acb5db35..4cf8227b73 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: |