STACK_OF(SSL_CIPHER) *ciphers = NULL;
STACK_OF(SSL_CIPHER) *scsvs = NULL;
CLIENTHELLO_MSG *clienthello = s->clienthello;
+ DOWNGRADE dgrd = DOWNGRADE_NONE;
*al = SSL_AD_INTERNAL_ERROR;
/* Finished parsing the ClientHello, now we can start processing it */
* versions are potentially compatible. Version negotiation comes later.
*/
if (!SSL_IS_DTLS(s)) {
- protverr = ssl_choose_server_version(s, clienthello);
+ protverr = ssl_choose_server_version(s, clienthello, &dgrd);
} else if (s->method->version != DTLS_ANY_VERSION &&
DTLS_VERSION_LT((int)clienthello->legacy_version, s->version)) {
protverr = SSL_R_VERSION_TOO_LOW;
goto err;
}
- /* TLSv1.3 defines that a ClientHello must end on a record boundary */
+ /* TLSv1.3 specifies that a ClientHello must end 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_EARLY_POST_PROCESS_CLIENT_HELLO,
s->d1->cookie_verified = 1;
}
if (s->method->version == DTLS_ANY_VERSION) {
- protverr = ssl_choose_server_version(s, clienthello);
+ protverr = ssl_choose_server_version(s, clienthello, &dgrd);
if (protverr != 0) {
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr);
s->version = s->client_version;
{
unsigned char *pos;
pos = s->s3->server_random;
- if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) {
+ if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE, dgrd) <= 0) {
goto err;
}
}
* Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher
*/
- if (!s->hit) {
-#ifdef OPENSSL_NO_COMP
- s->session->compress_meth = 0;
-#else
- s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
-#endif
+ if (!s->hit || s->hello_retry_request) {
sk_SSL_CIPHER_free(s->session->ciphers);
s->session->ciphers = ciphers;
if (ciphers == NULL) {
goto err;
}
ciphers = NULL;
+ }
+
+ if (!s->hit) {
+#ifdef OPENSSL_NO_COMP
+ s->session->compress_meth = 0;
+#else
+ s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
+#endif
if (!tls1_set_server_sigalgs(s)) {
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
goto err;
wst = WORK_MORE_B;
}
if (wst == WORK_MORE_B) {
- if (!s->hit) {
+ if (!s->hit || s->hello_retry_request) {
/* Let cert callback update server certificates if required */
if (s->cert->cert_cb) {
int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
- s->s3->tmp.new_cipher = cipher;
- if (!tls_choose_sigalg(s, &al))
+ if (SSL_IS_TLS13(s) && s->s3->tmp.new_cipher != NULL
+ && s->s3->tmp.new_cipher->id != cipher->id) {
+ /*
+ * A previous HRR picked a different ciphersuite to the one we
+ * just selected. Something must have changed.
+ */
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_BAD_CIPHER);
goto f_err;
- /* check whether we should disable session resumption */
- if (s->not_resumable_session_cb != NULL)
- s->session->not_resumable =
- s->not_resumable_session_cb(s, ((cipher->algorithm_mkey
- & (SSL_kDHE | SSL_kECDHE))
- != 0));
- if (s->session->not_resumable)
- /* do not send a session ticket */
- s->ext.ticket_expected = 0;
+ }
+ s->s3->tmp.new_cipher = cipher;
+ if (!s->hit) {
+ if (!tls_choose_sigalg(s, &al))
+ goto f_err;
+ /* check whether we should disable session resumption */
+ if (s->not_resumable_session_cb != NULL)
+ s->session->not_resumable =
+ s->not_resumable_session_cb(s, ((cipher->algorithm_mkey
+ & (SSL_kDHE | SSL_kECDHE))
+ != 0));
+ if (s->session->not_resumable)
+ /* do not send a session ticket */
+ s->ext.ticket_expected = 0;
+ }
} else {
/* Session-id reuse */
s->s3->tmp.new_cipher = s->session->cipher;
int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
{
- int i;
- STACK_OF(X509_NAME) *sk = NULL;
+ int al = SSL_AD_INTERNAL_ERROR;
if (SSL_IS_TLS13(s)) {
/* TODO(TLS1.3) for now send empty request context */
ERR_R_INTERNAL_ERROR);
goto err;
}
- } else {
- /* get the list of acceptable cert types */
- if (!WPACKET_start_sub_packet_u8(pkt)
- || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) {
+
+ if (!tls_construct_extensions(s, pkt, EXT_TLS1_3_CERTIFICATE_REQUEST,
+ NULL, 0, &al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
ERR_R_INTERNAL_ERROR);
goto err;
}
+ goto done;
+ }
+
+ /* get the list of acceptable cert types */
+ if (!WPACKET_start_sub_packet_u8(pkt)
+ || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
+ goto err;
}
if (SSL_USE_SIGALGS(s)) {
}
}
- /* Start sub-packet for client CA list */
- if (!WPACKET_start_sub_packet_u16(pkt)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- sk = SSL_get_client_CA_list(s);
- if (sk != NULL) {
- for (i = 0; i < sk_X509_NAME_num(sk); i++) {
- unsigned char *namebytes;
- X509_NAME *name = sk_X509_NAME_value(sk, i);
- int namelen;
-
- if (name == NULL
- || (namelen = i2d_X509_NAME(name, NULL)) < 0
- || !WPACKET_sub_allocate_bytes_u16(pkt, namelen,
- &namebytes)
- || i2d_X509_NAME(name, &namebytes) != namelen) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
- }
- /* else no CA names */
- if (!WPACKET_close(pkt)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- /*
- * TODO(TLS1.3) implement configurable certificate_extensions
- * For now just send zero length extensions.
- */
- if (SSL_IS_TLS13(s) && !WPACKET_put_bytes_u16(pkt, 0)) {
+ if (!construct_ca_names(s, pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
+ done:
s->s3->tmp.cert_request = 1;
-
return 1;
err:
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
return 0;
}
static int tls_construct_hello_retry_request(SSL *s, WPACKET *pkt)
{
int al = SSL_AD_INTERNAL_ERROR;
+ size_t len = 0;
/*
* TODO(TLS1.3): Remove the DRAFT version before release
* (should be s->version)
*/
if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)
+ || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len)
|| !tls_construct_extensions(s, pkt, EXT_TLS1_3_HELLO_RETRY_REQUEST,
NULL, 0, &al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return 0;
+ goto err;
}
/* Ditch the session. We'll create a new one next time around */
s->session = NULL;
s->hit = 0;
+ /*
+ * 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))
+ goto err;
+
return 1;
+ err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return 0;
}
MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt)