Module Name: src Committed By: tonnerre Date: Sat Jul 4 19:52:10 UTC 2009
Modified Files: src/crypto/dist/openssl/crypto/pqueue: pqueue.c pqueue.h src/crypto/dist/openssl/ssl: d1_both.c d1_pkt.c s3_pkt.c ssl.h ssl_err.c Log Message: Fix various vulnerabilities in OpenSSL which have not previously been addressed: CVE-2009-1377, CVE-2009-1378, CVE-2009-1379, CVE-2009-1386 and CVE-2009-1387. Changes deal mostly with size checking of various elements and fixes to various error paths. To generate a diff of this commit: cvs rdiff -u -r1.1.1.2 -r1.2 src/crypto/dist/openssl/crypto/pqueue/pqueue.c \ src/crypto/dist/openssl/crypto/pqueue/pqueue.h cvs rdiff -u -r1.3 -r1.4 src/crypto/dist/openssl/ssl/d1_both.c cvs rdiff -u -r1.1.1.5 -r1.2 src/crypto/dist/openssl/ssl/d1_pkt.c cvs rdiff -u -r1.9 -r1.10 src/crypto/dist/openssl/ssl/s3_pkt.c cvs rdiff -u -r1.18 -r1.19 src/crypto/dist/openssl/ssl/ssl.h cvs rdiff -u -r1.12 -r1.13 src/crypto/dist/openssl/ssl/ssl_err.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/crypto/dist/openssl/crypto/pqueue/pqueue.c diff -u src/crypto/dist/openssl/crypto/pqueue/pqueue.c:1.1.1.2 src/crypto/dist/openssl/crypto/pqueue/pqueue.c:1.2 --- src/crypto/dist/openssl/crypto/pqueue/pqueue.c:1.1.1.2 Fri May 9 21:34:33 2008 +++ src/crypto/dist/openssl/crypto/pqueue/pqueue.c Sat Jul 4 19:52:10 2009 @@ -237,3 +237,17 @@ return ret; } + +int +pqueue_size(pqueue_s *pq) +{ + pitem *item = pq->items; + int count = 0; + + while(item != NULL) + { + count++; + item = item->next; + } + return count; +} Index: src/crypto/dist/openssl/crypto/pqueue/pqueue.h diff -u src/crypto/dist/openssl/crypto/pqueue/pqueue.h:1.1.1.2 src/crypto/dist/openssl/crypto/pqueue/pqueue.h:1.2 --- src/crypto/dist/openssl/crypto/pqueue/pqueue.h:1.1.1.2 Fri May 9 21:34:33 2008 +++ src/crypto/dist/openssl/crypto/pqueue/pqueue.h Sat Jul 4 19:52:10 2009 @@ -89,5 +89,6 @@ pitem *pqueue_next(piterator *iter); void pqueue_print(pqueue pq); +int pqueue_size(pqueue pq); #endif /* ! HEADER_PQUEUE_H */ Index: src/crypto/dist/openssl/ssl/d1_both.c diff -u src/crypto/dist/openssl/ssl/d1_both.c:1.3 src/crypto/dist/openssl/ssl/d1_both.c:1.4 --- src/crypto/dist/openssl/ssl/d1_both.c:1.3 Fri May 9 21:49:42 2008 +++ src/crypto/dist/openssl/ssl/d1_both.c Sat Jul 4 19:52:10 2009 @@ -518,6 +518,7 @@ if ( s->d1->handshake_read_seq == frag->msg_header.seq) { + unsigned long frag_len = frag->msg_header.frag_len; pqueue_pop(s->d1->buffered_messages); al=dtls1_preprocess_fragment(s,&frag->msg_header,max); @@ -535,7 +536,7 @@ if (al==0) { *ok = 1; - return frag->msg_header.frag_len; + return frag_len; } ssl3_send_alert(s,SSL3_AL_FATAL,al); @@ -560,7 +561,16 @@ if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) goto err; - if (msg_hdr->seq <= s->d1->handshake_read_seq) + /* Try to find item in queue, to prevent duplicate entries */ + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char) (msg_hdr->seq>>8); + seq64be[7] = (unsigned char) msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + /* Discard the message if sequence number was already there, is + * too far in the future or the fragment is already in the queue */ + if (msg_hdr->seq <= s->d1->handshake_read_seq || + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL) { unsigned char devnull [256]; @@ -574,30 +584,31 @@ } } - frag = dtls1_hm_fragment_new(frag_len); - if ( frag == NULL) - goto err; + if (frag_len) + { + frag = dtls1_hm_fragment_new(frag_len); + if ( frag == NULL) + goto err; - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - if (frag_len) - { /* read the body of the fragment (header has already been read */ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, frag->fragment,frag_len,0); if (i<=0 || (unsigned long)i!=frag_len) goto err; - } - memset(seq64be,0,sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq>>8); - seq64be[7] = (unsigned char)(msg_hdr->seq); + pq_64bit_init(&seq64); + pq_64bit_assign_word(&seq64, msg_hdr->seq); - item = pitem_new(seq64be, frag); - if ( item == NULL) - goto err; + item = pitem_new(seq64be, frag); + pq_64bit_free(&seq64); + if ( item == NULL) + goto err; + + pqueue_insert(s->d1->buffered_messages, item); + } - pqueue_insert(s->d1->buffered_messages, item); return DTLS1_HM_FRAGMENT_RETRY; err: Index: src/crypto/dist/openssl/ssl/d1_pkt.c diff -u src/crypto/dist/openssl/ssl/d1_pkt.c:1.1.1.5 src/crypto/dist/openssl/ssl/d1_pkt.c:1.2 --- src/crypto/dist/openssl/ssl/d1_pkt.c:1.1.1.5 Fri May 9 21:34:43 2008 +++ src/crypto/dist/openssl/ssl/d1_pkt.c Sat Jul 4 19:52:10 2009 @@ -207,6 +207,10 @@ DTLS1_RECORD_DATA *rdata; pitem *item; + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); item = pitem_new(priority, rdata); if (rdata == NULL || item == NULL) Index: src/crypto/dist/openssl/ssl/s3_pkt.c diff -u src/crypto/dist/openssl/ssl/s3_pkt.c:1.9 src/crypto/dist/openssl/ssl/s3_pkt.c:1.10 --- src/crypto/dist/openssl/ssl/s3_pkt.c:1.9 Tue Jun 10 19:45:00 2008 +++ src/crypto/dist/openssl/ssl/s3_pkt.c Sat Jul 4 19:52:10 2009 @@ -1288,6 +1288,13 @@ if (s->s3->tmp.key_block == NULL) { + if (s->session == NULL) + { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); + return (0); + } + s->session->cipher=s->s3->tmp.new_cipher; if (!s->method->ssl3_enc->setup_key_block(s)) return(0); } Index: src/crypto/dist/openssl/ssl/ssl.h diff -u src/crypto/dist/openssl/ssl/ssl.h:1.18 src/crypto/dist/openssl/ssl/ssl.h:1.19 --- src/crypto/dist/openssl/ssl/ssl.h:1.18 Fri May 9 21:49:42 2008 +++ src/crypto/dist/openssl/ssl/ssl.h Sat Jul 4 19:52:10 2009 @@ -1806,6 +1806,7 @@ #define SSL_F_SSL3_CONNECT 132 #define SSL_F_SSL3_CTRL 213 #define SSL_F_SSL3_CTX_CTRL 133 +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 #define SSL_F_SSL3_ENC 134 #define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 Index: src/crypto/dist/openssl/ssl/ssl_err.c diff -u src/crypto/dist/openssl/ssl/ssl_err.c:1.12 src/crypto/dist/openssl/ssl/ssl_err.c:1.13 --- src/crypto/dist/openssl/ssl/ssl_err.c:1.12 Fri May 9 21:49:42 2008 +++ src/crypto/dist/openssl/ssl/ssl_err.c Sat Jul 4 19:52:10 2009 @@ -138,6 +138,7 @@ {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"}, +{ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), "SSL3_DO_CHANGE_CIPHER_SPEC"}, {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"}, {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"},