#include <openssl/bn.h>
#include <openssl/engine.h>
+static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt);
static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt);
static ossl_inline int cert_req_allowed(SSL *s);
static int key_exchange_expected(SSL *s);
-static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
WPACKET *pkt);
{
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
default:
break;
+ case TLS_ST_CW_CLNT_HELLO:
+ /*
+ * This must a ClientHello following a HelloRetryRequest, so the only
+ * thing we can get now is a ServerHello.
+ */
+ if (mt == SSL3_MT_SERVER_HELLO) {
+ st->hand_state = TLS_ST_CR_SRVR_HELLO;
+ return 1;
+ }
+ break;
+
case TLS_ST_CR_SRVR_HELLO:
if (mt == SSL3_MT_ENCRYPTED_EXTENSIONS) {
st->hand_state = TLS_ST_CR_ENCRYPTED_EXTENSIONS;
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;
}
int ske_expected;
/*
- * Note that after a ClientHello we don't know what version we are going
- * to negotiate yet, so we don't take this branch until later
+ * Note that after writing the first ClientHello we don't know what version
+ * we are going to negotiate yet, so we don't take this branch until later.
*/
if (SSL_IS_TLS13(s)) {
if (!ossl_statem_client13_read_transition(s, mt))
st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST;
return 1;
}
+ } else {
+ if (mt == SSL3_MT_HELLO_RETRY_REQUEST) {
+ st->hand_state = TLS_ST_CR_HELLO_RETRY_REQUEST;
+ return 1;
+ }
+ }
+ 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;
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 or TLS_ST_CW_CLNT_HELLO,
- * because we haven't negotiated TLSv1.3 yet at that point. They are
- * handled by ossl_statem_client_write_transition().
+ * Note: There are no cases for TLS_ST_BEFORE because we haven't negotiated
+ * TLSv1.3 yet at that point. They are handled by
+ * ossl_statem_client_write_transition().
*/
switch (st->hand_state) {
default:
/* Shouldn't happen */
return WRITE_TRAN_ERROR;
+ case TLS_ST_CW_CLNT_HELLO:
+ /* We only hit this in the case of HelloRetryRequest */
+ return WRITE_TRAN_FINISHED;
+
+ case TLS_ST_CR_HELLO_RETRY_REQUEST:
+ st->hand_state = TLS_ST_CW_CLNT_HELLO;
+ 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_FINISHED;
}
- /* Renegotiation - fall through */
+ /* Renegotiation */
+ /* fall thru */
case TLS_ST_BEFORE:
st->hand_state = TLS_ST_CW_CLNT_HELLO;
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 DTLS_ST_CR_HELLO_VERIFY_REQUEST:
return HELLO_VERIFY_REQUEST_MAX_LENGTH;
+ case TLS_ST_CR_HELLO_RETRY_REQUEST:
+ return HELLO_RETRY_REQUEST_MAX_LENGTH;
+
case TLS_ST_CR_CERT:
return s->max_cert_list;
case TLS_ST_CR_ENCRYPTED_EXTENSIONS:
return ENCRYPTED_EXTENSIONS_MAX_LENGTH;
+
+ case TLS_ST_CR_KEY_UPDATE:
+ return KEY_UPDATE_MAX_LENGTH;
}
}
case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
return dtls_process_hello_verify(s, pkt);
+ case TLS_ST_CR_HELLO_RETRY_REQUEST:
+ return tls_process_hello_retry_request(s, pkt);
+
case TLS_ST_CR_CERT:
return tls_process_server_certificate(s, pkt);
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);
}
}
case TLS_ST_CR_CERT_REQ:
return tls_prepare_client_certificate(s, wst);
-
-#ifndef OPENSSL_NO_SCTP
- case TLS_ST_CR_SRVR_DONE:
- /* We only get here if we are using SCTP and we are renegotiating */
- if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
- s->s3->in_read_app_data = 2;
- s->rwstate = SSL_READING;
- BIO_clear_retry_flags(SSL_get_rbio(s));
- BIO_set_retry_read(SSL_get_rbio(s));
- ossl_statem_set_sctp_read_sock(s, 1);
- return WORK_MORE_A;
- }
- ossl_statem_set_sctp_read_sock(s, 0);
- return WORK_FINISHED_STOP;
-#endif
}
}
return 0;
}
- if ((sess == NULL) || !ssl_version_supported(s, sess->ssl_version) ||
- /*
- * In the case of EAP-FAST, we can have a pre-shared
- * "ticket" without a session ID.
- */
- (!sess->session_id_length && !sess->ext.tick) ||
- (sess->not_resumable)) {
+ if (sess == NULL
+ || !ssl_version_supported(s, sess->ssl_version)
+ || !SSL_SESSION_is_resumable(sess)) {
if (!ssl_get_new_session(s, 0))
return 0;
}
/* 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;
/*
} else
i = 1;
- if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)) <= 0)
+ if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random),
+ DOWNGRADE_NONE) <= 0)
return 0;
/*-
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);
}
/* TLS extensions */
- if (!tls_construct_extensions(s, pkt, EXT_CLIENT_HELLO, NULL, 0, &al)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ if (!tls_construct_extensions(s, pkt, SSL_EXT_CLIENT_HELLO, NULL, 0, &al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
return 0;
}
return MSG_PROCESS_ERROR;
}
-MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
+static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars)
{
STACK_OF(SSL_CIPHER) *sk;
const SSL_CIPHER *c;
+ int i;
+
+ c = ssl_get_cipher_by_char(s, cipherchars, 0);
+ if (c == NULL) {
+ /* unknown cipher */
+ SSLerr(SSL_F_SET_CLIENT_CIPHERSUITE, SSL_R_UNKNOWN_CIPHER_RETURNED);
+ return 0;
+ }
+ /*
+ * If it is a disabled cipher we either didn't send it in client hello,
+ * or it's not allowed for the selected protocol. So we return an error.
+ */
+ if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK, 1)) {
+ SSLerr(SSL_F_SET_CLIENT_CIPHERSUITE, SSL_R_WRONG_CIPHER_RETURNED);
+ return 0;
+ }
+
+ sk = ssl_get_ciphers_by_id(s);
+ i = sk_SSL_CIPHER_find(sk, c);
+ if (i < 0) {
+ /* we did not say we would use this cipher */
+ SSLerr(SSL_F_SET_CLIENT_CIPHERSUITE, SSL_R_WRONG_CIPHER_RETURNED);
+ return 0;
+ }
+
+ if (SSL_IS_TLS13(s) && s->s3->tmp.new_cipher != NULL
+ && s->s3->tmp.new_cipher->id != c->id) {
+ /* ServerHello selected a different ciphersuite to that in the HRR */
+ SSLerr(SSL_F_SET_CLIENT_CIPHERSUITE, SSL_R_WRONG_CIPHER_RETURNED);
+ return 0;
+ }
+
+ /*
+ * Depending on the session caching (internal/external), the cipher
+ * and/or cipher_id values may not be set. Make sure that cipher_id is
+ * set and use it for comparison.
+ */
+ if (s->session->cipher != NULL)
+ s->session->cipher_id = s->session->cipher->id;
+ if (s->hit && (s->session->cipher_id != c->id)) {
+ SSLerr(SSL_F_SET_CLIENT_CIPHERSUITE,
+ SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+ return 0;
+ }
+ s->s3->tmp.new_cipher = c;
+
+ return 1;
+}
+
+MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
+{
PACKET session_id, extpkt;
size_t session_id_len;
const unsigned char *cipherchars;
- int i, al = SSL_AD_INTERNAL_ERROR;
+ int al = SSL_AD_INTERNAL_ERROR;
unsigned int compression;
unsigned int sversion;
unsigned int context;
goto f_err;
}
- /* We do this immediately so we know what format the ServerHello is in */
- protverr = ssl_choose_client_version(s, sversion);
+ /* load the server random */
+ if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+
+ /*
+ * We do this immediately so we know what format the ServerHello is in.
+ * Must be done after reading the random data so we can check for the
+ * TLSv1.3 downgrade sentinels
+ */
+ protverr = ssl_choose_client_version(s, sversion, 1, &al);
if (protverr != 0) {
- al = SSL_AD_PROTOCOL_VERSION;
SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, protverr);
goto f_err;
}
- /* load the server hello data */
- /* load the server random */
- if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+ /*
+ * 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;
}
/* TLS extensions */
if (PACKET_remaining(pkt) == 0) {
PACKET_null_init(&extpkt);
- } else if (!PACKET_as_length_prefixed_2(pkt, &extpkt)) {
+ } else if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
+ || PACKET_remaining(pkt) != 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_BAD_LENGTH);
goto f_err;
}
- context = SSL_IS_TLS13(s) ? EXT_TLS1_3_SERVER_HELLO
- : EXT_TLS1_2_SERVER_HELLO;
- if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al))
+ context = SSL_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO
+ : SSL_EXT_TLS1_2_SERVER_HELLO;
+ if (!tls_collect_extensions(s, &extpkt, context, &extensions, &al, NULL, 1))
goto f_err;
s->hit = 0;
if (SSL_IS_TLS13(s)) {
/* This will set s->hit if we are resuming */
if (!tls_parse_extension(s, TLSEXT_IDX_psk,
- EXT_TLS1_3_SERVER_HELLO,
+ SSL_EXT_TLS1_3_SERVER_HELLO,
extensions, NULL, 0, &al))
goto f_err;
} else {
&& 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;
SSL_R_SSL_SESSION_VERSION_MISMATCH);
goto f_err;
}
-
- c = ssl_get_cipher_by_char(s, cipherchars);
- if (c == NULL) {
- /* unknown cipher */
- al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED);
- goto f_err;
- }
/*
* Now that we know the version, update the check to see if it's an allowed
* version.
*/
s->s3->tmp.min_ver = s->version;
s->s3->tmp.max_ver = s->version;
- /*
- * If it is a disabled cipher we either didn't send it in client hello,
- * or it's not allowed for the selected protocol. So we return an error.
- */
- if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK)) {
- al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
- goto f_err;
- }
-
- sk = ssl_get_ciphers_by_id(s);
- i = sk_SSL_CIPHER_find(sk, c);
- if (i < 0) {
- /* we did not say we would use this cipher */
- al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
- goto f_err;
- }
- /*
- * Depending on the session caching (internal/external), the cipher
- * and/or cipher_id values may not be set. Make sure that cipher_id is
- * set and use it for comparison.
- */
- if (s->session->cipher)
- s->session->cipher_id = s->session->cipher->id;
- if (s->hit && (s->session->cipher_id != c->id)) {
+ if (!set_client_ciphersuite(s, cipherchars)) {
al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
- SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
goto f_err;
}
- s->s3->tmp.new_cipher = c;
#ifdef OPENSSL_NO_COMP
if (compression != 0) {
}
#endif
- if (!tls_parse_all_extensions(s, context, extensions, NULL, 0, &al))
+ if (!tls_parse_all_extensions(s, context, extensions, NULL, 0, &al, 1))
goto f_err;
#ifndef OPENSSL_NO_SCTP
*/
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;
return MSG_PROCESS_ERROR;
}
+static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt)
+{
+ unsigned int sversion;
+ int errorcode;
+ const unsigned char *cipherchars;
+ RAW_EXTENSION *extensions = NULL;
+ int al;
+ PACKET extpkt;
+
+ if (!PACKET_get_net_2(pkt, &sversion)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_LENGTH_MISMATCH);
+ goto f_err;
+ }
+
+ s->hello_retry_request = 1;
+
+ /* This will fail if it doesn't choose TLSv1.3+ */
+ errorcode = ssl_choose_client_version(s, sversion, 0, &al);
+ if (errorcode != 0) {
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, errorcode);
+ goto f_err;
+ }
+
+ if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) {
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_LENGTH_MISMATCH);
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
+ }
+
+ if (!set_client_ciphersuite(s, cipherchars)) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ goto f_err;
+ }
+
+ if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
+ /* Must have a non-empty extensions block */
+ || PACKET_remaining(&extpkt) == 0
+ /* Must be no trailing data after extensions */
+ || PACKET_remaining(pkt) != 0) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_BAD_LENGTH);
+ goto f_err;
+ }
+
+ if (!tls_collect_extensions(s, &extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST,
+ &extensions, &al, NULL, 1)
+ || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST,
+ extensions, NULL, 0, &al, 1))
+ goto f_err;
+
+ OPENSSL_free(extensions);
+ extensions = NULL;
+
+ if (s->ext.tls13_cookie_len == 0 && s->s3->tmp.pkey != NULL) {
+ /*
+ * We didn't receive a cookie or a new key_share so the next
+ * ClientHello will not change
+ */
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST,
+ SSL_R_NO_CHANGE_FOLLOWING_HRR);
+ goto f_err;
+ }
+
+ /*
+ * Re-initialise the Transcript Hash. We're going to prepopulate it with
+ * a synthetic message_hash in place of ClientHello1.
+ */
+ if (!create_synthetic_message_hash(s)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+
+ /*
+ * Add this message to the Transcript Hash. Normally this is done
+ * automatically prior to the message processing stage. However due to the
+ * need to create the synthetic message hash, we defer that step until now
+ * for HRR messages.
+ */
+ if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+ s->init_num + SSL3_HM_HEADER_LENGTH)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+
+ return MSG_PROCESS_FINISHED_READING;
+ f_err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ ossl_statem_set_error(s);
+ OPENSSL_free(extensions);
+ return MSG_PROCESS_ERROR;
+}
+
MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
{
int al, i, ret = MSG_PROCESS_ERROR, exp_idx;
if ((SSL_IS_TLS13(s) && !PACKET_get_1(pkt, &context))
|| context != 0
|| !PACKET_get_net_3(pkt, &cert_list_len)
- || PACKET_remaining(pkt) != cert_list_len) {
+ || PACKET_remaining(pkt) != cert_list_len
+ || PACKET_remaining(pkt) == 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
goto f_err;
SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_BAD_LENGTH);
goto f_err;
}
- if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_CERTIFICATE,
- &rawexts, &al)
- || !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE,
- rawexts, x, chainidx, &al)) {
+ if (!tls_collect_extensions(s, &extensions,
+ SSL_EXT_TLS1_3_CERTIFICATE, &rawexts,
+ &al, NULL, chainidx == 0)
+ || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_CERTIFICATE,
+ rawexts, x, chainidx, &al,
+ PACKET_remaining(pkt) == 0)) {
OPENSSL_free(rawexts);
goto f_err;
}
if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) {
x = NULL;
- al = SSL3_AL_FATAL;
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
goto f_err;
SSL_R_UNKNOWN_CERTIFICATE_TYPE);
goto f_err;
}
-
- exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- if (exp_idx >= 0 && i != exp_idx
- && (exp_idx != SSL_PKEY_GOST_EC ||
- (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256
- && i != SSL_PKEY_GOST01))) {
- x = NULL;
- al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
- SSL_R_WRONG_CERTIFICATE_TYPE);
- goto f_err;
+ /*
+ * Check certificate type is consistent with ciphersuite. For TLS 1.3
+ * skip check since TLS 1.3 ciphersuites can be used with any certificate
+ * type.
+ */
+ if (!SSL_IS_TLS13(s)) {
+ exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
+ if (exp_idx >= 0 && i != exp_idx
+ && (exp_idx != SSL_PKEY_GOST_EC ||
+ (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256
+ && i != SSL_PKEY_GOST01))) {
+ x = NULL;
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+ SSL_R_WRONG_CERTIFICATE_TYPE);
+ goto f_err;
+ }
}
s->session->peer_type = i;
}
if (!srp_verify_server_param(s, al)) {
- *al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SKE_SRP, SSL_R_BAD_SRP_PARAMETERS);
return 0;
}
goto err;
}
- /* test non-zero pupkey */
+ /* test non-zero pubkey */
if (BN_is_zero(bnpub_key)) {
- *al = SSL_AD_DECODE_ERROR;
+ *al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_BAD_DH_VALUE);
goto err;
}
p = g = NULL;
if (DH_check_params(dh, &check_bits) == 0 || check_bits != 0) {
- *al = SSL_AD_DECODE_ERROR;
+ *al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_BAD_DH_VALUE);
goto err;
}
* invalid curve. ECParameters is 3 bytes.
*/
if (!tls1_check_curve(s, ecparams, 3)) {
- *al = SSL_AD_DECODE_ERROR;
+ *al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_WRONG_CURVE);
return 0;
}
if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
PACKET_data(&encoded_pt),
PACKET_remaining(&encoded_pt))) {
- *al = SSL_AD_DECODE_ERROR;
+ *al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_BAD_ECPOINT);
return 0;
}
MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
{
- int al = -1, ispss = 0;
+ int al = -1;
long alg_k;
EVP_PKEY *pkey = NULL;
EVP_MD_CTX *md_ctx = NULL;
if (!PACKET_get_sub_packet(&save_param_start, ¶ms,
PACKET_remaining(&save_param_start) -
PACKET_remaining(pkt))) {
- al = SSL_AD_INTERNAL_ERROR;
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err;
}
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto err;
}
- rv = tls12_check_peer_sigalg(&md, s, sigalg, pkey);
+ rv = tls12_check_peer_sigalg(s, sigalg, pkey);
if (rv == -1) {
al = SSL_AD_INTERNAL_ERROR;
goto err;
al = SSL_AD_DECODE_ERROR;
goto err;
}
- ispss = SIGID_IS_PSS(sigalg);
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
- } else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
- md = EVP_md5_sha1();
- } else {
- md = EVP_sha1();
+ } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto err;
}
+ md = ssl_md(s->s3->tmp.peer_sigalg->hash_idx);
+
if (!PACKET_get_length_prefixed_2(pkt, &signature)
|| PACKET_remaining(pkt) != 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
goto err;
}
- if (ispss) {
+ if (SSL_USE_PSS(s)) {
if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0
- /* -1 here means set saltlen to the digest len */
- || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+ || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx,
+ RSA_PSS_SALTLEN_DIGEST) <= 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
goto err;
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;
- X509_NAME *xn = NULL;
- const unsigned char *data;
- const unsigned char *namestart, *namebytes;
- STACK_OF(X509_NAME) *ca_sk = NULL;
-
- if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ int al = SSL_AD_DECODE_ERROR;
+ size_t i;
- /* 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);
- 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];
+ /* Clear certificate validity flags */
+ for (i = 0; i < SSL_PKEY_NUM; i++)
+ s->s3->tmp.valid_flags[i] = 0;
+
+ if (SSL_IS_TLS13(s)) {
+ PACKET reqctx, extensions;
+ RAW_EXTENSION *rawexts = NULL;
- if (SSL_USE_SIGALGS(s)) {
- PACKET sigalgs;
+ /* 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;
- if (!PACKET_get_length_prefixed_2(pkt, &sigalgs)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ /* 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;
}
- /* Clear certificate digests and validity flags */
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- s->s3->tmp.md[i] = NULL;
- s->s3->tmp.valid_flags[i] = 0;
+ if (!PACKET_get_length_prefixed_2(pkt, &extensions)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_BAD_LENGTH);
+ goto err;
}
- if (!tls1_save_sigalgs(s, &sigalgs)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
- SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ if (!tls_collect_extensions(s, &extensions,
+ SSL_EXT_TLS1_3_CERTIFICATE_REQUEST,
+ &rawexts, &al, NULL, 1)
+ || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_CERTIFICATE_REQUEST,
+ rawexts, NULL, 0, &al, 1)) {
+ OPENSSL_free(rawexts);
goto err;
}
+ OPENSSL_free(rawexts);
if (!tls1_process_sigalgs(s)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
goto err;
}
} else {
- ssl_set_default_md(s);
- }
+ PACKET ctypes;
- /* get the CA RDNs */
- if (!PACKET_get_net_2(pkt, &list_len)
- || PACKET_remaining(pkt) != list_len) {
- 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)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ /* get the certificate types */
+ if (!PACKET_get_length_prefixed_1(pkt, &ctypes)) {
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
SSL_R_LENGTH_MISMATCH);
goto err;
}
- namestart = namebytes;
-
- if ((xn = d2i_X509_NAME(NULL, (const unsigned char **)&namebytes,
- name_len)) == NULL) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB);
+ if (!PACKET_memdup(&ctypes, &s->s3->tmp.ctype, &s->s3->tmp.ctype_len)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (namebytes != (namestart + name_len)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
- SSL_R_CA_DN_LENGTH_MISMATCH);
- goto err;
+ if (SSL_USE_SIGALGS(s)) {
+ PACKET sigalgs;
+
+ if (!PACKET_get_length_prefixed_2(pkt, &sigalgs)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+ SSL_R_LENGTH_MISMATCH);
+ goto err;
+ }
+
+ if (!tls1_save_sigalgs(s, &sigalgs)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+ SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ goto err;
+ }
+ if (!tls1_process_sigalgs(s)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
}
- if (!sk_X509_NAME_push(ca_sk, xn)) {
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+
+ /* get the CA RDNs */
+ if (!parse_ca_names(s, pkt, &al))
goto err;
- }
- xn = NULL;
+ }
+
+ if (PACKET_remaining(pkt) != 0) {
+ 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;
ret = MSG_PROCESS_CONTINUE_PROCESSING;
goto done;
err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
ossl_statem_set_error(s);
done:
- X509_NAME_free(xn);
- sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
return ret;
}
-static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
-{
- return (X509_NAME_cmp(*a, *b));
-}
-
MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
{
- int al;
+ int al = SSL_AD_DECODE_ERROR;
unsigned int ticklen;
unsigned long ticket_lifetime_hint, age_add = 0;
unsigned int sess_len;
|| (SSL_IS_TLS13(s) && !PACKET_get_net_4(pkt, &age_add))
|| !PACKET_get_net_2(pkt, &ticklen)
|| (!SSL_IS_TLS13(s) && PACKET_remaining(pkt) != ticklen)
- || (SSL_IS_TLS13(s) && (ticklen == 0
- || PACKET_remaining(pkt) < ticklen))) {
- al = SSL_AD_DECODE_ERROR;
+ || (SSL_IS_TLS13(s)
+ && (ticklen == 0 || PACKET_remaining(pkt) < ticklen))) {
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
if (ticklen == 0)
return MSG_PROCESS_CONTINUE_READING;
- /* TODO(TLS1.3): Is this a suitable test for TLS1.3? */
- if (s->session->session_id_length > 0) {
+ /*
+ * Sessions must be immutable once they go into the session cache. Otherwise
+ * we can get multi-thread problems. Therefore we don't "update" sessions,
+ * we replace them with a duplicate. In TLSv1.3 we need to do this every
+ * time a NewSessionTicket arrives because those messages arrive
+ * post-handshake and the session may have already gone into the session
+ * cache.
+ */
+ if (SSL_IS_TLS13(s) || s->session->session_id_length > 0) {
int i = s->session_ctx->session_cache_mode;
SSL_SESSION *new_sess;
/*
PACKET extpkt;
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
+ || PACKET_remaining(pkt) != 0
|| !tls_collect_extensions(s, &extpkt,
- EXT_TLS1_3_NEW_SESSION_TICKET,
- &exts, &al)
- || !tls_parse_all_extensions(s, EXT_TLS1_3_NEW_SESSION_TICKET,
- exts, NULL, 0, &al)) {
+ SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
+ &exts, &al, NULL, 1)
+ || !tls_parse_all_extensions(s,
+ SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
+ exts, NULL, 0, &al, 1)) {
SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_BAD_EXTENSION);
goto f_err;
}
/* This is a standalone message in TLSv1.3, so there is no more to read */
if (SSL_IS_TLS13(s)) {
+ OPENSSL_free(exts);
ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
return MSG_PROCESS_FINISHED_READING;
}
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
ossl_statem_set_error(s);
+ OPENSSL_free(exts);
return MSG_PROCESS_ERROR;
}
if (!tls_process_initial_server_flight(s, &al))
goto err;
-#ifndef OPENSSL_NO_SCTP
- /* Only applies to renegotiation */
- if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))
- && s->renegotiate != 0)
- return MSG_PROCESS_CONTINUE_PROCESSING;
- else
-#endif
- return MSG_PROCESS_FINISHED_READING;
+ return MSG_PROCESS_FINISHED_READING;
err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
identitylen = strlen(identity);
if (identitylen > PSK_MAX_IDENTITY_LEN) {
SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ *al = SSL_AD_INTERNAL_ERROR;
goto err;
}
}
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)) {
goto err;
}
- s->s3->tmp.pms = pms;
- s->s3->tmp.pmslen = pmslen;
-
/* Log the premaster secret, if logging is enabled. */
if (!ssl_log_rsa_client_key_exchange(s, encdata, enclen, pms, pmslen))
goto err;
+ s->s3->tmp.pms = pms;
+ s->s3->tmp.pmslen = pmslen;
+
return 1;
err:
OPENSSL_clear_free(pms, pmslen);
dgst_nid = NID_id_GostR3411_2012_256;
/*
- * Get server sertificate PKEY and create ctx from it
+ * Get server certificate PKEY and create ctx from it
*/
peer_cert = s->session->peer;
if (!peer_cert) {
if (!tls_construct_cke_srp(s, pkt, &al))
goto err;
} else if (!(alg_k & SSL_kPSK)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err;
}
*/
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))
}
/*
- * This is a historical discrepancy maintained for compatibility
- * reasons. If a TLS client receives a HelloRequest it will attempt
- * an abbreviated handshake. However if a DTLS client receives a
- * HelloRequest it will do a full handshake.
+ * This is a historical discrepancy (not in the RFC) maintained for
+ * compatibility reasons. If a TLS client receives a HelloRequest it will
+ * attempt an abbreviated handshake. However if a DTLS client receives a
+ * HelloRequest it will do a full handshake. Either behaviour is reasonable
+ * but doing one for TLS and another for DTLS is odd.
*/
if (SSL_IS_DTLS(s))
SSL_renegotiate(s);
PACKET extensions;
RAW_EXTENSION *rawexts = NULL;
- if (!PACKET_as_length_prefixed_2(pkt, &extensions)) {
+ if (!PACKET_as_length_prefixed_2(pkt, &extensions)
+ || PACKET_remaining(pkt) != 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS, SSL_R_LENGTH_MISMATCH);
goto err;
}
- if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
- &rawexts, &al)
- || !tls_parse_all_extensions(s, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
- rawexts, NULL, 0, &al))
+ if (!tls_collect_extensions(s, &extensions,
+ SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS, &rawexts,
+ &al, NULL, 1)
+ || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
+ rawexts, NULL, 0, &al, 1))
goto err;
OPENSSL_free(rawexts);
int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt)
{
int i;
- size_t totlen = 0, len, maxlen;
+ size_t totlen = 0, len, maxlen, maxverok = 0;
int empty_reneg_info_scsv = !s->renegotiate;
/* Set disabled masks for this session */
ssl_set_client_disabled(s);
c = sk_SSL_CIPHER_value(sk, i);
/* Skip disabled ciphers */
- if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
+ if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0))
continue;
if (!s->method->put_cipher_by_char(c, pkt, &len)) {
return 0;
}
+ /* Sanity check that the maximum version we offer has ciphers enabled */
+ if (!maxverok) {
+ if (SSL_IS_DTLS(s)) {
+ if (DTLS_VERSION_GE(c->max_dtls, s->s3->tmp.max_ver)
+ && DTLS_VERSION_LE(c->min_dtls, s->s3->tmp.max_ver))
+ maxverok = 1;
+ } else {
+ if (c->max_tls >= s->s3->tmp.max_ver
+ && c->min_tls <= s->s3->tmp.max_ver)
+ maxverok = 1;
+ }
+ }
+
totlen += len;
}
- if (totlen == 0) {
+ if (totlen == 0 || !maxverok) {
SSLerr(SSL_F_SSL_CIPHER_LIST_TO_BYTES, SSL_R_NO_CIPHERS_AVAILABLE);
+
+ if (!maxverok)
+ ERR_add_error_data(1, "No ciphers enabled for max supported "
+ "SSL/TLS version");
+
return 0;
}
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;
+}