diff options
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/d1_both.c | 43 | ||||
-rw-r--r-- | ssl/d1_clnt.c | 1 | ||||
-rw-r--r-- | ssl/d1_lib.c | 37 | ||||
-rw-r--r-- | ssl/d1_pkt.c | 92 | ||||
-rw-r--r-- | ssl/d1_srvr.c | 8 | ||||
-rw-r--r-- | ssl/s23_clnt.c | 8 | ||||
-rw-r--r-- | ssl/s2_clnt.c | 4 | ||||
-rw-r--r-- | ssl/s2_srvr.c | 12 | ||||
-rw-r--r-- | ssl/s3_both.c | 38 | ||||
-rw-r--r-- | ssl/s3_clnt.c | 30 | ||||
-rw-r--r-- | ssl/s3_lib.c | 34 | ||||
-rw-r--r-- | ssl/s3_srvr.c | 27 | ||||
-rw-r--r-- | ssl/ssl.h | 1 | ||||
-rw-r--r-- | ssl/ssl_err.c | 4 | ||||
-rw-r--r-- | ssl/ssl_lib.c | 4 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 3 | ||||
-rw-r--r-- | ssl/ssl_sess.c | 4 | ||||
-rw-r--r-- | ssl/t1_lib.c | 89 |
18 files changed, 273 insertions, 166 deletions
diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 19c3da616122..0cf1e49fd2a1 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -577,9 +577,12 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, /* * msg_len is limited to 2^24, but is effectively checked against max * above + * + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 */ if (!BUF_MEM_grow_clean - (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { + (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) { SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); return SSL_AD_INTERNAL_ERROR; } @@ -614,11 +617,23 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) 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; + + 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); - frag = (hm_fragment *)item->data; /* Don't return if reassembly still in progress */ if (frag->reassembly != NULL) @@ -1416,18 +1431,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, 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, @@ -1589,7 +1592,7 @@ int dtls1_process_heartbeat(SSL *s) memcpy(bp, pl, payload); bp += payload; /* Random padding */ - if (RAND_pseudo_bytes(bp, padding) < 0) { + if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } @@ -1674,11 +1677,11 @@ int dtls1_heartbeat(SSL *s) /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ - if (RAND_pseudo_bytes(p, 16) < 0) + if (RAND_bytes(p, 16) <= 0) goto err; p += 16; /* Random padding */ - if (RAND_pseudo_bytes(p, padding) < 0) + if (RAND_bytes(p, padding) <= 0) goto err; ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index eb371a255f89..e1f167bbd3c8 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -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; */ diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 011d7b7cbe69..99984dfe0f18 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -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) diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index d659ed428e6d..086ee98494dc 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -194,7 +194,7 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, #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, record_pqueue *queue) 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_process_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,20 +770,17 @@ 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; 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); @@ -1627,7 +1677,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* ssl3_enc can only have an error on read */ if (bs) { /* bs != 0 in case of CBC */ - RAND_pseudo_bytes(p, bs); + if (RAND_bytes(p, bs) <= 0) + goto err; /* * master IV and last CBC residue stand for the rest of randomness */ @@ -1814,8 +1865,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, 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 +1950,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, diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index f01b8a693f4e..bc30433afa2d 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -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; */ @@ -1701,7 +1702,10 @@ int dtls1_send_newsession_ticket(SSL *s) return -1; } } else { - RAND_pseudo_bytes(iv, 16); + if (RAND_bytes(iv, 16) <= 0) { + OPENSSL_free(senc); + return -1; + } EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, iv); HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c index 2b2855dee4a9..e93baed43a22 100644 --- a/ssl/s23_clnt.c +++ b/ssl/s23_clnt.c @@ -290,9 +290,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) unsigned long Time = (unsigned long)time(NULL); unsigned char *p = result; l2n(Time, p); - return RAND_pseudo_bytes(p, len - 4); + return RAND_bytes(p, len - 4); } else - return RAND_pseudo_bytes(result, len); + return RAND_bytes(result, len); } static int ssl23_client_hello(SSL *s) @@ -460,8 +460,8 @@ static int ssl23_client_hello(SSL *s) i = ch_len; s2n(i, d); memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); - if (RAND_pseudo_bytes - (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0) + if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) + <= 0) return -1; memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c index b23b083153fb..736ba1f3ffac 100644 --- a/ssl/s2_clnt.c +++ b/ssl/s2_clnt.c @@ -581,7 +581,7 @@ static int client_hello(SSL *s) /* * challenge id data */ - if (RAND_pseudo_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) + if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) return -1; memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); d += SSL2_CHALLENGE_LENGTH; @@ -629,7 +629,7 @@ static int client_master_key(SSL *s) return -1; } if (i > 0) - if (RAND_pseudo_bytes(sess->key_arg, i) <= 0) + if (RAND_bytes(sess->key_arg, i) <= 0) return -1; /* make a master key */ diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c index 07e9df82820a..d3b243c27e02 100644 --- a/ssl/s2_srvr.c +++ b/ssl/s2_srvr.c @@ -526,11 +526,8 @@ static int get_client_master_key(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - (int)num_encrypted_key_bytes) <= 0) + if (RAND_bytes(rand_premaster_secret, + (int)num_encrypted_key_bytes) <= 0) return 0; i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, @@ -822,8 +819,7 @@ static int server_hello(SSL *s) /* make and send conn_id */ s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; - if (RAND_pseudo_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= - 0) + if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0) return -1; memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); d += SSL2_CONNECTION_ID_LENGTH; @@ -962,7 +958,7 @@ static int request_certificate(SSL *s) p = (unsigned char *)s->init_buf->data; *(p++) = SSL2_MT_REQUEST_CERTIFICATE; *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; - if (RAND_pseudo_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) + if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) return -1; memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 107b460f27b6..d798d83cb77b 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -427,21 +427,22 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) } *ok = 1; s->state = stn; - s->init_msg = s->init_buf->data + 4; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = (int)s->s3->tmp.message_size; return s->init_num; } p = (unsigned char *)s->init_buf->data; - if (s->state == st1) { /* s->init_num < 4 */ + if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ int skip_message; do { - while (s->init_num < 4) { + while (s->init_num < SSL3_HM_HEADER_LENGTH) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], - 4 - s->init_num, 0); + SSL3_HM_HEADER_LENGTH - + s->init_num, 0); if (i <= 0) { s->rwstate = SSL_READING; *ok = 0; @@ -465,12 +466,13 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, 4, s, s->msg_callback_arg); + p, SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); } } while (skip_message); - /* s->init_num == 4 */ + /* s->init_num == SSL3_HM_HEADER_LENGTH */ if ((mt >= 0) && (*p != mt)) { al = SSL_AD_UNEXPECTED_MESSAGE; @@ -497,19 +499,20 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) { + /* + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 + */ + if (l + && !BUF_MEM_grow_clean(s->init_buf, + (int)l + SSL3_HM_HEADER_LENGTH + 16)) { SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); goto err; } s->s3->tmp.message_size = l; s->state = stn; - s->init_msg = s->init_buf->data + 4; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = 0; } @@ -538,10 +541,12 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) #endif /* Feed this message into MAC computation. */ - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); + ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH); if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + 4, s, s->msg_callback_arg); + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); *ok = 1; return s->init_num; f_err: @@ -619,7 +624,10 @@ int ssl_verify_alarm_type(long type) case X509_V_ERR_CERT_REVOKED: al = SSL_AD_CERTIFICATE_REVOKED; break; + case X509_V_ERR_UNSPECIFIED: case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: al = SSL_AD_INTERNAL_ERROR; break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 9e5875f1f9ba..f033a2bbf0d8 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -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)) @@ -2868,19 +2879,6 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } /* - * If we have client certificate, use its secret as peer key - */ - if (s->s3->tmp.cert_req && s->cert->key->privatekey) { - if (EVP_PKEY_derive_set_peer - (pkey_ctx, s->cert->key->privatekey) <= 0) { - /* - * If there was an error - just ignore it. Ephemeral key - * * would be used - */ - ERR_clear_error(); - } - } - /* * Compute shared IV and store it in algorithm-specific context * data */ @@ -2926,12 +2924,6 @@ int ssl3_send_client_key_exchange(SSL *s) n = msglen + 2; } memcpy(p, tmp, msglen); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) { - /* Set flag "skip certificate verify" */ - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } EVP_PKEY_CTX_free(pkey_ctx); s->session->master_key_length = s->method->ssl3_enc->generate_master_secret(s, diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 35d6587da951..6b1822d8f681 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -334,7 +334,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -387,7 +387,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -439,7 +439,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -492,7 +492,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -544,7 +544,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -630,7 +630,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -717,7 +717,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -783,7 +783,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_MD5, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -1733,7 +1733,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2110,7 +2110,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2190,7 +2190,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2270,7 +2270,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2350,7 +2350,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2430,7 +2430,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2480,7 +2480,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2496,7 +2496,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2512,7 +2512,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 04cf93a0f7c6..4f1a2e9aba80 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -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,14 +1114,14 @@ 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; } 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); @@ -2279,11 +2279,8 @@ int ssl3_get_client_key_exchange(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) + if (RAND_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) goto err; decrypt_len = RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); @@ -3237,6 +3234,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; diff --git a/ssl/ssl.h b/ssl/ssl.h index d6c475c27c08..114ee97c763b 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -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 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index caa671a27078..ed679d117b63 100644 --- a/ssl/ssl_err.c +++ b/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 @@ -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"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 33c52ac5bf03..83ef233b5072 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1662,7 +1662,7 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *p, size_t plen, int use_context) { - if (s->version < TLS1_VERSION) + if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) return -1; return s->method->ssl3_enc->export_keying_material(s, out, olen, label, @@ -1833,7 +1833,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->tlsext_servername_callback = 0; ret->tlsext_servername_arg = NULL; /* Setup RFC4507 ticket keys */ - if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) ret->options |= SSL_OP_NO_TICKET; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index d57b902fabbf..7b1fd1f3b199 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1026,7 +1026,8 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq, 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); diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 48fc4511f1fe..093b534bf98a 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -382,7 +382,7 @@ static int def_generate_session_id(const SSL *ssl, unsigned char *id, { unsigned int retry = 0; do - if (RAND_pseudo_bytes(id, *id_len) <= 0) + if (RAND_bytes(id, *id_len) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; @@ -602,7 +602,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, int r; #endif - if (session_id + len > limit) { + if (limit - session_id < len) { fatal = 1; goto err; } diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 0bdb77d49fc3..4bc13ca5ce29 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -942,11 +942,11 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, 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 unsigned char *data, 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 unsigned char *data, 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 unsigned char *data, } 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 char **p, 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 char **p, 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 char **p, 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 char **p, unsigned char *d, 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 *session_id, int len, /* Skip past DTLS cookie */ if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { i = *(p++); - p += i; - if (p >= limit) + + if (limit - p <= i) return -1; + + p += i; } /* Skip past cipher list */ n2s(p, i); - p += i; - if (p >= limit) + if (limit - p <= i) return -1; + p += i; + /* Skip past compression algorithm list */ i = *(p++); - p += i; - if (p > limit) + if (limit - p < i) return -1; + p += i; + /* 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 unsigned char *etick, 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 unsigned char *etick, 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 @@ -2591,7 +2610,7 @@ int tls1_process_heartbeat(SSL *s) memcpy(bp, pl, payload); bp += payload; /* Random padding */ - if (RAND_pseudo_bytes(bp, padding) < 0) { + if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } @@ -2677,13 +2696,13 @@ int tls1_heartbeat(SSL *s) /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ - if (RAND_pseudo_bytes(p, 16) < 0) { + if (RAND_bytes(p, 16) <= 0) { SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } p += 16; /* Random padding */ - if (RAND_pseudo_bytes(p, padding) < 0) { + if (RAND_bytes(p, padding) <= 0) { SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } |