diff options
author | Benjamin Kaduk <bkaduk@akamai.com> | 2017-03-16 17:17:16 -0500 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-06-12 09:31:47 +0100 |
commit | 193b5d769cdaa3bc0778f7b7ae354618097ca61e (patch) | |
tree | 1a9c63ea245b98e7138126fd06c9963e2ed08437 /ssl | |
parent | 0e1e4045c469f03294e33c0344d882e71dbd0d07 (diff) |
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@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2976)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/ssl_lib.c | 32 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 2 | ||||
-rw-r--r-- | ssl/statem/extensions.c | 2 |
3 files changed, 36 insertions, 0 deletions
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++; } } |