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);
} 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 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)) {
+ 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;
}
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)) {
SSL_R_SSL_SESSION_VERSION_MISMATCH);
goto f_err;
}
-
- c = ssl_get_cipher_by_char(s, cipherchars, 0);
- 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 */
+ if (!set_client_ciphersuite(s, cipherchars)) {
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)) {
- 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) {
al = SSL_AD_ILLEGAL_PARAMETER;
{
unsigned int sversion;
int errorcode;
+ const unsigned char *cipherchars;
RAW_EXTENSION *extensions = NULL;
int al;
PACKET extpkt;
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;
}
+ 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)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_BAD_LENGTH);
OPENSSL_free(extensions);
+ /*
+ * 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);
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,
+ EXT_TLS1_3_CERTIFICATE_REQUEST,
+ &rawexts, &al, NULL)
+ || !tls_parse_all_extensions(s, EXT_TLS1_3_CERTIFICATE_REQUEST,
+ rawexts, NULL, 0, &al)) {
+ 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;
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) {