diff options
Diffstat (limited to 'ssl/statem/statem_srvr.c')
| -rw-r--r-- | ssl/statem/statem_srvr.c | 1268 |
1 files changed, 549 insertions, 719 deletions
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 43f77a58992f..a9e67f9d32a7 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -3,7 +3,7 @@ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html @@ -18,11 +18,13 @@ #include <openssl/rand.h> #include <openssl/objects.h> #include <openssl/evp.h> -#include <openssl/hmac.h> #include <openssl/x509.h> #include <openssl/dh.h> +#include <openssl/rsa.h> #include <openssl/bn.h> #include <openssl/md5.h> +#include <openssl/trace.h> +#include <openssl/core_names.h> #include <openssl/asn1t.h> #define TICKET_NONCE_SIZE 8 @@ -83,7 +85,7 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt) case TLS_ST_SR_END_OF_EARLY_DATA: case TLS_ST_SW_FINISHED: - if (s->s3->tmp.cert_request) { + if (s->s3.tmp.cert_request) { if (mt == SSL3_MT_CERTIFICATE) { st->hand_state = TLS_ST_SR_CERT; return 1; @@ -186,7 +188,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) * list if we requested a certificate) */ if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE) { - if (s->s3->tmp.cert_request) { + if (s->s3.tmp.cert_request) { if (s->version == SSL3_VERSION) { if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { @@ -196,7 +198,6 @@ int ossl_statem_server_read_transition(SSL *s, int mt) * cert. */ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); return 0; } @@ -207,7 +208,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) st->hand_state = TLS_ST_SR_KEY_EXCH; return 1; } - } else if (s->s3->tmp.cert_request) { + } else if (s->s3.tmp.cert_request) { if (mt == SSL3_MT_CERTIFICATE) { st->hand_state = TLS_ST_SR_CERT; return 1; @@ -259,7 +260,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) case TLS_ST_SR_CHANGE: #ifndef OPENSSL_NO_NEXTPROTONEG - if (s->s3->npn_seen) { + if (s->s3.npn_seen) { if (mt == SSL3_MT_NEXT_PROTO) { st->hand_state = TLS_ST_SR_NEXT_PROTO; return 1; @@ -308,9 +309,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) BIO_set_retry_read(rbio); return 0; } - SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE, - SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, - SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); return 0; } @@ -323,7 +322,7 @@ int ossl_statem_server_read_transition(SSL *s, int mt) */ static int send_server_key_exchange(SSL *s) { - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; /* * only send a ServerKeyExchange if DH or fortezza but we have a @@ -385,7 +384,7 @@ int send_certificate_request(SSL *s) * section "Certificate request" in SSL 3 drafts and in * RFC 2246): */ - && (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && (!(s->s3.tmp.new_cipher->algorithm_auth & SSL_aNULL) /* * ... except when the application insists on * verification (against the specs, but statem_clnt.c accepts @@ -393,12 +392,12 @@ int send_certificate_request(SSL *s) */ || (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) /* don't request certificate for SRP auth */ - && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) + && !(s->s3.tmp.new_cipher->algorithm_auth & SSL_aSRP) /* * With normal PSK Certificates and Certificate Requests * are omitted */ - && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)) { + && !(s->s3.tmp.new_cipher->algorithm_auth & SSL_aPSK)) { return 1; } @@ -422,9 +421,7 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WRITE_TRAN_ERROR; case TLS_ST_OK: @@ -436,6 +433,10 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) st->hand_state = TLS_ST_SW_CERT_REQ; return WRITE_TRAN_CONTINUE; } + if (s->ext.extra_tickets_expected > 0) { + st->hand_state = TLS_ST_SW_SESSION_TICKET; + return WRITE_TRAN_CONTINUE; + } /* Try to read from the client instead */ return WRITE_TRAN_FINISHED; @@ -526,7 +527,9 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s) * Following an initial handshake we send the number of tickets we have * been configured for. */ - if (s->hit || s->num_tickets <= s->sent_tickets) { + if (!SSL_IS_FIRST_HANDSHAKE(s) && s->ext.extra_tickets_expected > 0) { + return WRITE_TRAN_CONTINUE; + } else if (s->hit || s->num_tickets <= s->sent_tickets) { /* We've written enough tickets out. */ st->hand_state = TLS_ST_OK; } @@ -553,9 +556,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WRITE_TRAN_ERROR; case TLS_ST_OK: @@ -605,7 +606,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL *s) } else { /* Check if it is anon DH or anon ECDH, */ /* normal PSK or SRP */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & + if (!(s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP | SSL_aPSK))) { st->hand_state = TLS_ST_SW_CERT; } else if (send_server_key_exchange(s)) { @@ -722,7 +723,8 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) return WORK_FINISHED_CONTINUE; case TLS_ST_SW_SESSION_TICKET: - if (SSL_IS_TLS13(s) && s->sent_tickets == 0) { + if (SSL_IS_TLS13(s) && s->sent_tickets == 0 + && s->ext.extra_tickets_expected == 0) { /* * Actually this is the end of the handshake, but we're going * straight into writing the session ticket out. So we finish off @@ -731,7 +733,8 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) * Calls SSLfatal as required. */ return tls_finish_handshake(s, wst, 0, 0); - } if (SSL_IS_DTLS(s)) { + } + if (SSL_IS_DTLS(s)) { /* * We're into the last flight. We don't retransmit the last flight * unless we need to, so we don't use the timer @@ -745,11 +748,9 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) break; /* Writes to s->session are only safe for initial handshakes */ if (s->session->cipher == NULL) { - s->session->cipher = s->s3->tmp.new_cipher; - } else if (s->session->cipher != s->s3->tmp.new_cipher) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER_PRE_WORK, - ERR_R_INTERNAL_ERROR); + s->session->cipher = s->s3.tmp.new_cipher; + } else if (s->session->cipher != s->s3.tmp.new_cipher) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } if (!s->method->ssl3_enc->setup_key_block(s)) { @@ -769,7 +770,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst) case TLS_ST_EARLY_DATA: if (s->early_data_state != SSL_EARLY_DATA_ACCEPTING - && (s->s3->flags & TLS1_FLAGS_STATELESS) == 0) + && (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return WORK_FINISHED_CONTINUE; /* Fall through */ @@ -869,9 +870,7 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst) sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER_POST_WORK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } @@ -1023,9 +1022,7 @@ int ossl_statem_server_construct_message(SSL *s, WPACKET *pkt, switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE, - SSL_R_BAD_HANDSHAKE_STATE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_STATE); return 0; case TLS_ST_SW_CHANGE: @@ -1186,9 +1183,7 @@ MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; case TLS_ST_SR_CLNT_HELLO: @@ -1234,9 +1229,7 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; case TLS_ST_SR_CLNT_HELLO: @@ -1254,7 +1247,7 @@ static int ssl_check_srp_ext_ClientHello(SSL *s) int ret; int al = SSL_AD_UNRECOGNIZED_NAME; - if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && + if ((s->s3.tmp.new_cipher->algorithm_mkey & SSL_kSRP) && (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) { if (s->srp_ctx.login == NULL) { /* @@ -1262,15 +1255,14 @@ static int ssl_check_srp_ext_ClientHello(SSL *s) * login name */ SSLfatal(s, SSL_AD_UNKNOWN_PSK_IDENTITY, - SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO, SSL_R_PSK_IDENTITY_NOT_FOUND); return -1; } else { - ret = SSL_srp_server_param_with_username(s, &al); + ret = ssl_srp_server_param_with_username_intern(s, &al); if (ret < 0) return 0; if (ret == SSL3_AL_FATAL) { - SSLfatal(s, al, SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO, + SSLfatal(s, al, al == SSL_AD_UNKNOWN_PSK_IDENTITY ? SSL_R_PSK_IDENTITY_NOT_FOUND : SSL_R_CLIENTHELLO_TLSEXT); @@ -1299,24 +1291,21 @@ int dtls_construct_hello_verify_request(SSL *s, WPACKET *pkt) if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, s->d1->cookie, &cookie_leni) == 0 || - cookie_leni > 255) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST, - SSL_R_COOKIE_GEN_CALLBACK_FAILURE); + cookie_leni > DTLS1_COOKIE_LENGTH) { + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); return 0; } s->d1->cookie_len = cookie_leni; if (!dtls_raw_hello_verify_request(pkt, s->d1->cookie, s->d1->cookie_len)) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); return 0; } return 1; } -#ifndef OPENSSL_NO_EC /*- * ssl_check_for_safari attempts to fingerprint Safari using OS X * SecureTransport using the TLS extension block in |hello|. @@ -1375,10 +1364,13 @@ static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello) ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ? sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength; - s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock, + s->s3.is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock, ext_len); } -#endif /* !OPENSSL_NO_EC */ + +#define RENEG_OPTIONS_OK(options) \ + ((options & SSL_OP_NO_RENEGOTIATION) == 0 \ + && (options & SSL_OP_ALLOW_CLIENT_RENEGOTIATION) != 0) MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) { @@ -1390,12 +1382,11 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) /* Check if this is actually an unexpected renegotiation ClientHello */ if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) { if (!ossl_assert(!SSL_IS_TLS13(s))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0 - || (!s->s3->send_connection_binding + if (!RENEG_OPTIONS_OK(s->options) + || (!s->s3.send_connection_binding && (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0)) { ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); @@ -1407,8 +1398,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) clienthello = OPENSSL_zalloc(sizeof(*clienthello)); if (clienthello == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1423,8 +1413,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) if (!SSL_IS_FIRST_HANDSHAKE(s) || s->hello_retry_request != SSL_HRR_NONE) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto err; } @@ -1450,15 +1439,13 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) * layer in order to have determined that this is a SSLv2 record * in the first place */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } if (!PACKET_get_net_2(pkt, &clienthello->legacy_version)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_LENGTH_TOO_SHORT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); goto err; } @@ -1475,14 +1462,12 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) if (!PACKET_get_net_2(pkt, &ciphersuite_len) || !PACKET_get_net_2(pkt, &session_id_len) || !PACKET_get_net_2(pkt, &challenge_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_RECORD_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RECORD_LENGTH_MISMATCH); goto err; } if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_LENGTH_MISMATCH); goto err; } @@ -1492,8 +1477,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) || !PACKET_get_sub_packet(pkt, &challenge, challenge_len) /* No extensions. */ || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_RECORD_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RECORD_LENGTH_MISMATCH); goto err; } clienthello->session_id_len = session_id_len; @@ -1511,8 +1495,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) challenge_len, challenge_len) /* Advertise only null compression. */ || !PACKET_buf_init(&compression, &null_compression, 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1524,22 +1507,19 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) || !PACKET_copy_all(&session_id, clienthello->session_id, SSL_MAX_SSL_SESSION_ID_LENGTH, &clienthello->session_id_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } if (SSL_IS_DTLS(s)) { if (!PACKET_get_length_prefixed_1(pkt, &cookie)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } if (!PACKET_copy_all(&cookie, clienthello->dtls_cookie, DTLS1_COOKIE_LENGTH, &clienthello->dtls_cookie_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* @@ -1556,14 +1536,12 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } if (!PACKET_get_length_prefixed_2(pkt, &clienthello->ciphersuites)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } if (!PACKET_get_length_prefixed_1(pkt, &compression)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -1573,8 +1551,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) } else { if (!PACKET_get_length_prefixed_2(pkt, &clienthello->extensions) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } } @@ -1583,8 +1560,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt) if (!PACKET_copy_all(&compression, clienthello->compressions, MAX_COMPRESSIONS_SIZE, &clienthello->compressions_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1636,15 +1612,13 @@ static int tls_early_post_process_client_hello(SSL *s) return -1; case SSL_CLIENT_HELLO_ERROR: default: - SSLfatal(s, al, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_CALLBACK_FAILED); + SSLfatal(s, al, SSL_R_CALLBACK_FAILED); goto err; } } /* Set up the client_random */ - memcpy(s->s3->client_random, clienthello->random, SSL3_RANDOM_SIZE); + memcpy(s->s3.client_random, clienthello->random, SSL3_RANDOM_SIZE); /* Choose the version */ @@ -1656,9 +1630,7 @@ static int tls_early_post_process_client_hello(SSL *s) * This is real SSLv2 or something completely unknown. We don't * support it. */ - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_UNKNOWN_PROTOCOL); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNKNOWN_PROTOCOL); goto err; } /* SSLv3/TLS */ @@ -1682,16 +1654,13 @@ static int tls_early_post_process_client_hello(SSL *s) /* like ssl3_get_record, send alert using remote version number */ s->version = s->client_version = clienthello->legacy_version; } - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, protverr); goto err; } /* TLSv1.3 specifies that a ClientHello must end on a record boundary */ if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_NOT_ON_RECORD_BOUNDARY); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); goto err; } @@ -1702,7 +1671,6 @@ static int tls_early_post_process_client_hello(SSL *s) if (s->ctx->app_verify_cookie_cb(s, clienthello->dtls_cookie, clienthello->dtls_cookie_len) == 0) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); goto err; /* else cookie verification succeeded */ @@ -1711,9 +1679,7 @@ static int tls_early_post_process_client_hello(SSL *s) } else if (s->d1->cookie_len != clienthello->dtls_cookie_len || memcmp(clienthello->dtls_cookie, s->d1->cookie, s->d1->cookie_len) != 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_COOKIE_MISMATCH); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_COOKIE_MISMATCH); goto err; } s->d1->cookie_verified = 1; @@ -1722,8 +1688,7 @@ static int tls_early_post_process_client_hello(SSL *s) protverr = ssl_choose_server_version(s, clienthello, &dgrd); if (protverr != 0) { s->version = s->client_version; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, protverr); goto err; } } @@ -1739,7 +1704,7 @@ static int tls_early_post_process_client_hello(SSL *s) goto err; } - s->s3->send_connection_binding = 0; + s->s3.send_connection_binding = 0; /* Check what signalling cipher-suite values were received. */ if (scsvs != NULL) { for(i = 0; i < sk_SSL_CIPHER_num(scsvs); i++) { @@ -1748,11 +1713,10 @@ static int tls_early_post_process_client_hello(SSL *s) if (s->renegotiate) { /* SCSV is fatal if renegotiating */ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); goto err; } - s->s3->send_connection_binding = 1; + s->s3.send_connection_binding = 1; } else if (SSL_CIPHER_get_id(c) == SSL3_CK_FALLBACK_SCSV && !ssl_check_version_downgrade(s)) { /* @@ -1763,7 +1727,6 @@ static int tls_early_post_process_client_hello(SSL *s) * an insecure downgrade. */ SSLfatal(s, SSL_AD_INAPPROPRIATE_FALLBACK, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_INAPPROPRIATE_FALLBACK); goto err; } @@ -1776,24 +1739,20 @@ static int tls_early_post_process_client_hello(SSL *s) ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s)); if (cipher == NULL) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_NO_SHARED_CIPHER); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SHARED_CIPHER); goto err; } if (s->hello_retry_request == SSL_HRR_PENDING - && (s->s3->tmp.new_cipher == NULL - || s->s3->tmp.new_cipher->id != cipher->id)) { + && (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. */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_BAD_CIPHER); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_CIPHER); goto err; } - s->s3->tmp.new_cipher = cipher; + s->s3.tmp.new_cipher = cipher; } /* We need to do this before getting the session */ @@ -1806,7 +1765,7 @@ static int tls_early_post_process_client_hello(SSL *s) /* * We don't allow resumption in a backwards compatible ClientHello. - * TODO(openssl-team): in TLS1.1+, session_id MUST be empty. + * In TLS1.1+, session_id MUST be empty. * * Versions before 0.9.7 always allow clients to resume sessions in * renegotiation. 0.9.7 and later allow this by default, but optionally @@ -1858,15 +1817,15 @@ static int tls_early_post_process_client_hello(SSL *s) j = 0; id = s->session->cipher->id; -#ifdef CIPHER_DEBUG - fprintf(stderr, "client sent %d ciphers\n", sk_SSL_CIPHER_num(ciphers)); -#endif + OSSL_TRACE_BEGIN(TLS_CIPHER) { + BIO_printf(trc_out, "client sent %d ciphers\n", + sk_SSL_CIPHER_num(ciphers)); + } for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { c = sk_SSL_CIPHER_value(ciphers, i); -#ifdef CIPHER_DEBUG - fprintf(stderr, "client [%2d of %2d]:%s\n", - i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c)); -#endif + if (trc_out != NULL) + BIO_printf(trc_out, "client [%2d of %2d]:%s\n", i, + sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c)); if (c->id == id) { j = 1; break; @@ -1878,10 +1837,11 @@ static int tls_early_post_process_client_hello(SSL *s) * to reuse it */ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_REQUIRED_CIPHER_MISSING); + OSSL_TRACE_CANCEL(TLS_CIPHER); goto err; } + OSSL_TRACE_END(TLS_CIPHER); } for (loop = 0; loop < clienthello->compressions_len; loop++) { @@ -1891,16 +1851,12 @@ static int tls_early_post_process_client_hello(SSL *s) if (loop >= clienthello->compressions_len) { /* no compress */ - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_NO_COMPRESSION_SPECIFIED); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_COMPRESSION_SPECIFIED); goto err; } -#ifndef OPENSSL_NO_EC if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) ssl_check_for_safari(s, clienthello); -#endif /* !OPENSSL_NO_EC */ /* TLS extensions */ if (!tls_parse_all_extensions(s, SSL_EXT_CLIENT_HELLO, @@ -1917,11 +1873,9 @@ static int tls_early_post_process_client_hello(SSL *s) */ { unsigned char *pos; - pos = s->s3->server_random; + pos = s->s3.server_random; if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE, dgrd) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } @@ -1956,9 +1910,7 @@ static int tls_early_post_process_client_hello(SSL *s) pref_cipher = ssl3_choose_cipher(s, s->peer_ciphers, SSL_get_ciphers(s)); if (pref_cipher == NULL) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_NO_SHARED_CIPHER); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SHARED_CIPHER); goto err; } @@ -1975,7 +1927,7 @@ static int tls_early_post_process_client_hello(SSL *s) * options, we will now look for them. We have complen-1 compression * algorithms from the client, starting at q. */ - s->s3->tmp.new_compression = NULL; + s->s3.tmp.new_compression = NULL; if (SSL_IS_TLS13(s)) { /* * We already checked above that the NULL compression method appears in @@ -1984,7 +1936,6 @@ static int tls_early_post_process_client_hello(SSL *s) */ if (clienthello->compressions_len != 1) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_INVALID_COMPRESSION_ALGORITHM); goto err; } @@ -1998,7 +1949,6 @@ static int tls_early_post_process_client_hello(SSL *s) /* Can't disable compression */ if (!ssl_allow_compression(s)) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION); goto err; } @@ -2006,13 +1956,12 @@ static int tls_early_post_process_client_hello(SSL *s) for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) { comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); if (comp_id == comp->id) { - s->s3->tmp.new_compression = comp; + s->s3.tmp.new_compression = comp; break; } } - if (s->s3->tmp.new_compression == NULL) { + if (s->s3.tmp.new_compression == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_INVALID_COMPRESSION_ALGORITHM); goto err; } @@ -2023,7 +1972,6 @@ static int tls_early_post_process_client_hello(SSL *s) } if (k >= clienthello->compressions_len) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING); goto err; } @@ -2048,7 +1996,7 @@ static int tls_early_post_process_client_hello(SSL *s) break; } if (done) - s->s3->tmp.new_compression = comp; + s->s3.tmp.new_compression = comp; else comp = NULL; } @@ -2058,9 +2006,7 @@ static int tls_early_post_process_client_hello(SSL *s) * using compression. */ if (s->session->compress_meth != 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - SSL_R_INCONSISTENT_COMPRESSION); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_INCONSISTENT_COMPRESSION); goto err; } #endif @@ -2073,9 +2019,7 @@ static int tls_early_post_process_client_hello(SSL *s) sk_SSL_CIPHER_free(s->peer_ciphers); s->peer_ciphers = ciphers; if (ciphers == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } ciphers = NULL; @@ -2128,12 +2072,12 @@ static int tls_handle_status_request(SSL *s) int ret; /* If no certificate can't return certificate status */ - if (s->s3->tmp.cert != NULL) { + if (s->s3.tmp.cert != NULL) { /* * Set current certificate to one we will use so SSL_get_certificate * et al can pick it up. */ - s->cert->key = s->s3->tmp.cert; + s->cert->key = s->s3.tmp.cert; ret = s->ctx->ext.status_cb(s, s->ctx->ext.status_arg); switch (ret) { /* We don't want to send a status request response */ @@ -2148,9 +2092,7 @@ static int tls_handle_status_request(SSL *s) /* something bad happened */ case SSL_TLSEXT_ERR_ALERT_FATAL: default: - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_HANDLE_STATUS_REQUEST, - SSL_R_CLIENTHELLO_TLSEXT); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CLIENTHELLO_TLSEXT); return 0; } } @@ -2168,25 +2110,24 @@ int tls_handle_alpn(SSL *s) const unsigned char *selected = NULL; unsigned char selected_len = 0; - if (s->ctx->ext.alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) { + if (s->ctx->ext.alpn_select_cb != NULL && s->s3.alpn_proposed != NULL) { int r = s->ctx->ext.alpn_select_cb(s, &selected, &selected_len, - s->s3->alpn_proposed, - (unsigned int)s->s3->alpn_proposed_len, + s->s3.alpn_proposed, + (unsigned int)s->s3.alpn_proposed_len, s->ctx->ext.alpn_select_cb_arg); if (r == SSL_TLSEXT_ERR_OK) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len); - if (s->s3->alpn_selected == NULL) { - s->s3->alpn_selected_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_HANDLE_ALPN, - ERR_R_INTERNAL_ERROR); + OPENSSL_free(s->s3.alpn_selected); + s->s3.alpn_selected = OPENSSL_memdup(selected, selected_len); + if (s->s3.alpn_selected == NULL) { + s->s3.alpn_selected_len = 0; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - s->s3->alpn_selected_len = selected_len; + s->s3.alpn_selected_len = selected_len; #ifndef OPENSSL_NO_NEXTPROTONEG /* ALPN takes precedence over NPN. */ - s->s3->npn_seen = 0; + s->s3.npn_seen = 0; #endif /* Check ALPN is consistent with session */ @@ -2205,7 +2146,6 @@ int tls_handle_alpn(SSL *s) */ if (!ossl_assert(s->session->ext.alpn_selected == NULL)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_HANDLE_ALPN, ERR_R_INTERNAL_ERROR); return 0; } @@ -2213,7 +2153,6 @@ int tls_handle_alpn(SSL *s) selected_len); if (s->session->ext.alpn_selected == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_HANDLE_ALPN, ERR_R_INTERNAL_ERROR); return 0; } @@ -2223,7 +2162,7 @@ int tls_handle_alpn(SSL *s) return 1; } else if (r != SSL_TLSEXT_ERR_NOACK) { - SSLfatal(s, SSL_AD_NO_APPLICATION_PROTOCOL, SSL_F_TLS_HANDLE_ALPN, + SSLfatal(s, SSL_AD_NO_APPLICATION_PROTOCOL, SSL_R_NO_APPLICATION_PROTOCOL); return 0; } @@ -2262,9 +2201,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) if (!s->hit && s->cert->cert_cb != NULL) { int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); if (rv == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, - SSL_R_CERT_CB_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CERT_CB_ERROR); goto err; } if (rv < 0) { @@ -2281,11 +2218,10 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) if (cipher == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); goto err; } - s->s3->tmp.new_cipher = cipher; + s->s3.tmp.new_cipher = cipher; } if (!s->hit) { if (!tls_choose_sigalg(s, 1)) { @@ -2296,7 +2232,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) if (s->not_resumable_session_cb != NULL) s->session->not_resumable = s->not_resumable_session_cb(s, - ((s->s3->tmp.new_cipher->algorithm_mkey + ((s->s3.tmp.new_cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) != 0)); if (s->session->not_resumable) /* do not send a session ticket */ @@ -2304,7 +2240,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) } } else { /* Session-id reuse */ - s->s3->tmp.new_cipher = s->session->cipher; + s->s3.tmp.new_cipher = s->session->cipher; } /*- @@ -2316,7 +2252,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst) * ssl version is set - sslv3 * s->session - The ssl session has been setup. * s->hit - session reuse flag - * s->s3->tmp.new_cipher- the new cipher to use. + * s->s3.tmp.new_cipher - the new cipher to use. */ /* @@ -2378,10 +2314,9 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) */ || !WPACKET_memcpy(pkt, s->hello_retry_request == SSL_HRR_PENDING - ? hrrrandom : s->s3->server_random, + ? hrrrandom : s->s3.server_random, SSL3_RANDOM_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -2417,8 +2352,7 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) } if (sl > sizeof(s->session->session_id)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -2426,17 +2360,16 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) #ifdef OPENSSL_NO_COMP compm = 0; #else - if (usetls13 || s->s3->tmp.new_compression == NULL) + if (usetls13 || s->s3.tmp.new_compression == NULL) compm = 0; else - compm = s->s3->tmp.new_compression->id; + compm = s->s3.tmp.new_compression->id; #endif if (!WPACKET_sub_memcpy_u8(pkt, session_id, sl) - || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len) + || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &len) || !WPACKET_put_bytes_u8(pkt, compm)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -2476,7 +2409,7 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt) int tls_construct_server_done(SSL *s, WPACKET *pkt) { - if (!s->s3->tmp.cert_request) { + if (!s->s3.tmp.cert_request) { if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ return 0; @@ -2487,35 +2420,30 @@ int tls_construct_server_done(SSL *s, WPACKET *pkt) int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) { -#ifndef OPENSSL_NO_DH EVP_PKEY *pkdh = NULL; -#endif -#ifndef OPENSSL_NO_EC unsigned char *encodedPoint = NULL; size_t encodedlen = 0; int curve_id = 0; -#endif - const SIGALG_LOOKUP *lu = s->s3->tmp.sigalg; + const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg; int i; unsigned long type; - const BIGNUM *r[4]; + BIGNUM *r[4]; EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); EVP_PKEY_CTX *pctx = NULL; size_t paramlen, paramoffset; + int freer = 0, ret = 0; if (!WPACKET_get_total_written(pkt, ¶moffset)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (md_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - type = s->s3->tmp.new_cipher->algorithm_mkey; + type = s->s3.tmp.new_cipher->algorithm_mkey; r[0] = r[1] = r[2] = r[3] = NULL; #ifndef OPENSSL_NO_PSK @@ -2523,87 +2451,68 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) if (type & (SSL_kPSK | SSL_kRSAPSK)) { } else #endif /* !OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_DH if (type & (SSL_kDHE | SSL_kDHEPSK)) { CERT *cert = s->cert; - EVP_PKEY *pkdhp = NULL; - DH *dh; if (s->cert->dh_tmp_auto) { - DH *dhp = ssl_get_auto_dh(s); - pkdh = EVP_PKEY_new(); - if (pkdh == NULL || dhp == NULL) { - DH_free(dhp); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + pkdh = ssl_get_auto_dh(s); + if (pkdh == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - EVP_PKEY_assign_DH(pkdh, dhp); pkdhp = pkdh; } else { pkdhp = cert->dh_tmp; } +#if !defined(OPENSSL_NO_DEPRECATED_3_0) if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) { - DH *dhp = s->cert->dh_tmp_cb(s, 0, 1024); - pkdh = ssl_dh_to_pkey(dhp); + pkdh = ssl_dh_to_pkey(s->cert->dh_tmp_cb(s, 0, 1024)); if (pkdh == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } pkdhp = pkdh; } +#endif if (pkdhp == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_TMP_DH_KEY); goto err; } if (!ssl_security(s, SSL_SECOP_TMP_DH, - EVP_PKEY_security_bits(pkdhp), 0, pkdhp)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_DH_KEY_TOO_SMALL); + EVP_PKEY_get_security_bits(pkdhp), 0, pkdhp)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_DH_KEY_TOO_SMALL); goto err; } - if (s->s3->tmp.pkey != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - s->s3->tmp.pkey = ssl_generate_pkey(pkdhp); - if (s->s3->tmp.pkey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, 0, ERR_R_INTERNAL_ERROR); + if (s->s3.tmp.pkey != NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - dh = EVP_PKEY_get0_DH(s->s3->tmp.pkey); - if (dh == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + s->s3.tmp.pkey = ssl_generate_pkey(s, pkdhp); + if (s->s3.tmp.pkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } EVP_PKEY_free(pkdh); pkdh = NULL; - DH_get0_pqg(dh, &r[0], NULL, &r[1]); - DH_get0_key(dh, &r[2], NULL); - } else -#endif -#ifndef OPENSSL_NO_EC - if (type & (SSL_kECDHE | SSL_kECDHEPSK)) { + /* These BIGNUMs need to be freed when we're finished */ + freer = 1; + if (!EVP_PKEY_get_bn_param(s->s3.tmp.pkey, OSSL_PKEY_PARAM_FFC_P, + &r[0]) + || !EVP_PKEY_get_bn_param(s->s3.tmp.pkey, OSSL_PKEY_PARAM_FFC_G, + &r[1]) + || !EVP_PKEY_get_bn_param(s->s3.tmp.pkey, + OSSL_PKEY_PARAM_PUB_KEY, &r[2])) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } else if (type & (SSL_kECDHE | SSL_kECDHEPSK)) { - if (s->s3->tmp.pkey != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + if (s->s3.tmp.pkey != NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -2611,23 +2520,23 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) curve_id = tls1_shared_group(s, -2); if (curve_id == 0) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); goto err; } - s->s3->tmp.pkey = ssl_generate_pkey_group(s, curve_id); + /* Cache the group used in the SSL_SESSION */ + s->session->kex_group = curve_id; /* Generate a new key for this curve */ - if (s->s3->tmp.pkey == NULL) { + s->s3.tmp.pkey = ssl_generate_pkey_group(s, curve_id); + if (s->s3.tmp.pkey == NULL) { /* SSLfatal() already called */ goto err; } /* Encode the public key. */ - encodedlen = EVP_PKEY_get1_tls_encodedpoint(s->s3->tmp.pkey, - &encodedPoint); + encodedlen = EVP_PKEY_get1_encoded_public_key(s->s3.tmp.pkey, + &encodedPoint); if (encodedlen == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EC_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); goto err; } @@ -2640,15 +2549,12 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) r[2] = NULL; r[3] = NULL; } else -#endif /* !OPENSSL_NO_EC */ #ifndef OPENSSL_NO_SRP if (type & SSL_kSRP) { if ((s->srp_ctx.N == NULL) || (s->srp_ctx.g == NULL) || (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_SRP_PARAM); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_SRP_PARAM); goto err; } r[0] = s->srp_ctx.N; @@ -2658,18 +2564,15 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) } else #endif { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto err; } - if (((s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) != 0) - || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) != 0) { + if (((s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) != 0) + || ((s->s3.tmp.new_cipher->algorithm_mkey & SSL_PSK)) != 0) { lu = NULL; } else if (lu == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -2685,9 +2588,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) if (len > PSK_MAX_IDENTITY_LEN || !WPACKET_sub_memcpy_u16(pkt, s->cert->psk_identity_hint, len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } @@ -2705,13 +2606,10 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) res = WPACKET_start_sub_packet_u16(pkt); if (!res) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } -#ifndef OPENSSL_NO_DH /*- * for interoperability with some versions of the Microsoft TLS * stack, we need to zero pad the DHE pub key to the same length @@ -2722,27 +2620,22 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) if (len > 0) { if (!WPACKET_allocate_bytes(pkt, len, &binval)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } memset(binval, 0, len); } } -#endif + if (!WPACKET_allocate_bytes(pkt, BN_num_bytes(r[i]), &binval) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } BN_bn2bin(r[i], binval); } -#ifndef OPENSSL_NO_EC if (type & (SSL_kECDHE | SSL_kECDHEPSK)) { /* * We only support named (not generic) curves. In this situation, the @@ -2754,65 +2647,47 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) || !WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_put_bytes_u8(pkt, curve_id) || !WPACKET_sub_memcpy_u8(pkt, encodedPoint, encodedlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } OPENSSL_free(encodedPoint); encodedPoint = NULL; } -#endif /* not anonymous */ if (lu != NULL) { - EVP_PKEY *pkey = s->s3->tmp.cert->privatekey; + EVP_PKEY *pkey = s->s3.tmp.cert->privatekey; const EVP_MD *md; unsigned char *sigbytes1, *sigbytes2, *tbs; - size_t siglen, tbslen; - int rv; + size_t siglen = 0, tbslen; - if (pkey == NULL || !tls1_lookup_md(lu, &md)) { + if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) { /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* Get length of the parameters we have written above */ if (!WPACKET_get_length(pkt, ¶mlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* send signature algorithm */ if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - /* - * Create the signature. We don't know the actual length of the sig - * until after we've created it, so we reserve enough bytes for it - * up front, and then properly allocate them in the WPACKET - * afterwards. - */ - siglen = EVP_PKEY_size(pkey); - if (!WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sigbytes1) - || EVP_DigestSignInit(md_ctx, &pctx, md, NULL, pkey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + + if (EVP_DigestSignInit_ex(md_ctx, &pctx, + md == NULL ? NULL : EVP_MD_get0_name(md), + s->ctx->libctx, s->ctx->propq, pkey, + NULL) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (lu->sig == EVP_PKEY_RSA_PSS) { if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } } @@ -2823,28 +2698,31 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } - rv = EVP_DigestSign(md_ctx, sigbytes1, &siglen, tbs, tbslen); - OPENSSL_free(tbs); - if (rv <= 0 || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) - || sigbytes1 != sigbytes2) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + + if (EVP_DigestSign(md_ctx, NULL, &siglen, tbs, tbslen) <=0 + || !WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sigbytes1) + || EVP_DigestSign(md_ctx, sigbytes1, &siglen, tbs, tbslen) <= 0 + || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) + || sigbytes1 != sigbytes2) { + OPENSSL_free(tbs); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } + OPENSSL_free(tbs); } - EVP_MD_CTX_free(md_ctx); - return 1; + ret = 1; err: -#ifndef OPENSSL_NO_DH EVP_PKEY_free(pkdh); -#endif -#ifndef OPENSSL_NO_EC OPENSSL_free(encodedPoint); -#endif EVP_MD_CTX_free(md_ctx); - return 0; + if (freer) { + BN_free(r[0]); + BN_free(r[1]); + BN_free(r[2]); + BN_free(r[3]); + } + return ret; } int tls_construct_certificate_request(SSL *s, WPACKET *pkt) @@ -2856,17 +2734,14 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) s->pha_context_len = 32; if ((s->pha_context = OPENSSL_malloc(s->pha_context_len)) == NULL) { s->pha_context_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (RAND_bytes(s->pha_context, s->pha_context_len) <= 0 + if (RAND_bytes_ex(s->ctx->libctx, s->pha_context, + s->pha_context_len, 0) <= 0 || !WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* reset the handshake hash back to just after the ClientFinished */ @@ -2876,9 +2751,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) } } else { if (!WPACKET_put_bytes_u8(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -2895,8 +2768,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) /* get the list of acceptable cert types */ if (!WPACKET_start_sub_packet_u8(pkt) || !ssl3_get_req_cert_type(s, pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -2908,9 +2780,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH) || !tls12_copy_sigalgs(s, pkt, psigs, nl) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -2922,7 +2792,7 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt) done: s->certreqs_sent++; - s->s3->tmp.cert_request = 1; + s->s3.tmp.cert_request = 1; return 1; } @@ -2934,24 +2804,20 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt) PACKET psk_identity; if (!PACKET_get_length_prefixed_2(pkt, &psk_identity)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } if (PACKET_remaining(&psk_identity) > PSK_MAX_IDENTITY_LEN) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - SSL_R_DATA_LENGTH_TOO_LONG); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } if (s->psk_server_callback == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - SSL_R_PSK_NO_SERVER_CB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PSK_NO_SERVER_CB); return 0; } if (!PACKET_strndup(&psk_identity, &s->session->psk_identity)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -2959,57 +2825,49 @@ static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt) psk, sizeof(psk)); if (psklen > PSK_MAX_PSK_LEN) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } else if (psklen == 0) { /* * PSK related to the given identity not found */ - SSLfatal(s, SSL_AD_UNKNOWN_PSK_IDENTITY, - SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - SSL_R_PSK_IDENTITY_NOT_FOUND); + SSLfatal(s, SSL_AD_UNKNOWN_PSK_IDENTITY, SSL_R_PSK_IDENTITY_NOT_FOUND); return 0; } - OPENSSL_free(s->s3->tmp.psk); - s->s3->tmp.psk = OPENSSL_memdup(psk, psklen); + OPENSSL_free(s->s3.tmp.psk); + s->s3.tmp.psk = OPENSSL_memdup(psk, psklen); OPENSSL_cleanse(psk, psklen); - if (s->s3->tmp.psk == NULL) { - s->s3->tmp.psklen = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_MALLOC_FAILURE); + if (s->s3.tmp.psk == NULL) { + s->s3.tmp.psklen = 0; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - s->s3->tmp.psklen = psklen; + s->s3.tmp.psklen = psklen; return 1; #else /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } static int tls_process_cke_rsa(SSL *s, PACKET *pkt) { -#ifndef OPENSSL_NO_RSA - unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - int decrypt_len; - unsigned char decrypt_good, version_good; - size_t j, padding_len; + size_t outlen; PACKET enc_premaster; - RSA *rsa = NULL; + EVP_PKEY *rsa = NULL; unsigned char *rsa_decrypt = NULL; int ret = 0; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[3], *p = params; - rsa = EVP_PKEY_get0_RSA(s->cert->pkeys[SSL_PKEY_RSA].privatekey); + rsa = s->cert->pkeys[SSL_PKEY_RSA].privatekey; if (rsa == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - SSL_R_MISSING_RSA_CERTIFICATE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_RSA_CERTIFICATE); return 0; } @@ -3019,136 +2877,70 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt) } else { if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } } - /* - * We want to be sure that the plaintext buffer size makes it safe to - * iterate over the entire size of a premaster secret - * (SSL_MAX_MASTER_KEY_LENGTH). Reject overly short RSA keys because - * their ciphertext cannot accommodate a premaster secret anyway. - */ - if (RSA_size(rsa) < SSL_MAX_MASTER_KEY_LENGTH) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - rsa_decrypt = OPENSSL_malloc(RSA_size(rsa)); + outlen = SSL_MAX_MASTER_KEY_LENGTH; + rsa_decrypt = OPENSSL_malloc(outlen); if (rsa_decrypt == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - /* - * We must not leak whether a decryption failure occurs because of - * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, - * section 7.4.7.1). The code follows that advice of the TLS RFC and - * generates a random premaster secret for the case that the decrypt - * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 - */ - - if (RAND_priv_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - ERR_R_INTERNAL_ERROR); + ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, rsa, s->ctx->propq); + if (ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } /* - * Decrypt with no padding. PKCS#1 padding will be removed as part of - * the timing-sensitive code below. + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). We use the special padding type + * RSA_PKCS1_WITH_TLS_PADDING to do that. It will automaticaly decrypt the + * RSA, check the padding and check that the client version is as expected + * in the premaster secret. If any of that fails then the function appears + * to return successfully but with a random result. The call below could + * still fail if the input is publicly invalid. + * See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* TODO(size_t): Convert this function */ - decrypt_len = (int)RSA_private_decrypt((int)PACKET_remaining(&enc_premaster), - PACKET_data(&enc_premaster), - rsa_decrypt, rsa, RSA_NO_PADDING); - if (decrypt_len < 0) { - SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - ERR_R_INTERNAL_ERROR); + if (EVP_PKEY_decrypt_init(ctx) <= 0 + || EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_WITH_TLS_PADDING) <= 0) { + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DECRYPTION_FAILED); goto err; } - /* Check the padding. See RFC 3447, section 7.2.2. */ + *p++ = OSSL_PARAM_construct_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, + (unsigned int *)&s->client_version); + if ((s->options & SSL_OP_TLS_ROLLBACK_BUG) != 0) + *p++ = OSSL_PARAM_construct_uint( + OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, + (unsigned int *)&s->version); + *p++ = OSSL_PARAM_construct_end(); - /* - * The smallest padded premaster is 11 bytes of overhead. Small keys - * are publicly invalid, so this may return immediately. This ensures - * PS is at least 8 bytes. - */ - if (decrypt_len < 11 + SSL_MAX_MASTER_KEY_LENGTH) { - SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - SSL_R_DECRYPTION_FAILED); + if (!EVP_PKEY_CTX_set_params(ctx, params) + || EVP_PKEY_decrypt(ctx, rsa_decrypt, &outlen, + PACKET_data(&enc_premaster), + PACKET_remaining(&enc_premaster)) <= 0) { + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DECRYPTION_FAILED); goto err; } - padding_len = decrypt_len - SSL_MAX_MASTER_KEY_LENGTH; - decrypt_good = constant_time_eq_int_8(rsa_decrypt[0], 0) & - constant_time_eq_int_8(rsa_decrypt[1], 2); - for (j = 2; j < padding_len - 1; j++) { - decrypt_good &= ~constant_time_is_zero_8(rsa_decrypt[j]); - } - decrypt_good &= constant_time_is_zero_8(rsa_decrypt[padding_len - 1]); - - /* - * If the version in the decrypted pre-master secret is correct then - * version_good will be 0xff, otherwise it'll be zero. The - * Klima-Pokorny-Rosa extension of Bleichenbacher's attack - * (http://eprint.iacr.org/2003/052/) exploits the version number - * check as a "bad version oracle". Thus version checks are done in - * constant time and are treated like any other decryption error. - */ - version_good = - constant_time_eq_8(rsa_decrypt[padding_len], - (unsigned)(s->client_version >> 8)); - version_good &= - constant_time_eq_8(rsa_decrypt[padding_len + 1], - (unsigned)(s->client_version & 0xff)); - - /* - * The premaster secret must contain the same version number as the - * ClientHello to detect version rollback attacks (strangely, the - * protocol does not offer such protection for DH ciphersuites). - * However, buggy clients exist that send the negotiated protocol - * version instead if the server does not support the requested - * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such - * clients. - */ - if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { - unsigned char workaround_good; - workaround_good = constant_time_eq_8(rsa_decrypt[padding_len], - (unsigned)(s->version >> 8)); - workaround_good &= - constant_time_eq_8(rsa_decrypt[padding_len + 1], - (unsigned)(s->version & 0xff)); - version_good |= workaround_good; - } - - /* - * Both decryption and version must be good for decrypt_good to - * remain non-zero (0xff). - */ - decrypt_good &= version_good; - /* - * Now copy rand_premaster_secret over from p using - * decrypt_good_mask. If decryption failed, then p does not - * contain valid plaintext, however, a check above guarantees - * it is still sufficiently large to read from. + * This test should never fail (otherwise we should have failed above) but + * we double check anyway. */ - for (j = 0; j < sizeof(rand_premaster_secret); j++) { - rsa_decrypt[padding_len + j] = - constant_time_select_8(decrypt_good, - rsa_decrypt[padding_len + j], - rand_premaster_secret[j]); + if (outlen != SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_cleanse(rsa_decrypt, SSL_MAX_MASTER_KEY_LENGTH); + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DECRYPTION_FAILED); + goto err; } - if (!ssl_generate_master_secret(s, rsa_decrypt + padding_len, - sizeof(rand_premaster_secret), 0)) { + /* Also cleanses rsa_decrypt (on success or failure) */ + if (!ssl_generate_master_secret(s, rsa_decrypt, + SSL_MAX_MASTER_KEY_LENGTH, 0)) { /* SSLfatal() already called */ goto err; } @@ -3156,62 +2948,45 @@ static int tls_process_cke_rsa(SSL *s, PACKET *pkt) ret = 1; err: OPENSSL_free(rsa_decrypt); + EVP_PKEY_CTX_free(ctx); return ret; -#else - /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_RSA, - ERR_R_INTERNAL_ERROR); - return 0; -#endif } static int tls_process_cke_dhe(SSL *s, PACKET *pkt) { -#ifndef OPENSSL_NO_DH EVP_PKEY *skey = NULL; - DH *cdh; unsigned int i; - BIGNUM *pub_key; const unsigned char *data; EVP_PKEY *ckey = NULL; int ret = 0; if (!PACKET_get_net_2(pkt, &i) || PACKET_remaining(pkt) != i) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); goto err; } - skey = s->s3->tmp.pkey; + skey = s->s3.tmp.pkey; if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - SSL_R_MISSING_TMP_DH_KEY); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_TMP_DH_KEY); goto err; } if (PACKET_remaining(pkt) == 0L) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - SSL_R_MISSING_TMP_DH_KEY); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_MISSING_TMP_DH_KEY); goto err; } if (!PACKET_get_bytes(pkt, &data, i)) { /* We already checked we have enough data */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } ckey = EVP_PKEY_new(); if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - SSL_R_BN_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COPY_PARAMETERS_FAILED); goto err; } - cdh = EVP_PKEY_get0_DH(ckey); - pub_key = BN_bin2bn(data, i, NULL); - if (pub_key == NULL || cdh == NULL || !DH_set0_key(cdh, pub_key, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - ERR_R_INTERNAL_ERROR); - BN_free(pub_key); + if (!EVP_PKEY_set1_encoded_public_key(ckey, data, i)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3221,30 +2996,22 @@ static int tls_process_cke_dhe(SSL *s, PACKET *pkt) } ret = 1; - EVP_PKEY_free(s->s3->tmp.pkey); - s->s3->tmp.pkey = NULL; + EVP_PKEY_free(s->s3.tmp.pkey); + s->s3.tmp.pkey = NULL; err: EVP_PKEY_free(ckey); return ret; -#else - /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_DHE, - ERR_R_INTERNAL_ERROR); - return 0; -#endif } static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) { -#ifndef OPENSSL_NO_EC - EVP_PKEY *skey = s->s3->tmp.pkey; + EVP_PKEY *skey = s->s3.tmp.pkey; EVP_PKEY *ckey = NULL; int ret = 0; if (PACKET_remaining(pkt) == 0L) { /* We don't support ECDH client auth */ - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PROCESS_CKE_ECDHE, - SSL_R_MISSING_TMP_ECDH_KEY); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_MISSING_TMP_ECDH_KEY); goto err; } else { unsigned int i; @@ -3258,25 +3025,22 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) /* Get encoded point length */ if (!PACKET_get_1(pkt, &i) || !PACKET_get_bytes(pkt, &data, i) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, - SSL_R_MISSING_TMP_ECDH_KEY); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_TMP_ECDH_KEY); goto err; } ckey = EVP_PKEY_new(); if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COPY_PARAMETERS_FAILED); goto err; } - if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, - ERR_R_EC_LIB); + + if (EVP_PKEY_set1_encoded_public_key(ckey, data, i) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); goto err; } } @@ -3287,18 +3051,12 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) } ret = 1; - EVP_PKEY_free(s->s3->tmp.pkey); - s->s3->tmp.pkey = NULL; + EVP_PKEY_free(s->s3.tmp.pkey); + s->s3.tmp.pkey = NULL; err: EVP_PKEY_free(ckey); return ret; -#else - /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, - ERR_R_INTERNAL_ERROR); - return 0; -#endif } static int tls_process_cke_srp(SSL *s, PACKET *pkt) @@ -3309,25 +3067,21 @@ static int tls_process_cke_srp(SSL *s, PACKET *pkt) if (!PACKET_get_net_2(pkt, &i) || !PACKET_get_bytes(pkt, &data, i)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_SRP, - SSL_R_BAD_SRP_A_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRP_A_LENGTH); return 0; } if ((s->srp_ctx.A = BN_bin2bn(data, i, NULL)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_SRP, - ERR_R_BN_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB); return 0; } if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 || BN_is_zero(s->srp_ctx.A)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_CKE_SRP, - SSL_R_BAD_SRP_PARAMETERS); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_SRP_PARAMETERS); return 0; } OPENSSL_free(s->session->srp_username); s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login); if (s->session->srp_username == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_SRP, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } @@ -3339,8 +3093,7 @@ static int tls_process_cke_srp(SSL *s, PACKET *pkt) return 1; #else /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_SRP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } @@ -3359,7 +3112,7 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) int ret = 0; /* Get our certificate private key */ - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_a = s->s3.tmp.new_cipher->algorithm_auth; if (alg_a & SSL_aGOST12) { /* * New GOST ciphersuites have SSL_aGOST01 bit too @@ -3375,15 +3128,13 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; } - pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pk, s->ctx->propq); if (pkey_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* @@ -3405,20 +3156,17 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) if (pKX == NULL || pKX->kxBlob == NULL || ASN1_TYPE_get(pKX->kxBlob) != V_ASN1_SEQUENCE) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - SSL_R_DECRYPTION_FAILED); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_DECRYPTION_FAILED); goto err; } if (!PACKET_forward(pkt, ptr - PACKET_data(pkt))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - SSL_R_DECRYPTION_FAILED); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_DECRYPTION_FAILED); goto err; } if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - SSL_R_DECRYPTION_FAILED); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_DECRYPTION_FAILED); goto err; } @@ -3427,8 +3175,7 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - SSL_R_DECRYPTION_FAILED); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_DECRYPTION_FAILED); goto err; } /* Generate master secret */ @@ -3449,8 +3196,85 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) return ret; #else /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; +#endif +} + +static int tls_process_cke_gost18(SSL *s, PACKET *pkt) +{ +#ifndef OPENSSL_NO_GOST + unsigned char rnd_dgst[32]; + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pk = NULL; + unsigned char premaster_secret[32]; + const unsigned char *start = NULL; + size_t outlen = 32, inlen = 0; + int ret = 0; + int cipher_nid = ossl_gost18_cke_cipher_nid(s); + + if (cipher_nid == NID_undef) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (ossl_gost_ukm(s, rnd_dgst) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Get our certificate private key */ + pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey != NULL ? + s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey : + s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey; + if (pk == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_STATE); + goto err; + } + + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pk, s->ctx->propq); + if (pkey_ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code depending on size */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); + goto err; + } + + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); + goto err; + } + inlen = PACKET_remaining(pkt); + start = PACKET_data(pkt); + + if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_DECRYPTION_FAILED); + goto err; + } + /* Generate master secret */ + if (!ssl_generate_master_secret(s, premaster_secret, + sizeof(premaster_secret), 0)) { + /* SSLfatal() already called */ + goto err; + } + ret = 1; + + err: + EVP_PKEY_CTX_free(pkey_ctx); + return ret; +#else + /* Should never happen */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } @@ -3459,7 +3283,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) { unsigned long alg_k; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_k = s->s3.tmp.new_cipher->algorithm_mkey; /* For PSK parse and retrieve identity, obtain PSK key */ if ((alg_k & SSL_PSK) && !tls_process_cke_psk_preamble(s, pkt)) { @@ -3470,9 +3294,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) if (alg_k & SSL_kPSK) { /* Identity extracted earlier: should be nothing left */ if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } /* PSK handled by ssl_generate_master_secret */ @@ -3505,19 +3327,22 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) /* SSLfatal() already called */ goto err; } + } else if (alg_k & SSL_kGOST18) { + if (!tls_process_cke_gost18(s, pkt)) { + /* SSLfatal() already called */ + goto err; + } } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, - SSL_R_UNKNOWN_CIPHER_TYPE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNKNOWN_CIPHER_TYPE); goto err; } return MSG_PROCESS_CONTINUE_PROCESSING; err: #ifndef OPENSSL_NO_PSK - OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen); - s->s3->tmp.psk = NULL; - s->s3->tmp.psklen = 0; + OPENSSL_clear_free(s->s3.tmp.psk, s->s3.tmp.psklen); + s->s3.tmp.psk = NULL; + s->s3.tmp.psklen = 0; #endif return MSG_PROCESS_ERROR; } @@ -3546,9 +3371,7 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } @@ -3569,10 +3392,8 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst) } return WORK_FINISHED_CONTINUE; } else { - if (!s->s3->handshake_buffer) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + if (!s->s3.handshake_buffer) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } /* @@ -3608,8 +3429,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) s->statem.enc_read_state = ENC_READ_STATE_VALID; if ((sk = sk_X509_new_null()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -3617,38 +3437,36 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) || (s->pha_context == NULL && PACKET_remaining(&context) != 0) || (s->pha_context != NULL && !PACKET_equal(&context, s->pha_context, s->pha_context_len)))) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - SSL_R_INVALID_CONTEXT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); goto err; } if (!PACKET_get_length_prefixed_3(pkt, &spkt) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } for (chainidx = 0; PACKET_remaining(&spkt) > 0; chainidx++) { if (!PACKET_get_net_3(&spkt, &l) || !PACKET_get_bytes(&spkt, &certbytes, l)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_CERT_LENGTH_MISMATCH); goto err; } certstart = certbytes; - x = d2i_X509(NULL, (const unsigned char **)&certbytes, l); + x = X509_new_ex(s->ctx->libctx, s->ctx->propq); if (x == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_MALLOC_FAILURE); goto err; } + if (d2i_X509(&x, (const unsigned char **)&certbytes, l) == NULL) { + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_ASN1_LIB); + goto err; + } + if (certbytes != (certstart + l)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_CERT_LENGTH_MISMATCH); goto err; } @@ -3657,9 +3475,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) PACKET extensions; if (!PACKET_get_length_prefixed_2(&spkt, &extensions)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); goto err; } if (!tls_collect_extensions(s, &extensions, @@ -3675,9 +3491,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) } if (!sk_X509_push(sk, x)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } x = NULL; @@ -3687,7 +3501,6 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) /* TLS does not mind 0 certs returned */ if (s->version == SSL3_VERSION) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_NO_CERTIFICATES_RETURNED); goto err; } @@ -3695,12 +3508,11 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) else if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { SSLfatal(s, SSL_AD_CERTIFICATE_REQUIRED, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); goto err; } /* No client certificate so digest cached records */ - if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, 0)) { + if (s->s3.handshake_buffer && !ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ goto err; } @@ -3709,19 +3521,12 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) i = ssl_verify_cert_chain(s, sk); if (i <= 0) { SSLfatal(s, ssl_x509err2alert(s->verify_result), - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED); goto err; } - if (i > 1) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, i); - goto err; - } pkey = X509_get0_pubkey(sk_X509_value(sk, 0)); if (pkey == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_UNKNOWN_CERTIFICATE_TYPE); goto err; } @@ -3737,9 +3542,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) if (s->post_handshake_auth == SSL_PHA_REQUESTED) { if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -3792,11 +3595,10 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) int tls_construct_server_certificate(SSL *s, WPACKET *pkt) { - CERT_PKEY *cpk = s->s3->tmp.cert; + CERT_PKEY *cpk = s->s3.tmp.cert; if (cpk == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -3805,8 +3607,7 @@ int tls_construct_server_certificate(SSL *s, WPACKET *pkt) * for the server Certificate message */ if (SSL_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!ssl3_output_cert_chain(s, pkt, cpk)) { @@ -3838,45 +3639,46 @@ static int create_ticket_prequel(SSL *s, WPACKET *pkt, uint32_t age_add, timeout = 0; if (!WPACKET_put_bytes_u32(pkt, timeout)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CREATE_TICKET_PREQUEL, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (SSL_IS_TLS13(s)) { if (!WPACKET_put_bytes_u32(pkt, age_add) || !WPACKET_sub_memcpy_u8(pkt, tick_nonce, TICKET_NONCE_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CREATE_TICKET_PREQUEL, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } /* Start the sub-packet for the actual ticket data */ if (!WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CREATE_TICKET_PREQUEL, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } return 1; } +/* + * Returns 1 on success, 0 to abort construction of the ticket (non-fatal), or + * -1 on fatal error + */ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, unsigned char *tick_nonce) { unsigned char *senc = NULL; EVP_CIPHER_CTX *ctx = NULL; - HMAC_CTX *hctx = NULL; + SSL_HMAC *hctx = NULL; unsigned char *p, *encdata1, *encdata2, *macdata1, *macdata2; const unsigned char *const_p; int len, slen_full, slen, lenfinal; SSL_SESSION *sess; - unsigned int hlen; + size_t hlen; SSL_CTX *tctx = s->session_ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char key_name[TLSEXT_KEYNAME_LENGTH]; - int iv_len, ok = 0; + int iv_len, ok = -1; size_t macoffset, macendoffset; /* get session encoding length */ @@ -3886,29 +3688,25 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, * long */ if (slen_full == 0 || slen_full > 0xFF00) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } senc = OPENSSL_malloc(slen_full); if (senc == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } ctx = EVP_CIPHER_CTX_new(); - hctx = HMAC_CTX_new(); + hctx = ssl_hmac_new(tctx); if (ctx == NULL || hctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } p = senc; if (!i2d_SSL_SESSION(s->session, &p)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3918,23 +3716,20 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, const_p = senc; sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); if (sess == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } slen = i2d_SSL_SESSION(sess, NULL); if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(sess); goto err; } p = senc; if (!i2d_SSL_SESSION(sess, &p)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(sess); goto err; } @@ -3944,46 +3739,78 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, * Initialize HMAC and cipher contexts. If callback present it does * all the work otherwise use generated values from parent ctx. */ - if (tctx->ext.ticket_key_cb) { - /* if 0 is returned, write an empty ticket */ - int ret = tctx->ext.ticket_key_cb(s, key_name, iv, ctx, - hctx, 1); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (tctx->ext.ticket_key_evp_cb != NULL || tctx->ext.ticket_key_cb != NULL) +#else + if (tctx->ext.ticket_key_evp_cb != NULL) +#endif + { + int ret = 0; - if (ret == 0) { + if (tctx->ext.ticket_key_evp_cb != NULL) + ret = tctx->ext.ticket_key_evp_cb(s, key_name, iv, ctx, + ssl_hmac_get0_EVP_MAC_CTX(hctx), + 1); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + else if (tctx->ext.ticket_key_cb != NULL) + /* if 0 is returned, write an empty ticket */ + ret = tctx->ext.ticket_key_cb(s, key_name, iv, ctx, + ssl_hmac_get0_HMAC_CTX(hctx), 1); +#endif + if (ret == 0) { + /* + * In TLSv1.2 we construct a 0 length ticket. In TLSv1.3 a 0 + * length ticket is not allowed so we abort construction of the + * ticket + */ + if (SSL_IS_TLS13(s)) { + ok = 0; + goto err; + } /* Put timeout and length */ if (!WPACKET_put_bytes_u32(pkt, 0) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } OPENSSL_free(senc); EVP_CIPHER_CTX_free(ctx); - HMAC_CTX_free(hctx); + ssl_hmac_free(hctx); return 1; } if (ret < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - SSL_R_CALLBACK_FAILED); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED); + goto err; + } + iv_len = EVP_CIPHER_CTX_get_iv_length(ctx); + if (iv_len < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - iv_len = EVP_CIPHER_CTX_iv_length(ctx); } else { - const EVP_CIPHER *cipher = EVP_aes_256_cbc(); + EVP_CIPHER *cipher = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC", + s->ctx->propq); - iv_len = EVP_CIPHER_iv_length(cipher); - if (RAND_bytes(iv, iv_len) <= 0 + if (cipher == NULL) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); + goto err; + } + + iv_len = EVP_CIPHER_get_iv_length(cipher); + if (iv_len < 0 + || RAND_bytes_ex(s->ctx->libctx, iv, iv_len, 0) <= 0 || !EVP_EncryptInit_ex(ctx, cipher, NULL, tctx->ext.secure->tick_aes_key, iv) - || !HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key, - sizeof(tctx->ext.secure->tick_hmac_key), - EVP_sha256(), NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + || !ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key, + sizeof(tctx->ext.secure->tick_hmac_key), + "SHA256")) { + EVP_CIPHER_free(cipher); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } + EVP_CIPHER_free(cipher); memcpy(key_name, tctx->ext.tick_key_name, sizeof(tctx->ext.tick_key_name)); } @@ -4009,23 +3836,21 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, || encdata1 + len != encdata2 || len + lenfinal > slen + EVP_MAX_BLOCK_LENGTH || !WPACKET_get_total_written(pkt, &macendoffset) - || !HMAC_Update(hctx, - (unsigned char *)s->init_buf->data + macoffset, - macendoffset - macoffset) + || !ssl_hmac_update(hctx, + (unsigned char *)s->init_buf->data + macoffset, + macendoffset - macoffset) || !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &macdata1) - || !HMAC_Final(hctx, macdata1, &hlen) + || !ssl_hmac_final(hctx, macdata1, &hlen, EVP_MAX_MD_SIZE) || hlen > EVP_MAX_MD_SIZE || !WPACKET_allocate_bytes(pkt, hlen, &macdata2) || macdata1 != macdata2) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* Close the sub-packet created by create_ticket_prequel() */ if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -4033,7 +3858,7 @@ static int construct_stateless_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, err: OPENSSL_free(senc); EVP_CIPHER_CTX_free(ctx); - HMAC_CTX_free(hctx); + ssl_hmac_free(hctx); return ok; } @@ -4048,14 +3873,27 @@ static int construct_stateful_ticket(SSL *s, WPACKET *pkt, uint32_t age_add, if (!WPACKET_memcpy(pkt, s->session->session_id, s->session->session_id_length) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATEFUL_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } return 1; } +static void tls_update_ticket_counts(SSL *s) +{ + /* + * Increment both |sent_tickets| and |next_ticket_nonce|. |sent_tickets| + * gets reset to 0 if we send more tickets following a post-handshake + * auth, but |next_ticket_nonce| does not. If we're sending extra + * tickets, decrement the count of pending extra tickets. + */ + s->sent_tickets++; + s->next_ticket_nonce++; + if (s->ext.extra_tickets_expected > 0) + s->ext.extra_tickets_expected--; +} + int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) { SSL_CTX *tctx = s->session_ctx; @@ -4064,6 +3902,7 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) unsigned char age_add_c[sizeof(uint32_t)]; uint32_t age_add; } age_add_u; + int ret = 0; age_add_u.age_add = 0; @@ -4072,13 +3911,11 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) uint64_t nonce; static const unsigned char nonce_label[] = "resumption"; const EVP_MD *md = ssl_handshake_md(s); - int hashleni = EVP_MD_size(md); + int hashleni = EVP_MD_get_size(md); /* Ensure cast to size_t is safe */ if (!ossl_assert(hashleni >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } hashlen = (size_t)hashleni; @@ -4104,10 +3941,9 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } - if (RAND_bytes(age_add_u.age_add_c, sizeof(age_add_u)) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, - ERR_R_INTERNAL_ERROR); + if (RAND_bytes_ex(s->ctx->libctx, age_add_u.age_add_c, + sizeof(age_add_u), 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } s->session->ext.tick_age_add = age_add_u.age_add; @@ -4130,28 +3966,25 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) } s->session->master_key_length = hashlen; - s->session->time = (long)time(NULL); - if (s->s3->alpn_selected != NULL) { + s->session->time = time(NULL); + ssl_session_calculate_timeout(s->session); + if (s->s3.alpn_selected != NULL) { OPENSSL_free(s->session->ext.alpn_selected); s->session->ext.alpn_selected = - OPENSSL_memdup(s->s3->alpn_selected, s->s3->alpn_selected_len); + OPENSSL_memdup(s->s3.alpn_selected, s->s3.alpn_selected_len); if (s->session->ext.alpn_selected == NULL) { s->session->ext.alpn_selected_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - s->session->ext.alpn_selected_len = s->s3->alpn_selected_len; + s->session->ext.alpn_selected_len = s->s3.alpn_selected_len; } s->session->ext.max_early_data = s->max_early_data; } if (tctx->generate_ticket_cb != NULL && tctx->generate_ticket_cb(s, tctx->ticket_cb_data) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* @@ -4167,10 +4000,20 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } - } else if (!construct_stateless_ticket(s, pkt, age_add_u.age_add, - tick_nonce)) { - /* SSLfatal() already called */ - goto err; + } else { + int tmpret; + + tmpret = construct_stateless_ticket(s, pkt, age_add_u.age_add, + tick_nonce); + if (tmpret != 1) { + if (tmpret == 0) { + ret = 2; /* Non-fatal. Abort construction but continue */ + /* We count this as a success so update the counts anwyay */ + tls_update_ticket_counts(s); + } + /* else SSLfatal() already called */ + goto err; + } } if (SSL_IS_TLS13(s)) { @@ -4180,19 +4023,13 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt) /* SSLfatal() already called */ goto err; } - /* - * Increment both |sent_tickets| and |next_ticket_nonce|. |sent_tickets| - * gets reset to 0 if we send more tickets following a post-handshake - * auth, but |next_ticket_nonce| does not. - */ - s->sent_tickets++; - s->next_ticket_nonce++; + tls_update_ticket_counts(s); ssl_update_cache(s, SSL_SESS_CACHE_SERVER); } - return 1; + ret = 1; err: - return 0; + return ret; } /* @@ -4204,8 +4041,7 @@ int tls_construct_cert_status_body(SSL *s, WPACKET *pkt) if (!WPACKET_put_bytes_u8(pkt, s->ext.status_type) || !WPACKET_sub_memcpy_u24(pkt, s->ext.ocsp.resp, s->ext.ocsp.resp_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -4242,15 +4078,13 @@ MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt) if (!PACKET_get_length_prefixed_1(pkt, &next_proto) || !PACKET_get_length_prefixed_1(pkt, &padding) || PACKET_remaining(pkt) > 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_NEXT_PROTO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } if (!PACKET_memdup(&next_proto, &s->ext.npn, &next_proto_len)) { s->ext.npn_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_NEXT_PROTO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; } @@ -4274,15 +4108,13 @@ static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt) MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt) { if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } if (s->early_data_state != SSL_EARLY_DATA_READING && s->early_data_state != SSL_EARLY_DATA_READ_RETRY) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; } @@ -4291,9 +4123,7 @@ MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt) * a record boundary. */ if (RECORD_LAYER_processed_read_pending(&s->rlayer)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, - SSL_R_NOT_ON_RECORD_BOUNDARY); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); return MSG_PROCESS_ERROR; } |
