summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man3/SSL_CTX_set_early_cb.pod17
-rw-r--r--include/openssl/ssl.h1
-rw-r--r--ssl/ssl_lib.c32
-rw-r--r--ssl/ssl_locl.h2
-rw-r--r--ssl/statem/extensions.c2
-rw-r--r--util/libssl.num1
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: