summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2016-09-09 10:08:45 +0100
committerMatt Caswell <matt@openssl.org>2016-09-22 00:25:58 +0100
commit2c0d295e26306e15a92eb23a84a1802005c1c137 (patch)
tree980f27d925ae0f60a87414ad3bfb55698678b304
parent151adf2e5cc23284a059e0f155505006a1c9fad9 (diff)
Fix OCSP Status Request extension unbounded memory growth
A malicious client can send an excessively large OCSP Status Request extension. If that client continually requests renegotiation, sending a large OCSP Status Request extension each time, then there will be unbounded memory growth on the server. This will eventually lead to a Denial Of Service attack through memory exhaustion. Servers with a default configuration are vulnerable even if they do not support OCSP. Builds using the "no-ocsp" build time option are not affected. I have also checked other extensions to see if they suffer from a similar problem but I could not find any other issues. CVE-2016-6304 Issue reported by Shi Lei. Reviewed-by: Rich Salz <rsalz@openssl.org>
-rw-r--r--ssl/t1_lib.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 7680491340..4bc13ca5ce 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1284,6 +1284,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
size -= 2;
if (dsize > size)
goto err;
+
+ /*
+ * We remove any OCSP_RESPIDs from a previous handshake
+ * to prevent unbounded memory growth - CVE-2016-6304
+ */
+ sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
+ OCSP_RESPID_free);
+ if (dsize > 0) {
+ s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
+ if (s->tlsext_ocsp_ids == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ } else {
+ s->tlsext_ocsp_ids = NULL;
+ }
+
while (dsize > 0) {
OCSP_RESPID *id;
int idsize;
@@ -1303,13 +1320,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
OCSP_RESPID_free(id);
goto err;
}
- if (!s->tlsext_ocsp_ids
- && !(s->tlsext_ocsp_ids =
- sk_OCSP_RESPID_new_null())) {
- OCSP_RESPID_free(id);
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
OCSP_RESPID_free(id);
*al = SSL_AD_INTERNAL_ERROR;