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);
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);
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;
if (s->ext.early_data != SSL_EARLY_DATA_REJECTED)
return 0;
- if (s->statem.hand_state != TLS_ST_SW_FINISHED)
- return 0;
+ if (s->hello_retry_request) {
+ if (s->statem.hand_state != TLS_ST_SW_HELLO_RETRY_REQUEST)
+ return 0;
+ } else {
+ if (s->statem.hand_state != TLS_ST_SW_FINISHED)
+ return 0;
+ }
return 1;
}