summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorBenjamin Kaduk <bkaduk@akamai.com>2017-03-16 17:17:16 -0500
committerMatt Caswell <matt@openssl.org>2017-06-12 09:31:47 +0100
commit193b5d769cdaa3bc0778f7b7ae354618097ca61e (patch)
tree1a9c63ea245b98e7138126fd06c9963e2ed08437 /ssl
parent0e1e4045c469f03294e33c0344d882e71dbd0d07 (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.c32
-rw-r--r--ssl/ssl_locl.h2
-rw-r--r--ssl/statem/extensions.c2
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++;
}
}