diff options
author | Matt Caswell <matt@openssl.org> | 2017-02-24 11:40:49 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2017-03-02 17:44:15 +0000 |
commit | a832b5ef7a6080a6a66d1135c80c9aaf5570fc02 (patch) | |
tree | 977d529d181f2f3278b453ff20b72ad48efac854 /ssl/record | |
parent | 38df5a452777b612f75796531c0b2629da6aa550 (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.c | 15 | ||||
-rw-r--r-- | ssl/record/record_locl.h | 1 | ||||
-rw-r--r-- | ssl/record/ssl3_record.c | 8 |
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; |