{
OSSL_STATEM *st = &s->statem;
- /*
- * TODO(TLS1.3): This is still based on the TLSv1.2 state machine. Over time
- * we will update this to look more like real TLSv1.3
- */
-
/*
* Note: There is no case for TLS_ST_CW_CLNT_HELLO, because we haven't
* yet negotiated TLSv1.3 at that point so that is handled by
st->hand_state = TLS_ST_CR_SESSION_TICKET;
return 1;
}
+ if (mt == SSL3_MT_KEY_UPDATE) {
+ st->hand_state = TLS_ST_CR_KEY_UPDATE;
+ return 1;
+ }
break;
}
}
break;
+ case TLS_ST_EARLY_DATA:
+ /*
+ * 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;
+ }
+ break;
+
case TLS_ST_CR_SRVR_HELLO:
if (s->hit) {
if (s->ext.ticket_expected) {
{
OSSL_STATEM *st = &s->statem;
- /*
- * TODO(TLS1.3): This is still based on the TLSv1.2 state machine. Over time
- * we will update this to look more like real TLSv1.3
- */
-
/*
* Note: There are no cases for TLS_ST_BEFORE because we haven't negotiated
* TLSv1.3 yet at that point. They are handled by
return WRITE_TRAN_CONTINUE;
case TLS_ST_CR_FINISHED:
+ if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
+ || s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING)
+ st->hand_state = TLS_ST_PENDING_EARLY_DATA_END;
+ else
+ st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
+ : TLS_ST_CW_FINISHED;
+ return WRITE_TRAN_CONTINUE;
+
+ case TLS_ST_PENDING_EARLY_DATA_END:
+ if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
+ st->hand_state = TLS_ST_CW_END_OF_EARLY_DATA;
+ return WRITE_TRAN_CONTINUE;
+ }
+ /* Fall through */
+
+ case TLS_ST_CW_END_OF_EARLY_DATA:
st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT
: TLS_ST_CW_FINISHED;
return WRITE_TRAN_CONTINUE;
st->hand_state = TLS_ST_CW_FINISHED;
return WRITE_TRAN_CONTINUE;
+ case TLS_ST_CR_KEY_UPDATE:
+ if (s->key_update != SSL_KEY_UPDATE_NONE) {
+ st->hand_state = TLS_ST_CW_KEY_UPDATE;
+ return WRITE_TRAN_CONTINUE;
+ }
+ /* Fall through */
+
+ case TLS_ST_CW_KEY_UPDATE:
case TLS_ST_CR_SESSION_TICKET:
case TLS_ST_CW_FINISHED:
st->hand_state = TLS_ST_OK;
- ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
case TLS_ST_OK:
- /* Just go straight to trying to read from the server */
+ if (s->key_update != SSL_KEY_UPDATE_NONE) {
+ st->hand_state = TLS_ST_CW_KEY_UPDATE;
+ return WRITE_TRAN_CONTINUE;
+ }
+
+ /* Try to read from the server instead */
return WRITE_TRAN_FINISHED;
}
}
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_EARLY_DATA;
+ return WRITE_TRAN_CONTINUE;
+ }
/*
* No transition at the end of writing because we don't know what
* we will be sent
*/
return WRITE_TRAN_FINISHED;
+ case TLS_ST_EARLY_DATA:
+ return WRITE_TRAN_FINISHED;
+
case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
st->hand_state = TLS_ST_CW_CLNT_HELLO;
return WRITE_TRAN_CONTINUE;
case TLS_ST_CW_CHANGE:
#if defined(OPENSSL_NO_NEXTPROTONEG)
- st->hand_state = TLS_ST_CW_FINISHED;
+ st->
+ hand_state = TLS_ST_CW_FINISHED;
#else
if (!SSL_IS_DTLS(s) && s->s3->npn_seen)
st->hand_state = TLS_ST_CW_NEXT_PROTO;
case TLS_ST_CW_FINISHED:
if (s->hit) {
st->hand_state = TLS_ST_OK;
- ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
} else {
return WRITE_TRAN_FINISHED;
return WRITE_TRAN_CONTINUE;
} else {
st->hand_state = TLS_ST_OK;
- ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
}
return WRITE_TRAN_CONTINUE;
}
st->hand_state = TLS_ST_OK;
- ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
}
}
}
break;
+ case TLS_ST_PENDING_EARLY_DATA_END:
+ /*
+ * If we've been called by SSL_do_handshake()/SSL_write(), or we did not
+ * attempt to write early data before calling SSL_read() then we press
+ * on with the handshake. Otherwise we pause here.
+ */
+ if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING
+ || s->early_data_state == SSL_EARLY_DATA_NONE)
+ return WORK_FINISHED_CONTINUE;
+ /* Fall through */
+
+ case TLS_ST_EARLY_DATA:
case TLS_ST_OK:
return tls_finish_handshake(s, wst, 1);
}
/*
* Perform any work that needs to be done after sending a message from the
* client to the server.
- case TLS_ST_SR_CERT_VRFY:
- return SSL3_RT_MAX_PLAIN_LENGTH;
*/
WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
{
/* Treat the next message as the first packet */
s->first_packet = 1;
}
+
+ if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
+ && s->max_early_data > 0) {
+ /*
+ * We haven't selected TLSv1.3 yet so we don't call the change
+ * cipher state function associated with the SSL_METHOD. Instead
+ * we call tls13_change_cipher_state() directly.
+ */
+ if (!tls13_change_cipher_state(s,
+ SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE))
+ return WORK_ERROR;
+ }
+ break;
+
+ case TLS_ST_CW_END_OF_EARLY_DATA:
+ /*
+ * 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;
break;
case TLS_ST_CW_KEY_EXCH:
return WORK_ERROR;
}
break;
+
+ case TLS_ST_CW_KEY_UPDATE:
+ if (statem_flush(s) != 1)
+ return WORK_MORE_A;
+ if (!tls13_update_key(s, 1))
+ return WORK_ERROR;
+ break;
}
return WORK_FINISHED_CONTINUE;
*mt = SSL3_MT_CLIENT_HELLO;
break;
+ case TLS_ST_CW_END_OF_EARLY_DATA:
+ *confunc = tls_construct_end_of_early_data;
+ *mt = SSL3_MT_END_OF_EARLY_DATA;
+ break;
+
+ case TLS_ST_PENDING_EARLY_DATA_END:
+ *confunc = NULL;
+ *mt = SSL3_MT_DUMMY;
+ break;
+
case TLS_ST_CW_CERT:
*confunc = tls_construct_client_certificate;
*mt = SSL3_MT_CERTIFICATE;
*confunc = tls_construct_finished;
*mt = SSL3_MT_FINISHED;
break;
+
+ case TLS_ST_CW_KEY_UPDATE:
+ *confunc = tls_construct_key_update;
+ *mt = SSL3_MT_KEY_UPDATE;
+ break;
}
return 1;
case TLS_ST_CR_ENCRYPTED_EXTENSIONS:
return ENCRYPTED_EXTENSIONS_MAX_LENGTH;
+
+ case TLS_ST_CR_KEY_UPDATE:
+ return KEY_UPDATE_MAX_LENGTH;
}
}
case TLS_ST_CR_ENCRYPTED_EXTENSIONS:
return tls_process_encrypted_extensions(s, pkt);
+
+ case TLS_ST_CR_KEY_UPDATE:
+ return tls_process_key_update(s, pkt);
}
}
}
/* 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;
/*
return 0;
}
#ifndef OPENSSL_NO_COMP
- if (ssl_allow_compression(s) && s->ctx->comp_methods) {
+ if (ssl_allow_compression(s)
+ && s->ctx->comp_methods
+ && (SSL_IS_DTLS(s) || s->s3->tmp.max_ver < TLS1_3_VERSION)) {
int compnum = sk_SSL_COMP_num(s->ctx->comp_methods);
for (i = 0; i < compnum; i++) {
comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
goto f_err;
}
+ /*
+ * In TLSv1.3 a ServerHello message signals a key change so the end of the
+ * message must be on a record boundary.
+ */
+ if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_NOT_ON_RECORD_BOUNDARY);
+ goto f_err;
+ }
+
/* load the server hello data */
/* load the server random */
if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) {
context = SSL_IS_TLS13(s) ? EXT_TLS1_3_SERVER_HELLO
: EXT_TLS1_2_SERVER_HELLO;
- if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al))
+ if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al, NULL))
goto f_err;
s->hit = 0;
&& master_key_length > 0) {
s->session->master_key_length = master_key_length;
s->session->cipher = pref_cipher ?
- pref_cipher : ssl_get_cipher_by_char(s, cipherchars);
+ pref_cipher : ssl_get_cipher_by_char(s, cipherchars, 0);
} else {
SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
- c = ssl_get_cipher_by_char(s, cipherchars);
+ c = ssl_get_cipher_by_char(s, cipherchars, 0);
if (c == NULL) {
/* unknown cipher */
al = SSL_AD_ILLEGAL_PARAMETER;
*/
if (SSL_IS_TLS13(s)
&& (!s->method->ssl3_enc->setup_key_block(s)
- || !s->method->ssl3_enc->change_cipher_state(s,
- SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE)
|| !s->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ))) {
al = SSL_AD_INTERNAL_ERROR;
}
if (!tls_collect_extensions(s, &extpkt, EXT_TLS1_3_HELLO_RETRY_REQUEST,
- &extensions, &al)
+ &extensions, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_HELLO_RETRY_REQUEST,
extensions, NULL, 0, &al))
goto f_err;
goto f_err;
}
if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE,
- &rawexts, &al)
+ &rawexts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE,
rawexts, x, chainidx, &al)) {
OPENSSL_free(rawexts);
MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
{
int ret = MSG_PROCESS_ERROR;
- unsigned int list_len, ctype_num, i, name_len;
+ unsigned int i, name_len;
X509_NAME *xn = NULL;
- const unsigned char *data;
const unsigned char *namestart, *namebytes;
STACK_OF(X509_NAME) *ca_sk = NULL;
+ PACKET cadns;
if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
goto err;
}
- /* get the certificate types */
- if (!PACKET_get_1(pkt, &ctype_num)
- || !PACKET_get_bytes(pkt, &data, ctype_num)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
- goto err;
- }
- OPENSSL_free(s->cert->ctypes);
- s->cert->ctypes = NULL;
- if (ctype_num > SSL3_CT_NUMBER) {
- /* If we exceed static buffer copy all to cert structure */
- s->cert->ctypes = OPENSSL_malloc(ctype_num);
- if (s->cert->ctypes == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+ if (SSL_IS_TLS13(s)) {
+ PACKET reqctx;
+
+ /* Free and zero certificate types: it is not present in TLS 1.3 */
+ OPENSSL_free(s->s3->tmp.ctype);
+ s->s3->tmp.ctype = NULL;
+ s->s3->tmp.ctype_len = 0;
+ /* TODO(TLS1.3) need to process request context, for now ignore */
+ if (!PACKET_get_length_prefixed_1(pkt, &reqctx)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+ SSL_R_LENGTH_MISMATCH);
+ goto err;
+ }
+ } else {
+ PACKET ctypes;
+
+ /* get the certificate types */
+ if (!PACKET_get_length_prefixed_1(pkt, &ctypes)) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+ SSL_R_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ if (!PACKET_memdup(&ctypes, &s->s3->tmp.ctype, &s->s3->tmp.ctype_len)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
- memcpy(s->cert->ctypes, data, ctype_num);
- s->cert->ctype_num = ctype_num;
- ctype_num = SSL3_CT_NUMBER;
}
- for (i = 0; i < ctype_num; i++)
- s->s3->tmp.ctype[i] = data[i];
if (SSL_USE_SIGALGS(s)) {
PACKET sigalgs;
goto err;
}
- /* Clear certificate digests and validity flags */
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- s->s3->tmp.md[i] = NULL;
+ /* Clear certificate validity flags */
+ for (i = 0; i < SSL_PKEY_NUM; i++)
s->s3->tmp.valid_flags[i] = 0;
- }
if (!tls1_save_sigalgs(s, &sigalgs)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
goto err;
}
- } else {
- ssl_set_default_md(s);
}
/* get the CA RDNs */
- if (!PACKET_get_net_2(pkt, &list_len)
- || PACKET_remaining(pkt) != list_len) {
+ if (!PACKET_get_length_prefixed_2(pkt, &cadns)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
goto err;
}
- while (PACKET_remaining(pkt)) {
- if (!PACKET_get_net_2(pkt, &name_len)
- || !PACKET_get_bytes(pkt, &namebytes, name_len)) {
+ while (PACKET_remaining(&cadns)) {
+ if (!PACKET_get_net_2(&cadns, &name_len)
+ || !PACKET_get_bytes(&cadns, &namebytes, name_len)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
SSL_R_LENGTH_MISMATCH);
}
xn = NULL;
}
+ /* TODO(TLS1.3) need to parse and process extensions, for now ignore */
+ if (SSL_IS_TLS13(s)) {
+ PACKET reqexts;
+
+ if (!PACKET_get_length_prefixed_2(pkt, &reqexts)) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+ SSL_R_EXT_LENGTH_MISMATCH);
+ goto err;
+ }
+ }
+
+ if (PACKET_remaining(pkt) != 0) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
+ goto err;
+ }
/* we should setup a certificate to return.... */
s->s3->tmp.cert_req = 1;
- s->s3->tmp.ctype_num = ctype_num;
sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
s->s3->tmp.ca_names = ca_sk;
ca_sk = NULL;
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
|| !tls_collect_extensions(s, &extpkt,
EXT_TLS1_3_NEW_SESSION_TICKET,
- &exts, &al)
+ &exts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_NEW_SESSION_TICKET,
exts, NULL, 0, &al)) {
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_BAD_EXTENSION);
}
EVP_PKEY_CTX_free(pctx);
pctx = NULL;
-# ifdef PKCS1_CHECK
- if (s->options & SSL_OP_PKCS1_CHECK_1)
- (*p)[1]++;
- if (s->options & SSL_OP_PKCS1_CHECK_2)
- tmp_buf[0] = 0x70;
-# endif
/* Fix buf for TLS and beyond */
if (s->version > SSL3_VERSION && !WPACKET_close(pkt)) {
*/
static int ssl3_check_client_certificate(SSL *s)
{
- if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey)
- return 0;
/* If no suitable signature algorithm can't use certificate */
- if (SSL_USE_SIGALGS(s) && !s->s3->tmp.md[s->cert->key - s->cert->pkeys])
+ if (!tls_choose_sigalg(s, NULL) || s->s3->tmp.sigalg == NULL)
return 0;
/*
* If strict mode check suitability of chain before using it. This also
: s->cert->key,
&al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return 0;
+ goto err;
+ }
+
+ if (SSL_IS_TLS13(s)
+ && SSL_IS_FIRST_HANDSHAKE(s)
+ && (!s->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE,
+ SSL_R_CANNOT_CHANGE_CIPHER);
+ goto err;
}
return 1;
+ err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return 0;
}
#define has_bits(i,m) (((i)&(m)) == (m))
}
if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
- &rawexts, &al)
+ &rawexts, &al, NULL)
|| !tls_parse_all_extensions(s, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
rawexts, NULL, 0, &al))
goto err;
return 1;
}
+
+int tls_construct_end_of_early_data(SSL *s, WPACKET *pkt)
+{
+ if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY
+ && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
+ return 1;
+}