Index: user/cperciva/freebsd-update-build/patches/10.1-RELEASE/38-SA-16:26.openssl =================================================================== --- user/cperciva/freebsd-update-build/patches/10.1-RELEASE/38-SA-16:26.openssl (nonexistent) +++ user/cperciva/freebsd-update-build/patches/10.1-RELEASE/38-SA-16:26.openssl (revision 306270) @@ -0,0 +1,879 @@ +Index: crypto/openssl/crypto/bn/bn_print.c +=================================================================== +--- crypto/openssl/crypto/bn/bn_print.c (revision 306156) ++++ crypto/openssl/crypto/bn/bn_print.c (working copy) +@@ -111,6 +111,7 @@ char *BN_bn2dec(const BIGNUM *a) + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; ++ int bn_data_num; + + /*- + * get an upper bound for the length of the decimal integer +@@ -120,8 +121,8 @@ char *BN_bn2dec(const BIGNUM *a) + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; +- bn_data = +- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG)); ++ bn_data_num = num / BN_DEC_NUM + 1; ++ bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = (char *)OPENSSL_malloc(num + 3); + if ((buf == NULL) || (bn_data == NULL)) { + BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); +@@ -143,7 +144,11 @@ char *BN_bn2dec(const BIGNUM *a) + i = 0; + while (!BN_is_zero(t)) { + *lp = BN_div_word(t, BN_DEC_CONV); ++ if (*lp == (BN_ULONG)-1) ++ goto err; + lp++; ++ if (lp - bn_data >= bn_data_num) ++ goto err; + } + lp--; + /* +Index: crypto/openssl/crypto/dsa/dsa_ossl.c +=================================================================== +--- crypto/openssl/crypto/dsa/dsa_ossl.c (revision 306156) ++++ crypto/openssl/crypto/dsa/dsa_ossl.c (working copy) +@@ -247,11 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + do + if (!BN_rand_range(&k, dsa->q)) + goto err; +- while (BN_is_zero(&k)) ; ++ while (BN_is_zero(&k)); ++ + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); + } + ++ + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) +@@ -264,6 +266,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + if (!BN_copy(&kq, &k)) + goto err; + ++ BN_set_flags(&kq, BN_FLG_CONSTTIME); ++ + /* + * We do not want timing information to leak the length of k, so we + * compute g^k using an equivalent exponent of fixed length. (This +@@ -282,6 +286,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + } else { + K = &k; + } ++ + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, + dsa->method_mont_p); + if (!BN_mod(r, r, dsa->q, ctx)) +Index: crypto/openssl/crypto/mdc2/mdc2dgst.c +=================================================================== +--- crypto/openssl/crypto/mdc2/mdc2dgst.c (revision 306156) ++++ crypto/openssl/crypto/mdc2/mdc2dgst.c (working copy) +@@ -91,7 +91,7 @@ int MDC2_Update(MDC2_CTX *c, const unsigned char * + + i = c->num; + if (i != 0) { +- if (i + len < MDC2_BLOCK) { ++ if (len < MDC2_BLOCK - i) { + /* partial block */ + memcpy(&(c->data[i]), in, len); + c->num += (int)len; +Index: crypto/openssl/crypto/ts/ts_lib.c +=================================================================== +--- crypto/openssl/crypto/ts/ts_lib.c (revision 306156) ++++ crypto/openssl/crypto/ts/ts_lib.c (working copy) +@@ -90,9 +90,8 @@ int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT * + { + char obj_txt[128]; + +- int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); +- BIO_write(bio, obj_txt, len); +- BIO_write(bio, "\n", 1); ++ OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); ++ BIO_printf(bio, "%s\n", obj_txt); + + return 1; + } +Index: crypto/openssl/ssl/d1_both.c +=================================================================== +--- crypto/openssl/ssl/d1_both.c (revision 306156) ++++ crypto/openssl/ssl/d1_both.c (working copy) +@@ -586,12 +586,24 @@ static int dtls1_retrieve_buffered_fragment(SSL *s + int al; + + *ok = 0; +- item = pqueue_peek(s->d1->buffered_messages); +- if (item == NULL) +- return 0; ++ do { ++ item = pqueue_peek(s->d1->buffered_messages); ++ if (item == NULL) ++ return 0; + +- frag = (hm_fragment *)item->data; ++ frag = (hm_fragment *)item->data; + ++ if (frag->msg_header.seq < s->d1->handshake_read_seq) { ++ /* This is a stale message that has been buffered so clear it */ ++ pqueue_pop(s->d1->buffered_messages); ++ dtls1_hm_fragment_free(frag); ++ pitem_free(item); ++ item = NULL; ++ frag = NULL; ++ } ++ } while (item == NULL); ++ ++ + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; +@@ -1388,18 +1400,6 @@ dtls1_retransmit_message(SSL *s, unsigned short se + return ret; + } + +-/* call this function when the buffered messages are no longer needed */ +-void dtls1_clear_record_buffer(SSL *s) +-{ +- pitem *item; +- +- for (item = pqueue_pop(s->d1->sent_messages); +- item != NULL; item = pqueue_pop(s->d1->sent_messages)) { +- dtls1_hm_fragment_free((hm_fragment *)item->data); +- pitem_free(item); +- } +-} +- + unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, + unsigned long frag_off, +Index: crypto/openssl/ssl/d1_clnt.c +=================================================================== +--- crypto/openssl/ssl/d1_clnt.c (revision 306156) ++++ crypto/openssl/ssl/d1_clnt.c (working copy) +@@ -740,6 +740,7 @@ int dtls1_connect(SSL *s) + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +Index: crypto/openssl/ssl/d1_lib.c +=================================================================== +--- crypto/openssl/ssl/d1_lib.c (revision 306156) ++++ crypto/openssl/ssl/d1_lib.c (working copy) +@@ -144,7 +144,6 @@ int dtls1_new(SSL *s) + static void dtls1_clear_queues(SSL *s) + { + pitem *item = NULL; +- hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { +@@ -165,28 +164,44 @@ static void dtls1_clear_queues(SSL *s) + pitem_free(item); + } + ++ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { ++ rdata = (DTLS1_RECORD_DATA *)item->data; ++ if (rdata->rbuf.buf) { ++ OPENSSL_free(rdata->rbuf.buf); ++ } ++ OPENSSL_free(item->data); ++ pitem_free(item); ++ } ++ ++ dtls1_clear_received_buffer(s); ++ dtls1_clear_sent_buffer(s); ++} ++ ++void dtls1_clear_received_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } ++} + ++void dtls1_clear_sent_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } +- +- while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { +- rdata = (DTLS1_RECORD_DATA *)item->data; +- if (rdata->rbuf.buf) { +- OPENSSL_free(rdata->rbuf.buf); +- } +- OPENSSL_free(item->data); +- pitem_free(item); +- } + } + ++ + void dtls1_free(SSL *s) + { + ssl3_free(s); +@@ -420,7 +435,7 @@ void dtls1_stop_timer(SSL *s) + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + } + + int dtls1_check_timeout_num(SSL *s) +Index: crypto/openssl/ssl/d1_pkt.c +=================================================================== +--- crypto/openssl/ssl/d1_pkt.c (revision 306156) ++++ crypto/openssl/ssl/d1_pkt.c (working copy) +@@ -194,7 +194,7 @@ static int dtls1_record_needs_buffering(SSL *s, SS + #endif + static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +-static int dtls1_process_record(SSL *s); ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); + + /* copy buffered record into SSL structure */ + static int dtls1_copy_record(SSL *s, pitem *item) +@@ -319,21 +319,70 @@ static int dtls1_retrieve_buffered_record(SSL *s, + static int dtls1_process_buffered_records(SSL *s) + { + pitem *item; ++ SSL3_BUFFER *rb; ++ SSL3_RECORD *rr; ++ DTLS1_BITMAP *bitmap; ++ unsigned int is_next_epoch; ++ int replayok = 1; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) +- return (1); /* Nothing to do. */ ++ return 1; /* Nothing to do. */ + ++ rr = &s->s3->rrec; ++ rb = &s->s3->rbuf; ++ ++ if (rb->left > 0) { ++ /* ++ * We've still got data from the current packet to read. There could ++ * be a record from the new epoch in it - so don't overwrite it ++ * with the unprocessed records yet (we'll do it when we've ++ * finished reading the current packet). ++ */ ++ return 1; ++ } ++ ++ + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); +- if (!dtls1_process_record(s)) +- return (0); ++ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); ++ if (bitmap == NULL) { ++ /* ++ * Should not happen. This will only ever be NULL when the ++ * current record is from a different epoch. But that cannot ++ * be the case because we already checked the epoch above ++ */ ++ SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++#ifndef OPENSSL_NO_SCTP ++ /* Only do replay check if no SCTP bio */ ++ if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) ++#endif ++ { ++ /* ++ * Check whether this is a repeat, or aged record. We did this ++ * check once already when we first received the record - but ++ * we might have updated the window since then due to ++ * records we subsequently processed. ++ */ ++ replayok = dtls1_record_replay_check(s, bitmap); ++ } ++ ++ if (!replayok || !dtls1_process_record(s, bitmap)) { ++ /* dump this record */ ++ rr->length = 0; ++ s->packet_length = 0; ++ continue; ++ } ++ + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num) < 0) +- return -1; ++ return 0; + } + } + +@@ -344,7 +393,7 @@ static int dtls1_process_buffered_records(SSL *s) + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + +- return (1); ++ return 1; + } + + #if 0 +@@ -391,7 +440,7 @@ static int dtls1_get_buffered_record(SSL *s) + + #endif + +-static int dtls1_process_record(SSL *s) ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) + { + int i, al; + int enc_err; +@@ -551,6 +600,10 @@ static int dtls1_get_buffered_record(SSL *s) + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; ++ ++ /* Mark receipt of record. */ ++ dtls1_record_bitmap_update(s, bitmap); ++ + return (1); + + f_err: +@@ -581,11 +634,12 @@ int dtls1_get_record(SSL *s) + + rr = &(s->s3->rrec); + ++ again: + /* + * The epoch may have changed. If so, process all the pending records. + * This is a non-blocking operation. + */ +- if (dtls1_process_buffered_records(s) < 0) ++ if (!dtls1_process_buffered_records(s)) + return -1; + + /* if we're renegotiating, then there may be buffered records */ +@@ -593,7 +647,6 @@ int dtls1_get_record(SSL *s) + return 1; + + /* get something from the wire */ +- again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { +@@ -717,8 +770,6 @@ int dtls1_get_record(SSL *s) + if (dtls1_buffer_record + (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) + return -1; +- /* Mark receipt of record. */ +- dtls1_record_bitmap_update(s, bitmap); + } + rr->length = 0; + s->packet_length = 0; +@@ -725,12 +776,11 @@ int dtls1_get_record(SSL *s) + goto again; + } + +- if (!dtls1_process_record(s)) { ++ if (!dtls1_process_record(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +- dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ + + return (1); + +@@ -1814,8 +1864,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3 + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + +- /* Only HM and ALERT messages can be from the next epoch */ ++ /* ++ * Only HM and ALERT messages can be from the next epoch and only if we ++ * have already processed all of the unprocessed records from the last ++ * epoch ++ */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && ++ s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; +@@ -1894,6 +1949,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) + s->d1->r_epoch++; + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); ++ ++ /* ++ * We must not use any buffered messages received from the previous ++ * epoch ++ */ ++ dtls1_clear_received_buffer(s); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, +Index: crypto/openssl/ssl/d1_srvr.c +=================================================================== +--- crypto/openssl/ssl/d1_srvr.c (revision 306156) ++++ crypto/openssl/ssl/d1_srvr.c (working copy) +@@ -282,7 +282,7 @@ int dtls1_accept(SSL *s) + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + dtls1_start_timer(s); + ret = dtls1_send_hello_request(s); + if (ret <= 0) +@@ -845,6 +845,7 @@ int dtls1_accept(SSL *s) + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +Index: crypto/openssl/ssl/s3_clnt.c +=================================================================== +--- crypto/openssl/ssl/s3_clnt.c (revision 306156) ++++ crypto/openssl/ssl/s3_clnt.c (working copy) +@@ -1143,6 +1143,12 @@ int ssl3_get_server_certificate(SSL *s) + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +@@ -2046,6 +2052,11 @@ int ssl3_get_certificate_request(SSL *s) + } + + for (nc = 0; nc < llen;) { ++ if (nc + 2 > llen) { ++ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); ++ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); ++ goto err; ++ } + n2s(p, l); + if ((l + nc + 2) > llen) { + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) +Index: crypto/openssl/ssl/s3_srvr.c +=================================================================== +--- crypto/openssl/ssl/s3_srvr.c (revision 306156) ++++ crypto/openssl/ssl/s3_srvr.c (working copy) +@@ -1041,7 +1041,7 @@ int ssl3_get_client_hello(SSL *s) + + session_length = *(p + SSL3_RANDOM_SIZE); + +- if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { ++ if (SSL3_RANDOM_SIZE + session_length + 1 >= (d + n) - p) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1059,7 +1059,7 @@ int ssl3_get_client_hello(SSL *s) + /* get the session-id */ + j = *(p++); + +- if (p + j > d + n) { ++ if ((d + n) - p < j) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1109,7 +1109,7 @@ int ssl3_get_client_hello(SSL *s) + + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + /* cookie stuff */ +- if (p + 1 > d + n) { ++ if ((d + n) - p < 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1116,7 +1116,7 @@ int ssl3_get_client_hello(SSL *s) + } + cookie_len = *(p++); + +- if (p + cookie_len > d + n) { ++ if ((d + n ) - p < cookie_len) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1162,7 +1162,7 @@ int ssl3_get_client_hello(SSL *s) + p += cookie_len; + } + +- if (p + 2 > d + n) { ++ if ((d + n ) - p < 2) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1176,7 +1176,7 @@ int ssl3_get_client_hello(SSL *s) + } + + /* i bytes of cipher data + 1 byte for compression length later */ +- if ((p + i + 1) > (d + n)) { ++ if ((d + n) - p < i + 1) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1242,7 +1242,7 @@ int ssl3_get_client_hello(SSL *s) + + /* compression */ + i = *(p++); +- if ((p + i) > (d + n)) { ++ if ((d + n) - p < i) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1264,7 +1264,7 @@ int ssl3_get_client_hello(SSL *s) + #ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (s->version >= SSL3_VERSION) { +- if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) { ++ if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) { + /* 'al' set by ssl_parse_clienthello_tlsext */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; +@@ -3218,6 +3218,12 @@ int ssl3_get_client_certificate(SSL *s) + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +Index: crypto/openssl/ssl/ssl.h +=================================================================== +--- crypto/openssl/ssl/ssl.h (revision 306156) ++++ crypto/openssl/ssl/ssl.h (working copy) +@@ -2256,6 +2256,7 @@ void ERR_load_SSL_strings(void); + # define SSL_F_DTLS1_HEARTBEAT 305 + # define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 + # define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 ++# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 + # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 + # define SSL_F_DTLS1_PROCESS_RECORD 257 + # define SSL_F_DTLS1_READ_BYTES 258 +Index: crypto/openssl/ssl/ssl_err.c +=================================================================== +--- crypto/openssl/ssl/ssl_err.c (revision 306156) ++++ crypto/openssl/ssl/ssl_err.c (working copy) +@@ -1,6 +1,6 @@ + /* ssl/ssl_err.c */ + /* ==================================================================== +- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -93,6 +93,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { + {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, ++ {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), ++ "DTLS1_PROCESS_BUFFERED_RECORDS"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), + "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, +Index: crypto/openssl/ssl/ssl_locl.h +=================================================================== +--- crypto/openssl/ssl/ssl_locl.h (revision 306156) ++++ crypto/openssl/ssl/ssl_locl.h (working copy) +@@ -1025,7 +1025,8 @@ int dtls1_retransmit_message(SSL *s, unsigned shor + unsigned long frag_off, int *found); + int dtls1_get_queue_priority(unsigned short seq, int is_ccs); + int dtls1_retransmit_buffered_messages(SSL *s); +-void dtls1_clear_record_buffer(SSL *s); ++void dtls1_clear_received_buffer(SSL *s); ++void dtls1_clear_sent_buffer(SSL *s); + void dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); + void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +@@ -1154,7 +1155,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, + unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit); + int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, +- unsigned char *d, int n, int *al); ++ unsigned char *limit, int *al); + int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n, int *al); + int ssl_prepare_clienthello_tlsext(SSL *s); +Index: crypto/openssl/ssl/ssl_sess.c +=================================================================== +--- crypto/openssl/ssl/ssl_sess.c (revision 306156) ++++ crypto/openssl/ssl/ssl_sess.c (working copy) +@@ -605,7 +605,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *se + if (len < 0 || len > SSL_MAX_SSL_SESSION_ID_LENGTH) + goto err; + +- if (session_id + len > limit) { ++ if (limit - session_id < len) { + fatal = 1; + goto err; + } +Index: crypto/openssl/ssl/t1_lib.c +=================================================================== +--- crypto/openssl/ssl/t1_lib.c (revision 306156) ++++ crypto/openssl/ssl/t1_lib.c (working copy) +@@ -913,7 +913,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, + * 10.8..10.8.3 (which don't work). + */ + static void ssl_check_for_safari(SSL *s, const unsigned char *data, +- const unsigned char *d, int n) ++ const unsigned char *limit) + { + unsigned short type, size; + static const unsigned char kSafariExtensionsBlock[] = { +@@ -942,11 +942,11 @@ static void ssl_check_for_safari(SSL *s, const uns + 0x02, 0x03, /* SHA-1/ECDSA */ + }; + +- if (data >= (d + n - 2)) ++ if (limit - data <= 2) + return; + data += 2; + +- if (data > (d + n - 4)) ++ if (limit - data < 4) + return; + n2s(data, type); + n2s(data, size); +@@ -954,7 +954,7 @@ static void ssl_check_for_safari(SSL *s, const uns + if (type != TLSEXT_TYPE_server_name) + return; + +- if (data + size > d + n) ++ if (limit - data < size) + return; + data += size; + +@@ -962,7 +962,7 @@ static void ssl_check_for_safari(SSL *s, const uns + const size_t len1 = sizeof(kSafariExtensionsBlock); + const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); + +- if (data + len1 + len2 != d + n) ++ if (limit - data != (int)(len1 + len2)) + return; + if (memcmp(data, kSafariExtensionsBlock, len1) != 0) + return; +@@ -971,7 +971,7 @@ static void ssl_check_for_safari(SSL *s, const uns + } else { + const size_t len = sizeof(kSafariExtensionsBlock); + +- if (data + len != d + n) ++ if (limit - data != (int)(len)) + return; + if (memcmp(data, kSafariExtensionsBlock, len) != 0) + return; +@@ -981,8 +981,8 @@ static void ssl_check_for_safari(SSL *s, const uns + } + # endif /* !OPENSSL_NO_EC */ + +-int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, +- int n, int *al) ++int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, ++ unsigned char *limit, int *al) + { + unsigned short type; + unsigned short size; +@@ -1004,7 +1004,7 @@ static void ssl_check_for_safari(SSL *s, const uns + + # ifndef OPENSSL_NO_EC + if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) +- ssl_check_for_safari(s, data, d, n); ++ ssl_check_for_safari(s, data, limit); + # endif /* !OPENSSL_NO_EC */ + + # ifndef OPENSSL_NO_SRP +@@ -1016,22 +1016,22 @@ static void ssl_check_for_safari(SSL *s, const uns + + s->srtp_profile = NULL; + +- if (data == d + n) ++ if (data == limit) + goto ri_check; + +- if (data > (d + n - 2)) ++ if (limit - data < 2) + goto err; + + n2s(data, len); + +- if (data > (d + n - len)) ++ if (limit - data != len) + goto err; + +- while (data <= (d + n - 4)) { ++ while (limit - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) ++ if (limit - data < size) + goto err; + # if 0 + fprintf(stderr, "Received extension type %d size %d\n", type, size); +@@ -1284,6 +1284,23 @@ static void ssl_check_for_safari(SSL *s, const uns + 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 @@ static void ssl_check_for_safari(SSL *s, const uns + 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; +@@ -1396,7 +1406,7 @@ static void ssl_check_for_safari(SSL *s, const uns + } + + /* Spurious data on the end */ +- if (data != d + n) ++ if (data != limit) + goto err; + + *p = data; +@@ -1460,20 +1470,20 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); + # endif + +- if (data >= (d + n - 2)) ++ if ((d + n) - data <= 2) + goto ri_check; + + n2s(data, length); +- if (data + length != d + n) { ++ if ((d + n) - data != length) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + +- while (data <= (d + n - 4)) { ++ while ((d + n) - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) ++ if ((d + n) - data < size) + goto ri_check; + + if (s->tlsext_debug_cb) +@@ -2181,29 +2191,33 @@ int tls1_process_ticket(SSL *s, unsigned char *ses + /* Skip past DTLS cookie */ + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + i = *(p++); ++ ++ if (limit - p <= i) ++ return -1; ++ + p += i; +- if (p >= limit) +- return -1; + } + /* Skip past cipher list */ + n2s(p, i); ++ if (limit - p <= i) ++ return -1; + p += i; +- if (p >= limit) +- return -1; ++ + /* Skip past compression algorithm list */ + i = *(p++); ++ if (limit - p < i) ++ return -1; + p += i; +- if (p > limit) +- return -1; ++ + /* Now at start of extensions */ +- if ((p + 2) >= limit) ++ if (limit - p <= 2) + return 0; + n2s(p, i); +- while ((p + 4) <= limit) { ++ while (limit - p >= 4) { + unsigned short type, size; + n2s(p, type); + n2s(p, size); +- if (p + size > limit) ++ if (limit - p < size) + return 0; + if (type == TLSEXT_TYPE_session_ticket) { + int r; +@@ -2271,9 +2285,7 @@ static int tls_decrypt_ticket(SSL *s, const unsign + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; +- /* Need at least keyname + iv + some encrypted data */ +- if (eticklen < 48) +- return 2; ++ + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); +@@ -2305,6 +2317,13 @@ static int tls_decrypt_ticket(SSL *s, const unsign + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } ++ /* Sanity check ticket length: must exceed keyname + IV + HMAC */ ++ if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { ++ HMAC_CTX_cleanup(&hctx); ++ EVP_CIPHER_CTX_cleanup(&ctx); ++ return 2; ++ } ++ + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + HMAC_Update(&hctx, etick, eticklen); Index: user/cperciva/freebsd-update-build/patches/10.2-RELEASE/21-SA-16:26.openssl =================================================================== --- user/cperciva/freebsd-update-build/patches/10.2-RELEASE/21-SA-16:26.openssl (nonexistent) +++ user/cperciva/freebsd-update-build/patches/10.2-RELEASE/21-SA-16:26.openssl (revision 306270) @@ -0,0 +1,879 @@ +Index: crypto/openssl/crypto/bn/bn_print.c +=================================================================== +--- crypto/openssl/crypto/bn/bn_print.c (revision 306156) ++++ crypto/openssl/crypto/bn/bn_print.c (working copy) +@@ -111,6 +111,7 @@ char *BN_bn2dec(const BIGNUM *a) + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; ++ int bn_data_num; + + /*- + * get an upper bound for the length of the decimal integer +@@ -120,8 +121,8 @@ char *BN_bn2dec(const BIGNUM *a) + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; +- bn_data = +- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG)); ++ bn_data_num = num / BN_DEC_NUM + 1; ++ bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = (char *)OPENSSL_malloc(num + 3); + if ((buf == NULL) || (bn_data == NULL)) { + BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); +@@ -143,7 +144,11 @@ char *BN_bn2dec(const BIGNUM *a) + i = 0; + while (!BN_is_zero(t)) { + *lp = BN_div_word(t, BN_DEC_CONV); ++ if (*lp == (BN_ULONG)-1) ++ goto err; + lp++; ++ if (lp - bn_data >= bn_data_num) ++ goto err; + } + lp--; + /* +Index: crypto/openssl/crypto/dsa/dsa_ossl.c +=================================================================== +--- crypto/openssl/crypto/dsa/dsa_ossl.c (revision 306156) ++++ crypto/openssl/crypto/dsa/dsa_ossl.c (working copy) +@@ -247,11 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + do + if (!BN_rand_range(&k, dsa->q)) + goto err; +- while (BN_is_zero(&k)) ; ++ while (BN_is_zero(&k)); ++ + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); + } + ++ + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) +@@ -264,6 +266,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + if (!BN_copy(&kq, &k)) + goto err; + ++ BN_set_flags(&kq, BN_FLG_CONSTTIME); ++ + /* + * We do not want timing information to leak the length of k, so we + * compute g^k using an equivalent exponent of fixed length. (This +@@ -282,6 +286,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + } else { + K = &k; + } ++ + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, + dsa->method_mont_p); + if (!BN_mod(r, r, dsa->q, ctx)) +Index: crypto/openssl/crypto/mdc2/mdc2dgst.c +=================================================================== +--- crypto/openssl/crypto/mdc2/mdc2dgst.c (revision 306156) ++++ crypto/openssl/crypto/mdc2/mdc2dgst.c (working copy) +@@ -91,7 +91,7 @@ int MDC2_Update(MDC2_CTX *c, const unsigned char * + + i = c->num; + if (i != 0) { +- if (i + len < MDC2_BLOCK) { ++ if (len < MDC2_BLOCK - i) { + /* partial block */ + memcpy(&(c->data[i]), in, len); + c->num += (int)len; +Index: crypto/openssl/crypto/ts/ts_lib.c +=================================================================== +--- crypto/openssl/crypto/ts/ts_lib.c (revision 306156) ++++ crypto/openssl/crypto/ts/ts_lib.c (working copy) +@@ -90,9 +90,8 @@ int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT * + { + char obj_txt[128]; + +- int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); +- BIO_write(bio, obj_txt, len); +- BIO_write(bio, "\n", 1); ++ OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); ++ BIO_printf(bio, "%s\n", obj_txt); + + return 1; + } +Index: crypto/openssl/ssl/d1_both.c +=================================================================== +--- crypto/openssl/ssl/d1_both.c (revision 306156) ++++ crypto/openssl/ssl/d1_both.c (working copy) +@@ -586,12 +586,24 @@ static int dtls1_retrieve_buffered_fragment(SSL *s + int al; + + *ok = 0; +- item = pqueue_peek(s->d1->buffered_messages); +- if (item == NULL) +- return 0; ++ do { ++ item = pqueue_peek(s->d1->buffered_messages); ++ if (item == NULL) ++ return 0; + +- frag = (hm_fragment *)item->data; ++ frag = (hm_fragment *)item->data; + ++ if (frag->msg_header.seq < s->d1->handshake_read_seq) { ++ /* This is a stale message that has been buffered so clear it */ ++ pqueue_pop(s->d1->buffered_messages); ++ dtls1_hm_fragment_free(frag); ++ pitem_free(item); ++ item = NULL; ++ frag = NULL; ++ } ++ } while (item == NULL); ++ ++ + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; +@@ -1388,18 +1400,6 @@ dtls1_retransmit_message(SSL *s, unsigned short se + return ret; + } + +-/* call this function when the buffered messages are no longer needed */ +-void dtls1_clear_record_buffer(SSL *s) +-{ +- pitem *item; +- +- for (item = pqueue_pop(s->d1->sent_messages); +- item != NULL; item = pqueue_pop(s->d1->sent_messages)) { +- dtls1_hm_fragment_free((hm_fragment *)item->data); +- pitem_free(item); +- } +-} +- + unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, + unsigned long frag_off, +Index: crypto/openssl/ssl/d1_clnt.c +=================================================================== +--- crypto/openssl/ssl/d1_clnt.c (revision 306156) ++++ crypto/openssl/ssl/d1_clnt.c (working copy) +@@ -740,6 +740,7 @@ int dtls1_connect(SSL *s) + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +Index: crypto/openssl/ssl/d1_lib.c +=================================================================== +--- crypto/openssl/ssl/d1_lib.c (revision 306156) ++++ crypto/openssl/ssl/d1_lib.c (working copy) +@@ -144,7 +144,6 @@ int dtls1_new(SSL *s) + static void dtls1_clear_queues(SSL *s) + { + pitem *item = NULL; +- hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { +@@ -165,28 +164,44 @@ static void dtls1_clear_queues(SSL *s) + pitem_free(item); + } + ++ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { ++ rdata = (DTLS1_RECORD_DATA *)item->data; ++ if (rdata->rbuf.buf) { ++ OPENSSL_free(rdata->rbuf.buf); ++ } ++ OPENSSL_free(item->data); ++ pitem_free(item); ++ } ++ ++ dtls1_clear_received_buffer(s); ++ dtls1_clear_sent_buffer(s); ++} ++ ++void dtls1_clear_received_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } ++} + ++void dtls1_clear_sent_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } +- +- while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { +- rdata = (DTLS1_RECORD_DATA *)item->data; +- if (rdata->rbuf.buf) { +- OPENSSL_free(rdata->rbuf.buf); +- } +- OPENSSL_free(item->data); +- pitem_free(item); +- } + } + ++ + void dtls1_free(SSL *s) + { + ssl3_free(s); +@@ -420,7 +435,7 @@ void dtls1_stop_timer(SSL *s) + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + } + + int dtls1_check_timeout_num(SSL *s) +Index: crypto/openssl/ssl/d1_pkt.c +=================================================================== +--- crypto/openssl/ssl/d1_pkt.c (revision 306156) ++++ crypto/openssl/ssl/d1_pkt.c (working copy) +@@ -194,7 +194,7 @@ static int dtls1_record_needs_buffering(SSL *s, SS + #endif + static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +-static int dtls1_process_record(SSL *s); ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); + + /* copy buffered record into SSL structure */ + static int dtls1_copy_record(SSL *s, pitem *item) +@@ -319,21 +319,70 @@ static int dtls1_retrieve_buffered_record(SSL *s, + static int dtls1_process_buffered_records(SSL *s) + { + pitem *item; ++ SSL3_BUFFER *rb; ++ SSL3_RECORD *rr; ++ DTLS1_BITMAP *bitmap; ++ unsigned int is_next_epoch; ++ int replayok = 1; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) +- return (1); /* Nothing to do. */ ++ return 1; /* Nothing to do. */ + ++ rr = &s->s3->rrec; ++ rb = &s->s3->rbuf; ++ ++ if (rb->left > 0) { ++ /* ++ * We've still got data from the current packet to read. There could ++ * be a record from the new epoch in it - so don't overwrite it ++ * with the unprocessed records yet (we'll do it when we've ++ * finished reading the current packet). ++ */ ++ return 1; ++ } ++ ++ + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); +- if (!dtls1_process_record(s)) +- return (0); ++ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); ++ if (bitmap == NULL) { ++ /* ++ * Should not happen. This will only ever be NULL when the ++ * current record is from a different epoch. But that cannot ++ * be the case because we already checked the epoch above ++ */ ++ SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++#ifndef OPENSSL_NO_SCTP ++ /* Only do replay check if no SCTP bio */ ++ if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) ++#endif ++ { ++ /* ++ * Check whether this is a repeat, or aged record. We did this ++ * check once already when we first received the record - but ++ * we might have updated the window since then due to ++ * records we subsequently processed. ++ */ ++ replayok = dtls1_record_replay_check(s, bitmap); ++ } ++ ++ if (!replayok || !dtls1_process_record(s, bitmap)) { ++ /* dump this record */ ++ rr->length = 0; ++ s->packet_length = 0; ++ continue; ++ } ++ + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num) < 0) +- return -1; ++ return 0; + } + } + +@@ -344,7 +393,7 @@ static int dtls1_process_buffered_records(SSL *s) + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + +- return (1); ++ return 1; + } + + #if 0 +@@ -391,7 +440,7 @@ static int dtls1_get_buffered_record(SSL *s) + + #endif + +-static int dtls1_process_record(SSL *s) ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) + { + int i, al; + int enc_err; +@@ -551,6 +600,10 @@ static int dtls1_get_buffered_record(SSL *s) + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; ++ ++ /* Mark receipt of record. */ ++ dtls1_record_bitmap_update(s, bitmap); ++ + return (1); + + f_err: +@@ -581,11 +634,12 @@ int dtls1_get_record(SSL *s) + + rr = &(s->s3->rrec); + ++ again: + /* + * The epoch may have changed. If so, process all the pending records. + * This is a non-blocking operation. + */ +- if (dtls1_process_buffered_records(s) < 0) ++ if (!dtls1_process_buffered_records(s)) + return -1; + + /* if we're renegotiating, then there may be buffered records */ +@@ -593,7 +647,6 @@ int dtls1_get_record(SSL *s) + return 1; + + /* get something from the wire */ +- again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { +@@ -717,8 +770,6 @@ int dtls1_get_record(SSL *s) + if (dtls1_buffer_record + (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) + return -1; +- /* Mark receipt of record. */ +- dtls1_record_bitmap_update(s, bitmap); + } + rr->length = 0; + s->packet_length = 0; +@@ -725,12 +776,11 @@ int dtls1_get_record(SSL *s) + goto again; + } + +- if (!dtls1_process_record(s)) { ++ if (!dtls1_process_record(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +- dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ + + return (1); + +@@ -1814,8 +1864,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3 + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + +- /* Only HM and ALERT messages can be from the next epoch */ ++ /* ++ * Only HM and ALERT messages can be from the next epoch and only if we ++ * have already processed all of the unprocessed records from the last ++ * epoch ++ */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && ++ s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; +@@ -1894,6 +1949,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) + s->d1->r_epoch++; + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); ++ ++ /* ++ * We must not use any buffered messages received from the previous ++ * epoch ++ */ ++ dtls1_clear_received_buffer(s); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, +Index: crypto/openssl/ssl/d1_srvr.c +=================================================================== +--- crypto/openssl/ssl/d1_srvr.c (revision 306156) ++++ crypto/openssl/ssl/d1_srvr.c (working copy) +@@ -282,7 +282,7 @@ int dtls1_accept(SSL *s) + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + dtls1_start_timer(s); + ret = dtls1_send_hello_request(s); + if (ret <= 0) +@@ -845,6 +845,7 @@ int dtls1_accept(SSL *s) + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +Index: crypto/openssl/ssl/s3_clnt.c +=================================================================== +--- crypto/openssl/ssl/s3_clnt.c (revision 306156) ++++ crypto/openssl/ssl/s3_clnt.c (working copy) +@@ -1143,6 +1143,12 @@ int ssl3_get_server_certificate(SSL *s) + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +@@ -2046,6 +2052,11 @@ int ssl3_get_certificate_request(SSL *s) + } + + for (nc = 0; nc < llen;) { ++ if (nc + 2 > llen) { ++ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); ++ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); ++ goto err; ++ } + n2s(p, l); + if ((l + nc + 2) > llen) { + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) +Index: crypto/openssl/ssl/s3_srvr.c +=================================================================== +--- crypto/openssl/ssl/s3_srvr.c (revision 306156) ++++ crypto/openssl/ssl/s3_srvr.c (working copy) +@@ -1041,7 +1041,7 @@ int ssl3_get_client_hello(SSL *s) + + session_length = *(p + SSL3_RANDOM_SIZE); + +- if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { ++ if (SSL3_RANDOM_SIZE + session_length + 1 >= (d + n) - p) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1059,7 +1059,7 @@ int ssl3_get_client_hello(SSL *s) + /* get the session-id */ + j = *(p++); + +- if (p + j > d + n) { ++ if ((d + n) - p < j) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1109,7 +1109,7 @@ int ssl3_get_client_hello(SSL *s) + + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + /* cookie stuff */ +- if (p + 1 > d + n) { ++ if ((d + n) - p < 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1116,7 +1116,7 @@ int ssl3_get_client_hello(SSL *s) + } + cookie_len = *(p++); + +- if (p + cookie_len > d + n) { ++ if ((d + n ) - p < cookie_len) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1162,7 +1162,7 @@ int ssl3_get_client_hello(SSL *s) + p += cookie_len; + } + +- if (p + 2 > d + n) { ++ if ((d + n ) - p < 2) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1176,7 +1176,7 @@ int ssl3_get_client_hello(SSL *s) + } + + /* i bytes of cipher data + 1 byte for compression length later */ +- if ((p + i + 1) > (d + n)) { ++ if ((d + n) - p < i + 1) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1242,7 +1242,7 @@ int ssl3_get_client_hello(SSL *s) + + /* compression */ + i = *(p++); +- if ((p + i) > (d + n)) { ++ if ((d + n) - p < i) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1264,7 +1264,7 @@ int ssl3_get_client_hello(SSL *s) + #ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (s->version >= SSL3_VERSION) { +- if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) { ++ if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) { + /* 'al' set by ssl_parse_clienthello_tlsext */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; +@@ -3218,6 +3218,12 @@ int ssl3_get_client_certificate(SSL *s) + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +Index: crypto/openssl/ssl/ssl.h +=================================================================== +--- crypto/openssl/ssl/ssl.h (revision 306156) ++++ crypto/openssl/ssl/ssl.h (working copy) +@@ -2256,6 +2256,7 @@ void ERR_load_SSL_strings(void); + # define SSL_F_DTLS1_HEARTBEAT 305 + # define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 + # define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 ++# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 + # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 + # define SSL_F_DTLS1_PROCESS_RECORD 257 + # define SSL_F_DTLS1_READ_BYTES 258 +Index: crypto/openssl/ssl/ssl_err.c +=================================================================== +--- crypto/openssl/ssl/ssl_err.c (revision 306156) ++++ crypto/openssl/ssl/ssl_err.c (working copy) +@@ -1,6 +1,6 @@ + /* ssl/ssl_err.c */ + /* ==================================================================== +- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -93,6 +93,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { + {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, ++ {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), ++ "DTLS1_PROCESS_BUFFERED_RECORDS"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), + "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, +Index: crypto/openssl/ssl/ssl_locl.h +=================================================================== +--- crypto/openssl/ssl/ssl_locl.h (revision 306156) ++++ crypto/openssl/ssl/ssl_locl.h (working copy) +@@ -1025,7 +1025,8 @@ int dtls1_retransmit_message(SSL *s, unsigned shor + unsigned long frag_off, int *found); + int dtls1_get_queue_priority(unsigned short seq, int is_ccs); + int dtls1_retransmit_buffered_messages(SSL *s); +-void dtls1_clear_record_buffer(SSL *s); ++void dtls1_clear_received_buffer(SSL *s); ++void dtls1_clear_sent_buffer(SSL *s); + void dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); + void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +@@ -1154,7 +1155,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, + unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit); + int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, +- unsigned char *d, int n, int *al); ++ unsigned char *limit, int *al); + int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n, int *al); + int ssl_prepare_clienthello_tlsext(SSL *s); +Index: crypto/openssl/ssl/ssl_sess.c +=================================================================== +--- crypto/openssl/ssl/ssl_sess.c (revision 306156) ++++ crypto/openssl/ssl/ssl_sess.c (working copy) +@@ -605,7 +605,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *se + if (len < 0 || len > SSL_MAX_SSL_SESSION_ID_LENGTH) + goto err; + +- if (session_id + len > limit) { ++ if (limit - session_id < len) { + fatal = 1; + goto err; + } +Index: crypto/openssl/ssl/t1_lib.c +=================================================================== +--- crypto/openssl/ssl/t1_lib.c (revision 306156) ++++ crypto/openssl/ssl/t1_lib.c (working copy) +@@ -913,7 +913,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, + * 10.8..10.8.3 (which don't work). + */ + static void ssl_check_for_safari(SSL *s, const unsigned char *data, +- const unsigned char *d, int n) ++ const unsigned char *limit) + { + unsigned short type, size; + static const unsigned char kSafariExtensionsBlock[] = { +@@ -942,11 +942,11 @@ static void ssl_check_for_safari(SSL *s, const uns + 0x02, 0x03, /* SHA-1/ECDSA */ + }; + +- if (data >= (d + n - 2)) ++ if (limit - data <= 2) + return; + data += 2; + +- if (data > (d + n - 4)) ++ if (limit - data < 4) + return; + n2s(data, type); + n2s(data, size); +@@ -954,7 +954,7 @@ static void ssl_check_for_safari(SSL *s, const uns + if (type != TLSEXT_TYPE_server_name) + return; + +- if (data + size > d + n) ++ if (limit - data < size) + return; + data += size; + +@@ -962,7 +962,7 @@ static void ssl_check_for_safari(SSL *s, const uns + const size_t len1 = sizeof(kSafariExtensionsBlock); + const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); + +- if (data + len1 + len2 != d + n) ++ if (limit - data != (int)(len1 + len2)) + return; + if (memcmp(data, kSafariExtensionsBlock, len1) != 0) + return; +@@ -971,7 +971,7 @@ static void ssl_check_for_safari(SSL *s, const uns + } else { + const size_t len = sizeof(kSafariExtensionsBlock); + +- if (data + len != d + n) ++ if (limit - data != (int)(len)) + return; + if (memcmp(data, kSafariExtensionsBlock, len) != 0) + return; +@@ -981,8 +981,8 @@ static void ssl_check_for_safari(SSL *s, const uns + } + # endif /* !OPENSSL_NO_EC */ + +-int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, +- int n, int *al) ++int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, ++ unsigned char *limit, int *al) + { + unsigned short type; + unsigned short size; +@@ -1004,7 +1004,7 @@ static void ssl_check_for_safari(SSL *s, const uns + + # ifndef OPENSSL_NO_EC + if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) +- ssl_check_for_safari(s, data, d, n); ++ ssl_check_for_safari(s, data, limit); + # endif /* !OPENSSL_NO_EC */ + + # ifndef OPENSSL_NO_SRP +@@ -1016,22 +1016,22 @@ static void ssl_check_for_safari(SSL *s, const uns + + s->srtp_profile = NULL; + +- if (data == d + n) ++ if (data == limit) + goto ri_check; + +- if (data > (d + n - 2)) ++ if (limit - data < 2) + goto err; + + n2s(data, len); + +- if (data > (d + n - len)) ++ if (limit - data != len) + goto err; + +- while (data <= (d + n - 4)) { ++ while (limit - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) ++ if (limit - data < size) + goto err; + # if 0 + fprintf(stderr, "Received extension type %d size %d\n", type, size); +@@ -1284,6 +1284,23 @@ static void ssl_check_for_safari(SSL *s, const uns + 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 @@ static void ssl_check_for_safari(SSL *s, const uns + 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; +@@ -1396,7 +1406,7 @@ static void ssl_check_for_safari(SSL *s, const uns + } + + /* Spurious data on the end */ +- if (data != d + n) ++ if (data != limit) + goto err; + + *p = data; +@@ -1460,20 +1470,20 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); + # endif + +- if (data >= (d + n - 2)) ++ if ((d + n) - data <= 2) + goto ri_check; + + n2s(data, length); +- if (data + length != d + n) { ++ if ((d + n) - data != length) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + +- while (data <= (d + n - 4)) { ++ while ((d + n) - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) ++ if ((d + n) - data < size) + goto ri_check; + + if (s->tlsext_debug_cb) +@@ -2181,29 +2191,33 @@ int tls1_process_ticket(SSL *s, unsigned char *ses + /* Skip past DTLS cookie */ + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + i = *(p++); ++ ++ if (limit - p <= i) ++ return -1; ++ + p += i; +- if (p >= limit) +- return -1; + } + /* Skip past cipher list */ + n2s(p, i); ++ if (limit - p <= i) ++ return -1; + p += i; +- if (p >= limit) +- return -1; ++ + /* Skip past compression algorithm list */ + i = *(p++); ++ if (limit - p < i) ++ return -1; + p += i; +- if (p > limit) +- return -1; ++ + /* Now at start of extensions */ +- if ((p + 2) >= limit) ++ if (limit - p <= 2) + return 0; + n2s(p, i); +- while ((p + 4) <= limit) { ++ while (limit - p >= 4) { + unsigned short type, size; + n2s(p, type); + n2s(p, size); +- if (p + size > limit) ++ if (limit - p < size) + return 0; + if (type == TLSEXT_TYPE_session_ticket) { + int r; +@@ -2271,9 +2285,7 @@ static int tls_decrypt_ticket(SSL *s, const unsign + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; +- /* Need at least keyname + iv + some encrypted data */ +- if (eticklen < 48) +- return 2; ++ + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); +@@ -2305,6 +2317,13 @@ static int tls_decrypt_ticket(SSL *s, const unsign + EVP_CIPHER_CTX_cleanup(&ctx); + return -1; + } ++ /* Sanity check ticket length: must exceed keyname + IV + HMAC */ ++ if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { ++ HMAC_CTX_cleanup(&hctx); ++ EVP_CIPHER_CTX_cleanup(&ctx); ++ return 2; ++ } ++ + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + HMAC_Update(&hctx, etick, eticklen); Index: user/cperciva/freebsd-update-build/patches/10.3-RELEASE/8-SA-16:26.openssl =================================================================== --- user/cperciva/freebsd-update-build/patches/10.3-RELEASE/8-SA-16:26.openssl (nonexistent) +++ user/cperciva/freebsd-update-build/patches/10.3-RELEASE/8-SA-16:26.openssl (revision 306270) @@ -0,0 +1,819 @@ +Index: crypto/openssl/crypto/bn/bn_print.c +=================================================================== +--- crypto/openssl/crypto/bn/bn_print.c (revision 306156) ++++ crypto/openssl/crypto/bn/bn_print.c (working copy) +@@ -111,6 +111,7 @@ char *BN_bn2dec(const BIGNUM *a) + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; ++ int bn_data_num; + + /*- + * get an upper bound for the length of the decimal integer +@@ -120,8 +121,8 @@ char *BN_bn2dec(const BIGNUM *a) + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; +- bn_data = +- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG)); ++ bn_data_num = num / BN_DEC_NUM + 1; ++ bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = (char *)OPENSSL_malloc(num + 3); + if ((buf == NULL) || (bn_data == NULL)) { + BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); +@@ -143,7 +144,11 @@ char *BN_bn2dec(const BIGNUM *a) + i = 0; + while (!BN_is_zero(t)) { + *lp = BN_div_word(t, BN_DEC_CONV); ++ if (*lp == (BN_ULONG)-1) ++ goto err; + lp++; ++ if (lp - bn_data >= bn_data_num) ++ goto err; + } + lp--; + /* +Index: crypto/openssl/crypto/dsa/dsa_ossl.c +=================================================================== +--- crypto/openssl/crypto/dsa/dsa_ossl.c (revision 306156) ++++ crypto/openssl/crypto/dsa/dsa_ossl.c (working copy) +@@ -247,11 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + do + if (!BN_rand_range(&k, dsa->q)) + goto err; +- while (BN_is_zero(&k)) ; ++ while (BN_is_zero(&k)); ++ + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); + } + ++ + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) +@@ -264,6 +266,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + if (!BN_copy(&kq, &k)) + goto err; + ++ BN_set_flags(&kq, BN_FLG_CONSTTIME); ++ + /* + * We do not want timing information to leak the length of k, so we + * compute g^k using an equivalent exponent of fixed length. (This +@@ -282,6 +286,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in + } else { + K = &k; + } ++ + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, + dsa->method_mont_p); + if (!BN_mod(r, r, dsa->q, ctx)) +Index: crypto/openssl/crypto/mdc2/mdc2dgst.c +=================================================================== +--- crypto/openssl/crypto/mdc2/mdc2dgst.c (revision 306156) ++++ crypto/openssl/crypto/mdc2/mdc2dgst.c (working copy) +@@ -91,7 +91,7 @@ int MDC2_Update(MDC2_CTX *c, const unsigned char * + + i = c->num; + if (i != 0) { +- if (i + len < MDC2_BLOCK) { ++ if (len < MDC2_BLOCK - i) { + /* partial block */ + memcpy(&(c->data[i]), in, len); + c->num += (int)len; +Index: crypto/openssl/crypto/ts/ts_lib.c +=================================================================== +--- crypto/openssl/crypto/ts/ts_lib.c (revision 306156) ++++ crypto/openssl/crypto/ts/ts_lib.c (working copy) +@@ -90,9 +90,8 @@ int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT * + { + char obj_txt[128]; + +- int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); +- BIO_write(bio, obj_txt, len); +- BIO_write(bio, "\n", 1); ++ OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); ++ BIO_printf(bio, "%s\n", obj_txt); + + return 1; + } +Index: crypto/openssl/ssl/d1_both.c +=================================================================== +--- crypto/openssl/ssl/d1_both.c (revision 306156) ++++ crypto/openssl/ssl/d1_both.c (working copy) +@@ -614,12 +614,24 @@ static int dtls1_retrieve_buffered_fragment(SSL *s + int al; + + *ok = 0; +- item = pqueue_peek(s->d1->buffered_messages); +- if (item == NULL) +- return 0; ++ do { ++ item = pqueue_peek(s->d1->buffered_messages); ++ if (item == NULL) ++ return 0; + +- frag = (hm_fragment *)item->data; ++ frag = (hm_fragment *)item->data; + ++ if (frag->msg_header.seq < s->d1->handshake_read_seq) { ++ /* This is a stale message that has been buffered so clear it */ ++ pqueue_pop(s->d1->buffered_messages); ++ dtls1_hm_fragment_free(frag); ++ pitem_free(item); ++ item = NULL; ++ frag = NULL; ++ } ++ } while (item == NULL); ++ ++ + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; +@@ -1416,18 +1428,6 @@ dtls1_retransmit_message(SSL *s, unsigned short se + return ret; + } + +-/* call this function when the buffered messages are no longer needed */ +-void dtls1_clear_record_buffer(SSL *s) +-{ +- pitem *item; +- +- for (item = pqueue_pop(s->d1->sent_messages); +- item != NULL; item = pqueue_pop(s->d1->sent_messages)) { +- dtls1_hm_fragment_free((hm_fragment *)item->data); +- pitem_free(item); +- } +-} +- + unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, + unsigned long frag_off, +Index: crypto/openssl/ssl/d1_clnt.c +=================================================================== +--- crypto/openssl/ssl/d1_clnt.c (revision 306156) ++++ crypto/openssl/ssl/d1_clnt.c (working copy) +@@ -751,6 +751,7 @@ int dtls1_connect(SSL *s) + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +Index: crypto/openssl/ssl/d1_lib.c +=================================================================== +--- crypto/openssl/ssl/d1_lib.c (revision 306156) ++++ crypto/openssl/ssl/d1_lib.c (working copy) +@@ -144,7 +144,6 @@ int dtls1_new(SSL *s) + static void dtls1_clear_queues(SSL *s) + { + pitem *item = NULL; +- hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { +@@ -165,28 +164,44 @@ static void dtls1_clear_queues(SSL *s) + pitem_free(item); + } + ++ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { ++ rdata = (DTLS1_RECORD_DATA *)item->data; ++ if (rdata->rbuf.buf) { ++ OPENSSL_free(rdata->rbuf.buf); ++ } ++ OPENSSL_free(item->data); ++ pitem_free(item); ++ } ++ ++ dtls1_clear_received_buffer(s); ++ dtls1_clear_sent_buffer(s); ++} ++ ++void dtls1_clear_received_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } ++} + ++void dtls1_clear_sent_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } +- +- while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { +- rdata = (DTLS1_RECORD_DATA *)item->data; +- if (rdata->rbuf.buf) { +- OPENSSL_free(rdata->rbuf.buf); +- } +- OPENSSL_free(item->data); +- pitem_free(item); +- } + } + ++ + void dtls1_free(SSL *s) + { + ssl3_free(s); +@@ -420,7 +435,7 @@ void dtls1_stop_timer(SSL *s) + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + } + + int dtls1_check_timeout_num(SSL *s) +Index: crypto/openssl/ssl/d1_pkt.c +=================================================================== +--- crypto/openssl/ssl/d1_pkt.c (revision 306156) ++++ crypto/openssl/ssl/d1_pkt.c (working copy) +@@ -194,7 +194,7 @@ static int dtls1_record_needs_buffering(SSL *s, SS + #endif + static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +-static int dtls1_process_record(SSL *s); ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); + + /* copy buffered record into SSL structure */ + static int dtls1_copy_record(SSL *s, pitem *item) +@@ -319,21 +319,70 @@ static int dtls1_retrieve_buffered_record(SSL *s, + static int dtls1_process_buffered_records(SSL *s) + { + pitem *item; ++ SSL3_BUFFER *rb; ++ SSL3_RECORD *rr; ++ DTLS1_BITMAP *bitmap; ++ unsigned int is_next_epoch; ++ int replayok = 1; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) +- return (1); /* Nothing to do. */ ++ return 1; /* Nothing to do. */ + ++ rr = &s->s3->rrec; ++ rb = &s->s3->rbuf; ++ ++ if (rb->left > 0) { ++ /* ++ * We've still got data from the current packet to read. There could ++ * be a record from the new epoch in it - so don't overwrite it ++ * with the unprocessed records yet (we'll do it when we've ++ * finished reading the current packet). ++ */ ++ return 1; ++ } ++ ++ + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); +- if (!dtls1_process_record(s)) +- return (0); ++ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); ++ if (bitmap == NULL) { ++ /* ++ * Should not happen. This will only ever be NULL when the ++ * current record is from a different epoch. But that cannot ++ * be the case because we already checked the epoch above ++ */ ++ SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++#ifndef OPENSSL_NO_SCTP ++ /* Only do replay check if no SCTP bio */ ++ if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) ++#endif ++ { ++ /* ++ * Check whether this is a repeat, or aged record. We did this ++ * check once already when we first received the record - but ++ * we might have updated the window since then due to ++ * records we subsequently processed. ++ */ ++ replayok = dtls1_record_replay_check(s, bitmap); ++ } ++ ++ if (!replayok || !dtls1_process_record(s, bitmap)) { ++ /* dump this record */ ++ rr->length = 0; ++ s->packet_length = 0; ++ continue; ++ } ++ + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num) < 0) +- return -1; ++ return 0; + } + } + +@@ -344,7 +393,7 @@ static int dtls1_process_buffered_records(SSL *s) + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + +- return (1); ++ return 1; + } + + #if 0 +@@ -391,7 +440,7 @@ static int dtls1_get_buffered_record(SSL *s) + + #endif + +-static int dtls1_process_record(SSL *s) ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) + { + int i, al; + int enc_err; +@@ -551,6 +600,10 @@ static int dtls1_get_buffered_record(SSL *s) + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; ++ ++ /* Mark receipt of record. */ ++ dtls1_record_bitmap_update(s, bitmap); ++ + return (1); + + f_err: +@@ -581,11 +634,12 @@ int dtls1_get_record(SSL *s) + + rr = &(s->s3->rrec); + ++ again: + /* + * The epoch may have changed. If so, process all the pending records. + * This is a non-blocking operation. + */ +- if (dtls1_process_buffered_records(s) < 0) ++ if (!dtls1_process_buffered_records(s)) + return -1; + + /* if we're renegotiating, then there may be buffered records */ +@@ -593,7 +647,6 @@ int dtls1_get_record(SSL *s) + return 1; + + /* get something from the wire */ +- again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { +@@ -717,8 +770,6 @@ int dtls1_get_record(SSL *s) + if (dtls1_buffer_record + (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) + return -1; +- /* Mark receipt of record. */ +- dtls1_record_bitmap_update(s, bitmap); + } + rr->length = 0; + s->packet_length = 0; +@@ -725,12 +776,11 @@ int dtls1_get_record(SSL *s) + goto again; + } + +- if (!dtls1_process_record(s)) { ++ if (!dtls1_process_record(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +- dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ + + return (1); + +@@ -1814,8 +1864,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3 + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + +- /* Only HM and ALERT messages can be from the next epoch */ ++ /* ++ * Only HM and ALERT messages can be from the next epoch and only if we ++ * have already processed all of the unprocessed records from the last ++ * epoch ++ */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && ++ s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; +@@ -1894,6 +1949,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) + s->d1->r_epoch++; + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); ++ ++ /* ++ * We must not use any buffered messages received from the previous ++ * epoch ++ */ ++ dtls1_clear_received_buffer(s); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, +Index: crypto/openssl/ssl/d1_srvr.c +=================================================================== +--- crypto/openssl/ssl/d1_srvr.c (revision 306156) ++++ crypto/openssl/ssl/d1_srvr.c (working copy) +@@ -295,7 +295,7 @@ int dtls1_accept(SSL *s) + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + dtls1_start_timer(s); + ret = dtls1_send_hello_request(s); + if (ret <= 0) +@@ -866,6 +866,7 @@ int dtls1_accept(SSL *s) + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +Index: crypto/openssl/ssl/s3_clnt.c +=================================================================== +--- crypto/openssl/ssl/s3_clnt.c (revision 306156) ++++ crypto/openssl/ssl/s3_clnt.c (working copy) +@@ -1143,6 +1143,12 @@ int ssl3_get_server_certificate(SSL *s) + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +@@ -2072,6 +2078,11 @@ int ssl3_get_certificate_request(SSL *s) + } + + for (nc = 0; nc < llen;) { ++ if (nc + 2 > llen) { ++ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); ++ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); ++ goto err; ++ } + n2s(p, l); + if ((l + nc + 2) > llen) { + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) +Index: crypto/openssl/ssl/s3_srvr.c +=================================================================== +--- crypto/openssl/ssl/s3_srvr.c (revision 306156) ++++ crypto/openssl/ssl/s3_srvr.c (working copy) +@@ -1040,7 +1040,7 @@ int ssl3_get_client_hello(SSL *s) + + session_length = *(p + SSL3_RANDOM_SIZE); + +- if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { ++ if (SSL3_RANDOM_SIZE + session_length + 1 >= (d + n) - p) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1058,7 +1058,7 @@ int ssl3_get_client_hello(SSL *s) + /* get the session-id */ + j = *(p++); + +- if (p + j > d + n) { ++ if ((d + n) - p < j) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1114,7 +1114,7 @@ int ssl3_get_client_hello(SSL *s) + + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + /* cookie stuff */ +- if (p + 1 > d + n) { ++ if ((d + n) - p < 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1121,7 +1121,7 @@ int ssl3_get_client_hello(SSL *s) + } + cookie_len = *(p++); + +- if (p + cookie_len > d + n) { ++ if ((d + n ) - p < cookie_len) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1166,7 +1166,7 @@ int ssl3_get_client_hello(SSL *s) + p += cookie_len; + } + +- if (p + 2 > d + n) { ++ if ((d + n ) - p < 2) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -1180,7 +1180,7 @@ int ssl3_get_client_hello(SSL *s) + } + + /* i bytes of cipher data + 1 byte for compression length later */ +- if ((p + i + 1) > (d + n)) { ++ if ((d + n) - p < i + 1) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1246,7 +1246,7 @@ int ssl3_get_client_hello(SSL *s) + + /* compression */ + i = *(p++); +- if ((p + i) > (d + n)) { ++ if ((d + n) - p < i) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -3237,6 +3237,12 @@ int ssl3_get_client_certificate(SSL *s) + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +Index: crypto/openssl/ssl/ssl.h +=================================================================== +--- crypto/openssl/ssl/ssl.h (revision 306156) ++++ crypto/openssl/ssl/ssl.h (working copy) +@@ -2256,6 +2256,7 @@ void ERR_load_SSL_strings(void); + # define SSL_F_DTLS1_HEARTBEAT 305 + # define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 + # define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 ++# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 + # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 + # define SSL_F_DTLS1_PROCESS_RECORD 257 + # define SSL_F_DTLS1_READ_BYTES 258 +Index: crypto/openssl/ssl/ssl_err.c +=================================================================== +--- crypto/openssl/ssl/ssl_err.c (revision 306156) ++++ crypto/openssl/ssl/ssl_err.c (working copy) +@@ -1,6 +1,6 @@ + /* ssl/ssl_err.c */ + /* ==================================================================== +- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -93,6 +93,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { + {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, ++ {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), ++ "DTLS1_PROCESS_BUFFERED_RECORDS"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), + "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, +Index: crypto/openssl/ssl/ssl_locl.h +=================================================================== +--- crypto/openssl/ssl/ssl_locl.h (revision 306156) ++++ crypto/openssl/ssl/ssl_locl.h (working copy) +@@ -1025,7 +1025,8 @@ int dtls1_retransmit_message(SSL *s, unsigned shor + unsigned long frag_off, int *found); + int dtls1_get_queue_priority(unsigned short seq, int is_ccs); + int dtls1_retransmit_buffered_messages(SSL *s); +-void dtls1_clear_record_buffer(SSL *s); ++void dtls1_clear_received_buffer(SSL *s); ++void dtls1_clear_sent_buffer(SSL *s); + void dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); + void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +Index: crypto/openssl/ssl/ssl_sess.c +=================================================================== +--- crypto/openssl/ssl/ssl_sess.c (revision 306156) ++++ crypto/openssl/ssl/ssl_sess.c (working copy) +@@ -602,7 +602,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *se + int r; + #endif + +- if (session_id + len > limit) { ++ if (limit - session_id < len) { + fatal = 1; + goto err; + } +Index: crypto/openssl/ssl/t1_lib.c +=================================================================== +--- crypto/openssl/ssl/t1_lib.c (revision 306156) ++++ crypto/openssl/ssl/t1_lib.c (working copy) +@@ -942,11 +942,11 @@ static void ssl_check_for_safari(SSL *s, const uns + 0x02, 0x03, /* SHA-1/ECDSA */ + }; + +- if (data >= (limit - 2)) ++ if (limit - data <= 2) + return; + data += 2; + +- if (data > (limit - 4)) ++ if (limit - data < 4) + return; + n2s(data, type); + n2s(data, size); +@@ -954,7 +954,7 @@ static void ssl_check_for_safari(SSL *s, const uns + if (type != TLSEXT_TYPE_server_name) + return; + +- if (data + size > limit) ++ if (limit - data < size) + return; + data += size; + +@@ -962,7 +962,7 @@ static void ssl_check_for_safari(SSL *s, const uns + const size_t len1 = sizeof(kSafariExtensionsBlock); + const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); + +- if (data + len1 + len2 != limit) ++ if (limit - data != (int)(len1 + len2)) + return; + if (memcmp(data, kSafariExtensionsBlock, len1) != 0) + return; +@@ -971,7 +971,7 @@ static void ssl_check_for_safari(SSL *s, const uns + } else { + const size_t len = sizeof(kSafariExtensionsBlock); + +- if (data + len != limit) ++ if (limit - data != (int)(len)) + return; + if (memcmp(data, kSafariExtensionsBlock, len) != 0) + return; +@@ -1019,19 +1019,19 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned + if (data == limit) + goto ri_check; + +- if (data > (limit - 2)) ++ if (limit - data < 2) + goto err; + + n2s(data, len); + +- if (data + len != limit) ++ if (limit - data != len) + goto err; + +- while (data <= (limit - 4)) { ++ while (limit - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (limit)) ++ if (limit - data < size) + goto err; + # if 0 + fprintf(stderr, "Received extension type %d size %d\n", type, size); +@@ -1284,6 +1284,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned + 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 + 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; +@@ -1460,20 +1470,20 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); + # endif + +- if (data >= (d + n - 2)) ++ if ((d + n) - data <= 2) + goto ri_check; + + n2s(data, length); +- if (data + length != d + n) { ++ if ((d + n) - data != length) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + +- while (data <= (d + n - 4)) { ++ while ((d + n) - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) ++ if ((d + n) - data < size) + goto ri_check; + + if (s->tlsext_debug_cb) +@@ -2179,29 +2189,33 @@ int tls1_process_ticket(SSL *s, unsigned char *ses + /* Skip past DTLS cookie */ + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + i = *(p++); ++ ++ if (limit - p <= i) ++ return -1; ++ + p += i; +- if (p >= limit) +- return -1; + } + /* Skip past cipher list */ + n2s(p, i); ++ if (limit - p <= i) ++ return -1; + p += i; +- if (p >= limit) +- return -1; ++ + /* Skip past compression algorithm list */ + i = *(p++); ++ if (limit - p < i) ++ return -1; + p += i; +- if (p > limit) +- return -1; ++ + /* Now at start of extensions */ +- if ((p + 2) >= limit) ++ if (limit - p <= 2) + return 0; + n2s(p, i); +- while ((p + 4) <= limit) { ++ while (limit - p >= 4) { + unsigned short type, size; + n2s(p, type); + n2s(p, size); +- if (p + size > limit) ++ if (limit - p < size) + return 0; + if (type == TLSEXT_TYPE_session_ticket) { + int r; +@@ -2269,9 +2283,7 @@ static int tls_decrypt_ticket(SSL *s, const unsign + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; +- /* Need at least keyname + iv + some encrypted data */ +- if (eticklen < 48) +- return 2; ++ + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); +@@ -2305,6 +2317,13 @@ static int tls_decrypt_ticket(SSL *s, const unsign + if (mlen < 0) { + goto err; + } ++ /* Sanity check ticket length: must exceed keyname + IV + HMAC */ ++ if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { ++ HMAC_CTX_cleanup(&hctx); ++ EVP_CIPHER_CTX_cleanup(&ctx); ++ return 2; ++ } ++ + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + if (HMAC_Update(&hctx, etick, eticklen) <= 0 Index: user/cperciva/freebsd-update-build/patches/9.3-RELEASE/46-SA-16:26.openssl =================================================================== --- user/cperciva/freebsd-update-build/patches/9.3-RELEASE/46-SA-16:26.openssl (nonexistent) +++ user/cperciva/freebsd-update-build/patches/9.3-RELEASE/46-SA-16:26.openssl (revision 306270) @@ -0,0 +1,874 @@ +--- crypto/openssl/crypto/bn/bn_print.c.orig ++++ crypto/openssl/crypto/bn/bn_print.c +@@ -111,6 +111,7 @@ + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; ++ int bn_data_num; + + /*- + * get an upper bound for the length of the decimal integer +@@ -120,8 +121,8 @@ + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; +- bn_data = +- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG)); ++ bn_data_num = num / BN_DEC_NUM + 1; ++ bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = (char *)OPENSSL_malloc(num + 3); + if ((buf == NULL) || (bn_data == NULL)) { + BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); +@@ -143,7 +144,11 @@ + i = 0; + while (!BN_is_zero(t)) { + *lp = BN_div_word(t, BN_DEC_CONV); ++ if (*lp == (BN_ULONG)-1) ++ goto err; + lp++; ++ if (lp - bn_data >= bn_data_num) ++ goto err; + } + lp--; + /* +--- crypto/openssl/crypto/dsa/dsa_ossl.c.orig ++++ crypto/openssl/crypto/dsa/dsa_ossl.c +@@ -235,11 +235,13 @@ + do + if (!BN_rand_range(&k, dsa->q)) + goto err; +- while (BN_is_zero(&k)) ; ++ while (BN_is_zero(&k)); ++ + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); + } + ++ + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) +@@ -252,6 +254,8 @@ + if (!BN_copy(&kq, &k)) + goto err; + ++ BN_set_flags(&kq, BN_FLG_CONSTTIME); ++ + /* + * We do not want timing information to leak the length of k, so we + * compute g^k using an equivalent exponent of fixed length. (This +@@ -270,6 +274,7 @@ + } else { + K = &k; + } ++ + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, + dsa->method_mont_p); + if (!BN_mod(r, r, dsa->q, ctx)) +--- crypto/openssl/crypto/mdc2/mdc2dgst.c.orig ++++ crypto/openssl/crypto/mdc2/mdc2dgst.c +@@ -94,7 +94,7 @@ + + i = c->num; + if (i != 0) { +- if (i + len < MDC2_BLOCK) { ++ if (len < MDC2_BLOCK - i) { + /* partial block */ + memcpy(&(c->data[i]), in, len); + c->num += (int)len; +--- crypto/openssl/ssl/d1_both.c.orig ++++ crypto/openssl/ssl/d1_both.c +@@ -543,12 +543,24 @@ + int al; + + *ok = 0; +- item = pqueue_peek(s->d1->buffered_messages); +- if (item == NULL) +- return 0; ++ do { ++ item = pqueue_peek(s->d1->buffered_messages); ++ if (item == NULL) ++ return 0; + +- frag = (hm_fragment *)item->data; ++ frag = (hm_fragment *)item->data; + ++ if (frag->msg_header.seq < s->d1->handshake_read_seq) { ++ /* This is a stale message that has been buffered so clear it */ ++ pqueue_pop(s->d1->buffered_messages); ++ dtls1_hm_fragment_free(frag); ++ pitem_free(item); ++ item = NULL; ++ frag = NULL; ++ } ++ } while (item == NULL); ++ ++ + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; +@@ -1335,18 +1347,6 @@ + return ret; + } + +-/* call this function when the buffered messages are no longer needed */ +-void dtls1_clear_record_buffer(SSL *s) +-{ +- pitem *item; +- +- for (item = pqueue_pop(s->d1->sent_messages); +- item != NULL; item = pqueue_pop(s->d1->sent_messages)) { +- dtls1_hm_fragment_free((hm_fragment *)item->data); +- pitem_free(item); +- } +-} +- + unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, + unsigned long frag_off, +--- crypto/openssl/ssl/d1_clnt.c.orig ++++ crypto/openssl/ssl/d1_clnt.c +@@ -564,6 +564,7 @@ + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +--- crypto/openssl/ssl/d1_lib.c.orig ++++ crypto/openssl/ssl/d1_lib.c +@@ -155,7 +155,6 @@ + static void dtls1_clear_queues(SSL *s) + { + pitem *item = NULL; +- hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { +@@ -176,6 +175,24 @@ + pitem_free(item); + } + ++ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { ++ rdata = (DTLS1_RECORD_DATA *)item->data; ++ if (rdata->rbuf.buf) { ++ OPENSSL_free(rdata->rbuf.buf); ++ } ++ OPENSSL_free(item->data); ++ pitem_free(item); ++ } ++ ++ dtls1_clear_received_buffer(s); ++ dtls1_clear_sent_buffer(s); ++} ++ ++void dtls1_clear_received_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + OPENSSL_free(frag->fragment); +@@ -182,7 +199,13 @@ + OPENSSL_free(frag); + pitem_free(item); + } ++} + ++void dtls1_clear_sent_buffer(SSL *s) ++{ ++ pitem *item = NULL; ++ hm_fragment *frag = NULL; ++ + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + OPENSSL_free(frag->fragment); +@@ -189,17 +212,9 @@ + OPENSSL_free(frag); + pitem_free(item); + } +- +- while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { +- rdata = (DTLS1_RECORD_DATA *)item->data; +- if (rdata->rbuf.buf) { +- OPENSSL_free(rdata->rbuf.buf); +- } +- OPENSSL_free(item->data); +- pitem_free(item); +- } + } + ++ + void dtls1_free(SSL *s) + { + ssl3_free(s); +@@ -431,7 +446,7 @@ + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + } + + int dtls1_check_timeout_num(SSL *s) +--- crypto/openssl/ssl/d1_pkt.c.orig ++++ crypto/openssl/ssl/d1_pkt.c +@@ -124,8 +124,7 @@ + + static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek); +-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, +- PQ_64BIT * seq_num); ++static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); + static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); + static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, + unsigned int *is_next_epoch); +@@ -135,7 +134,7 @@ + unsigned long *offset); + #endif + static int dtls1_buffer_record(SSL *s, record_pqueue *q, PQ_64BIT * priority); +-static int dtls1_process_record(SSL *s); ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); + #if PQ_64BIT_IS_INTEGER + static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT * num); + #endif +@@ -248,20 +247,66 @@ + static int dtls1_process_buffered_records(SSL *s) + { + pitem *item; ++ SSL3_BUFFER *rb; ++ SSL3_RECORD *rr; ++ DTLS1_BITMAP *bitmap; ++ unsigned int is_next_epoch; ++ int replayok = 1; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) +- return (1); /* Nothing to do. */ ++ return 1; /* Nothing to do. */ + ++ rr = &s->s3->rrec; ++ rb = &s->s3->rbuf; ++ ++ if (rb->left > 0) { ++ /* ++ * We've still got data from the current packet to read. There could ++ * be a record from the new epoch in it - so don't overwrite it ++ * with the unprocessed records yet (we'll do it when we've ++ * finished reading the current packet). ++ */ ++ return 1; ++ } ++ ++ + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); +- if (!dtls1_process_record(s)) +- return (0); +- dtls1_buffer_record(s, &(s->d1->processed_rcds), +- &s->s3->rrec.seq_num); ++ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); ++ if (bitmap == NULL) { ++ /* ++ * Should not happen. This will only ever be NULL when the ++ * current record is from a different epoch. But that cannot ++ * be the case because we already checked the epoch above ++ */ ++ SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, ++ ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ { ++ /* ++ * Check whether this is a repeat, or aged record. We did this ++ * check once already when we first received the record - but ++ * we might have updated the window since then due to ++ * records we subsequently processed. ++ */ ++ replayok = dtls1_record_replay_check(s, bitmap); ++ } ++ ++ if (!replayok || !dtls1_process_record(s, bitmap)) { ++ /* dump this record */ ++ rr->length = 0; ++ s->packet_length = 0; ++ continue; ++ } ++ ++ if (dtls1_buffer_record(s, &(s->d1->processed_rcds), ++ &s->s3->rrec.seq_num) < 0) ++ return 0; + } + } + +@@ -272,7 +317,7 @@ + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + +- return (1); ++ return 1; + } + + #if 0 +@@ -319,7 +364,7 @@ + + #endif + +-static int dtls1_process_record(SSL *s) ++static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) + { + int i, al; + int enc_err; +@@ -478,8 +523,10 @@ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; +- dtls1_record_bitmap_update(s, &(s->d1->bitmap)); /* Mark receipt of +- * record. */ ++ ++ /* Mark receipt of record. */ ++ dtls1_record_bitmap_update(s, bitmap); ++ + return (1); + + f_err: +@@ -510,6 +557,7 @@ + + rr = &(s->s3->rrec); + ++ again: + /* + * The epoch may have changed. If so, process all the pending records. + * This is a non-blocking operation. +@@ -521,7 +569,6 @@ + return 1; + + /* get something from the wire */ +- again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { +@@ -620,7 +667,7 @@ + if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && + s->packet_length > DTLS1_RT_HEADER_LENGTH && + s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && +- !dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) { ++ !dtls1_record_replay_check(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ +@@ -638,7 +685,9 @@ + */ + if (is_next_epoch) { + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { +- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num); ++ if (dtls1_buffer_record ++ (s, &(s->d1->unprocessed_rcds), &rr->seq_num) < 0) ++ return -1; + } + rr->length = 0; + s->packet_length = 0; +@@ -645,7 +694,7 @@ + goto again; + } + +- if (!dtls1_process_record(s)) { ++ if (!dtls1_process_record(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ +@@ -1514,8 +1563,7 @@ + return -1; + } + +-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, +- PQ_64BIT * seq_num) ++static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) + { + #if PQ_64BIT_IS_INTEGER + PQ_64BIT mask = 0x0000000000000001L; +@@ -1530,7 +1578,7 @@ + + if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || + pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) { +- pq_64bit_assign(seq_num, &rcd_num); ++ pq_64bit_assign(&s->s3->rrec.seq_num, &rcd_num); + pq_64bit_free(&rcd_num); + pq_64bit_free(&tmp); + return 1; /* this record is new */ +@@ -1561,7 +1609,7 @@ + return 0; /* record previously received */ + #endif + +- pq_64bit_assign(seq_num, &rcd_num); ++ pq_64bit_assign(&s->s3->rrec.seq_num, &rcd_num); + pq_64bit_free(&rcd_num); + pq_64bit_free(&tmp); + return 1; +@@ -1687,8 +1735,13 @@ + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + +- /* Only HM and ALERT messages can be from the next epoch */ ++ /* ++ * Only HM and ALERT messages can be from the next epoch and only if we ++ * have already processed all of the unprocessed records from the last ++ * epoch ++ */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && ++ s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; +@@ -1776,6 +1829,12 @@ + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + pq_64bit_init(&(s->d1->next_bitmap.map)); + pq_64bit_init(&(s->d1->next_bitmap.max_seq_num)); ++ ++ /* ++ * We must not use any buffered messages received from the previous ++ * epoch ++ */ ++ dtls1_clear_received_buffer(s); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, +--- crypto/openssl/ssl/d1_srvr.c.orig ++++ crypto/openssl/ssl/d1_srvr.c +@@ -242,7 +242,7 @@ + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; +- dtls1_clear_record_buffer(s); ++ dtls1_clear_sent_buffer(s); + dtls1_start_timer(s); + ret = dtls1_send_hello_request(s); + if (ret <= 0) +@@ -648,6 +648,7 @@ + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; ++ dtls1_clear_received_buffer(s); + goto end; + /* break; */ + +--- crypto/openssl/ssl/s3_clnt.c.orig ++++ crypto/openssl/ssl/s3_clnt.c +@@ -931,6 +931,12 @@ + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +@@ -1627,6 +1633,11 @@ + } + + for (nc = 0; nc < llen;) { ++ if (nc + 2 > llen) { ++ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); ++ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); ++ goto err; ++ } + n2s(p, l); + if ((l + nc + 2) > llen) { + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) +--- crypto/openssl/ssl/s3_srvr.c.orig ++++ crypto/openssl/ssl/s3_srvr.c +@@ -819,7 +819,7 @@ + + session_length = *(p + SSL3_RANDOM_SIZE); + +- if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { ++ if (SSL3_RANDOM_SIZE + session_length + 1 >= (d + n) - p) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -837,7 +837,7 @@ + /* get the session-id */ + j = *(p++); + +- if (p + j > d + n) { ++ if ((d + n) - p < j) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -874,7 +874,7 @@ + + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + /* cookie stuff */ +- if (p + 1 > d + n) { ++ if ((d + n) - p < 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -881,7 +881,7 @@ + } + cookie_len = *(p++); + +- if (p + cookie_len > d + n) { ++ if ((d + n ) - p < cookie_len) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -927,7 +927,7 @@ + p += cookie_len; + } + +- if (p + 2 > d + n) { ++ if ((d + n ) - p < 2) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; +@@ -941,7 +941,7 @@ + } + + /* i bytes of cipher data + 1 byte for compression length later */ +- if ((p + i + 1) > (d + n)) { ++ if ((d + n) - p < i + 1) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1007,7 +1007,7 @@ + + /* compression */ + i = *(p++); +- if ((p + i) > (d + n)) { ++ if ((d + n) - p < i) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); +@@ -1029,7 +1029,7 @@ + #ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (s->version >= SSL3_VERSION) { +- if (!ssl_parse_clienthello_tlsext(s, &p, d, n, &al)) { ++ if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) { + /* 'al' set by ssl_parse_clienthello_tlsext */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; +@@ -2526,6 +2526,12 @@ + goto f_err; + } + for (nc = 0; nc < llen;) { ++ if (nc + 3 > llen) { ++ al = SSL_AD_DECODE_ERROR; ++ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ++ SSL_R_CERT_LENGTH_MISMATCH); ++ goto f_err; ++ } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; +--- crypto/openssl/ssl/ssl.h.orig ++++ crypto/openssl/ssl/ssl.h +@@ -1803,6 +1803,7 @@ + # define SSL_F_DTLS1_HANDLE_TIMEOUT 282 + # define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 + # define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277 ++# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 + # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 + # define SSL_F_DTLS1_PROCESS_RECORD 257 + # define SSL_F_DTLS1_READ_BYTES 258 +--- crypto/openssl/ssl/ssl_err.c.orig ++++ crypto/openssl/ssl/ssl_err.c +@@ -1,6 +1,6 @@ + /* ssl/ssl_err.c */ + /* ==================================================================== +- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -92,6 +92,8 @@ + {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, ++ {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), ++ "DTLS1_PROCESS_BUFFERED_RECORDS"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), + "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, +--- crypto/openssl/ssl/ssl_locl.h.orig ++++ crypto/openssl/ssl/ssl_locl.h +@@ -910,7 +910,8 @@ + unsigned long frag_off, int *found); + int dtls1_get_queue_priority(unsigned short seq, int is_ccs); + int dtls1_retransmit_buffered_messages(SSL *s); +-void dtls1_clear_record_buffer(SSL *s); ++void dtls1_clear_received_buffer(SSL *s); ++void dtls1_clear_sent_buffer(SSL *s); + void dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); + void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +@@ -1022,7 +1023,7 @@ + unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, + unsigned char *limit); + int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, +- unsigned char *d, int n, int *al); ++ unsigned char *limit, int *al); + int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n, int *al); + int ssl_prepare_clienthello_tlsext(SSL *s); +--- crypto/openssl/ssl/ssl_sess.c.orig ++++ crypto/openssl/ssl/ssl_sess.c +@@ -384,7 +384,7 @@ + if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) + goto err; + +- if (session_id + len > limit) { ++ if (limit - session_id < len) { + fatal = 1; + goto err; + } +--- crypto/openssl/ssl/t1_lib.c.orig ++++ crypto/openssl/ssl/t1_lib.c +@@ -357,7 +357,7 @@ + * 10.8..10.8.3 (which don't work). + */ + static void ssl_check_for_safari(SSL *s, const unsigned char *data, +- const unsigned char *d, int n) ++ const unsigned char *limit) + { + unsigned short type, size; + static const unsigned char kSafariExtensionsBlock[] = { +@@ -386,11 +386,11 @@ + 0x02, 0x03, /* SHA-1/ECDSA */ + }; + +- if (data >= (d + n - 2)) ++ if (limit - data <= 2) + return; + data += 2; + +- if (data > (d + n - 4)) ++ if (limit - data < 4) + return; + n2s(data, type); + n2s(data, size); +@@ -398,7 +398,7 @@ + if (type != TLSEXT_TYPE_server_name) + return; + +- if (data + size > d + n) ++ if (limit - data < size) + return; + data += size; + +@@ -406,7 +406,7 @@ + const size_t len1 = sizeof(kSafariExtensionsBlock); + const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); + +- if (data + len1 + len2 != d + n) ++ if (limit - data != (int)(len1 + len2)) + return; + if (memcmp(data, kSafariExtensionsBlock, len1) != 0) + return; +@@ -415,7 +415,7 @@ + } else { + const size_t len = sizeof(kSafariExtensionsBlock); + +- if (data + len != d + n) ++ if (limit - data != (int)(len)) + return; + if (memcmp(data, kSafariExtensionsBlock, len) != 0) + return; +@@ -425,8 +425,8 @@ + } + # endif /* !OPENSSL_NO_EC */ + +-int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, +- int n, int *al) ++int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, ++ unsigned char *limit, int *al) + { + unsigned short type; + unsigned short size; +@@ -439,24 +439,26 @@ + + # ifndef OPENSSL_NO_EC + if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) +- ssl_check_for_safari(s, data, d, n); ++ ssl_check_for_safari(s, data, limit); + # endif /* !OPENSSL_NO_EC */ + +- if (data >= (d + n - 2)) ++ if (data == limit) + goto ri_check; + ++ if (limit - data < 2) ++ goto err; ++ + n2s(data, len); + +- if (data > (d + n - len)) +- goto ri_check; ++ if (limit - data != len) ++ goto err; + +- while (data <= (d + n - 4)) { ++ while (limit - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) +- goto ri_check; +- ++ if (limit - data < size) ++ goto err; + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); + /*- +@@ -580,6 +582,23 @@ + *al = SSL_AD_DECODE_ERROR; + return 0; + } ++ ++ /* ++ * 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; +@@ -606,13 +625,6 @@ + *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); + *al = SSL_AD_INTERNAL_ERROR; +@@ -672,6 +684,10 @@ + } + + return 1; ++ ++err: ++ *al = SSL_AD_DECODE_ERROR; ++ return 0; + } + + int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, +@@ -684,20 +700,20 @@ + int tlsext_servername = 0; + int renegotiate_seen = 0; + +- if (data >= (d + n - 2)) ++ if ((d + n) - data <= 2) + goto ri_check; + + n2s(data, length); +- if (data + length != d + n) { ++ if ((d + n) - data != length) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + +- while (data <= (d + n - 4)) { ++ while ((d + n) - data >= 4) { + n2s(data, type); + n2s(data, size); + +- if (data + size > (d + n)) ++ if ((d + n) - data < size) + goto ri_check; + + if (s->tlsext_debug_cb) +@@ -960,29 +976,33 @@ + /* Skip past DTLS cookie */ + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + i = *(p++); ++ ++ if (limit - p <= i) ++ return -1; ++ + p += i; +- if (p >= limit) +- return -1; + } + /* Skip past cipher list */ + n2s(p, i); ++ if (limit - p <= i) ++ return -1; + p += i; +- if (p >= limit) +- return -1; ++ + /* Skip past compression algorithm list */ + i = *(p++); ++ if (limit - p < i) ++ return -1; + p += i; +- if (p > limit) +- return -1; ++ + /* Now at start of extensions */ +- if ((p + 2) >= limit) ++ if (limit - p <= 2) + return 1; + n2s(p, i); +- while ((p + 4) <= limit) { ++ while (limit - p >= 4) { + unsigned short type, size; + n2s(p, type); + n2s(p, size); +- if (p + size > limit) ++ if (limit - p < size) + return 1; + if (type == TLSEXT_TYPE_session_ticket) { + /* +@@ -1012,9 +1032,7 @@ + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; +- /* Need at least keyname + iv + some encrypted data */ +- if (eticklen < 48) +- goto tickerr; ++ + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); +@@ -1042,6 +1060,13 @@ + * checks on ticket. + */ + mlen = HMAC_size(&hctx); ++ /* Sanity check ticket length: must exceed keyname + IV + HMAC */ ++ if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { ++ HMAC_CTX_cleanup(&hctx); ++ EVP_CIPHER_CTX_cleanup(&ctx); ++ return 2; ++ } ++ + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + HMAC_Update(&hctx, etick, eticklen);