summaryrefslogtreecommitdiff
path: root/thirdparty/openssl/ssl/d1_both.c
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2017-05-27 17:50:43 +0200
committerRémi Verschelde <rverschelde@gmail.com>2017-05-27 19:08:07 +0200
commit67305d1b0a6dbcdb032d5a5a0e92122cf8f10b8d (patch)
tree3502be2b2ae57c73fa21bd7b4a20dc02aab3aa06 /thirdparty/openssl/ssl/d1_both.c
parent996f1ae29e8d9bd2719f0dc72bfde6a8d77b1b12 (diff)
openssl: Sync with upstream 1.0.2l
Diffstat (limited to 'thirdparty/openssl/ssl/d1_both.c')
-rw-r--r--thirdparty/openssl/ssl/d1_both.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/thirdparty/openssl/ssl/d1_both.c b/thirdparty/openssl/ssl/d1_both.c
index 5d26c94926..e6bc761e8b 100644
--- a/thirdparty/openssl/ssl/d1_both.c
+++ b/thirdparty/openssl/ssl/d1_both.c
@@ -517,6 +517,17 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
return i;
}
+ /*
+ * Don't change the *message* read sequence number while listening. For
+ * the *record* write sequence we reflect the ClientHello sequence number
+ * when listening.
+ */
+ if (s->d1->listen)
+ memcpy(s->s3->write_sequence, s->s3->read_sequence,
+ sizeof(s->s3->write_sequence));
+ else
+ s->d1->handshake_read_seq++;
+
if (mt >= 0 && s->s3->tmp.message_type != mt) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
@@ -544,10 +555,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
- /* Don't change sequence numbers while listening */
- if (!s->d1->listen)
- s->d1->handshake_read_seq++;
-
s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
return s->init_num;
@@ -581,9 +588,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;
}
@@ -618,11 +628,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)
@@ -1053,7 +1075,9 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
int dtls1_read_failed(SSL *s, int code)
{
if (code > 0) {
+#ifdef TLS_DEBUG
fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
+#endif
return 1;
}
@@ -1125,7 +1149,9 @@ int dtls1_retransmit_buffered_messages(SSL *s)
(frag->msg_header.seq,
frag->msg_header.is_ccs), 0,
&found) <= 0 && found) {
+#ifdef TLS_DEBUG
fprintf(stderr, "dtls1_retransmit_message() failed\n");
+#endif
return -1;
}
}
@@ -1211,7 +1237,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
unsigned long header_length;
unsigned char seq64be[8];
struct dtls1_retransmit_state saved_state;
- unsigned char save_write_sequence[8];
+ unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0};
/*-
OPENSSL_assert(s->init_num == 0);
@@ -1225,7 +1251,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
item = pqueue_find(s->d1->sent_messages, seq64be);
if (item == NULL) {
+#ifdef TLS_DEBUG
fprintf(stderr, "retransmit: message %d non-existant\n", seq);
+#endif
*found = 0;
return 0;
}
@@ -1296,18 +1324,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,
@@ -1469,7 +1485,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;
}
@@ -1546,6 +1562,8 @@ int dtls1_heartbeat(SSL *s)
* - Padding
*/
buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ if (buf == NULL)
+ goto err;
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
@@ -1554,11 +1572,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);