output number of exts from tls_collect_extensions()
Modify the API of tls_collect_extensions() to be able to output the number of
extensions that are known (i.e., the length of its 'res' output). This number
can never be zero on a successful return due to the builtin extensions list,
but use a separate output variable so as to not overload the return value
semantics.
Having this value easily available will give consumers a way to avoid repeating
the calculation.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2279)
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 8e1b502..c011445 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -382,10 +382,11 @@
* extensions that we know about. We ignore others.
*/
int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context,
- RAW_EXTENSION **res, int *al)
+ RAW_EXTENSION **res, int *al, size_t *len)
{
PACKET extensions = *packet;
size_t i = 0;
+ size_t num_exts;
custom_ext_methods *exts = NULL;
RAW_EXTENSION *raw_extensions = NULL;
const EXTENSION_DEFINITION *thisexd;
@@ -403,9 +404,8 @@
exts = &s->cert->cli_ext;
}
- raw_extensions = OPENSSL_zalloc((OSSL_NELEM(ext_defs)
- + (exts != NULL ? exts->meths_count : 0))
- * sizeof(*raw_extensions));
+ num_exts = OSSL_NELEM(ext_defs) + (exts != NULL ? exts->meths_count : 0);
+ raw_extensions = OPENSSL_zalloc(num_exts * sizeof(*raw_extensions));
if (raw_extensions == NULL) {
*al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_COLLECT_EXTENSIONS, ERR_R_MALLOC_FAILURE);
@@ -454,6 +454,8 @@
}
*res = raw_extensions;
+ if (len != NULL)
+ *len = num_exts;
return 1;
err:
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index 3957a73..614da1b 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1254,7 +1254,7 @@
context = SSL_IS_TLS13(s) ? EXT_TLS1_3_SERVER_HELLO
: EXT_TLS1_2_SERVER_HELLO;
- if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al))
+ if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al, NULL))
goto f_err;
s->hit = 0;
@@ -1524,7 +1524,7 @@
}
if (!tls_collect_extensions(s, &extpkt, EXT_TLS1_3_HELLO_RETRY_REQUEST,
- &extensions, &al)
+ &extensions, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_HELLO_RETRY_REQUEST,
extensions, NULL, 0, &al))
goto f_err;
@@ -1596,7 +1596,7 @@
goto f_err;
}
if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE,
- &rawexts, &al)
+ &rawexts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE,
rawexts, x, chainidx, &al)) {
OPENSSL_free(rawexts);
@@ -2399,7 +2399,7 @@
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
|| !tls_collect_extensions(s, &extpkt,
EXT_TLS1_3_NEW_SESSION_TICKET,
- &exts, &al)
+ &exts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_NEW_SESSION_TICKET,
exts, NULL, 0, &al)) {
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_BAD_EXTENSION);
@@ -3362,7 +3362,7 @@
}
if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
- &rawexts, &al)
+ &rawexts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
rawexts, NULL, 0, &al))
goto err;
diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h
index 595a803..9230332 100644
--- a/ssl/statem/statem_locl.h
+++ b/ssl/statem/statem_locl.h
@@ -167,7 +167,7 @@
/* Extension processing */
__owur int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context,
- RAW_EXTENSION **res, int *al);
+ RAW_EXTENSION **res, int *al, size_t *len);
__owur int tls_parse_extension(SSL *s, TLSEXT_INDEX idx, int context,
RAW_EXTENSION *exts, X509 *x, size_t chainidx,
int *al);
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 0037e79..28f3b24 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -1423,7 +1423,7 @@
/* Preserve the raw extensions PACKET for later use */
extensions = clienthello.extensions;
if (!tls_collect_extensions(s, &extensions, EXT_CLIENT_HELLO,
- &clienthello.pre_proc_exts, &al)) {
+ &clienthello.pre_proc_exts, &al, NULL)) {
/* SSLerr already been called */
goto f_err;
}
@@ -3128,7 +3128,7 @@
goto f_err;
}
if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE,
- &rawexts, &al)
+ &rawexts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE,
rawexts, x, chainidx, &al)) {
OPENSSL_free(rawexts);