__owur int SSL_connect(SSL *ssl);
__owur int SSL_read(SSL *ssl, void *buf, int num);
__owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
+
+# define SSL_READ_EARLY_ERROR 0
+# define SSL_READ_EARLY_SUCCESS 1
+# define SSL_READ_EARLY_FINISH 2
+
+__owur int SSL_read_early(SSL *s, void *buf, size_t num, size_t *readbytes);
__owur int SSL_peek(SSL *ssl, void *buf, int num);
__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes);
__owur int SSL_write(SSL *ssl, const void *buf, int num);
# define SSL_F_SSL_PEEK_EX 432
# define SSL_F_SSL_PEEK_INTERNAL 522
# define SSL_F_SSL_READ 223
+# define SSL_F_SSL_READ_EARLY 529
# define SSL_F_SSL_READ_EX 434
# define SSL_F_SSL_READ_INTERNAL 523
# define SSL_F_SSL_RENEGOTIATE 516
# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 489
# define SSL_F_TLS_CONSTRUCT_CTOS_ALPN 466
# define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE 355
-# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 521
+# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 530
# define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS 467
# define SSL_F_TLS_CONSTRUCT_CTOS_EMS 468
# define SSL_F_TLS_CONSTRUCT_CTOS_ETM 469
# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239
# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242
# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243
+# define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178
# define SSL_R_UNEXPECTED_MESSAGE 244
# define SSL_R_UNEXPECTED_RECORD 245
# define SSL_R_UNINITIALIZED 276
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION);
goto f_err;
+ } else if (alert_descr == SSL_AD_END_OF_EARLY_DATA) {
+ if (!ssl_end_of_early_data_seen(s)) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES,
+ SSL_R_UNEXPECTED_END_OF_EARLY_DATA);
+ goto f_err;
+ }
+ return 0;
}
} else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
/*-
* enc_err is:
- * 0: (in non-constant time) if the record is publically invalid.
+ * 0: (in non-constant time) if the record is publicly invalid.
* 1: if the padding is valid
* -1: if the padding is invalid
*/
if (enc_err == 0) {
if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
/*
- * We assume this is unreadable early_data - we treat it like an
- * empty record
+ * Valid early_data that we cannot decrypt might fail here as
+ * publicly invalid. We treat it like an empty record.
*/
thisrr = &rr[0];
thisrr->length = 0;
}
if (enc_err < 0) {
+ if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
+ /*
+ * We assume this is unreadable early_data - we treat it like an
+ * empty record
+ */
+ thisrr = &rr[0];
+ thisrr->length = 0;
+ thisrr->read = 1;
+ RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
+ return 1;
+ }
/*
* A separate 'decryption_failed' alert was introduced with TLS 1.0,
* SSL 3.0 only has 'bad_record_mac'. But unless a decryption
{ERR_FUNC(SSL_F_SSL_PEEK_EX), "SSL_peek_ex"},
{ERR_FUNC(SSL_F_SSL_PEEK_INTERNAL), "ssl_peek_internal"},
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
+ {ERR_FUNC(SSL_F_SSL_READ_EARLY), "SSL_read_early"},
{ERR_FUNC(SSL_F_SSL_READ_EX), "SSL_read_ex"},
{ERR_FUNC(SSL_F_SSL_READ_INTERNAL), "ssl_read_internal"},
{ERR_FUNC(SSL_F_SSL_RENEGOTIATE), "SSL_renegotiate"},
"unable to load ssl3 md5 routines"},
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),
"unable to load ssl3 sha1 routines"},
+ {ERR_REASON(SSL_R_UNEXPECTED_END_OF_EARLY_DATA),
+ "unexpected end of early data"},
{ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"},
{ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"},
{ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"},
return ret;
}
+int SSL_read_early(SSL *s, void *buf, size_t num, size_t *readbytes)
+{
+ int ret;
+
+ if (!s->server) {
+ SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_ERROR;
+ }
+
+ /*
+ * TODO(TLS1.3): Somehow we need to check that we're not receiving too much
+ * data
+ */
+
+ switch (s->early_data_state) {
+ case SSL_EARLY_DATA_NONE:
+ if (!SSL_in_before(s)) {
+ SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_ERROR;
+ }
+ /* fall through */
+
+ case SSL_EARLY_DATA_ACCEPT_RETRY:
+ s->early_data_state = SSL_EARLY_DATA_ACCEPTING;
+ ret = SSL_accept(s);
+ if (ret <= 0) {
+ /* NBIO or error */
+ s->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY;
+ return SSL_READ_EARLY_ERROR;
+ }
+ /* fall through */
+
+ case SSL_EARLY_DATA_READ_RETRY:
+ if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
+ s->early_data_state = SSL_EARLY_DATA_READING;
+ ret = SSL_read_ex(s, buf, num, readbytes);
+ /*
+ * Record layer will call ssl_end_of_early_data_seen() if we see
+ * that alert - which updates the early_data_state to
+ * SSL_EARLY_DATA_FINISHED_READING
+ */
+ if (ret > 0 || (ret <= 0 && s->early_data_state
+ != SSL_EARLY_DATA_FINISHED_READING)) {
+ s->early_data_state = SSL_EARLY_DATA_READ_RETRY;
+ return ret > 0 ? SSL_READ_EARLY_SUCCESS : SSL_READ_EARLY_ERROR;
+ }
+ } else {
+ s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
+ }
+ *readbytes = 0;
+ ossl_statem_set_in_init(s, 1);
+ return SSL_READ_EARLY_FINISH;
+
+ default:
+ SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_ERROR;
+ }
+}
+
+int ssl_end_of_early_data_seen(SSL *s)
+{
+ if (s->early_data_state == SSL_EARLY_DATA_READING) {
+ s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
+ return 1;
+ }
+
+ return 0;
+}
+
static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
if (s->handshake_func == NULL) {
SSL_EARLY_DATA_CONNECTING,
SSL_EARLY_DATA_WRITE_RETRY,
SSL_EARLY_DATA_WRITING,
- SSL_EARLY_DATA_FINISHED_WRITING
+ SSL_EARLY_DATA_FINISHED_WRITING,
+ SSL_EARLY_DATA_ACCEPT_RETRY,
+ SSL_EARLY_DATA_ACCEPTING,
+ SSL_EARLY_DATA_READ_RETRY,
+ SSL_EARLY_DATA_READING,
+ SSL_EARLY_DATA_FINISHED_READING
} SSL_EARLY_DATA_STATE;
#define MAX_COMPRESSIONS_SIZE 255
# ifndef OPENSSL_UNIT_TEST
+int ssl_end_of_early_data_seen(SSL *s);
__owur int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes);
__owur int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written);
void ssl_clear_cipher_ctx(SSL *s);
}
if ((SSL_IS_FIRST_HANDSHAKE(s)
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING)
+ && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
+ && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING)
|| s->renegotiate) {
if (!tls_setup_handshake(s)) {
ossl_statem_set_error(s);
SSL_COMP *comp;
#endif
- /*
- * This is a real handshake so make sure we clean it up at the end. We set
- * this here so that we are after any early_data
- */
- s->statem.cleanuphand = 1;
-
if (!PACKET_get_net_2(pkt, &sversion)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
int al = SSL_AD_INTERNAL_ERROR;
size_t md_len;
+
+ /* This is a real handshake so make sure we clean it up at the end */
+ s->statem.cleanuphand = 1;
+
/* If this occurs, we have missed a message */
if (!SSL_IS_TLS13(s) && !s->s3->change_cipher_spec) {
al = SSL_AD_UNEXPECTED_MESSAGE;
s->d1->next_handshake_write_seq = 0;
dtls1_clear_received_buffer(s);
}
+ s->early_data_state = SSL_EARLY_DATA_NONE;
}
/*
return WRITE_TRAN_ERROR;
case TLS_ST_OK:
+ if (s->early_data_state == SSL_EARLY_DATA_FINISHED_READING) {
+ st->hand_state = TLS_ST_SW_FINISHED;
+ return WRITE_TRAN_FINISHED;
+ }
if (s->key_update != SSL_KEY_UPDATE_NONE) {
st->hand_state = TLS_ST_SW_KEY_UPDATE;
return WRITE_TRAN_CONTINUE;
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_FINISHED:
+ if (s->early_data_state == SSL_EARLY_DATA_ACCEPTING) {
+ st->hand_state = TLS_ST_OK;
+ ossl_statem_set_in_init(s, 0);
+ return WRITE_TRAN_CONTINUE;
+ }
return WRITE_TRAN_FINISHED;
case TLS_ST_SR_FINISHED:
s->new_session = 1;
}
- /* This is a real handshake so make sure we clean it up at the end */
- s->statem.cleanuphand = 1;
-
/*
* First, parse the raw ClientHello data into the CLIENTHELLO_MSG structure.
*/
SSL_CTX_get_max_early_data 431 1_1_1 EXIST::FUNCTION:
SSL_write_early 432 1_1_1 EXIST::FUNCTION:
SSL_write_early_finish 433 1_1_1 EXIST::FUNCTION:
+SSL_read_early 434 1_1_1 EXIST::FUNCTION: