summaryrefslogtreecommitdiffstats
path: root/ssl/record
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2017-02-24 11:40:49 +0000
committerMatt Caswell <matt@openssl.org>2017-03-02 17:44:15 +0000
commita832b5ef7a6080a6a66d1135c80c9aaf5570fc02 (patch)
tree977d529d181f2f3278b453ff20b72ad48efac854 /ssl/record
parent38df5a452777b612f75796531c0b2629da6aa550 (diff)
Skip early_data if appropriate after a HelloRetryRequest
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2737)
Diffstat (limited to 'ssl/record')
-rw-r--r--ssl/record/rec_layer_s3.c15
-rw-r--r--ssl/record/record_locl.h1
-rw-r--r--ssl/record/ssl3_record.c8
3 files changed, 20 insertions, 4 deletions
diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c
index 6fa272c77a..1dc2956478 100644
--- a/ssl/record/rec_layer_s3.c
+++ b/ssl/record/rec_layer_s3.c
@@ -1565,6 +1565,21 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
if (ossl_statem_app_data_allowed(s)) {
s->s3->in_read_app_data = 2;
return -1;
+ } else if (ossl_statem_skip_early_data(s)) {
+ /*
+ * This can happen after a client sends a CH followed by early_data,
+ * but the server responds with a HelloRetryRequest. The server
+ * reads the next record from the client expecting to find a
+ * plaintext ClientHello but gets a record which appears to be
+ * application data. The trial decrypt "works" because null
+ * decryption was applied. We just skip it and move on to the next
+ * record.
+ */
+ if (!early_data_count_ok(s, rr->length,
+ EARLY_DATA_CIPHERTEXT_OVERHEAD, &al))
+ goto f_err;
+ SSL3_RECORD_set_read(rr);
+ goto start;
} else {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
diff --git a/ssl/record/record_locl.h b/ssl/record/record_locl.h
index 6394835404..e249918ef4 100644
--- a/ssl/record/record_locl.h
+++ b/ssl/record/record_locl.h
@@ -115,3 +115,4 @@ __owur int tls1_cbc_remove_padding(const SSL *s,
size_t block_size, size_t mac_size);
int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
__owur int dtls1_get_record(SSL *s);
+int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al);
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index aebead2395..50582d1a73 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -101,16 +101,16 @@ static int ssl3_record_app_data_waiting(SSL *s)
return 1;
}
-static int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al)
+int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al)
{
uint32_t max_early_data = s->max_early_data;
/*
* We go with the lowest out of the max early data set in the session
- * and the configured max_early_data
+ * and the configured max_early_data.
*/
- if (s->session->ext.max_early_data < s->max_early_data)
- max_early_data = s->max_early_data;
+ if (s->hit && s->session->ext.max_early_data < s->max_early_data)
+ max_early_data = s->session->ext.max_early_data;
if (max_early_data == 0) {
*al = SSL_AD_UNEXPECTED_MESSAGE;