summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorguenther <>2014-08-07 20:24:12 +0000
committerguenther <>2014-08-07 20:24:12 +0000
commit7ebd67cca8deb00f38709e7165e966f7e6b20650 (patch)
treef00b29f8c5aa7ed7c4a2e2f4ce6adea8e7c8a623
parente58fb502ca02fb2bd4f85e5725abd1189d26921c (diff)
downloadopenbsd-7ebd67cca8deb00f38709e7165e966f7e6b20650.tar.gz
openbsd-7ebd67cca8deb00f38709e7165e966f7e6b20650.tar.bz2
openbsd-7ebd67cca8deb00f38709e7165e966f7e6b20650.zip
Fix CVE-2014-3506, DTLS handshake message size checks. From
https://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=1250f12613b61758675848f6600ebd914ccd7636 with comment/whitespace style tweaks ok bcook@ miod@
-rw-r--r--src/lib/libssl/d1_both.c38
-rw-r--r--src/lib/libssl/src/ssl/d1_both.c38
2 files changed, 44 insertions, 32 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
index aec6e272bf..fea701107f 100644
--- a/src/lib/libssl/d1_both.c
+++ b/src/lib/libssl/d1_both.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: d1_both.c,v 1.26 2014/08/07 20:02:23 miod Exp $ */ 1/* $OpenBSD: d1_both.c,v 1.27 2014/08/07 20:24:12 guenther Exp $ */
2/* 2/*
3 * DTLS implementation written by Nagendra Modadugu 3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -568,6 +568,21 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
568 return 0; 568 return 0;
569} 569}
570 570
571/*
572 * dtls1_max_handshake_message_len returns the maximum number of bytes
573 * permitted in a DTLS handshake message for |s|. The minimum is 16KB,
574 * but may be greater if the maximum certificate list size requires it.
575 */
576static unsigned long
577dtls1_max_handshake_message_len(const SSL *s)
578{
579 unsigned long max_len;
580
581 max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
582 if (max_len < (unsigned long)s->max_cert_list)
583 return s->max_cert_list;
584 return max_len;
585}
571 586
572static int 587static int
573dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) 588dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
@@ -576,22 +591,10 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
576 pitem *item = NULL; 591 pitem *item = NULL;
577 int i = -1, is_complete; 592 int i = -1, is_complete;
578 unsigned char seq64be[8]; 593 unsigned char seq64be[8];
579 unsigned long frag_len = msg_hdr->frag_len, max_len; 594 unsigned long frag_len = msg_hdr->frag_len;
580
581 if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
582 goto err;
583
584 /*
585 * Determine maximum allowed message size. Depends on (user set)
586 * maximum certificate length, but 16k is minimum.
587 */
588 if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <
589 s->max_cert_list)
590 max_len = s->max_cert_list;
591 else
592 max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
593 595
594 if ((msg_hdr->frag_off + frag_len) > max_len) 596 if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
597 msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
595 goto err; 598 goto err;
596 599
597 /* Try to find item in queue */ 600 /* Try to find item in queue */
@@ -725,6 +728,9 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
725 if (frag_len && frag_len < msg_hdr->msg_len) 728 if (frag_len && frag_len < msg_hdr->msg_len)
726 return dtls1_reassemble_fragment(s, msg_hdr, ok); 729 return dtls1_reassemble_fragment(s, msg_hdr, ok);
727 730
731 if (frag_len > dtls1_max_handshake_message_len(s))
732 goto err;
733
728 frag = dtls1_hm_fragment_new(frag_len, 0); 734 frag = dtls1_hm_fragment_new(frag_len, 0);
729 if (frag == NULL) 735 if (frag == NULL)
730 goto err; 736 goto err;
diff --git a/src/lib/libssl/src/ssl/d1_both.c b/src/lib/libssl/src/ssl/d1_both.c
index aec6e272bf..fea701107f 100644
--- a/src/lib/libssl/src/ssl/d1_both.c
+++ b/src/lib/libssl/src/ssl/d1_both.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: d1_both.c,v 1.26 2014/08/07 20:02:23 miod Exp $ */ 1/* $OpenBSD: d1_both.c,v 1.27 2014/08/07 20:24:12 guenther Exp $ */
2/* 2/*
3 * DTLS implementation written by Nagendra Modadugu 3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -568,6 +568,21 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
568 return 0; 568 return 0;
569} 569}
570 570
571/*
572 * dtls1_max_handshake_message_len returns the maximum number of bytes
573 * permitted in a DTLS handshake message for |s|. The minimum is 16KB,
574 * but may be greater if the maximum certificate list size requires it.
575 */
576static unsigned long
577dtls1_max_handshake_message_len(const SSL *s)
578{
579 unsigned long max_len;
580
581 max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
582 if (max_len < (unsigned long)s->max_cert_list)
583 return s->max_cert_list;
584 return max_len;
585}
571 586
572static int 587static int
573dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) 588dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
@@ -576,22 +591,10 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
576 pitem *item = NULL; 591 pitem *item = NULL;
577 int i = -1, is_complete; 592 int i = -1, is_complete;
578 unsigned char seq64be[8]; 593 unsigned char seq64be[8];
579 unsigned long frag_len = msg_hdr->frag_len, max_len; 594 unsigned long frag_len = msg_hdr->frag_len;
580
581 if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
582 goto err;
583
584 /*
585 * Determine maximum allowed message size. Depends on (user set)
586 * maximum certificate length, but 16k is minimum.
587 */
588 if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <
589 s->max_cert_list)
590 max_len = s->max_cert_list;
591 else
592 max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
593 595
594 if ((msg_hdr->frag_off + frag_len) > max_len) 596 if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
597 msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
595 goto err; 598 goto err;
596 599
597 /* Try to find item in queue */ 600 /* Try to find item in queue */
@@ -725,6 +728,9 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
725 if (frag_len && frag_len < msg_hdr->msg_len) 728 if (frag_len && frag_len < msg_hdr->msg_len)
726 return dtls1_reassemble_fragment(s, msg_hdr, ok); 729 return dtls1_reassemble_fragment(s, msg_hdr, ok);
727 730
731 if (frag_len > dtls1_max_handshake_message_len(s))
732 goto err;
733
728 frag = dtls1_hm_fragment_new(frag_len, 0); 734 frag = dtls1_hm_fragment_new(frag_len, 0);
729 if (frag == NULL) 735 if (frag == NULL)
730 goto err; 736 goto err;