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);
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
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;
/*-
}
/* TLS extensions */
- if (!tls_construct_extensions(s, pkt, EXT_CLIENT_HELLO, NULL, 0, &al)) {
+ if (!tls_construct_extensions(s, pkt, SSL_EXT_CLIENT_HELLO, NULL, 0, &al)) {
ssl3_send_alert(s, SSL3_AL_FATAL, al);
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
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)) {
+ if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK, 1)) {
SSLerr(SSL_F_SET_CLIENT_CIPHERSUITE, SSL_R_WRONG_CIPHER_RETURNED);
return 0;
}
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;
}
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);
- goto f_err;
- }
-
/* Get the session-id. */
if (!SSL_IS_TLS13(s)) {
if (!PACKET_get_length_prefixed_1(pkt, &session_id)) {
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, NULL))
+ 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 {
}
#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
s->hello_retry_request = 1;
/* This will fail if it doesn't choose TLSv1.3+ */
- errorcode = ssl_choose_client_version(s, sversion);
+ errorcode = ssl_choose_client_version(s, sversion, 0, &al);
if (errorcode != 0) {
- al = SSL_AD_PROTOCOL_VERSION;
SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, errorcode);
goto f_err;
}
goto f_err;
}
- if (!tls_collect_extensions(s, &extpkt, EXT_TLS1_3_HELLO_RETRY_REQUEST,
- &extensions, &al, NULL)
- || !tls_parse_all_extensions(s, EXT_TLS1_3_HELLO_RETRY_REQUEST,
- extensions, NULL, 0, &al))
+ 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);
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, NULL)
- || !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))) {
OPENSSL_free(rawexts);
goto f_err;
}
goto err;
}
- /* test non-zero pupkey */
+ /* test non-zero pubkey */
if (BN_is_zero(bnpub_key)) {
*al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_BAD_DH_VALUE);
MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
{
int ret = MSG_PROCESS_ERROR;
- unsigned int i, name_len;
- X509_NAME *xn = NULL;
- 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;
- }
+ int al = SSL_AD_DECODE_ERROR;
+ size_t 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;
+ PACKET reqctx, extensions;
+ RAW_EXTENSION *rawexts = NULL;
/* 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;
- }
- }
- if (SSL_USE_SIGALGS(s)) {
- PACKET sigalgs;
-
- if (!PACKET_get_length_prefixed_2(pkt, &sigalgs)) {
- 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_get_length_prefixed_2(pkt, &extensions)) {
+ SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_BAD_LENGTH);
+ goto err;
}
-
- /* 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,
- 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;
}
- }
-
- /* get the CA RDNs */
- 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;
- }
+ } else {
+ PACKET ctypes;
- 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);
+ /* 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 (!sk_X509_NAME_push(ca_sk, xn)) {
- SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
- 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;
+ }
}
- 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);
+ /* get the CA RDNs */
+ if (!parse_ca_names(s, pkt, &al))
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;
- 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 = SSL_AD_DECODE_ERROR;
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;
/*
if (!PACKET_as_length_prefixed_2(pkt, &extpkt)
|| !tls_collect_extensions(s, &extpkt,
- EXT_TLS1_3_NEW_SESSION_TICKET,
- &exts, &al, NULL)
- || !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;
}
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);
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) {
goto err;
}
- if (!tls_collect_extensions(s, &extensions, EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
- &rawexts, &al, NULL)
- || !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;
}