diff options
author | guenther <> | 2014-08-07 20:24:12 +0000 |
---|---|---|
committer | guenther <> | 2014-08-07 20:24:12 +0000 |
commit | 7ebd67cca8deb00f38709e7165e966f7e6b20650 (patch) | |
tree | f00b29f8c5aa7ed7c4a2e2f4ce6adea8e7c8a623 | |
parent | e58fb502ca02fb2bd4f85e5725abd1189d26921c (diff) | |
download | openbsd-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.c | 38 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/d1_both.c | 38 |
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 | */ | ||
576 | static unsigned long | ||
577 | dtls1_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 | ||
572 | static int | 587 | static int |
573 | dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | 588 | dtls1_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 | */ | ||
576 | static unsigned long | ||
577 | dtls1_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 | ||
572 | static int | 587 | static int |
573 | dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) | 588 | dtls1_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; |