# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR
# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
+# define SSL_AD_END_OF_EARLY_DATA TLS13_AD_END_OF_EARLY_DATA
# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION
# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
__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);
__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written);
+__owur int SSL_write_early(SSL *s, const void *buf, size_t num,
+ size_t *written);
+__owur int SSL_write_early_finish(SSL *s);
long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
long SSL_callback_ctrl(SSL *, int, void (*)(void));
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
# define SSL_F_SSL_VALIDATE_CT 400
# define SSL_F_SSL_VERIFY_CERT_CHAIN 207
# define SSL_F_SSL_WRITE 208
+# define SSL_F_SSL_WRITE_EARLY 526
+# define SSL_F_SSL_WRITE_EARLY_FINISH 527
# define SSL_F_SSL_WRITE_EX 433
# define SSL_F_SSL_WRITE_INTERNAL 524
# define SSL_F_STATE_MACHINE 353
# define SSL_F_TLS_PARSE_CTOS_PSK 505
# define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 464
# define SSL_F_TLS_PARSE_CTOS_USE_SRTP 465
-# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 520
+# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 528
# define SSL_F_TLS_PARSE_STOC_KEY_SHARE 445
# define SSL_F_TLS_PARSE_STOC_PSK 502
# define SSL_F_TLS_PARSE_STOC_RENEGOTIATE 448
# define TLS1_AD_USER_CANCELLED 90
# define TLS1_AD_NO_RENEGOTIATION 100
/* TLSv1.3 alerts */
+# define TLS13_AD_END_OF_EARLY_DATA 1
# define TLS13_AD_MISSING_EXTENSION 109 /* fatal */
/* codes 110-114 are from RFC3546 */
# define TLS1_AD_UNSUPPORTED_EXTENSION 110
}
/* Explicit IV length, block ciphers appropriate version flag */
- if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
+ if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) {
int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
if (mode == EVP_CIPH_CBC_MODE) {
/* TODO(size_t): Convert me */
/* Clear our SSL3_RECORD structures */
memset(wr, 0, sizeof wr);
for (j = 0; j < numpipes; j++) {
- unsigned int version = SSL_IS_TLS13(s) ? TLS1_VERSION : s->version;
+ unsigned int version = SSL_TREAT_AS_TLS13(s) ? TLS1_VERSION : s->version;
unsigned char *compressdata = NULL;
size_t maxcomplen;
unsigned int rectype;
* In TLSv1.3, once encrypting, we always use application data for the
* record type
*/
- if (SSL_IS_TLS13(s) && s->enc_write_ctx != NULL)
+ if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL)
rectype = SSL3_RT_APPLICATION_DATA;
else
rectype = type;
SSL3_RECORD_reset_input(&wr[j]);
}
- if (SSL_IS_TLS13(s) && s->enc_write_ctx != NULL) {
+ if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) {
if (!WPACKET_put_bytes_u8(thispkt, type)) {
SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
goto err;
SSL3_RECORD_set_length(thiswr, len);
}
- if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
- goto err;
+ if (s->early_data_state == SSL_EARLY_DATA_WRITING) {
+ /*
+ * We haven't actually negotiated the version yet, but we're trying to
+ * send early data - so we need to use the the tls13enc function.
+ */
+ if (tls13_enc(s, wr, numpipes, 1) < 1)
+ goto err;
+ } else {
+ if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
+ goto err;
+ }
for (j = 0; j < numpipes; j++) {
size_t origlen;
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
- /*
- * To get here we must have selected a ciphersuite - otherwise ctx would
- * be NULL
- */
- assert(s->s3->tmp.new_cipher != NULL);
- if (s->s3->tmp.new_cipher == NULL)
- return -1;
- alg_enc = s->s3->tmp.new_cipher->algorithm_enc;
+ if (s->early_data_state == SSL_EARLY_DATA_WRITING) {
+ alg_enc = s->session->cipher->algorithm_enc;
+ } else {
+ /*
+ * To get here we must have selected a ciphersuite - otherwise ctx would
+ * be NULL
+ */
+ assert(s->s3->tmp.new_cipher != NULL);
+ if (s->s3->tmp.new_cipher == NULL)
+ return -1;
+ alg_enc = s->s3->tmp.new_cipher->algorithm_enc;
+ }
if (alg_enc & SSL_AESCCM) {
if (alg_enc & (SSL_AES128CCM8 | SSL_AES256CCM8))
int ssl3_send_alert(SSL *s, int level, int desc)
{
/* Map tls/ssl alert value to correct one */
- desc = s->method->ssl3_enc->alert_value(desc);
+ if (SSL_TREAT_AS_TLS13(s))
+ desc = tls13_alert_code(desc);
+ else
+ desc = s->method->ssl3_enc->alert_value(desc);
if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have
* protocol_version alerts */
{ERR_FUNC(SSL_F_SSL_VALIDATE_CT), "ssl_validate_ct"},
{ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"},
{ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"},
+ {ERR_FUNC(SSL_F_SSL_WRITE_EARLY), "SSL_write_early"},
+ {ERR_FUNC(SSL_F_SSL_WRITE_EARLY_FINISH), "SSL_write_early_finish"},
{ERR_FUNC(SSL_F_SSL_WRITE_EX), "SSL_write_ex"},
{ERR_FUNC(SSL_F_SSL_WRITE_INTERNAL), "ssl_write_internal"},
{ERR_FUNC(SSL_F_STATE_MACHINE), "state_machine"},
return -1;
}
+ if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
+ || s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY)
+ return 0;
+
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
int ret;
struct ssl_async_args args;
return ret;
}
+int SSL_write_early(SSL *s, const void *buf, size_t num, size_t *written)
+{
+ int ret;
+
+ if (s->server) {
+ SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ /*
+ * TODO(TLS1.3): Somehow we need to check that we're not sending too much
+ * data
+ */
+
+ switch (s->early_data_state) {
+ case SSL_EARLY_DATA_NONE:
+ if (!SSL_in_before(s)) {
+ SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ /* fall through */
+
+ case SSL_EARLY_DATA_CONNECT_RETRY:
+ s->early_data_state = SSL_EARLY_DATA_CONNECTING;
+ ret = SSL_connect(s);
+ if (ret <= 0) {
+ /* NBIO or error */
+ s->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY;
+ return 0;
+ }
+ /* fall through */
+
+ case SSL_EARLY_DATA_WRITE_RETRY:
+ s->early_data_state = SSL_EARLY_DATA_WRITING;
+ ret = SSL_write_ex(s, buf, num, written);
+ s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
+ return ret;
+
+ default:
+ SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+}
+
+int SSL_write_early_finish(SSL *s)
+{
+ int ret;
+
+ if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY) {
+ SSLerr(SSL_F_SSL_WRITE_EARLY_FINISH, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ s->early_data_state = SSL_EARLY_DATA_WRITING;
+ ret = ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_END_OF_EARLY_DATA);
+ if (ret <= 0) {
+ s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
+ return 0;
+ }
+ s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
+ /*
+ * We set the enc_write_ctx back to NULL because we may end up writing
+ * in cleartext again if we get a HelloRetryRequest from the server.
+ */
+ EVP_CIPHER_CTX_free(s->enc_write_ctx);
+ s->enc_write_ctx = NULL;
+ ossl_statem_set_in_init(s, 1);
+ return 1;
+}
+
int SSL_shutdown(SSL *s)
{
/*
return -1;
}
+ if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
+ || s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY)
+ return -1;
+
s->method->ssl_renegotiate_check(s, 0);
if (SSL_in_init(s) || SSL_in_before(s)) {
&& (s)->method->version >= TLS1_3_VERSION \
&& (s)->method->version != TLS_ANY_VERSION)
+# define SSL_TREAT_AS_TLS13(s) \
+ (SSL_IS_TLS13(s) || (s)->early_data_state == SSL_EARLY_DATA_WRITING)
+
# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3->tmp.finish_md_len == 0)
/* See if we need explicit IV */
# endif
+typedef enum {
+ SSL_EARLY_DATA_NONE = 0,
+ SSL_EARLY_DATA_CONNECT_RETRY,
+ SSL_EARLY_DATA_CONNECTING,
+ SSL_EARLY_DATA_WRITE_RETRY,
+ SSL_EARLY_DATA_WRITING,
+ SSL_EARLY_DATA_FINISHED_WRITING
+} SSL_EARLY_DATA_STATE;
+
#define MAX_COMPRESSIONS_SIZE 255
struct ssl_comp_st {
int shutdown;
/* where we are */
OSSL_STATEM statem;
+ SSL_EARLY_DATA_STATE early_data_state;
BUF_MEM *init_buf; /* buffer used during init */
void *init_msg; /* pointer to handshake message body, set by
* ssl3_get_message() */
goto end;
}
- if (SSL_IS_FIRST_HANDSHAKE(s) || s->renegotiate) {
+ if ((SSL_IS_FIRST_HANDSHAKE(s)
+ && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING)
+ || s->renegotiate) {
if (!tls_setup_handshake(s)) {
ossl_statem_set_error(s);
goto end;
break;
case TLS_ST_OK:
+ if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING
+ && mt == SSL3_MT_SERVER_HELLO) {
+ st->hand_state = TLS_ST_CR_SRVR_HELLO;
+ return 1;
+ }
if (mt == SSL3_MT_NEWSESSION_TICKET) {
st->hand_state = TLS_ST_CR_SESSION_TICKET;
return 1;
break;
case TLS_ST_OK:
- if (mt == SSL3_MT_HELLO_REQUEST) {
+ if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING) {
+ /*
+ * We've not actually selected TLSv1.3 yet, but we have sent early
+ * data. The only thing allowed now is a ServerHello or a
+ * HelloRetryRequest.
+ */
+ if (mt == SSL3_MT_SERVER_HELLO) {
+ st->hand_state = TLS_ST_CR_SRVR_HELLO;
+ return 1;
+ }
+ if (mt == SSL3_MT_HELLO_RETRY_REQUEST) {
+ st->hand_state = TLS_ST_CR_HELLO_RETRY_REQUEST;
+ return 1;
+ }
+ } else if (mt == SSL3_MT_HELLO_REQUEST) {
st->hand_state = TLS_ST_CR_HELLO_REQ;
return 1;
}
return WRITE_TRAN_ERROR;
case TLS_ST_OK:
+ if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING) {
+ /*
+ * We are assuming this is a TLSv1.3 connection, although we haven't
+ * actually selected a version yet.
+ */
+ return WRITE_TRAN_FINISHED;
+ }
if (!s->renegotiate) {
/*
* We haven't requested a renegotiation ourselves so we must have
return WRITE_TRAN_CONTINUE;
case TLS_ST_CW_CLNT_HELLO:
+ if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) {
+ /*
+ * We are assuming this is a TLSv1.3 connection, although we haven't
+ * actually selected a version yet.
+ */
+ st->hand_state = TLS_ST_OK;
+ ossl_statem_set_in_init(s, 0);
+ return WRITE_TRAN_CONTINUE;
+ }
/*
* No transition at the end of writing because we don't know what
* we will be sent
}
/* else use the pre-loaded session */
- /* This is a real handshake so make sure we clean it up at the end */
- s->statem.cleanuphand = 1;
-
p = s->s3->client_random;
/*
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 tls13_alert_code(int code)
{
- if (code == SSL_AD_MISSING_EXTENSION)
+ if (code == SSL_AD_MISSING_EXTENSION || code == SSL_AD_END_OF_EARLY_DATA)
return code;
return tls1_alert_code(code);
SSL_CTX_set_max_early_data 429 1_1_1 EXIST::FUNCTION:
SSL_get_max_early_data 430 1_1_1 EXIST::FUNCTION:
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: