diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2016-09-22 12:33:51 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2016-09-22 12:33:51 +0000 |
commit | cd3a43194ba6e8a18f00eb4b9035459be92a6414 (patch) | |
tree | b2a62f4819c4b7801b9f9775c79e67d95ab78ab4 /lib/libssl/t1_lib.c | |
parent | 5dd823704c5ee5694f90e446f402302d9ae0be68 (diff) |
Avoid unbounded memory growth, which can be triggered by a client
repeatedly renegotiating and sending OCSP Status Request TLS extensions.
Fix based on OpenSSL.
Diffstat (limited to 'lib/libssl/t1_lib.c')
-rw-r--r-- | lib/libssl/t1_lib.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c index 6853bc210ee..3f66e2e6d0b 100644 --- a/lib/libssl/t1_lib.c +++ b/lib/libssl/t1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t1_lib.c,v 1.89 2016/09/22 06:57:40 guenther Exp $ */ +/* $OpenBSD: t1_lib.c,v 1.90 2016/09/22 12:33:50 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1444,10 +1444,28 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, /* Read in responder_id_list */ n2s(data, dsize); size -= 2; - if (dsize > size ) { + if (dsize > size) { *al = SSL_AD_DECODE_ERROR; return 0; } + + /* + * We remove any OCSP_RESPIDs from a + * previous handshake to prevent + * unbounded memory growth. + */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, + OCSP_RESPID_free); + s->tlsext_ocsp_ids = NULL; + 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; + } + } + while (dsize > 0) { OCSP_RESPID *id; int idsize; @@ -1475,13 +1493,6 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, *al = SSL_AD_DECODE_ERROR; return 0; } - 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); |