diff options
author | Enji Cooper <ngie@FreeBSD.org> | 2023-03-01 04:21:31 +0000 |
---|---|---|
committer | Enji Cooper <ngie@FreeBSD.org> | 2023-03-06 20:41:29 +0000 |
commit | e4520c8bd1d300a7a338d0ed4af171a2d0e583ef (patch) | |
tree | 26fed32699a59a50cfbc90a2eb4dac39b498d9ae /ssl | |
parent | 3c320f4e5ee3d575d48eee7edddbafa059bce3c9 (diff) | |
download | src-e4520c8bd1d300a7a338d0ed4af171a2d0e583ef.tar.gz src-e4520c8bd1d300a7a338d0ed4af171a2d0e583ef.zip |
Diffstat (limited to 'ssl')
61 files changed, 9251 insertions, 8931 deletions
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c index 67097d5cca41..401178f0c2e4 100644 --- a/ssl/bio_ssl.c +++ b/ssl/bio_ssl.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. 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 @@ -58,7 +58,7 @@ static int ssl_new(BIO *bi) BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs)); if (bs == NULL) { - BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); return 0; } BIO_set_init(bi, 0); diff --git a/ssl/build.info b/ssl/build.info index bb2f1deb5300..0851357f81eb 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -1,15 +1,44 @@ LIBS=../libssl + +#Needed for the multiblock code in rec_layer_s3.c +IF[{- !$disabled{asm} -}] + $AESDEF_x86=AES_ASM + $AESDEF_x86_64=AES_ASM + + IF[$AESDEF_{- $target{asm_arch} -}] + $AESDEF=$AESDEF_{- $target{asm_arch} -} + ENDIF +ENDIF + +$KTLSSRC= +IF[{- !$disabled{ktls} -}] + $KTLSSRC=ktls.c +ENDIF + SOURCE[../libssl]=\ - pqueue.c packet.c \ + pqueue.c \ statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c record/rec_layer_s3.c \ statem/statem_lib.c statem/extensions.c statem/extensions_srvr.c \ - statem/extensions_clnt.c statem/extensions_cust.c s3_cbc.c s3_msg.c \ + statem/extensions_clnt.c statem/extensions_cust.c s3_msg.c \ methods.c t1_lib.c t1_enc.c tls13_enc.c \ d1_lib.c record/rec_layer_d1.c d1_msg.c \ statem/statem_dtls.c d1_srtp.c \ ssl_lib.c ssl_cert.c ssl_sess.c \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \ - bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \ + bio_ssl.c ssl_err.c ssl_err_legacy.c tls_srp.c t1_trce.c ssl_utst.c \ record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ - statem/statem.c record/ssl3_record_tls13.c + statem/statem.c record/ssl3_record_tls13.c \ + tls_depr.c $KTLSSRC +# For shared builds we need to include the libcrypto packet.c and sources +# needed in providers (s3_cbc.c and record/tls_pad.c) in libssl as well. +SHARED_SOURCE[../libssl]=record/tls_pad.c ../crypto/packet.c +IF[{- !$disabled{'deprecated-3.0'} -}] + SHARED_SOURCE[../libssl]=s3_cbc.c + SOURCE[../libssl]=ssl_rsa_legacy.c +ENDIF + +DEFINE[../libssl]=$AESDEF + +SOURCE[../providers/libcommon.a]=record/tls_pad.c +SOURCE[../providers/libdefault.a ../providers/libfips.a]=s3_cbc.c diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 05b85c1078c0..95a34093c91b 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -1,7 +1,7 @@ /* * Copyright 2005-2021 The OpenSSL Project Authors. 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 @@ -193,7 +193,7 @@ int dtls1_clear(SSL *s) return 0; if (s->method->version == DTLS_ANY_VERSION) - s->version = DTLS_MAX_VERSION; + s->version = DTLS_MAX_VERSION_INTERNAL; #ifndef OPENSSL_NO_DTLS1_METHOD else if (s->options & SSL_OP_CISCO_ANYCONNECT) s->client_version = s->version = DTLS1_BAD_VER; @@ -352,7 +352,7 @@ static void dtls1_double_timeout(SSL *s) void dtls1_stop_timer(SSL *s) { /* Reset everything */ - memset(&s->d1->timeout, 0, sizeof(s->d1->timeout)); + s->d1->timeout_num_alerts = 0; memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout)); s->d1->timeout_duration_us = 1000000; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, @@ -365,10 +365,10 @@ int dtls1_check_timeout_num(SSL *s) { size_t mtu; - s->d1->timeout.num_alerts++; + s->d1->timeout_num_alerts++; /* Reduce MTU after 2 unsuccessful retransmissions */ - if (s->d1->timeout.num_alerts > 2 + if (s->d1->timeout_num_alerts > 2 && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); @@ -376,10 +376,9 @@ int dtls1_check_timeout_num(SSL *s) s->d1->mtu = mtu; } - if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { + if (s->d1->timeout_num_alerts > DTLS1_TMO_ALERT_COUNT) { /* fail the connection, enough alerts have been sent */ - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_DTLS1_CHECK_TIMEOUT_NUM, - SSL_R_READ_TIMEOUT_EXPIRED); + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_READ_TIMEOUT_EXPIRED); return -1; } @@ -403,11 +402,6 @@ int dtls1_handle_timeout(SSL *s) return -1; } - s->d1->timeout.read_timeouts++; - if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { - s->d1->timeout.read_timeouts = 1; - } - dtls1_start_timer(s); /* Calls SSLfatal() if required */ return dtls1_retransmit_buffered_messages(s); @@ -471,7 +465,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) wbio = SSL_get_wbio(s); if (!rbio || !wbio) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BIO_NOT_SET); + ERR_raise(ERR_LIB_SSL, SSL_R_BIO_NOT_SET); return -1; } @@ -483,12 +477,12 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * SSL_accept) */ if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION); return -1; } if (!ssl3_setup_buffers(s)) { - /* SSLerr already called */ + /* ERR_raise() already called */ return -1; } buf = RECORD_LAYER_get_rbuf(&s->rlayer)->buf; @@ -522,7 +516,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) } if (!PACKET_buf_init(&pkt, buf, n)) { - SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return -1; } @@ -537,7 +531,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* this packet contained a partial record, dump it */ if (n < DTLS1_RT_HEADER_LENGTH) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_RECORD_TOO_SMALL); + ERR_raise(ERR_LIB_SSL, SSL_R_RECORD_TOO_SMALL); goto end; } @@ -548,12 +542,12 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* Get the record header */ if (!PACKET_get_1(&pkt, &rectype) || !PACKET_get_1(&pkt, &versmajor)) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } if (rectype != SSL3_RT_HANDSHAKE) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); + ERR_raise(ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE); goto end; } @@ -562,7 +556,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * the same. */ if (versmajor != DTLS1_VERSION_MAJOR) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); goto end; } @@ -570,7 +564,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* Save the sequence number: 64 bits, with top 2 bytes = epoch */ || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE) || !PACKET_get_length_prefixed_2(&pkt, &msgpkt)) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } reclen = PACKET_remaining(&msgpkt); @@ -581,7 +575,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) /* This is an initial ClientHello so the epoch has to be 0 */ if (seq[0] != 0 || seq[1] != 0) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); + ERR_raise(ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE); goto end; } @@ -596,18 +590,18 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) || !PACKET_get_net_3_len(&msgpkt, &fraglen) || !PACKET_get_sub_packet(&msgpkt, &msgpayload, fraglen) || PACKET_remaining(&msgpkt) != 0) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } if (msgtype != SSL3_MT_CLIENT_HELLO) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); + ERR_raise(ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE); goto end; } /* Message sequence number can only be 0 or 1 */ if (msgseq > 2) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SEQUENCE_NUMBER); goto end; } @@ -620,7 +614,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) */ if (fragoff != 0 || fraglen > msglen) { /* Non initial ClientHello fragment (or bad fragment) */ - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO); + ERR_raise(ERR_LIB_SSL, SSL_R_FRAGMENTED_CLIENT_HELLO); goto end; } @@ -630,7 +624,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) s->msg_callback_arg); if (!PACKET_get_net_2(&msgpayload, &clientvers)) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } @@ -639,7 +633,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) */ if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) && s->method->version != DTLS_ANY_VERSION) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_WRONG_VERSION_NUMBER); + ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_VERSION_NUMBER); goto end; } @@ -650,7 +644,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * Could be malformed or the cookie does not fit within the initial * ClientHello fragment. Either way we can't handle it. */ - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH); goto end; } @@ -665,7 +659,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) * We have a cookie, so lets check it. */ if (s->ctx->app_verify_cookie_cb == NULL) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_VERIFY_COOKIE_CALLBACK); /* This is fatal */ return -1; } @@ -697,7 +691,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 || cookielen > 255) { - SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); + ERR_raise(ERR_LIB_SSL, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); /* This is fatal */ return -1; } @@ -760,7 +754,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) || !WPACKET_close(&wpkt) || !WPACKET_get_total_written(&wpkt, &wreclen) || !WPACKET_finish(&wpkt)) { - SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); WPACKET_cleanup(&wpkt); /* This is fatal */ return -1; @@ -782,7 +776,7 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); if ((tmpclient = BIO_ADDR_new()) == NULL) { - SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto end; } @@ -797,7 +791,6 @@ int DTLSv1_listen(SSL *s, BIO_ADDR *client) BIO_ADDR_free(tmpclient); tmpclient = NULL; - /* TODO(size_t): convert this call */ if (BIO_write(wbio, wbuf, wreclen) < (int)wreclen) { if (BIO_should_retry(wbio)) { /* diff --git a/ssl/d1_msg.c b/ssl/d1_msg.c index 8a31064ae13f..10438a395545 100644 --- a/ssl/d1_msg.c +++ b/ssl/d1_msg.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2020 The OpenSSL Project Authors. 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 @@ -19,14 +19,13 @@ int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, size_t len, if (i < 0) return i; if (i == 0) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_HANDSHAKE_FAILURE); return -1; } } if (len > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); + ERR_raise(ERR_LIB_SSL, SSL_R_DTLS_MESSAGE_TOO_BIG); return -1; } @@ -41,21 +40,21 @@ int dtls1_dispatch_alert(SSL *s) unsigned char *ptr = &buf[0]; size_t written; - s->s3->alert_dispatch = 0; + s->s3.alert_dispatch = 0; memset(buf, 0, sizeof(buf)); - *ptr++ = s->s3->send_alert[0]; - *ptr++ = s->s3->send_alert[1]; + *ptr++ = s->s3.send_alert[0]; + *ptr++ = s->s3.send_alert[1]; i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0, &written); if (i <= 0) { - s->s3->alert_dispatch = 1; + s->s3.alert_dispatch = 1; /* fprintf( stderr, "not done with alert\n" ); */ } else { (void)BIO_flush(s->wbio); if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, + s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3.send_alert, 2, s, s->msg_callback_arg); if (s->info_callback != NULL) @@ -64,7 +63,7 @@ int dtls1_dispatch_alert(SSL *s) cb = s->ctx->info_callback; if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; + j = (s->s3.send_alert[0] << 8) | s->s3.send_alert[1]; cb(s, SSL_CB_WRITE_ALERT, j); } } diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c index c05a77e34668..23007533826a 100644 --- a/ssl/d1_srtp.c +++ b/ssl/d1_srtp.c @@ -1,7 +1,7 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2020 The OpenSSL Project Authors. 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 @@ -68,8 +68,7 @@ static int ssl_ctx_make_profiles(const char *profiles_string, SRTP_PROTECTION_PROFILE *p; if ((profiles = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); return 1; } @@ -79,19 +78,16 @@ static int ssl_ctx_make_profiles(const char *profiles_string, if (!find_profile_by_name(ptr, &p, col ? (size_t)(col - ptr) : strlen(ptr))) { if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); goto err; } if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); goto err; } } else { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + ERR_raise(ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); goto err; } diff --git a/ssl/ktls.c b/ssl/ktls.c new file mode 100644 index 000000000000..ddbfd1447c54 --- /dev/null +++ b/ssl/ktls.c @@ -0,0 +1,247 @@ +/* + * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * 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 + */ + +#include "ssl_local.h" +#include "internal/ktls.h" + +#if defined(__FreeBSD__) +# include "crypto/cryptodev.h" + +/*- + * Check if a given cipher is supported by the KTLS interface. + * The kernel might still fail the setsockopt() if no suitable + * provider is found, but this checks if the socket option + * supports the cipher suite used at all. + */ +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + + switch (s->version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + case TLS1_3_VERSION: + break; + default: + return 0; + } + + switch (s->s3.tmp.new_cipher->algorithm_enc) { + case SSL_AES128GCM: + case SSL_AES256GCM: + return 1; + case SSL_AES128: + case SSL_AES256: + if (s->ext.use_etm) + return 0; + switch (s->s3.tmp.new_cipher->algorithm_mac) { + case SSL_SHA1: + case SSL_SHA256: + case SSL_SHA384: + return 1; + default: + return 0; + } + default: + return 0; + } +} + +/* Function to configure kernel TLS structure */ +int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, + void *rl_sequence, ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key, unsigned char *mac_key, + size_t mac_secret_size) +{ + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (s->s3.tmp.new_cipher->algorithm_enc) { + case SSL_AES128GCM: + case SSL_AES256GCM: + crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; + if (s->version == TLS1_3_VERSION) { + crypto_info->iv_len = EVP_CIPHER_CTX_get_iv_length(dd); + if (crypto_info->iv_len < 0) + return 0; + } + else + crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN; + break; + case SSL_AES128: + case SSL_AES256: + switch (s->s3.tmp.new_cipher->algorithm_mac) { + case SSL_SHA1: + crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC; + break; + case SSL_SHA256: + crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC; + break; + case SSL_SHA384: + crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC; + break; + default: + return 0; + } + crypto_info->cipher_algorithm = CRYPTO_AES_CBC; + crypto_info->iv_len = EVP_CIPHER_get_iv_length(c); + crypto_info->auth_key = mac_key; + crypto_info->auth_key_len = mac_secret_size; + break; + default: + return 0; + } + crypto_info->cipher_key = key; + crypto_info->cipher_key_len = EVP_CIPHER_get_key_length(c); + crypto_info->iv = iv; + crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; + crypto_info->tls_vminor = (s->version & 0x000000ff); +# ifdef TCP_RXTLS_ENABLE + memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); + if (rec_seq != NULL) + *rec_seq = crypto_info->rec_seq; +# else + if (rec_seq != NULL) + *rec_seq = NULL; +# endif + return 1; +}; + +#endif /* __FreeBSD__ */ + +#if defined(OPENSSL_SYS_LINUX) + +/* Function to check supported ciphers in Linux */ +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + switch (s->version) { + case TLS1_2_VERSION: + case TLS1_3_VERSION: + break; + default: + return 0; + } + + /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 + * or Chacha20-Poly1305 + */ +# ifdef OPENSSL_KTLS_AES_CCM_128 + if (EVP_CIPHER_is_a(c, "AES-128-CCM")) { + if (s->version == TLS_1_3_VERSION /* broken on 5.x kernels */ + || EVP_CIPHER_CTX_get_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) + return 0; + return 1; + } else +# endif + if (0 +# ifdef OPENSSL_KTLS_AES_GCM_128 + || EVP_CIPHER_is_a(c, "AES-128-GCM") +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + || EVP_CIPHER_is_a(c, "AES-256-GCM") +# endif +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + || EVP_CIPHER_is_a(c, "ChaCha20-Poly1305") +# endif + ) { + return 1; + } + return 0; +} + +/* Function to configure kernel TLS structure */ +int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, + void *rl_sequence, ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key, unsigned char *mac_key, + size_t mac_secret_size) +{ + unsigned char geniv[12]; + unsigned char *iiv = iv; + + if (s->version == TLS1_2_VERSION && + EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) { + if (!EVP_CIPHER_CTX_get_updated_iv(dd, geniv, + EVP_GCM_TLS_FIXED_IV_LEN + + EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; + iiv = geniv; + } + + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (EVP_CIPHER_get_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: + crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; + crypto_info->gcm128.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); + memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_128_IV_SIZE); + memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->gcm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm128.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: + crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; + crypto_info->gcm256.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); + memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_256_IV_SIZE); + memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); + memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->gcm256.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm256.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; + crypto_info->ccm128.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); + memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_CCM_128_IV_SIZE); + memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->ccm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->ccm128.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_CHACHA20_POLY1305 + case NID_chacha20_poly1305: + crypto_info->chacha20poly1305.info.cipher_type = TLS_CIPHER_CHACHA20_POLY1305; + crypto_info->chacha20poly1305.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->chacha20poly1305); + memcpy(crypto_info->chacha20poly1305.iv, iiv, + TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE); + memcpy(crypto_info->chacha20poly1305.key, key, + EVP_CIPHER_get_key_length(c)); + memcpy(crypto_info->chacha20poly1305.rec_seq, rl_sequence, + TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->chacha20poly1305.rec_seq; + return 1; +# endif + default: + return 0; + } + +} + +#endif /* OPENSSL_SYS_LINUX */ diff --git a/ssl/methods.c b/ssl/methods.c index c5e8898364cd..525f59e91231 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -1,13 +1,14 @@ /* * Copyright 1995-2016 The OpenSSL Project Authors. 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 */ #include <stdio.h> +#include <openssl/macros.h> #include <openssl/objects.h> #include "ssl_local.h" @@ -172,7 +173,7 @@ IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_client_method, ssl_undefined_function, ossl_statem_connect, DTLSv1_2_enc_data) -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 # ifndef OPENSSL_NO_TLS1_2_METHOD const SSL_METHOD *TLSv1_2_method(void) { diff --git a/ssl/packet.c b/ssl/packet.c deleted file mode 100644 index d6357495f53e..000000000000 --- a/ssl/packet.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 - */ - -#include "internal/cryptlib.h" -#include "packet_local.h" -#include <openssl/sslerr.h> - -#define DEFAULT_BUF_SIZE 256 - -int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) -{ - if (!WPACKET_reserve_bytes(pkt, len, allocbytes)) - return 0; - - pkt->written += len; - pkt->curr += len; - return 1; -} - -int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len, - unsigned char **allocbytes, size_t lenbytes) -{ - if (!WPACKET_start_sub_packet_len__(pkt, lenbytes) - || !WPACKET_allocate_bytes(pkt, len, allocbytes) - || !WPACKET_close(pkt)) - return 0; - - return 1; -} - -#define GETBUF(p) (((p)->staticbuf != NULL) \ - ? (p)->staticbuf : (unsigned char *)(p)->buf->data) - -int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes) -{ - /* Internal API, so should not fail */ - if (!ossl_assert(pkt->subs != NULL && len != 0)) - return 0; - - if (pkt->maxsize - pkt->written < len) - return 0; - - if (pkt->staticbuf == NULL && (pkt->buf->length - pkt->written < len)) { - size_t newlen; - size_t reflen; - - reflen = (len > pkt->buf->length) ? len : pkt->buf->length; - - if (reflen > SIZE_MAX / 2) { - newlen = SIZE_MAX; - } else { - newlen = reflen * 2; - if (newlen < DEFAULT_BUF_SIZE) - newlen = DEFAULT_BUF_SIZE; - } - if (BUF_MEM_grow(pkt->buf, newlen) == 0) - return 0; - } - if (allocbytes != NULL) - *allocbytes = WPACKET_get_curr(pkt); - - return 1; -} - -int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, - unsigned char **allocbytes, size_t lenbytes) -{ - if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes)) - return 0; - - *allocbytes += lenbytes; - - return 1; -} - -static size_t maxmaxsize(size_t lenbytes) -{ - if (lenbytes >= sizeof(size_t) || lenbytes == 0) - return SIZE_MAX; - - return ((size_t)1 << (lenbytes * 8)) - 1 + lenbytes; -} - -static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) -{ - unsigned char *lenchars; - - pkt->curr = 0; - pkt->written = 0; - - if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) { - SSLerr(SSL_F_WPACKET_INTERN_INIT_LEN, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (lenbytes == 0) - return 1; - - pkt->subs->pwritten = lenbytes; - pkt->subs->lenbytes = lenbytes; - - if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) { - OPENSSL_free(pkt->subs); - pkt->subs = NULL; - return 0; - } - pkt->subs->packet_len = lenchars - GETBUF(pkt); - - return 1; -} - -int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len, - size_t lenbytes) -{ - size_t max = maxmaxsize(lenbytes); - - /* Internal API, so should not fail */ - if (!ossl_assert(buf != NULL && len > 0)) - return 0; - - pkt->staticbuf = buf; - pkt->buf = NULL; - pkt->maxsize = (max < len) ? max : len; - - return wpacket_intern_init_len(pkt, lenbytes); -} - -int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes) -{ - /* Internal API, so should not fail */ - if (!ossl_assert(buf != NULL)) - return 0; - - pkt->staticbuf = NULL; - pkt->buf = buf; - pkt->maxsize = maxmaxsize(lenbytes); - - return wpacket_intern_init_len(pkt, lenbytes); -} - -int WPACKET_init(WPACKET *pkt, BUF_MEM *buf) -{ - return WPACKET_init_len(pkt, buf, 0); -} - -int WPACKET_set_flags(WPACKET *pkt, unsigned int flags) -{ - /* Internal API, so should not fail */ - if (!ossl_assert(pkt->subs != NULL)) - return 0; - - pkt->subs->flags = flags; - - return 1; -} - -/* Store the |value| of length |len| at location |data| */ -static int put_value(unsigned char *data, uint64_t value, size_t len) -{ - for (data += len - 1; len > 0; len--) { - *data = (unsigned char)(value & 0xff); - data--; - value >>= 8; - } - - /* Check whether we could fit the value in the assigned number of bytes */ - if (value > 0) - return 0; - - return 1; -} - - -/* - * Internal helper function used by WPACKET_close(), WPACKET_finish() and - * WPACKET_fill_lengths() to close a sub-packet and write out its length if - * necessary. If |doclose| is 0 then it goes through the motions of closing - * (i.e. it fills in all the lengths), but doesn't actually close anything. - */ -static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose) -{ - size_t packlen = pkt->written - sub->pwritten; - - if (packlen == 0 - && (sub->flags & WPACKET_FLAGS_NON_ZERO_LENGTH) != 0) - return 0; - - if (packlen == 0 - && sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) { - /* We can't handle this case. Return an error */ - if (!doclose) - return 0; - - /* Deallocate any bytes allocated for the length of the WPACKET */ - if ((pkt->curr - sub->lenbytes) == sub->packet_len) { - pkt->written -= sub->lenbytes; - pkt->curr -= sub->lenbytes; - } - - /* Don't write out the packet length */ - sub->packet_len = 0; - sub->lenbytes = 0; - } - - /* Write out the WPACKET length if needed */ - if (sub->lenbytes > 0 - && !put_value(&GETBUF(pkt)[sub->packet_len], packlen, - sub->lenbytes)) - return 0; - - if (doclose) { - pkt->subs = sub->parent; - OPENSSL_free(sub); - } - - return 1; -} - -int WPACKET_fill_lengths(WPACKET *pkt) -{ - WPACKET_SUB *sub; - - if (!ossl_assert(pkt->subs != NULL)) - return 0; - - for (sub = pkt->subs; sub != NULL; sub = sub->parent) { - if (!wpacket_intern_close(pkt, sub, 0)) - return 0; - } - - return 1; -} - -int WPACKET_close(WPACKET *pkt) -{ - /* - * Internal API, so should not fail - but we do negative testing of this - * so no assert (otherwise the tests fail) - */ - if (pkt->subs == NULL || pkt->subs->parent == NULL) - return 0; - - return wpacket_intern_close(pkt, pkt->subs, 1); -} - -int WPACKET_finish(WPACKET *pkt) -{ - int ret; - - /* - * Internal API, so should not fail - but we do negative testing of this - * so no assert (otherwise the tests fail) - */ - if (pkt->subs == NULL || pkt->subs->parent != NULL) - return 0; - - ret = wpacket_intern_close(pkt, pkt->subs, 1); - if (ret) { - OPENSSL_free(pkt->subs); - pkt->subs = NULL; - } - - return ret; -} - -int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) -{ - WPACKET_SUB *sub; - unsigned char *lenchars; - - /* Internal API, so should not fail */ - if (!ossl_assert(pkt->subs != NULL)) - return 0; - - if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) { - SSLerr(SSL_F_WPACKET_START_SUB_PACKET_LEN__, ERR_R_MALLOC_FAILURE); - return 0; - } - - sub->parent = pkt->subs; - pkt->subs = sub; - sub->pwritten = pkt->written + lenbytes; - sub->lenbytes = lenbytes; - - if (lenbytes == 0) { - sub->packet_len = 0; - return 1; - } - - if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) - return 0; - /* Convert to an offset in case the underlying BUF_MEM gets realloc'd */ - sub->packet_len = lenchars - GETBUF(pkt); - - return 1; -} - -int WPACKET_start_sub_packet(WPACKET *pkt) -{ - return WPACKET_start_sub_packet_len__(pkt, 0); -} - -int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t size) -{ - unsigned char *data; - - /* Internal API, so should not fail */ - if (!ossl_assert(size <= sizeof(uint64_t)) - || !WPACKET_allocate_bytes(pkt, size, &data) - || !put_value(data, val, size)) - return 0; - - return 1; -} - -int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize) -{ - WPACKET_SUB *sub; - size_t lenbytes; - - /* Internal API, so should not fail */ - if (!ossl_assert(pkt->subs != NULL)) - return 0; - - /* Find the WPACKET_SUB for the top level */ - for (sub = pkt->subs; sub->parent != NULL; sub = sub->parent) - continue; - - lenbytes = sub->lenbytes; - if (lenbytes == 0) - lenbytes = sizeof(pkt->maxsize); - - if (maxmaxsize(lenbytes) < maxsize || maxsize < pkt->written) - return 0; - - pkt->maxsize = maxsize; - - return 1; -} - -int WPACKET_memset(WPACKET *pkt, int ch, size_t len) -{ - unsigned char *dest; - - if (len == 0) - return 1; - - if (!WPACKET_allocate_bytes(pkt, len, &dest)) - return 0; - - memset(dest, ch, len); - - return 1; -} - -int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len) -{ - unsigned char *dest; - - if (len == 0) - return 1; - - if (!WPACKET_allocate_bytes(pkt, len, &dest)) - return 0; - - memcpy(dest, src, len); - - return 1; -} - -int WPACKET_sub_memcpy__(WPACKET *pkt, const void *src, size_t len, - size_t lenbytes) -{ - if (!WPACKET_start_sub_packet_len__(pkt, lenbytes) - || !WPACKET_memcpy(pkt, src, len) - || !WPACKET_close(pkt)) - return 0; - - return 1; -} - -int WPACKET_get_total_written(WPACKET *pkt, size_t *written) -{ - /* Internal API, so should not fail */ - if (!ossl_assert(written != NULL)) - return 0; - - *written = pkt->written; - - return 1; -} - -int WPACKET_get_length(WPACKET *pkt, size_t *len) -{ - /* Internal API, so should not fail */ - if (!ossl_assert(pkt->subs != NULL && len != NULL)) - return 0; - - *len = pkt->written - pkt->subs->pwritten; - - return 1; -} - -unsigned char *WPACKET_get_curr(WPACKET *pkt) -{ - return GETBUF(pkt) + pkt->curr; -} - -void WPACKET_cleanup(WPACKET *pkt) -{ - WPACKET_SUB *sub, *parent; - - for (sub = pkt->subs; sub != NULL; sub = parent) { - parent = sub->parent; - OPENSSL_free(sub); - } - pkt->subs = NULL; -} diff --git a/ssl/packet_local.h b/ssl/packet_local.h deleted file mode 100644 index 5b1d3fe56edb..000000000000 --- a/ssl/packet_local.h +++ /dev/null @@ -1,909 +0,0 @@ -/* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (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 - */ - -#ifndef OSSL_SSL_PACKET_LOCAL_H -# define OSSL_SSL_PACKET_LOCAL_H - -# include <string.h> -# include <openssl/bn.h> -# include <openssl/buffer.h> -# include <openssl/crypto.h> -# include <openssl/e_os2.h> - -# include "internal/numbers.h" - -typedef struct { - /* Pointer to where we are currently reading from */ - const unsigned char *curr; - /* Number of bytes remaining */ - size_t remaining; -} PACKET; - -/* Internal unchecked shorthand; don't use outside this file. */ -static ossl_inline void packet_forward(PACKET *pkt, size_t len) -{ - pkt->curr += len; - pkt->remaining -= len; -} - -/* - * Returns the number of bytes remaining to be read in the PACKET - */ -static ossl_inline size_t PACKET_remaining(const PACKET *pkt) -{ - return pkt->remaining; -} - -/* - * Returns a pointer to the first byte after the packet data. - * Useful for integrating with non-PACKET parsing code. - * Specifically, we use PACKET_end() to verify that a d2i_... call - * has consumed the entire packet contents. - */ -static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt) -{ - return pkt->curr + pkt->remaining; -} - -/* - * Returns a pointer to the PACKET's current position. - * For use in non-PACKETized APIs. - */ -static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt) -{ - return pkt->curr; -} - -/* - * Initialise a PACKET with |len| bytes held in |buf|. This does not make a - * copy of the data so |buf| must be present for the whole time that the PACKET - * is being used. - */ -__owur static ossl_inline int PACKET_buf_init(PACKET *pkt, - const unsigned char *buf, - size_t len) -{ - /* Sanity check for negative values. */ - if (len > (size_t)(SIZE_MAX / 2)) - return 0; - - pkt->curr = buf; - pkt->remaining = len; - return 1; -} - -/* Initialize a PACKET to hold zero bytes. */ -static ossl_inline void PACKET_null_init(PACKET *pkt) -{ - pkt->curr = NULL; - pkt->remaining = 0; -} - -/* - * Returns 1 if the packet has length |num| and its contents equal the |num| - * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal). - * If lengths are equal, performs the comparison in constant time. - */ -__owur static ossl_inline int PACKET_equal(const PACKET *pkt, const void *ptr, - size_t num) -{ - if (PACKET_remaining(pkt) != num) - return 0; - return CRYPTO_memcmp(pkt->curr, ptr, num) == 0; -} - -/* - * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|. - * Data is not copied: the |subpkt| packet will share its underlying buffer with - * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. - */ -__owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt, - PACKET *subpkt, size_t len) -{ - if (PACKET_remaining(pkt) < len) - return 0; - - return PACKET_buf_init(subpkt, pkt->curr, len); -} - -/* - * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not - * copied: the |subpkt| packet will share its underlying buffer with the - * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. - */ -__owur static ossl_inline int PACKET_get_sub_packet(PACKET *pkt, - PACKET *subpkt, size_t len) -{ - if (!PACKET_peek_sub_packet(pkt, subpkt, len)) - return 0; - - packet_forward(pkt, len); - - return 1; -} - -/* - * Peek ahead at 2 bytes in network order from |pkt| and store the value in - * |*data| - */ -__owur static ossl_inline int PACKET_peek_net_2(const PACKET *pkt, - unsigned int *data) -{ - if (PACKET_remaining(pkt) < 2) - return 0; - - *data = ((unsigned int)(*pkt->curr)) << 8; - *data |= *(pkt->curr + 1); - - return 1; -} - -/* Equivalent of n2s */ -/* Get 2 bytes in network order from |pkt| and store the value in |*data| */ -__owur static ossl_inline int PACKET_get_net_2(PACKET *pkt, unsigned int *data) -{ - if (!PACKET_peek_net_2(pkt, data)) - return 0; - - packet_forward(pkt, 2); - - return 1; -} - -/* Same as PACKET_get_net_2() but for a size_t */ -__owur static ossl_inline int PACKET_get_net_2_len(PACKET *pkt, size_t *data) -{ - unsigned int i; - int ret = PACKET_get_net_2(pkt, &i); - - if (ret) - *data = (size_t)i; - - return ret; -} - -/* - * Peek ahead at 3 bytes in network order from |pkt| and store the value in - * |*data| - */ -__owur static ossl_inline int PACKET_peek_net_3(const PACKET *pkt, - unsigned long *data) -{ - if (PACKET_remaining(pkt) < 3) - return 0; - - *data = ((unsigned long)(*pkt->curr)) << 16; - *data |= ((unsigned long)(*(pkt->curr + 1))) << 8; - *data |= *(pkt->curr + 2); - - return 1; -} - -/* Equivalent of n2l3 */ -/* Get 3 bytes in network order from |pkt| and store the value in |*data| */ -__owur static ossl_inline int PACKET_get_net_3(PACKET *pkt, unsigned long *data) -{ - if (!PACKET_peek_net_3(pkt, data)) - return 0; - - packet_forward(pkt, 3); - - return 1; -} - -/* Same as PACKET_get_net_3() but for a size_t */ -__owur static ossl_inline int PACKET_get_net_3_len(PACKET *pkt, size_t *data) -{ - unsigned long i; - int ret = PACKET_get_net_3(pkt, &i); - - if (ret) - *data = (size_t)i; - - return ret; -} - -/* - * Peek ahead at 4 bytes in network order from |pkt| and store the value in - * |*data| - */ -__owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt, - unsigned long *data) -{ - if (PACKET_remaining(pkt) < 4) - return 0; - - *data = ((unsigned long)(*pkt->curr)) << 24; - *data |= ((unsigned long)(*(pkt->curr + 1))) << 16; - *data |= ((unsigned long)(*(pkt->curr + 2))) << 8; - *data |= *(pkt->curr + 3); - - return 1; -} - -/* - * Peek ahead at 8 bytes in network order from |pkt| and store the value in - * |*data| - */ -__owur static ossl_inline int PACKET_peek_net_8(const PACKET *pkt, - uint64_t *data) -{ - if (PACKET_remaining(pkt) < 8) - return 0; - - *data = ((uint64_t)(*pkt->curr)) << 56; - *data |= ((uint64_t)(*(pkt->curr + 1))) << 48; - *data |= ((uint64_t)(*(pkt->curr + 2))) << 40; - *data |= ((uint64_t)(*(pkt->curr + 3))) << 32; - *data |= ((uint64_t)(*(pkt->curr + 4))) << 24; - *data |= ((uint64_t)(*(pkt->curr + 5))) << 16; - *data |= ((uint64_t)(*(pkt->curr + 6))) << 8; - *data |= *(pkt->curr + 7); - - return 1; -} - -/* Equivalent of n2l */ -/* Get 4 bytes in network order from |pkt| and store the value in |*data| */ -__owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data) -{ - if (!PACKET_peek_net_4(pkt, data)) - return 0; - - packet_forward(pkt, 4); - - return 1; -} - -/* Same as PACKET_get_net_4() but for a size_t */ -__owur static ossl_inline int PACKET_get_net_4_len(PACKET *pkt, size_t *data) -{ - unsigned long i; - int ret = PACKET_get_net_4(pkt, &i); - - if (ret) - *data = (size_t)i; - - return ret; -} - -/* Get 8 bytes in network order from |pkt| and store the value in |*data| */ -__owur static ossl_inline int PACKET_get_net_8(PACKET *pkt, uint64_t *data) -{ - if (!PACKET_peek_net_8(pkt, data)) - return 0; - - packet_forward(pkt, 8); - - return 1; -} - -/* Peek ahead at 1 byte from |pkt| and store the value in |*data| */ -__owur static ossl_inline int PACKET_peek_1(const PACKET *pkt, - unsigned int *data) -{ - if (!PACKET_remaining(pkt)) - return 0; - - *data = *pkt->curr; - - return 1; -} - -/* Get 1 byte from |pkt| and store the value in |*data| */ -__owur static ossl_inline int PACKET_get_1(PACKET *pkt, unsigned int *data) -{ - if (!PACKET_peek_1(pkt, data)) - return 0; - - packet_forward(pkt, 1); - - return 1; -} - -/* Same as PACKET_get_1() but for a size_t */ -__owur static ossl_inline int PACKET_get_1_len(PACKET *pkt, size_t *data) -{ - unsigned int i; - int ret = PACKET_get_1(pkt, &i); - - if (ret) - *data = (size_t)i; - - return ret; -} - -/* - * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value - * in |*data| - */ -__owur static ossl_inline int PACKET_peek_4(const PACKET *pkt, - unsigned long *data) -{ - if (PACKET_remaining(pkt) < 4) - return 0; - - *data = *pkt->curr; - *data |= ((unsigned long)(*(pkt->curr + 1))) << 8; - *data |= ((unsigned long)(*(pkt->curr + 2))) << 16; - *data |= ((unsigned long)(*(pkt->curr + 3))) << 24; - - return 1; -} - -/* Equivalent of c2l */ -/* - * Get 4 bytes in reverse network order from |pkt| and store the value in - * |*data| - */ -__owur static ossl_inline int PACKET_get_4(PACKET *pkt, unsigned long *data) -{ - if (!PACKET_peek_4(pkt, data)) - return 0; - - packet_forward(pkt, 4); - - return 1; -} - -/* - * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in - * |*data|. This just points at the underlying buffer that |pkt| is using. The - * caller should not free this data directly (it will be freed when the - * underlying buffer gets freed - */ -__owur static ossl_inline int PACKET_peek_bytes(const PACKET *pkt, - const unsigned char **data, - size_t len) -{ - if (PACKET_remaining(pkt) < len) - return 0; - - *data = pkt->curr; - - return 1; -} - -/* - * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This - * just points at the underlying buffer that |pkt| is using. The caller should - * not free this data directly (it will be freed when the underlying buffer gets - * freed - */ -__owur static ossl_inline int PACKET_get_bytes(PACKET *pkt, - const unsigned char **data, - size_t len) -{ - if (!PACKET_peek_bytes(pkt, data, len)) - return 0; - - packet_forward(pkt, len); - - return 1; -} - -/* Peek ahead at |len| bytes from |pkt| and copy them to |data| */ -__owur static ossl_inline int PACKET_peek_copy_bytes(const PACKET *pkt, - unsigned char *data, - size_t len) -{ - if (PACKET_remaining(pkt) < len) - return 0; - - memcpy(data, pkt->curr, len); - - return 1; -} - -/* - * Read |len| bytes from |pkt| and copy them to |data|. - * The caller is responsible for ensuring that |data| can hold |len| bytes. - */ -__owur static ossl_inline int PACKET_copy_bytes(PACKET *pkt, - unsigned char *data, size_t len) -{ - if (!PACKET_peek_copy_bytes(pkt, data, len)) - return 0; - - packet_forward(pkt, len); - - return 1; -} - -/* - * Copy packet data to |dest|, and set |len| to the number of copied bytes. - * If the packet has more than |dest_len| bytes, nothing is copied. - * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise. - * Does not forward PACKET position (because it is typically the last thing - * done with a given PACKET). - */ -__owur static ossl_inline int PACKET_copy_all(const PACKET *pkt, - unsigned char *dest, - size_t dest_len, size_t *len) -{ - if (PACKET_remaining(pkt) > dest_len) { - *len = 0; - return 0; - } - *len = pkt->remaining; - memcpy(dest, pkt->curr, pkt->remaining); - return 1; -} - -/* - * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the - * result in |*data|, and the length in |len|. - * If |*data| is not NULL, the old data is OPENSSL_free'd. - * If the packet is empty, or malloc fails, |*data| will be set to NULL. - * Returns 1 if the malloc succeeds and 0 otherwise. - * Does not forward PACKET position (because it is typically the last thing - * done with a given PACKET). - */ -__owur static ossl_inline int PACKET_memdup(const PACKET *pkt, - unsigned char **data, size_t *len) -{ - size_t length; - - OPENSSL_free(*data); - *data = NULL; - *len = 0; - - length = PACKET_remaining(pkt); - - if (length == 0) - return 1; - - *data = OPENSSL_memdup(pkt->curr, length); - if (*data == NULL) - return 0; - - *len = length; - return 1; -} - -/* - * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated - * buffer. Store a pointer to the result in |*data|. - * If |*data| is not NULL, the old data is OPENSSL_free'd. - * If the data in |pkt| does not contain a NUL-byte, the entire data is - * copied and NUL-terminated. - * Returns 1 if the malloc succeeds and 0 otherwise. - * Does not forward PACKET position (because it is typically the last thing done - * with a given PACKET). - */ -__owur static ossl_inline int PACKET_strndup(const PACKET *pkt, char **data) -{ - OPENSSL_free(*data); - - /* This will succeed on an empty packet, unless pkt->curr == NULL. */ - *data = OPENSSL_strndup((const char *)pkt->curr, PACKET_remaining(pkt)); - return (*data != NULL); -} - -/* Returns 1 if |pkt| contains at least one 0-byte, 0 otherwise. */ -static ossl_inline int PACKET_contains_zero_byte(const PACKET *pkt) -{ - return memchr(pkt->curr, 0, pkt->remaining) != NULL; -} - -/* Move the current reading position forward |len| bytes */ -__owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len) -{ - if (PACKET_remaining(pkt) < len) - return 0; - - packet_forward(pkt, len); - - return 1; -} - -/* - * Reads a variable-length vector prefixed with a one-byte length, and stores - * the contents in |subpkt|. |pkt| can equal |subpkt|. - * Data is not copied: the |subpkt| packet will share its underlying buffer with - * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. - * Upon failure, the original |pkt| and |subpkt| are not modified. - */ -__owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt, - PACKET *subpkt) -{ - unsigned int length; - const unsigned char *data; - PACKET tmp = *pkt; - if (!PACKET_get_1(&tmp, &length) || - !PACKET_get_bytes(&tmp, &data, (size_t)length)) { - return 0; - } - - *pkt = tmp; - subpkt->curr = data; - subpkt->remaining = length; - - return 1; -} - -/* - * Like PACKET_get_length_prefixed_1, but additionally, fails when there are - * leftover bytes in |pkt|. - */ -__owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt, - PACKET *subpkt) -{ - unsigned int length; - const unsigned char *data; - PACKET tmp = *pkt; - if (!PACKET_get_1(&tmp, &length) || - !PACKET_get_bytes(&tmp, &data, (size_t)length) || - PACKET_remaining(&tmp) != 0) { - return 0; - } - - *pkt = tmp; - subpkt->curr = data; - subpkt->remaining = length; - - return 1; -} - -/* - * Reads a variable-length vector prefixed with a two-byte length, and stores - * the contents in |subpkt|. |pkt| can equal |subpkt|. - * Data is not copied: the |subpkt| packet will share its underlying buffer with - * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. - * Upon failure, the original |pkt| and |subpkt| are not modified. - */ -__owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt, - PACKET *subpkt) -{ - unsigned int length; - const unsigned char *data; - PACKET tmp = *pkt; - - if (!PACKET_get_net_2(&tmp, &length) || - !PACKET_get_bytes(&tmp, &data, (size_t)length)) { - return 0; - } - - *pkt = tmp; - subpkt->curr = data; - subpkt->remaining = length; - - return 1; -} - -/* - * Like PACKET_get_length_prefixed_2, but additionally, fails when there are - * leftover bytes in |pkt|. - */ -__owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt, - PACKET *subpkt) -{ - unsigned int length; - const unsigned char *data; - PACKET tmp = *pkt; - - if (!PACKET_get_net_2(&tmp, &length) || - !PACKET_get_bytes(&tmp, &data, (size_t)length) || - PACKET_remaining(&tmp) != 0) { - return 0; - } - - *pkt = tmp; - subpkt->curr = data; - subpkt->remaining = length; - - return 1; -} - -/* - * Reads a variable-length vector prefixed with a three-byte length, and stores - * the contents in |subpkt|. |pkt| can equal |subpkt|. - * Data is not copied: the |subpkt| packet will share its underlying buffer with - * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|. - * Upon failure, the original |pkt| and |subpkt| are not modified. - */ -__owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt, - PACKET *subpkt) -{ - unsigned long length; - const unsigned char *data; - PACKET tmp = *pkt; - if (!PACKET_get_net_3(&tmp, &length) || - !PACKET_get_bytes(&tmp, &data, (size_t)length)) { - return 0; - } - - *pkt = tmp; - subpkt->curr = data; - subpkt->remaining = length; - - return 1; -} - -/* Writeable packets */ - -typedef struct wpacket_sub WPACKET_SUB; -struct wpacket_sub { - /* The parent WPACKET_SUB if we have one or NULL otherwise */ - WPACKET_SUB *parent; - - /* - * Offset into the buffer where the length of this WPACKET goes. We use an - * offset in case the buffer grows and gets reallocated. - */ - size_t packet_len; - - /* Number of bytes in the packet_len or 0 if we don't write the length */ - size_t lenbytes; - - /* Number of bytes written to the buf prior to this packet starting */ - size_t pwritten; - - /* Flags for this sub-packet */ - unsigned int flags; -}; - -typedef struct wpacket_st WPACKET; -struct wpacket_st { - /* The buffer where we store the output data */ - BUF_MEM *buf; - - /* Fixed sized buffer which can be used as an alternative to buf */ - unsigned char *staticbuf; - - /* - * Offset into the buffer where we are currently writing. We use an offset - * in case the buffer grows and gets reallocated. - */ - size_t curr; - - /* Number of bytes written so far */ - size_t written; - - /* Maximum number of bytes we will allow to be written to this WPACKET */ - size_t maxsize; - - /* Our sub-packets (always at least one if not finished) */ - WPACKET_SUB *subs; -}; - -/* Flags */ - -/* Default */ -#define WPACKET_FLAGS_NONE 0 - -/* Error on WPACKET_close() if no data written to the WPACKET */ -#define WPACKET_FLAGS_NON_ZERO_LENGTH 1 - -/* - * Abandon all changes on WPACKET_close() if no data written to the WPACKET, - * i.e. this does not write out a zero packet length - */ -#define WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH 2 - - -/* - * Initialise a WPACKET with the buffer in |buf|. The buffer must exist - * for the whole time that the WPACKET is being used. Additionally |lenbytes| of - * data is preallocated at the start of the buffer to store the length of the - * WPACKET once we know it. - */ -int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes); - -/* - * Same as WPACKET_init_len except there is no preallocation of the WPACKET - * length. - */ -int WPACKET_init(WPACKET *pkt, BUF_MEM *buf); - -/* - * Same as WPACKET_init_len except we do not use a growable BUF_MEM structure. - * A fixed buffer of memory |buf| of size |len| is used instead. A failure will - * occur if you attempt to write beyond the end of the buffer - */ -int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len, - size_t lenbytes); -/* - * Set the flags to be applied to the current sub-packet - */ -int WPACKET_set_flags(WPACKET *pkt, unsigned int flags); - -/* - * Closes the most recent sub-packet. It also writes out the length of the - * packet to the required location (normally the start of the WPACKET) if - * appropriate. The top level WPACKET should be closed using WPACKET_finish() - * instead of this function. - */ -int WPACKET_close(WPACKET *pkt); - -/* - * The same as WPACKET_close() but only for the top most WPACKET. Additionally - * frees memory resources for this WPACKET. - */ -int WPACKET_finish(WPACKET *pkt); - -/* - * Iterate through all the sub-packets and write out their lengths as if they - * were being closed. The lengths will be overwritten with the final lengths - * when the sub-packets are eventually closed (which may be different if more - * data is added to the WPACKET). This function fails if a sub-packet is of 0 - * length and WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH is set. - */ -int WPACKET_fill_lengths(WPACKET *pkt); - -/* - * Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated - * at the start of the sub-packet to store its length once we know it. Don't - * call this directly. Use the convenience macros below instead. - */ -int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes); - -/* - * Convenience macros for calling WPACKET_start_sub_packet_len with different - * lengths - */ -#define WPACKET_start_sub_packet_u8(pkt) \ - WPACKET_start_sub_packet_len__((pkt), 1) -#define WPACKET_start_sub_packet_u16(pkt) \ - WPACKET_start_sub_packet_len__((pkt), 2) -#define WPACKET_start_sub_packet_u24(pkt) \ - WPACKET_start_sub_packet_len__((pkt), 3) -#define WPACKET_start_sub_packet_u32(pkt) \ - WPACKET_start_sub_packet_len__((pkt), 4) - -/* - * Same as WPACKET_start_sub_packet_len__() except no bytes are pre-allocated - * for the sub-packet length. - */ -int WPACKET_start_sub_packet(WPACKET *pkt); - -/* - * Allocate bytes in the WPACKET for the output. This reserves the bytes - * and counts them as "written", but doesn't actually do the writing. A pointer - * to the allocated bytes is stored in |*allocbytes|. |allocbytes| may be NULL. - * WARNING: the allocated bytes must be filled in immediately, without further - * WPACKET_* calls. If not then the underlying buffer may be realloc'd and - * change its location. - */ -int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, - unsigned char **allocbytes); - -/* - * The same as WPACKET_allocate_bytes() except additionally a new sub-packet is - * started for the allocated bytes, and then closed immediately afterwards. The - * number of length bytes for the sub-packet is in |lenbytes|. Don't call this - * directly. Use the convenience macros below instead. - */ -int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len, - unsigned char **allocbytes, size_t lenbytes); - -/* - * Convenience macros for calling WPACKET_sub_allocate_bytes with different - * lengths - */ -#define WPACKET_sub_allocate_bytes_u8(pkt, len, bytes) \ - WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 1) -#define WPACKET_sub_allocate_bytes_u16(pkt, len, bytes) \ - WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 2) -#define WPACKET_sub_allocate_bytes_u24(pkt, len, bytes) \ - WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 3) -#define WPACKET_sub_allocate_bytes_u32(pkt, len, bytes) \ - WPACKET_sub_allocate_bytes__((pkt), (len), (bytes), 4) - -/* - * The same as WPACKET_allocate_bytes() except the reserved bytes are not - * actually counted as written. Typically this will be for when we don't know - * how big arbitrary data is going to be up front, but we do know what the - * maximum size will be. If this function is used, then it should be immediately - * followed by a WPACKET_allocate_bytes() call before any other WPACKET - * functions are called (unless the write to the allocated bytes is abandoned). - * - * For example: If we are generating a signature, then the size of that - * signature may not be known in advance. We can use WPACKET_reserve_bytes() to - * handle this: - * - * if (!WPACKET_sub_reserve_bytes_u16(&pkt, EVP_PKEY_size(pkey), &sigbytes1) - * || EVP_SignFinal(md_ctx, sigbytes1, &siglen, pkey) <= 0 - * || !WPACKET_sub_allocate_bytes_u16(&pkt, siglen, &sigbytes2) - * || sigbytes1 != sigbytes2) - * goto err; - */ -int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes); - -/* - * The "reserve_bytes" equivalent of WPACKET_sub_allocate_bytes__() - */ -int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len, - unsigned char **allocbytes, size_t lenbytes); - -/* - * Convenience macros for WPACKET_sub_reserve_bytes with different lengths - */ -#define WPACKET_sub_reserve_bytes_u8(pkt, len, bytes) \ - WPACKET_reserve_bytes__((pkt), (len), (bytes), 1) -#define WPACKET_sub_reserve_bytes_u16(pkt, len, bytes) \ - WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 2) -#define WPACKET_sub_reserve_bytes_u24(pkt, len, bytes) \ - WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 3) -#define WPACKET_sub_reserve_bytes_u32(pkt, len, bytes) \ - WPACKET_sub_reserve_bytes__((pkt), (len), (bytes), 4) - -/* - * Write the value stored in |val| into the WPACKET. The value will consume - * |bytes| amount of storage. An error will occur if |val| cannot be - * accommodated in |bytes| storage, e.g. attempting to write the value 256 into - * 1 byte will fail. Don't call this directly. Use the convenience macros below - * instead. - */ -int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t bytes); - -/* - * Convenience macros for calling WPACKET_put_bytes with different - * lengths - */ -#define WPACKET_put_bytes_u8(pkt, val) \ - WPACKET_put_bytes__((pkt), (val), 1) -#define WPACKET_put_bytes_u16(pkt, val) \ - WPACKET_put_bytes__((pkt), (val), 2) -#define WPACKET_put_bytes_u24(pkt, val) \ - WPACKET_put_bytes__((pkt), (val), 3) -#define WPACKET_put_bytes_u32(pkt, val) \ - WPACKET_put_bytes__((pkt), (val), 4) -#define WPACKET_put_bytes_u64(pkt, val) \ - WPACKET_put_bytes__((pkt), (val), 8) - -/* Set a maximum size that we will not allow the WPACKET to grow beyond */ -int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize); - -/* Copy |len| bytes of data from |*src| into the WPACKET. */ -int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len); - -/* Set |len| bytes of data to |ch| into the WPACKET. */ -int WPACKET_memset(WPACKET *pkt, int ch, size_t len); - -/* - * Copy |len| bytes of data from |*src| into the WPACKET and prefix with its - * length (consuming |lenbytes| of data for the length). Don't call this - * directly. Use the convenience macros below instead. - */ -int WPACKET_sub_memcpy__(WPACKET *pkt, const void *src, size_t len, - size_t lenbytes); - -/* Convenience macros for calling WPACKET_sub_memcpy with different lengths */ -#define WPACKET_sub_memcpy_u8(pkt, src, len) \ - WPACKET_sub_memcpy__((pkt), (src), (len), 1) -#define WPACKET_sub_memcpy_u16(pkt, src, len) \ - WPACKET_sub_memcpy__((pkt), (src), (len), 2) -#define WPACKET_sub_memcpy_u24(pkt, src, len) \ - WPACKET_sub_memcpy__((pkt), (src), (len), 3) -#define WPACKET_sub_memcpy_u32(pkt, src, len) \ - WPACKET_sub_memcpy__((pkt), (src), (len), 4) - -/* - * Return the total number of bytes written so far to the underlying buffer - * including any storage allocated for length bytes - */ -int WPACKET_get_total_written(WPACKET *pkt, size_t *written); - -/* - * Returns the length of the current sub-packet. This excludes any bytes - * allocated for the length itself. - */ -int WPACKET_get_length(WPACKET *pkt, size_t *len); - -/* - * Returns a pointer to the current write location, but does not allocate any - * bytes. - */ -unsigned char *WPACKET_get_curr(WPACKET *pkt); - -/* Release resources in a WPACKET if a failure has occurred. */ -void WPACKET_cleanup(WPACKET *pkt); - -#endif /* OSSL_SSL_PACKET_LOCAL_H */ diff --git a/ssl/pqueue.c b/ssl/pqueue.c index 758440217d45..0852aceacff7 100644 --- a/ssl/pqueue.c +++ b/ssl/pqueue.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2020 The OpenSSL Project Authors. 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 @@ -20,7 +20,7 @@ pitem *pitem_new(unsigned char *prio64be, void *data) pitem *item = OPENSSL_malloc(sizeof(*item)); if (item == NULL) { - SSLerr(SSL_F_PITEM_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } @@ -40,7 +40,7 @@ pqueue *pqueue_new(void) pqueue *pq = OPENSSL_zalloc(sizeof(*pq)); if (pq == NULL) - SSLerr(SSL_F_PQUEUE_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return pq; } diff --git a/ssl/record/README b/ssl/record/README.md index 630fe8027af1..263f257c84c4 100644 --- a/ssl/record/README +++ b/ssl/record/README.md @@ -18,10 +18,10 @@ of libssl. The source files map to components as follows: -dtls1_bitmap.c -> DTLS1_BITMAP component -ssl3_buffer.c -> SSL3_BUFFER component -ssl3_record.c -> SSL3_RECORD component -rec_layer_s3.c, rec_layer_d1.c -> RECORD_LAYER component + dtls1_bitmap.c -> DTLS1_BITMAP component + ssl3_buffer.c -> SSL3_BUFFER component + ssl3_record.c -> SSL3_RECORD component + rec_layer_s3.c, rec_layer_d1.c -> RECORD_LAYER component The RECORD_LAYER component is a facade pattern, i.e. it provides a simplified interface to the record layer for the rest of libssl. The other 3 components are @@ -38,33 +38,32 @@ RECORD_LAYER_* macros. Conceptually it looks like this: - libssl - | ----------------------------|-----record.h-------------------------------------- - | - _______V______________ - | | - | RECORD_LAYER | - | | - | rec_layer_s3.c | - | ^ | - | _________|__________ | - || || - || DTLS1_RECORD_LAYER || - || || - || rec_layer_d1.c || - ||____________________|| - |______________________| - record_local.h ^ ^ ^ - _________________| | |_________________ - | | | - _____V_________ ______V________ _______V________ - | | | | | | - | SSL3_BUFFER | | SSL3_RECORD | | DTLS1_BITMAP | - | |--->| | | | - | ssl3_buffer.c | | ssl3_record.c | | dtls1_bitmap.c | - |_______________| |_______________| |________________| - + libssl + | + -------------------------|-----record.h------------------------------------ + | + _______V______________ + | | + | RECORD_LAYER | + | | + | rec_layer_s3.c | + | ^ | + | _________|__________ | + || || + || DTLS1_RECORD_LAYER || + || || + || rec_layer_d1.c || + ||____________________|| + |______________________| + record_local.h ^ ^ ^ + _________________| | |_________________ + | | | + _____V_________ ______V________ _______V________ + | | | | | | + | SSL3_BUFFER | | SSL3_RECORD | | DTLS1_BITMAP | + | |--->| | | | + | ssl3_buffer.c | | ssl3_record.c | | dtls1_bitmap.c | + |_______________| |_______________| |________________| The two RECORD_LAYER source files build on each other, i.e. the main one is rec_layer_s3.c which provides the core SSL/TLS layer. The second diff --git a/ssl/record/dtls1_bitmap.c b/ssl/record/dtls1_bitmap.c index 8167b4183404..4733a62a9663 100644 --- a/ssl/record/dtls1_bitmap.c +++ b/ssl/record/dtls1_bitmap.c @@ -1,7 +1,7 @@ /* * Copyright 2005-2016 The OpenSSL Project Authors. 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 diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 78d29594c666..7f3d1a7f0ddf 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -1,7 +1,7 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2022 The OpenSSL Project Authors. 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 @@ -13,7 +13,7 @@ #include <openssl/evp.h> #include <openssl/buffer.h> #include "record_local.h" -#include "../packet_local.h" +#include "internal/packet.h" #include "internal/cryptlib.h" int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) @@ -21,7 +21,7 @@ int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl) DTLS_RECORD_LAYER *d; if ((d = OPENSSL_malloc(sizeof(*d))) == NULL) { - SSLerr(SSL_F_DTLS_RECORD_LAYER_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -77,6 +77,8 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) { rdata = (DTLS1_RECORD_DATA *)item->data; + if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT) + OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len); OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(item->data); pitem_free(item); @@ -84,6 +86,8 @@ void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl) while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) { rdata = (DTLS1_RECORD_DATA *)item->data; + if (rl->s->options & SSL_OP_CLEANSE_PLAINTEXT) + OPENSSL_cleanse(rdata->rbuf.buf, rdata->rbuf.len); OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(item->data); pitem_free(item); @@ -153,8 +157,7 @@ int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) if (rdata == NULL || item == NULL) { OPENSSL_free(rdata); pitem_free(item); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_BUFFER_RECORD, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -262,9 +265,7 @@ int dtls1_process_buffered_records(SSL *s) * current record is from a different epoch. But that cannot * be the case because we already checked the epoch above */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } #ifndef OPENSSL_NO_SCTP @@ -284,7 +285,7 @@ int dtls1_process_buffered_records(SSL *s) if (!replayok || !dtls1_process_record(s, bitmap)) { if (ossl_statem_in_error(s)) { /* dtls1_process_record called SSLfatal() */ - return -1; + return 0; } /* dump this record */ rr->length = 0; @@ -358,8 +359,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) || (peek && (type != SSL3_RT_APPLICATION_DATA))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -377,10 +377,10 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, s->rwstate = SSL_NOTHING; /*- - * s->s3->rrec.type - is the type of record - * s->s3->rrec.data, - data - * s->s3->rrec.off, - offset into 'data' for next read - * s->s3->rrec.length, - number of bytes. + * s->s3.rrec.type - is the type of record + * s->s3.rrec.data, - data + * s->s3.rrec.off, - offset into 'data' for next read + * s->s3.rrec.length, - number of bytes. */ rr = s->rlayer.rrec; @@ -445,8 +445,8 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, /* we now have a packet which can be read and processed */ - if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ + if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) { /* * We now have application data between CCS and Finished. Most likely @@ -488,7 +488,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && (s->enc_read_ctx == NULL)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS1_READ_BYTES, + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_APP_DATA_IN_HANDSHAKE); return -1; } @@ -517,6 +517,8 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, if (SSL3_RECORD_get_length(rr) == 0) SSL3_RECORD_set_read(rr); } else { + if (s->options & SSL_OP_CLEANSE_PLAINTEXT) + OPENSSL_cleanse(&(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n); SSL3_RECORD_sub_length(rr, n); SSL3_RECORD_add_off(rr, n); if (SSL3_RECORD_get_length(rr) == 0) { @@ -533,7 +535,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && s->d1->shutdown_received - && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) <= 0) { s->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; } @@ -557,8 +559,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, || !PACKET_get_1(&alert, &alert_level) || !PACKET_get_1(&alert, &alert_descr) || PACKET_remaining(&alert) != 0) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS1_READ_BYTES, - SSL_R_INVALID_ALERT); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_INVALID_ALERT); return -1; } @@ -577,12 +578,12 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; + s->s3.warn_alert = alert_descr; SSL3_RECORD_set_read(rr); s->rlayer.alert_count++; if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS1_READ_BYTES, + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_TOO_MANY_WARN_ALERTS); return -1; } @@ -595,7 +596,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * that nothing gets discarded. */ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) > 0) { s->d1->shutdown_received = 1; s->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); @@ -607,21 +608,17 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, return 0; } } else if (alert_level == SSL3_AL_FATAL) { - char tmp[16]; - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_DTLS1_READ_BYTES, - SSL_AD_REASON_OFFSET + alert_descr); - BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); - ERR_add_error_data(2, "SSL alert number ", tmp); + s->s3.fatal_alert = alert_descr; + SSLfatal_data(s, SSL_AD_NO_ALERT, + SSL_AD_REASON_OFFSET + alert_descr, + "SSL alert number %d", alert_descr); s->shutdown |= SSL_RECEIVED_SHUTDOWN; SSL3_RECORD_set_read(rr); SSL_CTX_remove_session(s->session_ctx, s->session); return 0; } else { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_DTLS1_READ_BYTES, - SSL_R_UNKNOWN_ALERT_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE); return -1; } @@ -705,8 +702,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * finished */ if (!ossl_assert(SSL_is_init_finished(s))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -742,8 +738,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, switch (SSL3_RECORD_get_type(rr)) { default: - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS1_READ_BYTES, - SSL_R_UNEXPECTED_RECORD); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; case SSL3_RT_CHANGE_CIPHER_SPEC: case SSL3_RT_ALERT: @@ -753,8 +748,7 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but * that should not happen when type != rr->type */ - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS1_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR); return -1; case SSL3_RT_APPLICATION_DATA: /* @@ -764,14 +758,13 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * application data at this point (session renegotiation not yet * started), we will indulge it. */ - if (s->s3->in_read_app_data && - (s->s3->total_renegotiations != 0) && + if (s->s3.in_read_app_data && + (s->s3.total_renegotiations != 0) && ossl_statem_app_data_allowed(s)) { - s->s3->in_read_app_data = 2; + s->s3.in_read_app_data = 2; return -1; } else { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS1_READ_BYTES, - SSL_R_UNEXPECTED_RECORD); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; } } @@ -788,8 +781,7 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf, size_t len, int i; if (!ossl_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_WRITE_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } s->rwstate = SSL_NOTHING; @@ -815,13 +807,12 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, * the buffer. */ if (!ossl_assert(SSL3_BUFFER_get_left(wb) == 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { + if (s->s3.alert_dispatch) { i = s->method->ssl_dispatch_alert(s); if (i <= 0) return i; @@ -832,23 +823,23 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, return 0; if (len > ssl_get_max_send_fragment(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, - SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); return 0; } sess = s->session; - if ((sess == NULL) || - (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) + if ((sess == NULL) + || (s->enc_write_ctx == NULL) + || (EVP_MD_CTX_get0_md(s->write_hash) == NULL)) clear = 1; if (clear) mac_size = 0; else { - mac_size = EVP_MD_CTX_size(s->write_hash); + mac_size = EVP_MD_CTX_get_size(s->write_hash); if (mac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); return -1; } @@ -880,9 +871,13 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* Explicit IV length, block ciphers appropriate version flag */ if (s->enc_write_ctx) { - int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx); if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx); + if (eivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); + return -1; + } if (eivlen <= 1) eivlen = 0; } @@ -908,8 +903,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* first we compress */ if (s->compress != NULL) { if (!ssl3_do_compress(s, &wr)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, - SSL_R_COMPRESSION_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE); return -1; } } else { @@ -928,8 +922,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, if (!s->method->ssl3_enc->mac(s, &wr, &(p[SSL3_RECORD_get_length(&wr) + eivlen]), 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } SSL3_RECORD_add_length(&wr, mac_size); @@ -942,10 +935,9 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, if (eivlen) SSL3_RECORD_add_length(&wr, eivlen); - if (s->method->ssl3_enc->enc(s, &wr, 1, 1) < 1) { + if (s->method->ssl3_enc->enc(s, &wr, 1, 1, NULL, mac_size) < 1) { if (!ossl_statem_in_error(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); } return -1; } @@ -953,8 +945,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, if (SSL_WRITE_ETM(s) && mac_size != 0) { if (!s->method->ssl3_enc->mac(s, &wr, &(p[SSL3_RECORD_get_length(&wr)]), 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_DTLS1_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } SSL3_RECORD_add_length(&wr, mac_size); diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 1db1712a0986..4121f3b2ae1c 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. 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 @@ -15,11 +15,11 @@ #include <openssl/buffer.h> #include <openssl/rand.h> #include "record_local.h" -#include "../packet_local.h" +#include "internal/packet.h" #include "internal/cryptlib.h" #if defined(OPENSSL_SMALL_FOOTPRINT) || \ - !( defined(AESNI_ASM) && ( \ + !( defined(AES_ASM) && ( \ defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined(_M_X64) ) \ ) @@ -276,16 +276,19 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, if (n > rb->len - rb->offset) { /* does not happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } - /* We always act like read_ahead is set for DTLS */ - if (!s->rlayer.read_ahead && !SSL_IS_DTLS(s)) + /* + * Ktls always reads full records. + * Also, we always act like read_ahead is set for DTLS. + */ + if (!BIO_get_ktls_recv(s->rbio) && !s->rlayer.read_ahead + && !SSL_IS_DTLS(s)) { /* ignore max parameter */ max = n; - else { + } else { if (max < n) max = n; if (max > rb->len - rb->offset) @@ -297,7 +300,7 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, int ret; /* - * Now we have len+left bytes at the front of s->s3->rbuf.buf and + * Now we have len+left bytes at the front of s->s3.rbuf.buf and * need to read in more until we have len+n (up to len+max if * possible) */ @@ -305,13 +308,22 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, clear_sys_error(); if (s->rbio != NULL) { s->rwstate = SSL_READING; - /* TODO(size_t): Convert this function */ ret = BIO_read(s->rbio, pkt + len + left, max - left); if (ret >= 0) bioread = ret; + if (ret <= 0 + && !BIO_should_retry(s->rbio) + && BIO_eof(s->rbio)) { + if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) { + SSL_set_shutdown(s, SSL_RECEIVED_SHUTDOWN); + s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY; + } else { + SSLfatal(s, SSL_AD_DECODE_ERROR, + SSL_R_UNEXPECTED_EOF_WHILE_READING); + } + } } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N, - SSL_R_READ_BIO_NOT_SET); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_READ_BIO_NOT_SET); ret = -1; } @@ -373,8 +385,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, */ if ((len < s->rlayer.wnum) || ((wb->left != 0) && (len < (s->rlayer.wnum + s->rlayer.wpend_tot)))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_BYTES, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_LENGTH); return -1; } @@ -387,10 +398,12 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, s->rlayer.wnum = 0; /* - * If we are supposed to be sending a KeyUpdate then go into init unless we - * have writes pending - in which case we should finish doing that first. + * If we are supposed to be sending a KeyUpdate or NewSessionTicket then go + * into init unless we have writes pending - in which case we should finish + * doing that first. */ - if (wb->left == 0 && s->key_update != SSL_KEY_UPDATE_NONE) + if (wb->left == 0 && (s->key_update != SSL_KEY_UPDATE_NONE + || s->ext.extra_tickets_expected > 0)) ossl_statem_set_in_init(s, 1); /* @@ -431,12 +444,15 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * jumbo buffer to accommodate up to 8 records, but the * compromise is considered worthy. */ - if (type == SSL3_RT_APPLICATION_DATA && - len >= 4 * (max_send_fragment = ssl_get_max_send_fragment(s)) && - s->compress == NULL && s->msg_callback == NULL && - !SSL_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) && - EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) & - EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { + if (type == SSL3_RT_APPLICATION_DATA + && len >= 4 * (max_send_fragment = ssl_get_max_send_fragment(s)) + && s->compress == NULL + && s->msg_callback == NULL + && !SSL_WRITE_ETM(s) + && SSL_USE_EXPLICIT_IV(s) + && BIO_get_ktls_send(s->wbio) == 0 + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) + & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) != 0) { unsigned char aad[13]; EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; size_t packlen; @@ -477,7 +493,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, break; } - if (s->s3->alert_dispatch) { + if (s->s3.alert_dispatch) { i = s->method->ssl_dispatch_alert(s); if (i <= 0) { /* SSLfatal() already called if appropriate */ @@ -579,24 +595,23 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * We should have prevented this when we set max_pipelines so we * shouldn't get here */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } if (maxpipes == 0 || s->enc_write_ctx == NULL - || !(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) - & EVP_CIPH_FLAG_PIPELINE) + || (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) + & EVP_CIPH_FLAG_PIPELINE) == 0 || !SSL_USE_EXPLICIT_IV(s)) maxpipes = 1; - if (max_send_fragment == 0 || split_send_fragment == 0 - || split_send_fragment > max_send_fragment) { + if (max_send_fragment == 0 + || split_send_fragment == 0 + || split_send_fragment > max_send_fragment) { /* * We should have prevented this when we set/get the split and max send * fragments so we shouldn't get here */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -646,7 +661,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, size_t len, * next chunk of data should get another prepended empty fragment * in ciphersuites with known-IV weakness: */ - s->s3->empty_fragment_done = 0; + s->s3.empty_fragment_done = 0; if (tmpwrit == n && (s->mode & SSL_MODE_RELEASE_BUFFERS) != 0 @@ -692,7 +707,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, } /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { + if (s->s3.alert_dispatch) { i = s->method->ssl_dispatch_alert(s); if (i <= 0) { /* SSLfatal() already called if appropriate */ @@ -713,16 +728,15 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, sess = s->session; - if ((sess == NULL) || - (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) { + if ((sess == NULL) + || (s->enc_write_ctx == NULL) + || (EVP_MD_CTX_get0_md(s->write_hash) == NULL)) { clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ mac_size = 0; } else { - /* TODO(siz_t): Convert me */ - mac_size = EVP_MD_CTX_size(s->write_hash); + mac_size = EVP_MD_CTX_get_size(s->write_hash); if (mac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } @@ -730,13 +744,13 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* * 'create_empty_fragment' is true only when this function calls itself */ - if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) { + if (!clear && !create_empty_fragment && !s->s3.empty_fragment_done) { /* * countermeasure against known-IV weakness in CBC ciphersuites (see * http://www.openssl.org/~bodo/tls-cbc.txt) */ - if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { + if (s->s3.need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { /* * recursive function call with 'create_empty_fragment' set; this * prepares and buffers the data for an empty fragment (these @@ -755,13 +769,25 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (prefix_len > (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { /* insufficient space */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } - s->s3->empty_fragment_done = 1; + s->s3.empty_fragment_done = 1; + } + + if (BIO_get_ktls_send(s->wbio)) { + /* + * ktls doesn't modify the buffer, but to avoid a warning we need to + * discard the const qualifier. + * This doesn't leak memory because the buffers have been released when + * switching to ktls. + */ + SSL3_BUFFER_set_buf(&s->rlayer.wbuf[0], (unsigned char *)buf); + SSL3_BUFFER_set_offset(&s->rlayer.wbuf[0], 0); + SSL3_BUFFER_set_app_buffer(&s->rlayer.wbuf[0], 1); + goto wpacket_init_complete; } if (create_empty_fragment) { @@ -779,8 +805,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (!WPACKET_init_static_len(&pkt[0], SSL3_BUFFER_get_buf(wb), SSL3_BUFFER_get_len(wb), 0) || !WPACKET_allocate_bytes(&pkt[0], align, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } wpinited = 1; @@ -791,8 +816,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, SSL3_BUFFER_get_len(wb), 0) || !WPACKET_allocate_bytes(&pkt[0], SSL3_BUFFER_get_offset(wb) + prefix_len, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } wpinited = 1; @@ -809,8 +833,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (!WPACKET_init_static_len(thispkt, SSL3_BUFFER_get_buf(wb), SSL3_BUFFER_get_len(wb), 0) || !WPACKET_allocate_bytes(thispkt, align, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } wpinited++; @@ -819,10 +842,13 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* Explicit IV length, block ciphers appropriate version flag */ if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && !SSL_TREAT_AS_TLS13(s)) { - int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx); if (mode == EVP_CIPH_CBC_MODE) { - /* TODO(size_t): Convert me */ - eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx); + if (eivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); + goto err; + } if (eivlen <= 1) eivlen = 0; } else if (mode == EVP_CIPH_GCM_MODE) { @@ -833,6 +859,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, } } + wpacket_init_complete: + totlen = 0; /* Clear our SSL3_RECORD structures */ memset(wr, 0, sizeof(wr)); @@ -874,17 +902,20 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (s->compress != NULL) maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD; - /* write the header */ - if (!WPACKET_put_bytes_u8(thispkt, rectype) + /* + * When using offload kernel will write the header. + * Otherwise write the header now + */ + if (!BIO_get_ktls_send(s->wbio) + && (!WPACKET_put_bytes_u8(thispkt, rectype) || !WPACKET_put_bytes_u16(thispkt, version) || !WPACKET_start_sub_packet_u16(thispkt) || (eivlen > 0 && !WPACKET_allocate_bytes(thispkt, eivlen, NULL)) || (maxcomplen > 0 && !WPACKET_reserve_bytes(thispkt, maxcomplen, - &compressdata))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + &compressdata)))) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -903,28 +934,30 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (s->compress != NULL) { if (!ssl3_do_compress(s, thiswr) || !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - SSL_R_COMPRESSION_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE); goto err; } } else { - if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); - goto err; + if (BIO_get_ktls_send(s->wbio)) { + SSL3_RECORD_reset_data(&wr[j]); + } else { + if (!WPACKET_memcpy(thispkt, thiswr->input, thiswr->length)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + SSL3_RECORD_reset_input(&wr[j]); } - SSL3_RECORD_reset_input(&wr[j]); } if (SSL_TREAT_AS_TLS13(s) + && !BIO_get_ktls_send(s->wbio) && s->enc_write_ctx != NULL && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS || type != SSL3_RT_ALERT)) { size_t rlen, max_send_fragment; if (!WPACKET_put_bytes_u8(thispkt, type)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } SSL3_RECORD_add_length(thiswr, 1); @@ -957,7 +990,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (padding > max_padding) padding = max_padding; if (!WPACKET_memset(thispkt, 0, padding)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -972,13 +1005,12 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * in the wb->buf */ - if (!SSL_WRITE_ETM(s) && mac_size != 0) { + if (!BIO_get_ktls_send(s->wbio) && !SSL_WRITE_ETM(s) && mac_size != 0) { unsigned char *mac; if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) || !s->method->ssl3_enc->mac(s, thiswr, mac, 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } @@ -989,26 +1021,25 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * max encrypted overhead does not need to include an allocation for that * MAC */ - if (!WPACKET_reserve_bytes(thispkt, - SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD - - mac_size, - NULL) - /* - * We also need next the amount of bytes written to this - * sub-packet - */ + if (!BIO_get_ktls_send(s->wbio)) { + if (!WPACKET_reserve_bytes(thispkt, + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + - mac_size, NULL) + /* + * We also need next the amount of bytes written to this + * sub-packet + */ || !WPACKET_get_length(thispkt, &len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; - } - - /* Get a pointer to the start of this record excluding header */ - recordstart = WPACKET_get_curr(thispkt) - len; + } - SSL3_RECORD_set_data(thiswr, recordstart); - SSL3_RECORD_reset_input(thiswr); - SSL3_RECORD_set_length(thiswr, len); + /* Get a pointer to the start of this record excluding header */ + recordstart = WPACKET_get_curr(thispkt) - len; + SSL3_RECORD_set_data(thiswr, recordstart); + SSL3_RECORD_reset_input(thiswr); + SSL3_RECORD_set_length(thiswr, len); + } } if (s->statem.enc_write_state == ENC_WRITE_STATE_WRITE_PLAIN_ALERTS) { @@ -1016,20 +1047,21 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * We haven't actually negotiated the version yet, but we're trying to * send early data - so we need to use the tls13enc function. */ - if (tls13_enc(s, wr, numpipes, 1) < 1) { + if (tls13_enc(s, wr, numpipes, 1, NULL, mac_size) < 1) { if (!ossl_statem_in_error(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); } goto err; } } else { - if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1) { - if (!ossl_statem_in_error(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + if (!BIO_get_ktls_send(s->wbio)) { + if (s->method->ssl3_enc->enc(s, wr, numpipes, 1, NULL, + mac_size) < 1) { + if (!ossl_statem_in_error(s)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + } + goto err; } - goto err; } } @@ -1039,6 +1071,9 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, thispkt = &pkt[j]; thiswr = &wr[j]; + if (BIO_get_ktls_send(s->wbio)) + goto mac_done; + /* Allocate bytes for the encryption overhead */ if (!WPACKET_get_length(thispkt, &origlen) /* Check we allowed enough room for the encryption growth */ @@ -1048,9 +1083,9 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, || origlen > thiswr->length || (thiswr->length > origlen && !WPACKET_allocate_bytes(thispkt, - thiswr->length - origlen, NULL))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + thiswr->length - origlen, + NULL))) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (SSL_WRITE_ETM(s) && mac_size != 0) { @@ -1058,8 +1093,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac) || !s->method->ssl3_enc->mac(s, thiswr, mac, 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } SSL3_RECORD_add_length(thiswr, mac_size); @@ -1067,39 +1101,32 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (!WPACKET_get_length(thispkt, &len) || !WPACKET_close(thispkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (s->msg_callback) { recordstart = WPACKET_get_curr(thispkt) - len - SSL3_RT_HEADER_LENGTH; - s->msg_callback(1, 0, SSL3_RT_HEADER, recordstart, + s->msg_callback(1, thiswr->rec_version, SSL3_RT_HEADER, recordstart, SSL3_RT_HEADER_LENGTH, s, s->msg_callback_arg); if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) { unsigned char ctype = type; - s->msg_callback(1, s->version, SSL3_RT_INNER_CONTENT_TYPE, + s->msg_callback(1, thiswr->rec_version, SSL3_RT_INNER_CONTENT_TYPE, &ctype, 1, s, s->msg_callback_arg); } } if (!WPACKET_finish(thispkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - /* - * we should now have thiswr->data pointing to the encrypted data, which - * is thiswr->length long - */ - SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for - * debugging */ - SSL3_RECORD_add_length(thiswr, SSL3_RT_HEADER_LENGTH); + /* header is added by the kernel when using offload */ + SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH); if (create_empty_fragment) { /* @@ -1108,14 +1135,21 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, */ if (j > 0) { /* We should never be pipelining an empty fragment!! */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DO_SSL3_WRITE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } *written = SSL3_RECORD_get_length(thiswr); return 1; } + mac_done: + /* + * we should now have thiswr->data pointing to the encrypted data, which + * is thiswr->length long + */ + SSL3_RECORD_set_type(thiswr, type); /* not needed but helps for + * debugging */ + /* now let's set up wb */ SSL3_BUFFER_set_left(&s->rlayer.wbuf[j], prefix_len + SSL3_RECORD_get_length(thiswr)); @@ -1138,7 +1172,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, return -1; } -/* if s->s3->wbuf.left != 0, we need to call this +/* if s->s3.wbuf.left != 0, we need to call this * * Return values are as per SSL_write() */ @@ -1154,8 +1188,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && (s->rlayer.wpend_buf != buf)) || (s->rlayer.wpend_type != type)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_PENDING, - SSL_R_BAD_WRITE_RETRY); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_WRITE_RETRY); return -1; } @@ -1169,7 +1202,17 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, clear_sys_error(); if (s->wbio != NULL) { s->rwstate = SSL_WRITING; - /* TODO(size_t): Convert this call */ + + /* + * To prevent coalescing of control and data messages, + * such as in buffer_write, we flush the BIO + */ + if (BIO_get_ktls_send(s->wbio) && type != SSL3_RT_APPLICATION_DATA) { + i = BIO_flush(s->wbio); + if (i <= 0) + return i; + BIO_set_ktls_ctrl_msg(s->wbio, type); + } i = BIO_write(s->wbio, (char *) &(SSL3_BUFFER_get_buf(&wb[currbuf]) [SSL3_BUFFER_get_offset(&wb[currbuf])]), @@ -1177,11 +1220,18 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, if (i >= 0) tmpwrit = i; } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_WRITE_PENDING, - SSL_R_BIO_NOT_SET); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BIO_NOT_SET); i = -1; } - if (i > 0 && tmpwrit == SSL3_BUFFER_get_left(&wb[currbuf])) { + + /* + * When an empty fragment is sent on a connection using KTLS, + * it is sent as a write of zero bytes. If this zero byte + * write succeeds, i will be 0 rather than a non-zero value. + * Treat i == 0 as success rather than an error for zero byte + * writes to permit this case. + */ + if (i >= 0 && tmpwrit == SSL3_BUFFER_get_left(&wb[currbuf])) { SSL3_BUFFER_set_left(&wb[currbuf], 0); SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit); if (currbuf + 1 < s->rlayer.numwpipes) @@ -1217,7 +1267,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, * * This function must handle any surprises the peer may have for us, such as * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec - * messages are treated as if they were handshake messages *if* the |recd_type| + * messages are treated as if they were handshake messages *if* the |recvd_type| * argument is non NULL. * Also if record payloads contain fragments too small to process, we store * them until there is enough for the respective protocol (the record protocol @@ -1257,8 +1307,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, && (type != SSL3_RT_HANDSHAKE)) || (peek && (type != SSL3_RT_APPLICATION_DATA))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -1325,8 +1374,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer); if (num_recs == 0) { /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } } @@ -1345,7 +1393,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, if (s->rlayer.handshake_fragment_len > 0 && SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE && SSL_IS_TLS13(s)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA); return -1; } @@ -1360,10 +1408,10 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, /* we now have a packet which can be read and processed */ - if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ + if (s->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); return -1; } @@ -1393,16 +1441,14 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && (s->enc_read_ctx == NULL)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_APP_DATA_IN_HANDSHAKE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_APP_DATA_IN_HANDSHAKE); return -1; } if (type == SSL3_RT_HANDSHAKE && SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC && s->rlayer.handshake_fragment_len > 0) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_CCS_RECEIVED_EARLY); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY); return -1; } @@ -1434,6 +1480,8 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, if (SSL3_RECORD_get_length(rr) == 0) SSL3_RECORD_set_read(rr); } else { + if (s->options & SSL_OP_CLEANSE_PLAINTEXT) + OPENSSL_cleanse(&(rr->data[rr->off]), n); SSL3_RECORD_sub_length(rr, n); SSL3_RECORD_add_off(rr, n); if (SSL3_RECORD_get_length(rr) == 0) { @@ -1478,8 +1526,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * initial ClientHello. Therefore |type| should always be equal to * |rr->type|. If not then something has gone horribly wrong */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } @@ -1487,13 +1534,12 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, && (s->server || rr->type != SSL3_RT_ALERT)) { /* * If we've got this far and still haven't decided on what version - * we're using then this must be a client side alert we're dealing with - * (we don't allow heartbeats yet). We shouldn't be receiving anything - * other than a ClientHello if we are a server. + * we're using then this must be a client side alert we're dealing + * with. We shouldn't be receiving anything other than a ClientHello + * if we are a server. */ s->version = rr->rec_version; - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); return -1; } @@ -1512,8 +1558,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, || !PACKET_get_1(&alert, &alert_level) || !PACKET_get_1(&alert, &alert_descr) || PACKET_remaining(&alert) != 0) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_INVALID_ALERT); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_INVALID_ALERT); return -1; } @@ -1533,12 +1578,12 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, if (alert_level == SSL3_AL_WARNING || (is_tls13 && alert_descr == SSL_AD_USER_CANCELLED)) { - s->s3->warn_alert = alert_descr; + s->s3.warn_alert = alert_descr; SSL3_RECORD_set_read(rr); s->rlayer.alert_count++; if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_TOO_MANY_WARN_ALERTS); return -1; } @@ -1555,14 +1600,11 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, s->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; } else if (alert_level == SSL3_AL_FATAL || is_tls13) { - char tmp[16]; - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_READ_BYTES, - SSL_AD_REASON_OFFSET + alert_descr); - BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); - ERR_add_error_data(2, "SSL alert number ", tmp); + s->s3.fatal_alert = alert_descr; + SSLfatal_data(s, SSL_AD_NO_ALERT, + SSL_AD_REASON_OFFSET + alert_descr, + "SSL alert number %d", alert_descr); s->shutdown |= SSL_RECEIVED_SHUTDOWN; SSL3_RECORD_set_read(rr); SSL_CTX_remove_session(s->session_ctx, s->session); @@ -1576,16 +1618,14 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * future we might have a renegotiation where we don't care if * the peer refused it where we carry on. */ - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_SSL3_READ_BYTES, - SSL_R_NO_RENEGOTIATION); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION); return -1; } else if (alert_level == SSL3_AL_WARNING) { /* We ignore any other warning alert in TLSv1.2 and below */ goto start; } - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SSL3_READ_BYTES, - SSL_R_UNKNOWN_ALERT_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE); return -1; } @@ -1623,7 +1663,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, */ SSL3_RECORD_set_length(rr, 0); SSL3_RECORD_set_read(rr); - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_READ_BYTES, + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY); return -1; } @@ -1658,8 +1698,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, } if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_CCS_RECEIVED_EARLY); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY); return -1; } @@ -1719,8 +1758,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * no progress is being made and the peer continually sends unrecognised * record types, using up resources processing them. */ - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_UNEXPECTED_RECORD); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; case SSL3_RT_CHANGE_CIPHER_SPEC: case SSL3_RT_ALERT: @@ -1730,8 +1768,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but * that should not happen when type != rr->type */ - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR); return -1; case SSL3_RT_APPLICATION_DATA: /* @@ -1742,7 +1779,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, * started), we will indulge it. */ if (ossl_statem_app_data_allowed(s)) { - s->s3->in_read_app_data = 2; + s->s3.in_read_app_data = 2; return -1; } else if (ossl_statem_skip_early_data(s)) { /* @@ -1762,8 +1799,7 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, SSL3_RECORD_set_read(rr); goto start; } else { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_READ_BYTES, - SSL_R_UNEXPECTED_RECORD); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; } } diff --git a/ssl/record/record.h b/ssl/record/record.h index af56206e07c9..234656bf9394 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. 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 @@ -25,6 +25,8 @@ typedef struct ssl3_buffer_st { size_t offset; /* how many bytes left */ size_t left; + /* 'buf' is from application for KTLS */ + int app_buffer; } SSL3_BUFFER; #define SEQ_NUM_SIZE 8 @@ -176,6 +178,12 @@ typedef struct record_layer_st { * * *****************************************************************************/ +struct ssl_mac_buf_st { + unsigned char *mac; + int alloced; +}; +typedef struct ssl_mac_buf_st SSL_MAC_BUF; + #define MIN_SSL2_RECORD_LEN 9 #define RECORD_LAYER_set_read_ahead(rl, ra) ((rl)->read_ahead = (ra)) @@ -211,13 +219,16 @@ __owur int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf, size_t len, int peek, size_t *readbytes); __owur int ssl3_setup_buffers(SSL *s); -__owur int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int send); +__owur int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int send, + SSL_MAC_BUF *mac, size_t macsize); __owur int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send); __owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, size_t len, size_t *written); -__owur int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send); +__owur int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, + SSL_MAC_BUF *mac, size_t macsize); __owur int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send); -__owur int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send); +__owur int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send, + SSL_MAC_BUF *mac, size_t macsize); int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl); void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl); void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl); diff --git a/ssl/record/record_local.h b/ssl/record/record_local.h index 5e8dd7f70442..0a929c696a55 100644 --- a/ssl/record/record_local.h +++ b/ssl/record/record_local.h @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. 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 @@ -65,6 +65,8 @@ void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); #define SSL3_BUFFER_add_offset(b, o) ((b)->offset += (o)) #define SSL3_BUFFER_is_initialised(b) ((b)->buf != NULL) #define SSL3_BUFFER_set_default_len(b, l) ((b)->default_len = (l)) +#define SSL3_BUFFER_set_app_buffer(b, l) ((b)->app_buffer = (l)) +#define SSL3_BUFFER_is_app_buffer(b) ((b)->app_buffer) void SSL3_BUFFER_clear(SSL3_BUFFER *b); void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, size_t n); @@ -88,6 +90,7 @@ int ssl3_release_write_buffer(SSL *s); #define SSL3_RECORD_get_input(r) ((r)->input) #define SSL3_RECORD_set_input(r, i) ((r)->input = (i)) #define SSL3_RECORD_reset_input(r) ((r)->input = (r)->data) +#define SSL3_RECORD_reset_data(r) ((r)->data = (r)->input) #define SSL3_RECORD_get_seq_num(r) ((r)->seq_num) #define SSL3_RECORD_get_off(r) ((r)->off) #define SSL3_RECORD_set_off(r, o) ((r)->off = (o)) @@ -104,13 +107,21 @@ void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num); int ssl3_get_record(SSL *s); __owur int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr); __owur int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr); -int ssl3_cbc_copy_mac(unsigned char *out, - const SSL3_RECORD *rec, size_t md_size); -__owur int ssl3_cbc_remove_padding(SSL3_RECORD *rec, - size_t block_size, size_t mac_size); -__owur int tls1_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - size_t block_size, size_t mac_size); +__owur int ssl3_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + OSSL_LIB_CTX *libctx); +__owur int tls1_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + int aead, + OSSL_LIB_CTX *libctx); int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); __owur int dtls1_get_record(SSL *s); int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send); diff --git a/ssl/record/ssl3_buffer.c b/ssl/record/ssl3_buffer.c index fa597c274671..f631829ef646 100644 --- a/ssl/record/ssl3_buffer.c +++ b/ssl/record/ssl3_buffer.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2023 The OpenSSL Project Authors. 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 @@ -66,8 +66,7 @@ int ssl3_setup_read_buffer(SSL *s) * We assume we're so doomed that we won't even be able to send an * alert. */ - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_SETUP_READ_BUFFER, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE); return 0; } b->buf = p; @@ -115,23 +114,26 @@ int ssl3_setup_write_buffer(SSL *s, size_t numwpipes, size_t len) for (currpipe = 0; currpipe < numwpipes; currpipe++) { SSL3_BUFFER *thiswb = &wb[currpipe]; - if (thiswb->buf != NULL && thiswb->len != len) { + if (thiswb->len != len) { OPENSSL_free(thiswb->buf); thiswb->buf = NULL; /* force reallocation */ } if (thiswb->buf == NULL) { - p = OPENSSL_malloc(len); - if (p == NULL) { - s->rlayer.numwpipes = currpipe; - /* - * We've got a malloc failure, and we're still initialising - * buffers. We assume we're so doomed that we won't even be able - * to send an alert. - */ - SSLfatal(s, SSL_AD_NO_ALERT, - SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE); - return 0; + if (s->wbio == NULL || !BIO_get_ktls_send(s->wbio)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + s->rlayer.numwpipes = currpipe; + /* + * We've got a malloc failure, and we're still initialising + * buffers. We assume we're so doomed that we won't even be able + * to send an alert. + */ + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + p = NULL; } memset(thiswb, 0, sizeof(SSL3_BUFFER)); thiswb->buf = p; @@ -164,7 +166,10 @@ int ssl3_release_write_buffer(SSL *s) while (pipes > 0) { wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1]; - OPENSSL_free(wb->buf); + if (SSL3_BUFFER_is_app_buffer(wb)) + SSL3_BUFFER_set_app_buffer(wb, 0); + else + OPENSSL_free(wb->buf); wb->buf = NULL; pipes--; } @@ -177,6 +182,8 @@ int ssl3_release_read_buffer(SSL *s) SSL3_BUFFER *b; b = RECORD_LAYER_get_rbuf(&s->rlayer); + if (s->options & SSL_OP_CLEANSE_PLAINTEXT) + OPENSSL_cleanse(b->buf, b->len); OPENSSL_free(b->buf); b->buf = NULL; return 1; diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 47c7369ed549..1867f001179f 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -1,15 +1,16 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. 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 */ #include "../ssl_local.h" -#include "internal/constant_time.h" +#include <openssl/trace.h> #include <openssl/rand.h> +#include <openssl/core_names.h> #include "record_local.h" #include "internal/cryptlib.h" @@ -114,8 +115,7 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send) if (!s->server && sess->ext.max_early_data == 0) { if (!ossl_assert(s->psksession != NULL && s->psksession->ext.max_early_data > 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_EARLY_DATA_COUNT_OK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } sess = s->psksession; @@ -131,7 +131,7 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send) if (max_early_data == 0) { SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA); + SSL_R_TOO_MUCH_EARLY_DATA); return 0; } @@ -140,7 +140,7 @@ int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send) if (s->early_data_count + length > max_early_data) { SSLfatal(s, send ? SSL_AD_INTERNAL_ERROR : SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA); + SSL_R_TOO_MUCH_EARLY_DATA); return 0; } s->early_data_count += length; @@ -181,14 +181,17 @@ int ssl3_get_record(SSL *s) unsigned char *p; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int version; - size_t mac_size; + size_t mac_size = 0; int imac_size; size_t num_recs = 0, max_recs, j; PACKET pkt, sslv2pkt; - size_t first_rec_len; + int is_ktls_left; + SSL_MAC_BUF *macbufs = NULL; + int ret = -1; rr = RECORD_LAYER_get_rrec(&s->rlayer); rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); + is_ktls_left = (SSL3_BUFFER_get_left(rbuf) > 0); max_recs = s->max_pipelines; if (max_recs == 0) max_recs = 1; @@ -207,22 +210,41 @@ int ssl3_get_record(SSL *s) rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, SSL3_BUFFER_get_len(rbuf), 0, num_recs == 0 ? 1 : 0, &n); - if (rret <= 0) - return rret; /* error or non-blocking */ + if (rret <= 0) { +#ifndef OPENSSL_NO_KTLS + if (!BIO_get_ktls_recv(s->rbio) || rret == 0) + return rret; /* error or non-blocking */ + switch (errno) { + case EBADMSG: + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + break; + case EMSGSIZE: + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, + SSL_R_PACKET_LENGTH_TOO_LONG); + break; + case EINVAL: + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, + SSL_R_WRONG_VERSION_NUMBER); + break; + default: + break; + } +#endif + return rret; + } RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY); p = RECORD_LAYER_get_packet(&s->rlayer); if (!PACKET_buf_init(&pkt, RECORD_LAYER_get_packet(&s->rlayer), RECORD_LAYER_get_packet_length(&s->rlayer))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GET_RECORD, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; } sslv2pkt = pkt; if (!PACKET_get_net_2_len(&sslv2pkt, &sslv2len) || !PACKET_get_1(&sslv2pkt, &type)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); return -1; } /* @@ -247,33 +269,35 @@ int ssl3_get_record(SSL *s) if (thisrr->length > SSL3_BUFFER_get_len(rbuf) - SSL2_RT_HEADER_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_PACKET_LENGTH_TOO_LONG); return -1; } if (thisrr->length < MIN_SSL2_RECORD_LEN) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, - SSL_R_LENGTH_TOO_SHORT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); return -1; } } else { /* SSLv3+ style record */ - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); /* Pull apart the header into the SSL3_RECORD */ if (!PACKET_get_1(&pkt, &type) || !PACKET_get_net_2(&pkt, &version) || !PACKET_get_net_2_len(&pkt, &thisrr->length)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, - ERR_R_INTERNAL_ERROR); + if (s->msg_callback) + s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); return -1; } thisrr->type = type; thisrr->rec_version = version; + if (s->msg_callback) + s->msg_callback(0, version, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); + /* * Lets check version. In TLSv1.3 we only check this field * when encryption is occurring (see later check). For the @@ -295,7 +319,7 @@ int ssl3_get_record(SSL *s) * shouldn't send a fatal alert back. We'll just * end. */ - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_WRONG_VERSION_NUMBER); return -1; } @@ -304,7 +328,7 @@ int ssl3_get_record(SSL *s) */ s->version = (unsigned short)version; } - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_VERSION_NUMBER); return -1; } @@ -318,22 +342,20 @@ int ssl3_get_record(SSL *s) strncmp((char *)p, "POST ", 5) == 0 || strncmp((char *)p, "HEAD ", 5) == 0 || strncmp((char *)p, "PUT ", 4) == 0) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD, - SSL_R_HTTP_REQUEST); + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST); return -1; } else if (strncmp((char *)p, "CONNE", 5) == 0) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_HTTPS_PROXY_REQUEST); return -1; } /* Doesn't look like TLS - don't send an alert */ - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_WRONG_VERSION_NUMBER); return -1; } else { SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); return -1; } @@ -347,11 +369,11 @@ int ssl3_get_record(SSL *s) || s->statem.enc_read_state != ENC_READ_STATE_ALLOW_PLAIN_ALERTS)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE); + SSL_R_BAD_RECORD_TYPE); return -1; } if (thisrr->rec_version != TLS1_2_VERSION) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER); return -1; } @@ -359,7 +381,7 @@ int ssl3_get_record(SSL *s) if (thisrr->length > SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_PACKET_LENGTH_TOO_LONG); return -1; } @@ -370,7 +392,7 @@ int ssl3_get_record(SSL *s) if (SSL_IS_TLS13(s)) { if (thisrr->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); return -1; } @@ -386,8 +408,12 @@ int ssl3_get_record(SSL *s) len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD; #endif + /* KTLS may use all of the buffer */ + if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left) + len = SSL3_BUFFER_get_left(rbuf); + if (thisrr->length > len) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); return -1; } @@ -404,6 +430,7 @@ int ssl3_get_record(SSL *s) } else { more = thisrr->length; } + if (more > 0) { /* now s->rlayer.packet_length == SSL3_RT_HEADER_LENGTH */ @@ -457,8 +484,8 @@ int ssl3_get_record(SSL *s) && thisrr->type == SSL3_RT_APPLICATION_DATA && SSL_USE_EXPLICIT_IV(s) && s->enc_read_ctx != NULL - && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx)) - & EVP_CIPH_FLAG_PIPELINE) + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx)) + & EVP_CIPH_FLAG_PIPELINE) != 0 && ssl3_record_app_data_waiting(s)); if (num_recs == 1 @@ -469,7 +496,7 @@ int ssl3_get_record(SSL *s) * CCS messages must be exactly 1 byte long, containing the value 0x01 */ if (thisrr->length != 1 || thisrr->data[0] != 0x01) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_CCS_MESSAGE); return -1; } @@ -481,7 +508,7 @@ int ssl3_get_record(SSL *s) RECORD_LAYER_inc_empty_record_count(&s->rlayer); if (RECORD_LAYER_get_empty_record_count(&s->rlayer) > MAX_EMPTY_RECORDS) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_CCS_MESSAGE); return -1; } @@ -492,57 +519,80 @@ int ssl3_get_record(SSL *s) } /* + * KTLS reads full records. If there is any data left, + * then it is from before enabling ktls + */ + if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left) + goto skip_decryption; + + if (s->read_hash != NULL) { + const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash); + + if (tmpmd != NULL) { + imac_size = EVP_MD_get_size(tmpmd); + if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return -1; + } + mac_size = (size_t)imac_size; + } + } + + /* * If in encrypt-then-mac mode calculate mac from encrypted record. All * the details below are public so no timing details can leak. */ if (SSL_READ_ETM(s) && s->read_hash) { unsigned char *mac; - /* TODO(size_t): convert this to do size_t properly */ - imac_size = EVP_MD_CTX_size(s->read_hash); - if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GET_RECORD, - ERR_LIB_EVP); - return -1; - } - mac_size = (size_t)imac_size; + for (j = 0; j < num_recs; j++) { thisrr = &rr[j]; if (thisrr->length < mac_size) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, - SSL_R_LENGTH_TOO_SHORT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); return -1; } thisrr->length -= mac_size; mac = thisrr->data + thisrr->length; i = s->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ ); if (i == 0 || CRYPTO_memcmp(md, mac, mac_size) != 0) { - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_F_SSL3_GET_RECORD, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); return -1; } } + /* + * We've handled the mac now - there is no MAC inside the encrypted + * record + */ + mac_size = 0; } - first_rec_len = rr[0].length; + if (mac_size > 0) { + macbufs = OPENSSL_zalloc(sizeof(*macbufs) * num_recs); + if (macbufs == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + return -1; + } + } - enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0); + enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0, macbufs, mac_size); /*- * enc_err is: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding is valid - * -1: if the padding is invalid + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or ETM decryption failed. + * 1: Success or MTE decryption failed (MAC will be randomised) */ if (enc_err == 0) { if (ossl_statem_in_error(s)) { /* SSLfatal() already got called */ - return -1; + goto end; } if (num_recs == 1 && ossl_statem_skip_early_data(s)) { /* - * Valid early_data that we cannot decrypt might fail here as - * publicly invalid. We treat it like an empty record. + * Valid early_data that we cannot decrypt will fail here. We treat + * it like an empty record. */ thisrr = &rr[0]; @@ -550,121 +600,48 @@ int ssl3_get_record(SSL *s) if (!early_data_count_ok(s, thisrr->length, EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) { /* SSLfatal() already called */ - return -1; + goto end; } thisrr->length = 0; thisrr->read = 1; RECORD_LAYER_set_numrpipes(&s->rlayer, 1); RECORD_LAYER_reset_read_sequence(&s->rlayer); - return 1; + ret = 1; + goto end; } - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_F_SSL3_GET_RECORD, - SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - return -1; - } -#ifdef SSL_DEBUG - printf("dec %lu\n", (unsigned long)rr[0].length); - { - size_t z; - for (z = 0; z < rr[0].length; z++) - printf("%02X%c", rr[0].data[z], ((z + 1) % 16) ? ' ' : '\n'); + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto end; } - printf("\n"); -#endif + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "dec %lu\n", (unsigned long)rr[0].length); + BIO_dump_indent(trc_out, rr[0].data, rr[0].length, 4); + } OSSL_TRACE_END(TLS); /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && - (s->enc_read_ctx != NULL) && - (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) { + if ((sess != NULL) + && (s->enc_read_ctx != NULL) + && (!SSL_READ_ETM(s) && EVP_MD_CTX_get0_md(s->read_hash) != NULL)) { /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - - mac_size = EVP_MD_CTX_size(s->read_hash); - if (!ossl_assert(mac_size <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GET_RECORD, - ERR_R_INTERNAL_ERROR); - return -1; - } for (j = 0; j < num_recs; j++) { + SSL_MAC_BUF *thismb = &macbufs[j]; thisrr = &rr[j]; - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (thisrr->orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - thisrr->orig_len < mac_size + 1)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, - SSL_R_LENGTH_TOO_SHORT); - return -1; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - if (!ssl3_cbc_copy_mac(mac_tmp, thisrr, mac_size)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GET_RECORD, - ERR_R_INTERNAL_ERROR); - return -1; - } - thisrr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |rec->orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - thisrr->length -= mac_size; - mac = &thisrr->data[thisrr->length]; - } i = s->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ ); - if (i == 0 || mac == NULL - || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) - enc_err = -1; + if (i == 0 || thismb == NULL || thismb->mac == NULL + || CRYPTO_memcmp(md, thismb->mac, (size_t)mac_size) != 0) + enc_err = 0; if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = -1; + enc_err = 0; } } - if (enc_err < 0) { + if (enc_err == 0) { if (ossl_statem_in_error(s)) { /* We already called SSLfatal() */ - return -1; - } - if (num_recs == 1 && ossl_statem_skip_early_data(s)) { - /* - * We assume this is unreadable early_data - we treat it like an - * empty record - */ - - /* - * The record length may have been modified by the mac check above - * so we use the previously saved value - */ - if (!early_data_count_ok(s, first_rec_len, - EARLY_DATA_CIPHERTEXT_OVERHEAD, 0)) { - /* SSLfatal() already called */ - return -1; - } - - thisrr = &rr[0]; - thisrr->length = 0; - thisrr->read = 1; - RECORD_LAYER_set_numrpipes(&s->rlayer, 1); - RECORD_LAYER_reset_read_sequence(&s->rlayer); - return 1; + goto end; } /* * A separate 'decryption_failed' alert was introduced with TLS 1.0, @@ -673,25 +650,27 @@ int ssl3_get_record(SSL *s) * not reveal which kind of error occurred -- this might become * visible to an attacker (e.g. via a logfile) */ - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - return -1; + goto end; } + skip_decryption: + for (j = 0; j < num_recs; j++) { thisrr = &rr[j]; /* thisrr->length is now just compressed */ if (s->expand != NULL) { if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_COMPRESSED_LENGTH_TOO_LONG); - return -1; + goto end; } if (!ssl3_do_uncompress(s, thisrr)) { - SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, SSL_F_SSL3_GET_RECORD, + SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, SSL_R_BAD_DECOMPRESSION); - return -1; + goto end; } } @@ -702,9 +681,8 @@ int ssl3_get_record(SSL *s) if (thisrr->length == 0 || thisrr->type != SSL3_RT_APPLICATION_DATA) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, - SSL_R_BAD_RECORD_TYPE); - return -1; + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); + goto end; } /* Strip trailing padding */ @@ -717,9 +695,8 @@ int ssl3_get_record(SSL *s) if (thisrr->type != SSL3_RT_APPLICATION_DATA && thisrr->type != SSL3_RT_ALERT && thisrr->type != SSL3_RT_HANDSHAKE) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, - SSL_R_BAD_RECORD_TYPE); - return -1; + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); + goto end; } if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE, @@ -734,23 +711,33 @@ int ssl3_get_record(SSL *s) && (thisrr->type == SSL3_RT_HANDSHAKE || thisrr->type == SSL3_RT_ALERT) && thisrr->length == 0) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, - SSL_R_BAD_LENGTH); - return -1; + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_LENGTH); + goto end; } - if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, - SSL_R_DATA_LENGTH_TOO_LONG); - return -1; + /* + * Usually thisrr->length is the length of a single record, but when + * KTLS handles the decryption, thisrr->length may be larger than + * SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced + * multiple records. + * Therefore we have to rely on KTLS to check the plaintext length + * limit in the kernel. + */ + if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH + && (!BIO_get_ktls_recv(s->rbio) || is_ktls_left)) { + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + goto end; } - /* If received packet overflows current Max Fragment Length setting */ + /* + * Check if the received packet overflows the current + * Max Fragment Length setting. + * Note: USE_MAX_FRAGMENT_LENGTH_EXT and KTLS are mutually exclusive. + */ if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_SSL3_GET_RECORD, - SSL_R_DATA_LENGTH_TOO_LONG); - return -1; + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + goto end; } thisrr->off = 0; @@ -767,9 +754,8 @@ int ssl3_get_record(SSL *s) RECORD_LAYER_inc_empty_record_count(&s->rlayer); if (RECORD_LAYER_get_empty_record_count(&s->rlayer) > MAX_EMPTY_RECORDS) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_SSL3_GET_RECORD, - SSL_R_RECORD_TOO_SMALL); - return -1; + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_RECORD_TOO_SMALL); + goto end; } } else { RECORD_LAYER_reset_empty_record_count(&s->rlayer); @@ -781,12 +767,21 @@ int ssl3_get_record(SSL *s) if (thisrr->type == SSL3_RT_APPLICATION_DATA && !early_data_count_ok(s, thisrr->length, 0, 0)) { /* SSLfatal already called */ - return -1; + goto end; } } RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs); - return 1; + ret = 1; + end: + if (macbufs != NULL) { + for (j = 0; j < num_recs; j++) { + if (macbufs[j].alloced) + OPENSSL_free(macbufs[j].mac); + } + OPENSSL_free(macbufs); + } + return ret; } int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr) @@ -801,7 +796,6 @@ int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr) if (rr->comp == NULL) return 0; - /* TODO(size_t): Convert this call */ i = COMP_expand_block(ssl->expand, rr->comp, SSL3_RT_MAX_PLAIN_LENGTH, rr->data, (int)rr->length); if (i < 0) @@ -818,7 +812,6 @@ int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr) #ifndef OPENSSL_NO_COMP int i; - /* TODO(size_t): Convert this call */ i = COMP_compress_block(ssl->compress, wr->data, (int)(wr->length + SSL3_RT_MAX_COMPRESSED_OVERHEAD), wr->input, (int)wr->length); @@ -833,23 +826,21 @@ int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr) } /*- - * ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|. Will call - * SSLfatal() for internal errors, but not otherwise. + * ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|. Calls SSLfatal on + * internal error, but not otherwise. It is the responsibility of the caller to + * report a bad_record_mac * * Returns: - * 0: (in non-constant time) if the record is publicly invalid (i.e. too - * short etc). - * 1: if the record's padding is valid / the encryption was successful. - * -1: if the record's padding is invalid or, if sending, an internal error - * occurred. + * 0: if the record is publicly invalid, or an internal error + * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised) */ -int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending) +int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending, + SSL_MAC_BUF *mac, size_t macsize) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; size_t l, i; - size_t bs, mac_size = 0; - int imac_size; + size_t bs; const EVP_CIPHER *enc; rec = inrecs; @@ -863,26 +854,31 @@ int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending) if (s->enc_write_ctx == NULL) enc = NULL; else - enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + enc = EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx); } else { ds = s->enc_read_ctx; if (s->enc_read_ctx == NULL) enc = NULL; else - enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + enc = EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx); } if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data, rec->input, rec->length); rec->input = rec->data; } else { + int provided = (EVP_CIPHER_get0_provider(enc) != NULL); + l = rec->length; - /* TODO(size_t): Convert this call */ - bs = EVP_CIPHER_CTX_block_size(ds); + bs = EVP_CIPHER_CTX_get_block_size(ds); /* COMPRESS */ - if ((bs != 1) && sending) { + if ((bs != 1) && sending && !provided) { + /* + * We only do this for legacy ciphers. Provided ciphers add the + * padding on the provider side. + */ i = bs - (l % bs); /* we need to add 'i-1' padding bytes */ @@ -897,67 +893,95 @@ int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending) } if (!sending) { - if (l == 0 || l % bs != 0) + if (l == 0 || l % bs != 0) { + /* Publicly invalid */ return 0; + } /* otherwise, rec->length >= bs */ } - /* TODO(size_t): Convert this call */ - if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) - return -1; + if (EVP_CIPHER_get0_provider(enc) != NULL) { + int outlen; - if (EVP_MD_CTX_md(s->read_hash) != NULL) { - /* TODO(size_t): convert me */ - imac_size = EVP_MD_CTX_size(s->read_hash); - if (imac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input, + (unsigned int)l)) + return 0; + rec->length = outlen; + + if (!sending && mac != NULL) { + /* Now get a pointer to the MAC */ + OSSL_PARAM params[2], *p = params; + + /* Get the MAC */ + mac->alloced = 0; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC, + (void **)&mac->mac, + macsize); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_get_params(ds, params)) { + /* Shouldn't normally happen */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } } - mac_size = (size_t)imac_size; + } else { + if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) { + /* Shouldn't happen */ + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!sending) + return ssl3_cbc_remove_padding_and_mac(&rec->length, + rec->orig_len, + rec->data, + (mac != NULL) ? &mac->mac : NULL, + (mac != NULL) ? &mac->alloced : NULL, + bs, + macsize, + s->ctx->libctx); } - if ((bs != 1) && !sending) - return ssl3_cbc_remove_padding(rec, bs, mac_size); } return 1; } #define MAX_PADDING 256 /*- - * tls1_enc encrypts/decrypts |n_recs| in |recs|. Will call SSLfatal() for - * internal errors, but not otherwise. + * tls1_enc encrypts/decrypts |n_recs| in |recs|. Calls SSLfatal on internal + * error, but not otherwise. It is the responsibility of the caller to report + * a bad_record_mac - if appropriate (DTLS just drops the record). * * Returns: - * 0: (in non-constant time) if the record is publicly invalid (i.e. too - * short etc). - * 1: if the record's padding is valid / the encryption was successful. - * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, - * an internal error occurred. + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or Encrypt-then-mac decryption failed. + * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised) */ -int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) +int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, + SSL_MAC_BUF *macs, size_t macsize) { EVP_CIPHER_CTX *ds; size_t reclen[SSL_MAX_PIPELINES]; unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN]; - int i, pad = 0, ret, tmpr; - size_t bs, mac_size = 0, ctr, padnum, loop; + int i, pad = 0, tmpr; + size_t bs, ctr, padnum, loop; unsigned char padval; - int imac_size; const EVP_CIPHER *enc; + int tlstree_enc = sending ? (s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) + : (s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE); if (n_recs == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (sending) { - if (EVP_MD_CTX_md(s->write_hash)) { - int n = EVP_MD_CTX_size(s->write_hash); + if (EVP_MD_CTX_get0_md(s->write_hash)) { + int n = EVP_MD_CTX_get_size(s->write_hash); if (!ossl_assert(n >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } } ds = s->enc_write_ctx; @@ -965,11 +989,12 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) enc = NULL; else { int ivlen; - enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + + enc = EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx); /* For TLSv1.1 and later explicit IV */ if (SSL_USE_EXPLICIT_IV(s) - && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) - ivlen = EVP_CIPHER_iv_length(enc); + && EVP_CIPHER_get_mode(enc) == EVP_CIPH_CBC_MODE) + ivlen = EVP_CIPHER_get_iv_length(enc); else ivlen = 0; if (ivlen > 1) { @@ -979,31 +1004,29 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) * we can't write into the input stream: Can this ever * happen?? (steve) */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; - } else if (RAND_bytes(recs[ctr].input, ivlen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } else if (RAND_bytes_ex(s->ctx->libctx, recs[ctr].input, + ivlen, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } } } } } else { - if (EVP_MD_CTX_md(s->read_hash)) { - int n = EVP_MD_CTX_size(s->read_hash); + if (EVP_MD_CTX_get0_md(s->read_hash)) { + int n = EVP_MD_CTX_get_size(s->read_hash); if (!ossl_assert(n >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } } ds = s->enc_read_ctx; if (s->enc_read_ctx == NULL) enc = NULL; else - enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + enc = EVP_CIPHER_CTX_get0_cipher(s->enc_read_ctx); } if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { @@ -1011,27 +1034,27 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) memmove(recs[ctr].data, recs[ctr].input, recs[ctr].length); recs[ctr].input = recs[ctr].data; } - ret = 1; } else { - bs = EVP_CIPHER_block_size(EVP_CIPHER_CTX_cipher(ds)); + int provided = (EVP_CIPHER_get0_provider(enc) != NULL); + + bs = EVP_CIPHER_get_block_size(EVP_CIPHER_CTX_get0_cipher(ds)); if (n_recs > 1) { - if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds)) - & EVP_CIPH_FLAG_PIPELINE)) { + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) + & EVP_CIPH_FLAG_PIPELINE) == 0) { /* * We shouldn't have been called with pipeline data if the * cipher doesn't support pipelining */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - SSL_R_PIPELINE_FAILURE); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); + return 0; } } for (ctr = 0; ctr < n_recs; ctr++) { reclen[ctr] = recs[ctr].length; - if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds)) - & EVP_CIPH_FLAG_AEAD_CIPHER) { + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) + & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { unsigned char *seq; seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) @@ -1062,9 +1085,8 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, EVP_AEAD_TLS1_AAD_LEN, buf[ctr]); if (pad <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } if (sending) { @@ -1072,15 +1094,18 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) recs[ctr].length += pad; } - } else if ((bs != 1) && sending) { + } else if ((bs != 1) && sending && !provided) { + /* + * We only do this for legacy ciphers. Provided ciphers add the + * padding on the provider side. + */ padnum = bs - (reclen[ctr] % bs); /* Add weird padding of up to 256 bytes */ if (padnum > MAX_PADDING) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } /* we need to add 'padnum' padding bytes of value padval */ padval = (unsigned char)(padnum - 1); @@ -1091,8 +1116,10 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) } if (!sending) { - if (reclen[ctr] == 0 || reclen[ctr] % bs != 0) + if (reclen[ctr] == 0 || reclen[ctr] % bs != 0) { + /* Publicly invalid */ return 0; + } } } if (n_recs > 1) { @@ -1104,9 +1131,8 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) } if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS, (int)n_recs, data) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - SSL_R_PIPELINE_FAILURE); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); + return 0; } /* Set the input buffers */ for (ctr = 0; ctr < n_recs; ctr++) { @@ -1116,69 +1142,156 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) (int)n_recs, data) <= 0 || EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_LENS, (int)n_recs, reclen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - SSL_R_PIPELINE_FAILURE); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PIPELINE_FAILURE); + return 0; } } - /* TODO(size_t): Convert this call */ - tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, - (unsigned int)reclen[0]); - if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds)) - & EVP_CIPH_FLAG_CUSTOM_CIPHER) - ? (tmpr < 0) - : (tmpr == 0)) - return -1; /* AEAD can fail to verify MAC */ - - if (sending == 0) { - if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE) { - for (ctr = 0; ctr < n_recs; ctr++) { - recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - } - } else if (EVP_CIPHER_mode(enc) == EVP_CIPH_CCM_MODE) { - for (ctr = 0; ctr < n_recs; ctr++) { - recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; - recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN; - } + if (!SSL_IS_DTLS(s) && tlstree_enc) { + unsigned char *seq; + int decrement_seq = 0; + + /* + * When sending, seq is incremented after MAC calculation. + * So if we are in ETM mode, we use seq 'as is' in the ctrl-function. + * Otherwise we have to decrease it in the implementation + */ + if (sending && !SSL_WRITE_ETM(s)) + decrement_seq = 1; + + seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) + : RECORD_LAYER_get_read_sequence(&s->rlayer); + if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, seq) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } } - ret = 1; - if (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL) { - imac_size = EVP_MD_CTX_size(s->read_hash); - if (imac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + if (provided) { + int outlen; + + /* Provided cipher - we do not support pipelining on this path */ + if (n_recs > 1) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } - mac_size = (size_t)imac_size; - } - if ((bs != 1) && !sending) { - int tmpret; - for (ctr = 0; ctr < n_recs; ctr++) { - tmpret = tls1_cbc_remove_padding(s, &recs[ctr], bs, mac_size); - /* - * If tmpret == 0 then this means publicly invalid so we can - * short circuit things here. Otherwise we must respect constant - * time behaviour. - */ - if (tmpret == 0) - return 0; - ret = constant_time_select_int(constant_time_eq_int(tmpret, 1), - ret, -1); + + if (!EVP_CipherUpdate(ds, recs[0].data, &outlen, recs[0].input, + (unsigned int)reclen[0])) + return 0; + recs[0].length = outlen; + + /* + * The length returned from EVP_CipherUpdate above is the actual + * payload length. We need to adjust the data/input ptr to skip over + * any explicit IV + */ + if (!sending) { + if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) { + recs[0].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + recs[0].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) { + recs[0].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; + recs[0].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; + } else if (bs != 1 && SSL_USE_EXPLICIT_IV(s)) { + recs[0].data += bs; + recs[0].input += bs; + recs[0].orig_len -= bs; + } + + /* Now get a pointer to the MAC (if applicable) */ + if (macs != NULL) { + OSSL_PARAM params[2], *p = params; + + /* Get the MAC */ + macs[0].alloced = 0; + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC, + (void **)&macs[0].mac, + macsize); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_get_params(ds, params)) { + /* Shouldn't normally happen */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + ERR_R_INTERNAL_ERROR); + return 0; + } + } } - } - if (pad && !sending) { - for (ctr = 0; ctr < n_recs; ctr++) { - recs[ctr].length -= pad; + } else { + /* Legacy cipher */ + + tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, + (unsigned int)reclen[0]); + if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) + & EVP_CIPH_FLAG_CUSTOM_CIPHER) != 0 + ? (tmpr < 0) + : (tmpr == 0)) { + /* AEAD can fail to verify MAC */ + return 0; + } + + if (!sending) { + for (ctr = 0; ctr < n_recs; ctr++) { + /* Adjust the record to remove the explicit IV/MAC/Tag */ + if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_GCM_MODE) { + recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (EVP_CIPHER_get_mode(enc) == EVP_CIPH_CCM_MODE) { + recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN; + recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN; + } else if (bs != 1 && SSL_USE_EXPLICIT_IV(s)) { + if (recs[ctr].length < bs) + return 0; + recs[ctr].data += bs; + recs[ctr].input += bs; + recs[ctr].length -= bs; + recs[ctr].orig_len -= bs; + } + + /* + * If using Mac-then-encrypt, then this will succeed but + * with a random MAC if padding is invalid + */ + if (!tls1_cbc_remove_padding_and_mac(&recs[ctr].length, + recs[ctr].orig_len, + recs[ctr].data, + (macs != NULL) ? &macs[ctr].mac : NULL, + (macs != NULL) ? &macs[ctr].alloced + : NULL, + bs, + pad ? (size_t)pad : macsize, + (EVP_CIPHER_get_flags(enc) + & EVP_CIPH_FLAG_AEAD_CIPHER) != 0, + s->ctx->libctx)) + return 0; + } } } } - return ret; + return 1; +} + +/* + * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. + */ +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ + switch (EVP_MD_CTX_get_type(ctx)) { + case NID_md5: + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + return 1; + default: + return 0; + } } int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) @@ -1191,24 +1304,27 @@ int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) int t; if (sending) { - mac_sec = &(ssl->s3->write_mac_secret[0]); + mac_sec = &(ssl->s3.write_mac_secret[0]); seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer); hash = ssl->write_hash; } else { - mac_sec = &(ssl->s3->read_mac_secret[0]); + mac_sec = &(ssl->s3.read_mac_secret[0]); seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer); hash = ssl->read_hash; } - t = EVP_MD_CTX_size(hash); - if (t < 0) + t = EVP_MD_CTX_get_size(hash); + if (t <= 0) return 0; md_size = t; npad = (48 / md_size) * md_size; - if (!sending && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(hash)) { + if (!sending + && EVP_CIPHER_CTX_get_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE + && ssl3_cbc_record_digest_supported(hash)) { +#ifdef OPENSSL_NO_DEPRECATED_3_0 + return 0; +#else /* * This is a CBC-encrypted record. We must avoid leaking any * timing-side channel information about how many blocks of data we @@ -1236,12 +1352,13 @@ int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) header[j++] = (unsigned char)(rec->length & 0xff); /* Final param == is SSLv3 */ - if (ssl3_cbc_digest_record(hash, + if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash), md, &md_size, header, rec->input, - rec->length + md_size, rec->orig_len, + rec->length, rec->orig_len, mac_sec, md_size, 1) <= 0) return 0; +#endif } else { unsigned int md_size_u; /* Chop the digest off the end :-) */ @@ -1285,9 +1402,12 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) int i; EVP_MD_CTX *hmac = NULL, *mac_ctx; unsigned char header[13]; - int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); + int stream_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM); + int tlstree_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE); int t; + int ret = 0; if (sending) { seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer); @@ -1297,7 +1417,7 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) hash = ssl->read_hash; } - t = EVP_MD_CTX_size(hash); + t = EVP_MD_CTX_get_size(hash); if (!ossl_assert(t >= 0)) return 0; md_size = t; @@ -1308,12 +1428,15 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) } else { hmac = EVP_MD_CTX_new(); if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash)) { - EVP_MD_CTX_free(hmac); - return 0; + goto end; } mac_ctx = hmac; } + if (!SSL_IS_DTLS(ssl) && tlstree_mac && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) { + goto end; + } + if (SSL_IS_DTLS(ssl)) { unsigned char dtlsseq[8], *p = dtlsseq; @@ -1331,52 +1454,33 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) header[11] = (unsigned char)(rec->length >> 8); header[12] = (unsigned char)(rec->length & 0xff); - if (!sending && !SSL_READ_ETM(ssl) && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(mac_ctx)) { - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - /* Final param == not SSLv3 */ - if (ssl3_cbc_digest_record(mac_ctx, - md, &md_size, - header, rec->input, - rec->length + md_size, rec->orig_len, - ssl->s3->read_mac_secret, - ssl->s3->read_mac_secret_size, 0) <= 0) { - EVP_MD_CTX_free(hmac); - return 0; - } - } else { - /* TODO(size_t): Convert these calls */ - if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 - || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 - || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { - EVP_MD_CTX_free(hmac); - return 0; - } - } + if (!sending && !SSL_READ_ETM(ssl) + && EVP_CIPHER_CTX_get_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE + && ssl3_cbc_record_digest_supported(mac_ctx)) { + OSSL_PARAM tls_hmac_params[2], *p = tls_hmac_params; - EVP_MD_CTX_free(hmac); + *p++ = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE, + &rec->orig_len); + *p++ = OSSL_PARAM_construct_end(); -#ifdef SSL_DEBUG - fprintf(stderr, "seq="); - { - int z; - for (z = 0; z < 8; z++) - fprintf(stderr, "%02X ", seq[z]); - fprintf(stderr, "\n"); + if (!EVP_PKEY_CTX_set_params(EVP_MD_CTX_get_pkey_ctx(mac_ctx), + tls_hmac_params)) { + goto end; + } } - fprintf(stderr, "rec="); - { - size_t z; - for (z = 0; z < rec->length; z++) - fprintf(stderr, "%02X ", rec->data[z]); - fprintf(stderr, "\n"); + + if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 + || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 + || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { + goto end; } -#endif + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "seq:\n"); + BIO_dump_indent(trc_out, seq, 8, 4); + BIO_printf(trc_out, "rec:\n"); + BIO_dump_indent(trc_out, rec->data, rec->length, 4); + } OSSL_TRACE_END(TLS); if (!SSL_IS_DTLS(ssl)) { for (i = 7; i >= 0; i--) { @@ -1385,228 +1489,14 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) break; } } -#ifdef SSL_DEBUG - { - unsigned int z; - for (z = 0; z < md_size; z++) - fprintf(stderr, "%02X ", md[z]); - fprintf(stderr, "\n"); - } -#endif - return 1; -} - -/*- - * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC - * record in |rec| by updating |rec->length| in constant time. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. - */ -int ssl3_cbc_remove_padding(SSL3_RECORD *rec, - size_t block_size, size_t mac_size) -{ - size_t padding_length; - size_t good; - const size_t overhead = 1 /* padding length byte */ + mac_size; - - /* - * These lengths are all public so we can test them in non-constant time. - */ - if (overhead > rec->length) - return 0; - - padding_length = rec->data[rec->length - 1]; - good = constant_time_ge_s(rec->length, padding_length + overhead); - /* SSLv3 requires that the padding is minimal. */ - good &= constant_time_ge_s(block_size, padding_length + 1); - rec->length -= good & (padding_length + 1); - return constant_time_select_int_s(good, 1, -1); -} - -/*- - * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC - * record in |rec| in constant time and returns 1 if the padding is valid and - * -1 otherwise. It also removes any explicit IV from the start of the record - * without leaking any timing about whether there was enough space after the - * padding was removed. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. - */ -int tls1_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - size_t block_size, size_t mac_size) -{ - size_t good; - size_t padding_length, to_check, i; - const size_t overhead = 1 /* padding length byte */ + mac_size; - /* Check if version requires explicit IV */ - if (SSL_USE_EXPLICIT_IV(s)) { - /* - * These lengths are all public so we can test them in non-constant - * time. - */ - if (overhead + block_size > rec->length) - return 0; - /* We can now safely skip explicit IV */ - rec->data += block_size; - rec->input += block_size; - rec->length -= block_size; - rec->orig_len -= block_size; - } else if (overhead > rec->length) - return 0; - - padding_length = rec->data[rec->length - 1]; - - if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx)) & - EVP_CIPH_FLAG_AEAD_CIPHER) { - /* padding is already verified */ - rec->length -= padding_length + 1; - return 1; - } - - good = constant_time_ge_s(rec->length, overhead + padding_length); - /* - * The padding consists of a length byte at the end of the record and - * then that many bytes of padding, all with the same value as the length - * byte. Thus, with the length byte included, there are i+1 bytes of - * padding. We can't check just |padding_length+1| bytes because that - * leaks decrypted information. Therefore we always have to check the - * maximum amount of padding possible. (Again, the length of the record - * is public information so we can use it.) - */ - to_check = 256; /* maximum amount of padding, inc length byte. */ - if (to_check > rec->length) - to_check = rec->length; - - for (i = 0; i < to_check; i++) { - unsigned char mask = constant_time_ge_8_s(padding_length, i); - unsigned char b = rec->data[rec->length - 1 - i]; - /* - * The final |padding_length+1| bytes should all have the value - * |padding_length|. Therefore the XOR should be zero. - */ - good &= ~(mask & (padding_length ^ b)); - } - - /* - * If any of the final |padding_length+1| bytes had the wrong value, one - * or more of the lower eight bits of |good| will be cleared. - */ - good = constant_time_eq_s(0xff, good & 0xff); - rec->length -= good & (padding_length + 1); - - return constant_time_select_int_s(good, 1, -1); -} - -/*- - * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in - * constant time (independent of the concrete value of rec->length, which may - * vary within a 256-byte window). - * - * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to - * this function. - * - * On entry: - * rec->orig_len >= md_size - * md_size <= EVP_MAX_MD_SIZE - * - * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with - * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into - * a single or pair of cache-lines, then the variable memory accesses don't - * actually affect the timing. CPUs with smaller cache-lines [if any] are - * not multi-core and are not considered vulnerable to cache-timing attacks. - */ -#define CBC_MAC_ROTATE_IN_PLACE - -int ssl3_cbc_copy_mac(unsigned char *out, - const SSL3_RECORD *rec, size_t md_size) -{ -#if defined(CBC_MAC_ROTATE_IN_PLACE) - unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; - unsigned char *rotated_mac; - char aux1, aux2, aux3, mask; -#else - unsigned char rotated_mac[EVP_MAX_MD_SIZE]; -#endif - - /* - * mac_end is the index of |rec->data| just after the end of the MAC. - */ - size_t mac_end = rec->length; - size_t mac_start = mac_end - md_size; - size_t in_mac; - /* - * scan_start contains the number of bytes that we can ignore because the - * MAC's position can only vary by 255 bytes. - */ - size_t scan_start = 0; - size_t i, j; - size_t rotate_offset; - - if (!ossl_assert(rec->orig_len >= md_size - && md_size <= EVP_MAX_MD_SIZE)) - return 0; - -#if defined(CBC_MAC_ROTATE_IN_PLACE) - rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); -#endif - - /* This information is public so it's safe to branch based on it. */ - if (rec->orig_len > md_size + 255 + 1) - scan_start = rec->orig_len - (md_size + 255 + 1); - - in_mac = 0; - rotate_offset = 0; - memset(rotated_mac, 0, md_size); - for (i = scan_start, j = 0; i < rec->orig_len; i++) { - size_t mac_started = constant_time_eq_s(i, mac_start); - size_t mac_ended = constant_time_lt_s(i, mac_end); - unsigned char b = rec->data[i]; - - in_mac |= mac_started; - in_mac &= mac_ended; - rotate_offset |= j & mac_started; - rotated_mac[j++] |= b & in_mac; - j &= constant_time_lt_s(j, md_size); - } - - /* Now rotate the MAC */ -#if defined(CBC_MAC_ROTATE_IN_PLACE) - j = 0; - for (i = 0; i < md_size; i++) { - /* - * in case cache-line is 32 bytes, - * load from both lines and select appropriately - */ - aux1 = rotated_mac[rotate_offset & ~32]; - aux2 = rotated_mac[rotate_offset | 32]; - mask = constant_time_eq_8(rotate_offset & ~32, rotate_offset); - aux3 = constant_time_select_8(mask, aux1, aux2); - out[j++] = aux3; - rotate_offset++; - rotate_offset &= constant_time_lt_s(rotate_offset, md_size); - } -#else - memset(out, 0, md_size); - rotate_offset = md_size - rotate_offset; - rotate_offset &= constant_time_lt_s(rotate_offset, md_size); - for (i = 0; i < md_size; i++) { - for (j = 0; j < md_size; j++) - out[j] |= rotated_mac[i] & constant_time_eq_8_s(j, rotate_offset); - rotate_offset++; - rotate_offset &= constant_time_lt_s(rotate_offset, md_size); - } -#endif - - return 1; + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "md:\n"); + BIO_dump_indent(trc_out, md, md_size, 4); + } OSSL_TRACE_END(TLS); + ret = 1; + end: + EVP_MD_CTX_free(hmac); + return ret; } int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) @@ -1616,9 +1506,11 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) SSL_SESSION *sess; SSL3_RECORD *rr; int imac_size; - size_t mac_size; + size_t mac_size = 0; unsigned char md[EVP_MAX_MD_SIZE]; size_t max_plain_length = SSL3_RT_MAX_PLAIN_LENGTH; + SSL_MAC_BUF macbuf = { NULL, 0 }; + int ret = 0; rr = RECORD_LAYER_get_rrec(&s->rlayer); sess = s->session; @@ -1643,8 +1535,7 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) /* check is not needed I believe */ if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); return 0; } @@ -1652,142 +1543,104 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) rr->data = rr->input; rr->orig_len = rr->length; + if (s->read_hash != NULL) { + const EVP_MD *tmpmd = EVP_MD_CTX_get0_md(s->read_hash); + + if (tmpmd != NULL) { + imac_size = EVP_MD_get_size(tmpmd); + if (!ossl_assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; + } + mac_size = (size_t)imac_size; + } + } + if (SSL_READ_ETM(s) && s->read_hash) { unsigned char *mac; - mac_size = EVP_MD_CTX_size(s->read_hash); - if (!ossl_assert(mac_size <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_PROCESS_RECORD, - ERR_R_INTERNAL_ERROR); - return 0; - } + if (rr->orig_len < mac_size) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_LENGTH_TOO_SHORT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); return 0; } rr->length -= mac_size; mac = rr->data + rr->length; i = s->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ ); if (i == 0 || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) { - SSLfatal(s, SSL_AD_BAD_RECORD_MAC, SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + SSLfatal(s, SSL_AD_BAD_RECORD_MAC, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); return 0; } + /* + * We've handled the mac now - there is no MAC inside the encrypted + * record + */ + mac_size = 0; } - enc_err = s->method->ssl3_enc->enc(s, rr, 1, 0); + /* + * Set a mark around the packet decryption attempt. This is DTLS, so + * bad packets are just ignored, and we don't want to leave stray + * errors in the queue from processing bogus junk that we ignored. + */ + ERR_set_mark(); + enc_err = s->method->ssl3_enc->enc(s, rr, 1, 0, &macbuf, mac_size); + /*- * enc_err is: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding is valid - * -1: if the padding is invalid + * 0: if the record is publicly invalid, or an internal error, or AEAD + * decryption failed, or ETM decryption failed. + * 1: Success or MTE decryption failed (MAC will be randomised) */ if (enc_err == 0) { + ERR_pop_to_mark(); if (ossl_statem_in_error(s)) { /* SSLfatal() got called */ - return 0; + goto end; } /* For DTLS we simply ignore bad packets. */ rr->length = 0; RECORD_LAYER_reset_packet_length(&s->rlayer); - return 0; - } -#ifdef SSL_DEBUG - printf("dec %ld\n", rr->length); - { - size_t z; - for (z = 0; z < rr->length; z++) - printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); + goto end; } - printf("\n"); -#endif + ERR_clear_last_mark(); + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "dec %zd\n", rr->length); + BIO_dump_indent(trc_out, rr->data, rr->length, 4); + } OSSL_TRACE_END(TLS); /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && !SSL_READ_ETM(s) && - (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { + if ((sess != NULL) + && !SSL_READ_ETM(s) + && (s->enc_read_ctx != NULL) + && (EVP_MD_CTX_get0_md(s->read_hash) != NULL)) { /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - - /* TODO(size_t): Convert this to do size_t properly */ - imac_size = EVP_MD_CTX_size(s->read_hash); - if (imac_size < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_PROCESS_RECORD, - ERR_LIB_EVP); - return 0; - } - mac_size = (size_t)imac_size; - if (!ossl_assert(mac_size <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_PROCESS_RECORD, - ERR_R_INTERNAL_ERROR); - return 0; - } - - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (rr->orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - rr->orig_len < mac_size + 1)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_LENGTH_TOO_SHORT); - return 0; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - if (!ssl3_cbc_copy_mac(mac_tmp, rr, mac_size)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_PROCESS_RECORD, - ERR_R_INTERNAL_ERROR); - return 0; - } - rr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |rec->orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - rr->length -= mac_size; - mac = &rr->data[rr->length]; - } i = s->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ ); - if (i == 0 || mac == NULL - || CRYPTO_memcmp(md, mac, mac_size) != 0) - enc_err = -1; + if (i == 0 || macbuf.mac == NULL + || CRYPTO_memcmp(md, macbuf.mac, mac_size) != 0) + enc_err = 0; if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = -1; + enc_err = 0; } - if (enc_err < 0) { + if (enc_err == 0) { /* decryption failed, silently discard message */ rr->length = 0; RECORD_LAYER_reset_packet_length(&s->rlayer); - return 0; + goto end; } /* r->length is now just compressed */ if (s->expand != NULL) { if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_DTLS1_PROCESS_RECORD, + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_COMPRESSED_LENGTH_TOO_LONG); - return 0; + goto end; } if (!ssl3_do_uncompress(s, rr)) { - SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, - SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION); - return 0; + SSLfatal(s, SSL_AD_DECOMPRESSION_FAILURE, SSL_R_BAD_DECOMPRESSION); + goto end; } } @@ -1797,19 +1650,18 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) /* send overflow if the plaintext is too long now it has passed MAC */ if (rr->length > max_plain_length) { - SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_DATA_LENGTH_TOO_LONG); - return 0; + SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); + goto end; } rr->off = 0; /*- * So at this point the following is true - * ssl->s3->rrec.type is the type of record - * ssl->s3->rrec.length == number of bytes in record - * ssl->s3->rrec.off == offset to first valid byte - * ssl->s3->rrec.data == where to take bytes from, increment - * after use :-). + * ssl->s3.rrec.type is the type of record + * ssl->s3.rrec.length == number of bytes in record + * ssl->s3.rrec.off == offset to first valid byte + * ssl->s3.rrec.data == where to take bytes from, increment + * after use :-). */ /* we have pulled in a full packet so zero things */ @@ -1818,7 +1670,11 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) /* Mark receipt of record. */ dtls1_record_bitmap_update(s, bitmap); - return 1; + ret = 1; + end: + if (macbuf.alloced) + OPENSSL_free(macbuf.mac); + return ret; } /* @@ -1833,9 +1689,9 @@ int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) * It will return <= 0 if more data is needed, normally due to an error * or non-blocking IO. * When it finishes, one packet has been decoded and can be found in - * ssl->s3->rrec.type - is the type of record - * ssl->s3->rrec.data, - data - * ssl->s3->rrec.length, - number of bytes + * ssl->s3.rrec.type - is the type of record + * ssl->s3.rrec.data - data + * ssl->s3.rrec.length - number of bytes */ /* used only by dtls1_read_bytes */ int dtls1_get_record(SSL *s) @@ -1990,10 +1846,6 @@ int dtls1_get_record(SSL *s) if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { #endif /* Check whether this is a repeat, or aged record. */ - /* - * TODO: Does it make sense to have replay protection in epoch 0 where - * we have no integrity negotiated yet? - */ if (!dtls1_record_replay_check(s, bitmap)) { rr->length = 0; rr->read = 1; diff --git a/ssl/record/ssl3_record_tls13.c b/ssl/record/ssl3_record_tls13.c index ab50e3762499..c605fa74d217 100644 --- a/ssl/record/ssl3_record_tls13.c +++ b/ssl/record/ssl3_record_tls13.c @@ -1,7 +1,7 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2022 The OpenSSL Project Authors. 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 @@ -12,21 +12,21 @@ #include "internal/cryptlib.h" /*- - * tls13_enc encrypts/decrypts |n_recs| in |recs|. Will call SSLfatal() for - * internal errors, but not otherwise. + * tls13_enc encrypts/decrypts |n_recs| in |recs|. Calls SSLfatal on internal + * error, but not otherwise. It is the responsibility of the caller to report + * a bad_record_mac. * * Returns: - * 0: (in non-constant time) if the record is publicly invalid (i.e. too - * short etc). - * 1: if the record encryption was successful. - * -1: if the record's AEAD-authenticator is invalid or, if sending, - * an internal error occurred. + * 0: On failure + * 1: if the record encryption/decryption was successful. */ -int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) +int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, + ossl_unused SSL_MAC_BUF *mac, ossl_unused size_t macsize) { EVP_CIPHER_CTX *ctx; unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH]; - size_t ivlen, taglen, offset, loop, hdrlen; + size_t taglen, offset, loop, hdrlen; + int ivlen; unsigned char *staticiv; unsigned char *seq; int lenu, lenf; @@ -36,10 +36,8 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) if (n_recs != 1) { /* Should not happen */ - /* TODO(TLS1.3): Support pipelining */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } if (sending) { @@ -64,7 +62,11 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) return 1; } - ivlen = EVP_CIPHER_CTX_iv_length(ctx); + ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + if (ivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } if (s->early_data_state == SSL_EARLY_DATA_WRITING || s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) { @@ -73,9 +75,8 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) } else { if (!ossl_assert(s->psksession != NULL && s->psksession->ext.max_early_data > 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } alg_enc = s->psksession->cipher->algorithm_enc; } @@ -84,12 +85,11 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) * To get here we must have selected a ciphersuite - otherwise ctx would * be NULL */ - if (!ossl_assert(s->s3->tmp.new_cipher != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + if (!ossl_assert(s->s3.tmp.new_cipher != NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } - alg_enc = s->s3->tmp.new_cipher->algorithm_enc; + alg_enc = s->s3.tmp.new_cipher->algorithm_enc; } if (alg_enc & SSL_AESCCM) { @@ -99,18 +99,16 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) taglen = EVP_CCM_TLS_TAG_LEN; if (sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } } else if (alg_enc & SSL_AESGCM) { taglen = EVP_GCM_TLS_TAG_LEN; } else if (alg_enc & SSL_CHACHA20) { taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } if (!sending) { @@ -126,9 +124,8 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) /* Set up IV */ if (ivlen < SEQ_NUM_SIZE) { /* Should not happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } offset = ivlen - SEQ_NUM_SIZE; memcpy(iv, staticiv, offset); @@ -143,15 +140,15 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) } if (loop == 0) { /* Sequence has wrapped */ - return -1; + return 0; } - /* TODO(size_t): lenu/lenf should be a size_t but EVP doesn't support it */ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0 || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, rec->data + rec->length) <= 0)) { - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } /* Set up the AAD */ @@ -162,8 +159,9 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) || !WPACKET_get_total_written(&wpkt, &hdrlen) || hdrlen != SSL3_RT_HEADER_LENGTH || !WPACKET_finish(&wpkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); WPACKET_cleanup(&wpkt); - return -1; + return 0; } /* @@ -179,15 +177,14 @@ int tls13_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) (unsigned int)rec->length) <= 0 || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 || (size_t)(lenu + lenf) != rec->length) { - return -1; + return 0; } if (sending) { /* Add the tag */ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, rec->data + rec->length) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_ENC, - ERR_R_INTERNAL_ERROR); - return -1; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } rec->length += taglen; } diff --git a/ssl/record/tls_pad.c b/ssl/record/tls_pad.c new file mode 100644 index 000000000000..d79c4e9f6315 --- /dev/null +++ b/ssl/record/tls_pad.c @@ -0,0 +1,325 @@ +/* + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * 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 + */ + +#include <openssl/rand.h> +#include <openssl/evp.h> +#include "internal/constant_time.h" +#include "internal/cryptlib.h" + +/* + * This file has no dependencies on the rest of libssl because it is shared + * with the providers. It contains functions for low level CBC TLS padding + * removal. Responsibility for this lies with the cipher implementations in the + * providers. However there are legacy code paths in libssl which also need to + * do this. In time those legacy code paths can be removed and this file can be + * moved out of libssl. + */ + +static int ssl3_cbc_copy_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, + size_t mac_size, + size_t good, + OSSL_LIB_CTX *libctx); + +int ssl3_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + OSSL_LIB_CTX *libctx); + +int tls1_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + int aead, + OSSL_LIB_CTX *libctx); + +/*- + * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC + * record in |recdata| by updating |reclen| in constant time. It also extracts + * the MAC from the underlying record and places a pointer to it in |mac|. The + * MAC data can either be newly allocated memory, or a pointer inside the + * |recdata| buffer. If allocated then |*alloced| is set to 1, otherwise it is + * set to 0. + * + * origreclen: the original record length before any changes were made + * block_size: the block size of the cipher used to encrypt the record. + * mac_size: the size of the MAC to be extracted + * aead: 1 if an AEAD cipher is in use, or 0 otherwise + * returns: + * 0: if the record is publicly invalid. + * 1: if the record is publicly valid. If the padding removal fails then the + * MAC returned is random. + */ +int ssl3_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + OSSL_LIB_CTX *libctx) +{ + size_t padding_length; + size_t good; + const size_t overhead = 1 /* padding length byte */ + mac_size; + + /* + * These lengths are all public so we can test them in non-constant time. + */ + if (overhead > *reclen) + return 0; + + padding_length = recdata[*reclen - 1]; + good = constant_time_ge_s(*reclen, padding_length + overhead); + /* SSLv3 requires that the padding is minimal. */ + good &= constant_time_ge_s(block_size, padding_length + 1); + *reclen -= good & (padding_length + 1); + + return ssl3_cbc_copy_mac(reclen, origreclen, recdata, mac, alloced, + block_size, mac_size, good, libctx); +} + +/*- + * tls1_cbc_remove_padding_and_mac removes padding from the decrypted, TLS, CBC + * record in |recdata| by updating |reclen| in constant time. It also extracts + * the MAC from the underlying record and places a pointer to it in |mac|. The + * MAC data can either be newly allocated memory, or a pointer inside the + * |recdata| buffer. If allocated then |*alloced| is set to 1, otherwise it is + * set to 0. + * + * origreclen: the original record length before any changes were made + * block_size: the block size of the cipher used to encrypt the record. + * mac_size: the size of the MAC to be extracted + * aead: 1 if an AEAD cipher is in use, or 0 otherwise + * returns: + * 0: if the record is publicly invalid. + * 1: if the record is publicly valid. If the padding removal fails then the + * MAC returned is random. + */ +int tls1_cbc_remove_padding_and_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, size_t mac_size, + int aead, + OSSL_LIB_CTX *libctx) +{ + size_t good = -1; + size_t padding_length, to_check, i; + size_t overhead = ((block_size == 1) ? 0 : 1) /* padding length byte */ + + mac_size; + + /* + * These lengths are all public so we can test them in non-constant + * time. + */ + if (overhead > *reclen) + return 0; + + if (block_size != 1) { + + padding_length = recdata[*reclen - 1]; + + if (aead) { + /* padding is already verified and we don't need to check the MAC */ + *reclen -= padding_length + 1 + mac_size; + return 1; + } + + good = constant_time_ge_s(*reclen, overhead + padding_length); + /* + * The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the + * length byte. Thus, with the length byte included, there are i+1 bytes + * of padding. We can't check just |padding_length+1| bytes because that + * leaks decrypted information. Therefore we always have to check the + * maximum amount of padding possible. (Again, the length of the record + * is public information so we can use it.) + */ + to_check = 256; /* maximum amount of padding, inc length byte. */ + if (to_check > *reclen) + to_check = *reclen; + + for (i = 0; i < to_check; i++) { + unsigned char mask = constant_time_ge_8_s(padding_length, i); + unsigned char b = recdata[*reclen - 1 - i]; + /* + * The final |padding_length+1| bytes should all have the value + * |padding_length|. Therefore the XOR should be zero. + */ + good &= ~(mask & (padding_length ^ b)); + } + + /* + * If any of the final |padding_length+1| bytes had the wrong value, one + * or more of the lower eight bits of |good| will be cleared. + */ + good = constant_time_eq_s(0xff, good & 0xff); + *reclen -= good & (padding_length + 1); + } + + return ssl3_cbc_copy_mac(reclen, origreclen, recdata, mac, alloced, + block_size, mac_size, good, libctx); +} + +/*- + * ssl3_cbc_copy_mac copies |md_size| bytes from the end of the record in + * |recdata| to |*mac| in constant time (independent of the concrete value of + * the record length |reclen|, which may vary within a 256-byte window). + * + * On entry: + * origreclen >= mac_size + * mac_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single or pair of cache-lines, then the variable memory accesses don't + * actually affect the timing. CPUs with smaller cache-lines [if any] are + * not multi-core and are not considered vulnerable to cache-timing attacks. + */ +#define CBC_MAC_ROTATE_IN_PLACE + +static int ssl3_cbc_copy_mac(size_t *reclen, + size_t origreclen, + unsigned char *recdata, + unsigned char **mac, + int *alloced, + size_t block_size, + size_t mac_size, + size_t good, + OSSL_LIB_CTX *libctx) +{ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; + char aux1, aux2, aux3, mask; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + unsigned char randmac[EVP_MAX_MD_SIZE]; + unsigned char *out; + + /* + * mac_end is the index of |recdata| just after the end of the MAC. + */ + size_t mac_end = *reclen; + size_t mac_start = mac_end - mac_size; + size_t in_mac; + /* + * scan_start contains the number of bytes that we can ignore because the + * MAC's position can only vary by 255 bytes. + */ + size_t scan_start = 0; + size_t i, j; + size_t rotate_offset; + + if (!ossl_assert(origreclen >= mac_size + && mac_size <= EVP_MAX_MD_SIZE)) + return 0; + + /* If no MAC then nothing to be done */ + if (mac_size == 0) { + /* No MAC so we can do this in non-constant time */ + if (good == 0) + return 0; + return 1; + } + + *reclen -= mac_size; + + if (block_size == 1) { + /* There's no padding so the position of the MAC is fixed */ + if (mac != NULL) + *mac = &recdata[*reclen]; + if (alloced != NULL) + *alloced = 0; + return 1; + } + + /* Create the random MAC we will emit if padding is bad */ + if (RAND_bytes_ex(libctx, randmac, mac_size, 0) <= 0) + return 0; + + if (!ossl_assert(mac != NULL && alloced != NULL)) + return 0; + *mac = out = OPENSSL_malloc(mac_size); + if (*mac == NULL) + return 0; + *alloced = 1; + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (origreclen > mac_size + 255 + 1) + scan_start = origreclen - (mac_size + 255 + 1); + + in_mac = 0; + rotate_offset = 0; + memset(rotated_mac, 0, mac_size); + for (i = scan_start, j = 0; i < origreclen; i++) { + size_t mac_started = constant_time_eq_s(i, mac_start); + size_t mac_ended = constant_time_lt_s(i, mac_end); + unsigned char b = recdata[i]; + + in_mac |= mac_started; + in_mac &= mac_ended; + rotate_offset |= j & mac_started; + rotated_mac[j++] |= b & in_mac; + j &= constant_time_lt_s(j, mac_size); + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < mac_size; i++) { + /* + * in case cache-line is 32 bytes, + * load from both lines and select appropriately + */ + aux1 = rotated_mac[rotate_offset & ~32]; + aux2 = rotated_mac[rotate_offset | 32]; + mask = constant_time_eq_8(rotate_offset & ~32, rotate_offset); + aux3 = constant_time_select_8(mask, aux1, aux2); + rotate_offset++; + + /* If the padding wasn't good we emit a random MAC */ + out[j++] = constant_time_select_8((unsigned char)(good & 0xff), + aux3, + randmac[i]); + rotate_offset &= constant_time_lt_s(rotate_offset, mac_size); + } +#else + memset(out, 0, mac_size); + rotate_offset = mac_size - rotate_offset; + rotate_offset &= constant_time_lt_s(rotate_offset, mac_size); + for (i = 0; i < mac_size; i++) { + for (j = 0; j < mac_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8_s(j, rotate_offset); + rotate_offset++; + rotate_offset &= constant_time_lt_s(rotate_offset, mac_size); + + /* If the padding wasn't good we emit a random MAC */ + out[i] = constant_time_select_8((unsigned char)(good & 0xff), out[i], + randmac[i]); + } +#endif + + return 1; +} diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index c95dcd9fdec1..85f296b80783 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c @@ -1,19 +1,69 @@ /* * Copyright 2012-2021 The OpenSSL Project Authors. 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 */ +/* + * This file has no dependencies on the rest of libssl because it is shared + * with the providers. It contains functions for low level MAC calculations. + * Responsibility for this lies with the HMAC implementation in the + * providers. However there are legacy code paths in libssl which also need to + * do this. In time those legacy code paths can be removed and this file can be + * moved out of libssl. + */ + + +/* + * MD5 and SHA-1 low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include "internal/constant_time.h" -#include "ssl_local.h" #include "internal/cryptlib.h" -#include <openssl/md5.h> +#include <openssl/evp.h> +#ifndef FIPS_MODULE +# include <openssl/md5.h> +#endif #include <openssl/sha.h> +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD *md, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char *header, + const unsigned char *data, + size_t data_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + size_t mac_secret_length, char is_sslv3); + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + /* * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's * length field. (SHA-384/512 have 128-bit length.) @@ -27,15 +77,16 @@ */ #define MAX_HASH_BLOCK_SIZE 128 +#ifndef FIPS_MODULE /* - * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in + * u32toLE serializes an unsigned, 32-bit number (n) as four bytes at (p) in * little-endian order. The value of p is advanced by four. */ -#define u32toLE(n, p) \ - (*((p)++)=(unsigned char)(n), \ - *((p)++)=(unsigned char)(n>>8), \ - *((p)++)=(unsigned char)(n>>16), \ - *((p)++)=(unsigned char)(n>>24)) +# define u32toLE(n, p) \ + (*((p)++)=(unsigned char)(n), \ + *((p)++)=(unsigned char)(n>>8), \ + *((p)++)=(unsigned char)(n>>16), \ + *((p)++)=(unsigned char)(n>>24)) /* * These functions serialize the state of a hash and thus perform the @@ -50,6 +101,7 @@ static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) u32toLE(md5->C, md_out); u32toLE(md5->D, md_out); } +#endif /* FIPS_MODULE */ static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) { @@ -84,25 +136,6 @@ static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) #undef LARGEST_DIGEST_CTX #define LARGEST_DIGEST_CTX SHA512_CTX -/* - * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function - * which ssl3_cbc_digest_record supports. - */ -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) -{ - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - return 1; - default: - return 0; - } -} - /*- * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS * record. @@ -113,30 +146,27 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) * md_out_size: if non-NULL, the number of output bytes is written here. * header: the 13-byte, TLS record header. * data: the record data itself, less any preceding explicit IV. - * data_plus_mac_size: the secret, reported length of the data and MAC - * once the padding has been removed. + * data_size: the secret, reported length of the data once the MAC and padding + * has been removed. * data_plus_mac_plus_padding_size: the public length of the whole - * record, including padding. + * record, including MAC and padding. * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. * - * On entry: by virtue of having been through one of the remove_padding - * functions, above, we know that data_plus_mac_size is large enough to contain - * a padding byte and MAC. (If the padding was invalid, it might contain the - * padding too. ) + * On entry: we know that data is data_plus_mac_plus_padding_size in length * Returns 1 on success or 0 on error */ -int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, +int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char *md_out, size_t *md_out_size, const unsigned char *header, const unsigned char *data, - size_t data_plus_mac_size, + size_t data_size, size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, size_t mac_secret_length, char is_sslv3) { union { - double align; + OSSL_UNION_ALIGN; unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state; void (*md_final_raw) (void *ctx, unsigned char *md_out); @@ -160,7 +190,7 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, */ size_t md_length_size = 8; char length_is_big_endian = 1; - int ret; + int ret = 0; /* * This is a, hopefully redundant, check that allows us to forget about @@ -169,8 +199,10 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, if (!ossl_assert(data_plus_mac_plus_padding_size < 1024 * 1024)) return 0; - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: + if (EVP_MD_is_a(md, "MD5")) { +#ifdef FIPS_MODULE + return 0; +#else if (MD5_Init((MD5_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_md5_final_raw; @@ -179,32 +211,29 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, md_size = 16; sslv3_pad_length = 48; length_is_big_endian = 0; - break; - case NID_sha1: +#endif + } else if (EVP_MD_is_a(md, "SHA1")) { if (SHA1_Init((SHA_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha1_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA1_Transform; md_size = 20; - break; - case NID_sha224: + } else if (EVP_MD_is_a(md, "SHA2-224")) { if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha256_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; md_size = 224 / 8; - break; - case NID_sha256: + } else if (EVP_MD_is_a(md, "SHA2-256")) { if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha256_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; md_size = 32; - break; - case NID_sha384: + } else if (EVP_MD_is_a(md, "SHA2-384")) { if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha512_final_raw; @@ -213,8 +242,7 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, md_size = 384 / 8; md_block_size = 128; md_length_size = 16; - break; - case NID_sha512: + } else if (EVP_MD_is_a(md, "SHA2-512")) { if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha512_final_raw; @@ -223,8 +251,7 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, md_size = 64; md_block_size = 128; md_length_size = 16; - break; - default: + } else { /* * ssl3_cbc_record_digest_supported should have been called first to * check that the hash function is supported. @@ -295,7 +322,7 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, /* * mac_end_offset is the index just past the end of the data to be MACed. */ - mac_end_offset = data_plus_mac_size + header_length - md_size; + mac_end_offset = data_size + header_length; /* * c is the index of the 0x80 byte in the final hash block that contains * application data. @@ -455,7 +482,8 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) goto err; - if (EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */ ) <= 0) + + if (EVP_DigestInit_ex(md_ctx, md, NULL /* engine */ ) <= 0) goto err; if (is_sslv3) { /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ @@ -474,14 +502,12 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0) goto err; } - /* TODO(size_t): Convert me */ ret = EVP_DigestFinal(md_ctx, md_out, &md_out_size_u); if (ret && md_out_size) *md_out_size = md_out_size_u; - EVP_MD_CTX_free(md_ctx); - return 1; + ret = 1; err: EVP_MD_CTX_free(md_ctx); - return 0; + return ret; } diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 7b119b452fd7..2ca3f74ae771 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -1,8 +1,8 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. 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 @@ -12,67 +12,64 @@ #include "ssl_local.h" #include <openssl/evp.h> #include <openssl/md5.h> +#include <openssl/core_names.h> #include "internal/cryptlib.h" static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) { + const EVP_MD *md5 = NULL, *sha1 = NULL; EVP_MD_CTX *m5; EVP_MD_CTX *s1; unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; unsigned char c = 'A'; - unsigned int i, j, k; + unsigned int i, k; int ret = 0; #ifdef CHARSET_EBCDIC c = os_toascii[c]; /* 'A' in ASCII */ #endif k = 0; + md5 = ssl_evp_md_fetch(s->ctx->libctx, NID_md5, s->ctx->propq); + sha1 = ssl_evp_md_fetch(s->ctx->libctx, NID_sha1, s->ctx->propq); m5 = EVP_MD_CTX_new(); s1 = EVP_MD_CTX_new(); - if (m5 == NULL || s1 == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, - ERR_R_MALLOC_FAILURE); + if (md5 == NULL || sha1 == NULL || m5 == NULL || s1 == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - EVP_MD_CTX_set_flags(m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { k++; if (k > sizeof(buf)) { /* bug: 'buf' is too small for this ciphersuite */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - for (j = 0; j < k; j++) - buf[j] = c; + memset(buf, c, k); c++; - if (!EVP_DigestInit_ex(s1, EVP_sha1(), NULL) + if (!EVP_DigestInit_ex(s1, sha1, NULL) || !EVP_DigestUpdate(s1, buf, k) || !EVP_DigestUpdate(s1, s->session->master_key, s->session->master_key_length) - || !EVP_DigestUpdate(s1, s->s3->server_random, SSL3_RANDOM_SIZE) - || !EVP_DigestUpdate(s1, s->s3->client_random, SSL3_RANDOM_SIZE) + || !EVP_DigestUpdate(s1, s->s3.server_random, SSL3_RANDOM_SIZE) + || !EVP_DigestUpdate(s1, s->s3.client_random, SSL3_RANDOM_SIZE) || !EVP_DigestFinal_ex(s1, smd, NULL) - || !EVP_DigestInit_ex(m5, EVP_md5(), NULL) + || !EVP_DigestInit_ex(m5, md5, NULL) || !EVP_DigestUpdate(m5, s->session->master_key, s->session->master_key_length) || !EVP_DigestUpdate(m5, smd, SHA_DIGEST_LENGTH)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if ((int)(i + MD5_DIGEST_LENGTH) > num) { if (!EVP_DigestFinal_ex(m5, smd, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } memcpy(km, smd, (num - i)); } else { if (!EVP_DigestFinal_ex(m5, km, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } @@ -84,6 +81,8 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) err: EVP_MD_CTX_free(m5); EVP_MD_CTX_free(s1); + ssl_evp_md_free(md5); + ssl_evp_md_free(sha1); return ret; } @@ -101,27 +100,25 @@ int ssl3_change_cipher_state(SSL *s, int which) size_t n, i, j, k, cl; int reuse_dd = 0; - c = s->s3->tmp.new_sym_enc; - m = s->s3->tmp.new_hash; + c = s->s3.tmp.new_sym_enc; + m = s->s3.tmp.new_hash; /* m == NULL will lead to a crash later */ if (!ossl_assert(m != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } #ifndef OPENSSL_NO_COMP - if (s->s3->tmp.new_compression == NULL) + if (s->s3.tmp.new_compression == NULL) comp = NULL; else - comp = s->s3->tmp.new_compression->method; + comp = s->s3.tmp.new_compression->method; #endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) { reuse_dd = 1; } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } else { /* @@ -132,8 +129,7 @@ int ssl3_change_cipher_state(SSL *s, int which) dd = s->enc_read_ctx; if (ssl_replace_hash(&s->read_hash, m) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } #ifndef OPENSSL_NO_COMP @@ -144,21 +140,19 @@ int ssl3_change_cipher_state(SSL *s, int which) s->expand = COMP_CTX_new(comp); if (s->expand == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL3_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err; } } #endif RECORD_LAYER_reset_read_sequence(&s->rlayer); - mac_secret = &(s->s3->read_mac_secret[0]); + mac_secret = &(s->s3.read_mac_secret[0]); } else { s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; if (s->enc_write_ctx != NULL) { reuse_dd = 1; } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } else { /* @@ -168,8 +162,7 @@ int ssl3_change_cipher_state(SSL *s, int which) } dd = s->enc_write_ctx; if (ssl_replace_hash(&s->write_hash, m) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } #ifndef OPENSSL_NO_COMP @@ -180,30 +173,28 @@ int ssl3_change_cipher_state(SSL *s, int which) s->compress = COMP_CTX_new(comp); if (s->compress == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL3_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err; } } #endif RECORD_LAYER_reset_write_sequence(&s->rlayer); - mac_secret = &(s->s3->write_mac_secret[0]); + mac_secret = &(s->s3.write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_reset(dd); - p = s->s3->tmp.key_block; - mdi = EVP_MD_size(m); + p = s->s3.tmp.key_block; + mdi = EVP_MD_get_size(m); if (mdi < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } i = mdi; - cl = EVP_CIPHER_key_length(c); + cl = EVP_CIPHER_get_key_length(c); j = cl; - k = EVP_CIPHER_iv_length(c); + k = EVP_CIPHER_get_iv_length(c); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms = &(p[0]); @@ -222,17 +213,21 @@ int ssl3_change_cipher_state(SSL *s, int which) n += k; } - if (n > s->s3->tmp.key_block_length) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + if (n > s->s3.tmp.key_block_length) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } memcpy(mac_secret, ms, i); if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_CIPHER_get0_provider(c) != NULL + && !tls_provider_set_tls_params(s, dd, c, m)) { + /* SSLfatal already called */ goto err; } @@ -251,40 +246,42 @@ int ssl3_setup_key_block(SSL *s) int ret = 0; SSL_COMP *comp; - if (s->s3->tmp.key_block_length != 0) + if (s->s3.tmp.key_block_length != 0) return 1; - if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_SETUP_KEY_BLOCK, - SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, &comp, + 0)) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; } - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; + ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); + s->s3.tmp.new_sym_enc = c; + ssl_evp_md_free(s->s3.tmp.new_hash); + s->s3.tmp.new_hash = hash; #ifdef OPENSSL_NO_COMP - s->s3->tmp.new_compression = NULL; + s->s3.tmp.new_compression = NULL; #else - s->s3->tmp.new_compression = comp; + s->s3.tmp.new_compression = comp; #endif - num = EVP_MD_size(hash); + num = EVP_MD_get_size(hash); if (num < 0) return 0; - num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c); + num = EVP_CIPHER_get_key_length(c) + num + EVP_CIPHER_get_iv_length(c); num *= 2; ssl3_cleanup_key_block(s); if ((p = OPENSSL_malloc(num)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_SETUP_KEY_BLOCK, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p; + s->s3.tmp.key_block_length = num; + s->s3.tmp.key_block = p; /* Calls SSLfatal() as required */ ret = ssl3_generate_key_block(s, p, num); @@ -294,16 +291,14 @@ int ssl3_setup_key_block(SSL *s) * enable vulnerability countermeasure for CBC ciphers with known-IV * problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ - s->s3->need_empty_fragments = 1; + s->s3.need_empty_fragments = 1; if (s->session->cipher != NULL) { if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3->need_empty_fragments = 0; + s->s3.need_empty_fragments = 0; -#ifndef OPENSSL_NO_RC4 if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3->need_empty_fragments = 0; -#endif + s->s3.need_empty_fragments = 0; } } @@ -312,9 +307,9 @@ int ssl3_setup_key_block(SSL *s) void ssl3_cleanup_key_block(SSL *s) { - OPENSSL_clear_free(s->s3->tmp.key_block, s->s3->tmp.key_block_length); - s->s3->tmp.key_block = NULL; - s->s3->tmp.key_block_length = 0; + OPENSSL_clear_free(s->s3.tmp.key_block, s->s3.tmp.key_block_length); + s->s3.tmp.key_block = NULL; + s->s3.tmp.key_block_length = 0; } int ssl3_init_finished_mac(SSL *s) @@ -322,13 +317,12 @@ int ssl3_init_finished_mac(SSL *s) BIO *buf = BIO_new(BIO_s_mem()); if (buf == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_INIT_FINISHED_MAC, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } ssl3_free_digest_list(s); - s->s3->handshake_buffer = buf; - (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); + s->s3.handshake_buffer = buf; + (void)BIO_set_close(s->s3.handshake_buffer, BIO_CLOSE); return 1; } @@ -339,34 +333,31 @@ int ssl3_init_finished_mac(SSL *s) void ssl3_free_digest_list(SSL *s) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - EVP_MD_CTX_free(s->s3->handshake_dgst); - s->s3->handshake_dgst = NULL; + BIO_free(s->s3.handshake_buffer); + s->s3.handshake_buffer = NULL; + EVP_MD_CTX_free(s->s3.handshake_dgst); + s->s3.handshake_dgst = NULL; } int ssl3_finish_mac(SSL *s, const unsigned char *buf, size_t len) { int ret; - if (s->s3->handshake_dgst == NULL) { + if (s->s3.handshake_dgst == NULL) { /* Note: this writes to a memory BIO so a failure is a fatal error */ if (len > INT_MAX) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINISH_MAC, - SSL_R_OVERFLOW_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_OVERFLOW_ERROR); return 0; } - ret = BIO_write(s->s3->handshake_buffer, (void *)buf, (int)len); + ret = BIO_write(s->s3.handshake_buffer, (void *)buf, (int)len); if (ret <= 0 || ret != (int)len) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINISH_MAC, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } else { - ret = EVP_DigestUpdate(s->s3->handshake_dgst, buf, len); + ret = EVP_DigestUpdate(s->s3.handshake_dgst, buf, len); if (!ret) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINISH_MAC, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -379,37 +370,49 @@ int ssl3_digest_cached_records(SSL *s, int keep) long hdatalen; void *hdata; - if (s->s3->handshake_dgst == NULL) { - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (s->s3.handshake_dgst == NULL) { + hdatalen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata); if (hdatalen <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, - SSL_R_BAD_HANDSHAKE_LENGTH); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH); return 0; } - s->s3->handshake_dgst = EVP_MD_CTX_new(); - if (s->s3->handshake_dgst == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, - ERR_R_MALLOC_FAILURE); + s->s3.handshake_dgst = EVP_MD_CTX_new(); + if (s->s3.handshake_dgst == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } md = ssl_handshake_md(s); - if (md == NULL || !EVP_DigestInit_ex(s->s3->handshake_dgst, md, NULL) - || !EVP_DigestUpdate(s->s3->handshake_dgst, hdata, hdatalen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, - ERR_R_INTERNAL_ERROR); + if (md == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); + return 0; + } + if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL) + || !EVP_DigestUpdate(s->s3.handshake_dgst, hdata, hdatalen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } if (keep == 0) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; + BIO_free(s->s3.handshake_buffer); + s->s3.handshake_buffer = NULL; } return 1; } +void ssl3_digest_master_key_set_params(const SSL_SESSION *session, + OSSL_PARAM params[]) +{ + int n = 0; + params[n++] = OSSL_PARAM_construct_octet_string(OSSL_DIGEST_PARAM_SSL3_MS, + (void *)session->master_key, + session->master_key_length); + params[n++] = OSSL_PARAM_construct_end(); +} + size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, unsigned char *p) { @@ -421,41 +424,40 @@ size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t len, return 0; } - if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, - SSL_R_NO_REQUIRED_DIGEST); + if (EVP_MD_CTX_get_type(s->s3.handshake_dgst) != NID_md5_sha1) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_REQUIRED_DIGEST); return 0; } ctx = EVP_MD_CTX_new(); if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, - ERR_R_INTERNAL_ERROR); + if (!EVP_MD_CTX_copy_ex(ctx, s->s3.handshake_dgst)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); ret = 0; goto err; } - ret = EVP_MD_CTX_size(ctx); + ret = EVP_MD_CTX_get_size(ctx); if (ret < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); ret = 0; goto err; } - if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0) - || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET, - (int)s->session->master_key_length, - s->session->master_key) <= 0 - || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_FINAL_FINISH_MAC, - ERR_R_INTERNAL_ERROR); - ret = 0; + if (sender != NULL) { + OSSL_PARAM digest_cmd_params[3]; + + ssl3_digest_master_key_set_params(s->session, digest_cmd_params); + + if (EVP_DigestUpdate(ctx, sender, len) <= 0 + || EVP_MD_CTX_set_params(ctx, digest_cmd_params) <= 0 + || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + ret = 0; + } } err: @@ -485,8 +487,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, size_t ret_secret_size = 0; if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_MASTER_SECRET, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < 3; i++) { @@ -494,18 +495,16 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, || EVP_DigestUpdate(ctx, salt[i], strlen((const char *)salt[i])) <= 0 || EVP_DigestUpdate(ctx, p, len) <= 0 - || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]), + || EVP_DigestUpdate(ctx, &(s->s3.client_random[0]), SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]), + || EVP_DigestUpdate(ctx, &(s->s3.server_random[0]), SSL3_RANDOM_SIZE) <= 0 - /* TODO(size_t) : convert me */ || EVP_DigestFinal_ex(ctx, buf, &n) <= 0 || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0 || EVP_DigestUpdate(ctx, p, len) <= 0 || EVP_DigestUpdate(ctx, buf, n) <= 0 || EVP_DigestFinal_ex(ctx, out, &n) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); ret = 0; break; } @@ -589,7 +588,7 @@ int ssl3_alert_code(int code) return TLS1_AD_NO_APPLICATION_PROTOCOL; case SSL_AD_CERTIFICATE_REQUIRED: return SSL_AD_HANDSHAKE_FAILURE; - case SSL_AD_MISSING_EXTENSION: + case TLS13_AD_MISSING_EXTENSION: return SSL_AD_HANDSHAKE_FAILURE; default: return -1; diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 32f9b257106b..78d4f040565d 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.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 @@ -16,6 +16,9 @@ #include <openssl/md5.h> #include <openssl/dh.h> #include <openssl/rand.h> +#include <openssl/trace.h> +#include <openssl/x509v3.h> +#include <openssl/core_names.h> #include "internal/cryptlib.h" #define TLS13_NUM_CIPHERS OSSL_NELEM(tls13_ciphers) @@ -63,7 +66,6 @@ static SSL_CIPHER tls13_ciphers[] = { 256, 256, }, -#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) { 1, TLS1_3_RFC_CHACHA20_POLY1305_SHA256, @@ -80,7 +82,6 @@ static SSL_CIPHER tls13_ciphers[] = { 256, 256, }, -#endif { 1, TLS1_3_RFC_AES_128_CCM_SHA256, @@ -2033,7 +2034,6 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, }, -#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) { 1, TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305, @@ -2146,10 +2146,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, -#endif /* !defined(OPENSSL_NO_CHACHA) && - * !defined(OPENSSL_NO_POLY1305) */ -#ifndef OPENSSL_NO_CAMELLIA { 1, TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256, @@ -2598,7 +2595,6 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, -#endif /* OPENSSL_NO_CAMELLIA */ #ifndef OPENSSL_NO_GOST { @@ -2635,7 +2631,23 @@ static SSL_CIPHER ssl3_ciphers[] = { }, { 1, - "GOST2012-GOST8912-GOST8912", + "IANA-GOST2012-GOST8912-GOST8912", + NULL, + 0x0300c102, + SSL_kGOST, + SSL_aGOST12 | SSL_aGOST01, + SSL_eGOST2814789CNT12, + SSL_GOST89MAC12, + TLS1_VERSION, TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC, + 256, + 256, + }, + { + 1, + "LEGACY-GOST2012-GOST8912-GOST8912", NULL, 0x0300ff85, SSL_kGOST, @@ -2665,9 +2677,40 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, + { + 1, + "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC", + NULL, + 0x0300C100, + SSL_kGOST18, + SSL_aGOST12, + SSL_KUZNYECHIK, + SSL_KUZNYECHIKOMAC, + TLS1_2_VERSION, TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, + 256, + 256, + }, + { + 1, + "GOST2012-MAGMA-MAGMAOMAC", + NULL, + 0x0300C101, + SSL_kGOST18, + SSL_aGOST12, + SSL_MAGMA, + SSL_MAGMAOMAC, + TLS1_2_VERSION, TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, + 256, + 256, + }, #endif /* OPENSSL_NO_GOST */ -#ifndef OPENSSL_NO_IDEA { 1, SSL3_TXT_RSA_IDEA_128_SHA, @@ -2684,9 +2727,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 128, 128, }, -#endif -#ifndef OPENSSL_NO_SEED { 1, TLS1_TXT_RSA_WITH_SEED_SHA, @@ -2751,7 +2792,6 @@ static SSL_CIPHER ssl3_ciphers[] = { 128, 128, }, -#endif /* OPENSSL_NO_SEED */ #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { @@ -2916,7 +2956,6 @@ static SSL_CIPHER ssl3_ciphers[] = { }, #endif /* OPENSSL_NO_WEAK_SSL_CIPHERS */ -#ifndef OPENSSL_NO_ARIA { 1, TLS1_TXT_RSA_WITH_ARIA_128_GCM_SHA256, @@ -3173,7 +3212,6 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, -#endif /* OPENSSL_NO_ARIA */ }; /* @@ -3291,78 +3329,68 @@ int ssl3_handshake_write(SSL *s) int ssl3_new(SSL *s) { - SSL3_STATE *s3; - - if ((s3 = OPENSSL_zalloc(sizeof(*s3))) == NULL) - goto err; - s->s3 = s3; - #ifndef OPENSSL_NO_SRP - if (!SSL_SRP_CTX_init(s)) - goto err; + if (!ssl_srp_ctx_init_intern(s)) + return 0; #endif if (!s->method->ssl_clear(s)) return 0; return 1; - err: - return 0; } void ssl3_free(SSL *s) { - if (s == NULL || s->s3 == NULL) + if (s == NULL) return; ssl3_cleanup_key_block(s); -#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) - EVP_PKEY_free(s->s3->peer_tmp); - s->s3->peer_tmp = NULL; - EVP_PKEY_free(s->s3->tmp.pkey); - s->s3->tmp.pkey = NULL; -#endif + EVP_PKEY_free(s->s3.peer_tmp); + s->s3.peer_tmp = NULL; + EVP_PKEY_free(s->s3.tmp.pkey); + s->s3.tmp.pkey = NULL; + + ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); + ssl_evp_md_free(s->s3.tmp.new_hash); - OPENSSL_free(s->s3->tmp.ctype); - sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free); - OPENSSL_free(s->s3->tmp.ciphers_raw); - OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen); - OPENSSL_free(s->s3->tmp.peer_sigalgs); - OPENSSL_free(s->s3->tmp.peer_cert_sigalgs); + OPENSSL_free(s->s3.tmp.ctype); + sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); + OPENSSL_free(s->s3.tmp.ciphers_raw); + OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); + OPENSSL_free(s->s3.tmp.peer_sigalgs); + OPENSSL_free(s->s3.tmp.peer_cert_sigalgs); ssl3_free_digest_list(s); - OPENSSL_free(s->s3->alpn_selected); - OPENSSL_free(s->s3->alpn_proposed); + OPENSSL_free(s->s3.alpn_selected); + OPENSSL_free(s->s3.alpn_proposed); #ifndef OPENSSL_NO_SRP - SSL_SRP_CTX_free(s); + ssl_srp_ctx_free_intern(s); #endif - OPENSSL_clear_free(s->s3, sizeof(*s->s3)); - s->s3 = NULL; + memset(&s->s3, 0, sizeof(s->s3)); } int ssl3_clear(SSL *s) { ssl3_cleanup_key_block(s); - OPENSSL_free(s->s3->tmp.ctype); - sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free); - OPENSSL_free(s->s3->tmp.ciphers_raw); - OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen); - OPENSSL_free(s->s3->tmp.peer_sigalgs); - OPENSSL_free(s->s3->tmp.peer_cert_sigalgs); - -#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) - EVP_PKEY_free(s->s3->tmp.pkey); - EVP_PKEY_free(s->s3->peer_tmp); -#endif /* !OPENSSL_NO_EC */ + OPENSSL_free(s->s3.tmp.ctype); + sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); + OPENSSL_free(s->s3.tmp.ciphers_raw); + OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); + OPENSSL_free(s->s3.tmp.peer_sigalgs); + OPENSSL_free(s->s3.tmp.peer_cert_sigalgs); + + EVP_PKEY_free(s->s3.tmp.pkey); + EVP_PKEY_free(s->s3.peer_tmp); ssl3_free_digest_list(s); - OPENSSL_free(s->s3->alpn_selected); - OPENSSL_free(s->s3->alpn_proposed); + OPENSSL_free(s->s3.alpn_selected); + OPENSSL_free(s->s3.alpn_proposed); /* NULL/zero-out everything in the s3 struct */ - memset(s->s3, 0, sizeof(*s->s3)); + memset(&s->s3, 0, sizeof(s->s3)); if (!ssl_free_wbio_buffer(s)) return 0; @@ -3395,79 +3423,61 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_CLIENT_CERT_REQUEST: break; case SSL_CTRL_GET_NUM_RENEGOTIATIONS: - ret = s->s3->num_renegotiations; + ret = s->s3.num_renegotiations; break; case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: - ret = s->s3->num_renegotiations; - s->s3->num_renegotiations = 0; + ret = s->s3.num_renegotiations; + s->s3.num_renegotiations = 0; break; case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: - ret = s->s3->total_renegotiations; + ret = s->s3.total_renegotiations; break; case SSL_CTRL_GET_FLAGS: - ret = (int)(s->s3->flags); + ret = (int)(s->s3.flags); break; -#ifndef OPENSSL_NO_DH +#if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_DH: { - DH *dh = (DH *)parg; EVP_PKEY *pkdh = NULL; - if (dh == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return ret; + if (parg == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; } - pkdh = ssl_dh_to_pkey(dh); + pkdh = ssl_dh_to_pkey(parg); if (pkdh == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } - if (!ssl_security(s, SSL_SECOP_TMP_DH, - EVP_PKEY_security_bits(pkdh), 0, pkdh)) { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_DH_KEY_TOO_SMALL); + if (!SSL_set0_tmp_dh_pkey(s, pkdh)) { EVP_PKEY_free(pkdh); - return ret; + return 0; } - EVP_PKEY_free(s->cert->dh_tmp); - s->cert->dh_tmp = pkdh; - ret = 1; + return 1; } break; case SSL_CTRL_SET_TMP_DH_CB: { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return ret; } +#endif case SSL_CTRL_SET_DH_AUTO: s->cert->dh_tmp_auto = larg; return 1; -#endif -#ifndef OPENSSL_NO_EC +#if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_ECDH: { - const EC_GROUP *group = NULL; - int nid; - if (parg == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - group = EC_KEY_get0_group((const EC_KEY *)parg); - if (group == NULL) { - SSLerr(SSL_F_SSL3_CTRL, EC_R_MISSING_PARAMETERS); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - nid = EC_GROUP_get_curve_name(group); - if (nid == NID_undef) - return 0; - return tls1_set_groups(&s->ext.supportedgroups, - &s->ext.supportedgroups_len, - &nid, 1); + return ssl_set_tmp_ecdh_groups(&s->ext.supportedgroups, + &s->ext.supportedgroups_len, + parg); } - break; -#endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_DEPRECATED_3_0 */ case SSL_CTRL_SET_TLSEXT_HOSTNAME: /* - * TODO(OpenSSL1.2) * This API is only used for a client to set what SNI it will request * from the server, but we currently allow it to be used on servers * as well, which is a programming error. Currently we just clear @@ -3486,15 +3496,15 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) break; len = strlen((char *)parg); if (len == 0 || len > TLSEXT_MAXLEN_host_name) { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); return 0; } if ((s->ext.hostname = OPENSSL_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } } else { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); return 0; } break; @@ -3546,13 +3556,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) ret = 1; break; -#ifndef OPENSSL_NO_HEARTBEATS - case SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT: - case SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING: - case SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS: - break; -#endif - case SSL_CTRL_CHAIN: if (larg) return ssl_cert_set1_chain(s, NULL, (STACK_OF(X509) *)parg); @@ -3578,7 +3581,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) const SSL_CIPHER *cipher; if (!s->server) return 0; - cipher = s->s3->tmp.new_cipher; + cipher = s->s3.tmp.new_cipher; if (cipher == NULL) return 0; /* @@ -3587,14 +3590,13 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) */ if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) return 2; - if (s->s3->tmp.cert == NULL) + if (s->s3.tmp.cert == NULL) return 0; - s->cert->key = s->s3->tmp.cert; + s->cert->key = s->s3.tmp.cert; return 1; } return ssl_cert_set_current(s->cert, larg); -#ifndef OPENSSL_NO_EC case SSL_CTRL_GET_GROUPS: { uint16_t *clist; @@ -3609,10 +3611,11 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) int *cptr = parg; for (i = 0; i < clistlen; i++) { - const TLS_GROUP_INFO *cinf = tls1_group_id_lookup(clist[i]); + const TLS_GROUP_INFO *cinf + = tls1_group_id_lookup(s->ctx, clist[i]); if (cinf != NULL) - cptr[i] = cinf->nid; + cptr[i] = tls1_group_id2nid(cinf->group_id, 1); else cptr[i] = TLSEXT_nid_unknown | clist[i]; } @@ -3625,21 +3628,28 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) &s->ext.supportedgroups_len, parg, larg); case SSL_CTRL_SET_GROUPS_LIST: - return tls1_set_groups_list(&s->ext.supportedgroups, + return tls1_set_groups_list(s->ctx, &s->ext.supportedgroups, &s->ext.supportedgroups_len, parg); case SSL_CTRL_GET_SHARED_GROUP: { uint16_t id = tls1_shared_group(s, larg); - if (larg != -1) { - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); - - return ginf == NULL ? 0 : ginf->nid; - } + if (larg != -1) + return tls1_group_id2nid(id, 1); return id; } -#endif + case SSL_CTRL_GET_NEGOTIATED_GROUP: + { + unsigned int id; + + if (SSL_IS_TLS13(s) && s->s3.did_kex) + id = s->s3.group_id; + else + id = s->session->kex_group; + ret = tls1_group_id2nid(id, 1); + break; + } case SSL_CTRL_SET_SIGALGS: return tls1_set_sigalgs(s->cert, parg, larg, 0); @@ -3655,11 +3665,11 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_CLIENT_CERT_TYPES: { const unsigned char **pctype = parg; - if (s->server || !s->s3->tmp.cert_req) + if (s->server || !s->s3.tmp.cert_req) return 0; if (pctype) - *pctype = s->s3->tmp.ctype; - return s->s3->tmp.ctype_len; + *pctype = s->s3.tmp.ctype; + return s->s3.tmp.ctype_len; } case SSL_CTRL_SET_CLIENT_CERT_TYPES: @@ -3683,44 +3693,35 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) return ssl_cert_get_cert_store(s->cert, parg, 1); case SSL_CTRL_GET_PEER_SIGNATURE_NID: - if (s->s3->tmp.peer_sigalg == NULL) + if (s->s3.tmp.peer_sigalg == NULL) return 0; - *(int *)parg = s->s3->tmp.peer_sigalg->hash; + *(int *)parg = s->s3.tmp.peer_sigalg->hash; return 1; case SSL_CTRL_GET_SIGNATURE_NID: - if (s->s3->tmp.sigalg == NULL) + if (s->s3.tmp.sigalg == NULL) return 0; - *(int *)parg = s->s3->tmp.sigalg->hash; + *(int *)parg = s->s3.tmp.sigalg->hash; return 1; case SSL_CTRL_GET_PEER_TMP_KEY: -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) - if (s->session == NULL || s->s3->peer_tmp == NULL) { + if (s->session == NULL || s->s3.peer_tmp == NULL) { return 0; } else { - EVP_PKEY_up_ref(s->s3->peer_tmp); - *(EVP_PKEY **)parg = s->s3->peer_tmp; + EVP_PKEY_up_ref(s->s3.peer_tmp); + *(EVP_PKEY **)parg = s->s3.peer_tmp; return 1; } -#else - return 0; -#endif case SSL_CTRL_GET_TMP_KEY: -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) - if (s->session == NULL || s->s3->tmp.pkey == NULL) { + if (s->session == NULL || s->s3.tmp.pkey == NULL) { return 0; } else { - EVP_PKEY_up_ref(s->s3->tmp.pkey); - *(EVP_PKEY **)parg = s->s3->tmp.pkey; + EVP_PKEY_up_ref(s->s3.tmp.pkey); + *(EVP_PKEY **)parg = s->s3.tmp.pkey; return 1; } -#else - return 0; -#endif -#ifndef OPENSSL_NO_EC case SSL_CTRL_GET_EC_POINT_FORMATS: { const unsigned char **pformat = parg; @@ -3730,7 +3731,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) *pformat = s->ext.peer_ecpointformats; return (int)s->ext.peer_ecpointformats_len; } -#endif default: break; @@ -3743,22 +3743,21 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) int ret = 0; switch (cmd) { -#ifndef OPENSSL_NO_DH +#if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_DH_CB: - { - s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; - } + s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + ret = 1; break; #endif case SSL_CTRL_SET_TLSEXT_DEBUG_CB: s->ext.debug_cb = (void (*)(SSL *, int, int, const unsigned char *, int, void *))fp; + ret = 1; break; case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB: - { - s->not_resumable_session_cb = (int (*)(SSL *, int))fp; - } + s->not_resumable_session_cb = (int (*)(SSL *, int))fp; + ret = 1; break; default: break; @@ -3769,62 +3768,46 @@ long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) { switch (cmd) { -#ifndef OPENSSL_NO_DH +#if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_DH: { - DH *dh = (DH *)parg; EVP_PKEY *pkdh = NULL; - if (dh == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_PASSED_NULL_PARAMETER); + if (parg == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - pkdh = ssl_dh_to_pkey(dh); + pkdh = ssl_dh_to_pkey(parg); if (pkdh == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } - if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH, - EVP_PKEY_security_bits(pkdh), 0, pkdh)) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_DH_KEY_TOO_SMALL); + if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkdh)) { EVP_PKEY_free(pkdh); return 0; } - EVP_PKEY_free(ctx->cert->dh_tmp); - ctx->cert->dh_tmp = pkdh; return 1; } case SSL_CTRL_SET_TMP_DH_CB: { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } +#endif case SSL_CTRL_SET_DH_AUTO: ctx->cert->dh_tmp_auto = larg; return 1; -#endif -#ifndef OPENSSL_NO_EC +#if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_ECDH: { - const EC_GROUP *group = NULL; - int nid; - if (parg == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } - group = EC_KEY_get0_group((const EC_KEY *)parg); - if (group == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, EC_R_MISSING_PARAMETERS); - return 0; - } - nid = EC_GROUP_get_curve_name(group); - if (nid == NID_undef) - return 0; - return tls1_set_groups(&ctx->ext.supportedgroups, - &ctx->ext.supportedgroups_len, - &nid, 1); + return ssl_set_tmp_ecdh_groups(&ctx->ext.supportedgroups, + &ctx->ext.supportedgroups_len, + parg); } -#endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_DEPRECATED_3_0 */ case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: ctx->ext.servername_arg = parg; break; @@ -3838,7 +3821,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) if (keys == NULL) return tick_keylen; if (larg != tick_keylen) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); return 0; } if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) { @@ -3892,11 +3875,11 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) if (parg == NULL) break; if (strlen((const char *)parg) > 255 || strlen((const char *)parg) < 1) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME); return 0; } if ((ctx->srp_ctx.login = OPENSSL_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } break; @@ -3905,8 +3888,8 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) srp_password_from_info_cb; if (ctx->srp_ctx.info != NULL) OPENSSL_free(ctx->srp_ctx.info); - if ((ctx->srp_ctx.info = BUF_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); + if ((ctx->srp_ctx.info = OPENSSL_strdup((char *)parg)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } break; @@ -3920,17 +3903,16 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) break; #endif -#ifndef OPENSSL_NO_EC case SSL_CTRL_SET_GROUPS: return tls1_set_groups(&ctx->ext.supportedgroups, &ctx->ext.supportedgroups_len, parg, larg); case SSL_CTRL_SET_GROUPS_LIST: - return tls1_set_groups_list(&ctx->ext.supportedgroups, + return tls1_set_groups_list(ctx, &ctx->ext.supportedgroups, &ctx->ext.supportedgroups_len, parg); -#endif + case SSL_CTRL_SET_SIGALGS: return tls1_set_sigalgs(ctx->cert, parg, larg, 0); @@ -3965,12 +3947,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) case SSL_CTRL_EXTRA_CHAIN_CERT: if (ctx->extra_certs == NULL) { if ((ctx->extra_certs = sk_X509_new_null()) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } } if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } break; @@ -4018,7 +4000,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) { switch (cmd) { -#ifndef OPENSSL_NO_DH +#if !defined(OPENSSL_NO_DEPRECATED_3_0) case SSL_CTRL_SET_TMP_DH_CB: { ctx->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; @@ -4033,12 +4015,14 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) ctx->ext.status_cb = (int (*)(SSL *, void *))fp; break; +# ifndef OPENSSL_NO_DEPRECATED_3_0 case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: ctx->ext.ticket_key_cb = (int (*)(SSL *, unsigned char *, unsigned char *, EVP_CIPHER_CTX *, HMAC_CTX *, int))fp; break; +#endif #ifndef OPENSSL_NO_SRP case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB: @@ -4067,6 +4051,14 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) return 1; } +int SSL_CTX_set_tlsext_ticket_key_evp_cb + (SSL_CTX *ctx, int (*fp)(SSL *, unsigned char *, unsigned char *, + EVP_CIPHER_CTX *, EVP_MAC_CTX *, int)) +{ + ctx->ext.ticket_key_evp_cb = fp; + return 1; +} + const SSL_CIPHER *ssl3_get_cipher_by_id(uint32_t id) { SSL_CIPHER c; @@ -4142,10 +4134,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, STACK_OF(SSL_CIPHER) *prio, *allow; int i, ii, ok, prefer_sha256 = 0; unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0; - const EVP_MD *mdsha256 = EVP_sha256(); -#ifndef OPENSSL_NO_CHACHA STACK_OF(SSL_CIPHER) *prio_chacha = NULL; -#endif /* Let's see which ciphers we can support */ @@ -4156,20 +4145,20 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, * pay with the price of sk_SSL_CIPHER_dup(). */ -#ifdef CIPHER_DEBUG - fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), - (void *)srvr); - for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) { - c = sk_SSL_CIPHER_value(srvr, i); - fprintf(stderr, "%p:%s\n", (void *)c, c->name); - } - fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), - (void *)clnt); - for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) { - c = sk_SSL_CIPHER_value(clnt, i); - fprintf(stderr, "%p:%s\n", (void *)c, c->name); - } -#endif + OSSL_TRACE_BEGIN(TLS_CIPHER) { + BIO_printf(trc_out, "Server has %d from %p:\n", + sk_SSL_CIPHER_num(srvr), (void *)srvr); + for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) { + c = sk_SSL_CIPHER_value(srvr, i); + BIO_printf(trc_out, "%p:%s\n", (void *)c, c->name); + } + BIO_printf(trc_out, "Client sent %d from %p:\n", + sk_SSL_CIPHER_num(clnt), (void *)clnt); + for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) { + c = sk_SSL_CIPHER_value(clnt, i); + BIO_printf(trc_out, "%p:%s\n", (void *)c, c->name); + } + } OSSL_TRACE_END(TLS_CIPHER); /* SUITE-B takes precedence over server preference and ChaCha priortiy */ if (tls1_suiteb(s)) { @@ -4178,7 +4167,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, } else if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { prio = srvr; allow = clnt; -#ifndef OPENSSL_NO_CHACHA + /* If ChaCha20 is at the top of the client preference list, and there are ChaCha20 ciphers in the server list, then temporarily prioritize all ChaCha20 ciphers in the servers list. */ @@ -4217,7 +4206,6 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, } } } -# endif } else { prio = clnt; allow = srvr; @@ -4264,8 +4252,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, * key exchange scheme skip tests. */ if (!SSL_IS_TLS13(s)) { - mask_k = s->s3->tmp.mask_k; - mask_a = s->s3->tmp.mask_a; + mask_k = s->s3.tmp.mask_k; + mask_a = s->s3.tmp.mask_a; #ifndef OPENSSL_NO_SRP if (s->srp_ctx.srp_Mask & SSL_kSRP) { mask_k |= SSL_kSRP; @@ -4283,19 +4271,16 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #endif /* OPENSSL_NO_PSK */ ok = (alg_k & mask_k) && (alg_a & mask_a); -#ifdef CIPHER_DEBUG - fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, - alg_a, mask_k, mask_a, (void *)c, c->name); -#endif + OSSL_TRACE7(TLS_CIPHER, + "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", + ok, alg_k, alg_a, mask_k, mask_a, (void *)c, c->name); -#ifndef OPENSSL_NO_EC /* * if we are considering an ECC cipher suite that uses an ephemeral * EC key check it */ if (alg_k & SSL_kECDHE) ok = ok && tls1_check_ec_tmp_key(s, c->id); -#endif /* OPENSSL_NO_EC */ if (!ok) continue; @@ -4306,18 +4291,20 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED, c->strength_bits, 0, (void *)c)) continue; -#if !defined(OPENSSL_NO_EC) + if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA) - && s->s3->is_probably_safari) { + && s->s3.is_probably_safari) { if (!ret) ret = sk_SSL_CIPHER_value(allow, ii); continue; } -#endif + if (prefer_sha256) { const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii); + const EVP_MD *md = ssl_md(s->ctx, tmp->algorithm2); - if (ssl_md(tmp->algorithm2) == mdsha256) { + if (md != NULL + && EVP_MD_is_a(md, OSSL_DIGEST_NAME_SHA2_256)) { ret = tmp; break; } @@ -4329,9 +4316,9 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, break; } } -#ifndef OPENSSL_NO_CHACHA + sk_SSL_CIPHER_free(prio_chacha); -#endif + return ret; } @@ -4345,36 +4332,35 @@ int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt) /* Get mask of algorithms disabled by signature list */ ssl_set_sig_mask(&alg_a, s, SSL_SECOP_SIGALG_MASK); - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_k = s->s3.tmp.new_cipher->algorithm_mkey; #ifndef OPENSSL_NO_GOST if (s->version >= TLS1_VERSION && (alg_k & SSL_kGOST)) - return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN); + if (!WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_512_SIGN)) + return 0; + + if (s->version >= TLS1_2_VERSION && (alg_k & SSL_kGOST18)) + if (!WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN)) + return 0; #endif if ((s->version == SSL3_VERSION) && (alg_k & SSL_kDHE)) { -#ifndef OPENSSL_NO_DH -# ifndef OPENSSL_NO_RSA if (!WPACKET_put_bytes_u8(pkt, SSL3_CT_RSA_EPHEMERAL_DH)) return 0; -# endif -# ifndef OPENSSL_NO_DSA - if (!WPACKET_put_bytes_u8(pkt, SSL3_CT_DSS_EPHEMERAL_DH)) + if (!(alg_a & SSL_aDSS) + && !WPACKET_put_bytes_u8(pkt, SSL3_CT_DSS_EPHEMERAL_DH)) return 0; -# endif -#endif /* !OPENSSL_NO_DH */ } -#ifndef OPENSSL_NO_RSA if (!(alg_a & SSL_aRSA) && !WPACKET_put_bytes_u8(pkt, SSL3_CT_RSA_SIGN)) return 0; -#endif -#ifndef OPENSSL_NO_DSA if (!(alg_a & SSL_aDSS) && !WPACKET_put_bytes_u8(pkt, SSL3_CT_DSS_SIGN)) return 0; -#endif -#ifndef OPENSSL_NO_EC + /* * ECDSA certs can be used with RSA cipher suites too so we don't * need to check for SSL_kECDH or SSL_kECDHE @@ -4383,7 +4369,7 @@ int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt) && !(alg_a & SSL_aECDSA) && !WPACKET_put_bytes_u8(pkt, TLS_CT_ECDSA_SIGN)) return 0; -#endif + return 1; } @@ -4421,11 +4407,11 @@ int ssl3_shutdown(SSL *s) ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); /* * our shutdown alert has been sent now, and if it still needs to be - * written, s->s3->alert_dispatch will be true + * written, s->s3.alert_dispatch will be true */ - if (s->s3->alert_dispatch) + if (s->s3.alert_dispatch) return -1; /* return WANT_WRITE */ - } else if (s->s3->alert_dispatch) { + } else if (s->s3.alert_dispatch) { /* resend it if not sent */ ret = s->method->ssl_dispatch_alert(s); if (ret == -1) { @@ -4448,7 +4434,7 @@ int ssl3_shutdown(SSL *s) } if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) && - !s->s3->alert_dispatch) + !s->s3.alert_dispatch) return 1; else return 0; @@ -4457,7 +4443,7 @@ int ssl3_shutdown(SSL *s) int ssl3_write(SSL *s, const void *buf, size_t len, size_t *written) { clear_sys_error(); - if (s->s3->renegotiate) + if (s->s3.renegotiate) ssl3_renegotiate_check(s, 0); return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, @@ -4470,13 +4456,13 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek, int ret; clear_sys_error(); - if (s->s3->renegotiate) + if (s->s3.renegotiate) ssl3_renegotiate_check(s, 0); - s->s3->in_read_app_data = 1; + s->s3.in_read_app_data = 1; ret = s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf, len, peek, readbytes); - if ((ret == -1) && (s->s3->in_read_app_data == 2)) { + if ((ret == -1) && (s->s3.in_read_app_data == 2)) { /* * ssl3_read_bytes decided to call s->handshake_func, which called * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes @@ -4490,7 +4476,7 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek, len, peek, readbytes); ossl_statem_set_in_handshake(s, 0); } else - s->s3->in_read_app_data = 0; + s->s3.in_read_app_data = 0; return ret; } @@ -4510,7 +4496,7 @@ int ssl3_renegotiate(SSL *s) if (s->handshake_func == NULL) return 1; - s->s3->renegotiate = 1; + s->s3.renegotiate = 1; return 1; } @@ -4526,7 +4512,7 @@ int ssl3_renegotiate_check(SSL *s, int initok) { int ret = 0; - if (s->s3->renegotiate) { + if (s->s3.renegotiate) { if (!RECORD_LAYER_read_pending(&s->rlayer) && !RECORD_LAYER_write_pending(&s->rlayer) && (initok || !SSL_in_init(s))) { @@ -4536,9 +4522,9 @@ int ssl3_renegotiate_check(SSL *s, int initok) * state. */ ossl_statem_set_renegotiate(s); - s->s3->renegotiate = 0; - s->s3->num_renegotiations++; - s->s3->total_renegotiations++; + s->s3.renegotiate = 0; + s->s3.num_renegotiations++; + s->s3.total_renegotiations++; ret = 1; } } @@ -4554,13 +4540,13 @@ int ssl3_renegotiate_check(SSL *s, int initok) long ssl_get_algorithm2(SSL *s) { long alg2; - if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL) + if (s->s3.tmp.new_cipher == NULL) return -1; - alg2 = s->s3->tmp.new_cipher->algorithm2; + alg2 = s->s3.tmp.new_cipher->algorithm2; if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) { if (alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; - } else if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) { + } else if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_PSK) { if (alg2 == (SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384)) return SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF; } @@ -4587,9 +4573,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, unsigned char *p = result; l2n(Time, p); - ret = RAND_bytes(p, len - 4); + ret = RAND_bytes_ex(s->ctx->libctx, p, len - 4, 0); } else { - ret = RAND_bytes(result, len); + ret = RAND_bytes_ex(s->ctx->libctx, result, len, 0); } if (ret > 0) { @@ -4610,13 +4596,13 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len, int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, int free_pms) { - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; int ret = 0; if (alg_k & SSL_PSK) { #ifndef OPENSSL_NO_PSK unsigned char *pskpms, *t; - size_t psklen = s->s3->tmp.psklen; + size_t psklen = s->s3.tmp.psklen; size_t pskpmslen; /* create PSK premaster_secret */ @@ -4637,11 +4623,11 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, memcpy(t, pms, pmslen); t += pmslen; s2n(psklen, t); - memcpy(t, s->s3->tmp.psk, psklen); + memcpy(t, s->s3.tmp.psk, psklen); - OPENSSL_clear_free(s->s3->tmp.psk, psklen); - s->s3->tmp.psk = NULL; - s->s3->tmp.psklen = 0; + OPENSSL_clear_free(s->s3.tmp.psk, psklen); + s->s3.tmp.psk = NULL; + s->s3.tmp.psklen = 0; if (!s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, pskpms, pskpmslen, &s->session->master_key_length)) { @@ -4672,21 +4658,21 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, OPENSSL_cleanse(pms, pmslen); } if (s->server == 0) { - s->s3->tmp.pms = NULL; - s->s3->tmp.pmslen = 0; + s->s3.tmp.pms = NULL; + s->s3.tmp.pmslen = 0; } return ret; } /* Generate a private key from parameters */ -EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm) +EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; if (pm == NULL) return NULL; - pctx = EVP_PKEY_CTX_new(pm, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pm, s->ctx->propq); if (pctx == NULL) goto err; if (EVP_PKEY_keygen_init(pctx) <= 0) @@ -4700,44 +4686,36 @@ EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm) EVP_PKEY_CTX_free(pctx); return pkey; } -#ifndef OPENSSL_NO_EC + /* Generate a private key from a group ID */ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) { + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(s->ctx, id); EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); - uint16_t gtype; if (ginf == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - gtype = ginf->flags & TLS_CURVE_TYPE; - if (gtype == TLS_CURVE_CUSTOM) - pctx = EVP_PKEY_CTX_new_id(ginf->nid, NULL); - else - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + + pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, ginf->algorithm, + s->ctx->propq); + if (pctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_keygen_init(pctx) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } - if (gtype != TLS_CURVE_CUSTOM - && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_EVP_LIB); + if (EVP_PKEY_CTX_set_group_name(pctx, ginf->realname) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } if (EVP_PKEY_keygen(pctx, &pkey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_PKEY_GROUP, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); EVP_PKEY_free(pkey); pkey = NULL; } @@ -4750,30 +4728,26 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id) /* * Generate parameters from a group ID */ -EVP_PKEY *ssl_generate_param_group(uint16_t id) +EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id) { EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *pkey = NULL; - const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(s->ctx, id); if (ginf == NULL) goto err; - if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) { - pkey = EVP_PKEY_new(); - if (pkey != NULL && EVP_PKEY_set_type(pkey, ginf->nid)) - return pkey; - EVP_PKEY_free(pkey); - return NULL; - } + pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, ginf->algorithm, + s->ctx->propq); - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); if (pctx == NULL) goto err; if (EVP_PKEY_paramgen_init(pctx) <= 0) goto err; - if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) + if (EVP_PKEY_CTX_set_group_name(pctx, ginf->realname) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; + } if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { EVP_PKEY_free(pkey); pkey = NULL; @@ -4783,7 +4757,32 @@ EVP_PKEY *ssl_generate_param_group(uint16_t id) EVP_PKEY_CTX_free(pctx); return pkey; } -#endif + +/* Generate secrets from pms */ +int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen) +{ + int rv = 0; + + /* SSLfatal() called as appropriate in the below functions */ + if (SSL_IS_TLS13(s)) { + /* + * If we are resuming then we already generated the early secret + * when we created the ClientHello, so don't recreate it. + */ + if (!s->hit) + rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, + 0, + (unsigned char *)&s->early_secret); + else + rv = 1; + + rv = rv && tls13_generate_handshake_secret(s, pms, pmslen); + } else { + rv = ssl_generate_master_secret(s, pms, pmslen, 0); + } + + return rv; +} /* Derive secrets for ECDH/DH */ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) @@ -4794,56 +4793,91 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) EVP_PKEY_CTX *pctx; if (privkey == NULL || pubkey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DERIVE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - pctx = EVP_PKEY_CTX_new(privkey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq); if (EVP_PKEY_derive_init(pctx) <= 0 || EVP_PKEY_derive_set_peer(pctx, pubkey) <= 0 || EVP_PKEY_derive(pctx, NULL, &pmslen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DERIVE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } + if (SSL_IS_TLS13(s) && EVP_PKEY_is_a(privkey, "DH")) + EVP_PKEY_CTX_set_dh_pad(pctx, 1); + pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DERIVE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_derive(pctx, pms, &pmslen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DERIVE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (gensecret) { /* SSLfatal() called as appropriate in the below functions */ - if (SSL_IS_TLS13(s)) { - /* - * If we are resuming then we already generated the early secret - * when we created the ClientHello, so don't recreate it. - */ - if (!s->hit) - rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, - 0, - (unsigned char *)&s->early_secret); - else - rv = 1; + rv = ssl_gensecret(s, pms, pmslen); + } else { + /* Save premaster secret */ + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; + pms = NULL; + rv = 1; + } - rv = rv && tls13_generate_handshake_secret(s, pms, pmslen); - } else { - rv = ssl_generate_master_secret(s, pms, pmslen, 0); - } + err: + OPENSSL_clear_free(pms, pmslen); + EVP_PKEY_CTX_free(pctx); + return rv; +} + +/* Decapsulate secrets for KEM */ +int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, + const unsigned char *ct, size_t ctlen, + int gensecret) +{ + int rv = 0; + unsigned char *pms = NULL; + size_t pmslen = 0; + EVP_PKEY_CTX *pctx; + + if (privkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq); + + if (EVP_PKEY_decapsulate_init(pctx, NULL) <= 0 + || EVP_PKEY_decapsulate(pctx, NULL, &pmslen, ct, ctlen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + pms = OPENSSL_malloc(pmslen); + if (pms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decapsulate(pctx, pms, &pmslen, ct, ctlen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (gensecret) { + /* SSLfatal() called as appropriate in the below functions */ + rv = ssl_gensecret(s, pms, pmslen); } else { /* Save premaster secret */ - s->s3->tmp.pms = pms; - s->s3->tmp.pmslen = pmslen; + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; pms = NULL; rv = 1; } @@ -4854,17 +4888,80 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) return rv; } -#ifndef OPENSSL_NO_DH -EVP_PKEY *ssl_dh_to_pkey(DH *dh) +int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, + unsigned char **ctp, size_t *ctlenp, + int gensecret) { - EVP_PKEY *ret; - if (dh == NULL) - return NULL; - ret = EVP_PKEY_new(); - if (EVP_PKEY_set1_DH(ret, dh) <= 0) { - EVP_PKEY_free(ret); - return NULL; + int rv = 0; + unsigned char *pms = NULL, *ct = NULL; + size_t pmslen = 0, ctlen = 0; + EVP_PKEY_CTX *pctx; + + if (pubkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } - return ret; + + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pubkey, s->ctx->propq); + + if (EVP_PKEY_encapsulate_init(pctx, NULL) <= 0 + || EVP_PKEY_encapsulate(pctx, NULL, &ctlen, NULL, &pmslen) <= 0 + || pmslen == 0 || ctlen == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + pms = OPENSSL_malloc(pmslen); + ct = OPENSSL_malloc(ctlen); + if (pms == NULL || ct == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encapsulate(pctx, ct, &ctlen, pms, &pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (gensecret) { + /* SSLfatal() called as appropriate in the below functions */ + rv = ssl_gensecret(s, pms, pmslen); + } else { + /* Save premaster secret */ + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; + pms = NULL; + rv = 1; + } + + if (rv > 0) { + /* Pass ownership of ct to caller */ + *ctp = ct; + *ctlenp = ctlen; + ct = NULL; + } + + err: + OPENSSL_clear_free(pms, pmslen); + OPENSSL_free(ct); + EVP_PKEY_CTX_free(pctx); + return rv; +} + +const char *SSL_group_to_name(SSL *s, int nid) { + int group_id = 0; + const TLS_GROUP_INFO *cinf = NULL; + + /* first convert to real group id for internal and external IDs */ + if (nid & TLSEXT_nid_unknown) + group_id = nid & 0xFFFF; + else + group_id = tls1_nid2group_id(nid); + + /* then look up */ + cinf = tls1_group_id_lookup(s->ctx, group_id); + + if (cinf != NULL) + return cinf->tlsname; + return NULL; } -#endif diff --git a/ssl/s3_msg.c b/ssl/s3_msg.c index 707e962d73d4..c0f0dbc17dcc 100644 --- a/ssl/s3_msg.c +++ b/ssl/s3_msg.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2021 The OpenSSL Project Authors. 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,20 +18,24 @@ int ssl3_do_change_cipher_spec(SSL *s) else i = SSL3_CHANGE_CIPHER_CLIENT_READ; - if (s->s3->tmp.key_block == NULL) { + if (s->s3.tmp.key_block == NULL) { if (s->session == NULL || s->session->master_key_length == 0) { /* might happen if dtls1_read_bytes() calls this */ - SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, SSL_R_CCS_RECEIVED_EARLY); + ERR_raise(ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY); return 0; } - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) + s->session->cipher = s->s3.tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + /* SSLfatal() already called */ return 0; + } } - if (!s->method->ssl3_enc->change_cipher_state(s, i)) + if (!s->method->ssl3_enc->change_cipher_state(s, i)) { + /* SSLfatal() already called */ return 0; + } return 1; } @@ -54,9 +58,9 @@ int ssl3_send_alert(SSL *s, int level, int desc) if ((level == SSL3_AL_FATAL) && (s->session != NULL)) SSL_CTX_remove_session(s->session_ctx, s->session); - s->s3->alert_dispatch = 1; - s->s3->send_alert[0] = level; - s->s3->send_alert[1] = desc; + s->s3.alert_dispatch = 1; + s->s3.send_alert[0] = level; + s->s3.send_alert[1] = desc; if (!RECORD_LAYER_write_pending(&s->rlayer)) { /* data still being written out? */ return s->method->ssl_dispatch_alert(s); @@ -75,12 +79,12 @@ int ssl3_dispatch_alert(SSL *s) void (*cb) (const SSL *ssl, int type, int val) = NULL; size_t written; - s->s3->alert_dispatch = 0; + s->s3.alert_dispatch = 0; alertlen = 2; - i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], &alertlen, 1, 0, + i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3.send_alert[0], &alertlen, 1, 0, &written); if (i <= 0) { - s->s3->alert_dispatch = 1; + s->s3.alert_dispatch = 1; } else { /* * Alert sent to BIO - now flush. If the message does not get sent due @@ -89,7 +93,7 @@ int ssl3_dispatch_alert(SSL *s) (void)BIO_flush(s->wbio); if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, + s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3.send_alert, 2, s, s->msg_callback_arg); if (s->info_callback != NULL) @@ -98,7 +102,7 @@ int ssl3_dispatch_alert(SSL *s) cb = s->ctx->info_callback; if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; + j = (s->s3.send_alert[0] << 8) | s->s3.send_alert[1]; cb(s, SSL_CB_WRITE_ALERT, j); } } diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c index 926436410050..3503fdc21060 100644 --- a/ssl/ssl_asn1.c +++ b/ssl/ssl_asn1.c @@ -2,7 +2,7 @@ * Copyright 1995-2021 The OpenSSL Project Authors. 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 @@ -43,6 +43,7 @@ typedef struct { ASN1_OCTET_STRING *alpn_selected; uint32_t tlsext_max_fragment_len_mode; ASN1_OCTET_STRING *ticket_appdata; + uint32_t kex_group; } SSL_SESSION_ASN1; ASN1_SEQUENCE(SSL_SESSION_ASN1) = { @@ -73,7 +74,8 @@ ASN1_SEQUENCE(SSL_SESSION_ASN1) = { ASN1_EXP_OPT_EMBED(SSL_SESSION_ASN1, max_early_data, ZUINT32, 15), ASN1_EXP_OPT(SSL_SESSION_ASN1, alpn_selected, ASN1_OCTET_STRING, 16), ASN1_EXP_OPT_EMBED(SSL_SESSION_ASN1, tlsext_max_fragment_len_mode, ZUINT32, 17), - ASN1_EXP_OPT(SSL_SESSION_ASN1, ticket_appdata, ASN1_OCTET_STRING, 18) + ASN1_EXP_OPT(SSL_SESSION_ASN1, ticket_appdata, ASN1_OCTET_STRING, 18), + ASN1_EXP_OPT_EMBED(SSL_SESSION_ASN1, kex_group, UINT32, 19) } static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) @@ -83,9 +85,9 @@ IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1) /* Initialise OCTET STRING from buffer and length */ static void ssl_session_oinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os, - unsigned char *data, size_t len) + const unsigned char *data, size_t len) { - os->data = data; + os->data = (unsigned char *)data; /* justified cast: data is not modified */ os->length = (int)len; os->flags = 0; *dest = os; @@ -93,15 +95,15 @@ static void ssl_session_oinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os, /* Initialise OCTET STRING from string */ static void ssl_session_sinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os, - char *data) + const char *data) { if (data != NULL) - ssl_session_oinit(dest, os, (unsigned char *)data, strlen(data)); + ssl_session_oinit(dest, os, (const unsigned char *)data, strlen(data)); else *dest = NULL; } -int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) +int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp) { SSL_SESSION_ASN1 as; @@ -134,6 +136,8 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) as.version = SSL_SESSION_ASN1_VERSION; as.ssl_version = in->ssl_version; + as.kex_group = in->kex_group; + if (in->cipher == NULL) l = in->cipher_id; else @@ -159,8 +163,8 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) ssl_session_oinit(&as.session_id_context, &sid_ctx, in->sid_ctx, in->sid_ctx_length); - as.time = in->time; - as.timeout = in->timeout; + as.time = (int64_t)in->time; + as.timeout = (int64_t)in->timeout; as.verify_result = in->verify_result; as.peer = in->peer; @@ -250,7 +254,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if (as == NULL) goto err; - if (!a || !*a) { + if (a == NULL || *a == NULL) { ret = SSL_SESSION_new(); if (ret == NULL) goto err; @@ -259,21 +263,23 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, } if (as->version != SSL_SESSION_ASN1_VERSION) { - SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_SSL_VERSION); goto err; } if ((as->ssl_version >> 8) != SSL3_VERSION_MAJOR && (as->ssl_version >> 8) != DTLS1_VERSION_MAJOR && as->ssl_version != DTLS1_BAD_VER) { - SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION); goto err; } ret->ssl_version = (int)as->ssl_version; + ret->kex_group = as->kex_group; + if (as->cipher->length != 2) { - SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_CIPHER_CODE_WRONG_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_CIPHER_CODE_WRONG_LENGTH); goto err; } @@ -296,14 +302,15 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, ret->master_key_length = tmpl; if (as->time != 0) - ret->time = (long)as->time; + ret->time = (time_t)as->time; else - ret->time = (long)time(NULL); + ret->time = time(NULL); if (as->timeout != 0) - ret->timeout = (long)as->timeout; + ret->timeout = (time_t)as->timeout; else ret->timeout = 3; + ssl_session_calculate_timeout(ret); X509_free(ret->peer); ret->peer = as->peer; @@ -339,7 +346,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, #ifndef OPENSSL_NO_COMP if (as->comp_id) { if (as->comp_id->length != 1) { - SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); goto err; } ret->compress_meth = as->comp_id->data[0]; diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index b615e7048da4..e4168e74c276 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -2,7 +2,7 @@ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. 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 @@ -15,6 +15,7 @@ #include "internal/o_dir.h" #include <openssl/bio.h> #include <openssl/pem.h> +#include <openssl/store.h> #include <openssl/x509v3.h> #include <openssl/dh.h> #include <openssl/bn.h> @@ -52,7 +53,7 @@ CERT *ssl_cert_new(void) CERT *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } @@ -63,7 +64,7 @@ CERT *ssl_cert_new(void) ret->sec_ex = NULL; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } @@ -77,7 +78,7 @@ CERT *ssl_cert_dup(CERT *cert) int i; if (ret == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } @@ -85,18 +86,18 @@ CERT *ssl_cert_dup(CERT *cert) ret->key = &ret->pkeys[cert->key - cert->pkeys]; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } -#ifndef OPENSSL_NO_DH + if (cert->dh_tmp != NULL) { ret->dh_tmp = cert->dh_tmp; EVP_PKEY_up_ref(ret->dh_tmp); } + ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; -#endif for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; @@ -114,7 +115,7 @@ CERT *ssl_cert_dup(CERT *cert) if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } } @@ -123,7 +124,7 @@ CERT *ssl_cert_dup(CERT *cert) ret->pkeys[i].serverinfo = OPENSSL_malloc(cert->pkeys[i].serverinfo_length); if (ret->pkeys[i].serverinfo == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; @@ -231,9 +232,7 @@ void ssl_cert_free(CERT *c) return; REF_ASSERT_ISNT(i < 0); -#ifndef OPENSSL_NO_DH EVP_PKEY_free(c->dh_tmp); -#endif ssl_cert_clear_certs(c); OPENSSL_free(c->conf_sigalgs); @@ -252,13 +251,16 @@ void ssl_cert_free(CERT *c) int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain) { int i, r; - CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key; + CERT_PKEY *cpk = s != NULL ? s->cert->key : ctx->cert->key; + if (!cpk) return 0; for (i = 0; i < sk_X509_num(chain); i++) { - r = ssl_security_cert(s, ctx, sk_X509_value(chain, i), 0, 0); + X509 *x = sk_X509_value(chain, i); + + r = ssl_security_cert(s, ctx, x, 0, 0); if (r != 1) { - SSLerr(SSL_F_SSL_CERT_SET0_CHAIN, r); + ERR_raise(ERR_LIB_SSL, r); return 0; } } @@ -290,7 +292,7 @@ int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x) return 0; r = ssl_security_cert(s, ctx, x, 0, 0); if (r != 1) { - SSLerr(SSL_F_SSL_CERT_ADD0_CHAIN_CERT, r); + ERR_raise(ERR_LIB_SSL, r); return 0; } if (!cpk->chain) @@ -360,6 +362,13 @@ void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) c->cert_cb_arg = arg; } +/* + * Verify a certificate chain + * Return codes: + * 1: Verify success + * 0: Verify failure or error + * -1: Retry required + */ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) { X509 *x; @@ -376,15 +385,15 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) else verify_store = s->ctx->cert_store; - ctx = X509_STORE_CTX_new(); + ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, s->ctx->propq); if (ctx == NULL) { - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } x = sk_X509_value(sk, 0); if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) { - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto end; } param = X509_STORE_CTX_get0_param(ctx); @@ -421,10 +430,14 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) if (s->verify_callback) X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback); - if (s->ctx->app_verify_callback != NULL) + if (s->ctx->app_verify_callback != NULL) { i = s->ctx->app_verify_callback(ctx, s->ctx->app_verify_arg); - else + } else { i = X509_verify_cert(ctx); + /* We treat an error in the same way as a failure to verify */ + if (i < 0) + i = 0; + } s->verify_result = X509_STORE_CTX_get_error(ctx); sk_X509_pop_free(s->verified_chain, X509_free); @@ -432,7 +445,7 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) if (X509_STORE_CTX_get0_chain(ctx) != NULL) { s->verified_chain = X509_STORE_CTX_get1_chain(ctx); if (s->verified_chain == NULL) { - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); i = 0; } } @@ -461,13 +474,13 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) ret = sk_X509_NAME_new_reserve(NULL, num); if (ret == NULL) { - SSLerr(SSL_F_SSL_DUP_CA_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } for (i = 0; i < num; i++) { name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); if (name == NULL) { - SSLerr(SSL_F_SSL_DUP_CA_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); sk_X509_NAME_pop_free(ret, X509_NAME_free); return NULL; } @@ -513,13 +526,13 @@ void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s) { - return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL; + return s->s3.tmp.peer_ca_names; } STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) { if (!s->server) - return s->s3 != NULL ? s->s3->tmp.peer_ca_names : NULL; + return s->s3.tmp.peer_ca_names; return s->client_ca_names != NULL ? s->client_ca_names : s->ctx->client_ca_names; } @@ -598,32 +611,43 @@ static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b) static unsigned long xname_hash(const X509_NAME *a) { - return X509_NAME_hash((X509_NAME *)a); + /* This returns 0 also if SHA1 is not available */ + return X509_NAME_hash_ex((X509_NAME *)a, NULL, NULL, NULL); } -STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) +STACK_OF(X509_NAME) *SSL_load_client_CA_file_ex(const char *file, + OSSL_LIB_CTX *libctx, + const char *propq) { BIO *in = BIO_new(BIO_s_file()); X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL; LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp); + OSSL_LIB_CTX *prev_libctx = NULL; if ((name_hash == NULL) || (in == NULL)) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } - if (!BIO_read_filename(in, file)) + x = X509_new_ex(libctx, propq); + if (x == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + if (BIO_read_filename(in, file) <= 0) goto err; + /* Internally lh_X509_NAME_retrieve() needs the libctx to retrieve SHA1 */ + prev_libctx = OSSL_LIB_CTX_set0_default(libctx); for (;;) { if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) break; if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } } @@ -650,6 +674,8 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) sk_X509_NAME_pop_free(ret, X509_NAME_free); ret = NULL; done: + /* restore the old libctx */ + OSSL_LIB_CTX_set0_default(prev_libctx); BIO_free(in); X509_free(x); lh_X509_NAME_free(name_hash); @@ -658,6 +684,11 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) return ret; } +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) +{ + return SSL_load_client_CA_file_ex(file, NULL, NULL); +} + int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *file) { @@ -672,11 +703,11 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, in = BIO_new(BIO_s_file()); if (in == NULL) { - SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } - if (!BIO_read_filename(in, file)) + if (BIO_read_filename(in, file) <= 0) goto err; for (;;) { @@ -722,8 +753,7 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, int r; if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { - SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, - SSL_R_PATH_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG); goto err; } #ifdef OPENSSL_SYS_VMS @@ -738,9 +768,9 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, } if (errno) { - SYSerr(SYS_F_OPENDIR, get_last_sys_error()); - ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); - SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "calling OPENSSL_dir_read(%s)", dir); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); goto err; } @@ -753,6 +783,71 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, return ret; } +static int add_uris_recursive(STACK_OF(X509_NAME) *stack, + const char *uri, int depth) +{ + int ok = 1; + OSSL_STORE_CTX *ctx = NULL; + X509 *x = NULL; + X509_NAME *xn = NULL; + + if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL) + goto err; + + while (!OSSL_STORE_eof(ctx) && !OSSL_STORE_error(ctx)) { + OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); + int infotype = info == 0 ? 0 : OSSL_STORE_INFO_get_type(info); + + if (info == NULL) + continue; + + if (infotype == OSSL_STORE_INFO_NAME) { + /* + * This is an entry in the "directory" represented by the current + * uri. if |depth| allows, dive into it. + */ + if (depth > 0) + ok = add_uris_recursive(stack, OSSL_STORE_INFO_get0_NAME(info), + depth - 1); + } else if (infotype == OSSL_STORE_INFO_CERT) { + if ((x = OSSL_STORE_INFO_get0_CERT(info)) == NULL + || (xn = X509_get_subject_name(x)) == NULL + || (xn = X509_NAME_dup(xn)) == NULL) + goto err; + if (sk_X509_NAME_find(stack, xn) >= 0) { + /* Duplicate. */ + X509_NAME_free(xn); + } else if (!sk_X509_NAME_push(stack, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + OSSL_STORE_INFO_free(info); + } + + ERR_clear_error(); + goto done; + + err: + ok = 0; + done: + OSSL_STORE_close(ctx); + + return ok; +} + +int SSL_add_store_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *store) +{ + int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b) + = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp); + int ret = add_uris_recursive(stack, store, 1); + + (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); + return ret; +} + /* Build a certificate chain for current certificate */ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) { @@ -762,10 +857,11 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) X509_STORE_CTX *xs_ctx = NULL; STACK_OF(X509) *chain = NULL, *untrusted = NULL; X509 *x; + SSL_CTX *real_ctx = (s == NULL) ? ctx : s->ctx; int i, rv = 0; if (!cpk->x509) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET); goto err; } /* Rearranging and check the chain: add everything to a store */ @@ -793,13 +889,13 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) untrusted = cpk->chain; } - xs_ctx = X509_STORE_CTX_new(); + xs_ctx = X509_STORE_CTX_new_ex(real_ctx->libctx, real_ctx->propq); if (xs_ctx == NULL) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } if (!X509_STORE_CTX_init(xs_ctx, chain_store, cpk->x509, untrusted)) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); goto err; } /* Set suite B flags if needed */ @@ -816,10 +912,9 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) if (i > 0) chain = X509_STORE_CTX_get1_chain(xs_ctx); if (i <= 0) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); i = X509_STORE_CTX_get_error(xs_ctx); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(i)); + ERR_raise_data(ERR_LIB_SSL, SSL_R_CERTIFICATE_VERIFY_FAILED, + "Verify error:%s", X509_verify_cert_error_string(i)); goto err; } @@ -844,7 +939,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) x = sk_X509_value(chain, i); rv = ssl_security_cert(s, ctx, x, 0, 0); if (rv != 1) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, rv); + ERR_raise(ERR_LIB_SSL, rv); sk_X509_pop_free(chain, X509_free); rv = 0; goto err; @@ -885,6 +980,11 @@ int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain) int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp) { int level; + /* + * note that there's a corresponding minbits_table + * in crypto/x509/x509_vfy.c that's used for checking the security level + * of RSA and DSA keys + */ static const int minbits_table[5 + 1] = { 0, 80, 112, 128, 192, 256 }; if (ctx != NULL) @@ -1008,19 +1108,20 @@ int ssl_cert_lookup_by_nid(int nid, size_t *pidx) const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx) { - int nid = EVP_PKEY_id(pk); - size_t tmpidx; - - if (nid == NID_undef) - return NULL; + size_t i; - if (!ssl_cert_lookup_by_nid(nid, &tmpidx)) - return NULL; + for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { + const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; - if (pidx != NULL) - *pidx = tmpidx; + if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) + || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { + if (pidx != NULL) + *pidx = i; + return tmp_lu; + } + } - return &ssl_cert_info[tmpidx]; + return NULL; } const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx) diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h index 0c47241c02b8..f66c5fe39075 100644 --- a/ssl/ssl_cert_table.h +++ b/ssl/ssl_cert_table.h @@ -1,7 +1,7 @@ /* * Copyright 2017-2018 The OpenSSL Project Authors. 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 diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index a3ca5294be2e..73a821289d43 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.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 @@ -16,35 +16,12 @@ #include <openssl/engine.h> #include <openssl/crypto.h> #include <openssl/conf.h> +#include <openssl/trace.h> #include "internal/nelem.h" #include "ssl_local.h" #include "internal/thread_once.h" #include "internal/cryptlib.h" -#define SSL_ENC_DES_IDX 0 -#define SSL_ENC_3DES_IDX 1 -#define SSL_ENC_RC4_IDX 2 -#define SSL_ENC_RC2_IDX 3 -#define SSL_ENC_IDEA_IDX 4 -#define SSL_ENC_NULL_IDX 5 -#define SSL_ENC_AES128_IDX 6 -#define SSL_ENC_AES256_IDX 7 -#define SSL_ENC_CAMELLIA128_IDX 8 -#define SSL_ENC_CAMELLIA256_IDX 9 -#define SSL_ENC_GOST89_IDX 10 -#define SSL_ENC_SEED_IDX 11 -#define SSL_ENC_AES128GCM_IDX 12 -#define SSL_ENC_AES256GCM_IDX 13 -#define SSL_ENC_AES128CCM_IDX 14 -#define SSL_ENC_AES256CCM_IDX 15 -#define SSL_ENC_AES128CCM8_IDX 16 -#define SSL_ENC_AES256CCM8_IDX 17 -#define SSL_ENC_GOST8912_IDX 18 -#define SSL_ENC_CHACHA_IDX 19 -#define SSL_ENC_ARIA128GCM_IDX 20 -#define SSL_ENC_ARIA256GCM_IDX 21 -#define SSL_ENC_NUM_IDX 22 - /* NB: make sure indices in these tables match values above */ typedef struct { @@ -76,10 +53,10 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */ {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */ {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */ + {SSL_MAGMA, NID_magma_ctr_acpkm}, /* SSL_ENC_MAGMA_IDX */ + {SSL_KUZNYECHIK, NID_kuznyechik_ctr_acpkm}, /* SSL_ENC_KUZNYECHIK_IDX */ }; -static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; - #define SSL_COMP_NULL_IDX 0 #define SSL_COMP_ZLIB_IDX 1 #define SSL_COMP_NUM_IDX 2 @@ -90,13 +67,6 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; static CRYPTO_ONCE ssl_load_builtin_comp_once = CRYPTO_ONCE_STATIC_INIT; #endif -/* - * Constant SSL_MAX_DIGEST equal to size of digests array should be defined - * in the ssl_local.h - */ - -#define SSL_MD_NUM_IDX SSL_MAX_DIGEST - /* NB: make sure indices in this table matches values above */ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { {SSL_MD5, NID_md5}, /* SSL_MD_MD5_IDX 0 */ @@ -110,11 +80,9 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */ {0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */ {0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */ - {0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */ -}; - -static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + {0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */ + {SSL_MAGMAOMAC, NID_magma_mac}, /* sSL_MD_MAGMAOMAC_IDX */ + {SSL_KUZNYECHIKOMAC, NID_kuznyechik_mac} /* SSL_MD_KUZNYECHIKOMAC_IDX */ }; /* *INDENT-OFF* */ @@ -128,6 +96,7 @@ static const ssl_cipher_table ssl_cipher_table_kx[] = { {SSL_kPSK, NID_kx_psk}, {SSL_kSRP, NID_kx_srp}, {SSL_kGOST, NID_kx_gost}, + {SSL_kGOST18, NID_kx_gost18}, {SSL_kANY, NID_kx_any} }; @@ -164,19 +133,17 @@ static int ssl_cipher_info_find(const ssl_cipher_table * table, * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is * found */ -static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { +static const int default_mac_pkey_id[SSL_MD_NUM_IDX] = { /* MD5, SHA, GOST94, MAC89 */ EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, /* SHA256, SHA384, GOST2012_256, MAC89-12 */ EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, /* GOST2012_512 */ EVP_PKEY_HMAC, - /* MD5/SHA1, SHA224, SHA512 */ - NID_undef, NID_undef, NID_undef + /* MD5/SHA1, SHA224, SHA512, MAGMAOMAC, KUZNYECHIKOMAC */ + NID_undef, NID_undef, NID_undef, NID_undef, NID_undef }; -static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; - #define CIPHER_ADD 1 #define CIPHER_KILL 2 #define CIPHER_DEL 3 @@ -228,6 +195,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_kDHEPSK, NULL, 0, SSL_kDHEPSK}, {0, SSL_TXT_kSRP, NULL, 0, SSL_kSRP}, {0, SSL_TXT_kGOST, NULL, 0, SSL_kGOST}, + {0, SSL_TXT_kGOST18, NULL, 0, SSL_kGOST18}, /* server authentication aliases */ {0, SSL_TXT_aRSA, NULL, 0, 0, SSL_aRSA}, @@ -261,7 +229,8 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_IDEA, NULL, 0, 0, 0, SSL_IDEA}, {0, SSL_TXT_SEED, NULL, 0, 0, 0, SSL_SEED}, {0, SSL_TXT_eNULL, NULL, 0, 0, 0, SSL_eNULL}, - {0, SSL_TXT_GOST, NULL, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12}, + {0, SSL_TXT_GOST, NULL, 0, 0, 0, + SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12 | SSL_MAGMA | SSL_KUZNYECHIK}, {0, SSL_TXT_AES128, NULL, 0, 0, 0, SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8}, {0, SSL_TXT_AES256, NULL, 0, 0, 0, @@ -275,11 +244,13 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_CAMELLIA256, NULL, 0, 0, 0, SSL_CAMELLIA256}, {0, SSL_TXT_CAMELLIA, NULL, 0, 0, 0, SSL_CAMELLIA}, {0, SSL_TXT_CHACHA20, NULL, 0, 0, 0, SSL_CHACHA20}, + {0, SSL_TXT_GOST2012_GOST8912_GOST8912, NULL, 0, 0, 0, SSL_eGOST2814789CNT12}, {0, SSL_TXT_ARIA, NULL, 0, 0, 0, SSL_ARIA}, {0, SSL_TXT_ARIA_GCM, NULL, 0, 0, 0, SSL_ARIA128GCM | SSL_ARIA256GCM}, {0, SSL_TXT_ARIA128, NULL, 0, 0, 0, SSL_ARIA128GCM}, {0, SSL_TXT_ARIA256, NULL, 0, 0, 0, SSL_ARIA256GCM}, + {0, SSL_TXT_CBC, NULL, 0, 0, 0, SSL_CBC}, /* MAC aliases */ {0, SSL_TXT_MD5, NULL, 0, 0, 0, 0, SSL_MD5}, @@ -342,108 +313,134 @@ static int get_optional_pkey_id(const char *pkey_name) ameth) <= 0) pkey_id = 0; } - ENGINE_finish(tmpeng); + tls_engine_finish(tmpeng); return pkey_id; } #endif -/* masks of disabled algorithms */ -static uint32_t disabled_enc_mask; -static uint32_t disabled_mac_mask; -static uint32_t disabled_mkey_mask; -static uint32_t disabled_auth_mask; - -int ssl_load_ciphers(void) +int ssl_load_ciphers(SSL_CTX *ctx) { size_t i; const ssl_cipher_table *t; + EVP_KEYEXCH *kex = NULL; + EVP_SIGNATURE *sig = NULL; - disabled_enc_mask = 0; - ssl_sort_cipher_list(); + ctx->disabled_enc_mask = 0; for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) { - if (t->nid == NID_undef) { - ssl_cipher_methods[i] = NULL; - } else { - const EVP_CIPHER *cipher = EVP_get_cipherbynid(t->nid); - ssl_cipher_methods[i] = cipher; + if (t->nid != NID_undef) { + const EVP_CIPHER *cipher + = ssl_evp_cipher_fetch(ctx->libctx, t->nid, ctx->propq); + + ctx->ssl_cipher_methods[i] = cipher; if (cipher == NULL) - disabled_enc_mask |= t->mask; + ctx->disabled_enc_mask |= t->mask; } } - disabled_mac_mask = 0; + ctx->disabled_mac_mask = 0; for (i = 0, t = ssl_cipher_table_mac; i < SSL_MD_NUM_IDX; i++, t++) { - const EVP_MD *md = EVP_get_digestbynid(t->nid); - ssl_digest_methods[i] = md; + const EVP_MD *md + = ssl_evp_md_fetch(ctx->libctx, t->nid, ctx->propq); + + ctx->ssl_digest_methods[i] = md; if (md == NULL) { - disabled_mac_mask |= t->mask; + ctx->disabled_mac_mask |= t->mask; } else { - int tmpsize = EVP_MD_size(md); + int tmpsize = EVP_MD_get_size(md); if (!ossl_assert(tmpsize >= 0)) return 0; - ssl_mac_secret_size[i] = tmpsize; + ctx->ssl_mac_secret_size[i] = tmpsize; } } - /* Make sure we can access MD5 and SHA1 */ - if (!ossl_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL)) - return 0; - if (!ossl_assert(ssl_digest_methods[SSL_MD_SHA1_IDX] != NULL)) - return 0; - disabled_mkey_mask = 0; - disabled_auth_mask = 0; + ctx->disabled_mkey_mask = 0; + ctx->disabled_auth_mask = 0; + + /* + * We ignore any errors from the fetches below. They are expected to fail + * if theose algorithms are not available. + */ + ERR_set_mark(); + sig = EVP_SIGNATURE_fetch(ctx->libctx, "DSA", ctx->propq); + if (sig == NULL) + ctx->disabled_auth_mask |= SSL_aDSS; + else + EVP_SIGNATURE_free(sig); + kex = EVP_KEYEXCH_fetch(ctx->libctx, "DH", ctx->propq); + if (kex == NULL) + ctx->disabled_mkey_mask |= SSL_kDHE | SSL_kDHEPSK; + else + EVP_KEYEXCH_free(kex); + kex = EVP_KEYEXCH_fetch(ctx->libctx, "ECDH", ctx->propq); + if (kex == NULL) + ctx->disabled_mkey_mask |= SSL_kECDHE | SSL_kECDHEPSK; + else + EVP_KEYEXCH_free(kex); + sig = EVP_SIGNATURE_fetch(ctx->libctx, "ECDSA", ctx->propq); + if (sig == NULL) + ctx->disabled_auth_mask |= SSL_aECDSA; + else + EVP_SIGNATURE_free(sig); + ERR_pop_to_mark(); -#ifdef OPENSSL_NO_RSA - disabled_mkey_mask |= SSL_kRSA | SSL_kRSAPSK; - disabled_auth_mask |= SSL_aRSA; -#endif -#ifdef OPENSSL_NO_DSA - disabled_auth_mask |= SSL_aDSS; -#endif -#ifdef OPENSSL_NO_DH - disabled_mkey_mask |= SSL_kDHE | SSL_kDHEPSK; -#endif -#ifdef OPENSSL_NO_EC - disabled_mkey_mask |= SSL_kECDHE | SSL_kECDHEPSK; - disabled_auth_mask |= SSL_aECDSA; -#endif #ifdef OPENSSL_NO_PSK - disabled_mkey_mask |= SSL_PSK; - disabled_auth_mask |= SSL_aPSK; + ctx->disabled_mkey_mask |= SSL_PSK; + ctx->disabled_auth_mask |= SSL_aPSK; #endif #ifdef OPENSSL_NO_SRP - disabled_mkey_mask |= SSL_kSRP; + ctx->disabled_mkey_mask |= SSL_kSRP; #endif /* * Check for presence of GOST 34.10 algorithms, and if they are not * present, disable appropriate auth and key exchange */ - ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); - if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) - ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; + memcpy(ctx->ssl_mac_pkey_id, default_mac_pkey_id, + sizeof(ctx->ssl_mac_pkey_id)); + + ctx->ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = + get_optional_pkey_id(SN_id_Gost28147_89_MAC); + if (ctx->ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) + ctx->ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; + else + ctx->disabled_mac_mask |= SSL_GOST89MAC; + + ctx->ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] = + get_optional_pkey_id(SN_gost_mac_12); + if (ctx->ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX]) + ctx->ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32; else - disabled_mac_mask |= SSL_GOST89MAC; + ctx->disabled_mac_mask |= SSL_GOST89MAC12; - ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] = - get_optional_pkey_id("gost-mac-12"); - if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX]) - ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32; + ctx->ssl_mac_pkey_id[SSL_MD_MAGMAOMAC_IDX] = + get_optional_pkey_id(SN_magma_mac); + if (ctx->ssl_mac_pkey_id[SSL_MD_MAGMAOMAC_IDX]) + ctx->ssl_mac_secret_size[SSL_MD_MAGMAOMAC_IDX] = 32; else - disabled_mac_mask |= SSL_GOST89MAC12; - - if (!get_optional_pkey_id("gost2001")) - disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12; - if (!get_optional_pkey_id("gost2012_256")) - disabled_auth_mask |= SSL_aGOST12; - if (!get_optional_pkey_id("gost2012_512")) - disabled_auth_mask |= SSL_aGOST12; + ctx->disabled_mac_mask |= SSL_MAGMAOMAC; + + ctx->ssl_mac_pkey_id[SSL_MD_KUZNYECHIKOMAC_IDX] = + get_optional_pkey_id(SN_kuznyechik_mac); + if (ctx->ssl_mac_pkey_id[SSL_MD_KUZNYECHIKOMAC_IDX]) + ctx->ssl_mac_secret_size[SSL_MD_KUZNYECHIKOMAC_IDX] = 32; + else + ctx->disabled_mac_mask |= SSL_KUZNYECHIKOMAC; + + if (!get_optional_pkey_id(SN_id_GostR3410_2001)) + ctx->disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12; + if (!get_optional_pkey_id(SN_id_GostR3410_2012_256)) + ctx->disabled_auth_mask |= SSL_aGOST12; + if (!get_optional_pkey_id(SN_id_GostR3410_2012_512)) + ctx->disabled_auth_mask |= SSL_aGOST12; /* * Disable GOST key exchange if no GOST signature algs are available * */ - if ((disabled_auth_mask & (SSL_aGOST01 | SSL_aGOST12)) == + if ((ctx->disabled_auth_mask & (SSL_aGOST01 | SSL_aGOST12)) == (SSL_aGOST01 | SSL_aGOST12)) - disabled_mkey_mask |= SSL_kGOST; + ctx->disabled_mkey_mask |= SSL_kGOST; + + if ((ctx->disabled_auth_mask & SSL_aGOST12) == SSL_aGOST12) + ctx->disabled_mkey_mask |= SSL_kGOST18; return 1; } @@ -460,7 +457,6 @@ DEFINE_RUN_ONCE_STATIC(do_load_builtin_compressions) SSL_COMP *comp = NULL; COMP_METHOD *method = COMP_zlib(); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); if (COMP_get_type(method) != NID_undef && ssl_comp_methods != NULL) { @@ -473,7 +469,6 @@ DEFINE_RUN_ONCE_STATIC(do_load_builtin_compressions) sk_SSL_COMP_sort(ssl_comp_methods); } } - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); return 1; } @@ -483,9 +478,39 @@ static int load_builtin_compressions(void) } #endif -int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, - size_t *mac_secret_size, SSL_COMP **comp, int use_etm) +int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc) +{ + int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, sslc->algorithm_enc); + + if (i == -1) { + *enc = NULL; + } else { + if (i == SSL_ENC_NULL_IDX) { + /* + * We assume we don't care about this coming from an ENGINE so + * just do a normal EVP_CIPHER_fetch instead of + * ssl_evp_cipher_fetch() + */ + *enc = EVP_CIPHER_fetch(ctx->libctx, "NULL", ctx->propq); + if (*enc == NULL) + return 0; + } else { + const EVP_CIPHER *cipher = ctx->ssl_cipher_methods[i]; + + if (cipher == NULL + || !ssl_evp_cipher_up_ref(cipher)) + return 0; + *enc = ctx->ssl_cipher_methods[i]; + } + } + return 1; +} + +int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, + const EVP_CIPHER **enc, const EVP_MD **md, + int *mac_pkey_type, size_t *mac_secret_size, + SSL_COMP **comp, int use_etm) { int i; const SSL_CIPHER *c; @@ -507,7 +532,8 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, ctmp.id = s->compress_meth; if (ssl_comp_methods != NULL) { i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp); - *comp = sk_SSL_COMP_value(ssl_comp_methods, i); + if (i >= 0) + *comp = sk_SSL_COMP_value(ssl_comp_methods, i); } /* If were only interested in comp then return success */ if ((enc == NULL) && (md == NULL)) @@ -517,16 +543,8 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, if ((enc == NULL) || (md == NULL)) return 0; - i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, c->algorithm_enc); - - if (i == -1) { - *enc = NULL; - } else { - if (i == SSL_ENC_NULL_IDX) - *enc = EVP_enc_null(); - else - *enc = ssl_cipher_methods[i]; - } + if (!ssl_cipher_get_evp_cipher(ctx, c, enc)) + return 0; i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac); if (i == -1) { @@ -538,67 +556,84 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, if (c->algorithm_mac == SSL_AEAD) mac_pkey_type = NULL; } else { - *md = ssl_digest_methods[i]; + const EVP_MD *digest = ctx->ssl_digest_methods[i]; + + if (digest == NULL + || !ssl_evp_md_up_ref(digest)) { + ssl_evp_cipher_free(*enc); + return 0; + } + *md = digest; if (mac_pkey_type != NULL) - *mac_pkey_type = ssl_mac_pkey_id[i]; + *mac_pkey_type = ctx->ssl_mac_pkey_id[i]; if (mac_secret_size != NULL) - *mac_secret_size = ssl_mac_secret_size[i]; + *mac_secret_size = ctx->ssl_mac_secret_size[i]; } - if ((*enc != NULL) && - (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) + if ((*enc != NULL) + && (*md != NULL + || (EVP_CIPHER_get_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) && (!mac_pkey_type || *mac_pkey_type != NID_undef)) { - const EVP_CIPHER *evp; + const EVP_CIPHER *evp = NULL; - if (use_etm) + if (use_etm + || s->ssl_version >> 8 != TLS1_VERSION_MAJOR + || s->ssl_version < TLS1_VERSION) return 1; - if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || - s->ssl_version < TLS1_VERSION) - return 1; - - if (c->algorithm_enc == SSL_RC4 && - c->algorithm_mac == SSL_MD5 && - (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES128 && - c->algorithm_mac == SSL_SHA1 && - (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES256 && - c->algorithm_mac == SSL_SHA1 && - (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES128 && - c->algorithm_mac == SSL_SHA256 && - (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES256 && - c->algorithm_mac == SSL_SHA256 && - (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256"))) - *enc = evp, *md = NULL; + if (c->algorithm_enc == SSL_RC4 + && c->algorithm_mac == SSL_MD5) + evp = ssl_evp_cipher_fetch(ctx->libctx, NID_rc4_hmac_md5, + ctx->propq); + else if (c->algorithm_enc == SSL_AES128 + && c->algorithm_mac == SSL_SHA1) + evp = ssl_evp_cipher_fetch(ctx->libctx, + NID_aes_128_cbc_hmac_sha1, + ctx->propq); + else if (c->algorithm_enc == SSL_AES256 + && c->algorithm_mac == SSL_SHA1) + evp = ssl_evp_cipher_fetch(ctx->libctx, + NID_aes_256_cbc_hmac_sha1, + ctx->propq); + else if (c->algorithm_enc == SSL_AES128 + && c->algorithm_mac == SSL_SHA256) + evp = ssl_evp_cipher_fetch(ctx->libctx, + NID_aes_128_cbc_hmac_sha256, + ctx->propq); + else if (c->algorithm_enc == SSL_AES256 + && c->algorithm_mac == SSL_SHA256) + evp = ssl_evp_cipher_fetch(ctx->libctx, + NID_aes_256_cbc_hmac_sha256, + ctx->propq); + + if (evp != NULL) { + ssl_evp_cipher_free(*enc); + ssl_evp_md_free(*md); + *enc = evp; + *md = NULL; + } return 1; - } else { - return 0; } + + return 0; } -const EVP_MD *ssl_md(int idx) +const EVP_MD *ssl_md(SSL_CTX *ctx, int idx) { idx &= SSL_HANDSHAKE_MAC_MASK; if (idx < 0 || idx >= SSL_MD_NUM_IDX) return NULL; - return ssl_digest_methods[idx]; + return ctx->ssl_digest_methods[idx]; } const EVP_MD *ssl_handshake_md(SSL *s) { - return ssl_md(ssl_get_algorithm2(s)); + return ssl_md(s->ctx, ssl_get_algorithm2(s)); } const EVP_MD *ssl_prf_md(SSL *s) { - return ssl_md(ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT); + return ssl_md(s->ctx, ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT); } #define ITEM_SEP(a) \ @@ -781,12 +816,12 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, const SSL_CIPHER *cp; int reverse = 0; -#ifdef CIPHER_DEBUG - fprintf(stderr, - "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n", - rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls, - algo_strength, strength_bits); -#endif + OSSL_TRACE_BEGIN(TLS_CIPHER){ + BIO_printf(trc_out, + "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n", + rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls, + algo_strength, strength_bits); + } if (rule == CIPHER_DEL || rule == CIPHER_BUMP) reverse = 1; /* needed to maintain sorting between currently @@ -825,13 +860,14 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, if (strength_bits != cp->strength_bits) continue; } else { -#ifdef CIPHER_DEBUG - fprintf(stderr, - "\nName: %s:\nAlgo = %08x/%08x/%08x/%08x/%08x Algo_strength = %08x\n", - cp->name, cp->algorithm_mkey, cp->algorithm_auth, - cp->algorithm_enc, cp->algorithm_mac, cp->min_tls, - cp->algo_strength); -#endif + if (trc_out != NULL) { + BIO_printf(trc_out, + "\nName: %s:" + "\nAlgo = %08x/%08x/%08x/%08x/%08x Algo_strength = %08x\n", + cp->name, cp->algorithm_mkey, cp->algorithm_auth, + cp->algorithm_enc, cp->algorithm_mac, cp->min_tls, + cp->algo_strength); + } if (cipher_id != 0 && (cipher_id != cp->id)) continue; if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) @@ -852,9 +888,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, continue; } -#ifdef CIPHER_DEBUG - fprintf(stderr, "Action = %d\n", rule); -#endif + if (trc_out != NULL) + BIO_printf(trc_out, "Action = %d\n", rule); /* add the cipher if it has not been added yet. */ if (rule == CIPHER_ADD) { @@ -904,6 +939,8 @@ static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey, *head_p = head; *tail_p = tail; + + OSSL_TRACE_END(TLS_CIPHER); } static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, @@ -928,7 +965,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, number_uses = OPENSSL_zalloc(sizeof(int) * (max_strength_bits + 1)); if (number_uses == NULL) { - SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -1025,7 +1062,7 @@ static int ssl_cipher_process_rulestr(const char *rule_str, * it is no command or separator nor * alphanumeric, so we call this an error. */ - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_COMMAND); return 0; } @@ -1181,14 +1218,13 @@ static int ssl_cipher_process_rulestr(const char *rule_str, } else if (buflen == 10 && strncmp(buf, "SECLEVEL=", 9) == 0) { int level = buf[9] - '0'; if (level < 0 || level > 5) { - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, - SSL_R_INVALID_COMMAND); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_COMMAND); } else { c->sec_level = level; ok = 1; } } else { - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_COMMAND); } if (ok == 0) retval = 0; @@ -1216,7 +1252,6 @@ static int ssl_cipher_process_rulestr(const char *rule_str, return retval; } -#ifndef OPENSSL_NO_EC static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, const char **prule_str) { @@ -1244,11 +1279,10 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */ if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) { - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE); + ERR_raise(ERR_LIB_SSL, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE); return 0; } -# ifndef OPENSSL_NO_EC + switch (suiteb_flags) { case SSL_CERT_FLAG_SUITEB_128_LOS: if (suiteb_comb2) @@ -1265,12 +1299,7 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, break; } return 1; -# else - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE); - return 0; -# endif } -#endif static int ciphersuite_cb(const char *elem, int len, void *arg) { @@ -1279,22 +1308,20 @@ static int ciphersuite_cb(const char *elem, int len, void *arg) /* Arbitrary sized temp buffer for the cipher name. Should be big enough */ char name[80]; - if (len > (int)(sizeof(name) - 1)) { - SSLerr(SSL_F_CIPHERSUITE_CB, SSL_R_NO_CIPHER_MATCH); - return 0; - } + if (len > (int)(sizeof(name) - 1)) + /* Anyway return 1 so we can parse rest of the list */ + return 1; memcpy(name, elem, len); name[len] = '\0'; cipher = ssl3_get_cipher_by_std_name(name); - if (cipher == NULL) { - SSLerr(SSL_F_CIPHERSUITE_CB, SSL_R_NO_CIPHER_MATCH); - return 0; - } + if (cipher == NULL) + /* Ciphersuite not found but return 1 to parse rest of the list */ + return 1; if (!sk_SSL_CIPHER_push(ciphersuites, cipher)) { - SSLerr(SSL_F_CIPHERSUITE_CB, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } @@ -1310,7 +1337,9 @@ static __owur int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const cha /* Parse the list. We explicitly allow an empty list */ if (*str != '\0' - && !CONF_parse_list(str, ':', 1, ciphersuite_cb, newciphers)) { + && (CONF_parse_list(str, ':', 1, ciphersuite_cb, newciphers) <= 0 + || sk_SSL_CIPHER_num(newciphers) == 0)) { + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); sk_SSL_CIPHER_free(newciphers); return 0; } @@ -1338,7 +1367,8 @@ static int update_cipher_list_by_id(STACK_OF(SSL_CIPHER) **cipher_list_by_id, return 1; } -static int update_cipher_list(STACK_OF(SSL_CIPHER) **cipher_list, +static int update_cipher_list(SSL_CTX *ctx, + STACK_OF(SSL_CIPHER) **cipher_list, STACK_OF(SSL_CIPHER) **cipher_list_by_id, STACK_OF(SSL_CIPHER) *tls13_ciphersuites) { @@ -1355,15 +1385,25 @@ static int update_cipher_list(STACK_OF(SSL_CIPHER) **cipher_list, while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0 && sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls == TLS1_3_VERSION) - sk_SSL_CIPHER_delete(tmp_cipher_list, 0); + (void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0); /* Insert the new TLSv1.3 ciphersuites */ - for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) - sk_SSL_CIPHER_insert(tmp_cipher_list, - sk_SSL_CIPHER_value(tls13_ciphersuites, i), i); + for (i = sk_SSL_CIPHER_num(tls13_ciphersuites) - 1; i >= 0; i--) { + const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i); + + /* Don't include any TLSv1.3 ciphersuites that are disabled */ + if ((sslc->algorithm_enc & ctx->disabled_enc_mask) == 0 + && (ssl_cipher_table_mac[sslc->algorithm2 + & SSL_HANDSHAKE_MAC_MASK].mask + & ctx->disabled_mac_mask) == 0) { + sk_SSL_CIPHER_unshift(tmp_cipher_list, sslc); + } + } - if (!update_cipher_list_by_id(cipher_list_by_id, tmp_cipher_list)) + if (!update_cipher_list_by_id(cipher_list_by_id, tmp_cipher_list)) { + sk_SSL_CIPHER_free(tmp_cipher_list); return 0; + } sk_SSL_CIPHER_free(*cipher_list); *cipher_list = tmp_cipher_list; @@ -1376,7 +1416,7 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str); if (ret && ctx->cipher_list != NULL) - return update_cipher_list(&ctx->cipher_list, &ctx->cipher_list_by_id, + return update_cipher_list(ctx, &ctx->cipher_list, &ctx->cipher_list_by_id, ctx->tls13_ciphersuites); return ret; @@ -1392,13 +1432,13 @@ int SSL_set_ciphersuites(SSL *s, const char *str) s->cipher_list = sk_SSL_CIPHER_dup(cipher_list); } if (ret && s->cipher_list != NULL) - return update_cipher_list(&s->cipher_list, &s->cipher_list_by_id, + return update_cipher_list(s->ctx, &s->cipher_list, &s->cipher_list_by_id, s->tls13_ciphersuites); return ret; } -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, STACK_OF(SSL_CIPHER) *tls13_ciphersuites, STACK_OF(SSL_CIPHER) **cipher_list, STACK_OF(SSL_CIPHER) **cipher_list_by_id, @@ -1411,26 +1451,26 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, const char *rule_p; CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; const SSL_CIPHER **ca_list = NULL; + const SSL_METHOD *ssl_method = ctx->method; /* * Return with error if nothing to do. */ if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) return NULL; -#ifndef OPENSSL_NO_EC + if (!check_suiteb_cipher_list(ssl_method, c, &rule_str)) return NULL; -#endif /* * To reduce the work to do we only want to process the compiled * in algorithms, so we first get the mask of disabled ciphers. */ - disabled_mkey = disabled_mkey_mask; - disabled_auth = disabled_auth_mask; - disabled_enc = disabled_enc_mask; - disabled_mac = disabled_mac_mask; + disabled_mkey = ctx->disabled_mkey_mask; + disabled_auth = ctx->disabled_auth_mask; + disabled_enc = ctx->disabled_enc_mask; + disabled_mac = ctx->disabled_mac_mask; /* * Now we have to collect the available ciphers from the compiled @@ -1441,7 +1481,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers); if (co_list == NULL) { - SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; /* Failure */ } @@ -1514,7 +1554,6 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, /* * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs. - * TODO(openssl-team): is there an easier way to accomplish all this? */ ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1, &head, &tail); @@ -1555,7 +1594,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max); if (ca_list == NULL) { OPENSSL_free(co_list); - SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; /* Failure */ } ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, @@ -1569,14 +1608,14 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, ok = 1; rule_p = rule_str; if (strncmp(rule_str, "DEFAULT", 7) == 0) { - ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, + ok = ssl_cipher_process_rulestr(OSSL_default_cipher_list(), &head, &tail, ca_list, c); rule_p += 7; if (*rule_p == ':') rule_p++; } - if (ok && (strlen(rule_p) > 0)) + if (ok && (rule_p[0] != '\0')) ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c); OPENSSL_free(ca_list); /* Not needed anymore */ @@ -1597,14 +1636,28 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, /* Add TLSv1.3 ciphers first - we always prefer those if possible */ for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) { - if (!sk_SSL_CIPHER_push(cipherstack, - sk_SSL_CIPHER_value(tls13_ciphersuites, i))) { + const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i); + + /* Don't include any TLSv1.3 ciphers that are disabled */ + if ((sslc->algorithm_enc & disabled_enc) != 0 + || (ssl_cipher_table_mac[sslc->algorithm2 + & SSL_HANDSHAKE_MAC_MASK].mask + & ctx->disabled_mac_mask) != 0) { + sk_SSL_CIPHER_delete(tls13_ciphersuites, i); + i--; + continue; + } + + if (!sk_SSL_CIPHER_push(cipherstack, sslc)) { OPENSSL_free(co_list); sk_SSL_CIPHER_free(cipherstack); return NULL; } } + OSSL_TRACE_BEGIN(TLS_CIPHER) { + BIO_printf(trc_out, "cipher selection:\n"); + } /* * The cipher selection for the list is done. The ciphers are added * to the resulting precedence to the STACK_OF(SSL_CIPHER). @@ -1614,14 +1667,15 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { OPENSSL_free(co_list); sk_SSL_CIPHER_free(cipherstack); + OSSL_TRACE_CANCEL(TLS_CIPHER); return NULL; } -#ifdef CIPHER_DEBUG - fprintf(stderr, "<%s>\n", curr->cipher->name); -#endif + if (trc_out != NULL) + BIO_printf(trc_out, "<%s>\n", curr->cipher->name); } } OPENSSL_free(co_list); /* Not needed any longer */ + OSSL_TRACE_END(TLS_CIPHER); if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) { sk_SSL_CIPHER_free(cipherstack); @@ -1638,12 +1692,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) const char *ver; const char *kx, *au, *enc, *mac; uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; - static const char *format = "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n"; + static const char *format = "%-30s %-7s Kx=%-8s Au=%-5s Enc=%-22s Mac=%-4s\n"; if (buf == NULL) { len = 128; if ((buf = OPENSSL_malloc(len)) == NULL) { - SSLerr(SSL_F_SSL_CIPHER_DESCRIPTION, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } } else if (len < 128) { @@ -1685,6 +1739,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kGOST: kx = "GOST"; break; + case SSL_kGOST18: + kx = "GOST18"; + break; case SSL_kANY: kx = "any"; break; @@ -1788,6 +1845,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_eGOST2814789CNT12: enc = "GOST89(256)"; break; + case SSL_MAGMA: + enc = "MAGMA"; + break; + case SSL_KUZNYECHIK: + enc = "KUZNYECHIK"; + break; case SSL_CHACHA20POLY1305: enc = "CHACHA20/POLY1305(256)"; break; @@ -1973,16 +2036,13 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) * 193 to 255: reserved for private use */ if (id < 193 || id > 255) { - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, - SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); + ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); return 1; } - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); comp = OPENSSL_malloc(sizeof(*comp)); if (comp == NULL) { - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 1; } @@ -1991,18 +2051,14 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) load_builtin_compressions(); if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { OPENSSL_free(comp); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, - SSL_R_DUPLICATE_COMPRESSION_ID); + ERR_raise(ERR_LIB_SSL, SSL_R_DUPLICATE_COMPRESSION_ID); return 1; } if (ssl_comp_methods == NULL || !sk_SSL_COMP_push(ssl_comp_methods, comp)) { OPENSSL_free(comp); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 1; } - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); return 0; } #endif @@ -2093,7 +2149,7 @@ const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c) if (idx < 0 || idx >= SSL_MD_NUM_IDX) return NULL; - return ssl_digest_methods[idx]; + return EVP_get_digestbynid(ssl_cipher_table_mac[idx].nid); } int SSL_CIPHER_is_aead(const SSL_CIPHER *c) @@ -2128,7 +2184,7 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, if (e_md == NULL) return 0; - mac = EVP_MD_size(e_md); + mac = EVP_MD_get_size(e_md); if (c->algorithm_enc != SSL_eNULL) { int cipher_nid = SSL_CIPHER_get_cipher_nid(c); const EVP_CIPHER *e_ciph = EVP_get_cipherbynid(cipher_nid); @@ -2136,12 +2192,12 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, /* If it wasn't AEAD or SSL_eNULL, we expect it to be a known CBC cipher. */ if (e_ciph == NULL || - EVP_CIPHER_mode(e_ciph) != EVP_CIPH_CBC_MODE) + EVP_CIPHER_get_mode(e_ciph) != EVP_CIPH_CBC_MODE) return 0; in = 1; /* padding length byte */ - out = EVP_CIPHER_iv_length(e_ciph); - blk = EVP_CIPHER_block_size(e_ciph); + out = EVP_CIPHER_get_iv_length(e_ciph); + blk = EVP_CIPHER_get_block_size(e_ciph); } } @@ -2153,11 +2209,33 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, return 1; } -int ssl_cert_is_disabled(size_t idx) +int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx) { const SSL_CERT_LOOKUP *cl = ssl_cert_lookup_by_idx(idx); - if (cl == NULL || (cl->amask & disabled_auth_mask) != 0) + if (cl == NULL || (cl->amask & ctx->disabled_auth_mask) != 0) return 1; return 0; } + +/* + * Default list of TLSv1.2 (and earlier) ciphers + * SSL_DEFAULT_CIPHER_LIST deprecated in 3.0.0 + * Update both macro and function simultaneously + */ +const char *OSSL_default_cipher_list(void) +{ + return "ALL:!COMPLEMENTOFDEFAULT:!eNULL"; +} + +/* + * Default list of TLSv1.3 (and later) ciphers + * TLS_DEFAULT_CIPHERSUITES deprecated in 3.0.0 + * Update both macro and function simultaneously + */ +const char *OSSL_default_ciphersuites(void) +{ + return "TLS_AES_256_GCM_SHA384:" + "TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256"; +} diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 0a3fef7c8c14..5146cedb96ec 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -1,7 +1,7 @@ /* - * Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2022 The OpenSSL Project Authors. 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 @@ -11,7 +11,8 @@ #include "ssl_local.h" #include <openssl/conf.h> #include <openssl/objects.h> -#include <openssl/dh.h> +#include <openssl/decoder.h> +#include <openssl/core_dispatch.h> #include "internal/nelem.h" /* @@ -23,12 +24,12 @@ typedef struct { const char *name; int namelen; unsigned int name_flags; - unsigned long option_value; + uint64_t option_value; } ssl_flag_tbl; /* Switch table: use for single command line switches like no_tls2 */ typedef struct { - unsigned long option_value; + uint64_t option_value; unsigned int name_flags; } ssl_switch_tbl; @@ -83,7 +84,7 @@ struct ssl_conf_ctx_st { SSL_CTX *ctx; SSL *ssl; /* Pointer to SSL or SSL_CTX options field or NULL if none */ - uint32_t *poptions; + uint64_t *poptions; /* Certificate filenames for each type */ char *cert_filename[SSL_PKEY_NUM]; /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ @@ -103,9 +104,10 @@ struct ssl_conf_ctx_st { }; static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags, - unsigned long option_value, int onoff) + uint64_t option_value, int onoff) { uint32_t *pflags; + if (cctx->poptions == NULL) return; if (name_flags & SSL_TFLAG_INV) @@ -121,8 +123,11 @@ static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags, break; case SSL_TFLAG_OPTION: - pflags = cctx->poptions; - break; + if (onoff) + *cctx->poptions |= option_value; + else + *cctx->poptions &= ~option_value; + return; default: return; @@ -143,7 +148,8 @@ static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, if (namelen == -1) { if (strcmp(tbl->name, name)) return 0; - } else if (tbl->namelen != namelen || strncasecmp(tbl->name, name, namelen)) + } else if (tbl->namelen != namelen + || OPENSSL_strncasecmp(tbl->name, name, namelen)) return 0; ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff); return 1; @@ -220,40 +226,32 @@ static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value) return cmd_Groups(cctx, value); } -#ifndef OPENSSL_NO_EC /* ECDH temporary parameters */ static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) { int rv = 1; - EC_KEY *ecdh; - int nid; /* Ignore values supported by 1.0.2 for the automatic selection */ if ((cctx->flags & SSL_CONF_FLAG_FILE) - && (strcasecmp(value, "+automatic") == 0 - || strcasecmp(value, "automatic") == 0)) + && (OPENSSL_strcasecmp(value, "+automatic") == 0 + || OPENSSL_strcasecmp(value, "automatic") == 0)) return 1; if ((cctx->flags & SSL_CONF_FLAG_CMDLINE) && strcmp(value, "auto") == 0) return 1; - nid = EC_curve_nist2nid(value); - if (nid == NID_undef) - nid = OBJ_sn2nid(value); - if (nid == 0) - return 0; - ecdh = EC_KEY_new_by_curve_name(nid); - if (!ecdh) + /* ECDHParameters accepts a single group name */ + if (strstr(value, ":") != NULL) return 0; + if (cctx->ctx) - rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh); + rv = SSL_CTX_set1_groups_list(cctx->ctx, value); else if (cctx->ssl) - rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh); - EC_KEY_free(ecdh); + rv = SSL_set1_groups_list(cctx->ssl, value); return rv > 0; } -#endif + static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) { int rv = 1; @@ -386,12 +384,19 @@ static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), SSL_FLAG_TBL("UnsafeLegacyRenegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), + SSL_FLAG_TBL("UnsafeLegacyServerConnect", + SSL_OP_LEGACY_SERVER_CONNECT), + SSL_FLAG_TBL("ClientRenegotiation", + SSL_OP_ALLOW_CLIENT_RENEGOTIATION), SSL_FLAG_TBL_INV("EncryptThenMac", SSL_OP_NO_ENCRYPT_THEN_MAC), SSL_FLAG_TBL("NoRenegotiation", SSL_OP_NO_RENEGOTIATION), SSL_FLAG_TBL("AllowNoDHEKEX", SSL_OP_ALLOW_NO_DHE_KEX), SSL_FLAG_TBL("PrioritizeChaCha", SSL_OP_PRIORITIZE_CHACHA), SSL_FLAG_TBL("MiddleboxCompat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT), - SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY) + SSL_FLAG_TBL_INV("AntiReplay", SSL_OP_NO_ANTI_REPLAY), + SSL_FLAG_TBL_INV("ExtendedMasterSecret", SSL_OP_NO_EXTENDED_MASTER_SECRET), + SSL_FLAG_TBL_INV("CANames", SSL_OP_DISABLE_TLSEXT_CA_NAMES), + SSL_FLAG_TBL("KTLS", SSL_OP_ENABLE_KTLS) }; if (value == NULL) return -3; @@ -437,7 +442,7 @@ static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) char **pfilename = &cctx->cert_filename[c->key - c->pkeys]; OPENSSL_free(*pfilename); *pfilename = OPENSSL_strdup(value); - if (!*pfilename) + if (*pfilename == NULL) rv = 0; } @@ -465,43 +470,73 @@ static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value) } static int do_store(SSL_CONF_CTX *cctx, - const char *CAfile, const char *CApath, int verify_store) + const char *CAfile, const char *CApath, const char *CAstore, + int verify_store) { CERT *cert; X509_STORE **st; - if (cctx->ctx) + SSL_CTX *ctx; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; + + if (cctx->ctx != NULL) { cert = cctx->ctx->cert; - else if (cctx->ssl) + ctx = cctx->ctx; + } else if (cctx->ssl != NULL) { cert = cctx->ssl->cert; - else + ctx = cctx->ssl->ctx; + } else { return 1; + } + if (ctx != NULL) { + libctx = ctx->libctx; + propq = ctx->propq; + } st = verify_store ? &cert->verify_store : &cert->chain_store; if (*st == NULL) { *st = X509_STORE_new(); if (*st == NULL) return 0; } - return X509_STORE_load_locations(*st, CAfile, CApath) > 0; + + if (CAfile != NULL && !X509_STORE_load_file_ex(*st, CAfile, libctx, propq)) + return 0; + if (CApath != NULL && !X509_STORE_load_path(*st, CApath)) + return 0; + if (CAstore != NULL && !X509_STORE_load_store_ex(*st, CAstore, libctx, + propq)) + return 0; + return 1; } static int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value) { - return do_store(cctx, NULL, value, 0); + return do_store(cctx, NULL, value, NULL, 0); } static int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value) { - return do_store(cctx, value, NULL, 0); + return do_store(cctx, value, NULL, NULL, 0); +} + +static int cmd_ChainCAStore(SSL_CONF_CTX *cctx, const char *value) +{ + return do_store(cctx, NULL, NULL, value, 0); } static int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value) { - return do_store(cctx, NULL, value, 1); + return do_store(cctx, NULL, value, NULL, 1); } static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value) { - return do_store(cctx, value, NULL, 1); + return do_store(cctx, value, NULL, NULL, 1); +} + +static int cmd_VerifyCAStore(SSL_CONF_CTX *cctx, const char *value) +{ + return do_store(cctx, NULL, NULL, value, 1); } static int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value) @@ -532,33 +567,69 @@ static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value) return cmd_RequestCAPath(cctx, value); } -#ifndef OPENSSL_NO_DH +static int cmd_RequestCAStore(SSL_CONF_CTX *cctx, const char *value) +{ + if (cctx->canames == NULL) + cctx->canames = sk_X509_NAME_new_null(); + if (cctx->canames == NULL) + return 0; + return SSL_add_store_cert_subjects_to_stack(cctx->canames, value); +} + +static int cmd_ClientCAStore(SSL_CONF_CTX *cctx, const char *value) +{ + return cmd_RequestCAStore(cctx, value); +} + static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) { int rv = 0; - DH *dh = NULL; + EVP_PKEY *dhpkey = NULL; BIO *in = NULL; - if (cctx->ctx || cctx->ssl) { + SSL_CTX *sslctx = (cctx->ssl != NULL) ? cctx->ssl->ctx : cctx->ctx; + OSSL_DECODER_CTX *decoderctx = NULL; + + if (cctx->ctx != NULL || cctx->ssl != NULL) { in = BIO_new(BIO_s_file()); if (in == NULL) goto end; if (BIO_read_filename(in, value) <= 0) goto end; - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (dh == NULL) + + decoderctx + = OSSL_DECODER_CTX_new_for_pkey(&dhpkey, "PEM", NULL, "DH", + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + sslctx->libctx, sslctx->propq); + if (decoderctx == NULL) + goto end; + ERR_set_mark(); + while (!OSSL_DECODER_from_bio(decoderctx, in) + && dhpkey == NULL + && !BIO_eof(in)); + OSSL_DECODER_CTX_free(decoderctx); + + if (dhpkey == NULL) { + ERR_clear_last_mark(); goto end; - } else + } + ERR_pop_to_mark(); + } else { return 1; - if (cctx->ctx) - rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); - if (cctx->ssl) - rv = SSL_set_tmp_dh(cctx->ssl, dh); + } + + if (cctx->ctx != NULL) { + if ((rv = SSL_CTX_set0_tmp_dh_pkey(cctx->ctx, dhpkey)) > 0) + dhpkey = NULL; + } + if (cctx->ssl != NULL) { + if ((rv = SSL_set0_tmp_dh_pkey(cctx->ssl, dhpkey)) > 0) + dhpkey = NULL; + } end: - DH_free(dh); + EVP_PKEY_free(dhpkey); BIO_free(in); return rv > 0; } -#endif static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value) { @@ -612,7 +683,8 @@ typedef struct { #define SSL_CONF_CMD_SWITCH(name, flags) \ {0, NULL, name, flags, SSL_CONF_TYPE_NONE} -/* See apps/apps.h if you change this table. */ +/* See apps/include/opt.h if you change this table. */ +/* The SSL_CONF_CMD_SWITCH should be the same order as ssl_cmd_switches */ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("no_ssl3", 0), SSL_CONF_CMD_SWITCH("no_tls1", 0), @@ -626,23 +698,23 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD_SWITCH("no_ticket", 0), SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0), - SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_SERVER), + SSL_CONF_CMD_SWITCH("client_renegotiation", SSL_CONF_FLAG_SERVER), + SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_CLIENT), SSL_CONF_CMD_SWITCH("no_renegotiation", 0), SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER), - SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER), + SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_CLIENT), SSL_CONF_CMD_SWITCH("allow_no_dhe_kex", 0), SSL_CONF_CMD_SWITCH("prioritize_chacha", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("strict", 0), SSL_CONF_CMD_SWITCH("no_middlebox", 0), SSL_CONF_CMD_SWITCH("anti_replay", SSL_CONF_FLAG_SERVER), SSL_CONF_CMD_SWITCH("no_anti_replay", SSL_CONF_FLAG_SERVER), + SSL_CONF_CMD_SWITCH("no_etm", 0), SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0), SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0), SSL_CONF_CMD_STRING(Curves, "curves", 0), SSL_CONF_CMD_STRING(Groups, "groups", 0), -#ifndef OPENSSL_NO_EC SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER), -#endif SSL_CONF_CMD_STRING(CipherString, "cipher", 0), SSL_CONF_CMD_STRING(Ciphersuites, "ciphersuites", 0), SSL_CONF_CMD_STRING(Protocol, NULL, 0), @@ -661,10 +733,14 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_TYPE_DIR), SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE, SSL_CONF_TYPE_FILE), + SSL_CONF_CMD(ChainCAStore, "chainCAstore", SSL_CONF_FLAG_CERTIFICATE, + SSL_CONF_TYPE_STORE), SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE, SSL_CONF_TYPE_DIR), SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE, SSL_CONF_TYPE_FILE), + SSL_CONF_CMD(VerifyCAStore, "verifyCAstore", SSL_CONF_FLAG_CERTIFICATE, + SSL_CONF_TYPE_STORE), SSL_CONF_CMD(RequestCAFile, "requestCAFile", SSL_CONF_FLAG_CERTIFICATE, SSL_CONF_TYPE_FILE), SSL_CONF_CMD(ClientCAFile, NULL, @@ -675,11 +751,14 @@ static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { SSL_CONF_CMD(ClientCAPath, NULL, SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, SSL_CONF_TYPE_DIR), -#ifndef OPENSSL_NO_DH + SSL_CONF_CMD(RequestCAStore, "requestCAStore", SSL_CONF_FLAG_CERTIFICATE, + SSL_CONF_TYPE_STORE), + SSL_CONF_CMD(ClientCAStore, NULL, + SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, + SSL_CONF_TYPE_STORE), SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE, SSL_CONF_TYPE_FILE), -#endif SSL_CONF_CMD_STRING(RecordPadding, "record_padding", 0), SSL_CONF_CMD_STRING(NumTickets, "num_tickets", SSL_CONF_FLAG_SERVER), }; @@ -699,6 +778,8 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */ /* legacy_renegotiation */ {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0}, + /* Allow client renegotiation */ + {SSL_OP_ALLOW_CLIENT_RENEGOTIATION, 0}, /* legacy_server_connect */ {SSL_OP_LEGACY_SERVER_CONNECT, 0}, /* no_renegotiation */ @@ -718,11 +799,13 @@ static const ssl_switch_tbl ssl_cmd_switches[] = { {SSL_OP_NO_ANTI_REPLAY, SSL_TFLAG_INV}, /* no_anti_replay */ {SSL_OP_NO_ANTI_REPLAY, 0}, + /* no Encrypt-then-Mac */ + {SSL_OP_NO_ENCRYPT_THEN_MAC, 0}, }; static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) { - if (!pcmd || !*pcmd) + if (pcmd == NULL || *pcmd == NULL) return 0; /* If a prefix is set, check and skip */ if (cctx->prefix) { @@ -732,7 +815,7 @@ static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) strncmp(*pcmd, cctx->prefix, cctx->prefixlen)) return 0; if (cctx->flags & SSL_CONF_FLAG_FILE && - strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) + OPENSSL_strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) return 0; *pcmd += cctx->prefixlen; } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { @@ -774,7 +857,7 @@ static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, return t; } if (cctx->flags & SSL_CONF_FLAG_FILE) { - if (t->str_file && strcasecmp(t->str_file, cmd) == 0) + if (t->str_file && OPENSSL_strcasecmp(t->str_file, cmd) == 0) return t; } } @@ -800,7 +883,7 @@ int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) { const ssl_conf_cmd_tbl *runcmd; if (cmd == NULL) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME); return 0; } @@ -821,17 +904,14 @@ int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) return 2; if (rv == -2) return -2; - if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE); - ERR_add_error_data(4, "cmd=", cmd, ", value=", value); - } + if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) + ERR_raise_data(ERR_LIB_SSL, SSL_R_BAD_VALUE, + "cmd=%s, value=%s", cmd, value); return 0; } - if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); - ERR_add_error_data(2, "cmd=", cmd); - } + if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) + ERR_raise_data(ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME, "cmd=%s", cmd); return -2; } @@ -840,13 +920,14 @@ int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) { int rv; const char *arg = NULL, *argn; - if (pargc && *pargc == 0) + + if (pargc != NULL && *pargc == 0) return 0; - if (!pargc || *pargc > 0) + if (pargc == NULL || *pargc > 0) arg = **pargv; if (arg == NULL) return 0; - if (!pargc || *pargc > 1) + if (pargc == NULL || *pargc > 1) argn = (*pargv)[1]; else argn = NULL; diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 324f2ccbb0de..41898844ff97 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -2,7 +2,7 @@ * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-2021 The OpenSSL Project Authors. 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 @@ -10,722 +10,10 @@ #include <openssl/err.h> #include <openssl/sslerr.h> +#include "sslerr.h" #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA SSL_str_functs[] = { - {ERR_PACK(ERR_LIB_SSL, SSL_F_ADD_CLIENT_KEY_SHARE_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_ADD_KEY_SHARE, 0), "add_key_share"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_BYTES_TO_CIPHER_LIST, 0), - "bytes_to_cipher_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CHECK_SUITEB_CIPHER_LIST, 0), - "check_suiteb_cipher_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CIPHERSUITE_CB, 0), "ciphersuite_cb"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_CA_NAMES, 0), "construct_ca_names"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS, 0), - "construct_key_exchange_tbs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_STATEFUL_TICKET, 0), - "construct_stateful_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CONSTRUCT_STATELESS_TICKET, 0), - "construct_stateless_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH, 0), - "create_synthetic_message_hash"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CREATE_TICKET_PREQUEL, 0), - "create_ticket_prequel"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CT_MOVE_SCTS, 0), "ct_move_scts"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CT_STRICT, 0), "ct_strict"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CUSTOM_EXT_ADD, 0), "custom_ext_add"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_CUSTOM_EXT_PARSE, 0), "custom_ext_parse"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_D2I_SSL_SESSION, 0), "d2i_SSL_SESSION"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DANE_CTX_ENABLE, 0), "dane_ctx_enable"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DANE_MTYPE_SET, 0), "dane_mtype_set"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DANE_TLSA_ADD, 0), "dane_tlsa_add"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DERIVE_SECRET_KEY_AND_IV, 0), - "derive_secret_key_and_iv"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DO_DTLS1_WRITE, 0), "do_dtls1_write"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DO_SSL3_WRITE, 0), "do_ssl3_write"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_BUFFER_RECORD, 0), - "dtls1_buffer_record"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_CHECK_TIMEOUT_NUM, 0), - "dtls1_check_timeout_num"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_HEARTBEAT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_HM_FRAGMENT_NEW, 0), - "dtls1_hm_fragment_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_PREPROCESS_FRAGMENT, 0), - "dtls1_preprocess_fragment"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, 0), - "dtls1_process_buffered_records"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_PROCESS_RECORD, 0), - "dtls1_process_record"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_READ_BYTES, 0), "dtls1_read_bytes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_READ_FAILED, 0), "dtls1_read_failed"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_RETRANSMIT_MESSAGE, 0), - "dtls1_retransmit_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_WRITE_APP_DATA_BYTES, 0), - "dtls1_write_app_data_bytes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS1_WRITE_BYTES, 0), "dtls1_write_bytes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLSV1_LISTEN, 0), "DTLSv1_listen"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, 0), - "dtls_construct_change_cipher_spec"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST, 0), - "dtls_construct_hello_verify_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, 0), - "dtls_get_reassembled_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_PROCESS_HELLO_VERIFY, 0), - "dtls_process_hello_verify"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_RECORD_LAYER_NEW, 0), - "DTLS_RECORD_LAYER_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_DTLS_WAIT_FOR_DRY, 0), "dtls_wait_for_dry"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_EARLY_DATA_COUNT_OK, 0), - "early_data_count_ok"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_EARLY_DATA, 0), "final_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_EC_PT_FORMATS, 0), - "final_ec_pt_formats"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_EMS, 0), "final_ems"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_KEY_SHARE, 0), "final_key_share"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_MAXFRAGMENTLEN, 0), - "final_maxfragmentlen"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_PSK, 0), "final_psk"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_RENEGOTIATE, 0), "final_renegotiate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_SERVER_NAME, 0), "final_server_name"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_FINAL_SIG_ALGS, 0), "final_sig_algs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_GET_CERT_VERIFY_TBS_DATA, 0), - "get_cert_verify_tbs_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_NSS_KEYLOG_INT, 0), "nss_keylog_int"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OPENSSL_INIT_SSL, 0), "OPENSSL_init_ssl"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION, 0), - "ossl_statem_client13_write_transition"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT_POST_PROCESS_MESSAGE, 0), - "ossl_statem_client_post_process_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE, 0), - "ossl_statem_client_process_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION, 0), - "ossl_statem_client_read_transition"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION, 0), - "ossl_statem_client_write_transition"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION, 0), - "ossl_statem_server13_write_transition"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE, 0), - "ossl_statem_server_post_process_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_POST_WORK, 0), - "ossl_statem_server_post_work"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE, 0), - "ossl_statem_server_process_message"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, 0), - "ossl_statem_server_read_transition"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION, 0), - "ossl_statem_server_write_transition"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_PARSE_CA_NAMES, 0), "parse_ca_names"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_PITEM_NEW, 0), "pitem_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_PQUEUE_NEW, 0), "pqueue_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_PROCESS_KEY_SHARE_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_READ_STATE_MACHINE, 0), "read_state_machine"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SET_CLIENT_CIPHERSUITE, 0), - "set_client_ciphersuite"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET, 0), - "srp_generate_client_master_secret"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET, 0), - "srp_generate_server_master_secret"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SRP_VERIFY_SERVER_PARAM, 0), - "srp_verify_server_param"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_CHANGE_CIPHER_STATE, 0), - "ssl3_change_cipher_state"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, 0), - "ssl3_check_cert_and_algorithm"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_CTRL, 0), "ssl3_ctrl"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_CTX_CTRL, 0), "ssl3_ctx_ctrl"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_DIGEST_CACHED_RECORDS, 0), - "ssl3_digest_cached_records"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, 0), - "ssl3_do_change_cipher_spec"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_ENC, 0), "ssl3_enc"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_FINAL_FINISH_MAC, 0), - "ssl3_final_finish_mac"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_FINISH_MAC, 0), "ssl3_finish_mac"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GENERATE_KEY_BLOCK, 0), - "ssl3_generate_key_block"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GENERATE_MASTER_SECRET, 0), - "ssl3_generate_master_secret"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, 0), "ssl3_get_record"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_INIT_FINISHED_MAC, 0), - "ssl3_init_finished_mac"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_OUTPUT_CERT_CHAIN, 0), - "ssl3_output_cert_chain"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_READ_BYTES, 0), "ssl3_read_bytes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_READ_N, 0), "ssl3_read_n"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_SETUP_KEY_BLOCK, 0), - "ssl3_setup_key_block"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_SETUP_READ_BUFFER, 0), - "ssl3_setup_read_buffer"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_SETUP_WRITE_BUFFER, 0), - "ssl3_setup_write_buffer"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_WRITE_BYTES, 0), "ssl3_write_bytes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_WRITE_PENDING, 0), "ssl3_write_pending"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_CERT_CHAIN, 0), "ssl_add_cert_chain"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_CERT_TO_BUF, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_CERT_TO_WPACKET, 0), - "ssl_add_cert_to_wpacket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, 0), - "SSL_add_dir_cert_subjects_to_stack"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, 0), - "SSL_add_file_cert_subjects_to_stack"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_BAD_METHOD, 0), "ssl_bad_method"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_BUILD_CERT_CHAIN, 0), - "ssl_build_cert_chain"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_BYTES_TO_CIPHER_LIST, 0), - "SSL_bytes_to_cipher_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CACHE_CIPHERLIST, 0), - "ssl_cache_cipherlist"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CERT_ADD0_CHAIN_CERT, 0), - "ssl_cert_add0_chain_cert"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CERT_DUP, 0), "ssl_cert_dup"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CERT_NEW, 0), "ssl_cert_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CERT_SET0_CHAIN, 0), - "ssl_cert_set0_chain"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CHECK_PRIVATE_KEY, 0), - "SSL_check_private_key"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO, 0), - "ssl_check_srp_ext_ClientHello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, 0), - "ssl_check_srvr_ecc_cert_and_alg"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CHOOSE_CLIENT_VERSION, 0), - "ssl_choose_client_version"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_DESCRIPTION, 0), - "SSL_CIPHER_description"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_LIST_TO_BYTES, 0), - "ssl_cipher_list_to_bytes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_PROCESS_RULESTR, 0), - "ssl_cipher_process_rulestr"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CIPHER_STRENGTH_SORT, 0), - "ssl_cipher_strength_sort"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CLEAR, 0), "SSL_clear"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT, 0), - "SSL_client_hello_get1_extensions_present"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, 0), - "SSL_COMP_add_compression_method"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CONF_CMD, 0), "SSL_CONF_cmd"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CREATE_CIPHER_LIST, 0), - "ssl_create_cipher_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTRL, 0), "SSL_ctrl"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, 0), - "SSL_CTX_check_private_key"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_ENABLE_CT, 0), "SSL_CTX_enable_ct"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_MAKE_PROFILES, 0), - "ssl_ctx_make_profiles"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_NEW, 0), "SSL_CTX_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_ALPN_PROTOS, 0), - "SSL_CTX_set_alpn_protos"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_CIPHER_LIST, 0), - "SSL_CTX_set_cipher_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, 0), - "SSL_CTX_set_client_cert_engine"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK, 0), - "SSL_CTX_set_ct_validation_callback"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, 0), - "SSL_CTX_set_session_id_context"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_SSL_VERSION, 0), - "SSL_CTX_set_ssl_version"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH, 0), - "SSL_CTX_set_tlsext_max_fragment_length"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_CERTIFICATE, 0), - "SSL_CTX_use_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, 0), - "SSL_CTX_use_certificate_ASN1"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, 0), - "SSL_CTX_use_certificate_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY, 0), - "SSL_CTX_use_PrivateKey"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, 0), - "SSL_CTX_use_PrivateKey_ASN1"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, 0), - "SSL_CTX_use_PrivateKey_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, 0), - "SSL_CTX_use_psk_identity_hint"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, 0), - "SSL_CTX_use_RSAPrivateKey"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, 0), - "SSL_CTX_use_RSAPrivateKey_ASN1"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, 0), - "SSL_CTX_use_RSAPrivateKey_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_SERVERINFO, 0), - "SSL_CTX_use_serverinfo"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_SERVERINFO_EX, 0), - "SSL_CTX_use_serverinfo_ex"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_CTX_USE_SERVERINFO_FILE, 0), - "SSL_CTX_use_serverinfo_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_DANE_DUP, 0), "ssl_dane_dup"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_DANE_ENABLE, 0), "SSL_dane_enable"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_DERIVE, 0), "ssl_derive"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_DO_CONFIG, 0), "ssl_do_config"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_DO_HANDSHAKE, 0), "SSL_do_handshake"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_DUP_CA_LIST, 0), "SSL_dup_CA_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_ENABLE_CT, 0), "SSL_enable_ct"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_GENERATE_PKEY_GROUP, 0), - "ssl_generate_pkey_group"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_GENERATE_SESSION_ID, 0), - "ssl_generate_session_id"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_GET_NEW_SESSION, 0), - "ssl_get_new_session"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_GET_PREV_SESSION, 0), - "ssl_get_prev_session"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_GET_SERVER_CERT_INDEX, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_GET_SIGN_PKEY, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_HANDSHAKE_HASH, 0), "ssl_handshake_hash"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_INIT_WBIO_BUFFER, 0), - "ssl_init_wbio_buffer"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_KEY_UPDATE, 0), "SSL_key_update"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOAD_CLIENT_CA_FILE, 0), - "SSL_load_client_CA_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOG_MASTER_SECRET, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, 0), - "ssl_log_rsa_client_key_exchange"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_MODULE_INIT, 0), "ssl_module_init"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_NEW, 0), "SSL_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_NEXT_PROTO_VALIDATE, 0), - "ssl_next_proto_validate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PEEK, 0), "SSL_peek"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PEEK_EX, 0), "SSL_peek_ex"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_PEEK_INTERNAL, 0), "ssl_peek_internal"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_READ, 0), "SSL_read"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_READ_EARLY_DATA, 0), - "SSL_read_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_READ_EX, 0), "SSL_read_ex"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_READ_INTERNAL, 0), "ssl_read_internal"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_RENEGOTIATE, 0), "SSL_renegotiate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_RENEGOTIATE_ABBREVIATED, 0), - "SSL_renegotiate_abbreviated"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0), - "SSL_SESSION_print_fp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_SET1_ID, 0), - "SSL_SESSION_set1_id"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_SET1_ID_CONTEXT, 0), - "SSL_SESSION_set1_id_context"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_ALPN_PROTOS, 0), - "SSL_set_alpn_protos"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_CERT, 0), "ssl_set_cert"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_CERT_AND_KEY, 0), - "ssl_set_cert_and_key"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_CIPHER_LIST, 0), - "SSL_set_cipher_list"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_CT_VALIDATION_CALLBACK, 0), - "SSL_set_ct_validation_callback"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_FD, 0), "SSL_set_fd"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_PKEY, 0), "ssl_set_pkey"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_RFD, 0), "SSL_set_rfd"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION, 0), "SSL_set_session"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION_ID_CONTEXT, 0), - "SSL_set_session_id_context"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_SESSION_TICKET_EXT, 0), - "SSL_set_session_ticket_ext"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH, 0), - "SSL_set_tlsext_max_fragment_length"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SET_WFD, 0), "SSL_set_wfd"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SHUTDOWN, 0), "SSL_shutdown"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SRP_CTX_INIT, 0), "SSL_SRP_CTX_init"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_START_ASYNC_JOB, 0), - "ssl_start_async_job"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_UNDEFINED_FUNCTION, 0), - "ssl_undefined_function"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_UNDEFINED_VOID_FUNCTION, 0), - "ssl_undefined_void_function"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_CERTIFICATE, 0), - "SSL_use_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_CERTIFICATE_ASN1, 0), - "SSL_use_certificate_ASN1"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_CERTIFICATE_FILE, 0), - "SSL_use_certificate_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY, 0), "SSL_use_PrivateKey"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY_ASN1, 0), - "SSL_use_PrivateKey_ASN1"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PRIVATEKEY_FILE, 0), - "SSL_use_PrivateKey_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_PSK_IDENTITY_HINT, 0), - "SSL_use_psk_identity_hint"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_RSAPRIVATEKEY, 0), - "SSL_use_RSAPrivateKey"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, 0), - "SSL_use_RSAPrivateKey_ASN1"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, 0), - "SSL_use_RSAPrivateKey_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_VALIDATE_CT, 0), "ssl_validate_ct"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_VERIFY_CERT_CHAIN, 0), - "ssl_verify_cert_chain"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, 0), - "SSL_verify_client_post_handshake"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE, 0), "SSL_write"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_EARLY_DATA, 0), - "SSL_write_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_EARLY_FINISH, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_EX, 0), "SSL_write_ex"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_WRITE_INTERNAL, 0), "ssl_write_internal"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_STATE_MACHINE, 0), "state_machine"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS12_CHECK_PEER_SIGALG, 0), - "tls12_check_peer_sigalg"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS12_COPY_SIGALGS, 0), "tls12_copy_sigalgs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_CHANGE_CIPHER_STATE, 0), - "tls13_change_cipher_state"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_ENC, 0), "tls13_enc"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_FINAL_FINISH_MAC, 0), - "tls13_final_finish_mac"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_GENERATE_SECRET, 0), - "tls13_generate_secret"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_HKDF_EXPAND, 0), "tls13_hkdf_expand"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA, 0), - "tls13_restore_handshake_digest_for_pha"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA, 0), - "tls13_save_handshake_digest_for_pha"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS13_SETUP_KEY_BLOCK, 0), - "tls13_setup_key_block"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_CHANGE_CIPHER_STATE, 0), - "tls1_change_cipher_state"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_ENC, 0), "tls1_enc"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_EXPORT_KEYING_MATERIAL, 0), - "tls1_export_keying_material"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_GET_CURVELIST, 0), "tls1_get_curvelist"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_PRF, 0), "tls1_PRF"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SAVE_U16, 0), "tls1_save_u16"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SETUP_KEY_BLOCK, 0), - "tls1_setup_key_block"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_GROUPS, 0), "tls1_set_groups"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_RAW_SIGALGS, 0), - "tls1_set_raw_sigalgs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_SERVER_SIGALGS, 0), - "tls1_set_server_sigalgs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_SHARED_SIGALGS, 0), - "tls1_set_shared_sigalgs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS1_SET_SIGALGS, 0), "tls1_set_sigalgs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CHOOSE_SIGALG, 0), "tls_choose_sigalg"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, 0), - "tls_client_key_exchange_post_work"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_COLLECT_EXTENSIONS, 0), - "tls_collect_extensions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES, 0), - "tls_construct_certificate_authorities"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, 0), - "tls_construct_certificate_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CERT_STATUS, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY, 0), - "tls_construct_cert_status_body"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, 0), - "tls_construct_cert_verify"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC, 0), - "tls_construct_change_cipher_spec"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_DHE, 0), - "tls_construct_cke_dhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, 0), - "tls_construct_cke_ecdhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_GOST, 0), - "tls_construct_cke_gost"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, 0), - "tls_construct_cke_psk_preamble"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_RSA, 0), - "tls_construct_cke_rsa"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CKE_SRP, 0), - "tls_construct_cke_srp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, 0), - "tls_construct_client_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, 0), - "tls_construct_client_hello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, 0), - "tls_construct_client_key_exchange"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_ALPN, 0), - "tls_construct_ctos_alpn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_COOKIE, 0), - "tls_construct_ctos_cookie"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, 0), - "tls_construct_ctos_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS, 0), - "tls_construct_ctos_ec_pt_formats"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_EMS, 0), - "tls_construct_ctos_ems"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_ETM, 0), - "tls_construct_ctos_etm"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_HELLO, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_KEY_EXCHANGE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, 0), - "tls_construct_ctos_key_share"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN, 0), - "tls_construct_ctos_maxfragmentlen"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_NPN, 0), - "tls_construct_ctos_npn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_PADDING, 0), - "tls_construct_ctos_padding"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH, 0), - "tls_construct_ctos_post_handshake_auth"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_PSK, 0), - "tls_construct_ctos_psk"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, 0), - "tls_construct_ctos_psk_kex_modes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE, 0), - "tls_construct_ctos_renegotiate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SCT, 0), - "tls_construct_ctos_sct"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME, 0), - "tls_construct_ctos_server_name"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET, 0), - "tls_construct_ctos_session_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS, 0), - "tls_construct_ctos_sig_algs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SRP, 0), - "tls_construct_ctos_srp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, 0), - "tls_construct_ctos_status_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, 0), - "tls_construct_ctos_supported_groups"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, 0), - "tls_construct_ctos_supported_versions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, 0), - "tls_construct_ctos_use_srtp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_CTOS_VERIFY, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS, 0), - "tls_construct_encrypted_extensions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA, 0), - "tls_construct_end_of_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_EXTENSIONS, 0), - "tls_construct_extensions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_FINISHED, 0), - "tls_construct_finished"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_HELLO_REQUEST, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST, 0), - "tls_construct_hello_retry_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_KEY_UPDATE, 0), - "tls_construct_key_update"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, 0), - "tls_construct_new_session_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_NEXT_PROTO, 0), - "tls_construct_next_proto"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, 0), - "tls_construct_server_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_SERVER_HELLO, 0), - "tls_construct_server_hello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, 0), - "tls_construct_server_key_exchange"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_ALPN, 0), - "tls_construct_stoc_alpn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, 0), - "tls_construct_stoc_cookie"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG, 0), - "tls_construct_stoc_cryptopro_bug"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_DONE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, 0), - "tls_construct_stoc_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS, 0), - "tls_construct_stoc_ec_pt_formats"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_EMS, 0), - "tls_construct_stoc_ems"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_ETM, 0), - "tls_construct_stoc_etm"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_HELLO, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, 0), - "tls_construct_stoc_key_share"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN, 0), - "tls_construct_stoc_maxfragmentlen"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG, 0), - "tls_construct_stoc_next_proto_neg"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_PSK, 0), - "tls_construct_stoc_psk"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE, 0), - "tls_construct_stoc_renegotiate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME, 0), - "tls_construct_stoc_server_name"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET, 0), - "tls_construct_stoc_session_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST, 0), - "tls_construct_stoc_status_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, 0), - "tls_construct_stoc_supported_groups"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS, 0), - "tls_construct_stoc_supported_versions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP, 0), - "tls_construct_stoc_use_srtp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, 0), - "tls_early_post_process_client_hello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_FINISH_HANDSHAKE, 0), - "tls_finish_handshake"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_GET_MESSAGE_BODY, 0), - "tls_get_message_body"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_GET_MESSAGE_HEADER, 0), - "tls_get_message_header"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_HANDLE_ALPN, 0), "tls_handle_alpn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_HANDLE_STATUS_REQUEST, 0), - "tls_handle_status_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES, 0), - "tls_parse_certificate_authorities"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_ALPN, 0), - "tls_parse_ctos_alpn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_COOKIE, 0), - "tls_parse_ctos_cookie"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_EARLY_DATA, 0), - "tls_parse_ctos_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS, 0), - "tls_parse_ctos_ec_pt_formats"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_EMS, 0), "tls_parse_ctos_ems"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, 0), - "tls_parse_ctos_key_share"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN, 0), - "tls_parse_ctos_maxfragmentlen"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH, 0), - "tls_parse_ctos_post_handshake_auth"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_PSK, 0), "tls_parse_ctos_psk"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES, 0), - "tls_parse_ctos_psk_kex_modes"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_RENEGOTIATE, 0), - "tls_parse_ctos_renegotiate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_SERVER_NAME, 0), - "tls_parse_ctos_server_name"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_SESSION_TICKET, 0), - "tls_parse_ctos_session_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_SIG_ALGS, 0), - "tls_parse_ctos_sig_algs"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT, 0), - "tls_parse_ctos_sig_algs_cert"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_SRP, 0), "tls_parse_ctos_srp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, 0), - "tls_parse_ctos_status_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS, 0), - "tls_parse_ctos_supported_groups"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_CTOS_USE_SRTP, 0), - "tls_parse_ctos_use_srtp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_ALPN, 0), - "tls_parse_stoc_alpn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_COOKIE, 0), - "tls_parse_stoc_cookie"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_EARLY_DATA, 0), - "tls_parse_stoc_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, 0), - "tls_parse_stoc_ec_pt_formats"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_KEY_SHARE, 0), - "tls_parse_stoc_key_share"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN, 0), - "tls_parse_stoc_maxfragmentlen"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_NPN, 0), "tls_parse_stoc_npn"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_PSK, 0), "tls_parse_stoc_psk"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, 0), - "tls_parse_stoc_renegotiate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_SCT, 0), "tls_parse_stoc_sct"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_SERVER_NAME, 0), - "tls_parse_stoc_server_name"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_SESSION_TICKET, 0), - "tls_parse_stoc_session_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_STATUS_REQUEST, 0), - "tls_parse_stoc_status_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS, 0), - "tls_parse_stoc_supported_versions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PARSE_STOC_USE_SRTP, 0), - "tls_parse_stoc_use_srtp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, 0), - "tls_post_process_client_hello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE, 0), - "tls_post_process_client_key_exchange"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE, 0), - "tls_prepare_client_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST, 0), - "tls_process_as_hello_retry_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, 0), - "tls_process_certificate_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CERT_STATUS, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CERT_STATUS_BODY, 0), - "tls_process_cert_status_body"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CERT_VERIFY, 0), - "tls_process_cert_verify"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, 0), - "tls_process_change_cipher_spec"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_DHE, 0), - "tls_process_cke_dhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_ECDHE, 0), - "tls_process_cke_ecdhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_GOST, 0), - "tls_process_cke_gost"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, 0), - "tls_process_cke_psk_preamble"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_RSA, 0), - "tls_process_cke_rsa"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CKE_SRP, 0), - "tls_process_cke_srp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, 0), - "tls_process_client_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CLIENT_HELLO, 0), - "tls_process_client_hello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, 0), - "tls_process_client_key_exchange"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS, 0), - "tls_process_encrypted_extensions"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_END_OF_EARLY_DATA, 0), - "tls_process_end_of_early_data"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_FINISHED, 0), - "tls_process_finished"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_HELLO_REQ, 0), - "tls_process_hello_req"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, 0), - "tls_process_hello_retry_request"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT, 0), - "tls_process_initial_server_flight"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_KEY_EXCHANGE, 0), - "tls_process_key_exchange"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_KEY_UPDATE, 0), - "tls_process_key_update"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, 0), - "tls_process_new_session_ticket"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_NEXT_PROTO, 0), - "tls_process_next_proto"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, 0), - "tls_process_server_certificate"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SERVER_DONE, 0), - "tls_process_server_done"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SERVER_HELLO, 0), - "tls_process_server_hello"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SKE_DHE, 0), - "tls_process_ske_dhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SKE_ECDHE, 0), - "tls_process_ske_ecdhe"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, 0), - "tls_process_ske_psk_preamble"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PROCESS_SKE_SRP, 0), - "tls_process_ske_srp"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_PSK_DO_BINDER, 0), "tls_psk_do_binder"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT, 0), ""}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_SETUP_HANDSHAKE, 0), - "tls_setup_handshake"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_USE_CERTIFICATE_CHAIN_FILE, 0), - "use_certificate_chain_file"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_WPACKET_INTERN_INIT_LEN, 0), - "wpacket_intern_init_len"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_WPACKET_START_SUB_PACKET_LEN__, 0), - "WPACKET_start_sub_packet_len__"}, - {ERR_PACK(ERR_LIB_SSL, SSL_F_WRITE_STATE_MACHINE, 0), - "write_state_machine"}, - {0, NULL} -}; - static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY), "application data after close notify"}, @@ -733,8 +21,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "app data in handshake"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), "attempt to reuse session in different context"}, - {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE), - "at least TLS 1.0 needed in FIPS mode"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE), "at least (D)TLS 1.2 needed in Suite B mode"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CHANGE_CIPHER_SPEC), @@ -786,6 +72,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CALLBACK_FAILED), "callback failed"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CANNOT_CHANGE_CIPHER), "cannot change cipher"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CANNOT_GET_GROUP_NAME), + "cannot get group name"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CA_KEY_TOO_SMALL), "ca key too small"}, @@ -800,8 +88,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "ciphersuite digest has changed"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, - {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CIPHER_OR_HASH_UNAVAILABLE), - "cipher or hash unavailable"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COMPRESSED_LENGTH_TOO_LONG), "compressed length too long"}, @@ -820,6 +106,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COOKIE_GEN_CALLBACK_FAILURE), "cookie gen callback failure"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COOKIE_MISMATCH), "cookie mismatch"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COPY_PARAMETERS_FAILED), + "copy parameters failed"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED), "custom ext handler already installed"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_ALREADY_ENABLED), @@ -937,6 +225,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "invalid status response"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_TICKET_KEYS_LENGTH), "invalid ticket keys length"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED), + "legacy sigalg disallowed or unsupported"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LENGTH_MISMATCH), "length mismatch"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LENGTH_TOO_LONG), "length too long"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LENGTH_TOO_SHORT), "length too short"}, @@ -1011,6 +301,9 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS), "no shared signature algorithms"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM), + "no suitable digest algorithm"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_GROUPS), "no suitable groups"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_KEY_SHARE), "no suitable key share"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM), @@ -1184,10 +477,6 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "tlsv1 unrecognized name"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_UNSUPPORTED_EXTENSION), "tlsv1 unsupported extension"}, - {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), - "peer does not accept heartbeats"}, - {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_HEARTBEAT_PENDING), - "heartbeat request already pending"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), "tls illegal exporter label"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), @@ -1210,6 +499,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { "unexpected ccs message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_END_OF_EARLY_DATA), "unexpected end of early data"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING), + "unexpected eof while reading"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_RECORD), "unexpected record"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized"}, @@ -1270,13 +561,11 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { #endif -int ERR_load_SSL_strings(void) +int ossl_err_load_SSL_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { - ERR_load_strings_const(SSL_str_functs); + if (ERR_reason_error_string(SSL_str_reasons[0].error) == NULL) ERR_load_strings_const(SSL_str_reasons); - } #endif return 1; } diff --git a/ssl/ssl_err_legacy.c b/ssl/ssl_err_legacy.c new file mode 100644 index 000000000000..7ce25e1f1112 --- /dev/null +++ b/ssl/ssl_err_legacy.c @@ -0,0 +1,21 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * 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 + */ + +/* This is the C source file where we include this header directly */ +#include <openssl/sslerr_legacy.h> +#include "sslerr.h" + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +int ERR_load_SSL_strings(void) +{ + return ossl_err_load_SSL_strings(); +} +#else +NON_EMPTY_TRANSLATION_UNIT +#endif diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index a5d45480c9e0..db0234d7a423 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2022 The OpenSSL Project Authors. 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 @@ -12,7 +12,9 @@ #include "internal/err.h" #include <openssl/crypto.h> #include <openssl/evp.h> +#include <openssl/trace.h> #include "ssl_local.h" +#include "sslerr.h" #include "internal/thread_once.h" static int stopped; @@ -23,89 +25,17 @@ static CRYPTO_ONCE ssl_base = CRYPTO_ONCE_STATIC_INIT; static int ssl_base_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base) { -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " - "Adding SSL ciphers and digests\n"); -#endif -#ifndef OPENSSL_NO_DES - EVP_add_cipher(EVP_des_cbc()); - EVP_add_cipher(EVP_des_ede3_cbc()); -#endif -#ifndef OPENSSL_NO_IDEA - EVP_add_cipher(EVP_idea_cbc()); -#endif -#ifndef OPENSSL_NO_RC4 - EVP_add_cipher(EVP_rc4()); -# ifndef OPENSSL_NO_MD5 - EVP_add_cipher(EVP_rc4_hmac_md5()); -# endif -#endif -#ifndef OPENSSL_NO_RC2 - EVP_add_cipher(EVP_rc2_cbc()); - /* - * Not actually used for SSL/TLS but this makes PKCS#12 work if an - * application only calls SSL_library_init(). - */ - EVP_add_cipher(EVP_rc2_40_cbc()); -#endif - EVP_add_cipher(EVP_aes_128_cbc()); - EVP_add_cipher(EVP_aes_192_cbc()); - EVP_add_cipher(EVP_aes_256_cbc()); - EVP_add_cipher(EVP_aes_128_gcm()); - EVP_add_cipher(EVP_aes_256_gcm()); - EVP_add_cipher(EVP_aes_128_ccm()); - EVP_add_cipher(EVP_aes_256_ccm()); - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); -#ifndef OPENSSL_NO_ARIA - EVP_add_cipher(EVP_aria_128_gcm()); - EVP_add_cipher(EVP_aria_256_gcm()); -#endif -#ifndef OPENSSL_NO_CAMELLIA - EVP_add_cipher(EVP_camellia_128_cbc()); - EVP_add_cipher(EVP_camellia_256_cbc()); -#endif -#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) - EVP_add_cipher(EVP_chacha20_poly1305()); -#endif - -#ifndef OPENSSL_NO_SEED - EVP_add_cipher(EVP_seed_cbc()); -#endif - -#ifndef OPENSSL_NO_MD5 - EVP_add_digest(EVP_md5()); - EVP_add_digest_alias(SN_md5, "ssl3-md5"); - EVP_add_digest(EVP_md5_sha1()); -#endif - EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ - EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); - EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); - EVP_add_digest(EVP_sha224()); - EVP_add_digest(EVP_sha256()); - EVP_add_digest(EVP_sha384()); - EVP_add_digest(EVP_sha512()); #ifndef OPENSSL_NO_COMP -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " - "SSL_COMP_get_compression_methods()\n"); -# endif + OSSL_TRACE(INIT, "ossl_init_ssl_base: " + "SSL_COMP_get_compression_methods()\n"); /* * This will initialise the built-in compression algorithms. The value * returned is a STACK_OF(SSL_COMP), but that can be discarded safely */ SSL_COMP_get_compression_methods(); #endif - /* initialize cipher/digest methods table */ - if (!ssl_load_ciphers()) - return 0; - -#ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " - "SSL_add_ssl_module()\n"); -#endif + ssl_sort_cipher_list(); + OSSL_TRACE(INIT,"ossl_init_ssl_base: SSL_add_ssl_module()\n"); /* * We ignore an error return here. Not much we can do - but not that bad * either. We can still safely continue. @@ -124,11 +54,8 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings) * pulling in all the error strings during static linking */ #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ossl_init_load_ssl_strings: " - "ERR_load_SSL_strings()\n"); -# endif - ERR_load_SSL_strings(); + OSSL_TRACE(INIT, "ossl_init_load_ssl_strings: ossl_err_load_SSL_strings()\n"); + ossl_err_load_SSL_strings(); #endif return 1; } @@ -149,10 +76,8 @@ static void ssl_library_stop(void) if (ssl_base_inited) { #ifndef OPENSSL_NO_COMP -# ifdef OPENSSL_INIT_DEBUG - fprintf(stderr, "OPENSSL_INIT: ssl_library_stop: " - "ssl_comp_free_compression_methods_int()\n"); -# endif + OSSL_TRACE(INIT, "ssl_library_stop: " + "ssl_comp_free_compression_methods_int()\n"); ssl_comp_free_compression_methods_int(); #endif } @@ -175,7 +100,7 @@ int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings) * sets an error etc */ stoperrset = 1; - SSLerr(SSL_F_OPENSSL_INIT_SSL, ERR_R_INIT_FAIL); + ERR_raise(ERR_LIB_SSL, ERR_R_INIT_FAIL); } return 0; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 47adc3211c85..214884b0f1ef 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.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 @@ -11,65 +11,51 @@ #include <stdio.h> #include "ssl_local.h" +#include "e_os.h" #include <openssl/objects.h> #include <openssl/x509v3.h> #include <openssl/rand.h> -#include <openssl/rand_drbg.h> #include <openssl/ocsp.h> #include <openssl/dh.h> #include <openssl/engine.h> #include <openssl/async.h> #include <openssl/ct.h> +#include <openssl/trace.h> #include "internal/cryptlib.h" #include "internal/refcount.h" +#include "internal/ktls.h" -const char SSL_version_str[] = OPENSSL_VERSION_TEXT; - -static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t) +static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t, + SSL_MAC_BUF *mac, size_t macsize) { - (void)r; - (void)s; - (void)t; return ssl_undefined_function(ssl); } static int ssl_undefined_function_2(SSL *ssl, SSL3_RECORD *r, unsigned char *s, int t) { - (void)r; - (void)s; - (void)t; return ssl_undefined_function(ssl); } static int ssl_undefined_function_3(SSL *ssl, unsigned char *r, unsigned char *s, size_t t, size_t *u) { - (void)r; - (void)s; - (void)t; - (void)u; return ssl_undefined_function(ssl); } static int ssl_undefined_function_4(SSL *ssl, int r) { - (void)r; return ssl_undefined_function(ssl); } static size_t ssl_undefined_function_5(SSL *ssl, const char *r, size_t s, unsigned char *t) { - (void)r; - (void)s; - (void)t; return ssl_undefined_function(ssl); } static int ssl_undefined_function_6(int r) { - (void)r; return ssl_undefined_function(NULL); } @@ -77,13 +63,6 @@ static int ssl_undefined_function_7(SSL *ssl, unsigned char *r, size_t s, const char *t, size_t u, const unsigned char *v, size_t w, int x) { - (void)r; - (void)s; - (void)t; - (void)u; - (void)v; - (void)w; - (void)x; return ssl_undefined_function(ssl); } @@ -147,7 +126,7 @@ static int dane_ctx_enable(struct dane_ctx_st *dctx) if (mdord == NULL || mdevp == NULL) { OPENSSL_free(mdord); OPENSSL_free(mdevp); - SSLerr(SSL_F_DANE_CTX_ENABLE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -221,7 +200,7 @@ static int ssl_dane_dup(SSL *to, SSL *from) to->dane.trecs = sk_danetls_record_new_reserve(NULL, num); if (to->dane.trecs == NULL) { - SSLerr(SSL_F_SSL_DANE_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -241,7 +220,7 @@ static int dane_mtype_set(struct dane_ctx_st *dctx, int i; if (mtype == DANETLS_MATCHING_FULL && md != NULL) { - SSLerr(SSL_F_DANE_MTYPE_SET, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL); return 0; } @@ -252,14 +231,14 @@ static int dane_mtype_set(struct dane_ctx_st *dctx, mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp)); if (mdevp == NULL) { - SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } dctx->mdevp = mdevp; mdord = OPENSSL_realloc(dctx->mdord, n * sizeof(*mdord)); if (mdord == NULL) { - SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } dctx->mdord = mdord; @@ -290,7 +269,7 @@ static const EVP_MD *tlsa_md_get(SSL_DANE *dane, uint8_t mtype) static int dane_tlsa_add(SSL_DANE *dane, uint8_t usage, uint8_t selector, - uint8_t mtype, unsigned const char *data, size_t dlen) + uint8_t mtype, const unsigned char *data, size_t dlen) { danetls_record *t; const EVP_MD *md = NULL; @@ -299,44 +278,44 @@ static int dane_tlsa_add(SSL_DANE *dane, int num; if (dane->trecs == NULL) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_NOT_ENABLED); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED); return -1; } if (ilen < 0 || dlen != (size_t)ilen) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DATA_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DATA_LENGTH); return 0; } if (usage > DANETLS_USAGE_LAST) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE); return 0; } if (selector > DANETLS_SELECTOR_LAST) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_SELECTOR); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_SELECTOR); return 0; } if (mtype != DANETLS_MATCHING_FULL) { md = tlsa_md_get(dane, mtype); if (md == NULL) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE); return 0; } } - if (md != NULL && dlen != (size_t)EVP_MD_size(md)) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH); + if (md != NULL && dlen != (size_t)EVP_MD_get_size(md)) { + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH); return 0; } if (!data) { - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_NULL_DATA); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA); return 0; } if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) { - SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } @@ -346,7 +325,7 @@ static int dane_tlsa_add(SSL_DANE *dane, t->data = OPENSSL_malloc(dlen); if (t->data == NULL) { tlsa_free(t); - SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } memcpy(t->data, data, dlen); @@ -363,12 +342,12 @@ static int dane_tlsa_add(SSL_DANE *dane, if (!d2i_X509(&cert, &p, ilen) || p < data || dlen != (size_t)(p - data)) { tlsa_free(t); - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE); return 0; } if (X509_get0_pubkey(cert) == NULL) { tlsa_free(t); - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE); return 0; } @@ -387,7 +366,7 @@ static int dane_tlsa_add(SSL_DANE *dane, if ((dane->certs == NULL && (dane->certs = sk_X509_new_null()) == NULL) || !sk_X509_push(dane->certs, cert)) { - SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); X509_free(cert); tlsa_free(t); return -1; @@ -398,7 +377,7 @@ static int dane_tlsa_add(SSL_DANE *dane, if (!d2i_PUBKEY(&pkey, &p, ilen) || p < data || dlen != (size_t)(p - data)) { tlsa_free(t); - SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY); return 0; } @@ -448,7 +427,7 @@ static int dane_tlsa_add(SSL_DANE *dane, if (!sk_danetls_record_insert(dane->trecs, t, i)) { tlsa_free(t); - SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } dane->umask |= DANETLS_USAGE_BIT(usage); @@ -566,6 +545,19 @@ static int ssl_check_allowed_versions(int min_version, int max_version) return 1; } +#if defined(__TANDEM) && defined(OPENSSL_VPROC) +/* + * Define a VPROC function for HP NonStop build ssl library. + * This is used by platform version identification tools. + * Do not inline this procedure or make it static. + */ +# define OPENSSL_VPROC_STRING_(x) x##_SSL +# define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x) +# define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC) +void OPENSSL_VPROC_FUNC(void) {} +#endif + + static void clear_ciphers(SSL *s) { /* clear the current cipher */ @@ -577,7 +569,7 @@ static void clear_ciphers(SSL *s) int SSL_clear(SSL *s) { if (s->method == NULL) { - SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_METHOD_SPECIFIED); return 0; } @@ -598,7 +590,7 @@ int SSL_clear(SSL *s) s->shutdown = 0; if (s->renegotiate) { - SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } @@ -652,6 +644,7 @@ int SSL_clear(SSL *s) return 1; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 /** Used to change an SSL_CTXs default SSL method type */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) { @@ -659,32 +652,33 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) ctx->method = meth; - if (!SSL_CTX_set_ciphersuites(ctx, TLS_DEFAULT_CIPHERSUITES)) { - SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + if (!SSL_CTX_set_ciphersuites(ctx, OSSL_default_ciphersuites())) { + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); return 0; } - sk = ssl_create_cipher_list(ctx->method, + sk = ssl_create_cipher_list(ctx, ctx->tls13_ciphersuites, &(ctx->cipher_list), &(ctx->cipher_list_by_id), - SSL_DEFAULT_CIPHER_LIST, ctx->cert); + OSSL_default_cipher_list(), ctx->cert); if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { - SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); return 0; } return 1; } +#endif SSL *SSL_new(SSL_CTX *ctx) { SSL *s; if (ctx == NULL) { - SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX); + ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_CTX); return NULL; } if (ctx->method == NULL) { - SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); return NULL; } @@ -774,7 +768,6 @@ SSL *SSL_new(SSL_CTX *ctx) s->ext.ocsp.resp_len = 0; SSL_CTX_up_ref(ctx); s->session_ctx = ctx; -#ifndef OPENSSL_NO_EC if (ctx->ext.ecpointformats) { s->ext.ecpointformats = OPENSSL_memdup(ctx->ext.ecpointformats, @@ -797,7 +790,7 @@ SSL *SSL_new(SSL_CTX *ctx) } s->ext.supportedgroups_len = ctx->ext.supportedgroups_len; } -#endif + #ifndef OPENSSL_NO_NEXTPROTONEG s->ext.npn = NULL; #endif @@ -843,6 +836,9 @@ SSL *SSL_new(SSL_CTX *ctx) s->psk_find_session_cb = ctx->psk_find_session_cb; s->psk_use_session_cb = ctx->psk_use_session_cb; + s->async_cb = ctx->async_cb; + s->async_cb_arg = ctx->async_cb_arg; + s->job = NULL; #ifndef OPENSSL_NO_CT @@ -854,7 +850,7 @@ SSL *SSL_new(SSL_CTX *ctx) return s; err: SSL_free(s); - SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } @@ -879,8 +875,7 @@ int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, unsigned int sid_ctx_len) { if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); return 0; } ctx->sid_ctx_length = sid_ctx_len; @@ -893,8 +888,7 @@ int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, unsigned int sid_ctx_len) { if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); return 0; } ssl->sid_ctx_length = sid_ctx_len; @@ -905,7 +899,8 @@ int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) { - CRYPTO_THREAD_write_lock(ctx->lock); + if (!CRYPTO_THREAD_write_lock(ctx->lock)) + return 0; ctx->generate_session_id = cb; CRYPTO_THREAD_unlock(ctx->lock); return 1; @@ -913,7 +908,8 @@ int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) { - CRYPTO_THREAD_write_lock(ssl->lock); + if (!CRYPTO_THREAD_write_lock(ssl->lock)) + return 0; ssl->generate_session_id = cb; CRYPTO_THREAD_unlock(ssl->lock); return 1; @@ -938,7 +934,8 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, r.session_id_length = id_len; memcpy(r.session_id, id, id_len); - CRYPTO_THREAD_read_lock(ssl->session_ctx->lock); + if (!CRYPTO_THREAD_read_lock(ssl->session_ctx->lock)) + return 0; p = lh_SSL_SESSION_retrieve(ssl->session_ctx->sessions, &r); CRYPTO_THREAD_unlock(ssl->session_ctx->lock); return (p != NULL); @@ -966,11 +963,40 @@ int SSL_set_trust(SSL *s, int trust) int SSL_set1_host(SSL *s, const char *hostname) { + /* If a hostname is provided and parses as an IP address, + * treat it as such. */ + if (hostname && X509_VERIFY_PARAM_set1_ip_asc(s->param, hostname) == 1) + return 1; + return X509_VERIFY_PARAM_set1_host(s->param, hostname, 0); } int SSL_add1_host(SSL *s, const char *hostname) { + /* If a hostname is provided and parses as an IP address, + * treat it as such. */ + if (hostname) + { + ASN1_OCTET_STRING *ip; + char *old_ip; + + ip = a2i_IPADDRESS(hostname); + if (ip) { + /* We didn't want it; only to check if it *is* an IP address */ + ASN1_OCTET_STRING_free(ip); + + old_ip = X509_VERIFY_PARAM_get1_ip_asc(s->param); + if (old_ip) + { + OPENSSL_free(old_ip); + /* There can be only one IP address */ + return 0; + } + + return X509_VERIFY_PARAM_set1_ip_asc(s->param, hostname); + } + } + return X509_VERIFY_PARAM_add1_host(s->param, hostname, 0); } @@ -1010,11 +1036,11 @@ int SSL_dane_enable(SSL *s, const char *basedomain) SSL_DANE *dane = &s->dane; if (s->ctx->dane.mdmax == 0) { - SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_CONTEXT_NOT_DANE_ENABLED); + ERR_raise(ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED); return 0; } if (dane->trecs != NULL) { - SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_DANE_ALREADY_ENABLED); + ERR_raise(ERR_LIB_SSL, SSL_R_DANE_ALREADY_ENABLED); return 0; } @@ -1025,14 +1051,14 @@ int SSL_dane_enable(SSL *s, const char *basedomain) */ if (s->ext.hostname == NULL) { if (!SSL_set_tlsext_host_name(s, basedomain)) { - SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN); + ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN); return -1; } } /* Primary RFC6125 reference identifier */ if (!X509_VERIFY_PARAM_set1_host(s->param, basedomain, 0)) { - SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN); + ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN); return -1; } @@ -1042,7 +1068,7 @@ int SSL_dane_enable(SSL *s, const char *basedomain) dane->trecs = sk_danetls_record_new_null(); if (dane->trecs == NULL) { - SSLerr(SSL_F_SSL_DANE_ENABLE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return -1; } return 1; @@ -1080,7 +1106,7 @@ int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki) } int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, - uint8_t *mtype, unsigned const char **data, size_t *dlen) + uint8_t *mtype, const unsigned char **data, size_t *dlen) { SSL_DANE *dane = &s->dane; @@ -1107,7 +1133,7 @@ SSL_DANE *SSL_get0_dane(SSL *s) } int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector, - uint8_t mtype, unsigned const char *data, size_t dlen) + uint8_t mtype, const unsigned char *data, size_t dlen) { return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen); } @@ -1159,11 +1185,15 @@ void SSL_free(SSL *s) dane_final(&s->dane); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + RECORD_LAYER_release(&s->rlayer); + /* Ignore return value */ ssl_free_wbio_buffer(s); BIO_free_all(s->wbio); + s->wbio = NULL; BIO_free_all(s->rbio); + s->rbio = NULL; BUF_MEM_free(s->init_buf); @@ -1189,12 +1219,10 @@ void SSL_free(SSL *s) OPENSSL_free(s->ext.hostname); SSL_CTX_free(s->session_ctx); -#ifndef OPENSSL_NO_EC OPENSSL_free(s->ext.ecpointformats); OPENSSL_free(s->ext.peer_ecpointformats); OPENSSL_free(s->ext.supportedgroups); OPENSSL_free(s->ext.peer_supportedgroups); -#endif /* OPENSSL_NO_EC */ sk_X509_EXTENSION_pop_free(s->ext.ocsp.exts, X509_EXTENSION_free); #ifndef OPENSSL_NO_OCSP sk_OCSP_RESPID_pop_free(s->ext.ocsp.ids, OCSP_RESPID_free); @@ -1220,8 +1248,6 @@ void SSL_free(SSL *s) if (s->method != NULL) s->method->ssl_free(s); - RECORD_LAYER_release(&s->rlayer); - SSL_CTX_free(s->ctx); ASYNC_WAIT_CTX_free(s->waitctx); @@ -1356,11 +1382,20 @@ int SSL_set_fd(SSL *s, int fd) bio = BIO_new(BIO_s_socket()); if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto err; } BIO_set_fd(bio, fd, BIO_NOCLOSE); SSL_set_bio(s, bio, bio); +#ifndef OPENSSL_NO_KTLS + /* + * The new socket is created successfully regardless of ktls_enable. + * ktls_enable doesn't change any functionality of the socket, except + * changing the setsockopt to enable the processing of ktls_start. + * Thus, it is not a problem to call it for non-TLS sockets. + */ + ktls_enable(fd); +#endif /* OPENSSL_NO_KTLS */ ret = 1; err: return ret; @@ -1375,11 +1410,20 @@ int SSL_set_wfd(SSL *s, int fd) BIO *bio = BIO_new(BIO_s_socket()); if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); return 0; } BIO_set_fd(bio, fd, BIO_NOCLOSE); SSL_set0_wbio(s, bio); +#ifndef OPENSSL_NO_KTLS + /* + * The new socket is created successfully regardless of ktls_enable. + * ktls_enable doesn't change any functionality of the socket, except + * changing the setsockopt to enable the processing of ktls_start. + * Thus, it is not a problem to call it for non-TLS sockets. + */ + ktls_enable(fd); +#endif /* OPENSSL_NO_KTLS */ } else { BIO_up_ref(rbio); SSL_set0_wbio(s, rbio); @@ -1396,7 +1440,7 @@ int SSL_set_rfd(SSL *s, int fd) BIO *bio = BIO_new(BIO_s_socket()); if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); return 0; } BIO_set_fd(bio, fd, BIO_NOCLOSE); @@ -1415,12 +1459,10 @@ size_t SSL_get_finished(const SSL *s, void *buf, size_t count) { size_t ret = 0; - if (s->s3 != NULL) { - ret = s->s3->tmp.finish_md_len; - if (count > ret) - count = ret; - memcpy(buf, s->s3->tmp.finish_md, count); - } + ret = s->s3.tmp.finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3.tmp.finish_md, count); return ret; } @@ -1429,12 +1471,10 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) { size_t ret = 0; - if (s->s3 != NULL) { - ret = s->s3->tmp.peer_finish_md_len; - if (count > ret) - count = ret; - memcpy(buf, s->s3->tmp.peer_finish_md, count); - } + ret = s->s3.tmp.peer_finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3.tmp.peer_finish_md, count); return ret; } @@ -1536,23 +1576,24 @@ int SSL_has_pending(const SSL *s) return RECORD_LAYER_read_pending(&s->rlayer); } -X509 *SSL_get_peer_certificate(const SSL *s) +X509 *SSL_get1_peer_certificate(const SSL *s) { - X509 *r; - - if ((s == NULL) || (s->session == NULL)) - r = NULL; - else - r = s->session->peer; - - if (r == NULL) - return r; + X509 *r = SSL_get0_peer_certificate(s); - X509_up_ref(r); + if (r != NULL) + X509_up_ref(r); return r; } +X509 *SSL_get0_peer_certificate(const SSL *s) +{ + if ((s == NULL) || (s->session == NULL)) + return NULL; + else + return s->session->peer; +} + STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) { STACK_OF(X509) *r; @@ -1577,7 +1618,7 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) int SSL_copy_session_id(SSL *t, const SSL *f) { int i; - /* Do we need to to SSL locking? */ + /* Do we need to do SSL locking? */ if (!SSL_set_session(t, SSL_get_session(f))) { return 0; } @@ -1606,11 +1647,11 @@ int SSL_copy_session_id(SSL *t, const SSL *f) int SSL_CTX_check_private_key(const SSL_CTX *ctx) { if ((ctx == NULL) || (ctx->cert->key->x509 == NULL)) { - SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED); return 0; } if (ctx->cert->key->privatekey == NULL) { - SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED); return 0; } return X509_check_private_key @@ -1621,15 +1662,15 @@ int SSL_CTX_check_private_key(const SSL_CTX *ctx) int SSL_check_private_key(const SSL *ssl) { if (ssl == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ssl->cert->key->x509 == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED); return 0; } if (ssl->cert->key->privatekey == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED); return 0; } return X509_check_private_key(ssl->cert->key->x509, @@ -1664,6 +1705,40 @@ int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, size_t *numaddfds, numdelfds); } +int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback) +{ + ctx->async_cb = callback; + return 1; +} + +int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg) +{ + ctx->async_cb_arg = arg; + return 1; +} + +int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback) +{ + s->async_cb = callback; + return 1; +} + +int SSL_set_async_callback_arg(SSL *s, void *arg) +{ + s->async_cb_arg = arg; + return 1; +} + +int SSL_get_async_status(SSL *s, int *status) +{ + ASYNC_WAIT_CTX *ctx = s->waitctx; + + if (ctx == NULL) + return 0; + *status = ASYNC_WAIT_CTX_get_status(ctx); + return 1; +} + int SSL_accept(SSL *s) { if (s->handshake_func == NULL) { @@ -1689,6 +1764,13 @@ long SSL_get_default_timeout(const SSL *s) return s->method->get_timeout(); } +static int ssl_async_wait_ctx_cb(void *arg) +{ + SSL *s = (SSL *)arg; + + return s->async_cb(s, s->async_cb_arg); +} + static int ssl_start_async_job(SSL *s, struct ssl_async_args *args, int (*func) (void *)) { @@ -1697,6 +1779,10 @@ static int ssl_start_async_job(SSL *s, struct ssl_async_args *args, s->waitctx = ASYNC_WAIT_CTX_new(); if (s->waitctx == NULL) return -1; + if (s->async_cb != NULL + && !ASYNC_WAIT_CTX_set_callback + (s->waitctx, ssl_async_wait_ctx_cb, s)) + return -1; } s->rwstate = SSL_NOTHING; @@ -1704,7 +1790,7 @@ static int ssl_start_async_job(SSL *s, struct ssl_async_args *args, sizeof(struct ssl_async_args))) { case ASYNC_ERR: s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_START_ASYNC_JOB, SSL_R_FAILED_TO_INIT_ASYNC); + ERR_raise(ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC); return -1; case ASYNC_PAUSE: s->rwstate = SSL_ASYNC_PAUSED; @@ -1717,7 +1803,7 @@ static int ssl_start_async_job(SSL *s, struct ssl_async_args *args, return ret; default: s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_START_ASYNC_JOB, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); /* Shouldn't happen */ return -1; } @@ -1748,7 +1834,7 @@ static int ssl_io_intern(void *vargs) int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_READ_INTERNAL, SSL_R_UNINITIALIZED); + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } @@ -1759,7 +1845,7 @@ int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) { - SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } /* @@ -1792,7 +1878,7 @@ int SSL_read(SSL *s, void *buf, int num) size_t readbytes; if (num < 0) { - SSLerr(SSL_F_SSL_READ, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); return -1; } @@ -1822,15 +1908,14 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) int ret; if (!s->server) { - SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return SSL_READ_EARLY_DATA_ERROR; } switch (s->early_data_state) { case SSL_EARLY_DATA_NONE: if (!SSL_in_before(s)) { - SSLerr(SSL_F_SSL_READ_EARLY_DATA, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return SSL_READ_EARLY_DATA_ERROR; } /* fall through */ @@ -1867,7 +1952,7 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) return SSL_READ_EARLY_DATA_FINISH; default: - SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return SSL_READ_EARLY_DATA_ERROR; } } @@ -1880,7 +1965,7 @@ int SSL_get_early_data_status(const SSL *s) static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_PEEK_INTERNAL, SSL_R_UNINITIALIZED); + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } @@ -1911,7 +1996,7 @@ int SSL_peek(SSL *s, void *buf, int num) size_t readbytes; if (num < 0) { - SSLerr(SSL_F_SSL_PEEK, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); return -1; } @@ -1940,20 +2025,20 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes) int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) { if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_WRITE_INTERNAL, SSL_R_UNINITIALIZED); + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } if (s->shutdown & SSL_SENT_SHUTDOWN) { s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_WRITE_INTERNAL, SSL_R_PROTOCOL_IS_SHUTDOWN); + ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); return -1; } if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY || s->early_data_state == SSL_EARLY_DATA_READ_RETRY) { - SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } /* If we are a client and haven't sent the Finished we better do that */ @@ -1977,13 +2062,77 @@ int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) } } +ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) +{ + ossl_ssize_t ret; + + if (s->handshake_func == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + ERR_raise(ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (!BIO_get_ktls_send(s->wbio)) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); + return -1; + } + + /* If we have an alert to send, lets send it */ + if (s->s3.alert_dispatch) { + ret = (ossl_ssize_t)s->method->ssl_dispatch_alert(s); + if (ret <= 0) { + /* SSLfatal() already called if appropriate */ + return ret; + } + /* if it went, fall through and send more stuff */ + } + + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + } else { +#ifdef EAGAIN + set_sys_error(EAGAIN); +#endif + } + return -1; + } + +#ifdef OPENSSL_NO_KTLS + ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR, + "can't call ktls_sendfile(), ktls disabled"); + return -1; +#else + ret = ktls_sendfile(SSL_get_wfd(s), fd, offset, size, flags); + if (ret < 0) { +#if defined(EAGAIN) && defined(EINTR) && defined(EBUSY) + if ((get_last_sys_error() == EAGAIN) || + (get_last_sys_error() == EINTR) || + (get_last_sys_error() == EBUSY)) + BIO_set_retry_write(s->wbio); + else +#endif + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); + return ret; + } + s->rwstate = SSL_NOTHING; + return ret; +#endif +} + int SSL_write(SSL *s, const void *buf, int num) { int ret; size_t written; if (num < 0) { - SSLerr(SSL_F_SSL_WRITE, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); return -1; } @@ -2020,8 +2169,7 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) || !SSL_in_before(s) || ((s->session == NULL || s->session->ext.max_early_data == 0) && (s->psk_use_session_cb == NULL))) { - SSLerr(SSL_F_SSL_WRITE_EARLY_DATA, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } /* fall through */ @@ -2075,7 +2223,7 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) return ret; default: - SSLerr(SSL_F_SSL_WRITE_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } } @@ -2090,7 +2238,7 @@ int SSL_shutdown(SSL *s) */ if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED); + ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED); return -1; } @@ -2108,36 +2256,31 @@ int SSL_shutdown(SSL *s) return s->method->ssl_shutdown(s); } } else { - SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_SHUTDOWN_WHILE_IN_INIT); + ERR_raise(ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT); return -1; } } int SSL_key_update(SSL *s, int updatetype) { - /* - * TODO(TLS1.3): How will applications know whether TLSv1.3 has been - * negotiated, and that it is appropriate to call SSL_key_update() instead - * of SSL_renegotiate(). - */ if (!SSL_IS_TLS13(s)) { - SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_WRONG_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED && updatetype != SSL_KEY_UPDATE_REQUESTED) { - SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_INVALID_KEY_UPDATE_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE); return 0; } if (!SSL_is_init_finished(s)) { - SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_STILL_IN_INIT); + ERR_raise(ERR_LIB_SSL, SSL_R_STILL_IN_INIT); return 0; } if (RECORD_LAYER_write_pending(&s->rlayer)) { - SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_BAD_WRITE_RETRY); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY); return 0; } @@ -2151,39 +2294,42 @@ int SSL_get_key_update_type(const SSL *s) return s->key_update; } -int SSL_renegotiate(SSL *s) +/* + * Can we accept a renegotiation request? If yes, set the flag and + * return 1 if yes. If not, raise error and return 0. + */ +static int can_renegotiate(const SSL *s) { if (SSL_IS_TLS13(s)) { - SSLerr(SSL_F_SSL_RENEGOTIATE, SSL_R_WRONG_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } - if ((s->options & SSL_OP_NO_RENEGOTIATION)) { - SSLerr(SSL_F_SSL_RENEGOTIATE, SSL_R_NO_RENEGOTIATION); + if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) { + ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION); return 0; } + return 1; +} + +int SSL_renegotiate(SSL *s) +{ + if (!can_renegotiate(s)) + return 0; + s->renegotiate = 1; s->new_session = 1; - return s->method->ssl_renegotiate(s); } int SSL_renegotiate_abbreviated(SSL *s) { - if (SSL_IS_TLS13(s)) { - SSLerr(SSL_F_SSL_RENEGOTIATE_ABBREVIATED, SSL_R_WRONG_SSL_VERSION); + if (!can_renegotiate(s)) return 0; - } - - if ((s->options & SSL_OP_NO_RENEGOTIATION)) { - SSLerr(SSL_F_SSL_RENEGOTIATE_ABBREVIATED, SSL_R_NO_RENEGOTIATION); - return 0; - } s->renegotiate = 1; s->new_session = 0; - return s->method->ssl_renegotiate(s); } @@ -2196,6 +2342,19 @@ int SSL_renegotiate_pending(const SSL *s) return (s->renegotiate != 0); } +int SSL_new_session_ticket(SSL *s) +{ + /* If we are in init because we're sending tickets, okay to send more. */ + if ((SSL_in_init(s) && s->ext.extra_tickets_expected == 0) + || SSL_IS_FIRST_HANDSHAKE(s) || !s->server + || !SSL_IS_TLS13(s)) + return 0; + s->ext.extra_tickets_expected++; + if (!RECORD_LAYER_write_pending(&s->rlayer) && !SSL_in_init(s)) + ossl_statem_set_in_init(s, 1); + return 1; +} + long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) { long l; @@ -2227,6 +2386,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_SET_MAX_SEND_FRAGMENT: if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) return 0; +#ifndef OPENSSL_NO_KTLS + if (s->wbio != NULL && BIO_get_ktls_send(s->wbio)) + return 0; +#endif /* OPENSSL_NO_KTLS */ s->max_send_fragment = larg; if (s->max_send_fragment < s->split_send_fragment) s->split_send_fragment = s->max_send_fragment; @@ -2244,10 +2407,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) RECORD_LAYER_set_read_ahead(&s->rlayer, 1); return 1; case SSL_CTRL_GET_RI_SUPPORT: - if (s->s3) - return s->s3->send_connection_binding; - else - return 0; + return s->s3.send_connection_binding; + case SSL_CTRL_SET_RETRY_VERIFY: + s->rwstate = SSL_RETRY_VERIFY; + return 1; case SSL_CTRL_CERT_FLAGS: return (s->cert->cert_flags |= larg); case SSL_CTRL_CLEAR_CERT_FLAGS: @@ -2255,10 +2418,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_RAW_CIPHERLIST: if (parg) { - if (s->s3->tmp.ciphers_raw == NULL) + if (s->s3.tmp.ciphers_raw == NULL) return 0; - *(unsigned char **)parg = s->s3->tmp.ciphers_raw; - return (int)s->s3->tmp.ciphers_rawlen; + *(unsigned char **)parg = s->s3.tmp.ciphers_raw; + return (int)s->s3.tmp.ciphers_rawlen; } else { return TLS_CIPHER_LEN; } @@ -2306,16 +2469,25 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) return ctx->sessions; } +static int ssl_tsan_load(SSL_CTX *ctx, TSAN_QUALIFIER int *stat) +{ + int res = 0; + + if (ssl_tsan_lock(ctx)) { + res = tsan_load(stat); + ssl_tsan_unlock(ctx); + } + return res; +} + long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) { long l; /* For some cases with ctx == NULL perform syntax checks */ if (ctx == NULL) { switch (cmd) { -#ifndef OPENSSL_NO_EC case SSL_CTRL_SET_GROUPS_LIST: - return tls1_set_groups_list(NULL, NULL, parg); -#endif + return tls1_set_groups_list(ctx, NULL, NULL, parg); case SSL_CTRL_SET_SIGALGS_LIST: case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: return tls1_set_sigalgs_list(NULL, parg, 0); @@ -2363,27 +2535,27 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) case SSL_CTRL_SESS_NUMBER: return lh_SSL_SESSION_num_items(ctx->sessions); case SSL_CTRL_SESS_CONNECT: - return tsan_load(&ctx->stats.sess_connect); + return ssl_tsan_load(ctx, &ctx->stats.sess_connect); case SSL_CTRL_SESS_CONNECT_GOOD: - return tsan_load(&ctx->stats.sess_connect_good); + return ssl_tsan_load(ctx, &ctx->stats.sess_connect_good); case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: - return tsan_load(&ctx->stats.sess_connect_renegotiate); + return ssl_tsan_load(ctx, &ctx->stats.sess_connect_renegotiate); case SSL_CTRL_SESS_ACCEPT: - return tsan_load(&ctx->stats.sess_accept); + return ssl_tsan_load(ctx, &ctx->stats.sess_accept); case SSL_CTRL_SESS_ACCEPT_GOOD: - return tsan_load(&ctx->stats.sess_accept_good); + return ssl_tsan_load(ctx, &ctx->stats.sess_accept_good); case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: - return tsan_load(&ctx->stats.sess_accept_renegotiate); + return ssl_tsan_load(ctx, &ctx->stats.sess_accept_renegotiate); case SSL_CTRL_SESS_HIT: - return tsan_load(&ctx->stats.sess_hit); + return ssl_tsan_load(ctx, &ctx->stats.sess_hit); case SSL_CTRL_SESS_CB_HIT: - return tsan_load(&ctx->stats.sess_cb_hit); + return ssl_tsan_load(ctx, &ctx->stats.sess_cb_hit); case SSL_CTRL_SESS_MISSES: - return tsan_load(&ctx->stats.sess_miss); + return ssl_tsan_load(ctx, &ctx->stats.sess_miss); case SSL_CTRL_SESS_TIMEOUTS: - return tsan_load(&ctx->stats.sess_timeout); + return ssl_tsan_load(ctx, &ctx->stats.sess_timeout); case SSL_CTRL_SESS_CACHE_FULL: - return tsan_load(&ctx->stats.sess_cache_full); + return ssl_tsan_load(ctx, &ctx->stats.sess_cache_full); case SSL_CTRL_MODE: return (ctx->mode |= larg); case SSL_CTRL_CLEAR_MODE: @@ -2572,7 +2744,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { STACK_OF(SSL_CIPHER) *sk; - sk = ssl_create_cipher_list(ctx->method, ctx->tls13_ciphersuites, + sk = ssl_create_cipher_list(ctx, ctx->tls13_ciphersuites, &ctx->cipher_list, &ctx->cipher_list_by_id, str, ctx->cert); /* @@ -2585,7 +2757,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) if (sk == NULL) return 0; else if (cipher_list_tls12_num(sk) == 0) { - SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); return 0; } return 1; @@ -2596,14 +2768,14 @@ int SSL_set_cipher_list(SSL *s, const char *str) { STACK_OF(SSL_CIPHER) *sk; - sk = ssl_create_cipher_list(s->ctx->method, s->tls13_ciphersuites, + sk = ssl_create_cipher_list(s->ctx, s->tls13_ciphersuites, &s->cipher_list, &s->cipher_list_by_id, str, s->cert); /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; else if (cipher_list_tls12_num(sk) == 0) { - SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); return 0; } return 1; @@ -2807,7 +2979,7 @@ void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, unsigned *len) { *data = s->ext.npn; - if (!*data) { + if (*data == NULL) { *len = 0; } else { *len = (unsigned int)s->ext.npn_len; @@ -2886,7 +3058,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, alpn = OPENSSL_memdup(protos, protos_len); if (alpn == NULL) { - SSLerr(SSL_F_SSL_CTX_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 1; } OPENSSL_free(ctx->ext.alpn); @@ -2918,7 +3090,7 @@ int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, alpn = OPENSSL_memdup(protos, protos_len); if (alpn == NULL) { - SSLerr(SSL_F_SSL_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 1; } OPENSSL_free(ssl->ext.alpn); @@ -2950,13 +3122,11 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, unsigned int *len) { - *data = NULL; - if (ssl->s3) - *data = ssl->s3->alpn_selected; + *data = ssl->s3.alpn_selected; if (*data == NULL) *len = 0; else - *len = (unsigned int)ssl->s3->alpn_selected_len; + *len = (unsigned int)ssl->s3.alpn_selected_len; } int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, @@ -3028,12 +3198,13 @@ static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) * via ssl.h. */ -SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) +SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const SSL_METHOD *meth) { SSL_CTX *ret = NULL; if (meth == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED); + ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED); return NULL; } @@ -3041,13 +3212,37 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) return NULL; if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); + ERR_raise(ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); goto err; } ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) goto err; + /* Init the reference counting before any call to SSL_CTX_free */ + ret->references = 1; + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } + +#ifdef TSAN_REQUIRES_LOCKING + ret->tsan_lock = CRYPTO_THREAD_lock_new(); + if (ret->tsan_lock == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } +#endif + + ret->libctx = libctx; + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); + if (ret->propq == NULL) + goto err; + } + ret->method = meth; ret->min_proto_version = 0; ret->max_proto_version = 0; @@ -3056,13 +3251,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; /* We take the system default. */ ret->session_timeout = meth->get_timeout(); - ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; - } ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; ret->verify_mode = SSL_VERIFY_NONE; if ((ret->cert = ssl_cert_new()) == NULL) @@ -3075,20 +3263,31 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (ret->cert_store == NULL) goto err; #ifndef OPENSSL_NO_CT - ret->ctlog_store = CTLOG_STORE_new(); + ret->ctlog_store = CTLOG_STORE_new_ex(libctx, propq); if (ret->ctlog_store == NULL) goto err; #endif - if (!SSL_CTX_set_ciphersuites(ret, TLS_DEFAULT_CIPHERSUITES)) + /* initialize cipher/digest methods table */ + if (!ssl_load_ciphers(ret)) + goto err2; + /* initialise sig algs */ + if (!ssl_setup_sig_algs(ret)) + goto err2; + + + if (!ssl_load_groups(ret)) + goto err2; + + if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites())) goto err; - if (!ssl_create_cipher_list(ret->method, + if (!ssl_create_cipher_list(ret, ret->tls13_ciphersuites, &ret->cipher_list, &ret->cipher_list_by_id, - SSL_DEFAULT_CIPHER_LIST, ret->cert) + OSSL_default_cipher_list(), ret->cert) || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); + ERR_raise(ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS); goto err2; } @@ -3096,14 +3295,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (ret->param == NULL) goto err; - if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); - goto err2; - } - if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); - goto err2; - } + /* + * If these aren't available from the provider we'll get NULL returns. + * That's fine but will cause errors later if SSLv3 is negotiated + */ + ret->md5 = ssl_evp_md_fetch(libctx, NID_md5, propq); + ret->sha1 = ssl_evp_md_fetch(libctx, NID_sha1, propq); if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL) goto err; @@ -3125,20 +3322,20 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; /* Setup RFC5077 ticket keys */ - if ((RAND_bytes(ret->ext.tick_key_name, - sizeof(ret->ext.tick_key_name)) <= 0) - || (RAND_priv_bytes(ret->ext.secure->tick_hmac_key, - sizeof(ret->ext.secure->tick_hmac_key)) <= 0) - || (RAND_priv_bytes(ret->ext.secure->tick_aes_key, - sizeof(ret->ext.secure->tick_aes_key)) <= 0)) + if ((RAND_bytes_ex(libctx, ret->ext.tick_key_name, + sizeof(ret->ext.tick_key_name), 0) <= 0) + || (RAND_priv_bytes_ex(libctx, ret->ext.secure->tick_hmac_key, + sizeof(ret->ext.secure->tick_hmac_key), 0) <= 0) + || (RAND_priv_bytes_ex(libctx, ret->ext.secure->tick_aes_key, + sizeof(ret->ext.secure->tick_aes_key), 0) <= 0)) ret->options |= SSL_OP_NO_TICKET; - if (RAND_priv_bytes(ret->ext.cookie_hmac_key, - sizeof(ret->ext.cookie_hmac_key)) <= 0) + if (RAND_priv_bytes_ex(libctx, ret->ext.cookie_hmac_key, + sizeof(ret->ext.cookie_hmac_key), 0) <= 0) goto err; #ifndef OPENSSL_NO_SRP - if (!SSL_CTX_SRP_CTX_init(ret)) + if (!ssl_ctx_srp_ctx_init_intern(ret)) goto err; #endif #ifndef OPENSSL_NO_ENGINE @@ -3160,11 +3357,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) # endif #endif /* - * Default is to connect to non-RI servers. When RI is more widely - * deployed might change this. - */ - ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; - /* * Disable compression by default to prevent CRIME. Applications can * re-enable compression by configuring * SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION); @@ -3211,12 +3403,17 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) return ret; err: - SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); err2: SSL_CTX_free(ret); return NULL; } +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) +{ + return SSL_CTX_new_ex(NULL, NULL, meth); +} + int SSL_CTX_up_ref(SSL_CTX *ctx) { int i; @@ -3232,6 +3429,7 @@ int SSL_CTX_up_ref(SSL_CTX *ctx) void SSL_CTX_free(SSL_CTX *a) { int i; + size_t j; if (a == NULL) return; @@ -3275,20 +3473,40 @@ void SSL_CTX_free(SSL_CTX *a) sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); #endif #ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_free(a); + ssl_ctx_srp_ctx_free_intern(a); #endif #ifndef OPENSSL_NO_ENGINE - ENGINE_finish(a->client_cert_engine); + tls_engine_finish(a->client_cert_engine); #endif -#ifndef OPENSSL_NO_EC OPENSSL_free(a->ext.ecpointformats); OPENSSL_free(a->ext.supportedgroups); -#endif + OPENSSL_free(a->ext.supported_groups_default); OPENSSL_free(a->ext.alpn); OPENSSL_secure_free(a->ext.secure); + ssl_evp_md_free(a->md5); + ssl_evp_md_free(a->sha1); + + for (j = 0; j < SSL_ENC_NUM_IDX; j++) + ssl_evp_cipher_free(a->ssl_cipher_methods[j]); + for (j = 0; j < SSL_MD_NUM_IDX; j++) + ssl_evp_md_free(a->ssl_digest_methods[j]); + for (j = 0; j < a->group_list_len; j++) { + OPENSSL_free(a->group_list[j].tlsname); + OPENSSL_free(a->group_list[j].realname); + OPENSSL_free(a->group_list[j].algorithm); + } + OPENSSL_free(a->group_list); + + OPENSSL_free(a->sigalg_lookup_cache); + CRYPTO_THREAD_lock_free(a->lock); +#ifdef TSAN_REQUIRES_LOCKING + CRYPTO_THREAD_lock_free(a->tsan_lock); +#endif + + OPENSSL_free(a->propq); OPENSSL_free(a); } @@ -3366,42 +3584,35 @@ void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) void ssl_set_masks(SSL *s) { CERT *c = s->cert; - uint32_t *pvalid = s->s3->tmp.valid_flags; + uint32_t *pvalid = s->s3.tmp.valid_flags; int rsa_enc, rsa_sign, dh_tmp, dsa_sign; unsigned long mask_k, mask_a; -#ifndef OPENSSL_NO_EC int have_ecc_cert, ecdsa_ok; -#endif + if (c == NULL) return; -#ifndef OPENSSL_NO_DH - dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL || c->dh_tmp_auto); -#else - dh_tmp = 0; -#endif + dh_tmp = (c->dh_tmp != NULL + || c->dh_tmp_cb != NULL + || c->dh_tmp_auto); rsa_enc = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID; rsa_sign = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID; dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_VALID; -#ifndef OPENSSL_NO_EC have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID; -#endif mask_k = 0; mask_a = 0; -#ifdef CIPHER_DEBUG - fprintf(stderr, "dht=%d re=%d rs=%d ds=%d\n", - dh_tmp, rsa_enc, rsa_sign, dsa_sign); -#endif + OSSL_TRACE4(TLS_CIPHER, "dh_tmp=%d rsa_enc=%d rsa_sign=%d dsa_sign=%d\n", + dh_tmp, rsa_enc, rsa_sign, dsa_sign); #ifndef OPENSSL_NO_GOST if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) { - mask_k |= SSL_kGOST; + mask_k |= SSL_kGOST | SSL_kGOST18; mask_a |= SSL_aGOST12; } if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) { - mask_k |= SSL_kGOST; + mask_k |= SSL_kGOST | SSL_kGOST18; mask_a |= SSL_aGOST12; } if (ssl_has_cert(s, SSL_PKEY_GOST01)) { @@ -3436,7 +3647,6 @@ void ssl_set_masks(SSL *s) * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites * depending on the key usage extension. */ -#ifndef OPENSSL_NO_EC if (have_ecc_cert) { uint32_t ex_kusage; ex_kusage = X509_get_key_usage(c->pkeys[SSL_PKEY_ECC].x509); @@ -3457,11 +3667,8 @@ void ssl_set_masks(SSL *s) && pvalid[SSL_PKEY_ED448] & CERT_PKEY_EXPLICIT_SIGN && TLS1_get_version(s) == TLS1_2_VERSION) mask_a |= SSL_aECDSA; -#endif -#ifndef OPENSSL_NO_EC mask_k |= SSL_kECDHE; -#endif #ifndef OPENSSL_NO_PSK mask_k |= SSL_kPSK; @@ -3474,31 +3681,26 @@ void ssl_set_masks(SSL *s) mask_k |= SSL_kECDHEPSK; #endif - s->s3->tmp.mask_k = mask_k; - s->s3->tmp.mask_a = mask_a; + s->s3.tmp.mask_k = mask_k; + s->s3.tmp.mask_a = mask_a; } -#ifndef OPENSSL_NO_EC - int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) { - if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aECDSA) { + if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aECDSA) { /* key usage, if present, must allow signing */ if (!(X509_get_key_usage(x) & X509v3_KU_DIGITAL_SIGNATURE)) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_NOT_FOR_SIGNING); + ERR_raise(ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; } } return 1; /* all checks are ok */ } -#endif - int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, size_t *serverinfo_length) { - CERT_PKEY *cpk = s->s3->tmp.cert; + CERT_PKEY *cpk = s->s3.tmp.cert; *serverinfo_length = 0; if (cpk == NULL || cpk->serverinfo == NULL) @@ -3571,11 +3773,12 @@ void ssl_update_cache(SSL *s, int mode) /* auto flush every 255 connections */ if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) { TSAN_QUALIFIER int *stat; + if (mode & SSL_SESS_CACHE_CLIENT) stat = &s->session_ctx->stats.sess_connect_good; else stat = &s->session_ctx->stats.sess_accept_good; - if ((tsan_load(stat) & 0xff) == 0xff) + if ((ssl_tsan_load(s->session_ctx, stat) & 0xff) == 0xff) SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL)); } } @@ -3682,6 +3885,8 @@ int SSL_get_error(const SSL *s, int i) } if (SSL_want_x509_lookup(s)) return SSL_ERROR_WANT_X509_LOOKUP; + if (SSL_want_retry_verify(s)) + return SSL_ERROR_WANT_RETRY_VERIFY; if (SSL_want_async(s)) return SSL_ERROR_WANT_ASYNC; if (SSL_want_async_job(s)) @@ -3690,7 +3895,7 @@ int SSL_get_error(const SSL *s, int i) return SSL_ERROR_WANT_CLIENT_HELLO_CB; if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && - (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) + (s->s3.warn_alert == SSL_AD_CLOSE_NOTIFY)) return SSL_ERROR_ZERO_RETURN; return SSL_ERROR_SYSCALL; @@ -3712,7 +3917,7 @@ int SSL_do_handshake(SSL *s) int ret = 1; if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET); + ERR_raise(ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET); return -1; } @@ -3755,14 +3960,13 @@ void SSL_set_connect_state(SSL *s) int ssl_undefined_function(SSL *s) { - SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } int ssl_undefined_void_function(void) { - SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -3773,7 +3977,7 @@ int ssl_undefined_const_function(const SSL *s) const SSL_METHOD *ssl_bad_method(int ver) { - SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return NULL; } @@ -4008,7 +4212,7 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s) { - return s->s3->tmp.new_cipher; + return s->s3.tmp.new_cipher; } const COMP_METHOD *SSL_get_current_compression(const SSL *s) @@ -4039,9 +4243,9 @@ int ssl_init_wbio_buffer(SSL *s) } bbio = BIO_new(BIO_f_buffer()); - if (bbio == NULL || !BIO_set_read_buffer_size(bbio, 1)) { + if (bbio == NULL || BIO_set_read_buffer_size(bbio, 1) <= 0) { BIO_free(bbio); - SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); return 0; } s->bbio = bbio; @@ -4157,7 +4361,8 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { - return X509_STORE_set_default_paths(ctx->cert_store); + return X509_STORE_set_default_paths_ex(ctx->cert_store, ctx->libctx, + ctx->propq); } int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx) @@ -4167,10 +4372,13 @@ int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx) lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_hash_dir()); if (lookup == NULL) return 0; + + /* We ignore errors, in case the directory doesn't exist */ + ERR_set_mark(); + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); - /* Clear any errors if the default directory does not exist */ - ERR_clear_error(); + ERR_pop_to_mark(); return 1; } @@ -4183,18 +4391,62 @@ int SSL_CTX_set_default_verify_file(SSL_CTX *ctx) if (lookup == NULL) return 0; - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + /* We ignore errors, in case the file doesn't exist */ + ERR_set_mark(); - /* Clear any errors if the default file does not exist */ - ERR_clear_error(); + X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, ctx->libctx, + ctx->propq); + + ERR_pop_to_mark(); return 1; } +int SSL_CTX_set_default_verify_store(SSL_CTX *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_store()); + if (lookup == NULL) + return 0; + + /* We ignore errors, in case the directory doesn't exist */ + ERR_set_mark(); + + X509_LOOKUP_add_store_ex(lookup, NULL, ctx->libctx, ctx->propq); + + ERR_pop_to_mark(); + + return 1; +} + +int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile) +{ + return X509_STORE_load_file_ex(ctx->cert_store, CAfile, ctx->libctx, + ctx->propq); +} + +int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) +{ + return X509_STORE_load_path(ctx->cert_store, CApath); +} + +int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore) +{ + return X509_STORE_load_store_ex(ctx->cert_store, CAstore, ctx->libctx, + ctx->propq); +} + int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath) { - return X509_STORE_load_locations(ctx->cert_store, CAfile, CApath); + if (CAfile == NULL && CApath == NULL) + return 0; + if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile)) + return 0; + if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath)) + return 0; + return 1; } void SSL_set_info_callback(SSL *ssl, @@ -4226,20 +4478,20 @@ long SSL_get_verify_result(const SSL *ssl) size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen) { if (outlen == 0) - return sizeof(ssl->s3->client_random); - if (outlen > sizeof(ssl->s3->client_random)) - outlen = sizeof(ssl->s3->client_random); - memcpy(out, ssl->s3->client_random, outlen); + return sizeof(ssl->s3.client_random); + if (outlen > sizeof(ssl->s3.client_random)) + outlen = sizeof(ssl->s3.client_random); + memcpy(out, ssl->s3.client_random, outlen); return outlen; } size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen) { if (outlen == 0) - return sizeof(ssl->s3->server_random); - if (outlen > sizeof(ssl->s3->server_random)) - outlen = sizeof(ssl->s3->server_random); - memcpy(out, ssl->s3->server_random, outlen); + return sizeof(ssl->s3.server_random); + if (outlen > sizeof(ssl->s3.server_random)) + outlen = sizeof(ssl->s3.server_random); + memcpy(out, ssl->s3.server_random, outlen); return outlen; } @@ -4309,32 +4561,11 @@ int SSL_want(const SSL *s) return s->rwstate; } -/** - * \brief Set the callback for generating temporary DH keys. - * \param ctx the SSL context. - * \param dh the callback - */ - -#ifndef OPENSSL_NO_DH -void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, - DH *(*dh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); -} - -void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); -} -#endif - #ifndef OPENSSL_NO_PSK int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) { if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } OPENSSL_free(ctx->cert->psk_identity_hint); @@ -4353,7 +4584,7 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) return 0; if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } OPENSSL_free(s->cert->psk_identity_hint); @@ -4485,11 +4716,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) return 1; } -void SSL_set_record_padding_callback(SSL *ssl, +int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb) (SSL *ssl, int type, size_t len, void *arg)) { - ssl->record_padding_cb = cb; + BIO *b; + + b = SSL_get_wbio(ssl); + if (b == NULL || !BIO_get_ktls_send(b)) { + ssl->record_padding_cb = cb; + return 1; + } + return 0; } void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) @@ -4569,27 +4807,24 @@ int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen, size_t *hashlen) { EVP_MD_CTX *ctx = NULL; - EVP_MD_CTX *hdgst = s->s3->handshake_dgst; - int hashleni = EVP_MD_CTX_size(hdgst); + EVP_MD_CTX *hdgst = s->s3.handshake_dgst; + int hashleni = EVP_MD_CTX_get_size(hdgst); int ret = 0; if (hashleni < 0 || (size_t)hashleni > outlen) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_HANDSHAKE_HASH, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } ctx = EVP_MD_CTX_new(); if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_HANDSHAKE_HASH, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (!EVP_MD_CTX_copy_ex(ctx, hdgst) || EVP_DigestFinal_ex(ctx, out, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_HANDSHAKE_HASH, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -4611,7 +4846,7 @@ int SSL_is_server(const SSL *s) return s->server; } -#if OPENSSL_API_COMPAT < 0x10100000L +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 void SSL_set_debug(SSL *s, int debug) { /* Old function was do-nothing anyway... */ @@ -4692,37 +4927,32 @@ void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx) return ctx->cert->sec_ex; } -/* - * Get/Set/Clear options in SSL_CTX or SSL, formerly macros, now functions that - * can return unsigned long, instead of the generic long return value from the - * control interface. - */ -unsigned long SSL_CTX_get_options(const SSL_CTX *ctx) +uint64_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; } -unsigned long SSL_get_options(const SSL *s) +uint64_t SSL_get_options(const SSL *s) { return s->options; } -unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op) +uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t op) { return ctx->options |= op; } -unsigned long SSL_set_options(SSL *s, unsigned long op) +uint64_t SSL_set_options(SSL *s, uint64_t op) { return s->options |= op; } -unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) +uint64_t SSL_CTX_clear_options(SSL_CTX *ctx, uint64_t op) { return ctx->options &= ~op; } -unsigned long SSL_clear_options(SSL *s, unsigned long op) +uint64_t SSL_clear_options(SSL *s, uint64_t op) { return s->options &= ~op; } @@ -4752,7 +4982,7 @@ static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src, if (*dst == NULL) { *dst = sk_SCT_new_null(); if (*dst == NULL) { - SSLerr(SSL_F_CT_MOVE_SCTS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } } @@ -4909,7 +5139,7 @@ static int ct_strict(const CT_POLICY_EVAL_CTX * ctx, if (status == SCT_VALIDATION_STATUS_VALID) return 1; } - SSLerr(SSL_F_CT_STRICT, SSL_R_NO_VALID_SCTS); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_VALID_SCTS); return 0; } @@ -4923,8 +5153,7 @@ int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, if (callback != NULL && SSL_CTX_has_client_custom_ext(s->ctx, TLSEXT_TYPE_signed_certificate_timestamp)) { - SSLerr(SSL_F_SSL_SET_CT_VALIDATION_CALLBACK, - SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED); + ERR_raise(ERR_LIB_SSL, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED); return 0; } @@ -4952,8 +5181,7 @@ int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, if (callback != NULL && SSL_CTX_has_client_custom_ext(ctx, TLSEXT_TYPE_signed_certificate_timestamp)) { - SSLerr(SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK, - SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED); + ERR_raise(ERR_LIB_SSL, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED); return 0; } @@ -5009,10 +5237,9 @@ int ssl_validate_ct(SSL *s) } } - ctx = CT_POLICY_EVAL_CTX_new(); + ctx = CT_POLICY_EVAL_CTX_new_ex(s->ctx->libctx, s->ctx->propq); if (ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_VALIDATE_CT, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto end; } @@ -5040,8 +5267,7 @@ int ssl_validate_ct(SSL *s) * ought to correspond to an inability to carry out its duties. */ if (SCT_LIST_validate(scts, ctx) < 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_SSL_VALIDATE_CT, - SSL_R_SCT_VERIFICATION_FAILED); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_SCT_VERIFICATION_FAILED); goto end; } @@ -5049,8 +5275,7 @@ int ssl_validate_ct(SSL *s) if (ret < 0) ret = 0; /* This function returns 0 on failure */ if (!ret) - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_SSL_VALIDATE_CT, - SSL_R_CALLBACK_FAILED); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_CALLBACK_FAILED); end: CT_POLICY_EVAL_CTX_free(ctx); @@ -5078,7 +5303,7 @@ int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode) { switch (validation_mode) { default: - SSLerr(SSL_F_SSL_CTX_ENABLE_CT, SSL_R_INVALID_CT_VALIDATION_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE); return 0; case SSL_CT_VALIDATION_PERMISSIVE: return SSL_CTX_set_ct_validation_callback(ctx, ct_permissive, NULL); @@ -5091,7 +5316,7 @@ int SSL_enable_ct(SSL *s, int validation_mode) { switch (validation_mode) { default: - SSLerr(SSL_F_SSL_ENABLE_CT, SSL_R_INVALID_CT_VALIDATION_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE); return 0; case SSL_CT_VALIDATION_PERMISSIVE: return SSL_set_ct_validation_callback(s, ct_permissive, NULL); @@ -5199,8 +5424,7 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen) return 1; } if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) { - SSLerr(SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) { @@ -5293,8 +5517,7 @@ static int nss_keylog_int(const char *prefix, prefix_len = strlen(prefix); out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3; if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) { - SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_NSS_KEYLOG_INT, - ERR_R_MALLOC_FAILURE); + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } @@ -5327,8 +5550,7 @@ int ssl_log_rsa_client_key_exchange(SSL *ssl, size_t premaster_len) { if (encrypted_premaster_len < 8) { - SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -5348,7 +5570,7 @@ int ssl_log_secret(SSL *ssl, { return nss_keylog_int(label, ssl, - ssl->s3->client_random, + ssl->s3.client_random, SSL3_RANDOM_SIZE, secret, secret_len); @@ -5363,20 +5585,18 @@ int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format) n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN; if (PACKET_remaining(cipher_suites) == 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SSL_CACHE_CIPHERLIST, - SSL_R_NO_CIPHERS_SPECIFIED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_CIPHERS_SPECIFIED); return 0; } if (PACKET_remaining(cipher_suites) % n != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL_CACHE_CIPHERLIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); return 0; } - OPENSSL_free(s->s3->tmp.ciphers_raw); - s->s3->tmp.ciphers_raw = NULL; - s->s3->tmp.ciphers_rawlen = 0; + OPENSSL_free(s->s3.tmp.ciphers_raw); + s->s3.tmp.ciphers_raw = NULL; + s->s3.tmp.ciphers_rawlen = 0; if (sslv2format) { size_t numciphers = PACKET_remaining(cipher_suites) / n; @@ -5392,13 +5612,12 @@ int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format) * problem. */ raw = OPENSSL_malloc(numciphers * TLS_CIPHER_LEN); - s->s3->tmp.ciphers_raw = raw; + s->s3.tmp.ciphers_raw = raw; if (raw == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CACHE_CIPHERLIST, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - for (s->s3->tmp.ciphers_rawlen = 0; + for (s->s3.tmp.ciphers_rawlen = 0; PACKET_remaining(&sslv2ciphers) > 0; raw += TLS_CIPHER_LEN) { if (!PACKET_get_1(&sslv2ciphers, &leadbyte) @@ -5407,20 +5626,18 @@ int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format) TLS_CIPHER_LEN)) || (leadbyte != 0 && !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL_CACHE_CIPHERLIST, - SSL_R_BAD_PACKET); - OPENSSL_free(s->s3->tmp.ciphers_raw); - s->s3->tmp.ciphers_raw = NULL; - s->s3->tmp.ciphers_rawlen = 0; + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_PACKET); + OPENSSL_free(s->s3.tmp.ciphers_raw); + s->s3.tmp.ciphers_raw = NULL; + s->s3.tmp.ciphers_rawlen = 0; return 0; } if (leadbyte == 0) - s->s3->tmp.ciphers_rawlen += TLS_CIPHER_LEN; + s->s3.tmp.ciphers_rawlen += TLS_CIPHER_LEN; } - } else if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw, - &s->s3->tmp.ciphers_rawlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CACHE_CIPHERLIST, - ERR_R_INTERNAL_ERROR); + } else if (!PACKET_memdup(cipher_suites, &s->s3.tmp.ciphers_raw, + &s->s3.tmp.ciphers_rawlen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } return 1; @@ -5453,20 +5670,18 @@ int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, if (PACKET_remaining(cipher_suites) == 0) { if (fatal) - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_BYTES_TO_CIPHER_LIST, - SSL_R_NO_CIPHERS_SPECIFIED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_CIPHERS_SPECIFIED); else - SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_NO_CIPHERS_SPECIFIED); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHERS_SPECIFIED); return 0; } if (PACKET_remaining(cipher_suites) % n != 0) { if (fatal) - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_BYTES_TO_CIPHER_LIST, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); else - SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); return 0; } @@ -5474,10 +5689,9 @@ int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, scsvs = sk_SSL_CIPHER_new_null(); if (sk == NULL || scsvs == NULL) { if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_BYTES_TO_CIPHER_LIST, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); else - SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } @@ -5496,20 +5710,18 @@ int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, if ((c->valid && !sk_SSL_CIPHER_push(sk, c)) || (!c->valid && !sk_SSL_CIPHER_push(scsvs, c))) { if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); else - SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } } } if (PACKET_remaining(cipher_suites) > 0) { if (fatal) - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_BYTES_TO_CIPHER_LIST, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); else - SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); goto err; } @@ -5611,9 +5823,9 @@ int SSL_stateless(SSL *s) ERR_clear_error(); - s->s3->flags |= TLS1_FLAGS_STATELESS; + s->s3.flags |= TLS1_FLAGS_STATELESS; ret = SSL_accept(s); - s->s3->flags &= ~TLS1_FLAGS_STATELESS; + s->s3.flags &= ~TLS1_FLAGS_STATELESS; if (ret > 0 && s->ext.cookieok) return 1; @@ -5637,34 +5849,34 @@ void SSL_set_post_handshake_auth(SSL *ssl, int val) int SSL_verify_client_post_handshake(SSL *ssl) { if (!SSL_IS_TLS13(ssl)) { - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_WRONG_SSL_VERSION); + ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } if (!ssl->server) { - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_NOT_SERVER); + ERR_raise(ERR_LIB_SSL, SSL_R_NOT_SERVER); return 0; } if (!SSL_is_init_finished(ssl)) { - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_STILL_IN_INIT); + ERR_raise(ERR_LIB_SSL, SSL_R_STILL_IN_INIT); return 0; } switch (ssl->post_handshake_auth) { case SSL_PHA_NONE: - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_EXTENSION_NOT_RECEIVED); + ERR_raise(ERR_LIB_SSL, SSL_R_EXTENSION_NOT_RECEIVED); return 0; default: case SSL_PHA_EXT_SENT: - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; case SSL_PHA_EXT_RECEIVED: break; case SSL_PHA_REQUEST_PENDING: - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_PENDING); + ERR_raise(ERR_LIB_SSL, SSL_R_REQUEST_PENDING); return 0; case SSL_PHA_REQUESTED: - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_SENT); + ERR_raise(ERR_LIB_SSL, SSL_R_REQUEST_SENT); return 0; } @@ -5673,7 +5885,7 @@ int SSL_verify_client_post_handshake(SSL *ssl) /* checks verify_mode and algorithm_auth */ if (!send_certificate_request(ssl)) { ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */ - SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_INVALID_CONFIG); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_CONFIG); return 0; } @@ -5707,3 +5919,119 @@ void SSL_set_allow_early_data_cb(SSL *s, s->allow_early_data_cb = cb; s->allow_early_data_cb_data = arg; } + +const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx, + int nid, + const char *properties) +{ + const EVP_CIPHER *ciph; + + ciph = tls_get_cipher_from_engine(nid); + if (ciph != NULL) + return ciph; + + /* + * If there is no engine cipher then we do an explicit fetch. This may fail + * and that could be ok + */ + ERR_set_mark(); + ciph = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties); + ERR_pop_to_mark(); + return ciph; +} + + +int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher) +{ + /* Don't up-ref an implicit EVP_CIPHER */ + if (EVP_CIPHER_get0_provider(cipher) == NULL) + return 1; + + /* + * The cipher was explicitly fetched and therefore it is safe to cast + * away the const + */ + return EVP_CIPHER_up_ref((EVP_CIPHER *)cipher); +} + +void ssl_evp_cipher_free(const EVP_CIPHER *cipher) +{ + if (cipher == NULL) + return; + + if (EVP_CIPHER_get0_provider(cipher) != NULL) { + /* + * The cipher was explicitly fetched and therefore it is safe to cast + * away the const + */ + EVP_CIPHER_free((EVP_CIPHER *)cipher); + } +} + +const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx, + int nid, + const char *properties) +{ + const EVP_MD *md; + + md = tls_get_digest_from_engine(nid); + if (md != NULL) + return md; + + /* Otherwise we do an explicit fetch */ + ERR_set_mark(); + md = EVP_MD_fetch(libctx, OBJ_nid2sn(nid), properties); + ERR_pop_to_mark(); + return md; +} + +int ssl_evp_md_up_ref(const EVP_MD *md) +{ + /* Don't up-ref an implicit EVP_MD */ + if (EVP_MD_get0_provider(md) == NULL) + return 1; + + /* + * The digest was explicitly fetched and therefore it is safe to cast + * away the const + */ + return EVP_MD_up_ref((EVP_MD *)md); +} + +void ssl_evp_md_free(const EVP_MD *md) +{ + if (md == NULL) + return; + + if (EVP_MD_get0_provider(md) != NULL) { + /* + * The digest was explicitly fetched and therefore it is safe to cast + * away the const + */ + EVP_MD_free((EVP_MD *)md); + } +} + +int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey) +{ + if (!ssl_security(s, SSL_SECOP_TMP_DH, + EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) { + ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL); + return 0; + } + EVP_PKEY_free(s->cert->dh_tmp); + s->cert->dh_tmp = dhpkey; + return 1; +} + +int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey) +{ + if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH, + EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) { + ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL); + return 0; + } + EVP_PKEY_free(ctx->cert->dh_tmp); + ctx->cert->dh_tmp = dhpkey; + return 1; +} diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 5c7921542310..5fb1feb80163 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -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 @@ -21,7 +21,6 @@ # include <openssl/buffer.h> # include <openssl/comp.h> # include <openssl/bio.h> -# include <openssl/rsa.h> # include <openssl/dsa.h> # include <openssl/err.h> # include <openssl/ssl.h> @@ -30,10 +29,12 @@ # include <openssl/ct.h> # include "record/record.h" # include "statem/statem.h" -# include "packet_local.h" +# include "internal/packet.h" # include "internal/dane.h" # include "internal/refcount.h" # include "internal/tsan_assist.h" +# include "internal/bio.h" +# include "internal/ktls.h" # ifdef OPENSSL_BUILD_SHLIBSSL # undef OPENSSL_EXTERN @@ -130,6 +131,9 @@ (c)[1]=(unsigned char)(((l)>> 8)&0xff), \ (c)[2]=(unsigned char)(((l) )&0xff)),(c)+=3) +# define TLS_MAX_VERSION_INTERNAL TLS1_3_VERSION +# define DTLS_MAX_VERSION_INTERNAL DTLS1_2_VERSION + /* * DTLS version numbers are strange because they're inverted. Except for * DTLS1_BAD_VER, which should be considered "lower" than the rest. @@ -176,6 +180,8 @@ # define SSL_kRSAPSK 0x00000040U # define SSL_kECDHEPSK 0x00000080U # define SSL_kDHEPSK 0x00000100U +/* GOST KDF key exchange, draft-smyshlyaev-tls12-gost-suites */ +# define SSL_kGOST18 0x00000200U /* all PSK */ @@ -230,6 +236,8 @@ # define SSL_CHACHA20POLY1305 0x00080000U # define SSL_ARIA128GCM 0x00100000U # define SSL_ARIA256GCM 0x00200000U +# define SSL_MAGMA 0x00400000U +# define SSL_KUZNYECHIK 0x00800000U # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) @@ -238,6 +246,9 @@ # define SSL_CHACHA20 (SSL_CHACHA20POLY1305) # define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM) # define SSL_ARIA (SSL_ARIAGCM) +# define SSL_CBC (SSL_DES | SSL_3DES | SSL_RC2 | SSL_IDEA \ + | SSL_AES128 | SSL_AES256 | SSL_CAMELLIA128 \ + | SSL_CAMELLIA256 | SSL_SEED) /* Bits for algorithm_mac (symmetric authentication) */ @@ -252,6 +263,8 @@ # define SSL_GOST12_256 0x00000080U # define SSL_GOST89MAC12 0x00000100U # define SSL_GOST12_512 0x00000200U +# define SSL_MAGMAOMAC 0x00000400U +# define SSL_KUZNYECHIKOMAC 0x00000800U /* * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make @@ -270,7 +283,11 @@ # define SSL_MD_MD5_SHA1_IDX 9 # define SSL_MD_SHA224_IDX 10 # define SSL_MD_SHA512_IDX 11 -# define SSL_MAX_DIGEST 12 +# define SSL_MD_MAGMAOMAC_IDX 12 +# define SSL_MD_KUZNYECHIKOMAC_IDX 13 +# define SSL_MAX_DIGEST 14 + +#define SSL_MD_NUM_IDX SSL_MAX_DIGEST /* Bits for algorithm2 (handshake digests and other extra flags) */ @@ -299,6 +316,11 @@ * goes into algorithm2) */ # define TLS1_STREAM_MAC 0x10000 +/* + * TLSTREE cipher/mac key derivation from draft-smyshlyaev-tls12-gost-suites + * (currently this also goes into algorithm2) + */ +# define TLS1_TLSTREE 0x20000 # define SSL_STRONG_MASK 0x0000001FU # define SSL_DEFAULT_MASK 0X00000020U @@ -330,8 +352,8 @@ || (s)->early_data_state == SSL_EARLY_DATA_WRITE_RETRY \ || (s)->hello_retry_request == SSL_HRR_PENDING) -# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3->tmp.finish_md_len == 0 \ - || (s)->s3->tmp.peer_finish_md_len == 0) +# define SSL_IS_FIRST_HANDSHAKE(S) ((s)->s3.tmp.finish_md_len == 0 \ + || (s)->s3.tmp.peer_finish_md_len == 0) /* See if we need explicit IV */ # define SSL_USE_EXPLICIT_IV(s) \ @@ -370,8 +392,8 @@ # define GET_MAX_FRAGMENT_LENGTH(session) \ (512U << (session->ext.max_fragment_len_mode - 1)) -# define SSL_READ_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_READ) -# define SSL_WRITE_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE) +# define SSL_READ_ETM(s) (s->s3.flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_READ) +# define SSL_WRITE_ETM(s) (s->s3.flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE) /* Mostly for SSLv3 */ # define SSL_PKEY_RSA 0 @@ -385,6 +407,32 @@ # define SSL_PKEY_ED448 8 # define SSL_PKEY_NUM 9 +# define SSL_ENC_DES_IDX 0 +# define SSL_ENC_3DES_IDX 1 +# define SSL_ENC_RC4_IDX 2 +# define SSL_ENC_RC2_IDX 3 +# define SSL_ENC_IDEA_IDX 4 +# define SSL_ENC_NULL_IDX 5 +# define SSL_ENC_AES128_IDX 6 +# define SSL_ENC_AES256_IDX 7 +# define SSL_ENC_CAMELLIA128_IDX 8 +# define SSL_ENC_CAMELLIA256_IDX 9 +# define SSL_ENC_GOST89_IDX 10 +# define SSL_ENC_SEED_IDX 11 +# define SSL_ENC_AES128GCM_IDX 12 +# define SSL_ENC_AES256GCM_IDX 13 +# define SSL_ENC_AES128CCM_IDX 14 +# define SSL_ENC_AES256CCM_IDX 15 +# define SSL_ENC_AES128CCM8_IDX 16 +# define SSL_ENC_AES256CCM8_IDX 17 +# define SSL_ENC_GOST8912_IDX 18 +# define SSL_ENC_CHACHA_IDX 19 +# define SSL_ENC_ARIA128GCM_IDX 20 +# define SSL_ENC_ARIA256GCM_IDX 21 +# define SSL_ENC_MAGMA_IDX 22 +# define SSL_ENC_KUZNYECHIK_IDX 23 +# define SSL_ENC_NUM_IDX 24 + /*- * SSL_kRSA <- RSA_ENC * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) @@ -475,7 +523,7 @@ struct ssl_method_st { * Matches the length of PSK_MAX_PSK_LEN. We keep it the same value for * consistency, even in the event of OPENSSL_NO_PSK being defined. */ -# define TLS13_MAX_RESUMPTION_PSK_LENGTH 256 +# define TLS13_MAX_RESUMPTION_PSK_LENGTH 512 /*- * Lets make this into an ASN.1 type structure as follows @@ -545,12 +593,15 @@ struct ssl_session_st { */ long verify_result; /* only for servers */ CRYPTO_REF_COUNT references; - long timeout; - long time; + time_t timeout; + time_t time; + time_t calc_timeout; + int timeout_ovf; unsigned int compress_meth; /* Need to lookup the method */ const SSL_CIPHER *cipher; unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used to * load the 'cipher' structure */ + unsigned int kex_group; /* TLS group from key exchange */ CRYPTO_EX_DATA ex_data; /* application specific data */ /* * These are used to make removal of session-ids more efficient and to @@ -585,6 +636,7 @@ struct ssl_session_st { unsigned char *ticket_appdata; size_t ticket_appdata_len; uint32_t flags; + SSL_CTX *owner; CRYPTO_RWLOCK *lock; }; @@ -732,7 +784,63 @@ typedef struct ssl_ctx_ext_secure_st { unsigned char tick_aes_key[TLSEXT_TICK_KEY_LENGTH]; } SSL_CTX_EXT_SECURE; +/* + * Helper function for HMAC + * The structure should be considered opaque, it will change once the low + * level deprecated calls are removed. At that point it can be replaced + * by EVP_MAC_CTX and most of the functions converted to macros or inlined + * directly. + */ +typedef struct ssl_hmac_st { + EVP_MAC_CTX *ctx; +# ifndef OPENSSL_NO_DEPRECATED_3_0 + HMAC_CTX *old_ctx; +# endif +} SSL_HMAC; + +SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx); +void ssl_hmac_free(SSL_HMAC *ctx); +# ifndef OPENSSL_NO_DEPRECATED_3_0 +HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx); +# endif +EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx); +int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md); +int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len); +int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, + size_t max_size); +size_t ssl_hmac_size(const SSL_HMAC *ctx); + +int ssl_get_EC_curve_nid(const EVP_PKEY *pkey); +__owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey, + const unsigned char *enckey, + size_t enckeylen); + +typedef struct tls_group_info_st { + char *tlsname; /* Curve Name as in TLS specs */ + char *realname; /* Curve Name according to provider */ + char *algorithm; /* Algorithm name to fetch */ + unsigned int secbits; /* Bits of security (from SP800-57) */ + uint16_t group_id; /* Group ID */ + int mintls; /* Minimum TLS version, -1 unsupported */ + int maxtls; /* Maximum TLS version (or 0 for undefined) */ + int mindtls; /* Minimum DTLS version, -1 unsupported */ + int maxdtls; /* Maximum DTLS version (or 0 for undefined) */ + char is_kem; /* Mode for this Group: 0 is KEX, 1 is KEM */ +} TLS_GROUP_INFO; + +/* flags values */ +# define TLS_GROUP_TYPE 0x0000000FU /* Mask for group type */ +# define TLS_GROUP_CURVE_PRIME 0x00000001U +# define TLS_GROUP_CURVE_CHAR2 0x00000002U +# define TLS_GROUP_CURVE_CUSTOM 0x00000004U +# define TLS_GROUP_FFDHE 0x00000008U +# define TLS_GROUP_ONLY_FOR_TLS1_3 0x00000010U + +# define TLS_GROUP_FFDHE_FOR_TLS1_3 (TLS_GROUP_FFDHE|TLS_GROUP_ONLY_FOR_TLS1_3) + struct ssl_ctx_st { + OSSL_LIB_CTX *libctx; + const SSL_METHOD *method; STACK_OF(SSL_CIPHER) *cipher_list; /* same as above but sorted for lookup */ @@ -793,6 +901,9 @@ struct ssl_ctx_st { * other processes - spooky * :-) */ } stats; +#ifdef TSAN_REQUIRES_LOCKING + CRYPTO_RWLOCK *tsan_lock; +#endif CRYPTO_REF_COUNT references; @@ -832,7 +943,7 @@ struct ssl_ctx_st { CRYPTO_EX_DATA ex_data; const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ - const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3-sha1' */ STACK_OF(X509) *extra_certs; STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ @@ -856,7 +967,7 @@ struct ssl_ctx_st { * SSL_new) */ - uint32_t options; + uint64_t options; uint32_t mode; int min_proto_version; int max_proto_version; @@ -929,10 +1040,16 @@ struct ssl_ctx_st { /* RFC 4507 session ticket keys */ unsigned char tick_key_name[TLSEXT_KEYNAME_LENGTH]; SSL_CTX_EXT_SECURE *secure; +# ifndef OPENSSL_NO_DEPRECATED_3_0 /* Callback to support customisation of ticket key setting */ int (*ticket_key_cb) (SSL *ssl, unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); +#endif + int (*ticket_key_evp_cb) (SSL *ssl, + unsigned char *name, unsigned char *iv, + EVP_CIPHER_CTX *ectx, EVP_MAC_CTX *hctx, + int enc); /* certificate status request info */ /* Callback for status request */ @@ -943,14 +1060,15 @@ struct ssl_ctx_st { /* RFC 4366 Maximum Fragment Length Negotiation */ uint8_t max_fragment_len_mode; -# ifndef OPENSSL_NO_EC /* EC extension values inherited by SSL structure */ size_t ecpointformats_len; unsigned char *ecpointformats; + size_t supportedgroups_len; uint16_t *supportedgroups; -# endif /* OPENSSL_NO_EC */ + uint16_t *supported_groups_default; + size_t supported_groups_default_len; /* * ALPN information (we are in the process of transitioning from NPN to * ALPN.) @@ -1063,8 +1181,34 @@ struct ssl_ctx_st { /* Do we advertise Post-handshake auth support? */ int pha_enabled; + + /* Callback for SSL async handling */ + SSL_async_callback_fn async_cb; + void *async_cb_arg; + + char *propq; + + int ssl_mac_pkey_id[SSL_MD_NUM_IDX]; + const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; + const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]; + size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; + + /* Cache of all sigalgs we know and whether they are available or not */ + struct sigalg_lookup_st *sigalg_lookup_cache; + + TLS_GROUP_INFO *group_list; + size_t group_list_len; + size_t group_list_max_len; + + /* masks of disabled algorithms */ + uint32_t disabled_enc_mask; + uint32_t disabled_mac_mask; + uint32_t disabled_mkey_mask; + uint32_t disabled_auth_mask; }; +typedef struct cert_pkey_st CERT_PKEY; + struct ssl_st { /* * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, @@ -1118,7 +1262,179 @@ struct ssl_st { * ssl3_get_message() */ size_t init_num; /* amount read/written */ size_t init_off; /* amount read/written */ - struct ssl3_state_st *s3; /* SSLv3 variables */ + + struct { + long flags; + size_t read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + size_t write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* + * When handshake digest is determined, buffer is hashed and + * freed and MD_CTX for the required digest is stored here. + */ + EVP_MD_CTX *handshake_dgst; + /* + * Set whenever an expected ChangeCipherSpec message is processed. + * Unset when the peer's Finished message is received. + * Unexpected ChangeCipherSpec messages trigger a fatal alert. + */ + int change_cipher_spec; + int warn_alert; + int fatal_alert; + /* + * we allow one fatal and one warning alert to be outstanding, send close + * alert via the warning alert + */ + int alert_dispatch; + unsigned char send_alert[2]; + /* + * This flag is set when we should renegotiate ASAP, basically when there + * is no more data in the read or write buffers + */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + int in_read_app_data; + struct { + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; + size_t finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; + size_t peer_finish_md_len; + size_t message_size; + int message_type; + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; + EVP_PKEY *pkey; /* holds short lived key exchange key */ + /* used for certificate requests */ + int cert_req; + /* Certificate types in certificate request message. */ + uint8_t *ctype; + size_t ctype_len; + /* Certificate authorities list peer sent */ + STACK_OF(X509_NAME) *peer_ca_names; + size_t key_block_length; + unsigned char *key_block; + const EVP_CIPHER *new_sym_enc; + const EVP_MD *new_hash; + int new_mac_pkey_type; + size_t new_mac_secret_size; +# ifndef OPENSSL_NO_COMP + const SSL_COMP *new_compression; +# else + char *new_compression; +# endif + int cert_request; + /* Raw values of the cipher list from a client */ + unsigned char *ciphers_raw; + size_t ciphers_rawlen; + /* Temporary storage for premaster secret */ + unsigned char *pms; + size_t pmslen; +# ifndef OPENSSL_NO_PSK + /* Temporary storage for PSK key */ + unsigned char *psk; + size_t psklen; +# endif + /* Signature algorithm we actually use */ + const struct sigalg_lookup_st *sigalg; + /* Pointer to certificate we use */ + CERT_PKEY *cert; + /* + * signature algorithms peer reports: e.g. supported signature + * algorithms extension for server or as part of a certificate + * request for client. + * Keep track of the algorithms for TLS and X.509 usage separately. + */ + uint16_t *peer_sigalgs; + uint16_t *peer_cert_sigalgs; + /* Size of above arrays */ + size_t peer_sigalgslen; + size_t peer_cert_sigalgslen; + /* Sigalg peer actually uses */ + const struct sigalg_lookup_st *peer_sigalg; + /* + * Set if corresponding CERT_PKEY can be used with current + * SSL session: e.g. appropriate curve, signature algorithms etc. + * If zero it can't be used at all. + */ + uint32_t valid_flags[SSL_PKEY_NUM]; + /* + * For servers the following masks are for the key and auth algorithms + * that are supported by the certs below. For clients they are masks of + * *disabled* algorithms based on the current session. + */ + uint32_t mask_k; + uint32_t mask_a; + /* + * The following are used by the client to see if a cipher is allowed or + * not. It contains the minimum and maximum version the client's using + * based on what it knows so far. + */ + int min_ver; + int max_ver; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + size_t previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + size_t previous_server_finished_len; + int send_connection_binding; + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Set if we saw the Next Protocol Negotiation extension from our peer. + */ + int npn_seen; +# endif + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /* + * In a server these point to the selected ALPN protocol after the + * ClientHello has been processed. In a client these contain the protocol + * that the server selected once the ServerHello has been processed. + */ + unsigned char *alpn_selected; + size_t alpn_selected_len; + /* used by the server to know what options were proposed */ + unsigned char *alpn_proposed; + size_t alpn_proposed_len; + /* used by the client to know if it actually sent alpn */ + int alpn_sent; + + /* + * This is set to true if we believe that this is a version of Safari + * running on OS X 10.6 or newer. We wish to know this because Safari on + * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. + */ + char is_probably_safari; + + /* + * Track whether we did a key exchange this handshake or not, so + * SSL_get_negotiated_group() knows whether to fall back to the + * value in the SSL_SESSION. + */ + char did_kex; + /* For clients: peer temporary key */ + /* The group_id for the key exchange key */ + uint16_t group_id; + EVP_PKEY *peer_tmp; + + } s3; + struct dtls1_state_st *d1; /* DTLSv1 variables */ /* callback that allows applications to peek at protocol messages */ void (*msg_callback) (int write_p, int version, int content_type, @@ -1235,7 +1551,7 @@ struct ssl_st { STACK_OF(X509_NAME) *client_ca_names; CRYPTO_REF_COUNT references; /* protocol behaviour */ - uint32_t options; + uint64_t options; /* API behaviour */ uint32_t mode; int min_proto_version; @@ -1289,7 +1605,8 @@ struct ssl_st { /* RFC4507 session ticket expected to be received or sent */ int ticket_expected; -# ifndef OPENSSL_NO_EC + /* TLS 1.3 tickets requested by the application. */ + int extra_tickets_expected; size_t ecpointformats_len; /* our list */ unsigned char *ecpointformats; @@ -1297,7 +1614,6 @@ struct ssl_st { size_t peer_ecpointformats_len; /* peer's list */ unsigned char *peer_ecpointformats; -# endif /* OPENSSL_NO_EC */ size_t supportedgroups_len; /* our list */ uint16_t *supportedgroups; @@ -1473,6 +1789,10 @@ struct ssl_st { SSL_allow_early_data_cb_fn allow_early_data_cb; void *allow_early_data_cb_data; + /* Callback for SSL async handling */ + SSL_async_callback_fn async_cb; + void *async_cb_arg; + /* * Signature algorithms shared by client and server: cached because these * are used most often. @@ -1502,22 +1822,10 @@ typedef struct sigalg_lookup_st { int sigandhash; /* Required public key curve (ECDSA only) */ int curve; + /* Whether this signature algorithm is actually available for use */ + int enabled; } SIGALG_LOOKUP; -typedef struct tls_group_info_st { - int nid; /* Curve NID */ - int secbits; /* Bits of security (from SP800-57) */ - uint16_t flags; /* Flags: currently just group type */ -} TLS_GROUP_INFO; - -/* flags values */ -# define TLS_CURVE_TYPE 0x3 /* Mask for group type */ -# define TLS_CURVE_PRIME 0x0 -# define TLS_CURVE_CHAR2 0x1 -# define TLS_CURVE_CUSTOM 0x2 - -typedef struct cert_pkey_st CERT_PKEY; - /* * Structure containing table entry of certificate info corresponding to * CERT_PKEY entries @@ -1527,178 +1835,6 @@ typedef struct { uint32_t amask; /* authmask corresponding to key type */ } SSL_CERT_LOOKUP; -typedef struct ssl3_state_st { - long flags; - size_t read_mac_secret_size; - unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; - size_t write_mac_secret_size; - unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; - unsigned char server_random[SSL3_RANDOM_SIZE]; - unsigned char client_random[SSL3_RANDOM_SIZE]; - /* flags for countermeasure against known-IV weakness */ - int need_empty_fragments; - int empty_fragment_done; - /* used during startup, digest all incoming/outgoing packets */ - BIO *handshake_buffer; - /* - * When handshake digest is determined, buffer is hashed and - * freed and MD_CTX for the required digest is stored here. - */ - EVP_MD_CTX *handshake_dgst; - /* - * Set whenever an expected ChangeCipherSpec message is processed. - * Unset when the peer's Finished message is received. - * Unexpected ChangeCipherSpec messages trigger a fatal alert. - */ - int change_cipher_spec; - int warn_alert; - int fatal_alert; - /* - * we allow one fatal and one warning alert to be outstanding, send close - * alert via the warning alert - */ - int alert_dispatch; - unsigned char send_alert[2]; - /* - * This flag is set when we should renegotiate ASAP, basically when there - * is no more data in the read or write buffers - */ - int renegotiate; - int total_renegotiations; - int num_renegotiations; - int in_read_app_data; - struct { - /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ - unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; - size_t finish_md_len; - unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; - size_t peer_finish_md_len; - size_t message_size; - int message_type; - /* used to hold the new cipher we are going to use */ - const SSL_CIPHER *new_cipher; -# if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) - EVP_PKEY *pkey; /* holds short lived DH/ECDH key */ -# endif - /* used for certificate requests */ - int cert_req; - /* Certificate types in certificate request message. */ - uint8_t *ctype; - size_t ctype_len; - /* Certificate authorities list peer sent */ - STACK_OF(X509_NAME) *peer_ca_names; - size_t key_block_length; - unsigned char *key_block; - const EVP_CIPHER *new_sym_enc; - const EVP_MD *new_hash; - int new_mac_pkey_type; - size_t new_mac_secret_size; -# ifndef OPENSSL_NO_COMP - const SSL_COMP *new_compression; -# else - char *new_compression; -# endif - int cert_request; - /* Raw values of the cipher list from a client */ - unsigned char *ciphers_raw; - size_t ciphers_rawlen; - /* Temporary storage for premaster secret */ - unsigned char *pms; - size_t pmslen; -# ifndef OPENSSL_NO_PSK - /* Temporary storage for PSK key */ - unsigned char *psk; - size_t psklen; -# endif - /* Signature algorithm we actually use */ - const SIGALG_LOOKUP *sigalg; - /* Pointer to certificate we use */ - CERT_PKEY *cert; - /* - * signature algorithms peer reports: e.g. supported signature - * algorithms extension for server or as part of a certificate - * request for client. - * Keep track of the algorithms for TLS and X.509 usage separately. - */ - uint16_t *peer_sigalgs; - uint16_t *peer_cert_sigalgs; - /* Size of above arrays */ - size_t peer_sigalgslen; - size_t peer_cert_sigalgslen; - /* Sigalg peer actually uses */ - const SIGALG_LOOKUP *peer_sigalg; - /* - * Set if corresponding CERT_PKEY can be used with current - * SSL session: e.g. appropriate curve, signature algorithms etc. - * If zero it can't be used at all. - */ - uint32_t valid_flags[SSL_PKEY_NUM]; - /* - * For servers the following masks are for the key and auth algorithms - * that are supported by the certs below. For clients they are masks of - * *disabled* algorithms based on the current session. - */ - uint32_t mask_k; - uint32_t mask_a; - /* - * The following are used by the client to see if a cipher is allowed or - * not. It contains the minimum and maximum version the client's using - * based on what it knows so far. - */ - int min_ver; - int max_ver; - } tmp; - - /* Connection binding to prevent renegotiation attacks */ - unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; - size_t previous_client_finished_len; - unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; - size_t previous_server_finished_len; - int send_connection_binding; /* TODOEKR */ - -# ifndef OPENSSL_NO_NEXTPROTONEG - /* - * Set if we saw the Next Protocol Negotiation extension from our peer. - */ - int npn_seen; -# endif - - /* - * ALPN information (we are in the process of transitioning from NPN to - * ALPN.) - */ - - /* - * In a server these point to the selected ALPN protocol after the - * ClientHello has been processed. In a client these contain the protocol - * that the server selected once the ServerHello has been processed. - */ - unsigned char *alpn_selected; - size_t alpn_selected_len; - /* used by the server to know what options were proposed */ - unsigned char *alpn_proposed; - size_t alpn_proposed_len; - /* used by the client to know if it actually sent alpn */ - int alpn_sent; - -# ifndef OPENSSL_NO_EC - /* - * This is set to true if we believe that this is a version of Safari - * running on OS X 10.6 or newer. We wish to know this because Safari on - * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. - */ - char is_probably_safari; -# endif /* !OPENSSL_NO_EC */ - - /* For clients: peer temporary key */ -# if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) - /* The group_id for the DH/ECDH key */ - uint16_t group_id; - EVP_PKEY *peer_tmp; -# endif - -} SSL3_STATE; - /* DTLS structures */ # ifndef OPENSSL_NO_SCTP @@ -1732,15 +1868,6 @@ struct hm_header_st { struct dtls1_retransmit_state saved_retransmit_state; }; -struct dtls1_timeout_st { - /* Number of read timeouts so far */ - unsigned int read_timeouts; - /* Number of write timeouts so far */ - unsigned int write_timeouts; - /* Number of alerts received so far */ - unsigned int num_alerts; -}; - typedef struct hm_fragment_st { struct hm_header_st msg_header; unsigned char *fragment; @@ -1786,7 +1913,8 @@ typedef struct dtls1_state_st { size_t mtu; /* max DTLS packet size */ struct hm_header_st w_msg_hdr; struct hm_header_st r_msg_hdr; - struct dtls1_timeout_st timeout; + /* Number of alerts received so far */ + unsigned int timeout_num_alerts; /* * Indicates when the last handshake msg sent will timeout */ @@ -1803,14 +1931,12 @@ typedef struct dtls1_state_st { } DTLS1_STATE; -# ifndef OPENSSL_NO_EC /* * From ECC-TLS draft, used in encoding the curve type in ECParameters */ # define EXPLICIT_PRIME_CURVE_TYPE 1 # define EXPLICIT_CHAR2_CURVE_TYPE 2 # define NAMED_CURVE_TYPE 3 -# endif /* OPENSSL_NO_EC */ struct cert_pkey_st { X509 *x509; @@ -1883,11 +2009,10 @@ typedef struct cert_st { * an index, not a pointer. */ CERT_PKEY *key; -# ifndef OPENSSL_NO_DH + EVP_PKEY *dh_tmp; DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize); int dh_tmp_auto; -# endif /* Flags related to certificates */ uint32_t cert_flags; CERT_PKEY pkeys[SSL_PKEY_NUM]; @@ -1950,7 +2075,7 @@ typedef struct cert_st { * of a mess of functions, but hell, think of it as an opaque structure :-) */ typedef struct ssl3_enc_method { - int (*enc) (SSL *, SSL3_RECORD *, size_t, int); + int (*enc) (SSL *, SSL3_RECORD *, size_t, int, SSL_MAC_BUF *, size_t); int (*mac) (SSL *, SSL3_RECORD *, unsigned char *, int); int (*setup_key_block) (SSL *); int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *, @@ -2042,6 +2167,8 @@ typedef enum downgrade_en { #define TLSEXT_SIGALG_dsa_sha512 0x0602 #define TLSEXT_SIGALG_dsa_sha224 0x0302 #define TLSEXT_SIGALG_dsa_sha1 0x0202 +#define TLSEXT_SIGALG_gostr34102012_256_intrinsic 0x0840 +#define TLSEXT_SIGALG_gostr34102012_512_intrinsic 0x0841 #define TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 0xeeee #define TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 0xefef #define TLSEXT_SIGALG_gostr34102001_gostr3411 0xeded @@ -2060,8 +2187,8 @@ typedef enum downgrade_en { #define TLSEXT_KEX_MODE_FLAG_KE 1 #define TLSEXT_KEX_MODE_FLAG_KE_DHE 2 -#define SSL_USE_PSS(s) (s->s3->tmp.peer_sigalg != NULL && \ - s->s3->tmp.peer_sigalg->sig == EVP_PKEY_RSA_PSS) +#define SSL_USE_PSS(s) (s->s3.tmp.peer_sigalg != NULL && \ + s->s3.tmp.peer_sigalg->sig == EVP_PKEY_RSA_PSS) /* A dummy signature value not valid for TLSv1.2 signature algs */ #define TLSEXT_signature_rsa_pss 0x0101 @@ -2261,12 +2388,12 @@ __owur int ssl_get_new_session(SSL *s, int session); __owur SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, size_t sess_id_len); __owur int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello); -__owur SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); +__owur SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket); __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); __owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, const SSL_CIPHER *const *bp); -__owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, +__owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx, STACK_OF(SSL_CIPHER) *tls13_ciphersuites, STACK_OF(SSL_CIPHER) **cipher_list, STACK_OF(SSL_CIPHER) **cipher_list_by_id, @@ -2278,14 +2405,16 @@ __owur int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, STACK_OF(SSL_CIPHER) **scsvs, int sslv2format, int fatal); void ssl_update_cache(SSL *s, int mode); -__owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, - size_t *mac_secret_size, SSL_COMP **comp, - int use_etm); +__owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc); +__owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s, + const EVP_CIPHER **enc, const EVP_MD **md, + int *mac_pkey_type, size_t *mac_secret_size, + SSL_COMP **comp, int use_etm); __owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, size_t *int_overhead, size_t *blocksize, size_t *ext_overhead); -__owur int ssl_cert_is_disabled(size_t idx); +__owur int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx); __owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr, int all); @@ -2323,15 +2452,26 @@ void ssl_set_masks(SSL *s); __owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); __owur int ssl_x509err2alert(int type); void ssl_sort_cipher_list(void); -int ssl_load_ciphers(void); +int ssl_load_ciphers(SSL_CTX *ctx); +__owur int ssl_setup_sig_algs(SSL_CTX *ctx); +int ssl_load_groups(SSL_CTX *ctx); __owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, size_t len, DOWNGRADE dgrd); __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, int free_pms); -__owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm); +__owur EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm); +__owur int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen); __owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int genmaster); +__owur int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, + const unsigned char *ct, size_t ctlen, + int gensecret); +__owur int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, + unsigned char **ctp, size_t *ctlenp, + int gensecret); __owur EVP_PKEY *ssl_dh_to_pkey(DH *dh); +__owur int ssl_set_tmp_ecdh_groups(uint16_t **pext, size_t *pextlen, + void *key); __owur unsigned int ssl_get_max_send_fragment(const SSL *ssl); __owur unsigned int ssl_get_split_send_fragment(const SSL *ssl); @@ -2354,6 +2494,8 @@ __owur int ssl3_num_ciphers(void); __owur const SSL_CIPHER *ssl3_get_cipher(unsigned int u); int ssl3_renegotiate(SSL *ssl); int ssl3_renegotiate_check(SSL *ssl, int initok); +void ssl3_digest_master_key_set_params(const SSL_SESSION *session, + OSSL_PARAM params[]); __owur int ssl3_dispatch_alert(SSL *s); __owur size_t ssl3_final_finish_mac(SSL *s, const char *sender, size_t slen, unsigned char *p); @@ -2503,29 +2645,28 @@ __owur int tls1_alert_code(int code); __owur int tls13_alert_code(int code); __owur int ssl3_alert_code(int code); -# ifndef OPENSSL_NO_EC __owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); -# endif SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); -# ifndef OPENSSL_NO_EC - -__owur const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t curve_id); +__owur const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t curve_id); +__owur int tls1_group_id2nid(uint16_t group_id, int include_unknown); +__owur uint16_t tls1_nid2group_id(int nid); __owur int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_curves); __owur uint16_t tls1_shared_group(SSL *s, int nmatch); __owur int tls1_set_groups(uint16_t **pext, size_t *pextlen, int *curves, size_t ncurves); -__owur int tls1_set_groups_list(uint16_t **pext, size_t *pextlen, +__owur int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen, const char *str); +__owur EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id); +__owur int tls_valid_group(SSL *s, uint16_t group_id, int minversion, + int maxversion, int isec, int *okfortls13); +__owur EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id); void tls1_get_formatlist(SSL *s, const unsigned char **pformats, size_t *num_formats); __owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id); -__owur EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id); -__owur EVP_PKEY *ssl_generate_param_group(uint16_t id); -# endif /* OPENSSL_NO_EC */ -__owur int tls_curve_allowed(SSL *s, uint16_t curve, int op); +__owur int tls_group_allowed(SSL *s, uint16_t curve, int op); void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, size_t *pgroupslen); @@ -2555,9 +2696,7 @@ void tls1_set_cert_validity(SSL *s); __owur int ssl_validate_ct(SSL *s); # endif -# ifndef OPENSSL_NO_DH -__owur DH *ssl_get_auto_dh(SSL *s); -# endif +__owur EVP_PKEY *ssl_get_auto_dh(SSL *s); __owur int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee); __owur int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *ex, @@ -2574,18 +2713,17 @@ __owur int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen); __owur int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert); __owur int tls1_process_sigalgs(SSL *s); __owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey); -__owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd); +__owur int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, + const EVP_MD **pmd); __owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs); -# ifndef OPENSSL_NO_EC __owur int tls_check_sigalg_curve(const SSL *s, int curve); -# endif __owur int tls12_check_peer_sigalg(SSL *s, uint16_t, EVP_PKEY *pkey); __owur int ssl_set_client_disabled(SSL *s); __owur int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int echde); __owur int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen, size_t *hashlen); -__owur const EVP_MD *ssl_md(int idx); +__owur const EVP_MD *ssl_md(SSL_CTX *ctx, int idx); __owur const EVP_MD *ssl_handshake_md(SSL *s); __owur const EVP_MD *ssl_prf_md(SSL *s); @@ -2614,18 +2752,31 @@ __owur int ssl_log_secret(SSL *ssl, const char *label, #define CLIENT_HANDSHAKE_LABEL "CLIENT_HANDSHAKE_TRAFFIC_SECRET" #define SERVER_HANDSHAKE_LABEL "SERVER_HANDSHAKE_TRAFFIC_SECRET" #define CLIENT_APPLICATION_LABEL "CLIENT_TRAFFIC_SECRET_0" +#define CLIENT_APPLICATION_N_LABEL "CLIENT_TRAFFIC_SECRET_N" #define SERVER_APPLICATION_LABEL "SERVER_TRAFFIC_SECRET_0" +#define SERVER_APPLICATION_N_LABEL "SERVER_TRAFFIC_SECRET_N" #define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET" #define EXPORTER_SECRET_LABEL "EXPORTER_SECRET" +# ifndef OPENSSL_NO_KTLS +/* ktls.c */ +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd); +int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, + void *rl_sequence, ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key, unsigned char *mac_key, + size_t mac_secret_size); +# endif + /* s3_cbc.c */ __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -__owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, +__owur int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char *md_out, size_t *md_out_size, const unsigned char *header, const unsigned char *data, - size_t data_plus_mac_size, + size_t data_size, size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, size_t mac_secret_length, char is_sslv3); @@ -2663,10 +2814,73 @@ void ssl_comp_free_compression_methods_int(void); /* ssl_mcnf.c */ void ssl_ctx_system_config(SSL_CTX *ctx); +const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx, + int nid, + const char *properties); +int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher); +void ssl_evp_cipher_free(const EVP_CIPHER *cipher); +const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx, + int nid, + const char *properties); +int ssl_evp_md_up_ref(const EVP_MD *md); +void ssl_evp_md_free(const EVP_MD *md); + +int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *ciph, + const EVP_MD *md); + +void tls_engine_finish(ENGINE *e); +const EVP_CIPHER *tls_get_cipher_from_engine(int nid); +const EVP_MD *tls_get_digest_from_engine(int nid); +int tls_engine_load_ssl_client_cert(SSL *s, X509 **px509, EVP_PKEY **ppkey); +int ssl_hmac_old_new(SSL_HMAC *ret); +void ssl_hmac_old_free(SSL_HMAC *ctx); +int ssl_hmac_old_init(SSL_HMAC *ctx, void *key, size_t len, char *md); +int ssl_hmac_old_update(SSL_HMAC *ctx, const unsigned char *data, size_t len); +int ssl_hmac_old_final(SSL_HMAC *ctx, unsigned char *md, size_t *len); +size_t ssl_hmac_old_size(const SSL_HMAC *ctx); + +int ssl_ctx_srp_ctx_free_intern(SSL_CTX *ctx); +int ssl_ctx_srp_ctx_init_intern(SSL_CTX *ctx); +int ssl_srp_ctx_free_intern(SSL *s); +int ssl_srp_ctx_init_intern(SSL *s); + +int ssl_srp_calc_a_param_intern(SSL *s); +int ssl_srp_server_param_with_username_intern(SSL *s, int *ad); + +void ssl_session_calculate_timeout(SSL_SESSION* ss); + # else /* OPENSSL_UNIT_TEST */ # define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer # define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers # endif + +/* Some helper routines to support TSAN operations safely */ +static ossl_unused ossl_inline int ssl_tsan_lock(const SSL_CTX *ctx) +{ +#ifdef TSAN_REQUIRES_LOCKING + if (!CRYPTO_THREAD_write_lock(ctx->tsan_lock)) + return 0; +#endif + return 1; +} + +static ossl_unused ossl_inline void ssl_tsan_unlock(const SSL_CTX *ctx) +{ +#ifdef TSAN_REQUIRES_LOCKING + CRYPTO_THREAD_unlock(ctx->tsan_lock); +#endif +} + +static ossl_unused ossl_inline void ssl_tsan_counter(const SSL_CTX *ctx, + TSAN_QUALIFIER int *stat) +{ + if (ssl_tsan_lock(ctx)) { + tsan_counter(stat); + ssl_tsan_unlock(ctx); + } +} + #endif diff --git a/ssl/ssl_mcnf.c b/ssl/ssl_mcnf.c index 583df4166908..c2366e41e365 100644 --- a/ssl/ssl_mcnf.c +++ b/ssl/ssl_mcnf.c @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. 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 @@ -28,19 +28,20 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) unsigned int flags; const SSL_METHOD *meth; const SSL_CONF_CMD *cmds; + OSSL_LIB_CTX *prev_libctx = NULL; + OSSL_LIB_CTX *libctx = NULL; if (s == NULL && ctx == NULL) { - SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); goto err; } if (name == NULL && system) name = "system_default"; if (!conf_ssl_name_find(name, &idx)) { - if (!system) { - SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_INVALID_CONFIGURATION_NAME); - ERR_add_error_data(2, "name=", name); - } + if (!system) + ERR_raise_data(ERR_LIB_SSL, SSL_R_INVALID_CONFIGURATION_NAME, + "name=%s", name); goto err; } cmds = conf_ssl_get(idx, &name, &cmd_count); @@ -53,32 +54,34 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) if (s != NULL) { meth = s->method; SSL_CONF_CTX_set_ssl(cctx, s); + libctx = s->ctx->libctx; } else { meth = ctx->method; SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); + libctx = ctx->libctx; } if (meth->ssl_accept != ssl_undefined_function) flags |= SSL_CONF_FLAG_SERVER; if (meth->ssl_connect != ssl_undefined_function) flags |= SSL_CONF_FLAG_CLIENT; SSL_CONF_CTX_set_flags(cctx, flags); + prev_libctx = OSSL_LIB_CTX_set0_default(libctx); for (i = 0; i < cmd_count; i++) { char *cmdstr, *arg; conf_ssl_get_cmd(cmds, i, &cmdstr, &arg); rv = SSL_CONF_cmd(cctx, cmdstr, arg); if (rv <= 0) { - if (rv == -2) - SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_UNKNOWN_COMMAND); - else - SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_BAD_VALUE); - ERR_add_error_data(6, "section=", name, ", cmd=", cmdstr, - ", arg=", arg); + int errcode = rv == -2 ? SSL_R_UNKNOWN_COMMAND : SSL_R_BAD_VALUE; + + ERR_raise_data(ERR_LIB_SSL, errcode, + "section=%s, cmd=%s, arg=%s", name, cmdstr, arg); goto err; } } rv = SSL_CONF_CTX_finish(cctx); err: + OSSL_LIB_CTX_set0_default(prev_libctx); SSL_CONF_CTX_free(cctx); return rv <= 0 ? 0 : 1; } diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 2df07bea6782..4f45e60535d2 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. 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 @@ -9,11 +9,12 @@ #include <stdio.h> #include "ssl_local.h" -#include "packet_local.h" +#include "internal/packet.h" #include <openssl/bio.h> #include <openssl/objects.h> #include <openssl/evp.h> #include <openssl/x509.h> +#include <openssl/x509v3.h> #include <openssl/pem.h> static int ssl_set_cert(CERT *c, X509 *x509); @@ -28,12 +29,13 @@ int SSL_use_certificate(SSL *ssl, X509 *x) { int rv; if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } + rv = ssl_security_cert(ssl, NULL, x, 0, 1); if (rv != 1) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv); + ERR_raise(ERR_LIB_SSL, rv); return 0; } @@ -45,32 +47,42 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) int j; BIO *in; int ret = 0; - X509 *x = NULL; + X509 *cert = NULL, *x = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) { + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq); + if (x == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); + cert = d2i_X509_bio(in, &x); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ssl->default_passwd_callback, - ssl->default_passwd_callback_userdata); + cert = PEM_read_bio_X509(in, &x, ssl->default_passwd_callback, + ssl->default_passwd_callback_userdata); } else { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); + if (cert == NULL) { + ERR_raise(ERR_LIB_SSL, j); goto end; } @@ -86,74 +98,35 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) X509 *x; int ret; - x = d2i_X509(NULL, &d, (long)len); + x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq); if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } - ret = SSL_use_certificate(ssl, x); - X509_free(x); - return ret; -} - -#ifndef OPENSSL_NO_RSA -int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) -{ - EVP_PKEY *pkey; - int ret; - - if (rsa == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if ((pkey = EVP_PKEY_new()) == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + if (d2i_X509(&x, &d, (long)len)== NULL) { + X509_free(x); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); return 0; } - RSA_up_ref(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - RSA_free(rsa); - EVP_PKEY_free(pkey); - return 0; - } - - ret = ssl_set_pkey(ssl->cert, pkey); - EVP_PKEY_free(pkey); + ret = SSL_use_certificate(ssl, x); + X509_free(x); return ret; } -#endif static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { size_t i; if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { - SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } - if (c->pkeys[i].x509 != NULL) { - EVP_PKEY *pktmp; - pktmp = X509_get0_pubkey(c->pkeys[i].x509); - if (pktmp == NULL) { - SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); - return 0; - } - /* - * The return code from EVP_PKEY_copy_parameters is deliberately - * ignored. Some EVP_PKEY types cannot do this. - */ - EVP_PKEY_copy_parameters(pktmp, pkey); - ERR_clear_error(); - - if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { - X509_free(c->pkeys[i].x509); - c->pkeys[i].x509 = NULL; - return 0; - } - } + if (c->pkeys[i].x509 != NULL + && !X509_check_private_key(c->pkeys[i].x509, pkey)) + return 0; EVP_PKEY_free(c->pkeys[i].privatekey); EVP_PKEY_up_ref(pkey); @@ -162,70 +135,12 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) return 1; } -#ifndef OPENSSL_NO_RSA -int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, - ssl->default_passwd_callback, - ssl->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (rsa == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - end: - BIO_free(in); - return ret; -} - -int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) -{ - int ret; - const unsigned char *p; - RSA *rsa; - - p = d; - if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return 0; - } - - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - return ret; -} -#endif /* !OPENSSL_NO_RSA */ - int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { int ret; if (pkey == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } ret = ssl_set_pkey(ssl->cert, pkey); @@ -240,28 +155,31 @@ int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) in = BIO_new(BIO_s_file()); if (in == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, - ssl->default_passwd_callback, - ssl->default_passwd_callback_userdata); + pkey = PEM_read_bio_PrivateKey_ex(in, NULL, + ssl->default_passwd_callback, + ssl->default_passwd_callback_userdata, + ssl->ctx->libctx, + ssl->ctx->propq); } else if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); + pkey = d2i_PrivateKey_ex_bio(in, NULL, ssl->ctx->libctx, + ssl->ctx->propq); } else { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (pkey == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); + ERR_raise(ERR_LIB_SSL, j); goto end; } ret = SSL_use_PrivateKey(ssl, pkey); @@ -279,8 +197,9 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, EVP_PKEY *pkey; p = d; - if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + if ((pkey = d2i_PrivateKey_ex(type, NULL, &p, (long)len, ssl->ctx->libctx, + ssl->ctx->propq)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); return 0; } @@ -293,12 +212,13 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { int rv; if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } + rv = ssl_security_cert(NULL, ctx, x, 0, 1); if (rv != 1) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv); + ERR_raise(ERR_LIB_SSL, rv); return 0; } return ssl_set_cert(ctx->cert, x); @@ -311,20 +231,20 @@ static int ssl_set_cert(CERT *c, X509 *x) pkey = X509_get0_pubkey(x); if (pkey == NULL) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); + ERR_raise(ERR_LIB_SSL, SSL_R_X509_LIB); return 0; } if (ssl_cert_lookup_by_pkey(pkey, &i) == NULL) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } -#ifndef OPENSSL_NO_EC - if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); + + if (i == SSL_PKEY_ECC && !EVP_PKEY_can_sign(pkey)) { + ERR_raise(ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; } -#endif + if (c->pkeys[i].privatekey != NULL) { /* * The return code from EVP_PKEY_copy_parameters is deliberately @@ -356,35 +276,40 @@ static int ssl_set_cert(CERT *c, X509 *x) int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { - int j; + int j = SSL_R_BAD_VALUE; BIO *in; int ret = 0; - X509 *x = NULL; + X509 *x = NULL, *cert = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); + goto end; + } + if (type != SSL_FILETYPE_ASN1 && type != SSL_FILETYPE_PEM) { + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + x = X509_new_ex(ctx->libctx, ctx->propq); + if (x == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); + cert = d2i_X509_bio(in, &x); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; + cert = PEM_read_bio_X509(in, &x, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); } - - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); + if (cert == NULL) { + ERR_raise(ERR_LIB_SSL, j); goto end; } @@ -400,106 +325,27 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) X509 *x; int ret; - x = d2i_X509(NULL, &d, (long)len); + x = X509_new_ex(ctx->libctx, ctx->propq); if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); - return 0; - } - - ret = SSL_CTX_use_certificate(ctx, x); - X509_free(x); - return ret; -} - -#ifndef OPENSSL_NO_RSA -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) -{ - int ret; - EVP_PKEY *pkey; - - if (rsa == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if ((pkey = EVP_PKEY_new()) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } - RSA_up_ref(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - RSA_free(rsa); - EVP_PKEY_free(pkey); + if (d2i_X509(&x, &d, (long)len) == NULL) { + X509_free(x); + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); return 0; } - ret = ssl_set_pkey(ctx->cert, pkey); - EVP_PKEY_free(pkey); - return ret; -} - -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (rsa == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - end: - BIO_free(in); - return ret; -} - -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, - long len) -{ - int ret; - const unsigned char *p; - RSA *rsa; - - p = d; - if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return 0; - } - - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); + ret = SSL_CTX_use_certificate(ctx, x); + X509_free(x); return ret; } -#endif /* !OPENSSL_NO_RSA */ int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { if (pkey == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } return ssl_set_pkey(ctx->cert, pkey); @@ -513,28 +359,29 @@ int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) in = BIO_new(BIO_s_file()); if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, + pkey = PEM_read_bio_PrivateKey_ex(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); + ctx->default_passwd_callback_userdata, + ctx->libctx, ctx->propq); } else if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); + pkey = d2i_PrivateKey_ex_bio(in, NULL, ctx->libctx, ctx->propq); } else { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (pkey == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); + ERR_raise(ERR_LIB_SSL, j); goto end; } ret = SSL_CTX_use_PrivateKey(ctx, pkey); @@ -552,8 +399,9 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, EVP_PKEY *pkey; p = d; - if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + if ((pkey = d2i_PrivateKey_ex(type, NULL, &p, (long)len, ctx->libctx, + ctx->propq)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); return 0; } @@ -574,6 +422,10 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) X509 *x = NULL; pem_password_cb *passwd_callback; void *passwd_callback_userdata; + SSL_CTX *real_ctx = (ssl == NULL) ? ctx : ssl->ctx; + + if (ctx == NULL && ssl == NULL) + return 0; ERR_clear_error(); /* clear error stack for * SSL_CTX_use_certificate() */ @@ -588,19 +440,23 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) in = BIO_new(BIO_s_file()); if (in == NULL) { - SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); goto end; } - x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, - passwd_callback_userdata); + x = X509_new_ex(real_ctx->libctx, real_ctx->propq); if (x == NULL) { - SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto end; + } + if (PEM_read_bio_X509_AUX(in, &x, passwd_callback, + passwd_callback_userdata) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PEM_LIB); goto end; } @@ -631,23 +487,32 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) goto end; } - while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback, - passwd_callback_userdata)) - != NULL) { - if (ctx) - r = SSL_CTX_add0_chain_cert(ctx, ca); - else - r = SSL_add0_chain_cert(ssl, ca); - /* - * Note that we must not free ca if it was successfully added to - * the chain (while we must free the main certificate, since its - * reference count is increased by SSL_CTX_use_certificate). - */ - if (!r) { - X509_free(ca); - ret = 0; + while (1) { + ca = X509_new_ex(real_ctx->libctx, real_ctx->propq); + if (ca == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto end; } + if (PEM_read_bio_X509(in, &ca, passwd_callback, + passwd_callback_userdata) != NULL) { + if (ctx) + r = SSL_CTX_add0_chain_cert(ctx, ca); + else + r = SSL_add0_chain_cert(ssl, ca); + /* + * Note that we must not free ca if it was successfully added to + * the chain (while we must free the main certificate, since its + * reference count is increased by SSL_CTX_use_certificate). + */ + if (!r) { + X509_free(ca); + ret = 0; + goto end; + } + } else { + X509_free(ca); + break; + } } /* When the while loop ends, it's usually just EOF. */ err = ERR_peek_last_error(); @@ -727,34 +592,6 @@ static int serverinfoex_srv_parse_cb(SSL *s, unsigned int ext_type, return 1; } -static size_t extension_contextoff(unsigned int version) -{ - return version == SSL_SERVERINFOV1 ? 4 : 0; -} - -static size_t extension_append_length(unsigned int version, size_t extension_length) -{ - return extension_length + extension_contextoff(version); -} - -static void extension_append(unsigned int version, - const unsigned char *extension, - const size_t extension_length, - unsigned char *serverinfo) -{ - const size_t contextoff = extension_contextoff(version); - - if (contextoff > 0) { - /* We know this only uses the last 2 bytes */ - serverinfo[0] = 0; - serverinfo[1] = 0; - serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; - serverinfo[3] = SYNTHV1CONTEXT & 0xff; - } - - memcpy(serverinfo + contextoff, extension, extension_length); -} - static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *arg) @@ -866,6 +703,34 @@ static int serverinfo_process_buffer(unsigned int version, return 1; } +static size_t extension_contextoff(unsigned int version) +{ + return version == SSL_SERVERINFOV1 ? 4 : 0; +} + +static size_t extension_append_length(unsigned int version, size_t extension_length) +{ + return extension_length + extension_contextoff(version); +} + +static void extension_append(unsigned int version, + const unsigned char *extension, + const size_t extension_length, + unsigned char *serverinfo) +{ + const size_t contextoff = extension_contextoff(version); + + if (contextoff > 0) { + /* We know this only uses the last 2 bytes */ + serverinfo[0] = 0; + serverinfo[1] = 0; + serverinfo[2] = (SYNTHV1CONTEXT >> 8) & 0xff; + serverinfo[3] = SYNTHV1CONTEXT & 0xff; + } + + memcpy(serverinfo + contextoff, extension, extension_length); +} + int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, const unsigned char *serverinfo, size_t serverinfo_length) @@ -873,7 +738,7 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, unsigned char *new_serverinfo = NULL; if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (version == SSL_SERVERINFOV1) { @@ -888,7 +753,7 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, sinfo = OPENSSL_malloc(sinfo_length); if (sinfo == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -902,17 +767,17 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, } if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, NULL)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA); return 0; } if (ctx->cert->key == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, serverinfo_length); if (new_serverinfo == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } ctx->cert->key->serverinfo = new_serverinfo; @@ -925,7 +790,7 @@ int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, */ if (!serverinfo_process_buffer(version, serverinfo, serverinfo_length, ctx)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_EX, SSL_R_INVALID_SERVERINFO_DATA); + ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA); return 0; } return 1; @@ -947,24 +812,25 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) long extension_length = 0; char *name = NULL; char *header = NULL; - char namePrefix1[] = "SERVERINFO FOR "; - char namePrefix2[] = "SERVERINFOV2 FOR "; + static const char namePrefix1[] = "SERVERINFO FOR "; + static const char namePrefix2[] = "SERVERINFOV2 FOR "; + unsigned int name_len; int ret = 0; BIO *bin = NULL; size_t num_extensions = 0; if (ctx == NULL || file == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER); + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); goto end; } bin = BIO_new(BIO_s_file()); if (bin == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(bin, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); goto end; } @@ -978,28 +844,26 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) * There must be at least one extension in this file */ if (num_extensions == 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_NO_PEM_EXTENSIONS); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS); goto end; } else /* End of file, we're done */ break; } /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ - if (strlen(name) < strlen(namePrefix1)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT); + name_len = strlen(name); + if (name_len < sizeof(namePrefix1) - 1) { + ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT); goto end; } - if (strncmp(name, namePrefix1, strlen(namePrefix1)) == 0) { + if (strncmp(name, namePrefix1, sizeof(namePrefix1) - 1) == 0) { version = SSL_SERVERINFOV1; } else { - if (strlen(name) < strlen(namePrefix2)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_PEM_NAME_TOO_SHORT); + if (name_len < sizeof(namePrefix2) - 1) { + ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT); goto end; } - if (strncmp(name, namePrefix2, strlen(namePrefix2)) != 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_PEM_NAME_BAD_PREFIX); + if (strncmp(name, namePrefix2, sizeof(namePrefix2) - 1) != 0) { + ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX); goto end; } version = SSL_SERVERINFOV2; @@ -1012,7 +876,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) if (extension_length < 4 || (extension[2] << 8) + extension[3] != extension_length - 4) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_DATA); goto end; } } else { @@ -1020,7 +884,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) if (extension_length < 8 || (extension[6] << 8) + extension[7] != extension_length - 8) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_DATA); goto end; } } @@ -1028,7 +892,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) append_length = extension_append_length(version, extension_length); tmp = OPENSSL_realloc(serverinfo, serverinfo_length + append_length); if (tmp == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto end; } serverinfo = tmp; @@ -1070,13 +934,13 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr /* Do all security checks before anything else */ rv = ssl_security_cert(ssl, ctx, x509, 0, 1); if (rv != 1) { - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, rv); + ERR_raise(ERR_LIB_SSL, rv); goto out; } for (j = 0; j < sk_X509_num(chain); j++) { rv = ssl_security_cert(ssl, ctx, sk_X509_value(chain, j), 0, 0); if (rv != 1) { - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, rv); + ERR_raise(ERR_LIB_SSL, rv); goto out; } } @@ -1091,25 +955,31 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr if (EVP_PKEY_missing_parameters(privatekey)) { if (EVP_PKEY_missing_parameters(pubkey)) { /* nobody has parameters? - error */ - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_MISSING_PARAMETERS); + ERR_raise(ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS); goto out; } else { /* copy to privatekey from pubkey */ - EVP_PKEY_copy_parameters(privatekey, pubkey); + if (!EVP_PKEY_copy_parameters(privatekey, pubkey)) { + ERR_raise(ERR_LIB_SSL, SSL_R_COPY_PARAMETERS_FAILED); + goto out; + } } } else if (EVP_PKEY_missing_parameters(pubkey)) { /* copy to pubkey from privatekey */ - EVP_PKEY_copy_parameters(pubkey, privatekey); + if (!EVP_PKEY_copy_parameters(pubkey, privatekey)) { + ERR_raise(ERR_LIB_SSL, SSL_R_COPY_PARAMETERS_FAILED); + goto out; + } } /* else both have parameters */ /* check that key <-> cert match */ - if (EVP_PKEY_cmp(pubkey, privatekey) != 1) { - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); + if (EVP_PKEY_eq(pubkey, privatekey) != 1) { + ERR_raise(ERR_LIB_SSL, SSL_R_PRIVATE_KEY_MISMATCH); goto out; } } if (ssl_cert_lookup_by_pkey(pubkey, &i) == NULL) { - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + ERR_raise(ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); goto out; } @@ -1117,14 +987,14 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr || c->pkeys[i].privatekey != NULL || c->pkeys[i].chain != NULL)) { /* No override, and something already there */ - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_NOT_REPLACING_CERTIFICATE); + ERR_raise(ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE); goto out; } if (chain != NULL) { dup_chain = X509_chain_up_ref(chain); if (dup_chain == NULL) { - SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto out; } } diff --git a/ssl/ssl_rsa_legacy.c b/ssl/ssl_rsa_legacy.c new file mode 100644 index 000000000000..49cd7a3bbaa5 --- /dev/null +++ b/ssl/ssl_rsa_legacy.c @@ -0,0 +1,180 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * 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 + */ + +/* We need to use the deprecated RSA low level calls */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/ssl.h> + +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) +{ + EVP_PKEY *pkey; + int ret; + + if (rsa == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((pkey = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + RSA_up_ref(rsa); + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { + RSA_free(rsa); + EVP_PKEY_free(pkey); + return 0; + } + + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + return ret; +} + +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + SSL_get_default_passwd_cb(ssl), + SSL_get_default_passwd_cb_userdata(ssl)); + } else { + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + ERR_raise(ERR_LIB_SSL, j); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + end: + BIO_free(in); + return ret; +} + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); + return 0; + } + + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) +{ + int ret; + EVP_PKEY *pkey; + + if (rsa == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((pkey = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_EVP_LIB); + return 0; + } + + RSA_up_ref(rsa); + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { + RSA_free(rsa); + EVP_PKEY_free(pkey); + return 0; + } + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + SSL_CTX_get_default_passwd_cb(ctx), + SSL_CTX_get_default_passwd_cb_userdata(ctx)); + } else { + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + ERR_raise(ERR_LIB_SSL, j); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_ASN1_LIB); + return 0; + } + + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + return ret; +} diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index cda6b7cc5bcf..68b57a532bfe 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -1,13 +1,17 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. 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 */ +#if defined(__TANDEM) && defined(_SPT_MODEL_) +# include <spthread.h> +# include <spt_extensions.h> /* timeval */ +#endif #include <stdio.h> #include <openssl/rand.h> #include <openssl/engine.h> @@ -20,6 +24,58 @@ static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); +DEFINE_STACK_OF(SSL_SESSION) + +__owur static int sess_timedout(time_t t, SSL_SESSION *ss) +{ + /* if timeout overflowed, it can never timeout! */ + if (ss->timeout_ovf) + return 0; + return t > ss->calc_timeout; +} + +/* + * Returns -1/0/+1 as other XXXcmp-type functions + * Takes overflow of calculated timeout into consideration + */ +__owur static int timeoutcmp(SSL_SESSION *a, SSL_SESSION *b) +{ + /* if only one overflowed, then it is greater */ + if (a->timeout_ovf && !b->timeout_ovf) + return 1; + if (!a->timeout_ovf && b->timeout_ovf) + return -1; + /* No overflow, or both overflowed, so straight compare is safe */ + if (a->calc_timeout < b->calc_timeout) + return -1; + if (a->calc_timeout > b->calc_timeout) + return 1; + return 0; +} + +/* + * Calculates effective timeout, saving overflow state + * Locking must be done by the caller of this function + */ +void ssl_session_calculate_timeout(SSL_SESSION *ss) +{ + /* Force positive timeout */ + if (ss->timeout < 0) + ss->timeout = 0; + ss->calc_timeout = ss->time + ss->timeout; + /* + * |timeout| is always zero or positive, so the check for + * overflow only needs to consider if |time| is positive + */ + ss->timeout_ovf = ss->time > 0 && ss->calc_timeout < ss->time; + /* + * N.B. Realistic overflow can only occur in our lifetimes on a + * 32-bit machine in January 2038. + * However, There are no controls to limit the |timeout| + * value, except to keep it positive. + */ +} + /* * SSL_get_session() and SSL_get1_session() are problematic in TLS1.3 because, * unlike in earlier protocol versions, the session ticket may not have been @@ -44,7 +100,8 @@ SSL_SESSION *SSL_get1_session(SSL *ssl) * somebody doesn't free ssl->session between when we check it's non-null * and when we up the reference count. */ - CRYPTO_THREAD_read_lock(ssl->lock); + if (!CRYPTO_THREAD_read_lock(ssl->lock)) + return NULL; sess = ssl->session; if (sess) SSL_SESSION_up_ref(sess); @@ -71,17 +128,18 @@ SSL_SESSION *SSL_SESSION_new(void) ss = OPENSSL_zalloc(sizeof(*ss)); if (ss == NULL) { - SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ ss->references = 1; ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ - ss->time = (unsigned long)time(NULL); + ss->time = time(NULL); + ssl_session_calculate_timeout(ss); ss->lock = CRYPTO_THREAD_lock_new(); if (ss->lock == NULL) { - SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(ss); return NULL; } @@ -94,7 +152,7 @@ SSL_SESSION *SSL_SESSION_new(void) return ss; } -SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src) +SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src) { return ssl_session_dup(src, 1); } @@ -103,7 +161,7 @@ SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src) * Create a new SSL_SESSION and duplicate the contents of |src| into it. If * ticket == 0 then no ticket information is duplicated, otherwise it is. */ -SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) +SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) { SSL_SESSION *dest; @@ -218,7 +276,7 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) return dest; err: - SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); SSL_SESSION_free(dest); return NULL; } @@ -259,7 +317,7 @@ static int def_generate_session_id(SSL *ssl, unsigned char *id, { unsigned int retry = 0; do - if (RAND_bytes(id, *id_len) <= 0) + if (RAND_bytes_ex(ssl->ctx->libctx, id, *id_len, 0) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; @@ -294,8 +352,7 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; break; default: - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_SESSION_ID, - SSL_R_UNSUPPORTED_SSL_VERSION); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNSUPPORTED_SSL_VERSION); return 0; } @@ -320,8 +377,14 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) } /* Choose which callback will set the session ID */ - CRYPTO_THREAD_read_lock(s->lock); - CRYPTO_THREAD_read_lock(s->session_ctx->lock); + if (!CRYPTO_THREAD_read_lock(s->lock)) + return 0; + if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) { + CRYPTO_THREAD_unlock(s->lock); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); + return 0; + } if (s->generate_session_id) cb = s->generate_session_id; else if (s->session_ctx->generate_session_id) @@ -333,7 +396,7 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) tmp = (int)ss->session_id_length; if (!cb(s, ss->session_id, &tmp)) { /* The callback failed */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_SESSION_ID, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); return 0; } @@ -343,7 +406,7 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) */ if (tmp == 0 || tmp > ss->session_id_length) { /* The callback set an illegal length */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_SESSION_ID, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); return 0; } @@ -351,8 +414,7 @@ int ssl_generate_session_id(SSL *s, SSL_SESSION *ss) /* Finally, check for a conflict */ if (SSL_has_matching_session_id(s, ss->session_id, (unsigned int)ss->session_id_length)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GENERATE_SESSION_ID, - SSL_R_SSL_SESSION_ID_CONFLICT); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SSL_SESSION_ID_CONFLICT); return 0; } @@ -366,8 +428,7 @@ int ssl_get_new_session(SSL *s, int session) SSL_SESSION *ss = NULL; if ((ss = SSL_SESSION_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_NEW_SESSION, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } @@ -376,6 +437,7 @@ int ssl_get_new_session(SSL *s, int session) ss->timeout = SSL_get_default_timeout(s); else ss->timeout = s->session_ctx->session_timeout; + ssl_session_calculate_timeout(ss); SSL_SESSION_free(s->session); s->session = NULL; @@ -398,8 +460,7 @@ int ssl_get_new_session(SSL *s, int session) } if (s->sid_ctx_length > sizeof(ss->sid_ctx)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_NEW_SESSION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } @@ -410,7 +471,7 @@ int ssl_get_new_session(SSL *s, int session) ss->verify_result = X509_V_OK; /* If client supports extended master secret set it in session */ - if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) + if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) ss->flags |= SSL_SESS_FLAG_EXTMS; return 1; @@ -432,7 +493,8 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, memcpy(data.session_id, sess_id, sess_id_len); data.session_id_length = sess_id_len; - CRYPTO_THREAD_read_lock(s->session_ctx->lock); + if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) + return NULL; ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); if (ret != NULL) { /* don't allow other threads to steal it: */ @@ -440,7 +502,7 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, } CRYPTO_THREAD_unlock(s->session_ctx->lock); if (ret == NULL) - tsan_counter(&s->session_ctx->stats.sess_miss); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_miss); } if (ret == NULL && s->session_ctx->get_session_cb != NULL) { @@ -449,7 +511,8 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id, ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, ©); if (ret != NULL) { - tsan_counter(&s->session_ctx->stats.sess_cb_hit); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_cb_hit); /* * Increment reference count now if the session callback asks us @@ -527,8 +590,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) case SSL_TICKET_FATAL_ERR_MALLOC: case SSL_TICKET_FATAL_ERR_OTHER: fatal = 1; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_PREV_SESSION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; case SSL_TICKET_NONE: case SSL_TICKET_EMPTY: @@ -574,14 +636,14 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) * noticing). */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_PREV_SESSION, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); fatal = 1; goto err; } - if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ - tsan_counter(&s->session_ctx->stats.sess_timeout); + if (sess_timedout(time(NULL), ret)) { + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_timeout); if (try_session_cache) { /* session was from the cache, so remove it */ SSL_CTX_remove_session(s->session_ctx, ret); @@ -592,13 +654,12 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) /* Check extended master secret extension consistency */ if (ret->flags & SSL_SESS_FLAG_EXTMS) { /* If old session includes extms, but new does not: abort handshake */ - if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SSL_GET_PREV_SESSION, - SSL_R_INCONSISTENT_EXTMS); + if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS)) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INCONSISTENT_EXTMS); fatal = 1; goto err; } - } else if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) { + } else if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) { /* If new session includes extms, but old does not: do not resume */ goto err; } @@ -609,7 +670,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello) s->session = ret; } - tsan_counter(&s->session_ctx->stats.sess_hit); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_hit); s->verify_result = s->session->verify_result; return 1; @@ -649,7 +710,10 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) * if session c is in already in cache, we take back the increment later */ - CRYPTO_THREAD_write_lock(ctx->lock); + if (!CRYPTO_THREAD_write_lock(ctx->lock)) { + SSL_SESSION_free(c); + return 0; + } s = lh_SSL_SESSION_insert(ctx->sessions, c); /* @@ -679,34 +743,41 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) s = c; } - /* Put at the head of the queue unless it is already in the cache */ - if (s == NULL) - SSL_SESSION_list_add(ctx, c); + /* Adjust last used time, and add back into the cache at the appropriate spot */ + if (ctx->session_cache_mode & SSL_SESS_CACHE_UPDATE_TIME) { + c->time = time(NULL); + ssl_session_calculate_timeout(c); + } - if (s != NULL) { - /* - * existing cache entry -- decrement previously incremented reference - * count because it already takes into account the cache - */ - - SSL_SESSION_free(s); /* s == c */ - ret = 0; - } else { + if (s == NULL) { /* * new cache entry -- remove old ones if cache has become too large + * delete cache entry *before* add, so we don't remove the one we're adding! */ ret = 1; if (SSL_CTX_sess_get_cache_size(ctx) > 0) { - while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) { + while (SSL_CTX_sess_number(ctx) >= SSL_CTX_sess_get_cache_size(ctx)) { if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) break; else - tsan_counter(&ctx->stats.sess_cache_full); + ssl_tsan_counter(ctx, &ctx->stats.sess_cache_full); } } } + + SSL_SESSION_list_add(ctx, c); + + if (s != NULL) { + /* + * existing cache entry -- decrement previously incremented reference + * count because it already takes into account the cache + */ + + SSL_SESSION_free(s); /* s == c */ + ret = 0; + } CRYPTO_THREAD_unlock(ctx->lock); return ret; } @@ -722,8 +793,10 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) int ret = 0; if ((c != NULL) && (c->session_id_length != 0)) { - if (lck) - CRYPTO_THREAD_write_lock(ctx->lock); + if (lck) { + if (!CRYPTO_THREAD_write_lock(ctx->lock)) + return 0; + } if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) { ret = 1; r = lh_SSL_SESSION_delete(ctx->sessions, r); @@ -739,8 +812,7 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) if (ret) SSL_SESSION_free(r); - } else - ret = 0; + } return ret; } @@ -811,8 +883,7 @@ int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, unsigned int sid_len) { if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { - SSLerr(SSL_F_SSL_SESSION_SET1_ID, - SSL_R_SSL_SESSION_ID_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_TOO_LONG); return 0; } s->session_id_length = sid_len; @@ -823,9 +894,21 @@ int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) { - if (s == NULL) + time_t new_timeout = (time_t)t; + + if (s == NULL || t < 0) return 0; - s->timeout = t; + if (s->owner != NULL) { + if (!CRYPTO_THREAD_write_lock(s->owner->lock)) + return 0; + s->timeout = new_timeout; + ssl_session_calculate_timeout(s); + SSL_SESSION_list_add(s->owner, s); + CRYPTO_THREAD_unlock(s->owner->lock); + } else { + s->timeout = new_timeout; + ssl_session_calculate_timeout(s); + } return 1; } @@ -833,21 +916,33 @@ long SSL_SESSION_get_timeout(const SSL_SESSION *s) { if (s == NULL) return 0; - return s->timeout; + return (long)s->timeout; } long SSL_SESSION_get_time(const SSL_SESSION *s) { if (s == NULL) return 0; - return s->time; + return (long)s->time; } long SSL_SESSION_set_time(SSL_SESSION *s, long t) { + time_t new_time = (time_t)t; + if (s == NULL) return 0; - s->time = t; + if (s->owner != NULL) { + if (!CRYPTO_THREAD_write_lock(s->owner->lock)) + return 0; + s->time = new_time; + ssl_session_calculate_timeout(s); + SSL_SESSION_list_add(s->owner, s); + CRYPTO_THREAD_unlock(s->owner->lock); + } else { + s->time = new_time; + ssl_session_calculate_timeout(s); + } return t; } @@ -956,8 +1051,7 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len) { if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); return 0; } s->sid_ctx_length = sid_ctx_len; @@ -1023,7 +1117,7 @@ int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) s->ext.session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); if (s->ext.session_ticket == NULL) { - SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } @@ -1042,46 +1136,52 @@ int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) return 0; } -typedef struct timeout_param_st { - SSL_CTX *ctx; - long time; - LHASH_OF(SSL_SESSION) *cache; -} TIMEOUT_PARAM; - -static void timeout_cb(SSL_SESSION *s, TIMEOUT_PARAM *p) -{ - if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ - /* - * The reason we don't call SSL_CTX_remove_session() is to save on - * locking overhead - */ - (void)lh_SSL_SESSION_delete(p->cache, s); - SSL_SESSION_list_remove(p->ctx, s); - s->not_resumable = 1; - if (p->ctx->remove_session_cb != NULL) - p->ctx->remove_session_cb(p->ctx, s); - SSL_SESSION_free(s); - } -} - -IMPLEMENT_LHASH_DOALL_ARG(SSL_SESSION, TIMEOUT_PARAM); - void SSL_CTX_flush_sessions(SSL_CTX *s, long t) { + STACK_OF(SSL_SESSION) *sk; + SSL_SESSION *current; unsigned long i; - TIMEOUT_PARAM tp; - tp.ctx = s; - tp.cache = s->sessions; - if (tp.cache == NULL) + if (!CRYPTO_THREAD_write_lock(s->lock)) return; - tp.time = t; - CRYPTO_THREAD_write_lock(s->lock); + + sk = sk_SSL_SESSION_new_null(); i = lh_SSL_SESSION_get_down_load(s->sessions); lh_SSL_SESSION_set_down_load(s->sessions, 0); - lh_SSL_SESSION_doall_TIMEOUT_PARAM(tp.cache, timeout_cb, &tp); + + /* + * Iterate over the list from the back (oldest), and stop + * when a session can no longer be removed. + * Add the session to a temporary list to be freed outside + * the SSL_CTX lock. + * But still do the remove_session_cb() within the lock. + */ + while (s->session_cache_tail != NULL) { + current = s->session_cache_tail; + if (t == 0 || sess_timedout((time_t)t, current)) { + lh_SSL_SESSION_delete(s->sessions, current); + SSL_SESSION_list_remove(s, current); + current->not_resumable = 1; + if (s->remove_session_cb != NULL) + s->remove_session_cb(s, current); + /* + * Throw the session on a stack, it's entirely plausible + * that while freeing outside the critical section, the + * session could be re-added, so avoid using the next/prev + * pointers. If the stack failed to create, or the session + * couldn't be put on the stack, just free it here + */ + if (sk == NULL || !sk_SSL_SESSION_push(sk, current)) + SSL_SESSION_free(current); + } else { + break; + } + } + lh_SSL_SESSION_set_down_load(s->sessions, i); CRYPTO_THREAD_unlock(s->lock); + + sk_SSL_SESSION_pop_free(sk, SSL_SESSION_free); } int ssl_clear_bad_session(SSL *s) @@ -1123,10 +1223,13 @@ static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) } } s->prev = s->next = NULL; + s->owner = NULL; } static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) { + SSL_SESSION *next; + if ((s->next != NULL) && (s->prev != NULL)) SSL_SESSION_list_remove(ctx, s); @@ -1136,11 +1239,40 @@ static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) s->prev = (SSL_SESSION *)&(ctx->session_cache_head); s->next = (SSL_SESSION *)&(ctx->session_cache_tail); } else { - s->next = ctx->session_cache_head; - s->next->prev = s; - s->prev = (SSL_SESSION *)&(ctx->session_cache_head); - ctx->session_cache_head = s; + if (timeoutcmp(s, ctx->session_cache_head) >= 0) { + /* + * if we timeout after (or the same time as) the first + * session, put us first - usual case + */ + s->next = ctx->session_cache_head; + s->next->prev = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = s; + } else if (timeoutcmp(s, ctx->session_cache_tail) < 0) { + /* if we timeout before the last session, put us last */ + s->prev = ctx->session_cache_tail; + s->prev->next = s; + s->next = (SSL_SESSION *)&(ctx->session_cache_tail); + ctx->session_cache_tail = s; + } else { + /* + * we timeout somewhere in-between - if there is only + * one session in the cache it will be caught above + */ + next = ctx->session_cache_head->next; + while (next != (SSL_SESSION*)&(ctx->session_cache_tail)) { + if (timeoutcmp(s, next) >= 0) { + s->next = next; + s->prev = next->prev; + next->prev->next = s; + next->prev = s; + break; + } + next = next->next; + } + } } + s->owner = ctx; } void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, @@ -1202,24 +1334,6 @@ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, return ctx->client_cert_cb; } -#ifndef OPENSSL_NO_ENGINE -int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) -{ - if (!ENGINE_init(e)) { - SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); - return 0; - } - if (!ENGINE_get_ssl_client_cert_function(e)) { - SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, - SSL_R_NO_CLIENT_CERT_METHOD); - ENGINE_finish(e); - return 0; - } - ctx->client_cert_engine = e; - return 1; -} -#endif - void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*cb) (SSL *ssl, unsigned char *cookie, diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index ca51c0331c22..f2316f7c9850 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -1,8 +1,8 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. 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 @@ -137,9 +137,9 @@ const char *SSL_state_string(const SSL *s) case TLS_ST_CW_NEXT_PROTO: return "TWNP"; case TLS_ST_BEFORE: - return "PINIT "; + return "PINIT"; case TLS_ST_OK: - return "SSLOK "; + return "SSLOK"; case TLS_ST_CW_CLNT_HELLO: return "TWCH"; case TLS_ST_CR_SRVR_HELLO: @@ -201,7 +201,7 @@ const char *SSL_state_string(const SSL *s) case TLS_ST_CR_CERT_VRFY: return "TRSCV"; case TLS_ST_SW_CERT_VRFY: - return "TRSCV"; + return "TWSCV"; case TLS_ST_CR_HELLO_REQ: return "TRHR"; case TLS_ST_SW_KEY_UPDATE: @@ -221,7 +221,7 @@ const char *SSL_state_string(const SSL *s) case TLS_ST_SR_END_OF_EARLY_DATA: return "TWEOED"; default: - return "UNKWN "; + return "UNKWN"; } } diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c index 759e1873e6b1..212fe00962ea 100644 --- a/ssl/ssl_txt.c +++ b/ssl/ssl_txt.c @@ -2,7 +2,7 @@ * Copyright 1995-2022 The OpenSSL Project Authors. 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 @@ -19,7 +19,7 @@ int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) int ret; if ((b = BIO_new(BIO_s_file())) == NULL) { - SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB); return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); @@ -107,7 +107,6 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) if (x->ext.tick) { if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) goto err; - /* TODO(size_t): Convert this call */ if (BIO_dump_indent (bp, (const char *)x->ext.tick, (int)x->ext.ticklen, 4) <= 0) @@ -117,7 +116,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) if (x->compress_meth != 0) { SSL_COMP *comp = NULL; - if (!ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp, 0)) + if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, &comp, 0)) goto err; if (comp == NULL) { if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= 0) diff --git a/ssl/ssl_utst.c b/ssl/ssl_utst.c index 487f56e53935..690db6d49746 100644 --- a/ssl/ssl_utst.c +++ b/ssl/ssl_utst.c @@ -1,7 +1,7 @@ /* * Copyright 2014-2016 The OpenSSL Project Authors. 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 diff --git a/ssl/sslerr.h b/ssl/sslerr.h new file mode 100644 index 000000000000..5c5b760e3821 --- /dev/null +++ b/ssl/sslerr.h @@ -0,0 +1,27 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * 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 + */ + +#ifndef OSSL_SSLERR_H +# define OSSL_SSLERR_H +# pragma once + +# include <openssl/opensslconf.h> +# include <openssl/symhacks.h> + +# ifdef __cplusplus +extern "C" { +# endif + +int ossl_err_load_SSL_strings(void); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/ssl/statem/README b/ssl/statem/README deleted file mode 100644 index bafe33060c92..000000000000 --- a/ssl/statem/README +++ /dev/null @@ -1,63 +0,0 @@ -State Machine Design -==================== - -This file provides some guidance on the thinking behind the design of the -state machine code to aid future maintenance. - -The state machine code replaces an older state machine present in OpenSSL -versions 1.0.2 and below. The new state machine has the following objectives: - - Remove duplication of state code between client and server - - Remove duplication of state code between TLS and DTLS - - Simplify transitions and bring the logic together in a single location - so that it is easier to validate - - Remove duplication of code between each of the message handling functions - - Receive a message first and then work out whether that is a valid - transition - not the other way around (the other way causes lots of issues - where we are expecting one type of message next but actually get something - else) - - Separate message flow state from handshake state (in order to better - understand each) - - message flow state = when to flush buffers; handling restarts in the - event of NBIO events; handling the common flow of steps for reading a - message and the common flow of steps for writing a message etc - - handshake state = what handshake message are we working on now - - Control complexity: only the state machine can change state: keep all - the state changes local to the state machine component - -The message flow state machine is divided into a reading sub-state machine and a -writing sub-state machine. See the source comments in statem.c for a more -detailed description of the various states and transitions possible. - -Conceptually the state machine component is designed as follows: - - libssl - | ----------------------------|-----statem.h-------------------------------------- - | - _______V____________________ - | | - | statem.c | - | | - | Core state machine code | - |____________________________| - statem_local.h ^ ^ - _________| |_______ - | | - _____________|____________ _____________|____________ - | | | | - | statem_clnt.c | | statem_srvr.c | - | | | | - | TLS/DTLS client specific | | TLS/DTLS server specific | - | state machine code | | state machine code | - |__________________________| |__________________________| - | |_______________|__ | - | ________________| | | - | | | | - ____________V_______V________ ________V______V_______________ - | | | | - | statem_lib.c | | statem_dtls.c | - | | | | - | Non core functions common | | Non core functions common to | - | to both servers and clients | | both DTLS servers and clients | - |_____________________________| |_______________________________| - diff --git a/ssl/statem/README.md b/ssl/statem/README.md new file mode 100644 index 000000000000..ee49ed986371 --- /dev/null +++ b/ssl/statem/README.md @@ -0,0 +1,63 @@ +State Machine Design +==================== + +This file provides some guidance on the thinking behind the design of the +state machine code to aid future maintenance. + +The state machine code replaces an older state machine present in OpenSSL +versions 1.0.2 and below. The new state machine has the following objectives: + + - Remove duplication of state code between client and server + - Remove duplication of state code between TLS and DTLS + - Simplify transitions and bring the logic together in a single location + so that it is easier to validate + - Remove duplication of code between each of the message handling functions + - Receive a message first and then work out whether that is a valid + transition - not the other way around (the other way causes lots of issues + where we are expecting one type of message next but actually get something + else) + - Separate message flow state from handshake state (in order to better + understand each) + * message flow state = when to flush buffers; handling restarts in the + event of NBIO events; handling the common flow of steps for reading a + message and the common flow of steps for writing a message etc + * handshake state = what handshake message are we working on now + - Control complexity: only the state machine can change state: keep all + the state changes local to the state machine component + +The message flow state machine is divided into a reading sub-state machine and a +writing sub-state machine. See the source comments in statem.c for a more +detailed description of the various states and transitions possible. + +Conceptually the state machine component is designed as follows: + + libssl + | + -------------------------|-----statem.h------------------------------------ + | + _______V____________________ + | | + | statem.c | + | | + | Core state machine code | + |____________________________| + statem_local.h ^ ^ + _________| |_______ + | | + _____________|____________ _____________|____________ + | | | | + | statem_clnt.c | | statem_srvr.c | + | | | | + | TLS/DTLS client specific | | TLS/DTLS server specific | + | state machine code | | state machine code | + |__________________________| |__________________________| + | |_______________|__ | + | ________________| | | + | | | | + ____________V_______V________ ________V______V_______________ + | | | | + | statem_lib.c | | statem_dtls.c | + | | | | + | Non core functions common | | Non core functions common to | + | to both servers and clients | | both DTLS servers and clients | + |_____________________________| |_______________________________| diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 0f39275baa01..8c9c16ec2120 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1,12 +1,17 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2022 The OpenSSL Project Authors. 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 */ +#if defined(__TANDEM) && defined(_SPT_MODEL_) +# include <spthread.h> +# include <spt_extensions.h> /* timeval */ +#endif + #include <string.h> #include "internal/nelem.h" #include "internal/cryptlib.h" @@ -17,10 +22,7 @@ static int final_renegotiate(SSL *s, unsigned int context, int sent); static int init_server_name(SSL *s, unsigned int context); static int final_server_name(SSL *s, unsigned int context, int sent); -#ifndef OPENSSL_NO_EC -static int init_ec_point_formats(SSL *s, unsigned int context); static int final_ec_pt_formats(SSL *s, unsigned int context, int sent); -#endif static int init_session_ticket(SSL *s, unsigned int context); #ifndef OPENSSL_NO_OCSP static int init_status_request(SSL *s, unsigned int context); @@ -43,13 +45,12 @@ static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, #ifndef OPENSSL_NO_SRP static int init_srp(SSL *s, unsigned int context); #endif +static int init_ec_point_formats(SSL *s, unsigned int context); static int init_etm(SSL *s, unsigned int context); static int init_ems(SSL *s, unsigned int context); static int final_ems(SSL *s, unsigned int context, int sent); static int init_psk_kex_modes(SSL *s, unsigned int context); -#ifndef OPENSSL_NO_EC static int final_key_share(SSL *s, unsigned int context, int sent); -#endif #ifndef OPENSSL_NO_SRTP static int init_srtp(SSL *s, unsigned int context); #endif @@ -97,6 +98,9 @@ typedef struct extensions_definition_st { * Definitions of all built-in extensions. NOTE: Changes in the number or order * of these extensions should be mirrored with equivalent changes to the * indexes ( TLSEXT_IDX_* ) defined in ssl_local.h. + * Extensions should be added to test/ext_internal_test.c as well, as that + * tests the ordering of the extensions. + * * Each extension has an initialiser, a client and * server side parser and a finaliser. The initialiser is called (if the * extension is relevant to the given context) even if we did not see the @@ -114,12 +118,10 @@ typedef struct extensions_definition_st { * messages the extension is relevant to. These flags also specify whether the * extension is relevant to a particular protocol or protocol version. * - * TODO(TLS1.3): Make sure we have a test to check the consistency of these - * * NOTE: WebSphere Application Server 7+ cannot handle empty extensions at * the end, keep these extensions before signature_algorithm. */ -#define INVALID_EXTENSION { 0x10000, 0, NULL, NULL, NULL, NULL, NULL, NULL } +#define INVALID_EXTENSION { TLSEXT_TYPE_invalid, 0, NULL, NULL, NULL, NULL, NULL, NULL } static const EXTENSION_DEFINITION ext_defs[] = { { TLSEXT_TYPE_renegotiate, @@ -155,7 +157,6 @@ static const EXTENSION_DEFINITION ext_defs[] = { #else INVALID_EXTENSION, #endif -#ifndef OPENSSL_NO_EC { TLSEXT_TYPE_ec_point_formats, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO @@ -197,10 +198,6 @@ static const EXTENSION_DEFINITION ext_defs[] = { tls_construct_stoc_supported_groups, tls_construct_ctos_supported_groups, NULL }, -#else - INVALID_EXTENSION, - INVALID_EXTENSION, -#endif { TLSEXT_TYPE_session_ticket, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO @@ -324,7 +321,6 @@ static const EXTENSION_DEFINITION ext_defs[] = { init_psk_kex_modes, tls_parse_ctos_psk_kex_modes, NULL, NULL, tls_construct_ctos_psk_kex_modes, NULL }, -#ifndef OPENSSL_NO_EC { /* * Must be in this list after supported_groups. We need that to have @@ -338,9 +334,6 @@ static const EXTENSION_DEFINITION ext_defs[] = { tls_construct_stoc_key_share, tls_construct_ctos_key_share, final_key_share }, -#else - INVALID_EXTENSION, -#endif { /* Must be after key_share */ TLSEXT_TYPE_cookie, @@ -395,6 +388,17 @@ static const EXTENSION_DEFINITION ext_defs[] = { } }; +/* Returns a TLSEXT_TYPE for the given index */ +unsigned int ossl_get_extension_type(size_t idx) +{ + size_t num_exts = OSSL_NELEM(ext_defs); + + if (idx >= num_exts) + return TLSEXT_TYPE_out_of_range; + + return ext_defs[idx].type; +} + /* Check whether an extension's context matches the current context */ static int validate_context(SSL *s, unsigned int extctx, unsigned int thisctx) { @@ -576,8 +580,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, num_exts = OSSL_NELEM(ext_defs) + (exts != NULL ? exts->meths_count : 0); raw_extensions = OPENSSL_zalloc(num_exts * sizeof(*raw_extensions)); if (raw_extensions == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_COLLECT_EXTENSIONS, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } @@ -589,8 +592,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, if (!PACKET_get_net_2(&extensions, &type) || !PACKET_get_length_prefixed_2(&extensions, &extension)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_COLLECT_EXTENSIONS, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); goto err; } /* @@ -603,8 +605,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, || (type == TLSEXT_TYPE_psk && (context & SSL_EXT_CLIENT_HELLO) != 0 && PACKET_remaining(&extensions) != 0)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_COLLECT_EXTENSIONS, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); goto err; } idx = thisex - raw_extensions; @@ -634,9 +635,9 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, && !((context & SSL_EXT_TLS1_2_SERVER_HELLO) != 0 && type == TLSEXT_TYPE_cryptopro_bug) #endif - ) { + ) { SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, - SSL_F_TLS_COLLECT_EXTENSIONS, SSL_R_UNSOLICITED_EXTENSION); + SSL_R_UNSOLICITED_EXTENSION); goto err; } if (thisex != NULL) { @@ -815,16 +816,14 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0 && !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_EXTENSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if ((context & SSL_EXT_CLIENT_HELLO) != 0) { reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_EXTENSIONS, - reason); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason); return 0; } } @@ -867,8 +866,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, } if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_EXTENSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -892,7 +890,7 @@ static int final_renegotiate(SSL *s, unsigned int context, int sent) if (!(s->options & SSL_OP_LEGACY_SERVER_CONNECT) && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && !sent) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_RENEGOTIATE, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); return 0; } @@ -904,7 +902,7 @@ static int final_renegotiate(SSL *s, unsigned int context, int sent) if (s->renegotiate && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && !sent) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_RENEGOTIATE, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); return 0; } @@ -913,6 +911,15 @@ static int final_renegotiate(SSL *s, unsigned int context, int sent) return 1; } +static ossl_inline void ssl_tsan_decr(const SSL_CTX *ctx, + TSAN_QUALIFIER int *stat) +{ + if (ssl_tsan_lock(ctx)) { + tsan_decr(stat); + ssl_tsan_unlock(ctx); + } +} + static int init_server_name(SSL *s, unsigned int context) { if (s->server) { @@ -932,8 +939,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent) int was_ticket = (SSL_get_options(s) & SSL_OP_NO_TICKET) == 0; if (!ossl_assert(s->ctx != NULL) || !ossl_assert(s->session_ctx != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -958,8 +964,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent) OPENSSL_free(s->session->ext.hostname); s->session->ext.hostname = OPENSSL_strdup(s->ext.hostname); if (s->session->ext.hostname == NULL && s->ext.hostname != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); } } } @@ -971,9 +976,9 @@ static int final_server_name(SSL *s, unsigned int context, int sent) * exceed sess_accept (zero) for the new context. */ if (SSL_IS_FIRST_HANDSHAKE(s) && s->ctx != s->session_ctx - && s->hello_retry_request == SSL_HRR_NONE) { - tsan_counter(&s->ctx->stats.sess_accept); - tsan_decr(&s->session_ctx->stats.sess_accept); + && s->hello_retry_request == SSL_HRR_NONE) { + ssl_tsan_counter(s->ctx, &s->ctx->stats.sess_accept); + ssl_tsan_decr(s->session_ctx, &s->session_ctx->stats.sess_accept); } /* @@ -994,13 +999,11 @@ static int final_server_name(SSL *s, unsigned int context, int sent) ss->ext.tick_lifetime_hint = 0; ss->ext.tick_age_add = 0; if (!ssl_generate_session_id(s, ss)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -1008,7 +1011,7 @@ static int final_server_name(SSL *s, unsigned int context, int sent) switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: - SSLfatal(s, altmp, SSL_F_FINAL_SERVER_NAME, SSL_R_CALLBACK_FAILED); + SSLfatal(s, altmp, SSL_R_CALLBACK_FAILED); return 0; case SSL_TLSEXT_ERR_ALERT_WARNING: @@ -1027,16 +1030,6 @@ static int final_server_name(SSL *s, unsigned int context, int sent) } } -#ifndef OPENSSL_NO_EC -static int init_ec_point_formats(SSL *s, unsigned int context) -{ - OPENSSL_free(s->ext.peer_ecpointformats); - s->ext.peer_ecpointformats = NULL; - s->ext.peer_ecpointformats_len = 0; - - return 1; -} - static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) { unsigned long alg_k, alg_a; @@ -1044,8 +1037,8 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) if (s->server) return 1; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_k = s->s3.tmp.new_cipher->algorithm_mkey; + alg_a = s->s3.tmp.new_cipher->algorithm_auth; /* * If we are client and using an elliptic curve cryptography cipher @@ -1066,7 +1059,7 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) break; } if (i == s->ext.peer_ecpointformats_len) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_FINAL_EC_PT_FORMATS, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); return 0; } @@ -1074,7 +1067,6 @@ static int final_ec_pt_formats(SSL *s, unsigned int context, int sent) return 1; } -#endif static int init_session_ticket(SSL *s, unsigned int context) { @@ -1106,7 +1098,7 @@ static int init_status_request(SSL *s, unsigned int context) #ifndef OPENSSL_NO_NEXTPROTONEG static int init_npn(SSL *s, unsigned int context) { - s->s3->npn_seen = 0; + s->s3.npn_seen = 0; return 1; } @@ -1114,13 +1106,13 @@ static int init_npn(SSL *s, unsigned int context) static int init_alpn(SSL *s, unsigned int context) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - s->s3->alpn_selected_len = 0; + OPENSSL_free(s->s3.alpn_selected); + s->s3.alpn_selected = NULL; + s->s3.alpn_selected_len = 0; if (s->server) { - OPENSSL_free(s->s3->alpn_proposed); - s->s3->alpn_proposed = NULL; - s->s3->alpn_proposed_len = 0; + OPENSSL_free(s->s3.alpn_proposed); + s->s3.alpn_proposed = NULL; + s->s3.alpn_proposed_len = 0; } return 1; } @@ -1148,19 +1140,19 @@ static int final_alpn(SSL *s, unsigned int context, int sent) static int init_sig_algs(SSL *s, unsigned int context) { /* Clear any signature algorithms extension received */ - OPENSSL_free(s->s3->tmp.peer_sigalgs); - s->s3->tmp.peer_sigalgs = NULL; - s->s3->tmp.peer_sigalgslen = 0; + OPENSSL_free(s->s3.tmp.peer_sigalgs); + s->s3.tmp.peer_sigalgs = NULL; + s->s3.tmp.peer_sigalgslen = 0; return 1; } -static int init_sig_algs_cert(SSL *s, unsigned int context) +static int init_sig_algs_cert(SSL *s, ossl_unused unsigned int context) { /* Clear any signature algorithms extension received */ - OPENSSL_free(s->s3->tmp.peer_cert_sigalgs); - s->s3->tmp.peer_cert_sigalgs = NULL; - s->s3->tmp.peer_cert_sigalgslen = 0; + OPENSSL_free(s->s3.tmp.peer_cert_sigalgs); + s->s3.tmp.peer_cert_sigalgs = NULL; + s->s3.tmp.peer_cert_sigalgslen = 0; return 1; } @@ -1175,6 +1167,15 @@ static int init_srp(SSL *s, unsigned int context) } #endif +static int init_ec_point_formats(SSL *s, unsigned int context) +{ + OPENSSL_free(s->ext.peer_ecpointformats); + s->ext.peer_ecpointformats = NULL; + s->ext.peer_ecpointformats_len = 0; + + return 1; +} + static int init_etm(SSL *s, unsigned int context) { s->ext.use_etm = 0; @@ -1184,9 +1185,9 @@ static int init_etm(SSL *s, unsigned int context) static int init_ems(SSL *s, unsigned int context) { - if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) { - s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; - s->s3->flags |= TLS1_FLAGS_REQUIRED_EXTMS; + if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) { + s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; + s->s3.flags |= TLS1_FLAGS_REQUIRED_EXTMS; } return 1; @@ -1198,10 +1199,9 @@ static int final_ems(SSL *s, unsigned int context, int sent) * Check extended master secret extension is not dropped on * renegotiation. */ - if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) - && (s->s3->flags & TLS1_FLAGS_REQUIRED_EXTMS)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_EMS, - SSL_R_INCONSISTENT_EXTMS); + if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) + && (s->s3.flags & TLS1_FLAGS_REQUIRED_EXTMS)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_INCONSISTENT_EXTMS); return 0; } if (!s->server && s->hit) { @@ -1209,10 +1209,9 @@ static int final_ems(SSL *s, unsigned int context, int sent) * Check extended master secret extension is consistent with * original session. */ - if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) != + if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) != !(s->session->flags & SSL_SESS_FLAG_EXTMS)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_EMS, - SSL_R_INCONSISTENT_EXTMS); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_INCONSISTENT_EXTMS); return 0; } } @@ -1222,8 +1221,8 @@ static int final_ems(SSL *s, unsigned int context, int sent) static int init_certificate_authorities(SSL *s, unsigned int context) { - sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free); - s->s3->tmp.peer_ca_names = NULL; + sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); + s->s3.tmp.peer_ca_names = NULL; return 1; } @@ -1239,9 +1238,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_certificate_authorities) || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1251,9 +1248,7 @@ static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, } if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1267,8 +1262,7 @@ static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, if (!parse_ca_names(s, pkt)) return 0; if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } return 1; @@ -1287,7 +1281,7 @@ static int init_srtp(SSL *s, unsigned int context) static int final_sig_algs(SSL *s, unsigned int context, int sent) { if (!sent && SSL_IS_TLS13(s) && !s->hit) { - SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_F_FINAL_SIG_ALGS, + SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_R_MISSING_SIGALGS_EXTENSION); return 0; } @@ -1295,9 +1289,9 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent) return 1; } -#ifndef OPENSSL_NO_EC static int final_key_share(SSL *s, unsigned int context, int sent) { +#if !defined(OPENSSL_NO_TLS1_3) if (!SSL_IS_TLS13(s)) return 1; @@ -1321,8 +1315,7 @@ static int final_key_share(SSL *s, unsigned int context, int sent) && (!s->hit || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0)) { /* Nothing left we can do - just fail */ - SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_F_FINAL_KEY_SHARE, - SSL_R_NO_SUITABLE_KEY_SHARE); + SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_R_NO_SUITABLE_KEY_SHARE); return 0; } /* @@ -1360,9 +1353,9 @@ static int final_key_share(SSL *s, unsigned int context, int sent) * send a HelloRetryRequest */ if (s->server) { - if (s->s3->peer_tmp != NULL) { + if (s->s3.peer_tmp != NULL) { /* We have a suitable key_share */ - if ((s->s3->flags & TLS1_FLAGS_STATELESS) != 0 + if ((s->s3.flags & TLS1_FLAGS_STATELESS) != 0 && !s->ext.cookieok) { if (!ossl_assert(s->hello_retry_request == SSL_HRR_NONE)) { /* @@ -1370,8 +1363,7 @@ static int final_key_share(SSL *s, unsigned int context, int sent) * previously sent HRR - so how can this be anything other * than 0? */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } s->hello_retry_request = SSL_HRR_PENDING; @@ -1406,7 +1398,7 @@ static int final_key_share(SSL *s, unsigned int context, int sent) if (i < num_groups) { /* A shared group exists so send a HelloRetryRequest */ - s->s3->group_id = group_id; + s->s3.group_id = group_id; s->hello_retry_request = SSL_HRR_PENDING; return 1; } @@ -1416,11 +1408,11 @@ static int final_key_share(SSL *s, unsigned int context, int sent) /* Nothing left we can do - just fail */ SSLfatal(s, sent ? SSL_AD_HANDSHAKE_FAILURE : SSL_AD_MISSING_EXTENSION, - SSL_F_FINAL_KEY_SHARE, SSL_R_NO_SUITABLE_KEY_SHARE); + SSL_R_NO_SUITABLE_KEY_SHARE); return 0; } - if ((s->s3->flags & TLS1_FLAGS_STATELESS) != 0 + if ((s->s3.flags & TLS1_FLAGS_STATELESS) != 0 && !s->ext.cookieok) { if (!ossl_assert(s->hello_retry_request == SSL_HRR_NONE)) { /* @@ -1428,8 +1420,7 @@ static int final_key_share(SSL *s, unsigned int context, int sent) * previously sent HRR - so how can this be anything other * than 0? */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } s->hello_retry_request = SSL_HRR_PENDING; @@ -1450,15 +1441,13 @@ static int final_key_share(SSL *s, unsigned int context, int sent) * processing). */ if (!sent && !tls13_generate_handshake_secret(s, NULL, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } - +#endif /* !defined(OPENSSL_NO_TLS1_3) */ return 1; } -#endif static int init_psk_kex_modes(SSL *s, unsigned int context) { @@ -1485,14 +1474,13 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, #endif const unsigned char *label; size_t bindersize, labelsize, hashsize; - int hashsizei = EVP_MD_size(md); + int hashsizei = EVP_MD_get_size(md); int ret = -1; int usepskfored = 0; /* Ensure cast to size_t is safe */ if (!ossl_assert(hashsizei >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } hashsize = (size_t)hashsizei; @@ -1538,8 +1526,7 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, if (mctx == NULL || EVP_DigestInit_ex(mctx, md, NULL) <= 0 || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1557,8 +1544,7 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, } if (EVP_DigestInit_ex(mctx, md, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1573,10 +1559,9 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, void *hdata; hdatalen = hdatalen_l = - BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + BIO_get_mem_data(s->s3.handshake_buffer, &hdata); if (hdatalen_l <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - SSL_R_BAD_HANDSHAKE_LENGTH); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH); goto err; } @@ -1593,32 +1578,29 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, || !PACKET_get_length_prefixed_3(&hashprefix, &msg) || !PACKET_forward(&hashprefix, 1) || !PACKET_get_length_prefixed_3(&hashprefix, &msg)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } hdatalen -= PACKET_remaining(&hashprefix); } if (EVP_DigestUpdate(mctx, hdata, hdatalen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } if (EVP_DigestUpdate(mctx, msgstart, binderoffset) <= 0 || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - mackey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finishedkey, - hashsize); + mackey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, finishedkey, + hashsize); if (mackey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1626,12 +1608,12 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, binderout = tmpbinder; bindersize = hashsize; - if (EVP_DigestSignInit(mctx, NULL, md, NULL, mackey) <= 0 + if (EVP_DigestSignInit_ex(mctx, NULL, EVP_MD_get0_name(md), s->ctx->libctx, + s->ctx->propq, mackey, NULL) <= 0 || EVP_DigestSignUpdate(mctx, hash, hashsize) <= 0 || EVP_DigestSignFinal(mctx, binderout, &bindersize) <= 0 || bindersize != hashsize) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1641,8 +1623,7 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, /* HMAC keys can't do EVP_DigestVerify* - use CRYPTO_memcmp instead */ ret = (CRYPTO_memcmp(binderin, binderout, hashsize) == 0); if (!ret) - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PSK_DO_BINDER, - SSL_R_BINDER_DOES_NOT_VERIFY); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BINDER_DOES_NOT_VERIFY); } err: @@ -1668,8 +1649,7 @@ static int final_early_data(SSL *s, unsigned int context, int sent) * later realised that it shouldn't have done (e.g. inconsistent * ALPN) */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_FINAL_EARLY_DATA, - SSL_R_BAD_EARLY_DATA); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EARLY_DATA); return 0; } @@ -1706,8 +1686,7 @@ static int final_maxfragmentlen(SSL *s, unsigned int context, int sent) */ if (s->server && s->hit && USE_MAX_FRAGMENT_LENGTH_EXT(s->session) && !sent ) { - SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_F_FINAL_MAXFRAGMENTLEN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } @@ -1723,7 +1702,7 @@ static int final_maxfragmentlen(SSL *s, unsigned int context, int sent) return 1; } -static int init_post_handshake_auth(SSL *s, unsigned int context) +static int init_post_handshake_auth(SSL *s, ossl_unused unsigned int context) { s->post_handshake_auth = SSL_PHA_NONE; @@ -1738,7 +1717,7 @@ static int final_psk(SSL *s, unsigned int context, int sent) { if (s->server && sent && s->clienthello != NULL && !s->clienthello->pre_proc_exts[TLSEXT_IDX_psk_kex_modes].present) { - SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_F_FINAL_PSK, + SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION); return 0; } diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index 1cbaefa9f123..842be0722bd0 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2022 The OpenSSL Project Authors. 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 @@ -22,11 +22,10 @@ EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished, - s->s3->previous_client_finished_len) + || !WPACKET_sub_memcpy_u8(pkt, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -51,8 +50,7 @@ EXT_RETURN tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, strlen(s->ext.hostname)) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -77,8 +75,7 @@ EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u8(pkt, s->ext.max_fragment_len_mode) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -103,8 +100,7 @@ EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, strlen(s->srp_ctx.login)) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_SRP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -112,8 +108,7 @@ EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, } #endif -#ifndef OPENSSL_NO_EC -static int use_ecc(SSL *s) +static int use_ecc(SSL *s, int min_version, int max_version) { int i, end, ret = 0; unsigned long alg_k, alg_a; @@ -139,7 +134,6 @@ static int use_ecc(SSL *s) break; } } - sk_SSL_CIPHER_free(cipher_stack); if (!ret) return 0; @@ -149,7 +143,8 @@ static int use_ecc(SSL *s) for (j = 0; j < num_groups; j++) { uint16_t ctmp = pgroups[j]; - if (tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) + if (tls_valid_group(s, ctmp, min_version, max_version, 1, NULL) + && tls_group_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) return 1; } @@ -162,8 +157,14 @@ EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, { const unsigned char *pformats; size_t num_formats; + int reason, min_version, max_version; - if (!use_ecc(s)) + reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); + if (reason != 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason); + return EXT_RETURN_FAIL; + } + if (!use_ecc(s, min_version, max_version)) return EXT_RETURN_NOT_SENT; /* Add TLS extension ECPointFormats to the ClientHello message */ @@ -174,8 +175,7 @@ EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -187,49 +187,69 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, size_t chainidx) { const uint16_t *pgroups = NULL; - size_t num_groups = 0, i; + size_t num_groups = 0, i, tls13added = 0, added = 0; + int min_version, max_version, reason; - if (!use_ecc(s)) + reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); + if (reason != 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason); + return EXT_RETURN_FAIL; + } + + /* + * We only support EC groups in TLSv1.2 or below, and in DTLS. Therefore + * if we don't have EC support then we don't send this extension. + */ + if (!use_ecc(s, min_version, max_version) + && (SSL_IS_DTLS(s) || max_version < TLS1_3_VERSION)) return EXT_RETURN_NOT_SENT; /* * Add TLS extension supported_groups to the ClientHello message */ - /* TODO(TLS1.3): Add support for DHE groups */ tls1_get_supported_groups(s, &pgroups, &num_groups); if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups) /* Sub-packet for supported_groups extension */ || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); + || !WPACKET_start_sub_packet_u16(pkt) + || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - /* Copy curve ID if supported */ + /* Copy group ID if supported */ for (i = 0; i < num_groups; i++) { uint16_t ctmp = pgroups[i]; + int okfortls13; - if (tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) { + if (tls_valid_group(s, ctmp, min_version, max_version, 0, &okfortls13) + && tls_group_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) { if (!WPACKET_put_bytes_u16(pkt, ctmp)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + if (okfortls13 && max_version == TLS1_3_VERSION) + tls13added++; + added++; } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); + if (added == 0) + SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_GROUPS, + "No groups enabled for max supported SSL/TLS version"); + else + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + + if (tls13added == 0 && max_version == TLS1_3_VERSION) { + SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_GROUPS, + "No groups enabled for max supported SSL/TLS version"); return EXT_RETURN_FAIL; } return EXT_RETURN_SENT; } -#endif EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, @@ -249,9 +269,7 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, ticklen = s->ext.session_ticket->length; s->session->ext.tick = OPENSSL_malloc(ticklen); if (s->session->ext.tick == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } memcpy(s->session->ext.tick, @@ -267,8 +285,7 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket) || !WPACKET_sub_memcpy_u16(pkt, s->session->ext.tick, ticklen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -294,8 +311,7 @@ EXT_RETURN tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, || !tls12_copy_sigalgs(s, pkt, salg, salglen) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -322,8 +338,7 @@ EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, || !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp) /* Sub-packet for the ids */ || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } for (i = 0; i < sk_OCSP_RESPID_num(s->ext.ocsp.ids); i++) { @@ -335,16 +350,13 @@ EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, /* Sub-packet for an individual id */ || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes) || i2d_OCSP_RESPID(id, &idbytes) != idlen) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } if (s->ext.ocsp.exts) { @@ -352,23 +364,18 @@ EXT_RETURN tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, int extlen = i2d_X509_EXTENSIONS(s->ext.ocsp.exts, NULL); if (extlen < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes) || i2d_X509_EXTENSIONS(s->ext.ocsp.exts, &extbytes) != extlen) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -389,8 +396,7 @@ EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, */ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_NPN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -401,7 +407,7 @@ EXT_RETURN tls_construct_ctos_npn(SSL *s, WPACKET *pkt, unsigned int context, EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - s->s3->alpn_sent = 0; + s->s3.alpn_sent = 0; if (s->ext.alpn == NULL || !SSL_IS_FIRST_HANDSHAKE(s)) return EXT_RETURN_NOT_SENT; @@ -412,11 +418,10 @@ EXT_RETURN tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_sub_memcpy_u16(pkt, s->ext.alpn, s->ext.alpn_len) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_ALPN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - s->s3->alpn_sent = 1; + s->s3.alpn_sent = 1; return EXT_RETURN_SENT; } @@ -438,8 +443,7 @@ EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) /* Sub-packet for the protection profile list */ || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -449,8 +453,7 @@ EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, sk_SRTP_PROTECTION_PROFILE_value(clnt, i); if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } } @@ -458,8 +461,7 @@ EXT_RETURN tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, /* Add an empty use_mki value */ || !WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -475,8 +477,7 @@ EXT_RETURN tls_construct_ctos_etm(SSL *s, WPACKET *pkt, unsigned int context, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_ETM, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -496,8 +497,7 @@ EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_SCT, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -508,10 +508,12 @@ EXT_RETURN tls_construct_ctos_sct(SSL *s, WPACKET *pkt, unsigned int context, EXT_RETURN tls_construct_ctos_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return EXT_RETURN_NOT_SENT; + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_EMS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -526,8 +528,7 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, reason); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, reason); return EXT_RETURN_FAIL; } @@ -541,24 +542,18 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u8(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } for (currv = max_version; currv >= min_version; currv--) { if (!WPACKET_put_bytes_u16(pkt, currv)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -582,8 +577,7 @@ EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL *s, WPACKET *pkt, || (nodhe && !WPACKET_put_bytes_u8(pkt, TLSEXT_KEX_MODE_KE)) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -602,16 +596,15 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) EVP_PKEY *key_share_key = NULL; size_t encodedlen; - if (s->s3->tmp.pkey != NULL) { + if (s->s3.tmp.pkey != NULL) { if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_ADD_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* * Could happen if we got an HRR that wasn't requesting a new key_share */ - key_share_key = s->s3->tmp.pkey; + key_share_key = s->s3.tmp.pkey; } else { key_share_key = ssl_generate_pkey_group(s, curve_id); if (key_share_key == NULL) { @@ -621,33 +614,32 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) } /* Encode the public key. */ - encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key, - &encoded_point); + encodedlen = EVP_PKEY_get1_encoded_public_key(key_share_key, + &encoded_point); if (encodedlen == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_ADD_KEY_SHARE, ERR_R_EC_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); goto err; } /* Create KeyShareEntry */ if (!WPACKET_put_bytes_u16(pkt, curve_id) || !WPACKET_sub_memcpy_u16(pkt, encoded_point, encodedlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_ADD_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } /* - * TODO(TLS1.3): When changing to send more than one key_share we're + * When changing to send more than one key_share we're * going to need to be able to save more than one EVP_PKEY. For now * we reuse the existing tmp.pkey */ - s->s3->tmp.pkey = key_share_key; - s->s3->group_id = curve_id; + s->s3.tmp.pkey = key_share_key; + s->s3.group_id = curve_id; OPENSSL_free(encoded_point); return 1; err: - if (s->s3->tmp.pkey == NULL) + if (s->s3.tmp.pkey == NULL) EVP_PKEY_free(key_share_key); OPENSSL_free(encoded_point); return 0; @@ -669,23 +661,26 @@ EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) /* KeyShare list sub-packet */ || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } tls1_get_supported_groups(s, &pgroups, &num_groups); /* - * TODO(TLS1.3): Make the number of key_shares sent configurable. For - * now, just send one + * Make the number of key_shares sent configurable. For + * now, we just send one */ - if (s->s3->group_id != 0) { - curve_id = s->s3->group_id; + if (s->s3.group_id != 0) { + curve_id = s->s3.group_id; } else { for (i = 0; i < num_groups; i++) { - if (!tls_curve_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) + if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) + continue; + + if (!tls_valid_group(s, pgroups[i], TLS1_3_VERSION, TLS1_3_VERSION, + 0, NULL)) continue; curve_id = pgroups[i]; @@ -694,8 +689,7 @@ EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, } if (curve_id == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, - SSL_R_NO_SUITABLE_KEY_SHARE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_KEY_SHARE); return EXT_RETURN_FAIL; } @@ -705,8 +699,7 @@ EXT_RETURN tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } return EXT_RETURN_SENT; @@ -730,8 +723,7 @@ EXT_RETURN tls_construct_ctos_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_sub_memcpy_u16(pkt, s->ext.tls13_cookie, s->ext.tls13_cookie_len) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto end; } @@ -765,8 +757,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, || (psksess != NULL && psksess->ssl_version != TLS1_3_VERSION))) { SSL_SESSION_free(psksess); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, - SSL_R_BAD_PSK); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; } @@ -780,8 +771,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, psk, sizeof(psk)); if (psklen > PSK_MAX_PSK_LEN) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } else if (psklen > 0) { const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; @@ -789,9 +779,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, idlen = strlen(identity); if (idlen > PSK_MAX_IDENTITY_LEN) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } id = (unsigned char *)identity; @@ -802,9 +790,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, */ cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id); if (cipher == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -813,9 +799,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, || !SSL_SESSION_set1_master_key(psksess, psk, psklen) || !SSL_SESSION_set_cipher(psksess, cipher) || !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); OPENSSL_cleanse(psk, psklen); return EXT_RETURN_FAIL; } @@ -831,8 +815,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, s->psksession_id = OPENSSL_memdup(id, idlen); if (s->psksession_id == NULL) { s->psksession_id_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } s->psksession_id_len = idlen; @@ -852,15 +835,13 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, || (s->ext.hostname != NULL && strcmp(s->ext.hostname, edsess->ext.hostname) != 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, SSL_R_INCONSISTENT_EARLY_DATA_SNI); return EXT_RETURN_FAIL; } } if ((s->ext.alpn == NULL && edsess->ext.alpn_selected != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, - SSL_R_INCONSISTENT_EARLY_DATA_ALPN); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_INCONSISTENT_EARLY_DATA_ALPN); return EXT_RETURN_FAIL; } @@ -873,8 +854,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, int found = 0; if (!PACKET_buf_init(&prots, s->ext.alpn, s->ext.alpn_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } while (PACKET_get_length_prefixed_1(&prots, &alpnpkt)) { @@ -886,7 +866,6 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, } if (!found) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, SSL_R_INCONSISTENT_EARLY_DATA_ALPN); return EXT_RETURN_FAIL; } @@ -895,8 +874,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -944,8 +922,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, * this extension MUST always appear second to last. */ if (!WPACKET_get_total_written(pkt, &hlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PADDING, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -956,7 +933,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, if (s->session->ssl_version == TLS1_3_VERSION && s->session->ext.ticklen != 0 && s->session->cipher != NULL) { - const EVP_MD *md = ssl_md(s->session->cipher->algorithm2); + const EVP_MD *md = ssl_md(s->ctx, s->session->cipher->algorithm2); if (md != NULL) { /* @@ -964,7 +941,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, * length. */ hlen += PSK_PRE_BINDER_OVERHEAD + s->session->ext.ticklen - + EVP_MD_size(md); + + EVP_MD_get_size(md); } } @@ -985,8 +962,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding) || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PADDING, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } memset(padbytes, 0, hlen); @@ -1030,11 +1006,10 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, if (s->session->ext.ticklen != 0) { /* Get the digest associated with the ciphersuite in the session */ if (s->session->cipher == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - mdres = ssl_md(s->session->cipher->algorithm2); + mdres = ssl_md(s->ctx, s->session->cipher->algorithm2); if (mdres == NULL) { /* * Don't recognize this cipher so we can't use the session. @@ -1096,7 +1071,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, */ agems += s->session->ext.tick_age_add; - reshashsize = EVP_MD_size(mdres); + reshashsize = EVP_MD_get_size(mdres); s->ext.tick_identity++; dores = 1; } @@ -1106,14 +1081,13 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_NOT_SENT; if (s->psksession != NULL) { - mdpsk = ssl_md(s->psksession->cipher->algorithm2); + mdpsk = ssl_md(s->ctx, s->psksession->cipher->algorithm2); if (mdpsk == NULL) { /* * Don't recognize this cipher so we can't use the session. * If this happens it's an application bug. */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - SSL_R_BAD_PSK); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; } @@ -1122,20 +1096,18 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, * Selected ciphersuite hash does not match the hash for the PSK * session. This is an application bug. */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - SSL_R_BAD_PSK); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; } - pskhashsize = EVP_MD_size(mdpsk); + pskhashsize = EVP_MD_get_size(mdpsk); } /* Create the extension, but skip over the binder for now */ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_psk) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1143,8 +1115,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, if (!WPACKET_sub_memcpy_u16(pkt, s->session->ext.tick, s->session->ext.ticklen) || !WPACKET_put_bytes_u32(pkt, agems)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } } @@ -1153,8 +1124,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, if (!WPACKET_sub_memcpy_u16(pkt, s->psksession_id, s->psksession_id_len) || !WPACKET_put_bytes_u32(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } s->ext.tick_identity++; @@ -1175,8 +1145,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, * calculate the HMAC of the message up to the binders */ || !WPACKET_fill_lengths(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1203,8 +1172,9 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, } EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, - unsigned int context, - X509 *x, size_t chainidx) + ossl_unused unsigned int context, + ossl_unused X509 *x, + ossl_unused size_t chainidx) { #ifndef OPENSSL_NO_TLS1_3 if (!s->pha_enabled) @@ -1214,9 +1184,7 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_post_handshake_auth) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1235,58 +1203,52 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - size_t expected_len = s->s3->previous_client_finished_len - + s->s3->previous_server_finished_len; + size_t expected_len = s->s3.previous_client_finished_len + + s->s3.previous_server_finished_len; size_t ilen; const unsigned char *data; /* Check for logic errors */ if (!ossl_assert(expected_len == 0 - || s->s3->previous_client_finished_len != 0) + || s->s3.previous_client_finished_len != 0) || !ossl_assert(expected_len == 0 - || s->s3->previous_server_finished_len != 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, - ERR_R_INTERNAL_ERROR); + || s->s3.previous_server_finished_len != 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* Parse the length byte */ if (!PACKET_get_1_len(pkt, &ilen)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, - SSL_R_RENEGOTIATION_ENCODING_ERR); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RENEGOTIATION_ENCODING_ERR); return 0; } /* Consistency check */ if (PACKET_remaining(pkt) != ilen) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, - SSL_R_RENEGOTIATION_ENCODING_ERR); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RENEGOTIATION_ENCODING_ERR); return 0; } /* Check that the extension matches */ if (ilen != expected_len) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, - SSL_R_RENEGOTIATION_MISMATCH); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - if (!PACKET_get_bytes(pkt, &data, s->s3->previous_client_finished_len) - || memcmp(data, s->s3->previous_client_finished, - s->s3->previous_client_finished_len) != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, - SSL_R_RENEGOTIATION_MISMATCH); + if (!PACKET_get_bytes(pkt, &data, s->s3.previous_client_finished_len) + || memcmp(data, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) != 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - if (!PACKET_get_bytes(pkt, &data, s->s3->previous_server_finished_len) - || memcmp(data, s->s3->previous_server_finished, - s->s3->previous_server_finished_len) != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_RENEGOTIATE, - SSL_R_RENEGOTIATION_MISMATCH); + if (!PACKET_get_bytes(pkt, &data, s->s3.previous_server_finished_len) + || memcmp(data, s->s3.previous_server_finished, + s->s3.previous_server_finished_len) != 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - s->s3->send_connection_binding = 1; + s->s3.send_connection_binding = 1; return 1; } @@ -1298,15 +1260,13 @@ int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, unsigned int value; if (PACKET_remaining(pkt) != 1 || !PACKET_get_1(pkt, &value)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } /* |value| should contains a valid max-fragment-length code. */ if (!IS_MAX_FRAGMENT_LENGTH_EXT_VALID(value)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -1319,7 +1279,6 @@ int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, */ if (value != s->ext.max_fragment_len_mode) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -1337,27 +1296,23 @@ int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { if (s->ext.hostname == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (PACKET_remaining(pkt) > 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_SERVER_NAME, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (!s->hit) { if (s->session->ext.hostname != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } s->session->ext.hostname = OPENSSL_strdup(s->ext.hostname); if (s->session->ext.hostname == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -1365,7 +1320,6 @@ int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, unsigned int context, return 1; } -#ifndef OPENSSL_NO_EC int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -1373,15 +1327,13 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, PACKET ecptformatlist; if (!PACKET_as_length_prefixed_1(pkt, &ecptformatlist)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (!s->hit) { ecpointformats_len = PACKET_remaining(&ecptformatlist); if (ecpointformats_len == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); return 0; } @@ -1390,8 +1342,7 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, s->ext.peer_ecpointformats = OPENSSL_malloc(ecpointformats_len); if (s->ext.peer_ecpointformats == NULL) { s->ext.peer_ecpointformats_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1400,15 +1351,13 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_copy_bytes(&ecptformatlist, s->ext.peer_ecpointformats, ecpointformats_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } return 1; } -#endif int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1417,19 +1366,16 @@ int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context, !s->ext.session_ticket_cb(s, PACKET_data(pkt), PACKET_remaining(pkt), s->ext.session_ticket_cb_arg)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_PARSE_STOC_SESSION_TICKET, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION); return 0; } if (!tls_use_ticket(s)) { - SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, - SSL_F_TLS_PARSE_STOC_SESSION_TICKET, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } if (PACKET_remaining(pkt) > 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_STOC_SESSION_TICKET, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -1444,7 +1390,6 @@ int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context, { if (context == SSL_EXT_TLS1_3_CERTIFICATE_REQUEST) { /* We ignore this if the server sends a CertificateRequest */ - /* TODO(TLS1.3): Add support for this */ return 1; } @@ -1453,13 +1398,11 @@ int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, unsigned int context, * request message. In TLS <= 1.2 it must also be empty. */ if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) { - SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, - SSL_F_TLS_PARSE_STOC_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } if (!SSL_IS_TLS13(s) && PACKET_remaining(pkt) > 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_STOC_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -1488,7 +1431,6 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, { if (context == SSL_EXT_TLS1_3_CERTIFICATE_REQUEST) { /* We ignore this if the server sends it in a CertificateRequest */ - /* TODO(TLS1.3): Add support for this */ return 1; } @@ -1509,13 +1451,11 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->ext.scts = OPENSSL_malloc(size); if (s->ext.scts == NULL) { s->ext.scts_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SCT, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } if (!PACKET_copy_bytes(pkt, s->ext.scts, size)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_SCT, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -1530,8 +1470,7 @@ int tls_parse_stoc_sct(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (custom_ext_find(&s->cert->custext, role, TLSEXT_TYPE_signed_certificate_timestamp, NULL) == NULL) { - SSLfatal(s, TLS1_AD_UNSUPPORTED_EXTENSION, SSL_F_TLS_PARSE_STOC_SCT, - SSL_R_BAD_EXTENSION); + SSLfatal(s, TLS1_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } @@ -1562,8 +1501,7 @@ static int ssl_next_proto_validate(SSL *s, PACKET *pkt) while (PACKET_remaining(pkt)) { if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol) || PACKET_remaining(&tmp_protocol) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL_NEXT_PROTO_VALIDATE, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } } @@ -1584,8 +1522,7 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* We must have requested it. */ if (s->ctx->ext.npn_select_cb == NULL) { - SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_F_TLS_PARSE_STOC_NPN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } @@ -1600,8 +1537,7 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, PACKET_remaining(pkt), s->ctx->ext.npn_select_cb_arg) != SSL_TLSEXT_ERR_OK) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_STOC_NPN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION); return 0; } @@ -1613,14 +1549,13 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, s->ext.npn = OPENSSL_malloc(selected_len); if (s->ext.npn == NULL) { s->ext.npn_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_NPN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } memcpy(s->ext.npn, selected, selected_len); s->ext.npn_len = selected_len; - s->s3->npn_seen = 1; + s->s3.npn_seen = 1; return 1; } @@ -1632,9 +1567,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t len; /* We must have requested it. */ - if (!s->s3->alpn_sent) { - SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_F_TLS_PARSE_STOC_ALPN, - SSL_R_BAD_EXTENSION); + if (!s->s3.alpn_sent) { + SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } /*- @@ -1646,28 +1580,25 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_get_net_2_len(pkt, &len) || PACKET_remaining(pkt) != len || !PACKET_get_1_len(pkt, &len) || PACKET_remaining(pkt) != len) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_malloc(len); - if (s->s3->alpn_selected == NULL) { - s->s3->alpn_selected_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, - ERR_R_INTERNAL_ERROR); + OPENSSL_free(s->s3.alpn_selected); + s->s3.alpn_selected = OPENSSL_malloc(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; } - if (!PACKET_copy_bytes(pkt, s->s3->alpn_selected, len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, - SSL_R_BAD_EXTENSION); + if (!PACKET_copy_bytes(pkt, s->s3.alpn_selected, len)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - s->s3->alpn_selected_len = len; + s->s3.alpn_selected_len = len; if (s->session->ext.alpn_selected == NULL || s->session->ext.alpn_selected_len != len - || memcmp(s->session->ext.alpn_selected, s->s3->alpn_selected, len) + || memcmp(s->session->ext.alpn_selected, s->s3.alpn_selected, len) != 0) { /* ALPN not consistent with the old session so cannot use early_data */ s->ext.early_data_ok = 0; @@ -1678,19 +1609,17 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * initialised to NULL. We should update it with the selected ALPN. */ if (!ossl_assert(s->session->ext.alpn_selected == NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_ALPN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } 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_PARSE_STOC_ALPN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - s->session->ext.alpn_selected_len = s->s3->alpn_selected_len; + s->session->ext.alpn_selected_len = s->s3.alpn_selected_len; } return 1; @@ -1709,23 +1638,21 @@ int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !PACKET_get_net_2(pkt, &id) || !PACKET_get_1(pkt, &mki) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_USE_SRTP, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); return 0; } if (mki != 0) { /* Must be no MKI, since we never offer one */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_USE_SRTP, - SSL_R_BAD_SRTP_MKI_VALUE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_SRTP_MKI_VALUE); return 0; } /* Throw an error if the server gave us an unsolicited extension */ clnt = SSL_get_srtp_profiles(s); if (clnt == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_USE_SRTP, - SSL_R_NO_SRTP_PROFILES); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_SRTP_PROFILES); return 0; } @@ -1742,7 +1669,7 @@ int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } } - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_USE_SRTP, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); return 0; } @@ -1753,10 +1680,12 @@ int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, { /* Ignore if inappropriate ciphersuite */ if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) - && s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD - && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4 - && s->s3->tmp.new_cipher->algorithm_enc != SSL_eGOST2814789CNT - && s->s3->tmp.new_cipher->algorithm_enc != SSL_eGOST2814789CNT12) + && s->s3.tmp.new_cipher->algorithm_mac != SSL_AEAD + && s->s3.tmp.new_cipher->algorithm_enc != SSL_RC4 + && s->s3.tmp.new_cipher->algorithm_enc != SSL_eGOST2814789CNT + && s->s3.tmp.new_cipher->algorithm_enc != SSL_eGOST2814789CNT12 + && s->s3.tmp.new_cipher->algorithm_enc != SSL_MAGMA + && s->s3.tmp.new_cipher->algorithm_enc != SSL_KUZNYECHIK) s->ext.use_etm = 1; return 1; @@ -1765,7 +1694,9 @@ int tls_parse_stoc_etm(SSL *s, PACKET *pkt, unsigned int context, X509 *x, int tls_parse_stoc_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS; + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return 1; + s->s3.flags |= TLS1_FLAGS_RECEIVED_EXTMS; if (!s->hit) s->session->flags |= SSL_SESS_FLAG_EXTMS; @@ -1779,9 +1710,7 @@ int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_get_net_2(pkt, &version) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -1791,7 +1720,6 @@ int tls_parse_stoc_supported_versions(SSL *s, PACKET *pkt, unsigned int context, */ if (version != TLS1_3_VERSION) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; } @@ -1812,18 +1740,17 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, #ifndef OPENSSL_NO_TLS1_3 unsigned int group_id; PACKET encoded_pt; - EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL; + EVP_PKEY *ckey = s->s3.tmp.pkey, *skey = NULL; + const TLS_GROUP_INFO *ginf = NULL; /* Sanity check */ - if (ckey == NULL || s->s3->peer_tmp != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + if (ckey == NULL || s->s3.peer_tmp != NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!PACKET_get_net_2(pkt, &group_id)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -1832,8 +1759,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t i, num_groups; if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -1841,9 +1767,8 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * It is an error if the HelloRetryRequest wants a key_share that we * already sent in the first ClientHello */ - if (group_id == s->s3->group_id) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_BAD_KEY_SHARE); + if (group_id == s->s3.group_id) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } @@ -1854,56 +1779,94 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, break; } if (i >= num_groups - || !tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_BAD_KEY_SHARE); + || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) + || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, + 0, NULL)) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } - s->s3->group_id = group_id; - EVP_PKEY_free(s->s3->tmp.pkey); - s->s3->tmp.pkey = NULL; + s->s3.group_id = group_id; + EVP_PKEY_free(s->s3.tmp.pkey); + s->s3.tmp.pkey = NULL; return 1; } - if (group_id != s->s3->group_id) { + if (group_id != s->s3.group_id) { /* * This isn't for the group that we sent in the original * key_share! */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_BAD_KEY_SHARE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } + /* Retain this group in the SSL_SESSION */ + if (!s->hit) { + s->session->kex_group = group_id; + } else if (group_id != s->session->kex_group) { + /* + * If this is a resumption but changed what group was used, we need + * to record the new group in the session, but the session is not + * a new session and could be in use by other threads. So, make + * a copy of the session to record the new information so that it's + * useful for any sessions resumed from tickets issued on this + * connection. + */ + SSL_SESSION *new_sess; - if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt) - || PACKET_remaining(&encoded_pt) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_LENGTH_MISMATCH); - return 0; + if ((new_sess = ssl_session_dup(s->session, 0)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + return 0; + } + SSL_SESSION_free(s->session); + s->session = new_sess; + s->session->kex_group = group_id; } - skey = EVP_PKEY_new(); - if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - ERR_R_MALLOC_FAILURE); - EVP_PKEY_free(skey); + if ((ginf = tls1_group_id_lookup(s->ctx, group_id)) == NULL) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } - if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_BAD_ECPOINT); - EVP_PKEY_free(skey); + + if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt) + || PACKET_remaining(&encoded_pt) == 0) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - if (ssl_derive(s, ckey, skey, 1) == 0) { - /* SSLfatal() already called */ - EVP_PKEY_free(skey); - return 0; + if (!ginf->is_kem) { + /* Regular KEX */ + skey = EVP_PKEY_new(); + if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COPY_PARAMETERS_FAILED); + EVP_PKEY_free(skey); + return 0; + } + + if (tls13_set_encoded_pub_key(skey, PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt)) <= 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT); + EVP_PKEY_free(skey); + return 0; + } + + if (ssl_derive(s, ckey, skey, 1) == 0) { + /* SSLfatal() already called */ + EVP_PKEY_free(skey); + return 0; + } + s->s3.peer_tmp = skey; + } else { + /* KEM Mode */ + const unsigned char *ct = PACKET_data(&encoded_pt); + size_t ctlen = PACKET_remaining(&encoded_pt); + + if (ssl_decapsulate(s, ckey, ct, ctlen, 1) == 0) { + /* SSLfatal() already called */ + return 0; + } } - s->s3->peer_tmp = skey; + s->s3.did_kex = 1; #endif return 1; @@ -1917,8 +1880,7 @@ int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_as_length_prefixed_2(pkt, &cookie) || !PACKET_memdup(&cookie, &s->ext.tls13_cookie, &s->ext.tls13_cookie_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -1933,8 +1895,7 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_get_net_4(pkt, &max_early_data) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_EARLY_DATA, - SSL_R_INVALID_MAX_EARLY_DATA); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_INVALID_MAX_EARLY_DATA); return 0; } @@ -1944,8 +1905,7 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, } if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_EARLY_DATA, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -1956,8 +1916,7 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, * using the first identity, or the SNI/ALPN is not consistent so the * server should not be accepting it. */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_EARLY_DATA, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); return 0; } @@ -1973,14 +1932,12 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, unsigned int identity; if (!PACKET_get_net_2(pkt, &identity) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_PSK, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } if (identity >= (unsigned int)s->ext.tick_identity) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_PSK, - SSL_R_BAD_PSK_IDENTITY); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PSK_IDENTITY); return 0; } @@ -1998,8 +1955,7 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (s->psksession == NULL) { /* Should never happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } diff --git a/ssl/statem/extensions_cust.c b/ssl/statem/extensions_cust.c index 1fe226f9f264..401a4c5c76b1 100644 --- a/ssl/statem/extensions_cust.c +++ b/ssl/statem/extensions_cust.c @@ -1,7 +1,7 @@ /* * Copyright 2014-2021 The OpenSSL Project Authors. 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 @@ -139,8 +139,7 @@ int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type, * extensions not sent in ClientHello. */ if ((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0) { - SSLfatal(s, TLS1_AD_UNSUPPORTED_EXTENSION, SSL_F_CUSTOM_EXT_PARSE, - SSL_R_BAD_EXTENSION); + SSLfatal(s, TLS1_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } } @@ -160,7 +159,7 @@ int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type, if (meth->parse_cb(s, ext_type, context, ext_data, ext_size, x, chainidx, &al, meth->parse_arg) <= 0) { - SSLfatal(s, al, SSL_F_CUSTOM_EXT_PARSE, SSL_R_BAD_EXTENSION); + SSLfatal(s, al, SSL_R_BAD_EXTENSION); return 0; } @@ -210,7 +209,7 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, meth->add_arg); if (cb_retval < 0) { - SSLfatal(s, al, SSL_F_CUSTOM_EXT_ADD, SSL_R_CALLBACK_FAILED); + SSLfatal(s, al, SSL_R_CALLBACK_FAILED); return 0; /* error */ } if (cb_retval == 0) @@ -221,8 +220,7 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, || !WPACKET_start_sub_packet_u16(pkt) || (outlen > 0 && !WPACKET_memcpy(pkt, out, outlen)) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CUSTOM_EXT_ADD, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if ((context & SSL_EXT_CLIENT_HELLO) != 0) { @@ -230,8 +228,7 @@ int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx, * We can't send duplicates: code logic should prevent this. */ if (!ossl_assert((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CUSTOM_EXT_ADD, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* @@ -492,11 +489,9 @@ int SSL_extension_supported(unsigned int ext_type) switch (ext_type) { /* Internally supported extensions. */ case TLSEXT_TYPE_application_layer_protocol_negotiation: -#ifndef OPENSSL_NO_EC case TLSEXT_TYPE_ec_point_formats: case TLSEXT_TYPE_supported_groups: case TLSEXT_TYPE_key_share: -#endif #ifndef OPENSSL_NO_NEXTPROTONEG case TLSEXT_TYPE_next_proto_neg: #endif diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 47541101db50..16765a5a5b6f 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2022 The OpenSSL Project Authors. 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 @@ -47,26 +47,23 @@ int tls_parse_ctos_renegotiate(SSL *s, PACKET *pkt, unsigned int context, /* Parse the length byte */ if (!PACKET_get_1(pkt, &ilen) || !PACKET_get_bytes(pkt, &data, ilen)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_RENEGOTIATE, - SSL_R_RENEGOTIATION_ENCODING_ERR); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_RENEGOTIATION_ENCODING_ERR); return 0; } /* Check that the extension matches */ - if (ilen != s->s3->previous_client_finished_len) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_CTOS_RENEGOTIATE, - SSL_R_RENEGOTIATION_MISMATCH); + if (ilen != s->s3.previous_client_finished_len) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - if (memcmp(data, s->s3->previous_client_finished, - s->s3->previous_client_finished_len)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PARSE_CTOS_RENEGOTIATE, - SSL_R_RENEGOTIATION_MISMATCH); + if (memcmp(data, s->s3.previous_client_finished, + s->s3.previous_client_finished_len)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_RENEGOTIATION_MISMATCH); return 0; } - s->s3->send_connection_binding = 1; + s->s3.send_connection_binding = 1; return 1; } @@ -103,8 +100,7 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_as_length_prefixed_2(pkt, &sni) /* ServerNameList must be at least 1 byte long. */ || PACKET_remaining(&sni) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_SERVER_NAME, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -122,8 +118,7 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_get_1(&sni, &servname_type) || servname_type != TLSEXT_NAMETYPE_host_name || !PACKET_as_length_prefixed_2(&sni, &hostname)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_SERVER_NAME, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -133,16 +128,12 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, */ if (!s->hit || SSL_IS_TLS13(s)) { if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) { - SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, - SSL_F_TLS_PARSE_CTOS_SERVER_NAME, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION); return 0; } if (PACKET_contains_zero_byte(&hostname)) { - SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, - SSL_F_TLS_PARSE_CTOS_SERVER_NAME, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION); return 0; } @@ -153,8 +144,7 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, OPENSSL_free(s->ext.hostname); s->ext.hostname = NULL; if (!PACKET_strndup(&hostname, &s->ext.hostname)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -165,10 +155,6 @@ int tls_parse_ctos_server_name(SSL *s, PACKET *pkt, unsigned int context, * the initial handshake and the resumption. In TLSv1.3 SNI is not * associated with the session. */ - /* - * TODO(openssl-team): if the SNI doesn't match, we MUST - * fall back to a full handshake. - */ s->servername_done = (s->session->ext.hostname != NULL) && PACKET_equal(&hostname, s->session->ext.hostname, strlen(s->session->ext.hostname)); @@ -183,15 +169,13 @@ int tls_parse_ctos_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, unsigned int value; if (PACKET_remaining(pkt) != 1 || !PACKET_get_1(pkt, &value)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } /* Received |value| should be a valid max-fragment-length code. */ if (!IS_MAX_FRAGMENT_LENGTH_EXT_VALID(value)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -203,7 +187,6 @@ int tls_parse_ctos_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, */ if (s->hit && s->session->ext.max_fragment_len_mode != value) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -224,19 +207,12 @@ int tls_parse_ctos_srp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_as_length_prefixed_1(pkt, &srp_I) || PACKET_contains_zero_byte(&srp_I)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_SRP, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - /* - * TODO(openssl-team): currently, we re-authenticate the user - * upon resumption. Instead, we MUST ignore the login. - */ if (!PACKET_strndup(&srp_I, &s->srp_ctx.login)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_SRP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -244,7 +220,6 @@ int tls_parse_ctos_srp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } #endif -#ifndef OPENSSL_NO_EC int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -252,8 +227,7 @@ int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_as_length_prefixed_1(pkt, &ec_point_format_list) || PACKET_remaining(&ec_point_format_list) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -261,15 +235,13 @@ int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_memdup(&ec_point_format_list, &s->ext.peer_ecpointformats, &s->ext.peer_ecpointformats_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } return 1; } -#endif /* OPENSSL_NO_EC */ int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -278,29 +250,28 @@ int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, unsigned int context, !s->ext.session_ticket_cb(s, PACKET_data(pkt), PACKET_remaining(pkt), s->ext.session_ticket_cb_arg)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } return 1; } -int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) +int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt, + ossl_unused unsigned int context, + ossl_unused X509 *x, + ossl_unused size_t chainidx) { PACKET supported_sig_algs; if (!PACKET_as_length_prefixed_2(pkt, &supported_sig_algs) || PACKET_remaining(&supported_sig_algs) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (!s->hit && !tls1_save_sigalgs(s, &supported_sig_algs, 1)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -314,14 +285,12 @@ int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_as_length_prefixed_2(pkt, &supported_sig_algs) || PACKET_remaining(&supported_sig_algs) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_SIG_ALGS, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (!s->hit && !tls1_save_sigalgs(s, &supported_sig_algs, 0)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_SIG_ALGS, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -343,8 +312,7 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, return 1; if (!PACKET_get_1(pkt, (unsigned int *)&s->ext.status_type)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -357,8 +325,7 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, } if (!PACKET_get_length_prefixed_2 (pkt, &responder_id_list)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -370,8 +337,7 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, if (PACKET_remaining(&responder_id_list) > 0) { s->ext.ocsp.ids = sk_OCSP_RESPID_new_null(); if (s->ext.ocsp.ids == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } } else { @@ -385,33 +351,28 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_get_length_prefixed_2(&responder_id_list, &responder_id) || PACKET_remaining(&responder_id) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } id_data = PACKET_data(&responder_id); - /* TODO(size_t): Convert d2i_* to size_t */ id = d2i_OCSP_RESPID(NULL, &id_data, (int)PACKET_remaining(&responder_id)); if (id == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (id_data != PACKET_end(&responder_id)) { OCSP_RESPID_free(id); - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (!sk_OCSP_RESPID_push(s->ext.ocsp.ids, id)) { OCSP_RESPID_free(id); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -419,8 +380,7 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, /* Read in request_extensions */ if (!PACKET_as_length_prefixed_2(pkt, &exts)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -432,8 +392,7 @@ int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, s->ext.ocsp.exts = d2i_X509_EXTENSIONS(NULL, &ext_data, (int)PACKET_remaining(&exts)); if (s->ext.ocsp.exts == NULL || ext_data != PACKET_end(&exts)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } } @@ -451,7 +410,7 @@ int tls_parse_ctos_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * renegotiation. */ if (SSL_IS_FIRST_HANDSHAKE(s)) - s->s3->npn_seen = 1; + s->s3.npn_seen = 1; return 1; } @@ -471,8 +430,7 @@ int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_as_length_prefixed_2(pkt, &protocol_list) || PACKET_remaining(&protocol_list) < 2) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_ALPN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -481,19 +439,17 @@ int tls_parse_ctos_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Protocol names can't be empty. */ if (!PACKET_get_length_prefixed_1(&protocol_list, &protocol) || PACKET_remaining(&protocol) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_ALPN, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } } while (PACKET_remaining(&protocol_list) != 0); - OPENSSL_free(s->s3->alpn_proposed); - s->s3->alpn_proposed = NULL; - s->s3->alpn_proposed_len = 0; + OPENSSL_free(s->s3.alpn_proposed); + s->s3.alpn_proposed = NULL; + s->s3.alpn_proposed_len = 0; if (!PACKET_memdup(&save_protocol_list, - &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_ALPN, - ERR_R_INTERNAL_ERROR); + &s->s3.alpn_proposed, &s->s3.alpn_proposed_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -516,7 +472,7 @@ int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Pull off the length of the cipher suite list and check it is even */ if (!PACKET_get_net_2(pkt, &ct) || (ct & 1) != 0 || !PACKET_get_sub_packet(pkt, &subpkt, ct)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_USE_SRTP, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); return 0; } @@ -528,7 +484,7 @@ int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, while (PACKET_remaining(&subpkt)) { if (!PACKET_get_net_2(&subpkt, &id)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_USE_SRTP, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); return 0; } @@ -553,15 +509,14 @@ int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Now extract the MKI value as a sanity check, but discard it for now */ if (!PACKET_get_1(pkt, &mki_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_USE_SRTP, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); return 0; } if (!PACKET_forward(pkt, mki_len) || PACKET_remaining(pkt)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_USE_SRTP, - SSL_R_BAD_SRTP_MKI_VALUE); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_SRTP_MKI_VALUE); return 0; } @@ -591,8 +546,7 @@ int tls_parse_ctos_psk_kex_modes(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_as_length_prefixed_1(pkt, &psk_kex_modes) || PACKET_remaining(&psk_kex_modes) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -626,15 +580,13 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; /* Sanity check */ - if (s->s3->peer_tmp != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + if (s->s3.peer_tmp != NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -648,19 +600,18 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * because we verify that the length is non-zero when we process that * extension. */ - SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, + SSLfatal(s, SSL_AD_MISSING_EXTENSION, SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION); return 0; } - if (s->s3->group_id != 0 && PACKET_remaining(&key_share_list) == 0) { + if (s->s3.group_id != 0 && PACKET_remaining(&key_share_list) == 0) { /* * If we set a group_id already, then we must have sent an HRR * requesting a new key_share. If we haven't got one then that is an * error */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, - SSL_R_BAD_KEY_SHARE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } @@ -668,8 +619,7 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_get_net_2(&key_share_list, &group_id) || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt) || PACKET_remaining(&encoded_pt) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -684,40 +634,46 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * If we sent an HRR then the key_share sent back MUST be for the group * we requested, and must be the only key_share sent. */ - if (s->s3->group_id != 0 - && (group_id != s->s3->group_id + if (s->s3.group_id != 0 + && (group_id != s->s3.group_id || PACKET_remaining(&key_share_list) != 0)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_KEY_SHARE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } /* Check if this share is in supported_groups sent from client */ if (!check_in_list(s, group_id, clntgroups, clnt_num_groups, 0)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_KEY_SHARE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } /* Check if this share is for a group we can use */ - if (!check_in_list(s, group_id, srvrgroups, srvr_num_groups, 1)) { + if (!check_in_list(s, group_id, srvrgroups, srvr_num_groups, 1) + || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) + /* + * We tolerate but ignore a group id that we don't think is + * suitable for TLSv1.3 + */ + || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, + 0, NULL)) { /* Share not suitable */ continue; } - if ((s->s3->peer_tmp = ssl_generate_param_group(group_id)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, + if ((s->s3.peer_tmp = ssl_generate_param_group(s, group_id)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); return 0; } - s->s3->group_id = group_id; + s->s3.group_id = group_id; + /* Cache the selected group ID in the SSL_SESSION */ + s->session->kex_group = group_id; - if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp, - PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_ECPOINT); + if (tls13_set_encoded_pub_key(s->s3.peer_tmp, + PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt)) <= 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT); return 0; } @@ -745,12 +701,11 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Ignore any cookie if we're not set up to verify it */ if (s->ctx->verify_stateless_cookie_cb == NULL - || (s->s3->flags & TLS1_FLAGS_STATELESS) == 0) + || (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return 1; if (!PACKET_as_length_prefixed_2(pkt, &cookie)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -759,35 +714,33 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, rawlen = PACKET_remaining(&raw); if (rawlen < SHA256_DIGEST_LENGTH || !PACKET_forward(&raw, rawlen - SHA256_DIGEST_LENGTH)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } mdin = PACKET_data(&raw); /* Verify the HMAC of the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext - .cookie_hmac_key)); + pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, + s->session_ctx->ext.cookie_hmac_key, + sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { EVP_MD_CTX_free(hctx); EVP_PKEY_free(pkey); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } hmaclen = SHA256_DIGEST_LENGTH; - if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, + s->ctx->propq, pkey, NULL) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, data, rawlen - SHA256_DIGEST_LENGTH) <= 0 || hmaclen != SHA256_DIGEST_LENGTH) { EVP_MD_CTX_free(hctx); EVP_PKEY_free(pkey); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -795,14 +748,12 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, EVP_PKEY_free(pkey); if (CRYPTO_memcmp(hmac, mdin, SHA256_DIGEST_LENGTH) != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_COOKIE_MISMATCH); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COOKIE_MISMATCH); return 0; } if (!PACKET_get_net_2(&cookie, &format)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } /* Check the cookie format is something we recognise. Ignore it if not */ @@ -816,37 +767,33 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Check the version number is sane */ if (!PACKET_get_net_2(&cookie, &version)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } if (version != TLS1_3_VERSION) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; } if (!PACKET_get_net_2(&cookie, &group_id)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } ciphdata = PACKET_data(&cookie); if (!PACKET_forward(&cookie, 2)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - if (group_id != s->s3->group_id - || s->s3->tmp.new_cipher + if (group_id != s->s3.group_id + || s->s3.tmp.new_cipher != ssl_get_cipher_by_char(s, ciphdata, 0)) { /* * We chose a different cipher or group id this time around to what is * in the cookie. Something must have changed. */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_BAD_CIPHER); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_CIPHER); return 0; } @@ -855,8 +802,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !PACKET_get_length_prefixed_2(&cookie, &chhash) || !PACKET_get_length_prefixed_1(&cookie, &appcookie) || PACKET_remaining(&cookie) != SHA256_DIGEST_LENGTH) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -870,8 +816,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Verify the app cookie */ if (s->ctx->verify_stateless_cookie_cb(s, PACKET_data(&appcookie), PACKET_remaining(&appcookie)) == 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_CTOS_COOKIE, - SSL_R_COOKIE_MISMATCH); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COOKIE_MISMATCH); return 0; } @@ -881,8 +826,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, * Note: This won't work with custom HRR extensions */ if (!WPACKET_init_static_len(&hrrpkt, hrr, sizeof(hrr), 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO) @@ -891,13 +835,12 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE) || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id, s->tmp_session_id_len) - || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, &hrrpkt, + || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, &hrrpkt, &ciphlen) || !WPACKET_put_bytes_u8(&hrrpkt, 0) || !WPACKET_start_sub_packet_u16(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_supported_versions) @@ -905,18 +848,16 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !WPACKET_put_bytes_u16(&hrrpkt, s->version) || !WPACKET_close(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (key_share) { if (!WPACKET_put_bytes_u16(&hrrpkt, TLSEXT_TYPE_key_share) || !WPACKET_start_sub_packet_u16(&hrrpkt) - || !WPACKET_put_bytes_u16(&hrrpkt, s->s3->group_id) + || !WPACKET_put_bytes_u16(&hrrpkt, s->s3.group_id) || !WPACKET_close(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -929,8 +870,7 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !WPACKET_get_total_written(&hrrpkt, &hrrlen) || !WPACKET_finish(&hrrpkt)) { WPACKET_cleanup(&hrrpkt); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -951,7 +891,6 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } -#ifndef OPENSSL_NO_EC int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { @@ -961,8 +900,7 @@ int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, if (!PACKET_as_length_prefixed_2(pkt, &supported_groups_list) || PACKET_remaining(&supported_groups_list) == 0 || (PACKET_remaining(&supported_groups_list) % 2) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -973,28 +911,27 @@ int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, if (!tls1_save_u16(&supported_groups_list, &s->ext.peer_supportedgroups, &s->ext.peer_supportedgroups_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } return 1; } -#endif int tls_parse_ctos_ems(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { /* The extension must always be empty */ if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_EMS, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS; + if (s->options & SSL_OP_NO_EXTENDED_MASTER_SECRET) + return 1; + + s->s3.flags |= TLS1_FLAGS_RECEIVED_EXTMS; return 1; } @@ -1004,14 +941,12 @@ int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_EARLY_DATA, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (s->hello_retry_request != SSL_HRR_NONE) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PARSE_CTOS_EARLY_DATA, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); return 0; } @@ -1064,8 +999,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; if (!PACKET_get_length_prefixed_2(pkt, &identities)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -1077,8 +1011,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (!PACKET_get_length_prefixed_2(&identities, &identity) || !PACKET_get_net_4(&identities, &ticket_agel)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -1086,8 +1019,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, if (s->psk_find_session_cb != NULL && !s->psk_find_session_cb(s, PACKET_data(&identity), idlen, &sess)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_EXTENSION); return 0; } @@ -1100,16 +1032,14 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, unsigned int pskdatalen; if (!PACKET_strndup(&identity, &pskid)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } pskdatalen = s->psk_server_callback(s, pskid, pskdata, sizeof(pskdata)); OPENSSL_free(pskid); if (pskdatalen > PSK_MAX_PSK_LEN) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } else if (pskdatalen > 0) { const SSL_CIPHER *cipher; @@ -1122,8 +1052,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id); if (cipher == NULL) { OPENSSL_cleanse(pskdata, pskdatalen); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1135,8 +1064,7 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, || !SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) { OPENSSL_cleanse(pskdata, pskdatalen); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } OPENSSL_cleanse(pskdata, pskdatalen); @@ -1149,9 +1077,8 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, SSL_SESSION *sesstmp = ssl_session_dup(sess, 0); if (sesstmp == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_PSK, ERR_R_INTERNAL_ERROR); - goto err; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; } SSL_SESSION_free(sess); sess = sesstmp; @@ -1185,15 +1112,13 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, &sess); if (ret == SSL_TICKET_EMPTY) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } if (ret == SSL_TICKET_FATAL_ERR_MALLOC || ret == SSL_TICKET_FATAL_ERR_OTHER) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PARSE_CTOS_PSK, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (ret == SSL_TICKET_NONE || ret == SSL_TICKET_NO_DECRYPT) @@ -1234,8 +1159,14 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } } - md = ssl_md(sess->cipher->algorithm2); - if (md != ssl_md(s->s3->tmp.new_cipher->algorithm2)) { + md = ssl_md(s->ctx, sess->cipher->algorithm2); + if (md == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!EVP_MD_is_a(md, + EVP_MD_get0_name(ssl_md(s->ctx, + s->s3.tmp.new_cipher->algorithm2)))) { /* The ciphersuite is not compatible with this session. */ SSL_SESSION_free(sess); sess = NULL; @@ -1250,25 +1181,22 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; binderoffset = PACKET_data(pkt) - (const unsigned char *)s->init_buf->data; - hashsize = EVP_MD_size(md); + hashsize = EVP_MD_get_size(md); if (!PACKET_get_length_prefixed_2(pkt, &binders)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); goto err; } for (i = 0; i <= id; i++) { if (!PACKET_get_length_prefixed_1(&binders, &binder)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); goto err; } } if (PACKET_remaining(&binder) != hashsize) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); goto err; } if (tls_psk_do_binder(s, md, (const unsigned char *)s->init_buf->data, @@ -1288,11 +1216,13 @@ err: return 0; } -int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, unsigned int context, - X509 *x, size_t chainidx) +int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, + ossl_unused unsigned int context, + ossl_unused X509 *x, + ossl_unused size_t chainidx) { if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH, + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR); return 0; } @@ -1309,21 +1239,20 @@ EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (!s->s3->send_connection_binding) + if (!s->s3.send_connection_binding) return EXT_RETURN_NOT_SENT; /* Still add this even if SSL_OP_NO_RENEGOTIATION is set */ if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u8(pkt) - || !WPACKET_memcpy(pkt, s->s3->previous_client_finished, - s->s3->previous_client_finished_len) - || !WPACKET_memcpy(pkt, s->s3->previous_server_finished, - s->s3->previous_server_finished_len) + || !WPACKET_memcpy(pkt, s->s3.previous_client_finished, + s->s3.previous_client_finished_len) + || !WPACKET_memcpy(pkt, s->s3.previous_server_finished, + s->s3.previous_server_finished_len) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1346,8 +1275,7 @@ EXT_RETURN tls_construct_stoc_server_name(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1370,21 +1298,19 @@ EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u8(pkt, s->session->ext.max_fragment_len_mode) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } return EXT_RETURN_SENT; } -#ifndef OPENSSL_NO_EC EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + unsigned long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3.tmp.new_cipher->algorithm_auth; int using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) && (s->ext.peer_ecpointformats != NULL); const unsigned char *plist; @@ -1398,46 +1324,45 @@ EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } return EXT_RETURN_SENT; } -#endif -#ifndef OPENSSL_NO_EC EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { const uint16_t *groups; size_t numgroups, i, first = 1; + int version; - /* s->s3->group_id is non zero if we accepted a key_share */ - if (s->s3->group_id == 0) + /* s->s3.group_id is non zero if we accepted a key_share */ + if (s->s3.group_id == 0) return EXT_RETURN_NOT_SENT; /* Get our list of supported groups */ tls1_get_supported_groups(s, &groups, &numgroups); if (numgroups == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } /* Copy group ID if supported */ + version = SSL_version(s); for (i = 0; i < numgroups; i++) { uint16_t group = groups[i]; - if (tls_curve_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) { + if (tls_valid_group(s, group, version, version, 0, NULL) + && tls_group_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) { if (first) { /* * Check if the client is already using our preferred group. If * so we don't need to add this extension */ - if (s->s3->group_id == group) + if (s->s3.group_id == group) return EXT_RETURN_NOT_SENT; /* Add extension header */ @@ -1445,33 +1370,26 @@ EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, /* Sub-packet for supported_groups extension */ || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } first = 0; } if (!WPACKET_put_bytes_u16(pkt, group)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } } } if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } return EXT_RETURN_SENT; } -#endif EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, @@ -1484,8 +1402,7 @@ EXT_RETURN tls_construct_stoc_session_ticket(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1509,8 +1426,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request) || !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1524,8 +1440,7 @@ EXT_RETURN tls_construct_stoc_status_request(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1541,9 +1456,9 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, const unsigned char *npa; unsigned int npalen; int ret; - int npn_seen = s->s3->npn_seen; + int npn_seen = s->s3.npn_seen; - s->s3->npn_seen = 0; + s->s3.npn_seen = 0; if (!npn_seen || s->ctx->ext.npn_advertised_cb == NULL) return EXT_RETURN_NOT_SENT; @@ -1552,12 +1467,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, if (ret == SSL_TLSEXT_ERR_OK) { if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg) || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - s->s3->npn_seen = 1; + s->s3.npn_seen = 1; } return EXT_RETURN_SENT; @@ -1567,19 +1480,18 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt, EXT_RETURN tls_construct_stoc_alpn(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (s->s3->alpn_selected == NULL) + if (s->s3.alpn_selected == NULL) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_application_layer_protocol_negotiation) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected, - s->s3->alpn_selected_len) + || !WPACKET_sub_memcpy_u8(pkt, s->s3.alpn_selected, + s->s3.alpn_selected_len) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_ALPN, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1600,8 +1512,7 @@ EXT_RETURN tls_construct_stoc_use_srtp(SSL *s, WPACKET *pkt, || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id) || !WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1619,18 +1530,19 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, * Don't use encrypt_then_mac if AEAD or RC4 might want to disable * for other cases too. */ - if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD - || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4 - || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT - || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) { + if (s->s3.tmp.new_cipher->algorithm_mac == SSL_AEAD + || s->s3.tmp.new_cipher->algorithm_enc == SSL_RC4 + || s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT + || s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12 + || s->s3.tmp.new_cipher->algorithm_enc == SSL_MAGMA + || s->s3.tmp.new_cipher->algorithm_enc == SSL_KUZNYECHIK) { s->ext.use_etm = 0; return EXT_RETURN_NOT_SENT; } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_ETM, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1640,13 +1552,12 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, EXT_RETURN tls_construct_stoc_ems(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if ((s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) + if ((s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) == 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret) || !WPACKET_put_bytes_u16(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_EMS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1658,9 +1569,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt, size_t chainidx) { if (!ossl_assert(SSL_IS_TLS13(s))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1668,9 +1577,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u16(pkt, s->version) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1684,7 +1591,8 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, #ifndef OPENSSL_NO_TLS1_3 unsigned char *encodedPoint; size_t encoded_pt_len = 0; - EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL; + EVP_PKEY *ckey = s->s3.peer_tmp, *skey = NULL; + const TLS_GROUP_INFO *ginf = NULL; if (s->hello_retry_request == SSL_HRR_PENDING) { if (ckey != NULL) { @@ -1693,11 +1601,9 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->s3->group_id) + || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1707,8 +1613,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, if (ckey == NULL) { /* No key_share received from client - must be resuming */ if (!s->hit || !tls13_generate_handshake_secret(s, NULL, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } return EXT_RETURN_NOT_SENT; @@ -1723,44 +1628,88 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u16(pkt, s->s3->group_id)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); + || !WPACKET_put_bytes_u16(pkt, s->s3.group_id)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - skey = ssl_generate_pkey(ckey); - if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_MALLOC_FAILURE); + if ((ginf = tls1_group_id_lookup(s->ctx, s->s3.group_id)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - /* Generate encoding of server key */ - encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); - if (encoded_pt_len == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_EC_LIB); - EVP_PKEY_free(skey); - return EXT_RETURN_FAIL; - } + if (!ginf->is_kem) { + /* Regular KEX */ + skey = ssl_generate_pkey(s, ckey); + if (skey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + return EXT_RETURN_FAIL; + } - if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) - || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(skey); + /* Generate encoding of server key */ + encoded_pt_len = EVP_PKEY_get1_encoded_public_key(skey, &encodedPoint); + if (encoded_pt_len == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); + EVP_PKEY_free(skey); + return EXT_RETURN_FAIL; + } + + if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) + || !WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(skey); + OPENSSL_free(encodedPoint); + return EXT_RETURN_FAIL; + } OPENSSL_free(encodedPoint); - return EXT_RETURN_FAIL; - } - OPENSSL_free(encodedPoint); - /* This causes the crypto state to be updated based on the derived keys */ - s->s3->tmp.pkey = skey; - if (ssl_derive(s, skey, ckey, 1) == 0) { - /* SSLfatal() already called */ - return EXT_RETURN_FAIL; + /* + * This causes the crypto state to be updated based on the derived keys + */ + s->s3.tmp.pkey = skey; + if (ssl_derive(s, skey, ckey, 1) == 0) { + /* SSLfatal() already called */ + return EXT_RETURN_FAIL; + } + } else { + /* KEM mode */ + unsigned char *ct = NULL; + size_t ctlen = 0; + + /* + * This does not update the crypto state. + * + * The generated pms is stored in `s->s3.tmp.pms` to be later used via + * ssl_gensecret(). + */ + if (ssl_encapsulate(s, ckey, &ct, &ctlen, 0) == 0) { + /* SSLfatal() already called */ + return EXT_RETURN_FAIL; + } + + if (ctlen == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + OPENSSL_free(ct); + return EXT_RETURN_FAIL; + } + + if (!WPACKET_sub_memcpy_u16(pkt, ct, ctlen) + || !WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + OPENSSL_free(ct); + return EXT_RETURN_FAIL; + } + OPENSSL_free(ct); + + /* + * This causes the crypto state to be updated based on the generated pms + */ + if (ssl_gensecret(s, s->s3.tmp.pms, s->s3.tmp.pmslen) == 0) { + /* SSLfatal() already called */ + return EXT_RETURN_FAIL; + } } + s->s3.did_kex = 1; return EXT_RETURN_SENT; #else return EXT_RETURN_FAIL; @@ -1778,12 +1727,11 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, EVP_PKEY *pkey; int ret = EXT_RETURN_FAIL; - if ((s->s3->flags & TLS1_FLAGS_STATELESS) == 0) + if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return EXT_RETURN_NOT_SENT; if (s->ctx->gen_stateless_cookie_cb == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - SSL_R_NO_COOKIE_CALLBACK_SET); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_COOKIE_CALLBACK_SET); return EXT_RETURN_FAIL; } @@ -1794,16 +1742,15 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_reserve_bytes(pkt, MAX_COOKIE_SIZE, &cookie) || !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION) || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION) - || !WPACKET_put_bytes_u16(pkt, s->s3->group_id) - || !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, + || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) + || !s->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &ciphlen) /* Is there a key_share extension present in this HRR? */ - || !WPACKET_put_bytes_u8(pkt, s->s3->peer_tmp == NULL) + || !WPACKET_put_bytes_u8(pkt, s->s3.peer_tmp == NULL) || !WPACKET_put_bytes_u64(pkt, time(NULL)) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_reserve_bytes(pkt, EVP_MAX_MD_SIZE, &hashval1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1823,15 +1770,13 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt) || !WPACKET_start_sub_packet_u8(pkt) || !WPACKET_reserve_bytes(pkt, SSL_COOKIE_LENGTH, &appcookie1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } /* Generate the application cookie */ if (s->ctx->gen_stateless_cookie_cb(s, appcookie1, &appcookielen) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - SSL_R_COOKIE_GEN_CALLBACK_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); return EXT_RETURN_FAIL; } @@ -1840,42 +1785,38 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_close(pkt) || !WPACKET_get_total_written(pkt, &totcookielen) || !WPACKET_reserve_bytes(pkt, SHA256_DIGEST_LENGTH, &hmac)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } hmaclen = SHA256_DIGEST_LENGTH; totcookielen -= startlen; if (!ossl_assert(totcookielen <= MAX_COOKIE_SIZE - SHA256_DIGEST_LENGTH)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } /* HMAC the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext - .cookie_hmac_key)); + pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, + s->session_ctx->ext.cookie_hmac_key, + sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_DigestSignInit(hctx, NULL, EVP_sha256(), NULL, pkey) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, + s->ctx->propq, pkey, NULL) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, cookie, totcookielen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (!ossl_assert(totcookielen + hmaclen <= MAX_COOKIE_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1884,8 +1825,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, || !ossl_assert(cookie == hmac - totcookielen) || !WPACKET_close(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1913,14 +1853,13 @@ EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 }; - if (((s->s3->tmp.new_cipher->id & 0xFFFF) != 0x80 - && (s->s3->tmp.new_cipher->id & 0xFFFF) != 0x81) + if (((s->s3.tmp.new_cipher->id & 0xFFFF) != 0x80 + && (s->s3.tmp.new_cipher->id & 0xFFFF) != 0x81) || (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG) == 0) return EXT_RETURN_NOT_SENT; if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1939,8 +1878,7 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u32(pkt, s->max_early_data) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1953,8 +1891,7 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1971,8 +1908,7 @@ EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_put_bytes_u16(pkt, s->ext.tick_identity) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_STOC_PSK, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index 20f5bd584e6c..553546d93a41 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -1,12 +1,17 @@ /* - * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. 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 */ +#if defined(__TANDEM) && defined(_SPT_MODEL_) +# include <spthread.h> +# include <spt_extensions.h> /* timeval */ +#endif + #include "internal/cryptlib.h" #include <openssl/rand.h> #include "../ssl_local.h" @@ -111,14 +116,8 @@ void ossl_statem_set_renegotiate(SSL *s) s->statem.request_state = TLS_ST_SW_HELLO_REQ; } -/* - * Put the state machine into an error state and send an alert if appropriate. - * This is a permanent error for the current connection. - */ -void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file, - int line) +void ossl_statem_send_fatal(SSL *s, int al) { - ERR_put_error(ERR_LIB_SSL, func, reason, file, line); /* We shouldn't call SSLfatal() twice. Once is enough */ if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR) return; @@ -130,16 +129,32 @@ void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file, } /* + * Error reporting building block that's used instead of ERR_set_error(). + * In addition to what ERR_set_error() does, this puts the state machine + * into an error state and sends an alert if appropriate. + * This is a permanent error for the current connection. + */ +void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ERR_vset_error(ERR_LIB_SSL, reason, fmt, args); + va_end(args); + + ossl_statem_send_fatal(s, al); +} + +/* * This macro should only be called if we are already expecting to be in * a fatal error state. We verify that we are, and set it if not (this would * indicate a bug). */ -#define check_fatal(s, f) \ +#define check_fatal(s) \ do { \ if (!ossl_assert((s)->statem.in_init \ && (s)->statem.state == MSG_FLOW_ERROR)) \ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, (f), \ - SSL_R_MISSING_FATAL); \ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_MISSING_FATAL); \ } while (0) /* @@ -319,7 +334,7 @@ static int state_machine(SSL *s, int server) * If we are stateless then we already called SSL_clear() - don't do * it again and clear the STATELESS flag itself. */ - if ((s->s3->flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(s)) + if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(s)) return -1; } #ifndef OPENSSL_NO_SCTP @@ -356,33 +371,28 @@ static int state_machine(SSL *s, int server) if (SSL_IS_DTLS(s)) { if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && (server || (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00))) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } } else { if ((s->version >> 8) != SSL3_VERSION_MAJOR) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } } if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } if (s->init_buf == NULL) { if ((buf = BUF_MEM_new()) == NULL) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } s->init_buf = buf; @@ -390,8 +400,7 @@ static int state_machine(SSL *s, int server) } if (!ssl3_setup_buffers(s)) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } s->init_num = 0; @@ -399,7 +408,7 @@ static int state_machine(SSL *s, int server) /* * Should have been reset by tls_process_finished, too. */ - s->s3->change_cipher_spec = 0; + s->s3.change_cipher_spec = 0; /* * Ok, we now need to push on a buffering BIO ...but not with @@ -409,8 +418,7 @@ static int state_machine(SSL *s, int server) if (!SSL_IS_DTLS(s) || !BIO_dgram_is_sctp(SSL_get_wbio(s))) #endif if (!ssl_init_wbio_buffer(s)) { - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_NO_ALERT, ERR_R_INTERNAL_ERROR); goto end; } @@ -452,8 +460,8 @@ static int state_machine(SSL *s, int server) } } else { /* Error */ - check_fatal(s, SSL_F_STATE_MACHINE); - SSLerr(SSL_F_STATE_MACHINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + check_fatal(s); + ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); goto end; } } @@ -574,7 +582,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) /* * In DTLS we get the whole message in one go - header and body */ - ret = dtls_get_message(s, &mt, &len); + ret = dtls_get_message(s, &mt); } else { ret = tls_get_message_header(s, &mt); } @@ -598,19 +606,18 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) if (!transition(s, mt)) return SUB_STATE_ERROR; - if (s->s3->tmp.message_size > max_message_size(s)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_READ_STATE_MACHINE, + if (s->s3.tmp.message_size > max_message_size(s)) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); return SUB_STATE_ERROR; } /* dtls_get_message already did this */ if (!SSL_IS_DTLS(s) - && s->s3->tmp.message_size > 0 - && !grow_init_buf(s, s->s3->tmp.message_size + && s->s3.tmp.message_size > 0 + && !grow_init_buf(s, s->s3.tmp.message_size + SSL3_HM_HEADER_LENGTH)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE, - ERR_R_BUF_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); return SUB_STATE_ERROR; } @@ -618,19 +625,23 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) /* Fall through */ case READ_STATE_BODY: - if (!SSL_IS_DTLS(s)) { - /* We already got this above for DTLS */ + if (SSL_IS_DTLS(s)) { + /* + * Actually we already have the body, but we give DTLS the + * opportunity to do any further processing. + */ + ret = dtls_get_message_body(s, &len); + } else { ret = tls_get_message_body(s, &len); - if (ret == 0) { - /* Could be non-blocking IO */ - return SUB_STATE_ERROR; - } + } + if (ret == 0) { + /* Could be non-blocking IO */ + return SUB_STATE_ERROR; } s->first_packet = 0; if (!PACKET_buf_init(&pkt, s->init_msg, len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return SUB_STATE_ERROR; } ret = process_message(s, &pkt); @@ -640,7 +651,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) switch (ret) { case MSG_PROCESS_ERROR: - check_fatal(s, SSL_F_READ_STATE_MACHINE); + check_fatal(s); return SUB_STATE_ERROR; case MSG_PROCESS_FINISHED_READING: @@ -664,7 +675,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) st->read_state_work = post_process_message(s, st->read_state_work); switch (st->read_state_work) { case WORK_ERROR: - check_fatal(s, SSL_F_READ_STATE_MACHINE); + check_fatal(s); /* Fall through */ case WORK_MORE_A: case WORK_MORE_B: @@ -685,8 +696,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return SUB_STATE_ERROR; } } @@ -801,7 +811,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) break; case WRITE_TRAN_ERROR: - check_fatal(s, SSL_F_WRITE_STATE_MACHINE); + check_fatal(s); return SUB_STATE_ERROR; } break; @@ -809,7 +819,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) case WRITE_STATE_PRE_WORK: switch (st->write_state_work = pre_work(s, st->write_state_work)) { case WORK_ERROR: - check_fatal(s, SSL_F_WRITE_STATE_MACHINE); + check_fatal(s); /* Fall through */ case WORK_MORE_A: case WORK_MORE_B: @@ -836,20 +846,32 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) if (!WPACKET_init(&pkt, s->init_buf) || !ssl_set_handshake_header(s, &pkt, mt)) { WPACKET_cleanup(&pkt); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_WRITE_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return SUB_STATE_ERROR; } - if (confunc != NULL && !confunc(s, &pkt)) { - WPACKET_cleanup(&pkt); - check_fatal(s, SSL_F_WRITE_STATE_MACHINE); - return SUB_STATE_ERROR; + if (confunc != NULL) { + int tmpret; + + tmpret = confunc(s, &pkt); + if (tmpret <= 0) { + WPACKET_cleanup(&pkt); + check_fatal(s); + return SUB_STATE_ERROR; + } else if (tmpret == 2) { + /* + * The construction function decided not to construct the + * message after all and continue. Skip sending. + */ + WPACKET_cleanup(&pkt); + st->write_state = WRITE_STATE_POST_WORK; + st->write_state_work = WORK_MORE_A; + break; + } /* else success */ } if (!ssl_close_construct_packet(s, &pkt, mt) || !WPACKET_finish(&pkt)) { WPACKET_cleanup(&pkt); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_WRITE_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return SUB_STATE_ERROR; } @@ -870,7 +892,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) case WRITE_STATE_POST_WORK: switch (st->write_state_work = post_work(s, st->write_state_work)) { case WORK_ERROR: - check_fatal(s, SSL_F_WRITE_STATE_MACHINE); + check_fatal(s); /* Fall through */ case WORK_MORE_A: case WORK_MORE_B: @@ -887,8 +909,7 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) break; default: - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_WRITE_STATE_MACHINE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return SUB_STATE_ERROR; } } @@ -923,7 +944,7 @@ int ossl_statem_app_data_allowed(SSL *s) if (st->state == MSG_FLOW_UNINITED) return 0; - if (!s->s3->in_read_app_data || (s->s3->total_renegotiations == 0)) + if (!s->s3.in_read_app_data || (s->s3.total_renegotiations == 0)) return 0; if (s->server) { @@ -952,7 +973,7 @@ int ossl_statem_app_data_allowed(SSL *s) */ int ossl_statem_export_allowed(SSL *s) { - return s->s3->previous_server_finished_len != 0 + return s->s3.previous_server_finished_len != 0 && s->statem.hand_state != TLS_ST_SW_FINISHED; } diff --git a/ssl/statem/statem.h b/ssl/statem/statem.h index 144d930fc7c5..5db31b63585d 100644 --- a/ssl/statem/statem.h +++ b/ssl/statem/statem.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2021 The OpenSSL Project Authors. 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 @@ -132,15 +132,15 @@ __owur int ossl_statem_accept(SSL *s); __owur int ossl_statem_connect(SSL *s); void ossl_statem_clear(SSL *s); void ossl_statem_set_renegotiate(SSL *s); -void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file, - int line); +void ossl_statem_send_fatal(SSL *s, int al); +void ossl_statem_fatal(SSL *s, int al, int reason, const char *fmt, ...); # define SSL_AD_NO_ALERT -1 -# ifndef OPENSSL_NO_ERR -# define SSLfatal(s, al, f, r) ossl_statem_fatal((s), (al), (f), (r), \ - OPENSSL_FILE, OPENSSL_LINE) -# else -# define SSLfatal(s, al, f, r) ossl_statem_fatal((s), (al), (f), (r), NULL, 0) -# endif +# define SSLfatal_alert(s, al) ossl_statem_send_fatal((s), (al)) +# define SSLfatal(s, al, r) SSLfatal_data((s), (al), (r), NULL) +# define SSLfatal_data \ + (ERR_new(), \ + ERR_set_debug(OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC), \ + ossl_statem_fatal) int ossl_statem_in_error(const SSL *s); void ossl_statem_set_in_init(SSL *s, int init); diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index d19c44e8d984..3cd1ee2d3dfe 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.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 @@ -20,9 +20,13 @@ #include <openssl/evp.h> #include <openssl/md5.h> #include <openssl/dh.h> +#include <openssl/rsa.h> #include <openssl/bn.h> #include <openssl/engine.h> -#include <internal/cryptlib.h> +#include <openssl/trace.h> +#include <openssl/core_names.h> +#include <openssl/param_build.h> +#include "internal/cryptlib.h" static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); @@ -43,8 +47,8 @@ static ossl_inline int cert_req_allowed(SSL *s) { /* TLS does not like anon-DH with client cert */ if ((s->version > SSL3_VERSION - && (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) - || (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aSRP | SSL_aPSK))) + && (s->s3.tmp.new_cipher->algorithm_auth & SSL_aNULL)) + || (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aSRP | SSL_aPSK))) return 0; return 1; @@ -59,7 +63,7 @@ static ossl_inline int cert_req_allowed(SSL *s) */ static int key_exchange_expected(SSL *s) { - long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + long alg_k = s->s3.tmp.new_cipher->algorithm_mkey; /* * Can't skip server key exchange if this is an ephemeral @@ -163,8 +167,9 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) return 1; } if (mt == SSL3_MT_CERTIFICATE_REQUEST) { -#if DTLS_MAX_VERSION != DTLS1_2_VERSION -# error TODO(DTLS1.3): Restore digest for PHA before adding message. +#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION + /* Restore digest for PHA before adding message.*/ +# error Internal DTLS version error #endif if (!SSL_IS_DTLS(s) && s->post_handshake_auth == SSL_PHA_EXT_SENT) { s->post_handshake_auth = SSL_PHA_REQUESTED; @@ -271,7 +276,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) s->hit = 1; st->hand_state = TLS_ST_CR_CHANGE; return 1; - } else if (!(s->s3->tmp.new_cipher->algorithm_auth + } else if (!(s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP | SSL_aPSK))) { if (mt == SSL3_MT_CERTIFICATE) { st->hand_state = TLS_ST_CR_CERT; @@ -281,7 +286,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) ske_expected = key_exchange_expected(s); /* SKE is optional for some PSK ciphersuites */ if (ske_expected - || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) + || ((s->s3.tmp.new_cipher->algorithm_mkey & SSL_PSK) && mt == SSL3_MT_SERVER_KEY_EXCHANGE)) { if (mt == SSL3_MT_SERVER_KEY_EXCHANGE) { st->hand_state = TLS_ST_CR_KEY_EXCH; @@ -313,7 +318,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) case TLS_ST_CR_CERT_STATUS: ske_expected = key_exchange_expected(s); /* SKE is optional for some PSK ciphersuites */ - if (ske_expected || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) + if (ske_expected || ((s->s3.tmp.new_cipher->algorithm_mkey & SSL_PSK) && mt == SSL3_MT_SERVER_KEY_EXCHANGE)) { if (mt == SSL3_MT_SERVER_KEY_EXCHANGE) { st->hand_state = TLS_ST_CR_KEY_EXCH; @@ -390,9 +395,7 @@ int ossl_statem_client_read_transition(SSL *s, int mt) BIO_set_retry_read(rbio); return 0; } - SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE, - SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION, - SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL3_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); return 0; } @@ -413,9 +416,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WRITE_TRAN_ERROR; case TLS_ST_CR_CERT_REQ: @@ -429,9 +430,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) */ if (!ossl_assert((s->shutdown & SSL_SENT_SHUTDOWN) != 0)) { /* Shouldn't happen - same as default case */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WRITE_TRAN_ERROR; } st->hand_state = TLS_ST_OK; @@ -445,7 +444,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) && s->hello_retry_request == SSL_HRR_NONE) st->hand_state = TLS_ST_CW_CHANGE; else - st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT + st->hand_state = (s->s3.tmp.cert_req != 0) ? TLS_ST_CW_CERT : TLS_ST_CW_FINISHED; return WRITE_TRAN_CONTINUE; @@ -458,13 +457,13 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL *s) case TLS_ST_CW_END_OF_EARLY_DATA: case TLS_ST_CW_CHANGE: - st->hand_state = (s->s3->tmp.cert_req != 0) ? TLS_ST_CW_CERT + st->hand_state = (s->s3.tmp.cert_req != 0) ? TLS_ST_CW_CERT : TLS_ST_CW_FINISHED; return WRITE_TRAN_CONTINUE; case TLS_ST_CW_CERT: /* If a non-empty Certificate we also send CertificateVerify */ - st->hand_state = (s->s3->tmp.cert_req == 1) ? TLS_ST_CW_CERT_VRFY + st->hand_state = (s->s3.tmp.cert_req == 1) ? TLS_ST_CW_CERT_VRFY : TLS_ST_CW_FINISHED; return WRITE_TRAN_CONTINUE; @@ -509,9 +508,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WRITE_TRAN_ERROR; case TLS_ST_OK: @@ -567,7 +564,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) return WRITE_TRAN_CONTINUE; case TLS_ST_CR_SRVR_DONE: - if (s->s3->tmp.cert_req) + if (s->s3.tmp.cert_req) st->hand_state = TLS_ST_CW_CERT; else st->hand_state = TLS_ST_CW_KEY_EXCH; @@ -588,12 +585,12 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) * need to skip the certificate verify message when client's * ECDH public key is sent inside the client certificate. */ - if (s->s3->tmp.cert_req == 1) { + if (s->s3.tmp.cert_req == 1) { st->hand_state = TLS_ST_CW_CERT_VRFY; } else { st->hand_state = TLS_ST_CW_CHANGE; } - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + if (s->s3.flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { st->hand_state = TLS_ST_CW_CHANGE; } return WRITE_TRAN_CONTINUE; @@ -611,7 +608,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL *s) #if defined(OPENSSL_NO_NEXTPROTONEG) st->hand_state = TLS_ST_CW_FINISHED; #else - if (!SSL_IS_DTLS(s) && s->s3->npn_seen) + if (!SSL_IS_DTLS(s) && s->s3.npn_seen) st->hand_state = TLS_ST_CW_NEXT_PROTO; else st->hand_state = TLS_ST_CW_FINISHED; @@ -796,14 +793,14 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) return WORK_ERROR; break; } - s->session->cipher = s->s3->tmp.new_cipher; + s->session->cipher = s->s3.tmp.new_cipher; #ifdef OPENSSL_NO_COMP s->session->compress_meth = 0; #else - if (s->s3->tmp.new_compression == NULL) + if (s->s3.tmp.new_compression == NULL) s->session->compress_meth = 0; else - s->session->compress_meth = s->s3->tmp.new_compression->id; + s->session->compress_meth = s->s3.tmp.new_compression->id; #endif if (!s->method->ssl3_enc->setup_key_block(s)) { /* SSLfatal() already called */ @@ -890,9 +887,7 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE, - SSL_R_BAD_HANDSHAKE_STATE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_STATE); return 0; case TLS_ST_CW_CHANGE: @@ -1016,7 +1011,7 @@ size_t ossl_statem_client_max_message_size(SSL *s) } /* - * Process a message that the client has been received from the server. + * Process a message that the client has received from the server. */ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) { @@ -1025,9 +1020,7 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt) switch (st->hand_state) { default: /* Shouldn't happen */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; case TLS_ST_CR_SRVR_HELLO: @@ -1085,11 +1078,12 @@ WORK_STATE ossl_statem_client_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_CLIENT_POST_PROCESS_MESSAGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; + case TLS_ST_CR_CERT: + return tls_post_process_server_certificate(s, wst); + case TLS_ST_CR_CERT_VRFY: case TLS_ST_CR_CERT_REQ: return tls_prepare_client_certificate(s, wst); @@ -1110,8 +1104,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) /* Work out what SSL/TLS/DTLS version to use */ protverr = ssl_set_client_hello_version(s); if (protverr != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - protverr); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, protverr); return 0; } @@ -1126,7 +1119,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) } /* else use the pre-loaded session */ - p = s->s3->client_random; + p = s->s3.client_random; /* * for DTLS if client_random is initialized, reuse it, we are @@ -1135,7 +1128,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) if (SSL_IS_DTLS(s)) { size_t idx; i = 1; - for (idx = 0; idx < sizeof(s->s3->client_random); idx++) { + for (idx = 0; idx < sizeof(s->s3.client_random); idx++) { if (p[idx]) { i = 0; break; @@ -1145,10 +1138,9 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) i = (s->hello_retry_request == SSL_HRR_NONE); } - if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random), + if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3.client_random), DOWNGRADE_NONE) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1186,9 +1178,8 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) * supported_versions extension for the real supported versions. */ if (!WPACKET_put_bytes_u16(pkt, s->client_version) - || !WPACKET_memcpy(pkt, s->s3->client_random, SSL3_RANDOM_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + || !WPACKET_memcpy(pkt, s->s3.client_random, SSL3_RANDOM_SIZE)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1201,10 +1192,9 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) s->tmp_session_id_len = sess_id_len; session_id = s->tmp_session_id; if (s->hello_retry_request == SSL_HRR_NONE - && RAND_bytes(s->tmp_session_id, sess_id_len) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + && RAND_bytes_ex(s->ctx->libctx, s->tmp_session_id, + sess_id_len, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } else { @@ -1222,8 +1212,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) || (sess_id_len != 0 && !WPACKET_memcpy(pkt, session_id, sess_id_len)) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1232,16 +1221,14 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) if (s->d1->cookie_len > sizeof(s->d1->cookie) || !WPACKET_sub_memcpy_u8(pkt, s->d1->cookie, s->d1->cookie_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } /* Ciphers supported */ if (!WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1250,28 +1237,24 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) return 0; } if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* COMPRESSION */ if (!WPACKET_start_sub_packet_u8(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } #ifndef OPENSSL_NO_COMP if (ssl_allow_compression(s) && s->ctx->comp_methods - && (SSL_IS_DTLS(s) || s->s3->tmp.max_ver < TLS1_3_VERSION)) { + && (SSL_IS_DTLS(s) || s->s3.tmp.max_ver < TLS1_3_VERSION)) { int compnum = sk_SSL_COMP_num(s->ctx->comp_methods); for (i = 0; i < compnum; i++) { comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); if (!WPACKET_put_bytes_u8(pkt, comp->id)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -1279,8 +1262,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) #endif /* Add the NULL method */ if (!WPACKET_put_bytes_u8(pkt, 0) || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1300,21 +1282,18 @@ MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt) if (!PACKET_forward(pkt, 2) || !PACKET_get_length_prefixed_1(pkt, &cookiepkt)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_DTLS_PROCESS_HELLO_VERIFY, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } cookie_len = PACKET_remaining(&cookiepkt); if (cookie_len > sizeof(s->d1->cookie)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_DTLS_PROCESS_HELLO_VERIFY, - SSL_R_LENGTH_TOO_LONG); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_LENGTH_TOO_LONG); return MSG_PROCESS_ERROR; } if (!PACKET_copy_bytes(&cookiepkt, s->d1->cookie, cookie_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_DTLS_PROCESS_HELLO_VERIFY, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } s->d1->cookie_len = cookie_len; @@ -1331,8 +1310,7 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) c = ssl_get_cipher_by_char(s, cipherchars, 0); if (c == NULL) { /* unknown cipher */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SET_CLIENT_CIPHERSUITE, - SSL_R_UNKNOWN_CIPHER_RETURNED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_CIPHER_RETURNED); return 0; } /* @@ -1340,8 +1318,7 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) * or it's not allowed for the selected protocol. So we return an error. */ if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK, 1)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SET_CLIENT_CIPHERSUITE, - SSL_R_WRONG_CIPHER_RETURNED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CIPHER_RETURNED); return 0; } @@ -1349,16 +1326,14 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) i = sk_SSL_CIPHER_find(sk, c); if (i < 0) { /* we did not say we would use this cipher */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SET_CLIENT_CIPHERSUITE, - SSL_R_WRONG_CIPHER_RETURNED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CIPHER_RETURNED); return 0; } - if (SSL_IS_TLS13(s) && s->s3->tmp.new_cipher != NULL - && s->s3->tmp.new_cipher->id != c->id) { + if (SSL_IS_TLS13(s) && s->s3.tmp.new_cipher != NULL + && s->s3.tmp.new_cipher->id != c->id) { /* ServerHello selected a different ciphersuite to that in the HRR */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SET_CLIENT_CIPHERSUITE, - SSL_R_WRONG_CIPHER_RETURNED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CIPHER_RETURNED); return 0; } @@ -1371,14 +1346,15 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) s->session->cipher_id = s->session->cipher->id; if (s->hit && (s->session->cipher_id != c->id)) { if (SSL_IS_TLS13(s)) { + const EVP_MD *md = ssl_md(s->ctx, c->algorithm2); + /* * In TLSv1.3 it is valid for the server to select a different * ciphersuite as long as the hash is the same. */ - if (ssl_md(c->algorithm2) - != ssl_md(s->session->cipher->algorithm2)) { + if (md == NULL + || md != ssl_md(s->ctx, s->session->cipher->algorithm2)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_SET_CLIENT_CIPHERSUITE, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED); return 0; } @@ -1387,12 +1363,12 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars) * Prior to TLSv1.3 resuming a session always meant using the same * ciphersuite. */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SET_CLIENT_CIPHERSUITE, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); return 0; } } - s->s3->tmp.new_cipher = c; + s->s3.tmp.new_cipher = c; return 1; } @@ -1412,8 +1388,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) #endif if (!PACKET_get_net_2(pkt, &sversion)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -1423,48 +1398,41 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) && PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE && memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) { if (s->hello_retry_request != SSL_HRR_NONE) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto err; } s->hello_retry_request = SSL_HRR_PENDING; hrr = 1; if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } } else { - if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); + if (!PACKET_copy_bytes(pkt, s->s3.server_random, SSL3_RANDOM_SIZE)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } } /* Get the session-id. */ if (!PACKET_get_length_prefixed_1(pkt, &session_id)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } session_id_len = PACKET_remaining(&session_id); if (session_id_len > sizeof(s->session->session_id) || session_id_len > SSL3_SESSION_ID_SIZE) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_SSL3_SESSION_ID_TOO_LONG); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_SSL3_SESSION_ID_TOO_LONG); goto err; } if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } if (!PACKET_get_1(pkt, &compression)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -1473,8 +1441,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) PACKET_null_init(&extpkt); } else if (!PACKET_as_length_prefixed_2(pkt, &extpkt) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); goto err; } @@ -1496,7 +1463,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) if (SSL_IS_TLS13(s) || hrr) { if (compression != 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_INVALID_COMPRESSION_ALGORITHM); goto err; } @@ -1504,8 +1470,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) if (session_id_len != s->tmp_session_id_len || memcmp(PACKET_data(&session_id), s->tmp_session_id, session_id_len) != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_INVALID_SESSION_ID); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_SESSION_ID); goto err; } } @@ -1526,8 +1491,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) context = SSL_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO : SSL_EXT_TLS1_2_SERVER_HELLO; if (!tls_validate_all_contexts(s, context, extensions)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_BAD_EXTENSION); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); goto err; } @@ -1540,7 +1504,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) */ if (RECORD_LAYER_processed_read_pending(&s->rlayer)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_NOT_ON_RECORD_BOUNDARY); goto err; } @@ -1583,8 +1546,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) s->session->cipher = pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s, cipherchars, 0); } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } @@ -1601,7 +1563,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { /* actually a client application bug */ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); goto err; } @@ -1614,7 +1575,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * overwritten if the server refuses resumption. */ if (s->session->session_id_length > 0) { - tsan_counter(&s->session_ctx->stats.sess_miss); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_miss); if (!ssl_get_new_session(s, 0)) { /* SSLfatal() already called */ goto err; @@ -1639,7 +1600,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) /* Session version and negotiated protocol version should match */ if (s->version != s->session->ssl_version) { - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_TLS_PROCESS_SERVER_HELLO, + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_SSL_SESSION_VERSION_MISMATCH); goto err; } @@ -1647,8 +1608,8 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * Now that we know the version, update the check to see if it's an allowed * version. */ - s->s3->tmp.min_ver = s->version; - s->s3->tmp.max_ver = s->version; + s->s3.tmp.min_ver = s->version; + s->s3.tmp.max_ver = s->version; if (!set_client_ciphersuite(s, cipherchars)) { /* SSLfatal() already called */ @@ -1657,7 +1618,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) #ifdef OPENSSL_NO_COMP if (compression != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SERVER_HELLO, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); goto err; } @@ -1666,32 +1627,30 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * using compression. */ if (s->session->compress_meth != 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_INCONSISTENT_COMPRESSION); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_INCONSISTENT_COMPRESSION); goto err; } #else if (s->hit && compression != s->session->compress_meth) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SERVER_HELLO, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); goto err; } if (compression == 0) comp = NULL; else if (!ssl_allow_compression(s)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SERVER_HELLO, - SSL_R_COMPRESSION_DISABLED); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COMPRESSION_DISABLED); goto err; } else { comp = ssl3_comp_find(s->ctx->comp_methods, compression); } if (compression != 0 && comp == NULL) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SERVER_HELLO, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); goto err; } else { - s->s3->tmp.new_compression = comp; + s->s3.tmp.new_compression = comp; } #endif @@ -1722,8 +1681,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SERVER_HELLO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1775,18 +1733,12 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, OPENSSL_free(extensions); extensions = NULL; - if (s->ext.tls13_cookie_len == 0 -#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) - && s->s3->tmp.pkey != NULL -#endif - ) { + if (s->ext.tls13_cookie_len == 0 && s->s3.tmp.pkey != NULL) { /* * We didn't receive a cookie or a new key_share so the next * ClientHello will not change */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST, - SSL_R_NO_CHANGE_FOLLOWING_HRR); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_CHANGE_FOLLOWING_HRR); goto err; } @@ -1817,22 +1769,17 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, return MSG_PROCESS_ERROR; } +/* prepare server cert verification by setting s->session->peer_chain from pkt */ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) { - int i; - MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; unsigned long cert_list_len, cert_len; X509 *x = NULL; const unsigned char *certstart, *certbytes; - STACK_OF(X509) *sk = NULL; - EVP_PKEY *pkey = NULL; - size_t chainidx, certidx; + size_t chainidx; unsigned int context = 0; - const SSL_CERT_LOOKUP *clu; - if ((sk = sk_X509_new_null()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - ERR_R_MALLOC_FAILURE); + if ((s->session->peer_chain = sk_X509_new_null()) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -1841,30 +1788,31 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) || !PACKET_get_net_3(pkt, &cert_list_len) || PACKET_remaining(pkt) != cert_list_len || PACKET_remaining(pkt) == 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } for (chainidx = 0; PACKET_remaining(pkt); chainidx++) { if (!PACKET_get_net_3(pkt, &cert_len) || !PACKET_get_bytes(pkt, &certbytes, cert_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_SERVER_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, cert_len); + x = X509_new_ex(s->ctx->libctx, s->ctx->propq); if (x == NULL) { - SSLfatal(s, SSL_AD_BAD_CERTIFICATE, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_ASN1_LIB); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); goto err; } + if (d2i_X509(&x, (const unsigned char **)&certbytes, + cert_len) == NULL) { + SSLfatal(s, SSL_AD_BAD_CERTIFICATE, ERR_R_ASN1_LIB); + goto err; + } + if (certbytes != (certstart + cert_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_CERT_LENGTH_MISMATCH); goto err; } @@ -1873,9 +1821,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) PACKET extensions; if (!PACKET_get_length_prefixed_2(pkt, &extensions)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); goto err; } if (!tls_collect_extensions(s, &extensions, @@ -1891,16 +1837,40 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) OPENSSL_free(rawexts); } - if (!sk_X509_push(sk, x)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - ERR_R_MALLOC_FAILURE); + if (!sk_X509_push(s->session->peer_chain, x)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } x = NULL; } + return MSG_PROCESS_CONTINUE_PROCESSING; + + err: + X509_free(x); + sk_X509_pop_free(s->session->peer_chain, X509_free); + s->session->peer_chain = NULL; + return MSG_PROCESS_ERROR; +} + +/* + * Verify the s->session->peer_chain and check server cert type. + * On success set s->session->peer and s->session->verify_result. + * Else the peer certificate verification callback may request retry. + */ +WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) +{ + X509 *x; + EVP_PKEY *pkey = NULL; + const SSL_CERT_LOOKUP *clu; + size_t certidx; + int i; - i = ssl_verify_cert_chain(s, sk); + if (s->rwstate == SSL_RETRY_VERIFY) + s->rwstate = SSL_NOTHING; + i = ssl_verify_cert_chain(s, s->session->peer_chain); + if (i > 0 && s->rwstate == SSL_RETRY_VERIFY) { + return WORK_MORE_A; + } /* * The documented interface is that SSL_VERIFY_PEER should be set in order * for client side verification of the server certificate to take place. @@ -1917,40 +1887,28 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) */ if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) { SSLfatal(s, ssl_x509err2alert(s->verify_result), - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED); - goto err; + return WORK_ERROR; } ERR_clear_error(); /* but we keep s->verify_result */ - if (i > 1) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, i); - goto err; - } - s->session->peer_chain = sk; /* * Inconsistency alert: cert_chain does include the peer's certificate, * which we don't include in statem_srvr.c */ - x = sk_X509_value(sk, 0); - sk = NULL; + x = sk_X509_value(s->session->peer_chain, 0); pkey = X509_get0_pubkey(x); if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) { - x = NULL; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); - goto err; + return WORK_ERROR; } if ((clu = ssl_cert_lookup_by_pkey(pkey, &certidx)) == NULL) { - x = NULL; - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - SSL_R_UNKNOWN_CERTIFICATE_TYPE); - goto err; + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return WORK_ERROR; } /* * Check certificate type is consistent with ciphersuite. For TLS 1.3 @@ -1958,12 +1916,9 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) * type. */ if (!SSL_IS_TLS13(s)) { - if ((clu->amask & s->s3->tmp.new_cipher->algorithm_auth) == 0) { - x = NULL; - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, - SSL_R_WRONG_CERTIFICATE_TYPE); - goto err; + if ((clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CERTIFICATE_TYPE); + return WORK_ERROR; } } @@ -1971,7 +1926,6 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) X509_up_ref(x); s->session->peer = x; s->session->verify_result = s->verify_result; - x = NULL; /* Save the current hash state for when we receive the CertificateVerify */ if (SSL_IS_TLS13(s) @@ -1979,15 +1933,9 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) sizeof(s->cert_verify_hash), &s->cert_verify_hash_len)) { /* SSLfatal() already called */; - goto err; + return WORK_ERROR; } - - ret = MSG_PROCESS_CONTINUE_READING; - - err: - X509_free(x); - sk_X509_pop_free(sk, X509_free); - return ret; + return WORK_FINISHED_CONTINUE; } static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt) @@ -1998,8 +1946,7 @@ static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt) /* PSK ciphersuites are preceded by an identity hint */ if (!PACKET_get_length_prefixed_2(pkt, &psk_identity_hint)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -2010,9 +1957,7 @@ static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt) * identity. */ if (PACKET_remaining(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, - SSL_R_DATA_LENGTH_TOO_LONG); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } @@ -2021,15 +1966,13 @@ static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt) s->session->psk_identity_hint = NULL; } else if (!PACKET_strndup(&psk_identity_hint, &s->session->psk_identity_hint)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } return 1; #else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } @@ -2043,12 +1986,10 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) || !PACKET_get_length_prefixed_2(pkt, &generator) || !PACKET_get_length_prefixed_1(pkt, &salt) || !PACKET_get_length_prefixed_2(pkt, &server_pub)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SKE_SRP, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - /* TODO(size_t): Convert BN_bin2bn() calls */ if ((s->srp_ctx.N = BN_bin2bn(PACKET_data(&prime), (int)PACKET_remaining(&prime), NULL)) == NULL @@ -2061,8 +2002,7 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) || (s->srp_ctx.B = BN_bin2bn(PACKET_data(&server_pub), (int)PACKET_remaining(&server_pub), NULL)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_SRP, - ERR_R_BN_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB); return 0; } @@ -2072,128 +2012,114 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) } /* We must check if there is a certificate */ - if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS)) + if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS)) *pkey = X509_get0_pubkey(s->session->peer); return 1; #else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_SRP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) { -#ifndef OPENSSL_NO_DH PACKET prime, generator, pub_key; EVP_PKEY *peer_tmp = NULL; - - DH *dh = NULL; BIGNUM *p = NULL, *g = NULL, *bnpub_key = NULL; - - int check_bits = 0; + EVP_PKEY_CTX *pctx = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM_BLD *tmpl = NULL; + int ret = 0; if (!PACKET_get_length_prefixed_2(pkt, &prime) || !PACKET_get_length_prefixed_2(pkt, &generator) || !PACKET_get_length_prefixed_2(pkt, &pub_key)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - peer_tmp = EVP_PKEY_new(); - dh = DH_new(); - - if (peer_tmp == NULL || dh == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - /* TODO(size_t): Convert these calls */ p = BN_bin2bn(PACKET_data(&prime), (int)PACKET_remaining(&prime), NULL); g = BN_bin2bn(PACKET_data(&generator), (int)PACKET_remaining(&generator), NULL); bnpub_key = BN_bin2bn(PACKET_data(&pub_key), (int)PACKET_remaining(&pub_key), NULL); if (p == NULL || g == NULL || bnpub_key == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - ERR_R_BN_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BN_LIB); goto err; } - /* test non-zero pubkey */ - if (BN_is_zero(bnpub_key)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SKE_DHE, - SSL_R_BAD_DH_VALUE); + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g) + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, + bnpub_key) + || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if (!DH_set0_pqg(dh, p, NULL, g)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - ERR_R_BN_LIB); + pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq); + if (pctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - p = g = NULL; - - if (DH_check_params(dh, &check_bits) == 0 || check_bits != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SKE_DHE, - SSL_R_BAD_DH_VALUE); + if (EVP_PKEY_fromdata_init(pctx) <= 0 + || EVP_PKEY_fromdata(pctx, &peer_tmp, EVP_PKEY_KEYPAIR, params) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_DH_VALUE); goto err; } - if (!DH_set0_key(dh, bnpub_key, NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - ERR_R_BN_LIB); - goto err; - } - bnpub_key = NULL; - - if (EVP_PKEY_assign_DH(peer_tmp, dh) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - ERR_R_EVP_LIB); + EVP_PKEY_CTX_free(pctx); + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, peer_tmp, s->ctx->propq); + if (pctx == NULL + /* + * EVP_PKEY_param_check() will verify that the DH params are using + * a safe prime. In this context, because we're using ephemeral DH, + * we're ok with it not being a safe prime. + * EVP_PKEY_param_check_quick() skips the safe prime check. + */ + || EVP_PKEY_param_check_quick(pctx) != 1 + || EVP_PKEY_public_check(pctx) != 1) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE); goto err; } - dh = NULL; - if (!ssl_security(s, SSL_SECOP_TMP_DH, EVP_PKEY_security_bits(peer_tmp), + if (!ssl_security(s, SSL_SECOP_TMP_DH, + EVP_PKEY_get_security_bits(peer_tmp), 0, peer_tmp)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_PROCESS_SKE_DHE, - SSL_R_DH_KEY_TOO_SMALL); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_DH_KEY_TOO_SMALL); goto err; } - s->s3->peer_tmp = peer_tmp; + s->s3.peer_tmp = peer_tmp; + peer_tmp = NULL; /* * FIXME: This makes assumptions about which ciphersuites come with * public keys. We should have a less ad-hoc way of doing this */ - if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS)) + if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS)) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous DH, so no certificate or pkey. */ - return 1; + ret = 1; err: + OSSL_PARAM_BLD_free(tmpl); + OSSL_PARAM_free(params); + EVP_PKEY_free(peer_tmp); + EVP_PKEY_CTX_free(pctx); BN_free(p); BN_free(g); BN_free(bnpub_key); - DH_free(dh); - EVP_PKEY_free(peer_tmp); - return 0; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_DHE, - ERR_R_INTERNAL_ERROR); - return 0; -#endif + return ret; } static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) { -#ifndef OPENSSL_NO_EC PACKET encoded_pt; unsigned int curve_type, curve_id; @@ -2203,8 +2129,7 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) * ECParameters in this case is just three bytes. */ if (!PACKET_get_1(pkt, &curve_type) || !PACKET_get_net_2(pkt, &curve_id)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE, - SSL_R_LENGTH_TOO_SHORT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); return 0; } /* @@ -2213,28 +2138,25 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) */ if (curve_type != NAMED_CURVE_TYPE || !tls1_check_group_id(s, curve_id, 1)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SKE_ECDHE, - SSL_R_WRONG_CURVE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); return 0; } - if ((s->s3->peer_tmp = ssl_generate_param_group(curve_id)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE, + if ((s->s3.peer_tmp = ssl_generate_param_group(s, curve_id)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); return 0; } if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp, - PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_SKE_ECDHE, - SSL_R_BAD_ECPOINT); + if (EVP_PKEY_set1_encoded_public_key(s->s3.peer_tmp, + PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt)) <= 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_ECPOINT); return 0; } @@ -2243,18 +2165,15 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) * ECParameters in the server key exchange message. We do support RSA * and ECDSA. */ - if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aECDSA) + if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aECDSA) *pkey = X509_get0_pubkey(s->session->peer); - else if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aRSA) + else if (s->s3.tmp.new_cipher->algorithm_auth & SSL_aRSA) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous ECDH, so no certificate or pkey. */ + /* Cache the agreed upon group in the SSL_SESSION */ + s->session->kex_group = curve_id; return 1; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE, - ERR_R_INTERNAL_ERROR); - return 0; -#endif } MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) @@ -2265,14 +2184,12 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) EVP_PKEY_CTX *pctx = NULL; PACKET save_param_start, signature; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_k = s->s3.tmp.new_cipher->algorithm_mkey; save_param_start = *pkt; -#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) - EVP_PKEY_free(s->s3->peer_tmp); - s->s3->peer_tmp = NULL; -#endif + EVP_PKEY_free(s->s3.peer_tmp); + s->s3.peer_tmp = NULL; if (alg_k & SSL_PSK) { if (!tls_process_ske_psk_preamble(s, pkt)) { @@ -2299,15 +2216,13 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; } } else if (alg_k) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto err; } /* if it was signed, check the signature */ if (pkey != NULL) { PACKET params; - int maxsig; const EVP_MD *md = NULL; unsigned char *tbs; size_t tbslen; @@ -2320,8 +2235,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (!PACKET_get_sub_packet(&save_param_start, ¶ms, PACKET_remaining(&save_param_start) - PACKET_remaining(pkt))) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -2329,8 +2243,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) unsigned int sigalg; if (!PACKET_get_net_2(pkt, &sigalg)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_LENGTH_TOO_SHORT); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); goto err; } if (tls12_check_peer_sigalg(s, sigalg, pkey) <=0) { @@ -2338,63 +2251,44 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; } } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED); goto err; } - if (!tls1_lookup_md(s->s3->tmp.peer_sigalg, &md)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); goto err; } -#ifdef SSL_DEBUG if (SSL_USE_SIGALGS(s)) - fprintf(stderr, "USING TLSv1.2 HASH %s\n", - md == NULL ? "n/a" : EVP_MD_name(md)); -#endif + OSSL_TRACE1(TLS, "USING TLSv1.2 HASH %s\n", + md == NULL ? "n/a" : EVP_MD_get0_name(md)); if (!PACKET_get_length_prefixed_2(pkt, &signature) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_LENGTH_MISMATCH); - goto err; - } - maxsig = EVP_PKEY_size(pkey); - if (maxsig < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - /* - * Check signature length - */ - if (PACKET_remaining(&signature) > (size_t)maxsig) { - /* wrong packet length */ - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_WRONG_SIGNATURE_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_DigestVerifyInit(md_ctx, &pctx, md, NULL, pkey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_EVP_LIB); + if (EVP_DigestVerifyInit_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_EVP_LIB); goto err; } if (SSL_USE_PSS(s)) { 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_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } } @@ -2409,28 +2303,25 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) PACKET_remaining(&signature), tbs, tbslen); OPENSSL_free(tbs); if (rv <= 0) { - SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_BAD_SIGNATURE); + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_BAD_SIGNATURE); goto err; } EVP_MD_CTX_free(md_ctx); md_ctx = NULL; } else { /* aNULL, aSRP or PSK do not need public keys */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) + if (!(s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_PSK)) { /* Might be wrong key type, check it */ if (ssl3_check_cert_and_algorithm(s)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_BAD_DATA); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_DATA); } /* else this shouldn't happen, SSLfatal() already called */ goto err; } /* still data left over */ if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - SSL_R_EXTRA_DATA_IN_MESSAGE); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_EXTRA_DATA_IN_MESSAGE); goto err; } } @@ -2447,7 +2338,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) /* Clear certificate validity flags */ for (i = 0; i < SSL_PKEY_NUM; i++) - s->s3->tmp.valid_flags[i] = 0; + s->s3.tmp.valid_flags[i] = 0; if (SSL_IS_TLS13(s)) { PACKET reqctx, extensions; @@ -2463,25 +2354,21 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) } /* Free and zero certificate types: it is not present in TLS 1.3 */ - OPENSSL_free(s->s3->tmp.ctype); - s->s3->tmp.ctype = NULL; - s->s3->tmp.ctype_len = 0; + OPENSSL_free(s->s3.tmp.ctype); + s->s3.tmp.ctype = NULL; + s->s3.tmp.ctype_len = 0; OPENSSL_free(s->pha_context); s->pha_context = NULL; s->pha_context_len = 0; if (!PACKET_get_length_prefixed_1(pkt, &reqctx) || !PACKET_memdup(&reqctx, &s->pha_context, &s->pha_context_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } if (!PACKET_get_length_prefixed_2(pkt, &extensions)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); return MSG_PROCESS_ERROR; } if (!tls_collect_extensions(s, &extensions, @@ -2495,9 +2382,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) } OPENSSL_free(rawexts); if (!tls1_process_sigalgs(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_LENGTH); return MSG_PROCESS_ERROR; } } else { @@ -2505,16 +2390,12 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) /* get the certificate types */ if (!PACKET_get_length_prefixed_1(pkt, &ctypes)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } - if (!PACKET_memdup(&ctypes, &s->s3->tmp.ctype, &s->s3->tmp.ctype_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - ERR_R_INTERNAL_ERROR); + if (!PACKET_memdup(&ctypes, &s->s3.tmp.ctype, &s->s3.tmp.ctype_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; } @@ -2522,9 +2403,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) PACKET sigalgs; if (!PACKET_get_length_prefixed_2(pkt, &sigalgs)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } @@ -2534,14 +2413,11 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) */ if (!tls1_save_sigalgs(s, &sigalgs, 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_SIGNATURE_ALGORITHMS_ERROR); return MSG_PROCESS_ERROR; } if (!tls1_process_sigalgs(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return MSG_PROCESS_ERROR; } } @@ -2554,21 +2430,19 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) } if (PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } /* we should setup a certificate to return.... */ - s->s3->tmp.cert_req = 1; + s->s3.tmp.cert_req = 1; /* * In TLSv1.3 we don't prepare the client certificate yet. We wait until * after the CertificateVerify message has been received. This is because * in TLSv1.3 the CertificateRequest arrives before the Certificate message * but in TLSv1.2 it is the other way around. We want to make sure that - * SSL_get_peer_certificate() returns something sensible in + * SSL_get1_peer_certificate() returns something sensible in * client_cert_cb. */ if (SSL_IS_TLS13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED) @@ -2584,6 +2458,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) unsigned int sess_len; RAW_EXTENSION *exts = NULL; PACKET nonce; + EVP_MD *sha256 = NULL; PACKET_null_init(&nonce); @@ -2594,8 +2469,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) || !PACKET_get_net_2(pkt, &ticklen) || (SSL_IS_TLS13(s) ? (ticklen == 0 || PACKET_remaining(pkt) < ticklen) : PACKET_remaining(pkt) != ticklen)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -2623,9 +2497,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) * one */ if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -2643,11 +2515,8 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session = new_sess; } - /* - * Technically the cast to long here is not guaranteed by the C standard - - * but we use it elsewhere, so this should be ok. - */ - s->session->time = (long)time(NULL); + s->session->time = time(NULL); + ssl_session_calculate_timeout(s->session); OPENSSL_free(s->session->ext.tick); s->session->ext.tick = NULL; @@ -2655,13 +2524,11 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session->ext.tick = OPENSSL_malloc(ticklen); if (s->session->ext.tick == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } if (!PACKET_copy_bytes(pkt, s->session->ext.tick, ticklen)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -2674,9 +2541,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) if (!PACKET_as_length_prefixed_2(pkt, &extpkt) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -2699,35 +2564,40 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) * other way is to set zero length session ID when the ticket is * presented and rely on the handshake to determine session resumption. * We choose the former approach because this fits in with assumptions - * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is - * SHA256 is disabled) hash of the ticket. + * elsewhere in OpenSSL. The session ID is set to the SHA256 hash of the + * ticket. */ + sha256 = EVP_MD_fetch(s->ctx->libctx, "SHA2-256", s->ctx->propq); + if (sha256 == NULL) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); + goto err; + } /* - * TODO(size_t): we use sess_len here because EVP_Digest expects an int + * We use sess_len here because EVP_Digest expects an int * but s->session->session_id_length is a size_t */ if (!EVP_Digest(s->session->ext.tick, ticklen, s->session->session_id, &sess_len, - EVP_sha256(), NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - ERR_R_EVP_LIB); + sha256, NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } + EVP_MD_free(sha256); + sha256 = NULL; s->session->session_id_length = sess_len; s->session->not_resumable = 0; /* This is a standalone message in TLSv1.3, so there is no more to read */ if (SSL_IS_TLS13(s)) { const EVP_MD *md = ssl_handshake_md(s); - int hashleni = EVP_MD_size(md); + int hashleni = EVP_MD_get_size(md); size_t hashlen; static const unsigned char nonce_label[] = "resumption"; /* Ensure cast to size_t is safe */ if (!ossl_assert(hashleni >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } hashlen = (size_t)hashleni; @@ -2751,6 +2621,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) return MSG_PROCESS_CONTINUE_READING; err: + EVP_MD_free(sha256); OPENSSL_free(exts); return MSG_PROCESS_ERROR; } @@ -2766,27 +2637,23 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt) if (!PACKET_get_1(pkt, &type) || type != TLSEXT_STATUSTYPE_ocsp) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY, - SSL_R_UNSUPPORTED_STATUS_TYPE); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_UNSUPPORTED_STATUS_TYPE); return 0; } if (!PACKET_get_net_3_len(pkt, &resplen) || PACKET_remaining(pkt) != resplen) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } s->ext.ocsp.resp = OPENSSL_malloc(resplen); if (s->ext.ocsp.resp == NULL) { s->ext.ocsp.resp_len = 0; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } s->ext.ocsp.resp_len = resplen; if (!PACKET_copy_bytes(pkt, s->ext.ocsp.resp, resplen)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_STATUS_BODY, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } @@ -2832,13 +2699,11 @@ int tls_process_initial_server_flight(SSL *s) if (ret == 0) { SSLfatal(s, SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE, - SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT, SSL_R_INVALID_STATUS_RESPONSE); return 0; } if (ret < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT, SSL_R_OCSP_CALLBACK_FAILURE); return 0; } @@ -2860,15 +2725,13 @@ MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt) { if (PACKET_remaining(pkt) > 0) { /* should contain no data */ - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_DONE, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } #ifndef OPENSSL_NO_SRP - if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { - if (SRP_Calc_A_param(s) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SERVER_DONE, - SSL_R_SRP_A_CALC); + if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kSRP) { + if (ssl_srp_calc_a_param_intern(s) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SRP_A_CALC); return MSG_PROCESS_ERROR; } } @@ -2899,8 +2762,7 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) size_t psklen = 0; if (s->psk_client_callback == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, - SSL_R_PSK_NO_CLIENT_CB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_PSK_NO_CLIENT_CB); goto err; } @@ -2911,43 +2773,37 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) psk, sizeof(psk)); if (psklen > PSK_MAX_PSK_LEN) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); psklen = PSK_MAX_PSK_LEN; /* Avoid overrunning the array on cleanse */ goto err; } else if (psklen == 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, - SSL_R_PSK_IDENTITY_NOT_FOUND); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_PSK_IDENTITY_NOT_FOUND); goto err; } identitylen = strlen(identity); if (identitylen > PSK_MAX_IDENTITY_LEN) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } tmppsk = OPENSSL_memdup(psk, psklen); tmpidentity = OPENSSL_strdup(identity); if (tmppsk == NULL || tmpidentity == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - OPENSSL_free(s->s3->tmp.psk); - s->s3->tmp.psk = tmppsk; - s->s3->tmp.psklen = psklen; + OPENSSL_free(s->s3.tmp.psk); + s->s3.tmp.psk = tmppsk; + s->s3.tmp.psklen = psklen; tmppsk = NULL; OPENSSL_free(s->session->psk_identity); s->session->psk_identity = tmpidentity; tmpidentity = NULL; if (!WPACKET_sub_memcpy_u16(pkt, identity, identitylen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -2961,15 +2817,13 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) return ret; #else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) { -#ifndef OPENSSL_NO_RSA unsigned char *encdata = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *pctx = NULL; @@ -2981,52 +2835,45 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) /* * We should always have a server certificate with SSL_kRSA. */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } pkey = X509_get0_pubkey(s->session->peer); - if (EVP_PKEY_get0_RSA(pkey) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_INTERNAL_ERROR); + if (!EVP_PKEY_is_a(pkey, "RSA")) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } pmslen = SSL_MAX_MASTER_KEY_LENGTH; pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } pms[0] = s->client_version >> 8; pms[1] = s->client_version & 0xff; - /* TODO(size_t): Convert this function */ - if (RAND_bytes(pms + 2, (int)(pmslen - 2)) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_MALLOC_FAILURE); + if (RAND_bytes_ex(s->ctx->libctx, pms + 2, pmslen - 2, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION && !WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - pctx = EVP_PKEY_CTX_new(pkey, NULL); + + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pkey, s->ctx->propq); if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0 || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } if (!WPACKET_allocate_bytes(pkt, enclen, &encdata) || EVP_PKEY_encrypt(pctx, encdata, &enclen, pms, pmslen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - SSL_R_BAD_RSA_ENCRYPT); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_RSA_ENCRYPT); goto err; } EVP_PKEY_CTX_free(pctx); @@ -3034,8 +2881,7 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION && !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3045,8 +2891,8 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) goto err; } - s->s3->tmp.pms = pms; - s->s3->tmp.pmslen = pmslen; + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; return 1; err: @@ -3054,40 +2900,26 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) EVP_PKEY_CTX_free(pctx); return 0; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_RSA, - ERR_R_INTERNAL_ERROR); - return 0; -#endif } static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) { -#ifndef OPENSSL_NO_DH - DH *dh_clnt = NULL; - const BIGNUM *pub_key; EVP_PKEY *ckey = NULL, *skey = NULL; unsigned char *keybytes = NULL; + int prime_len; + unsigned char *encoded_pub = NULL; + size_t encoded_pub_len, pad_len; + int ret = 0; - skey = s->s3->peer_tmp; + skey = s->s3.peer_tmp; if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - ckey = ssl_generate_pkey(skey); + ckey = ssl_generate_pkey(s, skey); if (ckey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - dh_clnt = EVP_PKEY_get0_DH(ckey); - - if (dh_clnt == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3097,47 +2929,58 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) } /* send off the data */ - DH_get0_key(dh_clnt, &pub_key, NULL); - if (!WPACKET_sub_allocate_bytes_u16(pkt, BN_num_bytes(pub_key), - &keybytes)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE, - ERR_R_INTERNAL_ERROR); - goto err; + + /* Generate encoding of server key */ + encoded_pub_len = EVP_PKEY_get1_encoded_public_key(ckey, &encoded_pub); + if (encoded_pub_len == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(ckey); + return EXT_RETURN_FAIL; } - BN_bn2bin(pub_key, keybytes); - EVP_PKEY_free(ckey); + /* + * For interoperability with some versions of the Microsoft TLS + * stack, we need to zero pad the DHE pub key to the same length + * as the prime. + */ + prime_len = EVP_PKEY_get_size(ckey); + pad_len = prime_len - encoded_pub_len; + if (pad_len > 0) { + if (!WPACKET_sub_allocate_bytes_u16(pkt, pad_len, &keybytes)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + memset(keybytes, 0, pad_len); + } - return 1; + if (!WPACKET_sub_memcpy_u16(pkt, encoded_pub, encoded_pub_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; err: + OPENSSL_free(encoded_pub); EVP_PKEY_free(ckey); - return 0; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE, - ERR_R_INTERNAL_ERROR); - return 0; -#endif + return ret; } static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) { -#ifndef OPENSSL_NO_EC unsigned char *encodedPoint = NULL; size_t encoded_pt_len = 0; EVP_PKEY *ckey = NULL, *skey = NULL; int ret = 0; - skey = s->s3->peer_tmp; + skey = s->s3.peer_tmp; if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - ckey = ssl_generate_pkey(skey); + ckey = ssl_generate_pkey(s, skey); if (ckey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -3147,17 +2990,15 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) } /* Generate encoding of client key */ - encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(ckey, &encodedPoint); + encoded_pt_len = EVP_PKEY_get1_encoded_public_key(ckey, &encodedPoint); if (encoded_pt_len == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, - ERR_R_EC_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EC_LIB); goto err; } if (!WPACKET_sub_memcpy_u8(pkt, encodedPoint, encoded_pt_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3166,11 +3007,6 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) OPENSSL_free(encodedPoint); EVP_PKEY_free(ckey); return ret; -#else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, - ERR_R_INTERNAL_ERROR); - return 0; -#endif } static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) @@ -3187,23 +3023,24 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) unsigned char *pms = NULL; size_t pmslen = 0; - if ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0) + if ((s->s3.tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0) dgst_nid = NID_id_GostR3411_2012_256; /* * Get server certificate PKEY and create ctx from it */ peer_cert = s->session->peer; - if (!peer_cert) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CONSTRUCT_CKE_GOST, - SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + if (peer_cert == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); return 0; } - pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL); + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, + X509_get0_pubkey(peer_cert), + s->ctx->propq); if (pkey_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } /* @@ -3216,18 +3053,15 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) pmslen = 32; pms = OPENSSL_malloc(pmslen); if (pms == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 /* Generate session key - * TODO(size_t): Convert this function */ - || RAND_bytes(pms, (int)pmslen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - ERR_R_INTERNAL_ERROR); + || RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; }; /* @@ -3237,21 +3071,19 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) ukm_hash = EVP_MD_CTX_new(); if (ukm_hash == NULL || EVP_DigestInit(ukm_hash, EVP_get_digestbynid(dgst_nid)) <= 0 - || EVP_DigestUpdate(ukm_hash, s->s3->client_random, + || EVP_DigestUpdate(ukm_hash, s->s3.client_random, SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(ukm_hash, s->s3->server_random, + || EVP_DigestUpdate(ukm_hash, s->s3.server_random, SSL3_RANDOM_SIZE) <= 0 || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } EVP_MD_CTX_free(ukm_hash); ukm_hash = NULL; if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - SSL_R_LIBRARY_BUG); + EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); goto err; } /* Make GOST keytransport blob message */ @@ -3260,22 +3092,20 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) */ msglen = 255; if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - SSL_R_LIBRARY_BUG); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); goto err; } if (!WPACKET_put_bytes_u8(pkt, V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) || (msglen >= 0x80 && !WPACKET_put_bytes_u8(pkt, 0x81)) || !WPACKET_sub_memcpy_u8(pkt, tmp, msglen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } EVP_PKEY_CTX_free(pkey_ctx); - s->s3->tmp.pms = pms; - s->s3->tmp.pmslen = pmslen; + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; return 1; err: @@ -3284,8 +3114,140 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) EVP_MD_CTX_free(ukm_hash); return 0; #else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; +#endif +} + +#ifndef OPENSSL_NO_GOST +int ossl_gost18_cke_cipher_nid(const SSL *s) +{ + if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0) + return NID_magma_ctr; + else if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_KUZNYECHIK) != 0) + return NID_kuznyechik_ctr; + + return NID_undef; +} + +int ossl_gost_ukm(const SSL *s, unsigned char *dgst_buf) +{ + EVP_MD_CTX * hash = NULL; + unsigned int md_len; + const EVP_MD *md = ssl_evp_md_fetch(s->ctx->libctx, NID_id_GostR3411_2012_256, s->ctx->propq); + + if (md == NULL) + return 0; + + if ((hash = EVP_MD_CTX_new()) == NULL + || EVP_DigestInit(hash, md) <= 0 + || EVP_DigestUpdate(hash, s->s3.client_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(hash, s->s3.server_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestFinal_ex(hash, dgst_buf, &md_len) <= 0) { + EVP_MD_CTX_free(hash); + ssl_evp_md_free(md); + return 0; + } + + EVP_MD_CTX_free(hash); + ssl_evp_md_free(md); + return 1; +} +#endif + +static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) +{ +#ifndef OPENSSL_NO_GOST + /* GOST 2018 key exchange message creation */ + unsigned char rnd_dgst[32]; + unsigned char *encdata = NULL; + EVP_PKEY_CTX *pkey_ctx = NULL; + X509 *peer_cert; + unsigned char *pms = NULL; + size_t pmslen = 0; + size_t msglen; + 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; + } + + /* Pre-master secret - random bytes */ + pmslen = 32; + pms = OPENSSL_malloc(pmslen); + if (pms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Get server certificate PKEY and create ctx from it */ + peer_cert = s->session->peer; + if (peer_cert == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + goto err; + } + + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, + X509_get0_pubkey(peer_cert), + s->ctx->propq); + if (pkey_ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt_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 */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, + 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_ENCRYPT, + EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); + goto err; + } + + if (EVP_PKEY_encrypt(pkey_ctx, NULL, &msglen, pms, pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + goto err; + } + + if (!WPACKET_allocate_bytes(pkt, msglen, &encdata) + || EVP_PKEY_encrypt(pkey_ctx, encdata, &msglen, pms, pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + goto err; + } + + EVP_PKEY_CTX_free(pkey_ctx); + pkey_ctx = NULL; + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; + + return 1; + err: + EVP_PKEY_CTX_free(pkey_ctx); + OPENSSL_clear_free(pms, pmslen); + return 0; +#else + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } @@ -3298,8 +3260,7 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) if (s->srp_ctx.A == NULL || !WPACKET_sub_allocate_bytes_u16(pkt, BN_num_bytes(s->srp_ctx.A), &abytes)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_SRP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } BN_bn2bin(s->srp_ctx.A, abytes); @@ -3307,15 +3268,13 @@ static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) 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_CONSTRUCT_CKE_SRP, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } return 1; #else - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_SRP, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; #endif } @@ -3324,7 +3283,7 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) { unsigned long alg_k; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_k = s->s3.tmp.new_cipher->algorithm_mkey; /* * All of the construct functions below call SSLfatal() if necessary so @@ -3346,24 +3305,26 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) } else if (alg_k & SSL_kGOST) { if (!tls_construct_cke_gost(s, pkt)) goto err; + } else if (alg_k & SSL_kGOST18) { + if (!tls_construct_cke_gost18(s, pkt)) + goto err; } else if (alg_k & SSL_kSRP) { if (!tls_construct_cke_srp(s, pkt)) goto err; } else if (!(alg_k & SSL_kPSK)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } return 1; err: - OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen); - s->s3->tmp.pms = NULL; - s->s3->tmp.pmslen = 0; + OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); + s->s3.tmp.pms = NULL; + s->s3.tmp.pmslen = 0; #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 0; } @@ -3373,12 +3334,12 @@ int tls_client_key_exchange_post_work(SSL *s) unsigned char *pms = NULL; size_t pmslen = 0; - pms = s->s3->tmp.pms; - pmslen = s->s3->tmp.pmslen; + pms = s->s3.tmp.pms; + pmslen = s->s3.tmp.pmslen; #ifndef OPENSSL_NO_SRP /* Check for SRP */ - if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { + if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kSRP) { if (!srp_generate_client_master_secret(s)) { /* SSLfatal() already called */ goto err; @@ -3387,9 +3348,8 @@ int tls_client_key_exchange_post_work(SSL *s) } #endif - if (pms == NULL && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, ERR_R_MALLOC_FAILURE); + if (pms == NULL && !(s->s3.tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } if (!ssl_generate_master_secret(s, pms, pmslen, 1)) { @@ -3423,9 +3383,7 @@ int tls_client_key_exchange_post_work(SSL *s) if (SSL_export_keying_material(s, sctpauthkey, sizeof(sctpauthkey), labelbuffer, labellen, NULL, 0, 0) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3437,8 +3395,8 @@ int tls_client_key_exchange_post_work(SSL *s) return 1; err: OPENSSL_clear_free(pms, pmslen); - s->s3->tmp.pms = NULL; - s->s3->tmp.pmslen = 0; + s->s3.tmp.pms = NULL; + s->s3.tmp.pmslen = 0; return 0; } @@ -3450,7 +3408,7 @@ int tls_client_key_exchange_post_work(SSL *s) static int ssl3_check_client_certificate(SSL *s) { /* If no suitable signature algorithm can't use certificate */ - if (!tls_choose_sigalg(s, 0) || s->s3->tmp.sigalg == NULL) + if (!tls_choose_sigalg(s, 0) || s->s3.tmp.sigalg == NULL) return 0; /* * If strict mode check suitability of chain before using it. This also @@ -3477,9 +3435,7 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) return WORK_MORE_A; } if (i == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE, - SSL_R_CALLBACK_FAILED); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED); return WORK_ERROR; } s->rwstate = SSL_NOTHING; @@ -3512,8 +3468,7 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) i = 0; } else if (i == 1) { i = 0; - SSLerr(SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE, - SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); } X509_free(x509); @@ -3522,11 +3477,11 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) i = 0; if (i == 0) { if (s->version == SSL3_VERSION) { - s->s3->tmp.cert_req = 0; + s->s3.tmp.cert_req = 0; ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); return WORK_FINISHED_CONTINUE; } else { - s->s3->tmp.cert_req = 2; + s->s3.tmp.cert_req = 2; if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ return WORK_ERROR; @@ -3540,8 +3495,7 @@ WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst) } /* Shouldn't ever get here */ - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } @@ -3551,18 +3505,16 @@ int tls_construct_client_certificate(SSL *s, WPACKET *pkt) if (s->pha_context == NULL) { /* no context available, add 0-length context */ if (!WPACKET_put_bytes_u8(pkt, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } else if (!WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } if (!ssl3_output_cert_chain(s, pkt, - (s->s3->tmp.cert_req == 2) ? NULL + (s->s3.tmp.cert_req == 2) ? NULL : s->cert->key)) { /* SSLfatal() already called */ return 0; @@ -3576,8 +3528,7 @@ int tls_construct_client_certificate(SSL *s, WPACKET *pkt) * This is a fatal error, which leaves enc_write_ctx in an inconsistent * state and thus ssl3_send_alert may crash. */ - SSLfatal(s, SSL_AD_NO_ALERT, SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, - SSL_R_CANNOT_CHANGE_CIPHER); + SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_CANNOT_CHANGE_CIPHER); return 0; } @@ -3590,8 +3541,8 @@ int ssl3_check_cert_and_algorithm(SSL *s) size_t idx; long alg_k, alg_a; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; + alg_k = s->s3.tmp.new_cipher->algorithm_mkey; + alg_a = s->s3.tmp.new_cipher->algorithm_auth; /* we don't have a certificate */ if (!(alg_a & SSL_aCERT)) @@ -3602,36 +3553,27 @@ int ssl3_check_cert_and_algorithm(SSL *s) /* Check certificate is recognised and suitable for cipher */ if (clu == NULL || (alg_a & clu->amask) == 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_SIGNING_CERT); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_MISSING_SIGNING_CERT); return 0; } -#ifndef OPENSSL_NO_EC if (clu->amask & SSL_aECDSA) { if (ssl_check_srvr_ecc_cert_and_alg(s->session->peer, s)) return 1; - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_ECC_CERT); return 0; } -#endif -#ifndef OPENSSL_NO_RSA + if (alg_k & (SSL_kRSA | SSL_kRSAPSK) && idx != SSL_PKEY_RSA) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_RSA_ENCRYPTING_CERT); return 0; } -#endif -#ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kDHE) && (s->s3->peer_tmp == NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - ERR_R_INTERNAL_ERROR); + + if ((alg_k & SSL_kDHE) && (s->s3.peer_tmp == NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } -#endif return 1; } @@ -3647,8 +3589,7 @@ int tls_construct_next_proto(SSL *s, WPACKET *pkt) if (!WPACKET_sub_memcpy_u8(pkt, s->ext.npn, len) || !WPACKET_sub_allocate_bytes_u8(pkt, padding_len, &padding)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_NEXT_PROTO, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -3662,8 +3603,7 @@ MSG_PROCESS_RETURN tls_process_hello_req(SSL *s, PACKET *pkt) { if (PACKET_remaining(pkt) > 0) { /* should contain no data */ - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_HELLO_REQ, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return MSG_PROCESS_ERROR; } @@ -3694,8 +3634,7 @@ static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt) if (!PACKET_as_length_prefixed_2(pkt, &extensions) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -3721,9 +3660,7 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) int i = 0; #ifndef OPENSSL_NO_ENGINE if (s->ctx->client_cert_engine) { - i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, - SSL_get_client_CA_list(s), - px509, ppkey, NULL, NULL, NULL); + i = tls_engine_load_ssl_client_cert(s, px509, ppkey); if (i != 0) return i; } @@ -3741,14 +3678,12 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) /* Set disabled masks for this session */ if (!ssl_set_client_disabled(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CIPHER_LIST_TO_BYTES, - SSL_R_NO_PROTOCOLS_AVAILABLE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_PROTOCOLS_AVAILABLE); return 0; } if (sk == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CIPHER_LIST_TO_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -3782,20 +3717,19 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) continue; if (!s->method->put_cipher_by_char(c, pkt, &len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CIPHER_LIST_TO_BYTES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* Sanity check that the maximum version we offer has ciphers enabled */ if (!maxverok) { if (SSL_IS_DTLS(s)) { - if (DTLS_VERSION_GE(c->max_dtls, s->s3->tmp.max_ver) - && DTLS_VERSION_LE(c->min_dtls, s->s3->tmp.max_ver)) + if (DTLS_VERSION_GE(c->max_dtls, s->s3.tmp.max_ver) + && DTLS_VERSION_LE(c->min_dtls, s->s3.tmp.max_ver)) maxverok = 1; } else { - if (c->max_tls >= s->s3->tmp.max_ver - && c->min_tls <= s->s3->tmp.max_ver) + if (c->max_tls >= s->s3.tmp.max_ver + && c->min_tls <= s->s3.tmp.max_ver) maxverok = 1; } } @@ -3804,13 +3738,13 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) } if (totlen == 0 || !maxverok) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CIPHER_LIST_TO_BYTES, - SSL_R_NO_CIPHERS_AVAILABLE); - - if (!maxverok) - ERR_add_error_data(1, "No ciphers enabled for max supported " - "SSL/TLS version"); + const char *maxvertext = + !maxverok + ? "No ciphers enabled for max supported SSL/TLS version" + : NULL; + SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_CIPHERS_AVAILABLE, + maxvertext); return 0; } @@ -3820,8 +3754,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) 0, NULL, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (!s->method->put_cipher_by_char(&scsv, pkt, &len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL_CIPHER_LIST_TO_BYTES, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -3830,8 +3763,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, WPACKET *pkt) 0, NULL, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (!s->method->put_cipher_by_char(&scsv, pkt, &len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SSL_CIPHER_LIST_TO_BYTES, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -3844,9 +3776,7 @@ int tls_construct_end_of_early_data(SSL *s, WPACKET *pkt) { if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index 8fe6cea72359..788d0eff656b 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -1,7 +1,7 @@ /* * Copyright 2005-2022 The OpenSSL Project Authors. 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 @@ -60,13 +60,13 @@ static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) unsigned char *bitmask = NULL; if ((frag = OPENSSL_malloc(sizeof(*frag))) == NULL) { - SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return NULL; } if (frag_len) { if ((buf = OPENSSL_malloc(frag_len)) == NULL) { - SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(frag); return NULL; } @@ -79,7 +79,7 @@ static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) if (reassembly) { bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len)); if (bitmask == NULL) { - SSLerr(SSL_F_DTLS1_HM_FRAGMENT_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); OPENSSL_free(buf); OPENSSL_free(frag); return NULL; @@ -132,17 +132,17 @@ int dtls1_do_write(SSL *s, int type) if (s->write_hash) { if (s->enc_write_ctx - && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) & + && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) mac_size = 0; else - mac_size = EVP_MD_CTX_size(s->write_hash); + mac_size = EVP_MD_CTX_get_size(s->write_hash); } else mac_size = 0; if (s->enc_write_ctx && - (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) - blocksize = 2 * EVP_CIPHER_CTX_block_size(s->enc_write_ctx); + (EVP_CIPHER_CTX_get_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) + blocksize = 2 * EVP_CIPHER_CTX_get_block_size(s->enc_write_ctx); else blocksize = 0; @@ -328,7 +328,7 @@ int dtls1_do_write(SSL *s, int type) return 0; } -int dtls_get_message(SSL *s, int *mt, size_t *len) +int dtls_get_message(SSL *s, int *mt) { struct hm_header_st *msg_hdr; unsigned char *p; @@ -349,10 +349,9 @@ int dtls_get_message(SSL *s, int *mt, size_t *len) return 0; } - *mt = s->s3->tmp.message_type; + *mt = s->s3.tmp.message_type; p = (unsigned char *)s->init_buf->data; - *len = s->init_num; if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { if (s->msg_callback) { @@ -373,32 +372,54 @@ int dtls_get_message(SSL *s, int *mt, size_t *len) s2n(msg_hdr->seq, p); l2n3(0, p); l2n3(msg_len, p); - if (s->version != DTLS1_BAD_VER) { - p -= DTLS1_HM_HEADER_LENGTH; - msg_len += DTLS1_HM_HEADER_LENGTH; - } + memset(msg_hdr, 0, sizeof(*msg_hdr)); + + s->d1->handshake_read_seq++; + + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + + return 1; +} + +/* + * Actually we already have the message body - but this is an opportunity for + * DTLS to do any further processing it wants at the same point that TLS would + * be asked for the message body. + */ +int dtls_get_message_body(SSL *s, size_t *len) +{ + unsigned char *msg = (unsigned char *)s->init_buf->data; + size_t msg_len = s->init_num + DTLS1_HM_HEADER_LENGTH; + + if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { + /* Nothing to be done */ + goto end; + } /* * If receiving Finished, record MAC of prior handshake messages for * Finished verification. */ - if (*mt == SSL3_MT_FINISHED && !ssl3_take_mac(s)) { + if (*(s->init_buf->data) == SSL3_MT_FINISHED && !ssl3_take_mac(s)) { /* SSLfatal() already called */ return 0; } - if (!ssl3_finish_mac(s, p, msg_len)) + if (s->version == DTLS1_BAD_VER) { + msg += DTLS1_HM_HEADER_LENGTH; + msg_len -= DTLS1_HM_HEADER_LENGTH; + } + + if (!ssl3_finish_mac(s, msg, msg_len)) return 0; + if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, msg_len, s, s->msg_callback_arg); - - memset(msg_hdr, 0, sizeof(*msg_hdr)); - - s->d1->handshake_read_seq++; - - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + s->init_buf->data, s->init_num + DTLS1_HM_HEADER_LENGTH, + s, s->msg_callback_arg); + end: + *len = s->init_num; return 1; } @@ -426,8 +447,7 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) /* sanity checking */ if ((frag_off + frag_len) > msg_len || msg_len > dtls1_max_handshake_message_len(s)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_DTLS1_PREPROCESS_FRAGMENT, - SSL_R_EXCESSIVE_MESSAGE_SIZE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); return 0; } @@ -437,14 +457,13 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) * dtls_max_handshake_message_len(s) above */ if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_PREPROCESS_FRAGMENT, - ERR_R_BUF_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); return 0; } - s->s3->tmp.message_size = msg_len; + s->s3.tmp.message_size = msg_len; s->d1->r_msg_hdr.msg_len = msg_len; - s->s3->tmp.message_type = msg_hdr->type; + s->s3.tmp.message_type = msg_hdr->type; s->d1->r_msg_hdr.type = msg_hdr->type; s->d1->r_msg_hdr.seq = msg_hdr->seq; } else if (msg_len != s->d1->r_msg_hdr.msg_len) { @@ -452,8 +471,7 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr) * They must be playing with us! BTW, failure to enforce upper limit * would open possibility for buffer overrun. */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_DTLS1_PREPROCESS_FRAGMENT, - SSL_R_EXCESSIVE_MESSAGE_SIZE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); return 0; } @@ -473,23 +491,64 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) * (2) update s->init_num */ pitem *item; + piterator iter; hm_fragment *frag; int ret; + int chretran = 0; + iter = pqueue_iterator(s->d1->buffered_messages); do { - item = pqueue_peek(s->d1->buffered_messages); + item = pqueue_next(&iter); if (item == NULL) return 0; frag = (hm_fragment *)item->data; if (frag->msg_header.seq < s->d1->handshake_read_seq) { - /* This is a stale message that has been buffered so clear it */ - pqueue_pop(s->d1->buffered_messages); - dtls1_hm_fragment_free(frag); - pitem_free(item); - item = NULL; - frag = NULL; + pitem *next; + hm_fragment *nextfrag; + + if (!s->server + || frag->msg_header.seq != 0 + || s->d1->handshake_read_seq != 1 + || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { + /* + * This is a stale message that has been buffered so clear it. + * It is safe to pop this message from the queue even though + * we have an active iterator + */ + pqueue_pop(s->d1->buffered_messages); + dtls1_hm_fragment_free(frag); + pitem_free(item); + item = NULL; + frag = NULL; + } else { + /* + * We have fragments for a ClientHello without a cookie, + * even though we have sent a HelloVerifyRequest. It is possible + * that the HelloVerifyRequest got lost and this is a + * retransmission of the original ClientHello + */ + next = pqueue_next(&iter); + if (next != NULL) { + nextfrag = (hm_fragment *)next->data; + if (nextfrag->msg_header.seq == s->d1->handshake_read_seq) { + /* + * We have fragments for both a ClientHello without + * cookie and one with. Ditch the one without. + */ + pqueue_pop(s->d1->buffered_messages); + dtls1_hm_fragment_free(frag); + pitem_free(item); + item = next; + frag = nextfrag; + } else { + chretran = 1; + } + } else { + chretran = 1; + } + } } } while (item == NULL); @@ -497,7 +556,7 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) if (frag->reassembly != NULL) return 0; - if (s->d1->handshake_read_seq == frag->msg_header.seq) { + if (s->d1->handshake_read_seq == frag->msg_header.seq || chretran) { size_t frag_len = frag->msg_header.frag_len; pqueue_pop(s->d1->buffered_messages); @@ -515,6 +574,16 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, size_t *len) pitem_free(item); if (ret) { + if (chretran) { + /* + * We got a new ClientHello with a message sequence of 0. + * Reset the read/write sequences back to the beginning. + * We process it like this is the first time we've seen a + * ClientHello from the client. + */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; + } *len = frag_len; return 1; } @@ -741,6 +810,7 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) int i, ret, recvd_type; struct hm_header_st msg_hdr; size_t readbytes; + int chretran = 0; *errtype = 0; @@ -768,7 +838,6 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) { if (wire[0] != SSL3_MT_CCS) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_BAD_CHANGE_CIPHER_SPEC); goto f_err; } @@ -776,16 +845,15 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) memcpy(s->init_buf->data, wire, readbytes); s->init_num = readbytes - 1; s->init_msg = s->init_buf->data + 1; - s->s3->tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC; - s->s3->tmp.message_size = readbytes - 1; + s->s3.tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC; + s->s3.tmp.message_size = readbytes - 1; *len = readbytes - 1; return 1; } /* Handshake fails if message header is incomplete */ if (readbytes != DTLS1_HM_HEADER_LENGTH) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } @@ -801,8 +869,7 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) * Fragments must not span records. */ if (frag_len > RECORD_LAYER_get_rrec_length(&s->rlayer)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); goto f_err; } @@ -813,8 +880,20 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) * although we're still expecting seq 0 (ClientHello) */ if (msg_hdr.seq != s->d1->handshake_read_seq) { - *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); - return 0; + if (!s->server + || msg_hdr.seq != 0 + || s->d1->handshake_read_seq != 1 + || wire[0] != SSL3_MT_CLIENT_HELLO + || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { + *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); + return 0; + } + /* + * We received a ClientHello and sent back a HelloVerifyRequest. We + * now seem to have received a retransmitted initial ClientHello. That + * is allowed (possibly our HelloVerifyRequest got lost). + */ + chretran = 1; } if (frag_len && frag_len < mlen) { @@ -841,9 +920,7 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) goto redo; } else { /* Incorrectly formatted Hello request */ - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, - SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } } @@ -878,11 +955,21 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) * to fail */ if (readbytes != frag_len) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_BAD_LENGTH); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); goto f_err; } + if (chretran) { + /* + * We got a new ClientHello with a message sequence of 0. + * Reset the read/write sequences back to the beginning. + * We process it like this is the first time we've seen a ClientHello + * from the client. + */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; + } + /* * Note that s->init_num is *not* used as current offset in * s->init_buf->data, but as a counter summing up fragments' lengths: as @@ -902,7 +989,7 @@ static int dtls_get_reassembled_message(SSL *s, int *errtype, size_t *len) * for these 2 messages, we need to * ssl->enc_read_ctx re-init * ssl->rlayer.read_sequence zero - * ssl->s3->read_mac_secret re-init + * ssl->s3.read_mac_secret re-init * ssl->session->read_sym_enc assign * ssl->session->read_compression assign * ssl->session->read_hash assign @@ -913,9 +1000,7 @@ int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) s->d1->next_handshake_write_seq++; if (!WPACKET_put_bytes_u16(pkt, s->d1->handshake_write_seq)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } @@ -936,8 +1021,7 @@ WORK_STATE dtls_wait_for_dry(SSL *s) /* read app data until dry event */ ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); if (ret < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS_WAIT_FOR_DRY, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } @@ -950,12 +1034,11 @@ WORK_STATE dtls_wait_for_dry(SSL *s) */ if (dtls_get_reassembled_message(s, &errtype, &len)) { /* The call succeeded! This should never happen */ - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_DTLS_WAIT_FOR_DRY, - SSL_R_UNEXPECTED_MESSAGE); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); return WORK_ERROR; } - s->s3->in_read_app_data = 2; + s->s3.in_read_app_data = 2; s->rwstate = SSL_READING; BIO_clear_retry_flags(SSL_get_rbio(s)); BIO_set_retry_read(SSL_get_rbio(s)); @@ -968,8 +1051,7 @@ WORK_STATE dtls_wait_for_dry(SSL *s) int dtls1_read_failed(SSL *s, int code) { if (code > 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_DTLS1_READ_FAILED, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1051,12 +1133,16 @@ int dtls1_buffer_message(SSL *s, int is_ccs) if (!ossl_assert(s->d1->w_msg_hdr.msg_len + ((s->version == DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH) - == (unsigned int)s->init_num)) + == (unsigned int)s->init_num)) { + dtls1_hm_fragment_free(frag); return 0; + } } else { if (!ossl_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) { + dtls1_hm_fragment_free(frag); return 0; + } } frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; @@ -1111,8 +1197,7 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found) item = pqueue_find(s->d1->sent_messages, seq64be); if (item == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DTLS1_RETRANSMIT_MESSAGE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); *found = 0; return 0; } diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 695caab3d628..bcce73bcdc3e 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1,8 +1,8 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. 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 @@ -17,7 +17,9 @@ #include <openssl/buffer.h> #include <openssl/objects.h> #include <openssl/evp.h> +#include <openssl/rsa.h> #include <openssl/x509.h> +#include <openssl/trace.h> /* * Map error codes to TLS/SSL alart types. @@ -88,6 +90,8 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype) int tls_setup_handshake(SSL *s) { + int ver_min, ver_max, ok; + if (!ssl3_init_finished_mac(s)) { /* SSLfatal() already called */ return 0; @@ -96,20 +100,59 @@ int tls_setup_handshake(SSL *s) /* Reset any extension flags */ memset(s->ext.extflags, 0, sizeof(s->ext.extflags)); + if (ssl_get_min_max_version(s, &ver_min, &ver_max, NULL) != 0) { + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_NO_PROTOCOLS_AVAILABLE); + return 0; + } + + /* Sanity check that we have MD5-SHA1 if we need it */ + if (s->ctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { + int md5sha1_needed = 0; + + /* We don't have MD5-SHA1 - do we need it? */ + if (SSL_IS_DTLS(s)) { + if (DTLS_VERSION_LE(ver_max, DTLS1_VERSION)) + md5sha1_needed = 1; + } else { + if (ver_max <= TLS1_1_VERSION) + md5sha1_needed = 1; + } + if (md5sha1_needed) { + SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_NO_SUITABLE_DIGEST_ALGORITHM, + "The max supported SSL/TLS version needs the" + " MD5-SHA1 digest but it is not available" + " in the loaded providers. Use (D)TLSv1.2 or" + " above, or load different providers"); + return 0; + } + + ok = 1; + /* Don't allow TLSv1.1 or below to be negotiated */ + if (SSL_IS_DTLS(s)) { + if (DTLS_VERSION_LT(ver_min, DTLS1_2_VERSION)) + ok = SSL_set_min_proto_version(s, DTLS1_2_VERSION); + } else { + if (ver_min < TLS1_2_VERSION) + ok = SSL_set_min_proto_version(s, TLS1_2_VERSION); + } + if (!ok) { + /* Shouldn't happen */ + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + ok = 0; if (s->server) { STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s); - int i, ver_min, ver_max, ok = 0; + int i; /* * Sanity check that the maximum version we accept has ciphers * enabled. For clients we do this check during construction of the * ClientHello. */ - if (ssl_get_min_max_version(s, &ver_min, &ver_max, NULL) != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_SETUP_HANDSHAKE, - ERR_R_INTERNAL_ERROR); - return 0; - } for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); @@ -124,32 +167,33 @@ int tls_setup_handshake(SSL *s) break; } if (!ok) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_SETUP_HANDSHAKE, - SSL_R_NO_CIPHERS_AVAILABLE); - ERR_add_error_data(1, "No ciphers enabled for max supported " - "SSL/TLS version"); + SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_NO_CIPHERS_AVAILABLE, + "No ciphers enabled for max supported " + "SSL/TLS version"); return 0; } if (SSL_IS_FIRST_HANDSHAKE(s)) { /* N.B. s->session_ctx == s->ctx here */ - tsan_counter(&s->session_ctx->stats.sess_accept); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_accept); } else { /* N.B. s->ctx may not equal s->session_ctx */ - tsan_counter(&s->ctx->stats.sess_accept_renegotiate); + ssl_tsan_counter(s->ctx, &s->ctx->stats.sess_accept_renegotiate); - s->s3->tmp.cert_request = 0; + s->s3.tmp.cert_request = 0; } } else { if (SSL_IS_FIRST_HANDSHAKE(s)) - tsan_counter(&s->session_ctx->stats.sess_connect); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_connect); else - tsan_counter(&s->session_ctx->stats.sess_connect_renegotiate); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_connect_renegotiate); /* mark client_random uninitialized */ - memset(s->s3->client_random, 0, sizeof(s->s3->client_random)); + memset(s->s3.client_random, 0, sizeof(s->s3.client_random)); s->hit = 0; - s->s3->tmp.cert_req = 0; + s->s3.tmp.cert_req = 0; if (SSL_IS_DTLS(s)) s->statem.use_timer = 1; @@ -215,10 +259,9 @@ static int get_cert_verify_tbs_data(SSL *s, unsigned char *tls13tbs, size_t retlen; long retlen_l; - retlen = retlen_l = BIO_get_mem_data(s->s3->handshake_buffer, hdata); + retlen = retlen_l = BIO_get_mem_data(s->s3.handshake_buffer, hdata); if (retlen_l <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_GET_CERT_VERIFY_TBS_DATA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } *hdatalen = retlen; @@ -237,25 +280,22 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) void *hdata; unsigned char *sig = NULL; unsigned char tls13tbs[TLS13_TBS_PREAMBLE_SIZE + EVP_MAX_MD_SIZE]; - const SIGALG_LOOKUP *lu = s->s3->tmp.sigalg; + const SIGALG_LOOKUP *lu = s->s3.tmp.sigalg; - if (lu == NULL || s->s3->tmp.cert == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); + if (lu == NULL || s->s3.tmp.cert == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - pkey = s->s3->tmp.cert->privatekey; + pkey = s->s3.tmp.cert->privatekey; - if (pkey == NULL || !tls1_lookup_md(lu, &md)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); + if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -266,21 +306,15 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) } if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); - goto err; - } - siglen = EVP_PKEY_size(pkey); - sig = OPENSSL_malloc(siglen); - if (sig == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, pkey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_EVP_LIB); + if (EVP_DigestSignInit_ex(mctx, &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_EVP_LIB); goto err; } @@ -288,26 +322,45 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) 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_CERT_VERIFY, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } } if (s->version == SSL3_VERSION) { + /* + * Here we use EVP_DigestSignUpdate followed by EVP_DigestSignFinal + * in order to add the EVP_CTRL_SSL3_MASTER_SECRET call between them. + */ if (EVP_DigestSignUpdate(mctx, hdata, hdatalen) <= 0 - || !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET, - (int)s->session->master_key_length, - s->session->master_key) - || EVP_DigestSignFinal(mctx, sig, &siglen) <= 0) { + || EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET, + (int)s->session->master_key_length, + s->session->master_key) <= 0 + || EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + goto err; + } + sig = OPENSSL_malloc(siglen); + if (sig == NULL + || EVP_DigestSignFinal(mctx, sig, &siglen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + goto err; + } + } else { + /* + * Here we *must* use EVP_DigestSign() because Ed25519/Ed448 does not + * support streaming via EVP_DigestSignUpdate/EVP_DigestSignFinal + */ + if (EVP_DigestSign(mctx, NULL, &siglen, hdata, hdatalen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + goto err; + } + sig = OPENSSL_malloc(siglen); + if (sig == NULL + || EVP_DigestSign(mctx, sig, &siglen, hdata, hdatalen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } - } else if (EVP_DigestSign(mctx, sig, &siglen, hdata, hdatalen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_EVP_LIB); - goto err; } #ifndef OPENSSL_NO_GOST @@ -322,8 +375,7 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) #endif if (!WPACKET_sub_memcpy_u16(pkt, sig, siglen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -361,21 +413,19 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) EVP_PKEY_CTX *pctx = NULL; if (mctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } peer = s->session->peer; pkey = X509_get0_pubkey(peer); if (pkey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if (ssl_cert_lookup_by_pkey(pkey, NULL) == NULL) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_CERT_VERIFY, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); goto err; } @@ -384,8 +434,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) unsigned int sigalg; if (!PACKET_get_net_2(pkt, &sigalg)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - SSL_R_BAD_PACKET); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_PACKET); goto err; } if (tls12_check_peer_sigalg(s, sigalg, pkey) <= 0) { @@ -393,22 +442,19 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) goto err; } } else if (!tls1_set_peer_legacy_sigalg(s, pkey)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED); goto err; } - if (!tls1_lookup_md(s->s3->tmp.peer_sigalg, &md)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - ERR_R_INTERNAL_ERROR); + if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } -#ifdef SSL_DEBUG if (SSL_USE_SIGALGS(s)) - fprintf(stderr, "USING TLSv1.2 HASH %s\n", - md == NULL ? "n/a" : EVP_MD_name(md)); -#endif + OSSL_TRACE1(TLS, "USING TLSv1.2 HASH %s\n", + md == NULL ? "n/a" : EVP_MD_get0_name(md)); /* Check for broken implementations of GOST ciphersuites */ /* @@ -418,29 +464,20 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) #ifndef OPENSSL_NO_GOST if (!SSL_USE_SIGALGS(s) && ((PACKET_remaining(pkt) == 64 - && (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001 - || EVP_PKEY_id(pkey) == NID_id_GostR3410_2012_256)) + && (EVP_PKEY_get_id(pkey) == NID_id_GostR3410_2001 + || EVP_PKEY_get_id(pkey) == NID_id_GostR3410_2012_256)) || (PACKET_remaining(pkt) == 128 - && EVP_PKEY_id(pkey) == NID_id_GostR3410_2012_512))) { + && EVP_PKEY_get_id(pkey) == NID_id_GostR3410_2012_512))) { len = PACKET_remaining(pkt); } else #endif if (!PACKET_get_net_2(pkt, &len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } - j = EVP_PKEY_size(pkey); - if (((int)len > j) || ((int)PACKET_remaining(pkt) > j) - || (PACKET_remaining(pkt) == 0)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - SSL_R_WRONG_SIGNATURE_SIZE); - goto err; - } if (!PACKET_get_bytes(pkt, &data, len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -449,24 +486,24 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) goto err; } -#ifdef SSL_DEBUG - fprintf(stderr, "Using client verify alg %s\n", - md == NULL ? "n/a" : EVP_MD_name(md)); -#endif - if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, pkey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - ERR_R_EVP_LIB); + OSSL_TRACE1(TLS, "Using client verify alg %s\n", + md == NULL ? "n/a" : EVP_MD_get0_name(md)); + + if (EVP_DigestVerifyInit_ex(mctx, &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_EVP_LIB); goto err; } #ifndef OPENSSL_NO_GOST { - int pktype = EVP_PKEY_id(pkey); + int pktype = EVP_PKEY_get_id(pkey); if (pktype == NID_id_GostR3410_2001 || pktype == NID_id_GostR3410_2012_256 || pktype == NID_id_GostR3410_2012_512) { if ((gost_data = OPENSSL_malloc(len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } BUF_reverse(gost_data, data, len); @@ -479,30 +516,26 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) 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_PROCESS_CERT_VERIFY, - ERR_R_EVP_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } } if (s->version == SSL3_VERSION) { if (EVP_DigestVerifyUpdate(mctx, hdata, hdatalen) <= 0 - || !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET, - (int)s->session->master_key_length, - s->session->master_key)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - ERR_R_EVP_LIB); + || EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET, + (int)s->session->master_key_length, + s->session->master_key) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } if (EVP_DigestVerifyFinal(mctx, data, len) <= 0) { - SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - SSL_R_BAD_SIGNATURE); + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_BAD_SIGNATURE); goto err; } } else { j = EVP_DigestVerify(mctx, data, len, hdata, hdatalen); if (j <= 0) { - SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, - SSL_R_BAD_SIGNATURE); + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_BAD_SIGNATURE); goto err; } } @@ -512,16 +545,16 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) * certificate after the CertVerify instead of when we get the * CertificateRequest. This is because in TLSv1.3 the CertificateRequest * comes *before* the Certificate message. In TLSv1.2 it comes after. We - * want to make sure that SSL_get_peer_certificate() will return the actual + * want to make sure that SSL_get1_peer_certificate() will return the actual * server certificate from the client_cert_cb callback. */ - if (!s->server && SSL_IS_TLS13(s) && s->s3->tmp.cert_req == 1) + if (!s->server && SSL_IS_TLS13(s) && s->s3.tmp.cert_req == 1) ret = MSG_PROCESS_CONTINUE_PROCESSING; else ret = MSG_PROCESS_CONTINUE_READING; err: - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; + BIO_free(s->s3.handshake_buffer); + s->s3.handshake_buffer = NULL; EVP_MD_CTX_free(mctx); #ifndef OPENSSL_NO_GOST OPENSSL_free(gost_data); @@ -545,7 +578,7 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) */ if (SSL_IS_TLS13(s) && !s->server - && s->s3->tmp.cert_req == 0 + && s->s3.tmp.cert_req == 0 && (!s->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {; /* SSLfatal() already called */ @@ -562,17 +595,16 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) finish_md_len = s->method->ssl3_enc->final_finish_mac(s, sender, slen, - s->s3->tmp.finish_md); + s->s3.tmp.finish_md); if (finish_md_len == 0) { /* SSLfatal() already called */ return 0; } - s->s3->tmp.finish_md_len = finish_md_len; + s->s3.tmp.finish_md_len = finish_md_len; - if (!WPACKET_memcpy(pkt, s->s3->tmp.finish_md, finish_md_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_FINISHED, - ERR_R_INTERNAL_ERROR); + if (!WPACKET_memcpy(pkt, s->s3.tmp.finish_md, finish_md_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -591,18 +623,17 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) * Copy the finished so we can use it for renegotiation checks */ if (!ossl_assert(finish_md_len <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_FINISHED, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!s->server) { - memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, + memcpy(s->s3.previous_client_finished, s->s3.tmp.finish_md, finish_md_len); - s->s3->previous_client_finished_len = finish_md_len; + s->s3.previous_client_finished_len = finish_md_len; } else { - memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, + memcpy(s->s3.previous_server_finished, s->s3.tmp.finish_md, finish_md_len); - s->s3->previous_server_finished_len = finish_md_len; + s->s3.previous_server_finished_len = finish_md_len; } return 1; @@ -611,8 +642,7 @@ int tls_construct_finished(SSL *s, WPACKET *pkt) int tls_construct_key_update(SSL *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, s->key_update)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_KEY_UPDATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -629,15 +659,13 @@ MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt) * be on a record boundary. */ if (RECORD_LAYER_processed_read_pending(&s->rlayer)) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_TLS_PROCESS_KEY_UPDATE, - SSL_R_NOT_ON_RECORD_BOUNDARY); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); return MSG_PROCESS_ERROR; } if (!PACKET_get_1(pkt, &updatetype) || PACKET_remaining(pkt) != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_KEY_UPDATE, - SSL_R_BAD_KEY_UPDATE); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_KEY_UPDATE); return MSG_PROCESS_ERROR; } @@ -647,8 +675,7 @@ MSG_PROCESS_RETURN tls_process_key_update(SSL *s, PACKET *pkt) */ if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED && updatetype != SSL_KEY_UPDATE_REQUESTED) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PROCESS_KEY_UPDATE, - SSL_R_BAD_KEY_UPDATE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_UPDATE); return MSG_PROCESS_ERROR; } @@ -685,11 +712,11 @@ int ssl3_take_mac(SSL *s) slen = s->method->ssl3_enc->client_finished_label_len; } - s->s3->tmp.peer_finish_md_len = + s->s3.tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, sender, slen, - s->s3->tmp.peer_finish_md); + s->s3.tmp.peer_finish_md); - if (s->s3->tmp.peer_finish_md_len == 0) { + if (s->s3.tmp.peer_finish_md_len == 0) { /* SSLfatal() already called */ return 0; } @@ -712,31 +739,25 @@ MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt) && remain != DTLS1_CCS_HEADER_LENGTH + 1) || (s->version != DTLS1_BAD_VER && remain != DTLS1_CCS_HEADER_LENGTH - 1)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, - SSL_R_BAD_CHANGE_CIPHER_SPEC); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_CHANGE_CIPHER_SPEC); return MSG_PROCESS_ERROR; } } else { if (remain != 0) { - SSLfatal(s, SSL_AD_DECODE_ERROR, - SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, - SSL_R_BAD_CHANGE_CIPHER_SPEC); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_CHANGE_CIPHER_SPEC); return MSG_PROCESS_ERROR; } } /* Check we have a cipher to change to */ - if (s->s3->tmp.new_cipher == NULL) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, SSL_R_CCS_RECEIVED_EARLY); + if (s->s3.tmp.new_cipher == NULL) { + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_CCS_RECEIVED_EARLY); return MSG_PROCESS_ERROR; } - s->s3->change_cipher_spec = 1; + s->s3.change_cipher_spec = 1; if (!ssl3_do_change_cipher_spec(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; } @@ -785,31 +806,27 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) * message must be 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_PROCESS_FINISHED, - SSL_R_NOT_ON_RECORD_BOUNDARY); + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); return MSG_PROCESS_ERROR; } /* If this occurs, we have missed a message */ - if (!SSL_IS_TLS13(s) && !s->s3->change_cipher_spec) { - SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_F_TLS_PROCESS_FINISHED, - SSL_R_GOT_A_FIN_BEFORE_A_CCS); + if (!SSL_IS_TLS13(s) && !s->s3.change_cipher_spec) { + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_GOT_A_FIN_BEFORE_A_CCS); return MSG_PROCESS_ERROR; } - s->s3->change_cipher_spec = 0; + s->s3.change_cipher_spec = 0; - md_len = s->s3->tmp.peer_finish_md_len; + md_len = s->s3.tmp.peer_finish_md_len; if (md_len != PACKET_remaining(pkt)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_FINISHED, - SSL_R_BAD_DIGEST_LENGTH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_DIGEST_LENGTH); return MSG_PROCESS_ERROR; } - if (CRYPTO_memcmp(PACKET_data(pkt), s->s3->tmp.peer_finish_md, + if (CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md, md_len) != 0) { - SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_F_TLS_PROCESS_FINISHED, - SSL_R_DIGEST_CHECK_FAILED); + SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DIGEST_CHECK_FAILED); return MSG_PROCESS_ERROR; } @@ -817,18 +834,17 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) * Copy the finished so we can use it for renegotiation checks */ if (!ossl_assert(md_len <= EVP_MAX_MD_SIZE)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_FINISHED, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return MSG_PROCESS_ERROR; } if (s->server) { - memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, + memcpy(s->s3.previous_client_finished, s->s3.tmp.peer_finish_md, md_len); - s->s3->previous_client_finished_len = md_len; + s->s3.previous_client_finished_len = md_len; } else { - memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, + memcpy(s->s3.previous_server_finished, s->s3.tmp.peer_finish_md, md_len); - s->s3->previous_server_finished_len = md_len; + s->s3.previous_server_finished_len = md_len; } /* @@ -870,8 +886,7 @@ MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt) { if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -886,14 +901,12 @@ static int ssl_add_cert_to_wpacket(SSL *s, WPACKET *pkt, X509 *x, int chain) len = i2d_X509(x, NULL); if (len < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_TO_WPACKET, - ERR_R_BUF_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); return 0; } if (!WPACKET_sub_allocate_bytes_u24(pkt, len, &outbytes) || i2d_X509(x, &outbytes) != len) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_TO_WPACKET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -937,17 +950,16 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) chain_store = s->ctx->cert_store; if (chain_store != NULL) { - X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new(); + X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, + s->ctx->propq); if (xs_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } if (!X509_STORE_CTX_init(xs_ctx, chain_store, x, NULL)) { X509_STORE_CTX_free(xs_ctx); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, - ERR_R_X509_LIB); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_X509_LIB); return 0; } /* @@ -964,12 +976,12 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) if (i != 1) { #if 0 /* Dummy error calls so mkerr generates them */ - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_EE_KEY_TOO_SMALL); - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_CA_KEY_TOO_SMALL); - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_CA_MD_TOO_WEAK); + ERR_raise(ERR_LIB_SSL, SSL_R_EE_KEY_TOO_SMALL); + ERR_raise(ERR_LIB_SSL, SSL_R_CA_KEY_TOO_SMALL); + ERR_raise(ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK); #endif X509_STORE_CTX_free(xs_ctx); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, i); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); return 0; } chain_count = sk_X509_num(chain); @@ -986,7 +998,7 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) } else { i = ssl_security_cert_chain(s, extra_certs, x, 0); if (i != 1) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, i); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, i); return 0; } if (!ssl_add_cert_to_wpacket(s, pkt, x, 0)) { @@ -1007,8 +1019,7 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) { if (!WPACKET_start_sub_packet_u24(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_OUTPUT_CERT_CHAIN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1016,8 +1027,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) return 0; if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_OUTPUT_CERT_CHAIN, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1029,7 +1039,8 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) * in NBIO events. If |clearbufs| is set then init_buf and the wbio buffer is * freed up as well. */ -WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) +WORK_STATE tls_finish_handshake(SSL *s, ossl_unused WORK_STATE wst, + int clearbufs, int stop) { void (*cb) (const SSL *ssl, int type, int val) = NULL; int cleanuphand = s->statem.cleanuphand; @@ -1055,8 +1066,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) } if (!ssl_free_wbio_buffer(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_FINISH_HANDSHAKE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return WORK_ERROR; } s->init_num = 0; @@ -1088,7 +1098,7 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) ssl_update_cache(s, SSL_SESS_CACHE_SERVER); /* N.B. s->ctx may not equal s->session_ctx */ - tsan_counter(&s->ctx->stats.sess_accept_good); + ssl_tsan_counter(s->ctx, &s->ctx->stats.sess_accept_good); s->handshake_func = ossl_statem_accept; } else { if (SSL_IS_TLS13(s)) { @@ -1107,10 +1117,12 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs, int stop) ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); } if (s->hit) - tsan_counter(&s->session_ctx->stats.sess_hit); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_hit); s->handshake_func = ossl_statem_connect; - tsan_counter(&s->session_ctx->stats.sess_connect_good); + ssl_tsan_counter(s->session_ctx, + &s->session_ctx->stats.sess_connect_good); } if (SSL_IS_DTLS(s)) { @@ -1172,12 +1184,11 @@ int tls_get_message_header(SSL *s, int *mt) */ if (s->init_num != 0 || readbytes != 1 || p[0] != SSL3_MT_CCS) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_GET_MESSAGE_HEADER, SSL_R_BAD_CHANGE_CIPHER_SPEC); return 0; } if (s->statem.hand_state == TLS_ST_BEFORE - && (s->s3->flags & TLS1_FLAGS_STATELESS) != 0) { + && (s->s3.flags & TLS1_FLAGS_STATELESS) != 0) { /* * We are stateless and we received a CCS. Probably this is * from a client between the first and second ClientHellos. @@ -1187,14 +1198,13 @@ int tls_get_message_header(SSL *s, int *mt) */ return 0; } - s->s3->tmp.message_type = *mt = SSL3_MT_CHANGE_CIPHER_SPEC; + s->s3.tmp.message_type = *mt = SSL3_MT_CHANGE_CIPHER_SPEC; s->init_num = readbytes - 1; s->init_msg = s->init_buf->data; - s->s3->tmp.message_size = readbytes; + s->s3.tmp.message_size = readbytes; return 1; } else if (recvd_type != SSL3_RT_HANDSHAKE) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, - SSL_F_TLS_GET_MESSAGE_HEADER, SSL_R_CCS_RECEIVED_EARLY); return 0; } @@ -1224,7 +1234,7 @@ int tls_get_message_header(SSL *s, int *mt) /* s->init_num == SSL3_HM_HEADER_LENGTH */ *mt = *p; - s->s3->tmp.message_type = *(p++); + s->s3.tmp.message_type = *(p++); if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) { /* @@ -1236,7 +1246,7 @@ int tls_get_message_header(SSL *s, int *mt) */ l = RECORD_LAYER_get_rrec_length(&s->rlayer) + SSL3_HM_HEADER_LENGTH; - s->s3->tmp.message_size = l; + s->s3.tmp.message_size = l; s->init_msg = s->init_buf->data; s->init_num = SSL3_HM_HEADER_LENGTH; @@ -1244,11 +1254,11 @@ int tls_get_message_header(SSL *s, int *mt) n2l3(p, l); /* BUF_MEM_grow takes an 'int' parameter */ if (l > (INT_MAX - SSL3_HM_HEADER_LENGTH)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_GET_MESSAGE_HEADER, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); return 0; } - s->s3->tmp.message_size = l; + s->s3.tmp.message_size = l; s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = 0; @@ -1263,14 +1273,14 @@ int tls_get_message_body(SSL *s, size_t *len) unsigned char *p; int i; - if (s->s3->tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { + if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { /* We've already read everything in */ *len = (unsigned long)s->init_num; return 1; } p = s->init_msg; - n = s->s3->tmp.message_size - s->init_num; + n = s->s3.tmp.message_size - s->init_num; while (n > 0) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL, &p[s->init_num], n, 0, &readbytes); @@ -1313,9 +1323,9 @@ int tls_get_message_body(SSL *s, size_t *len) */ #define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2) /* KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_IS_TLS13(s) || (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET - && s->s3->tmp.message_type != SSL3_MT_KEY_UPDATE)) { - if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO + if (!SSL_IS_TLS13(s) || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET + && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { + if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE || memcmp(hrrrandom, s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET, @@ -1418,7 +1428,7 @@ typedef struct { const SSL_METHOD *(*smeth) (void); } version_info; -#if TLS_MAX_VERSION != TLS1_3_VERSION +#if TLS_MAX_VERSION_INTERNAL != TLS1_3_VERSION # error Code needs update for TLS_method() support beyond TLS1_3_VERSION. #endif @@ -1452,7 +1462,7 @@ static const version_info tls_version_table[] = { {0, NULL, NULL}, }; -#if DTLS_MAX_VERSION != DTLS1_2_VERSION +#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION # error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. #endif @@ -1505,15 +1515,12 @@ static int ssl_method_error(const SSL *s, const SSL_METHOD *method) /* * Only called by servers. Returns 1 if the server has a TLSv1.3 capable * certificate type, or has PSK or a certificate callback configured, or has - * a servername callback configured. Otherwise returns 0. + * a servername callback configure. Otherwise returns 0. */ static int is_tls13_capable(const SSL *s) { int i; -#ifndef OPENSSL_NO_EC int curve; - EC_KEY *eckey; -#endif if (!ossl_assert(s->ctx != NULL) || !ossl_assert(s->session_ctx != NULL)) return 0; @@ -1547,7 +1554,6 @@ static int is_tls13_capable(const SSL *s) } if (!ssl_has_cert(s, i)) continue; -#ifndef OPENSSL_NO_EC if (i != SSL_PKEY_ECC) return 1; /* @@ -1555,15 +1561,9 @@ static int is_tls13_capable(const SSL *s) * more restrictive so check that our sig algs are consistent with this * EC cert. See section 4.2.3 of RFC8446. */ - eckey = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey); - if (eckey == NULL) - continue; - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)); + curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC].privatekey); if (tls_check_sigalg_curve(s, curve)) return 1; -#else - return 1; -#endif } return 0; @@ -1676,9 +1676,9 @@ int ssl_set_version_bound(int method_version, int version, int *bound) return 1; } - valid_tls = version >= SSL3_VERSION && version <= TLS_MAX_VERSION; + valid_tls = version >= SSL3_VERSION && version <= TLS_MAX_VERSION_INTERNAL; valid_dtls = - DTLS_VERSION_LE(version, DTLS_MAX_VERSION) && + DTLS_VERSION_LE(version, DTLS_MAX_VERSION_INTERNAL) && DTLS_VERSION_GE(version, DTLS1_BAD_VER); if (!valid_tls && !valid_dtls) @@ -1751,7 +1751,7 @@ int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello, DOWNGRADE *dgrd) * With version-flexible methods we have an initial state with: * * s->method->version == (D)TLS_ANY_VERSION, - * s->version == (D)TLS_MAX_VERSION. + * s->version == (D)TLS_MAX_VERSION_INTERNAL. * * So we detect version-flexible methods via the method version, not the * handle version. @@ -1914,8 +1914,7 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) if (s->hello_retry_request != SSL_HRR_NONE && s->version != TLS1_3_VERSION) { s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_SSL_CHOOSE_CLIENT_VERSION, - SSL_R_WRONG_SSL_VERSION); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_SSL_VERSION); return 0; } @@ -1923,9 +1922,7 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) default: if (s->version != s->method->version) { s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_SSL_CHOOSE_CLIENT_VERSION, - SSL_R_WRONG_SSL_VERSION); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_SSL_VERSION); return 0; } /* @@ -1947,21 +1944,18 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) ret = ssl_get_min_max_version(s, &ver_min, &ver_max, &real_max); if (ret != 0) { s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_SSL_CHOOSE_CLIENT_VERSION, ret); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, ret); return 0; } if (SSL_IS_DTLS(s) ? DTLS_VERSION_LT(s->version, ver_min) : s->version < ver_min) { s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_SSL_CHOOSE_CLIENT_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; } else if (SSL_IS_DTLS(s) ? DTLS_VERSION_GT(s->version, ver_max) : s->version > ver_max) { s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, - SSL_F_SSL_CHOOSE_CLIENT_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; } @@ -1971,12 +1965,11 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) /* Check for downgrades */ if (s->version == TLS1_2_VERSION && real_max > s->version) { if (memcmp(tls12downgrade, - s->s3->server_random + SSL3_RANDOM_SIZE + s->s3.server_random + SSL3_RANDOM_SIZE - sizeof(tls12downgrade), sizeof(tls12downgrade)) == 0) { s->version = origv; SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_SSL_CHOOSE_CLIENT_VERSION, SSL_R_INAPPROPRIATE_FALLBACK); return 0; } @@ -1984,12 +1977,11 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) && s->version < TLS1_2_VERSION && real_max > s->version) { if (memcmp(tls11downgrade, - s->s3->server_random + SSL3_RANDOM_SIZE + s->s3.server_random + SSL3_RANDOM_SIZE - sizeof(tls11downgrade), sizeof(tls11downgrade)) == 0) { s->version = origv; SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_SSL_CHOOSE_CLIENT_VERSION, SSL_R_INAPPROPRIATE_FALLBACK); return 0; } @@ -2004,8 +1996,7 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions) } s->version = origv; - SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_F_SSL_CHOOSE_CLIENT_VERSION, - SSL_R_UNSUPPORTED_PROTOCOL); + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); return 0; } @@ -2170,7 +2161,6 @@ int ssl_set_client_hello_version(SSL *s) * used. Returns 1 if the group is in the list (and allowed if |checkallow| is * 1) or 0 otherwise. */ -#ifndef OPENSSL_NO_EC int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, size_t num_groups, int checkallow) { @@ -2184,14 +2174,13 @@ int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups, if (group_id == group && (!checkallow - || tls_curve_allowed(s, group, SSL_SECOP_CURVE_CHECK))) { + || tls_group_allowed(s, group, SSL_SECOP_CURVE_CHECK))) { return 1; } } return 0; } -#endif /* Replace ClientHello1 in the transcript hash with a synthetic message */ int create_synthetic_message_hash(SSL *s, const unsigned char *hashval, @@ -2238,7 +2227,7 @@ int create_synthetic_message_hash(SSL *s, const unsigned char *hashval, if (hrr != NULL && (!ssl3_finish_mac(s, hrr, hrrlen) || !ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->s3->tmp.message_size + s->s3.tmp.message_size + SSL3_HM_HEADER_LENGTH))) { /* SSLfatal() already called */ return 0; @@ -2259,14 +2248,12 @@ int parse_ca_names(SSL *s, PACKET *pkt) PACKET cadns; if (ca_sk == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_PARSE_CA_NAMES, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } /* get the CA RDNs */ if (!PACKET_get_length_prefixed_2(pkt, &cadns)) { - SSLfatal(s, SSL_AD_DECODE_ERROR,SSL_F_PARSE_CA_NAMES, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -2276,33 +2263,29 @@ int parse_ca_names(SSL *s, PACKET *pkt) if (!PACKET_get_net_2(&cadns, &name_len) || !PACKET_get_bytes(&cadns, &namebytes, name_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_PARSE_CA_NAMES, - SSL_R_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } namestart = namebytes; if ((xn = d2i_X509_NAME(NULL, &namebytes, name_len)) == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_PARSE_CA_NAMES, - ERR_R_ASN1_LIB); + SSLfatal(s, SSL_AD_DECODE_ERROR, ERR_R_ASN1_LIB); goto err; } if (namebytes != (namestart + name_len)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_PARSE_CA_NAMES, - SSL_R_CA_DN_LENGTH_MISMATCH); + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_CA_DN_LENGTH_MISMATCH); goto err; } if (!sk_X509_NAME_push(ca_sk, xn)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_PARSE_CA_NAMES, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } xn = NULL; } - sk_X509_NAME_pop_free(s->s3->tmp.peer_ca_names, X509_NAME_free); - s->s3->tmp.peer_ca_names = ca_sk; + sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free); + s->s3.tmp.peer_ca_names = ca_sk; return 1; @@ -2332,12 +2315,11 @@ int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) { /* Start sub-packet for client CA list */ if (!WPACKET_start_sub_packet_u16(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (ca_sk != NULL) { + if ((ca_sk != NULL) && !(s->options & SSL_OP_DISABLE_TLSEXT_CA_NAMES)) { int i; for (i = 0; i < sk_X509_NAME_num(ca_sk); i++) { @@ -2350,16 +2332,14 @@ int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt) || !WPACKET_sub_allocate_bytes_u16(pkt, namelen, &namebytes) || i2d_X509_NAME(name, &namebytes) != namelen) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } } if (!WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -2374,12 +2354,11 @@ size_t construct_key_exchange_tbs(SSL *s, unsigned char **ptbs, unsigned char *tbs = OPENSSL_malloc(tbslen); if (tbs == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - memcpy(tbs, s->s3->client_random, SSL3_RANDOM_SIZE); - memcpy(tbs + SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE); + memcpy(tbs, s->s3.client_random, SSL3_RANDOM_SIZE); + memcpy(tbs + SSL3_RANDOM_SIZE, s->s3.server_random, SSL3_RANDOM_SIZE); memcpy(tbs + SSL3_RANDOM_SIZE * 2, param, paramlen); @@ -2400,16 +2379,12 @@ int tls13_save_handshake_digest_for_pha(SSL *s) s->pha_dgst = EVP_MD_CTX_new(); if (s->pha_dgst == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (!EVP_MD_CTX_copy_ex(s->pha_dgst, - s->s3->handshake_dgst)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA, - ERR_R_INTERNAL_ERROR); + s->s3.handshake_dgst)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); EVP_MD_CTX_free(s->pha_dgst); s->pha_dgst = NULL; return 0; @@ -2425,16 +2400,12 @@ int tls13_save_handshake_digest_for_pha(SSL *s) int tls13_restore_handshake_digest_for_pha(SSL *s) { if (s->pha_dgst == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (!EVP_MD_CTX_copy_ex(s->s3->handshake_dgst, + if (!EVP_MD_CTX_copy_ex(s->s3.handshake_dgst, s->pha_dgst)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } return 1; diff --git a/ssl/statem/statem_local.h b/ssl/statem/statem_local.h index eae88053dcd7..ad4d93b1e279 100644 --- a/ssl/statem/statem_local.h +++ b/ssl/statem/statem_local.h @@ -1,7 +1,7 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2022 The OpenSSL Project Authors. 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 @@ -19,7 +19,6 @@ /* The spec allows for a longer length than this, but we limit it */ #define HELLO_VERIFY_REQUEST_MAX_LENGTH 258 #define END_OF_EARLY_DATA_MAX_LENGTH 0 -#define SERVER_HELLO_MAX_LENGTH 20000 #define HELLO_RETRY_REQUEST_MAX_LENGTH 20000 #define ENCRYPTED_EXTENSIONS_MAX_LENGTH 20000 #define SESSION_TICKET_MAX_LENGTH_TLS13 131338 @@ -28,12 +27,21 @@ #define SERVER_HELLO_DONE_MAX_LENGTH 0 #define KEY_UPDATE_MAX_LENGTH 1 #define CCS_MAX_LENGTH 1 + +/* Max ServerHello size permitted by RFC 8446 */ +#define SERVER_HELLO_MAX_LENGTH 65607 + /* Max should actually be 36 but we are generous */ #define FINISHED_MAX_LENGTH 64 /* Dummy message type */ #define SSL3_MT_DUMMY -1 +/* Invalid extension ID for non-supported extensions */ +#define TLSEXT_TYPE_invalid 0x10000 +#define TLSEXT_TYPE_out_of_range 0x10001 +unsigned int ossl_get_extension_type(size_t idx); + extern const unsigned char hrrrandom[]; /* Message processing return codes */ @@ -94,7 +102,8 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst); /* Functions for getting new message data */ __owur int tls_get_message_header(SSL *s, int *mt); __owur int tls_get_message_body(SSL *s, size_t *len); -__owur int dtls_get_message(SSL *s, int *mt, size_t *len); +__owur int dtls_get_message(SSL *s, int *mt); +__owur int dtls_get_message_body(SSL *s, size_t *len); /* Message construction and processing functions */ __owur int tls_process_initial_server_flight(SSL *s); @@ -128,6 +137,7 @@ __owur int tls_construct_cert_status_body(SSL *s, WPACKET *pkt); __owur int tls_construct_cert_status(SSL *s, WPACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt); +__owur WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst); __owur int ssl3_check_cert_and_algorithm(SSL *s); #ifndef OPENSSL_NO_NEXTPROTONEG __owur int tls_construct_next_proto(SSL *s, WPACKET *pkt); @@ -155,6 +165,11 @@ __owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt); __owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt); MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt); +#ifndef OPENSSL_NO_GOST +/* These functions are used in GOST18 CKE, both for client and server */ +int ossl_gost18_cke_cipher_nid(const SSL *s); +int ossl_gost_ukm(const SSL *s, unsigned char *dgst_buf); +#endif /* Extension processing */ @@ -198,12 +213,10 @@ int tls_parse_ctos_srp(SSL *s, PACKET *pkt, unsigned int context, X509 *x, #endif int tls_parse_ctos_early_data(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -#ifndef OPENSSL_NO_EC int tls_parse_ctos_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_ctos_supported_groups(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidxl); -#endif int tls_parse_ctos_session_ticket(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt, unsigned int context, @@ -251,11 +264,9 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, EXT_RETURN tls_construct_stoc_maxfragmentlen(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -#ifndef OPENSSL_NO_EC EXT_RETURN tls_construct_stoc_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -#endif EXT_RETURN tls_construct_stoc_supported_groups(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); @@ -312,14 +323,13 @@ EXT_RETURN tls_construct_ctos_maxfragmentlen(SSL *s, WPACKET *pkt, unsigned int EXT_RETURN tls_construct_ctos_srp(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #endif -#ifndef OPENSSL_NO_EC EXT_RETURN tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); EXT_RETURN tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -#endif + EXT_RETURN tls_construct_ctos_early_data(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); @@ -379,10 +389,8 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_stoc_maxfragmentlen(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -#ifndef OPENSSL_NO_EC int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -#endif int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); #ifndef OPENSSL_NO_OCSP 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. + * This test should never fail (otherwise we should have failed above) but + * we double check anyway. */ - 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. - */ - 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 (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; } diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index f8e53d4efc79..91238e6457b8 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -2,7 +2,7 @@ * Copyright 1995-2022 The OpenSSL Project Authors. 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 @@ -10,10 +10,16 @@ #include <stdio.h> #include "ssl_local.h" +#include "record/record_local.h" +#include "internal/ktls.h" +#include "internal/cryptlib.h" #include <openssl/comp.h> #include <openssl/evp.h> #include <openssl/kdf.h> #include <openssl/rand.h> +#include <openssl/obj_mac.h> +#include <openssl/core_names.h> +#include <openssl/trace.h> /* seed1 through seed5 are concatenated */ static int tls1_PRF(SSL *s, @@ -26,41 +32,55 @@ static int tls1_PRF(SSL *s, unsigned char *out, size_t olen, int fatal) { const EVP_MD *md = ssl_prf_md(s); - EVP_PKEY_CTX *pctx = NULL; - int ret = 0; + EVP_KDF *kdf; + EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[8], *p = params; + const char *mdname; if (md == NULL) { /* Should never happen */ if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_PRF, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); else - SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL); - if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0 - || EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) <= 0 - || EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, (int)slen) <= 0 - || EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, (int)seed1_len) <= 0 - || EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, (int)seed2_len) <= 0 - || EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, (int)seed3_len) <= 0 - || EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed4, (int)seed4_len) <= 0 - || EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed5, (int)seed5_len) <= 0 - || EVP_PKEY_derive(pctx, out, &olen) <= 0) { - if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_PRF, - ERR_R_INTERNAL_ERROR); - else - SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); + kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_PRF, s->ctx->propq); + if (kdf == NULL) goto err; + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) + goto err; + mdname = EVP_MD_get0_name(md); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + (unsigned char *)sec, + (size_t)slen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + (void *)seed1, (size_t)seed1_len); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + (void *)seed2, (size_t)seed2_len); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + (void *)seed3, (size_t)seed3_len); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + (void *)seed4, (size_t)seed4_len); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, + (void *)seed5, (size_t)seed5_len); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_derive(kctx, out, olen, params)) { + EVP_KDF_CTX_free(kctx); + return 1; } - ret = 1; - err: - EVP_PKEY_CTX_free(pctx); - return ret; + if (fatal) + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + else + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + EVP_KDF_CTX_free(kctx); + return 0; } static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) @@ -70,14 +90,99 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) /* Calls SSLfatal() as required */ ret = tls1_PRF(s, TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, - SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, + TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3.server_random, + SSL3_RANDOM_SIZE, s->s3.client_random, SSL3_RANDOM_SIZE, NULL, 0, NULL, 0, s->session->master_key, s->session->master_key_length, km, num, 1); return ret; } +#ifndef OPENSSL_NO_KTLS + /* + * Count the number of records that were not processed yet from record boundary. + * + * This function assumes that there are only fully formed records read in the + * record layer. If read_ahead is enabled, then this might be false and this + * function will fail. + */ +# ifndef OPENSSL_NO_KTLS_RX +static int count_unprocessed_records(SSL *s) +{ + SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); + PACKET pkt, subpkt; + int count = 0; + + if (!PACKET_buf_init(&pkt, rbuf->buf + rbuf->offset, rbuf->left)) + return -1; + + while (PACKET_remaining(&pkt) > 0) { + /* Skip record type and version */ + if (!PACKET_forward(&pkt, 3)) + return -1; + + /* Read until next record */ + if (!PACKET_get_length_prefixed_2(&pkt, &subpkt)) + return -1; + + count += 1; + } + + return count; +} +# endif +#endif + + +int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *ciph, + const EVP_MD *md) +{ + /* + * Provided cipher, the TLS padding/MAC removal is performed provider + * side so we need to tell the ctx about our TLS version and mac size + */ + OSSL_PARAM params[3], *pprm = params; + size_t macsize = 0; + int imacsize = -1; + + if ((EVP_CIPHER_get_flags(ciph) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0 + /* + * We look at s->ext.use_etm instead of SSL_READ_ETM() or + * SSL_WRITE_ETM() because this test applies to both reading + * and writing. + */ + && !s->ext.use_etm) + imacsize = EVP_MD_get_size(md); + if (imacsize >= 0) + macsize = (size_t)imacsize; + + *pprm++ = OSSL_PARAM_construct_int(OSSL_CIPHER_PARAM_TLS_VERSION, + &s->version); + *pprm++ = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, + &macsize); + *pprm = OSSL_PARAM_construct_end(); + + if (!EVP_CIPHER_CTX_set_params(ctx, params)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + + +static int tls_iv_length_within_key_block(const EVP_CIPHER *c) +{ + /* If GCM/CCM mode only part of IV comes from PRF */ + if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) + return EVP_GCM_TLS_FIXED_IV_LEN; + else if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) + return EVP_CCM_TLS_FIXED_IV_LEN; + else + return EVP_CIPHER_get_iv_length(c); +} + int tls1_change_cipher_state(SSL *s, int which) { unsigned char *p, *mac_secret; @@ -94,30 +199,44 @@ int tls1_change_cipher_state(SSL *s, int which) EVP_PKEY *mac_key; size_t n, i, j, k, cl; int reuse_dd = 0; +#ifndef OPENSSL_NO_KTLS + ktls_crypto_info_t crypto_info; + unsigned char *rec_seq; + void *rl_sequence; +# ifndef OPENSSL_NO_KTLS_RX + int count_unprocessed; + int bit; +# endif + BIO *bio; +#endif - c = s->s3->tmp.new_sym_enc; - m = s->s3->tmp.new_hash; - mac_type = s->s3->tmp.new_mac_pkey_type; + c = s->s3.tmp.new_sym_enc; + m = s->s3.tmp.new_hash; + mac_type = s->s3.tmp.new_mac_pkey_type; #ifndef OPENSSL_NO_COMP - comp = s->s3->tmp.new_compression; + comp = s->s3.tmp.new_compression; #endif if (which & SSL3_CC_READ) { if (s->ext.use_etm) - s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; + s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; else - s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; + s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ; - if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; + if (s->enc_read_ctx != NULL) { reuse_dd = 1; } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } else { /* @@ -127,8 +246,10 @@ int tls1_change_cipher_state(SSL *s, int which) } dd = s->enc_read_ctx; mac_ctx = ssl_replace_hash(&s->read_hash, NULL); - if (mac_ctx == NULL) + if (mac_ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; + } #ifndef OPENSSL_NO_COMP COMP_CTX_free(s->expand); s->expand = NULL; @@ -136,7 +257,6 @@ int tls1_change_cipher_state(SSL *s, int which) s->expand = COMP_CTX_new(comp->method); if (s->expand == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS1_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err; } @@ -147,42 +267,42 @@ int tls1_change_cipher_state(SSL *s, int which) */ if (!SSL_IS_DTLS(s)) RECORD_LAYER_reset_read_sequence(&s->rlayer); - mac_secret = &(s->s3->read_mac_secret[0]); - mac_secret_size = &(s->s3->read_mac_secret_size); + mac_secret = &(s->s3.read_mac_secret[0]); + mac_secret_size = &(s->s3.read_mac_secret_size); } else { s->statem.enc_write_state = ENC_WRITE_STATE_INVALID; if (s->ext.use_etm) - s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; + s->s3.flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; else - s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; + s->s3.flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE; - if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; + + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) { reuse_dd = 1; } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } dd = s->enc_write_ctx; if (SSL_IS_DTLS(s)) { mac_ctx = EVP_MD_CTX_new(); if (mac_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } s->write_hash = mac_ctx; } else { mac_ctx = ssl_replace_hash(&s->write_hash, NULL); if (mac_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } } @@ -193,8 +313,7 @@ int tls1_change_cipher_state(SSL *s, int which) s->compress = COMP_CTX_new(comp->method); if (s->compress == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS1_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); + SSL_R_COMPRESSION_LIBRARY_ERROR); goto err; } } @@ -204,27 +323,19 @@ int tls1_change_cipher_state(SSL *s, int which) */ if (!SSL_IS_DTLS(s)) RECORD_LAYER_reset_write_sequence(&s->rlayer); - mac_secret = &(s->s3->write_mac_secret[0]); - mac_secret_size = &(s->s3->write_mac_secret_size); + mac_secret = &(s->s3.write_mac_secret[0]); + mac_secret_size = &(s->s3.write_mac_secret_size); } if (reuse_dd) EVP_CIPHER_CTX_reset(dd); - p = s->s3->tmp.key_block; - i = *mac_secret_size = s->s3->tmp.new_mac_secret_size; + p = s->s3.tmp.key_block; + i = *mac_secret_size = s->s3.tmp.new_mac_secret_size; - /* TODO(size_t): convert me */ - cl = EVP_CIPHER_key_length(c); + cl = EVP_CIPHER_get_key_length(c); j = cl; - /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ - /* If GCM/CCM mode only part of IV comes from PRF */ - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - k = EVP_GCM_TLS_FIXED_IV_LEN; - else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) - k = EVP_CCM_TLS_FIXED_IV_LEN; - else - k = EVP_CIPHER_iv_length(c); + k = tls_iv_length_within_key_block(c); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms = &(p[0]); @@ -243,92 +354,166 @@ int tls1_change_cipher_state(SSL *s, int which) n += k; } - if (n > s->s3->tmp.key_block_length) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + if (n > s->s3.tmp.key_block_length) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } memcpy(mac_secret, ms, i); - if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { - /* TODO(size_t): Convert this function */ - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, - (int)*mac_secret_size); + if (!(EVP_CIPHER_get_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + if (mac_type == EVP_PKEY_HMAC) { + mac_key = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, mac_secret, + *mac_secret_size); + } else { + /* + * If its not HMAC then the only other types of MAC we support are + * the GOST MACs, so we need to use the old style way of creating + * a MAC key. + */ + mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, + (int)*mac_secret_size); + } if (mac_key == NULL - || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) { + || EVP_DigestSignInit_ex(mac_ctx, NULL, EVP_MD_get0_name(m), + s->ctx->libctx, s->ctx->propq, mac_key, + NULL) <= 0) { EVP_PKEY_free(mac_key); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } EVP_PKEY_free(mac_key); } -#ifdef SSL_DEBUG - printf("which = %04X\nmac key=", which); - { - size_t z; - for (z = 0; z < i; z++) - printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "which = %04X, mac key:\n", which); + BIO_dump_indent(trc_out, ms, i, 4); + } OSSL_TRACE_END(TLS); + + if (EVP_CIPHER_get_mode(c) == EVP_CIPH_GCM_MODE) { if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) - || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, (int)k, - iv)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + || EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, (int)k, + iv) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - } else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) { + } else if (EVP_CIPHER_get_mode(c) == EVP_CIPH_CCM_MODE) { int taglen; - if (s->s3->tmp. + if (s->s3.tmp. new_cipher->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) taglen = EVP_CCM8_TLS_TAG_LEN; else taglen = EVP_CCM_TLS_TAG_LEN; if (!EVP_CipherInit_ex(dd, c, NULL, NULL, NULL, (which & SSL3_CC_WRITE)) - || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) - || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) - || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_CCM_SET_IV_FIXED, (int)k, iv) + || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) <= 0) + || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0) + || (EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_CCM_SET_IV_FIXED, (int)k, iv) <= 0) || !EVP_CipherInit_ex(dd, NULL, NULL, key, NULL, -1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } else { if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } } /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ - if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size - && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, - (int)*mac_secret_size, mac_secret)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + if ((EVP_CIPHER_get_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) + && *mac_secret_size + && EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, + (int)*mac_secret_size, mac_secret) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - s->statem.enc_write_state = ENC_WRITE_STATE_VALID; + if (EVP_CIPHER_get0_provider(c) != NULL + && !tls_provider_set_tls_params(s, dd, c, m)) { + /* SSLfatal already called */ + goto err; + } + +#ifndef OPENSSL_NO_KTLS + if (s->compress || (s->options & SSL_OP_ENABLE_KTLS) == 0) + goto skip_ktls; -#ifdef SSL_DEBUG - printf("which = %04X\nkey=", which); - { - int z; - for (z = 0; z < EVP_CIPHER_key_length(c); z++) - printf("%02X%c", key[z], ((z + 1) % 16) ? ' ' : '\n'); + /* ktls supports only the maximum fragment size */ + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) + goto skip_ktls; + + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(s, c, dd)) + goto skip_ktls; + + if (which & SSL3_CC_WRITE) + bio = s->wbio; + else + bio = s->rbio; + + if (!ossl_assert(bio != NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ + if (which & SSL3_CC_WRITE) { + if (BIO_flush(bio) <= 0) + goto skip_ktls; } - printf("\niv="); - { - size_t z; - for (z = 0; z < k; z++) - printf("%02X%c", iv[z], ((z + 1) % 16) ? ' ' : '\n'); + + /* ktls doesn't support renegotiation */ + if ((BIO_get_ktls_send(s->wbio) && (which & SSL3_CC_WRITE)) || + (BIO_get_ktls_recv(s->rbio) && (which & SSL3_CC_READ))) { + SSLfatal(s, SSL_AD_NO_RENEGOTIATION, ERR_R_INTERNAL_ERROR); + goto err; } - printf("\n"); -#endif + + if (which & SSL3_CC_WRITE) + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); + else + rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); + + if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq, + iv, key, ms, *mac_secret_size)) + goto skip_ktls; + + if (which & SSL3_CC_READ) { +# ifndef OPENSSL_NO_KTLS_RX + count_unprocessed = count_unprocessed_records(s); + if (count_unprocessed < 0) + goto skip_ktls; + + /* increment the crypto_info record sequence */ + while (count_unprocessed) { + for (bit = 7; bit >= 0; bit--) { /* increment */ + ++rec_seq[bit]; + if (rec_seq[bit] != 0) + break; + } + count_unprocessed--; + } +# else + goto skip_ktls; +# endif + } + + /* ktls works with user provided buffers directly */ + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { + if (which & SSL3_CC_WRITE) + ssl3_release_write_buffer(s); + SSL_set_options(s, SSL_OP_NO_RENEGOTIATION); + } + + skip_ktls: +#endif /* OPENSSL_NO_KTLS */ + s->statem.enc_write_state = ENC_WRITE_STATE_VALID; + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "which = %04X, key:\n", which); + BIO_dump_indent(trc_out, key, EVP_CIPHER_get_key_length(c), 4); + BIO_printf(trc_out, "iv:\n"); + BIO_dump_indent(trc_out, iv, k, 4); + } OSSL_TRACE_END(TLS); return 1; err: @@ -345,69 +530,57 @@ int tls1_setup_key_block(SSL *s) size_t num, mac_secret_size = 0; int ret = 0; - if (s->s3->tmp.key_block_length != 0) + if (s->s3.tmp.key_block_length != 0) return 1; - if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type, &mac_secret_size, - &comp, s->ext.use_etm)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_SETUP_KEY_BLOCK, - SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, &mac_type, + &mac_secret_size, &comp, s->ext.use_etm)) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; } - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; - s->s3->tmp.new_mac_pkey_type = mac_type; - s->s3->tmp.new_mac_secret_size = mac_secret_size; - num = EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c); + ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); + s->s3.tmp.new_sym_enc = c; + ssl_evp_md_free(s->s3.tmp.new_hash); + s->s3.tmp.new_hash = hash; + s->s3.tmp.new_mac_pkey_type = mac_type; + s->s3.tmp.new_mac_secret_size = mac_secret_size; + num = mac_secret_size + EVP_CIPHER_get_key_length(c) + + tls_iv_length_within_key_block(c); num *= 2; ssl3_cleanup_key_block(s); if ((p = OPENSSL_malloc(num)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_SETUP_KEY_BLOCK, - ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } - s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p; + s->s3.tmp.key_block_length = num; + s->s3.tmp.key_block = p; + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "key block length: %zu\n", num); + BIO_printf(trc_out, "client random\n"); + BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4); + BIO_printf(trc_out, "server random\n"); + BIO_dump_indent(trc_out, s->s3.server_random, SSL3_RANDOM_SIZE, 4); + BIO_printf(trc_out, "master key\n"); + BIO_dump_indent(trc_out, + s->session->master_key, + s->session->master_key_length, 4); + } OSSL_TRACE_END(TLS); -#ifdef SSL_DEBUG - printf("client random\n"); - { - int z; - for (z = 0; z < SSL3_RANDOM_SIZE; z++) - printf("%02X%c", s->s3->client_random[z], - ((z + 1) % 16) ? ' ' : '\n'); - } - printf("server random\n"); - { - int z; - for (z = 0; z < SSL3_RANDOM_SIZE; z++) - printf("%02X%c", s->s3->server_random[z], - ((z + 1) % 16) ? ' ' : '\n'); - } - printf("master key\n"); - { - size_t z; - for (z = 0; z < s->session->master_key_length; z++) - printf("%02X%c", s->session->master_key[z], - ((z + 1) % 16) ? ' ' : '\n'); - } -#endif if (!tls1_generate_key_block(s, p, num)) { /* SSLfatal() already called */ goto err; } -#ifdef SSL_DEBUG - printf("\nkey block\n"); - { - size_t z; - for (z = 0; z < num; z++) - printf("%02X%c", p[z], ((z + 1) % 16) ? ' ' : '\n'); - } -#endif + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "key block\n"); + BIO_dump_indent(trc_out, p, num, 4); + } OSSL_TRACE_END(TLS); if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) && s->method->version <= TLS1_VERSION) { @@ -415,16 +588,14 @@ int tls1_setup_key_block(SSL *s) * enable vulnerability countermeasure for CBC ciphers with known-IV * problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ - s->s3->need_empty_fragments = 1; + s->s3.need_empty_fragments = 1; if (s->session->cipher != NULL) { if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3->need_empty_fragments = 0; + s->s3.need_empty_fragments = 0; -#ifndef OPENSSL_NO_RC4 if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3->need_empty_fragments = 0; -#endif + s->s3.need_empty_fragments = 0; } } @@ -438,6 +609,10 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, { size_t hashlen; unsigned char hash[EVP_MAX_MD_SIZE]; + size_t finished_size = TLS1_FINISH_MAC_LENGTH; + + if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kGOST18) + finished_size = 32; if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ @@ -451,12 +626,12 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, s->session->master_key, s->session->master_key_length, - out, TLS1_FINISH_MAC_LENGTH, 1)) { + out, finished_size, 1)) { /* SSLfatal() already called */ return 0; } OPENSSL_cleanse(hash, hashlen); - return TLS1_FINISH_MAC_LENGTH; + return finished_size; } int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, @@ -475,10 +650,10 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, /* SSLfatal() already called */ return 0; } -#ifdef SSL_DEBUG - fprintf(stderr, "Handshake hashes:\n"); - BIO_dump_fp(stderr, (char *)hash, hashlen); -#endif + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "Handshake hashes:\n"); + BIO_dump(trc_out, (char *)hash, hashlen); + } OSSL_TRACE_END(TLS); if (!tls1_PRF(s, TLS_MD_EXTENDED_MASTER_SECRET_CONST, TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, @@ -495,26 +670,28 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, if (!tls1_PRF(s, TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, + s->s3.client_random, SSL3_RANDOM_SIZE, NULL, 0, - s->s3->server_random, SSL3_RANDOM_SIZE, + s->s3.server_random, SSL3_RANDOM_SIZE, NULL, 0, p, len, out, SSL3_MASTER_SECRET_SIZE, 1)) { /* SSLfatal() already called */ return 0; } } -#ifdef SSL_DEBUG - fprintf(stderr, "Premaster Secret:\n"); - BIO_dump_fp(stderr, (char *)p, len); - fprintf(stderr, "Client Random:\n"); - BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE); - fprintf(stderr, "Server Random:\n"); - BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE); - fprintf(stderr, "Master Secret:\n"); - BIO_dump_fp(stderr, (char *)s->session->master_key, - SSL3_MASTER_SECRET_SIZE); -#endif + + OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "Premaster Secret:\n"); + BIO_dump_indent(trc_out, p, len, 4); + BIO_printf(trc_out, "Client Random:\n"); + BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4); + BIO_printf(trc_out, "Server Random:\n"); + BIO_dump_indent(trc_out, s->s3.server_random, SSL3_RANDOM_SIZE, 4); + BIO_printf(trc_out, "Master Secret:\n"); + BIO_dump_indent(trc_out, + s->session->master_key, + SSL3_MASTER_SECRET_SIZE, 4); + } OSSL_TRACE_END(TLS); *secret_size = SSL3_MASTER_SECRET_SIZE; return 1; @@ -545,9 +722,9 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, currentvalpos = 0; memcpy(val + currentvalpos, (unsigned char *)label, llen); currentvalpos += llen; - memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); + memcpy(val + currentvalpos, s->s3.client_random, SSL3_RANDOM_SIZE); currentvalpos += SSL3_RANDOM_SIZE; - memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); + memcpy(val + currentvalpos, s->s3.server_random, SSL3_RANDOM_SIZE); currentvalpos += SSL3_RANDOM_SIZE; if (use_context) { @@ -592,11 +769,11 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, goto ret; err1: - SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); + ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); rv = 0; goto ret; err2: - SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); rv = 0; ret: OPENSSL_clear_free(val, vallen); @@ -672,7 +849,7 @@ int tls1_alert_code(int code) return TLS1_AD_NO_APPLICATION_PROTOCOL; case SSL_AD_CERTIFICATE_REQUIRED: return SSL_AD_HANDSHAKE_FAILURE; - case SSL_AD_MISSING_EXTENSION: + case TLS13_AD_MISSING_EXTENSION: return SSL_AD_HANDSHAKE_FAILURE; default: return -1; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 5f657f888e0d..51c2283db915 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1,7 +1,7 @@ /* * Copyright 1995-2022 The OpenSSL Project Authors. 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 @@ -12,12 +12,17 @@ #include <openssl/objects.h> #include <openssl/evp.h> #include <openssl/hmac.h> +#include <openssl/core_names.h> #include <openssl/ocsp.h> #include <openssl/conf.h> #include <openssl/x509v3.h> #include <openssl/dh.h> #include <openssl/bn.h> +#include <openssl/provider.h> +#include <openssl/param_build.h> #include "internal/nelem.h" +#include "internal/sizes.h" +#include "internal/tlsgroups.h" #include "ssl_local.h" #include <openssl/ct.h> @@ -124,51 +129,60 @@ int tls1_clear(SSL *s) return 0; if (s->method->version == TLS_ANY_VERSION) - s->version = TLS_MAX_VERSION; + s->version = TLS_MAX_VERSION_INTERNAL; else s->version = s->method->version; return 1; } -#ifndef OPENSSL_NO_EC - -/* - * Table of curve information. - * Do not delete entries or reorder this array! It is used as a lookup - * table: the index of each entry is one less than the TLS curve id. - */ -static const TLS_GROUP_INFO nid_list[] = { - {NID_sect163k1, 80, TLS_CURVE_CHAR2}, /* sect163k1 (1) */ - {NID_sect163r1, 80, TLS_CURVE_CHAR2}, /* sect163r1 (2) */ - {NID_sect163r2, 80, TLS_CURVE_CHAR2}, /* sect163r2 (3) */ - {NID_sect193r1, 80, TLS_CURVE_CHAR2}, /* sect193r1 (4) */ - {NID_sect193r2, 80, TLS_CURVE_CHAR2}, /* sect193r2 (5) */ - {NID_sect233k1, 112, TLS_CURVE_CHAR2}, /* sect233k1 (6) */ - {NID_sect233r1, 112, TLS_CURVE_CHAR2}, /* sect233r1 (7) */ - {NID_sect239k1, 112, TLS_CURVE_CHAR2}, /* sect239k1 (8) */ - {NID_sect283k1, 128, TLS_CURVE_CHAR2}, /* sect283k1 (9) */ - {NID_sect283r1, 128, TLS_CURVE_CHAR2}, /* sect283r1 (10) */ - {NID_sect409k1, 192, TLS_CURVE_CHAR2}, /* sect409k1 (11) */ - {NID_sect409r1, 192, TLS_CURVE_CHAR2}, /* sect409r1 (12) */ - {NID_sect571k1, 256, TLS_CURVE_CHAR2}, /* sect571k1 (13) */ - {NID_sect571r1, 256, TLS_CURVE_CHAR2}, /* sect571r1 (14) */ - {NID_secp160k1, 80, TLS_CURVE_PRIME}, /* secp160k1 (15) */ - {NID_secp160r1, 80, TLS_CURVE_PRIME}, /* secp160r1 (16) */ - {NID_secp160r2, 80, TLS_CURVE_PRIME}, /* secp160r2 (17) */ - {NID_secp192k1, 80, TLS_CURVE_PRIME}, /* secp192k1 (18) */ - {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME}, /* secp192r1 (19) */ - {NID_secp224k1, 112, TLS_CURVE_PRIME}, /* secp224k1 (20) */ - {NID_secp224r1, 112, TLS_CURVE_PRIME}, /* secp224r1 (21) */ - {NID_secp256k1, 128, TLS_CURVE_PRIME}, /* secp256k1 (22) */ - {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME}, /* secp256r1 (23) */ - {NID_secp384r1, 192, TLS_CURVE_PRIME}, /* secp384r1 (24) */ - {NID_secp521r1, 256, TLS_CURVE_PRIME}, /* secp521r1 (25) */ - {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */ - {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ - {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ - {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ - {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ +/* Legacy NID to group_id mapping. Only works for groups we know about */ +static struct { + int nid; + uint16_t group_id; +} nid_to_group[] = { + {NID_sect163k1, OSSL_TLS_GROUP_ID_sect163k1}, + {NID_sect163r1, OSSL_TLS_GROUP_ID_sect163r1}, + {NID_sect163r2, OSSL_TLS_GROUP_ID_sect163r2}, + {NID_sect193r1, OSSL_TLS_GROUP_ID_sect193r1}, + {NID_sect193r2, OSSL_TLS_GROUP_ID_sect193r2}, + {NID_sect233k1, OSSL_TLS_GROUP_ID_sect233k1}, + {NID_sect233r1, OSSL_TLS_GROUP_ID_sect233r1}, + {NID_sect239k1, OSSL_TLS_GROUP_ID_sect239k1}, + {NID_sect283k1, OSSL_TLS_GROUP_ID_sect283k1}, + {NID_sect283r1, OSSL_TLS_GROUP_ID_sect283r1}, + {NID_sect409k1, OSSL_TLS_GROUP_ID_sect409k1}, + {NID_sect409r1, OSSL_TLS_GROUP_ID_sect409r1}, + {NID_sect571k1, OSSL_TLS_GROUP_ID_sect571k1}, + {NID_sect571r1, OSSL_TLS_GROUP_ID_sect571r1}, + {NID_secp160k1, OSSL_TLS_GROUP_ID_secp160k1}, + {NID_secp160r1, OSSL_TLS_GROUP_ID_secp160r1}, + {NID_secp160r2, OSSL_TLS_GROUP_ID_secp160r2}, + {NID_secp192k1, OSSL_TLS_GROUP_ID_secp192k1}, + {NID_X9_62_prime192v1, OSSL_TLS_GROUP_ID_secp192r1}, + {NID_secp224k1, OSSL_TLS_GROUP_ID_secp224k1}, + {NID_secp224r1, OSSL_TLS_GROUP_ID_secp224r1}, + {NID_secp256k1, OSSL_TLS_GROUP_ID_secp256k1}, + {NID_X9_62_prime256v1, OSSL_TLS_GROUP_ID_secp256r1}, + {NID_secp384r1, OSSL_TLS_GROUP_ID_secp384r1}, + {NID_secp521r1, OSSL_TLS_GROUP_ID_secp521r1}, + {NID_brainpoolP256r1, OSSL_TLS_GROUP_ID_brainpoolP256r1}, + {NID_brainpoolP384r1, OSSL_TLS_GROUP_ID_brainpoolP384r1}, + {NID_brainpoolP512r1, OSSL_TLS_GROUP_ID_brainpoolP512r1}, + {EVP_PKEY_X25519, OSSL_TLS_GROUP_ID_x25519}, + {EVP_PKEY_X448, OSSL_TLS_GROUP_ID_x448}, + {NID_id_tc26_gost_3410_2012_256_paramSetA, 0x0022}, + {NID_id_tc26_gost_3410_2012_256_paramSetB, 0x0023}, + {NID_id_tc26_gost_3410_2012_256_paramSetC, 0x0024}, + {NID_id_tc26_gost_3410_2012_256_paramSetD, 0x0025}, + {NID_id_tc26_gost_3410_2012_512_paramSetA, 0x0026}, + {NID_id_tc26_gost_3410_2012_512_paramSetB, 0x0027}, + {NID_id_tc26_gost_3410_2012_512_paramSetC, 0x0028}, + {NID_ffdhe2048, OSSL_TLS_GROUP_ID_ffdhe2048}, + {NID_ffdhe3072, OSSL_TLS_GROUP_ID_ffdhe3072}, + {NID_ffdhe4096, OSSL_TLS_GROUP_ID_ffdhe4096}, + {NID_ffdhe6144, OSSL_TLS_GROUP_ID_ffdhe6144}, + {NID_ffdhe8192, OSSL_TLS_GROUP_ID_ffdhe8192} }; static const unsigned char ecformats_default[] = { @@ -178,12 +192,24 @@ static const unsigned char ecformats_default[] = { }; /* The default curves */ -static const uint16_t eccurves_default[] = { +static const uint16_t supported_groups_default[] = { 29, /* X25519 (29) */ 23, /* secp256r1 (23) */ 30, /* X448 (30) */ 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ + 34, /* GC256A (34) */ + 35, /* GC256B (35) */ + 36, /* GC256C (36) */ + 37, /* GC256D (37) */ + 38, /* GC512A (38) */ + 39, /* GC512B (39) */ + 40, /* GC512C (40) */ + 0x100, /* ffdhe2048 (0x100) */ + 0x101, /* ffdhe3072 (0x101) */ + 0x102, /* ffdhe4096 (0x102) */ + 0x103, /* ffdhe6144 (0x103) */ + 0x104, /* ffdhe8192 (0x104) */ }; static const uint16_t suiteb_curves[] = { @@ -191,21 +217,271 @@ static const uint16_t suiteb_curves[] = { TLSEXT_curve_P_384 }; -const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id) +struct provider_group_data_st { + SSL_CTX *ctx; + OSSL_PROVIDER *provider; +}; + +#define TLS_GROUP_LIST_MALLOC_BLOCK_SIZE 10 +static OSSL_CALLBACK add_provider_groups; +static int add_provider_groups(const OSSL_PARAM params[], void *data) +{ + struct provider_group_data_st *pgd = data; + SSL_CTX *ctx = pgd->ctx; + OSSL_PROVIDER *provider = pgd->provider; + const OSSL_PARAM *p; + TLS_GROUP_INFO *ginf = NULL; + EVP_KEYMGMT *keymgmt; + unsigned int gid; + unsigned int is_kem = 0; + int ret = 0; + + if (ctx->group_list_max_len == ctx->group_list_len) { + TLS_GROUP_INFO *tmp = NULL; + + if (ctx->group_list_max_len == 0) + tmp = OPENSSL_malloc(sizeof(TLS_GROUP_INFO) + * TLS_GROUP_LIST_MALLOC_BLOCK_SIZE); + else + tmp = OPENSSL_realloc(ctx->group_list, + (ctx->group_list_max_len + + TLS_GROUP_LIST_MALLOC_BLOCK_SIZE) + * sizeof(TLS_GROUP_INFO)); + if (tmp == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->group_list = tmp; + memset(tmp + ctx->group_list_max_len, + 0, + sizeof(TLS_GROUP_INFO) * TLS_GROUP_LIST_MALLOC_BLOCK_SIZE); + ctx->group_list_max_len += TLS_GROUP_LIST_MALLOC_BLOCK_SIZE; + } + + ginf = &ctx->group_list[ctx->group_list_len]; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->tlsname = OPENSSL_strdup(p->data); + if (ginf->tlsname == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->realname = OPENSSL_strdup(p->data); + if (ginf->realname == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ID); + if (p == NULL || !OSSL_PARAM_get_uint(p, &gid) || gid > UINT16_MAX) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->group_id = (uint16_t)gid; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ALG); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->algorithm = OPENSSL_strdup(p->data); + if (ginf->algorithm == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS); + if (p == NULL || !OSSL_PARAM_get_uint(p, &ginf->secbits)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM); + if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->is_kem = 1 & is_kem; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_TLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mindtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxdtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + /* + * Now check that the algorithm is actually usable for our property query + * string. Regardless of the result we still return success because we have + * successfully processed this group, even though we may decide not to use + * it. + */ + ret = 1; + ERR_set_mark(); + keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ginf->algorithm, ctx->propq); + if (keymgmt != NULL) { + /* + * We have successfully fetched the algorithm - however if the provider + * doesn't match this one then we ignore it. + * + * Note: We're cheating a little here. Technically if the same algorithm + * is available from more than one provider then it is undefined which + * implementation you will get back. Theoretically this could be + * different every time...we assume here that you'll always get the + * same one back if you repeat the exact same fetch. Is this a reasonable + * assumption to make (in which case perhaps we should document this + * behaviour)? + */ + if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) { + /* We have a match - so we will use this group */ + ctx->group_list_len++; + ginf = NULL; + } + EVP_KEYMGMT_free(keymgmt); + } + ERR_pop_to_mark(); + err: + if (ginf != NULL) { + OPENSSL_free(ginf->tlsname); + OPENSSL_free(ginf->realname); + OPENSSL_free(ginf->algorithm); + ginf->algorithm = ginf->tlsname = ginf->realname = NULL; + } + return ret; +} + +static int discover_provider_groups(OSSL_PROVIDER *provider, void *vctx) { - /* ECC curves from RFC 4492 and RFC 7027 */ - if (group_id < 1 || group_id > OSSL_NELEM(nid_list)) - return NULL; - return &nid_list[group_id - 1]; + struct provider_group_data_st pgd; + + pgd.ctx = vctx; + pgd.provider = provider; + return OSSL_PROVIDER_get_capabilities(provider, "TLS-GROUP", + add_provider_groups, &pgd); } -static uint16_t tls1_nid2group_id(int nid) +int ssl_load_groups(SSL_CTX *ctx) +{ + size_t i, j, num_deflt_grps = 0; + uint16_t tmp_supp_groups[OSSL_NELEM(supported_groups_default)]; + + if (!OSSL_PROVIDER_do_all(ctx->libctx, discover_provider_groups, ctx)) + return 0; + + for (i = 0; i < OSSL_NELEM(supported_groups_default); i++) { + for (j = 0; j < ctx->group_list_len; j++) { + if (ctx->group_list[j].group_id == supported_groups_default[i]) { + tmp_supp_groups[num_deflt_grps++] = ctx->group_list[j].group_id; + break; + } + } + } + + if (num_deflt_grps == 0) + return 1; + + ctx->ext.supported_groups_default + = OPENSSL_malloc(sizeof(uint16_t) * num_deflt_grps); + + if (ctx->ext.supported_groups_default == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + memcpy(ctx->ext.supported_groups_default, + tmp_supp_groups, + num_deflt_grps * sizeof(tmp_supp_groups[0])); + ctx->ext.supported_groups_default_len = num_deflt_grps; + + return 1; +} + +static uint16_t tls1_group_name2id(SSL_CTX *ctx, const char *name) +{ + size_t i; + + for (i = 0; i < ctx->group_list_len; i++) { + if (strcmp(ctx->group_list[i].tlsname, name) == 0 + || strcmp(ctx->group_list[i].realname, name) == 0) + return ctx->group_list[i].group_id; + } + + return 0; +} + +const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id) { size_t i; - for (i = 0; i < OSSL_NELEM(nid_list); i++) { - if (nid_list[i].nid == nid) - return (uint16_t)(i + 1); + + for (i = 0; i < ctx->group_list_len; i++) { + if (ctx->group_list[i].group_id == group_id) + return &ctx->group_list[i]; + } + + return NULL; +} + +int tls1_group_id2nid(uint16_t group_id, int include_unknown) +{ + size_t i; + + if (group_id == 0) + return NID_undef; + + /* + * Return well known Group NIDs - for backwards compatibility. This won't + * work for groups we don't know about. + */ + for (i = 0; i < OSSL_NELEM(nid_to_group); i++) + { + if (nid_to_group[i].group_id == group_id) + return nid_to_group[i].nid; + } + if (!include_unknown) + return NID_undef; + return TLSEXT_nid_unknown | (int)group_id; +} + +uint16_t tls1_nid2group_id(int nid) +{ + size_t i; + + /* + * Return well known Group ids - for backwards compatibility. This won't + * work for groups we don't know about. + */ + for (i = 0; i < OSSL_NELEM(nid_to_group); i++) + { + if (nid_to_group[i].nid == nid) + return nid_to_group[i].group_id; } + return 0; } @@ -216,7 +492,6 @@ static uint16_t tls1_nid2group_id(int nid) void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, size_t *pgroupslen) { - /* For Suite B mode only include P-256, P-384 */ switch (tls1_suiteb(s)) { case SSL_CERT_FLAG_SUITEB_128_LOS: @@ -236,8 +511,8 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, default: if (s->ext.supportedgroups == NULL) { - *pgroups = eccurves_default; - *pgroupslen = OSSL_NELEM(eccurves_default); + *pgroups = s->ctx->ext.supported_groups_default; + *pgroupslen = s->ctx->ext.supported_groups_default_len; } else { *pgroups = s->ext.supportedgroups; *pgroupslen = s->ext.supportedgroups_len; @@ -246,21 +521,61 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, } } -/* See if curve is allowed by security callback */ -int tls_curve_allowed(SSL *s, uint16_t curve, int op) +int tls_valid_group(SSL *s, uint16_t group_id, int minversion, int maxversion, + int isec, int *okfortls13) { - const TLS_GROUP_INFO *cinfo = tls1_group_id_lookup(curve); - unsigned char ctmp[2]; + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group_id); + int ret; - if (cinfo == NULL) + if (okfortls13 != NULL) + *okfortls13 = 0; + + if (ginfo == NULL) return 0; -# ifdef OPENSSL_NO_EC2M - if (cinfo->flags & TLS_CURVE_CHAR2) + + if (SSL_IS_DTLS(s)) { + if (ginfo->mindtls < 0 || ginfo->maxdtls < 0) + return 0; + if (ginfo->maxdtls == 0) + ret = 1; + else + ret = DTLS_VERSION_LE(minversion, ginfo->maxdtls); + if (ginfo->mindtls > 0) + ret &= DTLS_VERSION_GE(maxversion, ginfo->mindtls); + } else { + if (ginfo->mintls < 0 || ginfo->maxtls < 0) + return 0; + if (ginfo->maxtls == 0) + ret = 1; + else + ret = (minversion <= ginfo->maxtls); + if (ginfo->mintls > 0) + ret &= (maxversion >= ginfo->mintls); + if (ret && okfortls13 != NULL && maxversion == TLS1_3_VERSION) + *okfortls13 = (ginfo->maxtls == 0) + || (ginfo->maxtls >= TLS1_3_VERSION); + } + ret &= !isec + || strcmp(ginfo->algorithm, "EC") == 0 + || strcmp(ginfo->algorithm, "X25519") == 0 + || strcmp(ginfo->algorithm, "X448") == 0; + + return ret; +} + +/* See if group is allowed by security callback */ +int tls_group_allowed(SSL *s, uint16_t group, int op) +{ + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group); + unsigned char gtmp[2]; + + if (ginfo == NULL) return 0; -# endif - ctmp[0] = curve >> 8; - ctmp[1] = curve & 0xff; - return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)ctmp); + + gtmp[0] = group >> 8; + gtmp[1] = group & 0xff; + return ssl_security(s, op, ginfo->secbits, + tls1_group_id2nid(ginfo->group_id, 0), (void *)gtmp); } /* Return 1 if "id" is in "list" */ @@ -295,7 +610,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) * For Suite B ciphersuite determines curve: we already know * these are acceptable due to previous checks. */ - unsigned long cid = s->s3->tmp.new_cipher->id; + unsigned long cid = s->s3.tmp.new_cipher->id; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) return TLSEXT_curve_P_256; @@ -323,7 +638,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) uint16_t id = pref[i]; if (!tls1_in_list(id, supp, num_supp) - || !tls_curve_allowed(s, id, SSL_SECOP_CURVE_SHARED)) + || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED)) continue; if (nmatch == k) return id; @@ -341,141 +656,121 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, uint16_t *glist; size_t i; /* - * Bitmap of groups included to detect duplicates: only works while group - * ids < 32 + * Bitmap of groups included to detect duplicates: two variables are added + * to detect duplicates as some values are more than 32. */ - unsigned long dup_list = 0; + unsigned long *dup_list = NULL; + unsigned long dup_list_egrp = 0; + unsigned long dup_list_dhgrp = 0; if (ngroups == 0) { - SSLerr(SSL_F_TLS1_SET_GROUPS, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); return 0; } if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) { - SSLerr(SSL_F_TLS1_SET_GROUPS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < ngroups; i++) { unsigned long idmask; uint16_t id; - /* TODO(TLS1.3): Convert for DH groups */ id = tls1_nid2group_id(groups[i]); - idmask = 1L << id; - if (!id || (dup_list & idmask)) { - OPENSSL_free(glist); - return 0; - } - dup_list |= idmask; + if ((id & 0x00FF) >= (sizeof(unsigned long) * 8)) + goto err; + idmask = 1L << (id & 0x00FF); + dup_list = (id < 0x100) ? &dup_list_egrp : &dup_list_dhgrp; + if (!id || ((*dup_list) & idmask)) + goto err; + *dup_list |= idmask; glist[i] = id; } OPENSSL_free(*pext); *pext = glist; *pextlen = ngroups; return 1; +err: + OPENSSL_free(glist); + return 0; } -# define MAX_CURVELIST OSSL_NELEM(nid_list) - +# define GROUPLIST_INCREMENT 40 +# define GROUP_NAME_BUFFER_LENGTH 64 typedef struct { - size_t nidcnt; - int nid_arr[MAX_CURVELIST]; -} nid_cb_st; + SSL_CTX *ctx; + size_t gidcnt; + size_t gidmax; + uint16_t *gid_arr; +} gid_cb_st; -static int nid_cb(const char *elem, int len, void *arg) +static int gid_cb(const char *elem, int len, void *arg) { - nid_cb_st *narg = arg; + gid_cb_st *garg = arg; size_t i; - int nid; - char etmp[20]; + uint16_t gid = 0; + char etmp[GROUP_NAME_BUFFER_LENGTH]; + if (elem == NULL) return 0; - if (narg->nidcnt == MAX_CURVELIST) - return 0; + if (garg->gidcnt == garg->gidmax) { + uint16_t *tmp = + OPENSSL_realloc(garg->gid_arr, garg->gidmax + GROUPLIST_INCREMENT); + if (tmp == NULL) + return 0; + garg->gidmax += GROUPLIST_INCREMENT; + garg->gid_arr = tmp; + } if (len > (int)(sizeof(etmp) - 1)) return 0; memcpy(etmp, elem, len); etmp[len] = 0; - nid = EC_curve_nist2nid(etmp); - if (nid == NID_undef) - nid = OBJ_sn2nid(etmp); - if (nid == NID_undef) - nid = OBJ_ln2nid(etmp); - if (nid == NID_undef) + + gid = tls1_group_name2id(garg->ctx, etmp); + if (gid == 0) { + ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT, + "group '%s' cannot be set", etmp); return 0; - for (i = 0; i < narg->nidcnt; i++) - if (narg->nid_arr[i] == nid) + } + for (i = 0; i < garg->gidcnt; i++) + if (garg->gid_arr[i] == gid) return 0; - narg->nid_arr[narg->nidcnt++] = nid; + garg->gid_arr[garg->gidcnt++] = gid; return 1; } -/* Set groups based on a colon separate list */ -int tls1_set_groups_list(uint16_t **pext, size_t *pextlen, const char *str) -{ - nid_cb_st ncb; - ncb.nidcnt = 0; - if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) - return 0; - if (pext == NULL) - return 1; - return tls1_set_groups(pext, pextlen, ncb.nid_arr, ncb.nidcnt); -} -/* Return group id of a key */ -static uint16_t tls1_get_group_id(EVP_PKEY *pkey) +/* Set groups based on a colon separated list */ +int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen, + const char *str) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - const EC_GROUP *grp; + gid_cb_st gcb; + uint16_t *tmparr; + int ret = 0; - if (ec == NULL) + gcb.gidcnt = 0; + gcb.gidmax = GROUPLIST_INCREMENT; + gcb.gid_arr = OPENSSL_malloc(gcb.gidmax * sizeof(*gcb.gid_arr)); + if (gcb.gid_arr == NULL) return 0; - grp = EC_KEY_get0_group(ec); - return tls1_nid2group_id(EC_GROUP_get_curve_name(grp)); -} - -/* Check a key is compatible with compression extension */ -static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) -{ - const EC_KEY *ec; - const EC_GROUP *grp; - unsigned char comp_id; - size_t i; - - /* If not an EC key nothing to check */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) - return 1; - ec = EVP_PKEY_get0_EC_KEY(pkey); - grp = EC_KEY_get0_group(ec); - - /* Get required compression id */ - if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_UNCOMPRESSED) { - comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; - } else if (SSL_IS_TLS13(s)) { - /* - * ec_point_formats extension is not used in TLSv1.3 so we ignore - * this check. - */ - return 1; - } else { - int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(grp)); - - if (field_type == NID_X9_62_prime_field) - comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; - else if (field_type == NID_X9_62_characteristic_two_field) - comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; - else - return 0; + gcb.ctx = ctx; + if (!CONF_parse_list(str, ':', 1, gid_cb, &gcb)) + goto end; + if (pext == NULL) { + ret = 1; + goto end; } + /* - * If point formats extension present check it, otherwise everything is - * supported (see RFC4492). + * gid_cb ensurse there are no duplicates so we can just go ahead and set + * the result */ - if (s->ext.peer_ecpointformats == NULL) - return 1; - - for (i = 0; i < s->ext.peer_ecpointformats_len; i++) { - if (s->ext.peer_ecpointformats[i] == comp_id) - return 1; - } - return 0; + tmparr = OPENSSL_memdup(gcb.gid_arr, gcb.gidcnt * sizeof(*tmparr)); + if (tmparr == NULL) + goto end; + *pext = tmparr; + *pextlen = gcb.gidcnt; + ret = 1; + end: + OPENSSL_free(gcb.gid_arr); + return ret; } /* Check a group id matches preferences */ @@ -488,8 +783,8 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) return 0; /* Check for Suite B compliance */ - if (tls1_suiteb(s) && s->s3->tmp.new_cipher != NULL) { - unsigned long cid = s->s3->tmp.new_cipher->id; + if (tls1_suiteb(s) && s->s3.tmp.new_cipher != NULL) { + unsigned long cid = s->s3.tmp.new_cipher->id; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { if (group_id != TLSEXT_curve_P_256) @@ -510,7 +805,7 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) return 0; } - if (!tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) + if (!tls_group_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) return 0; /* For clients, nothing more to check */ @@ -550,6 +845,64 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, } } +/* Check a key is compatible with compression extension */ +static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) +{ + unsigned char comp_id; + size_t i; + int point_conv; + + /* If not an EC key nothing to check */ + if (!EVP_PKEY_is_a(pkey, "EC")) + return 1; + + + /* Get required compression id */ + point_conv = EVP_PKEY_get_ec_point_conv_form(pkey); + if (point_conv == 0) + return 0; + if (point_conv == POINT_CONVERSION_UNCOMPRESSED) { + comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; + } else if (SSL_IS_TLS13(s)) { + /* + * ec_point_formats extension is not used in TLSv1.3 so we ignore + * this check. + */ + return 1; + } else { + int field_type = EVP_PKEY_get_field_type(pkey); + + if (field_type == NID_X9_62_prime_field) + comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + else if (field_type == NID_X9_62_characteristic_two_field) + comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + else + return 0; + } + /* + * If point formats extension present check it, otherwise everything is + * supported (see RFC4492). + */ + if (s->ext.peer_ecpointformats == NULL) + return 1; + + for (i = 0; i < s->ext.peer_ecpointformats_len; i++) { + if (s->ext.peer_ecpointformats[i] == comp_id) + return 1; + } + return 0; +} + +/* Return group id of a key */ +static uint16_t tls1_get_group_id(EVP_PKEY *pkey) +{ + int curve_nid = ssl_get_EC_curve_nid(pkey); + + if (curve_nid == NID_undef) + return 0; + return tls1_nid2group_id(curve_nid); +} + /* * Check cert parameters compatible with extensions: currently just checks EC * certificates have compatible curves and compression. @@ -562,7 +915,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) if (pkey == NULL) return 0; /* If not EC nothing to do */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) + if (!EVP_PKEY_is_a(pkey, "EC")) return 1; /* Check compression */ if (!tls1_check_pkey_comp(s, pkey)) @@ -625,24 +978,13 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) return 0; } -#else - -static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) -{ - return 1; -} - -#endif /* OPENSSL_NO_EC */ - /* Default sigalg schemes */ static const uint16_t tls12_sigalgs[] = { -#ifndef OPENSSL_NO_EC TLSEXT_SIGALG_ecdsa_secp256r1_sha256, TLSEXT_SIGALG_ecdsa_secp384r1_sha384, TLSEXT_SIGALG_ecdsa_secp521r1_sha512, TLSEXT_SIGALG_ed25519, TLSEXT_SIGALG_ed448, -#endif TLSEXT_SIGALG_rsa_pss_pss_sha256, TLSEXT_SIGALG_rsa_pss_pss_sha384, @@ -655,121 +997,125 @@ static const uint16_t tls12_sigalgs[] = { TLSEXT_SIGALG_rsa_pkcs1_sha384, TLSEXT_SIGALG_rsa_pkcs1_sha512, -#ifndef OPENSSL_NO_EC TLSEXT_SIGALG_ecdsa_sha224, TLSEXT_SIGALG_ecdsa_sha1, -#endif + TLSEXT_SIGALG_rsa_pkcs1_sha224, TLSEXT_SIGALG_rsa_pkcs1_sha1, -#ifndef OPENSSL_NO_DSA + TLSEXT_SIGALG_dsa_sha224, TLSEXT_SIGALG_dsa_sha1, TLSEXT_SIGALG_dsa_sha256, TLSEXT_SIGALG_dsa_sha384, TLSEXT_SIGALG_dsa_sha512, -#endif + #ifndef OPENSSL_NO_GOST + TLSEXT_SIGALG_gostr34102012_256_intrinsic, + TLSEXT_SIGALG_gostr34102012_512_intrinsic, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, TLSEXT_SIGALG_gostr34102001_gostr3411, #endif }; -#ifndef OPENSSL_NO_EC + static const uint16_t suiteb_sigalgs[] = { TLSEXT_SIGALG_ecdsa_secp256r1_sha256, TLSEXT_SIGALG_ecdsa_secp384r1_sha384 }; -#endif static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { -#ifndef OPENSSL_NO_EC {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA256, NID_X9_62_prime256v1}, + NID_ecdsa_with_SHA256, NID_X9_62_prime256v1, 1}, {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA384, NID_secp384r1}, + NID_ecdsa_with_SHA384, NID_secp384r1, 1}, {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA512, NID_secp521r1}, + NID_ecdsa_with_SHA512, NID_secp521r1, 1}, {"ed25519", TLSEXT_SIGALG_ed25519, NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"ed448", TLSEXT_SIGALG_ed448, NID_undef, -1, EVP_PKEY_ED448, SSL_PKEY_ED448, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_ecdsa_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA224, NID_undef}, + NID_ecdsa_with_SHA224, NID_undef, 1}, {NULL, TLSEXT_SIGALG_ecdsa_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA1, NID_undef}, -#endif + NID_ecdsa_with_SHA1, NID_undef, 1}, {"rsa_pss_rsae_sha256", TLSEXT_SIGALG_rsa_pss_rsae_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_rsae_sha384", TLSEXT_SIGALG_rsa_pss_rsae_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_rsae_sha512", TLSEXT_SIGALG_rsa_pss_rsae_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_pss_sha256", TLSEXT_SIGALG_rsa_pss_pss_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_pss_sha384", TLSEXT_SIGALG_rsa_pss_pss_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_pss_sha512", TLSEXT_SIGALG_rsa_pss_pss_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha256WithRSAEncryption, NID_undef}, + NID_sha256WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha384WithRSAEncryption, NID_undef}, + NID_sha384WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha512WithRSAEncryption, NID_undef}, + NID_sha512WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha224", TLSEXT_SIGALG_rsa_pkcs1_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha224WithRSAEncryption, NID_undef}, + NID_sha224WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha1WithRSAEncryption, NID_undef}, -#ifndef OPENSSL_NO_DSA + NID_sha1WithRSAEncryption, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_dsa_with_SHA256, NID_undef}, + NID_dsa_with_SHA256, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_dsaWithSHA1, NID_undef}, -#endif + NID_dsaWithSHA1, NID_undef, 1}, #ifndef OPENSSL_NO_GOST + {NULL, TLSEXT_SIGALG_gostr34102012_256_intrinsic, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, + NID_undef, NID_undef, 1}, + {NULL, TLSEXT_SIGALG_gostr34102012_512_intrinsic, + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411, NID_id_GostR3411_94, SSL_MD_GOST94_IDX, NID_id_GostR3410_2001, SSL_PKEY_GOST01, - NID_undef, NID_undef} + NID_undef, NID_undef, 1} #endif }; /* Legacy sigalgs for TLS < 1.2 RSA TLS signatures */ @@ -777,7 +1123,7 @@ static const SIGALG_LOOKUP legacy_rsa_sigalg = { "rsa_pkcs1_md5_sha1", 0, NID_md5_sha1, SSL_MD_MD5_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_undef, NID_undef + NID_undef, NID_undef, 1 }; /* @@ -790,27 +1136,86 @@ static const uint16_t tls_default_sigalg[] = { TLSEXT_SIGALG_dsa_sha1, /* SSL_PKEY_DSA_SIGN */ TLSEXT_SIGALG_ecdsa_sha1, /* SSL_PKEY_ECC */ TLSEXT_SIGALG_gostr34102001_gostr3411, /* SSL_PKEY_GOST01 */ - TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, /* SSL_PKEY_GOST12_256 */ - TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, /* SSL_PKEY_GOST12_512 */ + TLSEXT_SIGALG_gostr34102012_256_intrinsic, /* SSL_PKEY_GOST12_256 */ + TLSEXT_SIGALG_gostr34102012_512_intrinsic, /* SSL_PKEY_GOST12_512 */ 0, /* SSL_PKEY_ED25519 */ 0, /* SSL_PKEY_ED448 */ }; +int ssl_setup_sig_algs(SSL_CTX *ctx) +{ + size_t i; + const SIGALG_LOOKUP *lu; + SIGALG_LOOKUP *cache + = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl)); + EVP_PKEY *tmpkey = EVP_PKEY_new(); + int ret = 0; + + if (cache == NULL || tmpkey == NULL) + goto err; + + ERR_set_mark(); + for (i = 0, lu = sigalg_lookup_tbl; + i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) { + EVP_PKEY_CTX *pctx; + + cache[i] = *lu; + + /* + * Check hash is available. + * This test is not perfect. A provider could have support + * for a signature scheme, but not a particular hash. However the hash + * could be available from some other loaded provider. In that case it + * could be that the signature is available, and the hash is available + * independently - but not as a combination. We ignore this for now. + */ + if (lu->hash != NID_undef + && ctx->ssl_digest_methods[lu->hash_idx] == NULL) { + cache[i].enabled = 0; + continue; + } + + if (!EVP_PKEY_set_type(tmpkey, lu->sig)) { + cache[i].enabled = 0; + continue; + } + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, tmpkey, ctx->propq); + /* If unable to create pctx we assume the sig algorithm is unavailable */ + if (pctx == NULL) + cache[i].enabled = 0; + EVP_PKEY_CTX_free(pctx); + } + ERR_pop_to_mark(); + ctx->sigalg_lookup_cache = cache; + cache = NULL; + + ret = 1; + err: + OPENSSL_free(cache); + EVP_PKEY_free(tmpkey); + return ret; +} + /* Lookup TLS signature algorithm */ -static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg) +static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg) { size_t i; - const SIGALG_LOOKUP *s; + const SIGALG_LOOKUP *lu; - for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); - i++, s++) { - if (s->sigalg == sigalg) - return s; + for (i = 0, lu = s->ctx->sigalg_lookup_cache; + /* cache should have the same number of elements as sigalg_lookup_tbl */ + i < OSSL_NELEM(sigalg_lookup_tbl); + lu++, i++) { + if (lu->sigalg == sigalg) { + if (!lu->enabled) + return NULL; + return lu; + } } return NULL; } /* Lookup hash: return 0 if invalid or not enabled */ -int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) +int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd) { const EVP_MD *md; if (lu == NULL) @@ -819,7 +1224,7 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) if (lu->hash == NID_undef) { md = NULL; } else { - md = ssl_md(lu->hash_idx); + md = ssl_md(ctx, lu->hash_idx); if (md == NULL) return 0; } @@ -835,16 +1240,17 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) * SHA512 has a hash length of 64 bytes, which is incompatible * with a 128 byte (1024 bit) key. */ -#define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_size(md) + 2) -static int rsa_pss_check_min_key_size(const RSA *rsa, const SIGALG_LOOKUP *lu) +#define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_get_size(md) + 2) +static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const EVP_PKEY *pkey, + const SIGALG_LOOKUP *lu) { const EVP_MD *md; - if (rsa == NULL) + if (pkey == NULL) return 0; - if (!tls1_lookup_md(lu, &md) || md == NULL) + if (!tls1_lookup_md(ctx, lu, &md) || md == NULL) return 0; - if (RSA_size(rsa) < RSA_PSS_MINIMUM_KEY_SIZE(md)) + if (EVP_PKEY_get_size(pkey) < RSA_PSS_MINIMUM_KEY_SIZE(md)) return 0; return 1; } @@ -866,7 +1272,9 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) for (i = 0; i < SSL_PKEY_NUM; i++) { const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(i); - if (clu->amask & s->s3->tmp.new_cipher->algorithm_auth) { + if (clu == NULL) + continue; + if (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) { idx = i; break; } @@ -875,7 +1283,7 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) /* * Some GOST ciphersuites allow more than one signature algorithms * */ - if (idx == SSL_PKEY_GOST01 && s->s3->tmp.new_cipher->algorithm_auth != SSL_aGOST01) { + if (idx == SSL_PKEY_GOST01 && s->s3.tmp.new_cipher->algorithm_auth != SSL_aGOST01) { int real_idx; for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST01; @@ -886,6 +1294,21 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) } } } + /* + * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used + * with new (aGOST12-only) ciphersuites, we should find out which one is available really. + */ + else if (idx == SSL_PKEY_GOST12_256) { + int real_idx; + + for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256; + real_idx--) { + if (s->cert->pkeys[real_idx].privatekey != NULL) { + idx = real_idx; + break; + } + } + } } else { idx = s->cert->key - s->cert->pkeys; } @@ -893,9 +1316,11 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg)) return NULL; if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, tls_default_sigalg[idx]); - if (!tls1_lookup_md(lu, NULL)) + if (lu == NULL) + return NULL; + if (!tls1_lookup_md(s->ctx, lu, NULL)) return NULL; if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) return NULL; @@ -916,7 +1341,7 @@ int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey) lu = tls1_get_legacy_sigalg(s, idx); if (lu == NULL) return 0; - s->s3->tmp.peer_sigalg = lu; + s->s3.tmp.peer_sigalg = lu; return 1; } @@ -926,7 +1351,6 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) * If Suite B mode use Suite B sigalgs only, ignore any other * preferences. */ -#ifndef OPENSSL_NO_EC switch (tls1_suiteb(s)) { case SSL_CERT_FLAG_SUITEB_128_LOS: *psigs = suiteb_sigalgs; @@ -940,7 +1364,6 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) *psigs = suiteb_sigalgs + 1; return 1; } -#endif /* * We use client_sigalgs (if not NULL) if we're a server * and sending a certificate request or if we're a client and @@ -958,7 +1381,6 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) } } -#ifndef OPENSSL_NO_EC /* * Called by servers only. Checks that we have a sig alg that supports the * specified EC curve. @@ -977,7 +1399,7 @@ int tls_check_sigalg_curve(const SSL *s, int curve) } for (i = 0; i < siglen; i++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, sigs[i]); if (lu == NULL) continue; @@ -989,23 +1411,40 @@ int tls_check_sigalg_curve(const SSL *s, int curve) return 0; } -#endif /* * Return the number of security bits for the signature algorithm, or 0 on * error. */ -static int sigalg_security_bits(const SIGALG_LOOKUP *lu) +static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu) { const EVP_MD *md = NULL; int secbits = 0; - if (!tls1_lookup_md(lu, &md)) + if (!tls1_lookup_md(ctx, lu, &md)) return 0; if (md != NULL) { + int md_type = EVP_MD_get_type(md); + /* Security bits: half digest bits */ - secbits = EVP_MD_size(md) * 4; + secbits = EVP_MD_get_size(md) * 4; + /* + * SHA1 and MD5 are known to be broken. Reduce security bits so that + * they're no longer accepted at security level 1. The real values don't + * really matter as long as they're lower than 80, which is our + * security level 1. + * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for + * SHA1 at 2^63.4 and MD5+SHA1 at 2^67.2 + * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf + * puts a chosen-prefix attack for MD5 at 2^39. + */ + if (md_type == NID_sha1) + secbits = 64; + else if (md_type == NID_md5_sha1) + secbits = 67; + else if (md_type == NID_md5) + secbits = 39; } else { /* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */ if (lu->sigalg == TLSEXT_SIGALG_ed25519) @@ -1027,25 +1466,25 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) const EVP_MD *md = NULL; char sigalgstr[2]; size_t sent_sigslen, i, cidx; - int pkeyid = EVP_PKEY_id(pkey); + int pkeyid = -1; const SIGALG_LOOKUP *lu; int secbits = 0; + pkeyid = EVP_PKEY_get_id(pkey); /* Should never happen */ if (pkeyid == -1) return -1; if (SSL_IS_TLS13(s)) { /* Disallow DSA for TLS 1.3 */ if (pkeyid == EVP_PKEY_DSA) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Only allow PSS for TLS 1.3 */ if (pkeyid == EVP_PKEY_RSA) pkeyid = EVP_PKEY_RSA_PSS; } - lu = tls1_lookup_sigalg(sig); + lu = tls1_lookup_sigalg(s, sig); /* * Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type * is consistent with signature: RSA keys can be used for RSA-PSS @@ -1054,45 +1493,38 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) || (pkeyid != lu->sig && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Check the sigalg is consistent with the key OID */ - if (!ssl_cert_lookup_by_nid(EVP_PKEY_id(pkey), &cidx) + if (!ssl_cert_lookup_by_nid(EVP_PKEY_get_id(pkey), &cidx) || lu->sig_idx != (int)cidx) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } -#ifndef OPENSSL_NO_EC if (pkeyid == EVP_PKEY_EC) { /* Check point compression is permitted */ if (!tls1_check_pkey_comp(s, pkey)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_ILLEGAL_POINT_COMPRESSION); return 0; } /* For TLS 1.3 or Suite B check curve matches signature algorithm */ if (SSL_IS_TLS13(s) || tls1_suiteb(s)) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + int curve = ssl_get_EC_curve_nid(pkey); if (lu->curve != NID_undef && curve != lu->curve) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); return 0; } } if (!SSL_IS_TLS13(s)) { /* Check curve matches extensions */ if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); return 0; } if (tls1_suiteb(s)) { @@ -1100,18 +1532,15 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256 && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } } } } else if (tls1_suiteb(s)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } -#endif /* Check signature matches a type we sent */ sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); @@ -1122,13 +1551,11 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) /* Allow fallback to SHA1 if not strict mode */ if (i == sent_sigslen && (lu->hash != NID_sha1 || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - if (!tls1_lookup_md(lu, &md)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_UNKNOWN_DIGEST); + if (!tls1_lookup_md(s->ctx, lu, &md)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST); return 0; } /* @@ -1137,33 +1564,32 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) */ sigalgstr[0] = (sig >> 8) & 0xff; sigalgstr[1] = sig & 0xff; - secbits = sigalg_security_bits(lu); + secbits = sigalg_security_bits(s->ctx, lu); if (secbits == 0 || !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits, - md != NULL ? EVP_MD_type(md) : NID_undef, + md != NULL ? EVP_MD_get_type(md) : NID_undef, (void *)sigalgstr)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Store the sigalg the peer uses */ - s->s3->tmp.peer_sigalg = lu; + s->s3.tmp.peer_sigalg = lu; return 1; } int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3->tmp.peer_sigalg == NULL) + if (s->s3.tmp.peer_sigalg == NULL) return 0; - *pnid = s->s3->tmp.peer_sigalg->sig; + *pnid = s->s3.tmp.peer_sigalg->sig; return 1; } int SSL_get_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3->tmp.sigalg == NULL) + if (s->s3.tmp.sigalg == NULL) return 0; - *pnid = s->s3->tmp.sigalg->sig; + *pnid = s->s3.tmp.sigalg->sig; return 1; } @@ -1179,23 +1605,23 @@ int SSL_get_signature_type_nid(const SSL *s, int *pnid) */ int ssl_set_client_disabled(SSL *s) { - s->s3->tmp.mask_a = 0; - s->s3->tmp.mask_k = 0; - ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK); - if (ssl_get_min_max_version(s, &s->s3->tmp.min_ver, - &s->s3->tmp.max_ver, NULL) != 0) + s->s3.tmp.mask_a = 0; + s->s3.tmp.mask_k = 0; + ssl_set_sig_mask(&s->s3.tmp.mask_a, s, SSL_SECOP_SIGALG_MASK); + if (ssl_get_min_max_version(s, &s->s3.tmp.min_ver, + &s->s3.tmp.max_ver, NULL) != 0) return 0; #ifndef OPENSSL_NO_PSK /* with PSK there must be client callback set */ if (!s->psk_client_callback) { - s->s3->tmp.mask_a |= SSL_aPSK; - s->s3->tmp.mask_k |= SSL_PSK; + s->s3.tmp.mask_a |= SSL_aPSK; + s->s3.tmp.mask_k |= SSL_PSK; } #endif /* OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_SRP if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) { - s->s3->tmp.mask_a |= SSL_aSRP; - s->s3->tmp.mask_k |= SSL_kSRP; + s->s3.tmp.mask_a |= SSL_aSRP; + s->s3.tmp.mask_k |= SSL_kSRP; } #endif return 1; @@ -1212,10 +1638,10 @@ int ssl_set_client_disabled(SSL *s) */ int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe) { - if (c->algorithm_mkey & s->s3->tmp.mask_k - || c->algorithm_auth & s->s3->tmp.mask_a) + if (c->algorithm_mkey & s->s3.tmp.mask_k + || c->algorithm_auth & s->s3.tmp.mask_a) return 1; - if (s->s3->tmp.max_ver == 0) + if (s->s3.tmp.max_ver == 0) return 1; if (!SSL_IS_DTLS(s)) { int min_tls = c->min_tls; @@ -1228,11 +1654,11 @@ int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe) && (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0) min_tls = SSL3_VERSION; - if ((min_tls > s->s3->tmp.max_ver) || (c->max_tls < s->s3->tmp.min_ver)) + if ((min_tls > s->s3.tmp.max_ver) || (c->max_tls < s->s3.tmp.min_ver)) return 1; } - if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3->tmp.max_ver) - || DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver))) + if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver) + || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver))) return 1; return !ssl_security(s, op, c->strength_bits, 0, (void *)c); @@ -1255,13 +1681,13 @@ int tls1_set_server_sigalgs(SSL *s) s->shared_sigalgslen = 0; /* Clear certificate validity flags */ for (i = 0; i < SSL_PKEY_NUM; i++) - s->s3->tmp.valid_flags[i] = 0; + s->s3.tmp.valid_flags[i] = 0; /* * If peer sent no signature algorithms check to see if we support * the default algorithm for each certificate type */ - if (s->s3->tmp.peer_cert_sigalgs == NULL - && s->s3->tmp.peer_sigalgs == NULL) { + if (s->s3.tmp.peer_cert_sigalgs == NULL + && s->s3.tmp.peer_sigalgs == NULL) { const uint16_t *sent_sigs; size_t sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); @@ -1274,7 +1700,7 @@ int tls1_set_server_sigalgs(SSL *s) /* Check default matches a type we sent */ for (j = 0; j < sent_sigslen; j++) { if (lu->sigalg == sent_sigs[j]) { - s->s3->tmp.valid_flags[i] = CERT_PKEY_SIGN; + s->s3.tmp.valid_flags[i] = CERT_PKEY_SIGN; break; } } @@ -1283,15 +1709,14 @@ int tls1_set_server_sigalgs(SSL *s) } if (!tls1_process_sigalgs(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (s->shared_sigalgs != NULL) return 1; /* Fatal error if no shared signature algorithms */ - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS1_SET_SERVER_SIGALGS, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS); return 0; } @@ -1360,11 +1785,11 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, SSL_SESSION *sess = NULL; unsigned char *sdec; const unsigned char *p; - int slen, renew_ticket = 0, declen; + int slen, ivlen, renew_ticket = 0, declen; SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER; size_t mlen; unsigned char tick_hmac[EVP_MAX_MD_SIZE]; - HMAC_CTX *hctx = NULL; + SSL_HMAC *hctx = NULL; EVP_CIPHER_CTX *ctx = NULL; SSL_CTX *tctx = s->session_ctx; @@ -1394,7 +1819,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Initialize session ticket encryption and HMAC contexts */ - hctx = HMAC_CTX_new(); + hctx = ssl_hmac_new(tctx); if (hctx == NULL) { ret = SSL_TICKET_FATAL_ERR_MALLOC; goto end; @@ -1404,11 +1829,28 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, ret = SSL_TICKET_FATAL_ERR_MALLOC; goto end; } - if (tctx->ext.ticket_key_cb) { +#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 + { unsigned char *nctick = (unsigned char *)etick; - int rv = tctx->ext.ticket_key_cb(s, nctick, + int rv = 0; + + if (tctx->ext.ticket_key_evp_cb != NULL) + rv = tctx->ext.ticket_key_evp_cb(s, nctick, + nctick + TLSEXT_KEYNAME_LENGTH, + ctx, + ssl_hmac_get0_EVP_MAC_CTX(hctx), + 0); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + else if (tctx->ext.ticket_key_cb != NULL) + /* if 0 is returned, write an empty ticket */ + rv = tctx->ext.ticket_key_cb(s, nctick, nctick + TLSEXT_KEYNAME_LENGTH, - ctx, hctx, 0); + ctx, ssl_hmac_get0_HMAC_CTX(hctx), 0); +#endif if (rv < 0) { ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; @@ -1420,21 +1862,29 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (rv == 2) renew_ticket = 1; } else { + EVP_CIPHER *aes256cbc = NULL; + /* Check key name matches */ if (memcmp(etick, tctx->ext.tick_key_name, TLSEXT_KEYNAME_LENGTH) != 0) { ret = SSL_TICKET_NO_DECRYPT; goto end; } - if (HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key, - sizeof(tctx->ext.secure->tick_hmac_key), - EVP_sha256(), NULL) <= 0 - || EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, + + aes256cbc = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC", + s->ctx->propq); + if (aes256cbc == NULL + || ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key, + sizeof(tctx->ext.secure->tick_hmac_key), + "SHA256") <= 0 + || EVP_DecryptInit_ex(ctx, aes256cbc, NULL, tctx->ext.secure->tick_aes_key, etick + TLSEXT_KEYNAME_LENGTH) <= 0) { + EVP_CIPHER_free(aes256cbc); ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } + EVP_CIPHER_free(aes256cbc); if (SSL_IS_TLS13(s)) renew_ticket = 1; } @@ -1442,22 +1892,27 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, * Attempt to process session ticket, first conduct sanity and integrity * checks on ticket. */ - mlen = HMAC_size(hctx); + mlen = ssl_hmac_size(hctx); if (mlen == 0) { ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } + ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + if (ivlen < 0) { + ret = SSL_TICKET_FATAL_ERR_OTHER; + goto end; + } + /* Sanity check ticket length: must exceed keyname + IV + HMAC */ - if (eticklen <= - TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx) + mlen) { + if (eticklen <= TLSEXT_KEYNAME_LENGTH + ivlen + mlen) { ret = SSL_TICKET_NO_DECRYPT; goto end; } eticklen -= mlen; /* Check HMAC of encrypted ticket */ - if (HMAC_Update(hctx, etick, eticklen) <= 0 - || HMAC_Final(hctx, tick_hmac, NULL) <= 0) { + if (ssl_hmac_update(hctx, etick, eticklen) <= 0 + || ssl_hmac_final(hctx, tick_hmac, NULL, sizeof(tick_hmac)) <= 0) { ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } @@ -1468,8 +1923,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ - p = etick + TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx); - eticklen -= TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx); + p = etick + TLSEXT_KEYNAME_LENGTH + ivlen; + eticklen -= TLSEXT_KEYNAME_LENGTH + ivlen; sdec = OPENSSL_malloc(eticklen); if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p, (int)eticklen) <= 0) { @@ -1520,7 +1975,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, end: EVP_CIPHER_CTX_free(ctx); - HMAC_CTX_free(hctx); + ssl_hmac_free(hctx); /* * If set, the decrypt_ticket_cb() is called unless a fatal error was @@ -1595,21 +2050,23 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) unsigned char sigalgstr[2]; int secbits; - /* See if sigalgs is recognised and if hash is enabled */ - if (!tls1_lookup_md(lu, NULL)) + if (lu == NULL || !lu->enabled) return 0; /* DSA is not allowed in TLS 1.3 */ if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA) return 0; - /* TODO(OpenSSL1.2) fully axe DSA/etc. in ClientHello per TLS 1.3 spec */ - if (!s->server && !SSL_IS_DTLS(s) && s->s3->tmp.min_ver >= TLS1_3_VERSION + /* + * At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3 + * spec + */ + if (!s->server && !SSL_IS_DTLS(s) && s->s3.tmp.min_ver >= TLS1_3_VERSION && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX || lu->hash_idx == SSL_MD_MD5_IDX || lu->hash_idx == SSL_MD_SHA224_IDX)) return 0; /* See if public key algorithm allowed */ - if (ssl_cert_is_disabled(lu->sig_idx)) + if (ssl_cert_is_disabled(s->ctx, lu->sig_idx)) return 0; if (lu->sig == NID_id_GostR3410_2012_256 @@ -1620,7 +2077,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) return 0; if (!s->server && s->method->version == TLS_ANY_VERSION - && s->s3->tmp.max_ver >= TLS1_3_VERSION) { + && s->s3.tmp.max_ver >= TLS1_3_VERSION) { int i, num; STACK_OF(SSL_CIPHER) *sk; @@ -1630,7 +2087,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) * ciphersuites enabled. */ - if (s->s3->tmp.min_ver >= TLS1_3_VERSION) + if (s->s3.tmp.min_ver >= TLS1_3_VERSION) return 0; sk = SSL_get_ciphers(s); @@ -1643,7 +2100,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) continue; - if ((c->algorithm_mkey & SSL_kGOST) != 0) + if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0) break; } if (i == num) @@ -1652,7 +2109,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) } /* Finally see if security callback allows it */ - secbits = sigalg_security_bits(lu); + secbits = sigalg_security_bits(s->ctx, lu); sigalgstr[0] = (lu->sigalg >> 8) & 0xff; sigalgstr[1] = lu->sigalg & 0xff; return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr); @@ -1675,15 +2132,15 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) */ sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); for (i = 0; i < sigalgslen; i++, sigalgs++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*sigalgs); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *sigalgs); const SSL_CERT_LOOKUP *clu; if (lu == NULL) continue; clu = ssl_cert_lookup_by_idx(lu->sig_idx); - if (clu == NULL) - continue; + if (clu == NULL) + continue; /* If algorithm is disabled see if we can enable it */ if ((clu->amask & disabled_mask) != 0 @@ -1700,9 +2157,10 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, int rv = 0; for (i = 0; i < psiglen; i++, psig++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*psig); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *psig); - if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) + if (lu == NULL + || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) continue; if (!WPACKET_put_bytes_u16(pkt, *psig)) return 0; @@ -1717,7 +2175,7 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, rv = 1; } if (rv == 0) - SSLerr(SSL_F_TLS12_COPY_SIGALGS, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return rv; } @@ -1729,10 +2187,11 @@ static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig, const uint16_t *ptmp, *atmp; size_t i, j, nmatch = 0; for (i = 0, ptmp = pref; i < preflen; i++, ptmp++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*ptmp); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *ptmp); /* Skip disabled hashes or signature algorithms */ - if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu)) + if (lu == NULL + || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu)) continue; for (j = 0, atmp = allow; j < allowlen; j++, atmp++) { if (*ptmp == *atmp) { @@ -1771,18 +2230,18 @@ static int tls1_set_shared_sigalgs(SSL *s) if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; - allow = s->s3->tmp.peer_sigalgs; - allowlen = s->s3->tmp.peer_sigalgslen; + allow = s->s3.tmp.peer_sigalgs; + allowlen = s->s3.tmp.peer_sigalgslen; } else { allow = conf; allowlen = conflen; - pref = s->s3->tmp.peer_sigalgs; - preflen = s->s3->tmp.peer_sigalgslen; + pref = s->s3.tmp.peer_sigalgs; + preflen = s->s3.tmp.peer_sigalgslen; } nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); if (nmatch) { if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) { - SSLerr(SSL_F_TLS1_SET_SHARED_SIGALGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); @@ -1809,7 +2268,7 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen) size >>= 1; if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL) { - SSLerr(SSL_F_TLS1_SAVE_U16, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++) @@ -1837,11 +2296,11 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) return 0; if (cert) - return tls1_save_u16(pkt, &s->s3->tmp.peer_cert_sigalgs, - &s->s3->tmp.peer_cert_sigalgslen); + return tls1_save_u16(pkt, &s->s3.tmp.peer_cert_sigalgs, + &s->s3.tmp.peer_cert_sigalgslen); else - return tls1_save_u16(pkt, &s->s3->tmp.peer_sigalgs, - &s->s3->tmp.peer_sigalgslen); + return tls1_save_u16(pkt, &s->s3.tmp.peer_sigalgs, + &s->s3.tmp.peer_sigalgslen); } @@ -1850,7 +2309,7 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) int tls1_process_sigalgs(SSL *s) { size_t i; - uint32_t *pvalid = s->s3->tmp.valid_flags; + uint32_t *pvalid = s->s3.tmp.valid_flags; if (!tls1_set_shared_sigalgs(s)) return 0; @@ -1866,7 +2325,7 @@ int tls1_process_sigalgs(SSL *s) if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) continue; /* If not disabled indicate we can explicitly sign */ - if (pvalid[idx] == 0 && !ssl_cert_is_disabled(idx)) + if (pvalid[idx] == 0 && !ssl_cert_is_disabled(s->ctx, idx)) pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; } return 1; @@ -1876,8 +2335,8 @@ int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash, unsigned char *rsig, unsigned char *rhash) { - uint16_t *psig = s->s3->tmp.peer_sigalgs; - size_t numsigalgs = s->s3->tmp.peer_sigalgslen; + uint16_t *psig = s->s3.tmp.peer_sigalgs; + size_t numsigalgs = s->s3.tmp.peer_sigalgslen; if (psig == NULL || numsigalgs > INT_MAX) return 0; if (idx >= 0) { @@ -1890,7 +2349,7 @@ int SSL_get_sigalgs(SSL *s, int idx, *rhash = (unsigned char)((*psig >> 8) & 0xff); if (rsig != NULL) *rsig = (unsigned char)(*psig & 0xff); - lu = tls1_lookup_sigalg(*psig); + lu = tls1_lookup_sigalg(s, *psig); if (psign != NULL) *psign = lu != NULL ? lu->sig : NID_undef; if (phash != NULL) @@ -2039,7 +2498,7 @@ int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, uint16_t *sigalgs; if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) { - SSLerr(SSL_F_TLS1_SET_RAW_SIGALGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs)); @@ -2065,7 +2524,7 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) if (salglen & 1) return 0; if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) { - SSLerr(SSL_F_TLS1_SET_SIGALGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0, sptr = sigalgs; i < salglen; i += 2) { @@ -2115,20 +2574,20 @@ static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) if (default_nid) return sig_nid == default_nid ? 1 : 0; - if (SSL_IS_TLS13(s) && s->s3->tmp.peer_cert_sigalgs != NULL) { + if (SSL_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) { /* * If we're in TLSv1.3 then we only get here if we're checking the * chain. If the peer has specified peer_cert_sigalgs then we use them * otherwise we default to normal sigalgs. */ - sigalgslen = s->s3->tmp.peer_cert_sigalgslen; + sigalgslen = s->s3.tmp.peer_cert_sigalgslen; use_pc_sigalgs = 1; } else { sigalgslen = s->shared_sigalgslen; } for (i = 0; i < sigalgslen; i++) { sigalg = use_pc_sigalgs - ? tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]) + ? tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]) : s->shared_sigalgs[i]; if (sigalg != NULL && sig_nid == sigalg->sigandhash) return 1; @@ -2139,7 +2598,7 @@ static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) /* Check to see if a certificate issuer name matches list of CA names */ static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) { - X509_NAME *nm; + const X509_NAME *nm; int i; nm = X509_get_issuer_name(x); for (i = 0; i < sk_X509_NAME_num(names); i++) { @@ -2183,7 +2642,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, idx = (int)(cpk - c->pkeys); } else cpk = c->pkeys + idx; - pvalid = s->s3->tmp.valid_flags + idx; + pvalid = s->s3.tmp.valid_flags + idx; x = cpk->x509; pk = cpk->privatekey; chain = cpk->chain; @@ -2200,7 +2659,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (ssl_cert_lookup_by_pkey(pk, &certidx) == NULL) return 0; idx = certidx; - pvalid = s->s3->tmp.valid_flags + idx; + pvalid = s->s3.tmp.valid_flags + idx; if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) check_flags = CERT_PKEY_STRICT_FLAGS; @@ -2227,8 +2686,8 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { int default_nid; int rsign = 0; - if (s->s3->tmp.peer_cert_sigalgs != NULL - || s->s3->tmp.peer_sigalgs != NULL) { + if (s->s3.tmp.peer_cert_sigalgs != NULL + || s->s3.tmp.peer_sigalgs != NULL) { default_nid = 0; /* If no sigalgs extension use defaults from RFC5246 */ } else { @@ -2276,7 +2735,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, size_t j; const uint16_t *p = c->conf_sigalgs; for (j = 0; j < c->conf_sigalgslen; j++, p++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*p); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *p); if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign) break; @@ -2340,22 +2799,19 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (!s->server && strict_mode) { STACK_OF(X509_NAME) *ca_dn; int check_type = 0; - switch (EVP_PKEY_id(pk)) { - case EVP_PKEY_RSA: + + if (EVP_PKEY_is_a(pk, "RSA")) check_type = TLS_CT_RSA_SIGN; - break; - case EVP_PKEY_DSA: + else if (EVP_PKEY_is_a(pk, "DSA")) check_type = TLS_CT_DSS_SIGN; - break; - case EVP_PKEY_EC: + else if (EVP_PKEY_is_a(pk, "EC")) check_type = TLS_CT_ECDSA_SIGN; - break; - } + if (check_type) { - const uint8_t *ctypes = s->s3->tmp.ctype; + const uint8_t *ctypes = s->s3.tmp.ctype; size_t j; - for (j = 0; j < s->s3->tmp.ctype_len; j++, ctypes++) { + for (j = 0; j < s->s3.tmp.ctype_len; j++, ctypes++) { if (*ctypes == check_type) { rv |= CERT_PKEY_CERT_TYPE; break; @@ -2367,7 +2823,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, rv |= CERT_PKEY_CERT_TYPE; } - ca_dn = s->s3->tmp.peer_ca_names; + ca_dn = s->s3.tmp.peer_ca_names; if (ca_dn == NULL || sk_X509_NAME_num(ca_dn) == 0 @@ -2434,36 +2890,28 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) return tls1_check_chain(s, x, pk, chain, -1); } -#ifndef OPENSSL_NO_DH -DH *ssl_get_auto_dh(SSL *s) +EVP_PKEY *ssl_get_auto_dh(SSL *s) { - DH *dhp = NULL; - BIGNUM *p = NULL, *g = NULL; + EVP_PKEY *dhp = NULL; + BIGNUM *p; int dh_secbits = 80, sec_level_bits; + EVP_PKEY_CTX *pctx = NULL; + OSSL_PARAM_BLD *tmpl = NULL; + OSSL_PARAM *params = NULL; if (s->cert->dh_tmp_auto != 2) { - if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { - if (s->s3->tmp.new_cipher->strength_bits == 256) + if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { + if (s->s3.tmp.new_cipher->strength_bits == 256) dh_secbits = 128; else dh_secbits = 80; } else { - if (s->s3->tmp.cert == NULL) + if (s->s3.tmp.cert == NULL) return NULL; - dh_secbits = EVP_PKEY_security_bits(s->s3->tmp.cert->privatekey); + dh_secbits = EVP_PKEY_get_security_bits(s->s3.tmp.cert->privatekey); } } - dhp = DH_new(); - if (dhp == NULL) - return NULL; - g = BN_new(); - if (g == NULL || !BN_set_word(g, 2)) { - DH_free(dhp); - BN_free(g); - return NULL; - } - /* Do not pick a prime that is too weak for the current security level */ sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL); if (dh_secbits < sec_level_bits) @@ -2479,15 +2927,32 @@ DH *ssl_get_auto_dh(SSL *s) p = BN_get_rfc3526_prime_2048(NULL); else p = BN_get_rfc2409_prime_1024(NULL); - if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { - DH_free(dhp); - BN_free(p); - BN_free(g); - return NULL; - } + if (p == NULL) + goto err; + + pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq); + if (pctx == NULL + || EVP_PKEY_fromdata_init(pctx) != 1) + goto err; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !OSSL_PARAM_BLD_push_uint(tmpl, OSSL_PKEY_PARAM_FFC_G, 2)) + goto err; + + params = OSSL_PARAM_BLD_to_param(tmpl); + if (params == NULL + || EVP_PKEY_fromdata(pctx, &dhp, EVP_PKEY_KEY_PARAMETERS, params) != 1) + goto err; + +err: + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(tmpl); + EVP_PKEY_CTX_free(pctx); + BN_free(p); return dhp; } -#endif static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op) { @@ -2500,7 +2965,7 @@ static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op) * reject keys which omit parameters but this only affects DSA and * omission of parameters is never (?) done in practice. */ - secbits = EVP_PKEY_security_bits(pkey); + secbits = EVP_PKEY_get_security_bits(pkey); } if (s) return ssl_security(s, op, secbits, 0, x); @@ -2584,12 +3049,12 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) /* If not recognised or not supported by cipher mask it is not suitable */ if (clu == NULL - || (clu->amask & s->s3->tmp.new_cipher->algorithm_auth) == 0 + || (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0 || (clu->nid == EVP_PKEY_RSA_PSS - && (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0)) + && (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0)) return -1; - return s->s3->tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; + return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; } /* @@ -2602,27 +3067,36 @@ static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu; - int mdnid, pknid, default_mdnid; + int mdnid, pknid, supported; size_t i; + const char *mdname = NULL; - /* If the EVP_PKEY reports a mandatory digest, allow nothing else. */ - ERR_set_mark(); - if (EVP_PKEY_get_default_digest_nid(pkey, &default_mdnid) == 2 && - sig->hash != default_mdnid) - return 0; - - /* If it didn't report a mandatory NID, for whatever reasons, - * just clear the error and allow all hashes to be used. */ - ERR_pop_to_mark(); + /* + * If the given EVP_PKEY cannot support signing with this digest, + * the answer is simply 'no'. + */ + if (sig->hash != NID_undef) + mdname = OBJ_nid2sn(sig->hash); + supported = EVP_PKEY_digestsign_supports_digest(pkey, s->ctx->libctx, + mdname, + s->ctx->propq); + if (supported <= 0) + return 0; - if (s->s3->tmp.peer_cert_sigalgs != NULL) { - for (i = 0; i < s->s3->tmp.peer_cert_sigalgslen; i++) { - lu = tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]); - if (lu == NULL - || !X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL)) + /* + * The TLS 1.3 signature_algorithms_cert extension places restrictions + * on the sigalg with which the certificate was signed (by its issuer). + */ + if (s->s3.tmp.peer_cert_sigalgs != NULL) { + if (!X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL)) + return 0; + for (i = 0; i < s->s3.tmp.peer_cert_sigalgslen; i++) { + lu = tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]); + if (lu == NULL) continue; + /* - * TODO this does not differentiate between the + * This does not differentiate between the * rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not * have a chain here that lets us look at the key OID in the * signing certificate. @@ -2632,6 +3106,11 @@ static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, } return 0; } + + /* + * Without signat_algorithms_cert, any certificate for which we have + * a viable public key is permitted. + */ return 1; } @@ -2682,9 +3161,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu = NULL; size_t i; -#ifndef OPENSSL_NO_EC int curve = -1; -#endif EVP_PKEY *tmppkey; /* Look for a shared sigalgs matching possible certificates */ @@ -2698,7 +3175,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) || lu->sig == EVP_PKEY_RSA) continue; /* Check that we have a cert, and signature_algorithms_cert */ - if (!tls1_lookup_md(lu, NULL)) + if (!tls1_lookup_md(s->ctx, lu, NULL)) continue; if ((pkey == NULL && !has_usable_cert(s, lu, -1)) || (pkey != NULL && !is_cert_usable(s, lu, x, pkey))) @@ -2708,19 +3185,13 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) : s->cert->pkeys[lu->sig_idx].privatekey; if (lu->sig == EVP_PKEY_EC) { -#ifndef OPENSSL_NO_EC - if (curve == -1) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(tmppkey); - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } + if (curve == -1) + curve = ssl_get_EC_curve_nid(tmppkey); if (lu->curve != NID_undef && curve != lu->curve) continue; -#else - continue; -#endif } else if (lu->sig == EVP_PKEY_RSA_PSS) { /* validate that key is large enough for the signature algorithm */ - if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu)) + if (!rsa_pss_check_min_key_size(s->ctx, tmppkey, lu)) continue; } break; @@ -2748,39 +3219,34 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) const SIGALG_LOOKUP *lu = NULL; int sig_idx = -1; - s->s3->tmp.cert = NULL; - s->s3->tmp.sigalg = NULL; + s->s3.tmp.cert = NULL; + s->s3.tmp.sigalg = NULL; if (SSL_IS_TLS13(s)) { lu = find_sig_alg(s, NULL, NULL); if (lu == NULL) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CHOOSE_SIGALG, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } } else { /* If ciphersuite doesn't require a cert nothing to do */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aCERT)) + if (!(s->s3.tmp.new_cipher->algorithm_auth & SSL_aCERT)) return 1; if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys)) return 1; if (SSL_USE_SIGALGS(s)) { size_t i; - if (s->s3->tmp.peer_sigalgs != NULL) { -#ifndef OPENSSL_NO_EC - int curve; + if (s->s3.tmp.peer_sigalgs != NULL) { + int curve = -1; /* For Suite B need to match signature algorithm to curve */ - if (tls1_suiteb(s)) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey); - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } else { - curve = -1; - } -#endif + if (tls1_suiteb(s)) + curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC] + .privatekey); /* * Find highest preference signature algorithm matching @@ -2806,12 +3272,10 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) /* validate that key is large enough for the signature algorithm */ EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey; - if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu)) + if (!rsa_pss_check_min_key_size(s->ctx, pkey, lu)) continue; } -#ifndef OPENSSL_NO_EC if (curve == -1 || lu->curve == curve) -#endif break; } #ifndef OPENSSL_NO_GOST @@ -2820,12 +3284,11 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) * in supported_algorithms extension, so when we have GOST-based ciphersuite, * we have to assume GOST support. */ - if (i == s->shared_sigalgslen && s->s3->tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) { + if (i == s->shared_sigalgslen && s->s3.tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) { if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CHOOSE_SIGALG, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } else { @@ -2838,7 +3301,6 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CHOOSE_SIGALG, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } @@ -2852,8 +3314,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } @@ -2867,8 +3329,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if (i == sent_sigslen) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_CHOOSE_SIGALG, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } @@ -2877,17 +3338,17 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } } } if (sig_idx == -1) sig_idx = lu->sig_idx; - s->s3->tmp.cert = &s->cert->pkeys[sig_idx]; - s->cert->key = s->s3->tmp.cert; - s->s3->tmp.sigalg = lu; + s->s3.tmp.cert = &s->cert->pkeys[sig_idx]; + s->cert->key = s->s3.tmp.cert; + s->s3.tmp.sigalg = lu; return 1; } @@ -2895,8 +3356,7 @@ int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode) { if (mode != TLSEXT_max_fragment_length_DISABLED && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) { - SSLerr(SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH, - SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -2908,8 +3368,7 @@ int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode) { if (mode != TLSEXT_max_fragment_length_DISABLED && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) { - SSLerr(SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH, - SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -2921,3 +3380,129 @@ uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *session) { return session->ext.max_fragment_len_mode; } + +/* + * Helper functions for HMAC access with legacy support included. + */ +SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx) +{ + SSL_HMAC *ret = OPENSSL_zalloc(sizeof(*ret)); + EVP_MAC *mac = NULL; + + if (ret == NULL) + return NULL; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->ext.ticket_key_evp_cb == NULL + && ctx->ext.ticket_key_cb != NULL) { + if (!ssl_hmac_old_new(ret)) + goto err; + return ret; + } +#endif + mac = EVP_MAC_fetch(ctx->libctx, "HMAC", ctx->propq); + if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL) + goto err; + EVP_MAC_free(mac); + return ret; + err: + EVP_MAC_CTX_free(ret->ctx); + EVP_MAC_free(mac); + OPENSSL_free(ret); + return NULL; +} + +void ssl_hmac_free(SSL_HMAC *ctx) +{ + if (ctx != NULL) { + EVP_MAC_CTX_free(ctx->ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + ssl_hmac_old_free(ctx); +#endif + OPENSSL_free(ctx); + } +} + +EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx) +{ + return ctx->ctx; +} + +int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md) +{ + OSSL_PARAM params[2], *p = params; + + if (ctx->ctx != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_MAC_init(ctx->ctx, key, len, params)) + return 1; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_init(ctx, key, len, md); +#endif + return 0; +} + +int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len) +{ + if (ctx->ctx != NULL) + return EVP_MAC_update(ctx->ctx, data, len); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_update(ctx, data, len); +#endif + return 0; +} + +int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, + size_t max_size) +{ + if (ctx->ctx != NULL) + return EVP_MAC_final(ctx->ctx, md, len, max_size); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_final(ctx, md, len); +#endif + return 0; +} + +size_t ssl_hmac_size(const SSL_HMAC *ctx) +{ + if (ctx->ctx != NULL) + return EVP_MAC_CTX_get_mac_size(ctx->ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_size(ctx); +#endif + return 0; +} + +int ssl_get_EC_curve_nid(const EVP_PKEY *pkey) +{ + char gname[OSSL_MAX_NAME_SIZE]; + + if (EVP_PKEY_get_group_name(pkey, gname, sizeof(gname), NULL) > 0) + return OBJ_txt2nid(gname); + + return NID_undef; +} + +__owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey, + const unsigned char *enckey, + size_t enckeylen) +{ + if (EVP_PKEY_is_a(pkey, "DH")) { + int bits = EVP_PKEY_get_bits(pkey); + + if (bits <= 0 || enckeylen != (size_t)bits / 8) + /* the encoded key must be padded to the length of the p */ + return 0; + } else if (EVP_PKEY_is_a(pkey, "EC")) { + if (enckeylen < 3 /* point format and at least 1 byte for x and y */ + || enckey[0] != 0x04) + return 0; + } + + return EVP_PKEY_set1_encoded_public_key(pkey, enckey, enckeylen); +} diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index e2c397b75657..405b1e6864a7 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -1,7 +1,7 @@ /* - * Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2021 The OpenSSL Project Authors. 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 @@ -427,6 +427,7 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = { {0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"}, {0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"}, {0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"}, + {0xC102, "IANA-GOST2012-GOST8912-GOST8912"}, {0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"}, {0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"}, {0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"}, @@ -441,8 +442,11 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = { {0x1305, "TLS_AES_128_CCM_8_SHA256"}, {0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, - {0xFF85, "GOST2012-GOST8912-GOST8912"}, + {0xFF85, "LEGACY-GOST2012-GOST8912-GOST8912"}, {0xFF87, "GOST2012-NULL-GOST12"}, + {0xC100, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC"}, + {0xC101, "GOST2012-MAGMA-MAGMAOMAC"}, + {0xC102, "GOST2012-GOST8912-IANA"}, }; /* Compression methods */ @@ -468,7 +472,6 @@ static const ssl_trace_tbl ssl_exts_tbl[] = { {TLSEXT_TYPE_srp, "srp"}, {TLSEXT_TYPE_signature_algorithms, "signature_algorithms"}, {TLSEXT_TYPE_use_srtp, "use_srtp"}, - {TLSEXT_TYPE_heartbeat, "tls_heartbeat"}, {TLSEXT_TYPE_application_layer_protocol_negotiation, "application_layer_protocol_negotiation"}, {TLSEXT_TYPE_signed_certificate_timestamp, "signed_certificate_timestamps"}, @@ -522,6 +525,13 @@ static const ssl_trace_tbl ssl_groups_tbl[] = { {28, "brainpoolP512r1"}, {29, "ecdh_x25519"}, {30, "ecdh_x448"}, + {34, "GC256A"}, + {35, "GC256B"}, + {36, "GC256C"}, + {37, "GC256D"}, + {38, "GC512A"}, + {39, "GC512B"}, + {40, "GC512C"}, {256, "ffdhe2048"}, {257, "ffdhe3072"}, {258, "ffdhe4096"}, @@ -569,6 +579,8 @@ static const ssl_trace_tbl ssl_sigalg_tbl[] = { {TLSEXT_SIGALG_dsa_sha512, "dsa_sha512"}, {TLSEXT_SIGALG_dsa_sha224, "dsa_sha224"}, {TLSEXT_SIGALG_dsa_sha1, "dsa_sha1"}, + {TLSEXT_SIGALG_gostr34102012_256_intrinsic, "gost2012_256"}, + {TLSEXT_SIGALG_gostr34102012_512_intrinsic, "gost2012_512"}, {TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, "gost2012_256"}, {TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, "gost2012_512"}, {TLSEXT_SIGALG_gostr34102001_gostr3411, "gost2001_gost94"}, @@ -584,7 +596,9 @@ static const ssl_trace_tbl ssl_ctype_tbl[] = { {20, "fortezza_dms"}, {64, "ecdsa_sign"}, {65, "rsa_fixed_ecdh"}, - {66, "ecdsa_fixed_ecdh"} + {66, "ecdsa_fixed_ecdh"}, + {67, "gost_sign256"}, + {68, "gost_sign512"}, }; static const ssl_trace_tbl ssl_psk_kex_modes_tbl[] = { @@ -786,9 +800,6 @@ static int ssl_print_extension(BIO *bio, int indent, int server, } break; - case TLSEXT_TYPE_heartbeat: - return 0; - case TLSEXT_TYPE_session_ticket: if (extlen != 0) ssl_print_hex(bio, indent + 4, "ticket", ext, extlen); @@ -1039,7 +1050,7 @@ static int ssl_print_server_hello(BIO *bio, int indent, static int ssl_get_keyex(const char **pname, const SSL *ssl) { - unsigned long alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_k = ssl->s3.tmp.new_cipher->algorithm_mkey; if (alg_k & SSL_kRSA) { *pname = "rsa"; @@ -1077,6 +1088,10 @@ static int ssl_get_keyex(const char **pname, const SSL *ssl) *pname = "GOST"; return SSL_kGOST; } + if (alg_k & SSL_kGOST18) { + *pname = "GOST18"; + return SSL_kGOST18; + } *pname = "UNKNOWN"; return 0; } @@ -1119,7 +1134,15 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl, if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen)) return 0; break; - + case SSL_kGOST: + ssl_print_hex(bio, indent + 2, "GostKeyTransportBlob", msg, msglen); + msglen = 0; + break; + case SSL_kGOST18: + ssl_print_hex(bio, indent + 2, + "GOST-wrapped PreMasterSecret", msg, msglen); + msglen = 0; + break; } return !msglen; @@ -1158,7 +1181,6 @@ static int ssl_print_server_keyex(BIO *bio, int indent, const SSL *ssl, return 0; break; -# ifndef OPENSSL_NO_EC case SSL_kECDHE: case SSL_kECDHEPSK: if (msglen < 1) @@ -1184,7 +1206,6 @@ static int ssl_print_server_keyex(BIO *bio, int indent, const SSL *ssl, return 0; } break; -# endif case SSL_kPSK: case SSL_kRSAPSK: diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index ff85df4483f7..ddcff5eb8911 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -1,7 +1,7 @@ /* * Copyright 2016-2022 The OpenSSL Project Authors. 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 @@ -9,14 +9,20 @@ #include <stdlib.h> #include "ssl_local.h" +#include "internal/ktls.h" +#include "record/record_local.h" #include "internal/cryptlib.h" #include <openssl/evp.h> #include <openssl/kdf.h> +#include <openssl/core_names.h> #define TLS13_MAX_LABEL_LEN 249 -/* Always filled with zeros */ -static const unsigned char default_zeros[EVP_MAX_MD_SIZE]; +#ifdef CHARSET_EBCDIC +static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 }; +#else +static const unsigned char label_prefix[] = "tls13 "; +#endif /* * Given a |secret|; a |label| of length |labellen|; and |data| of length @@ -26,84 +32,72 @@ static const unsigned char default_zeros[EVP_MAX_MD_SIZE]; * |fatal| is set. Returns 1 on success 0 on failure. */ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, - const unsigned char *label, size_t labellen, - const unsigned char *data, size_t datalen, - unsigned char *out, size_t outlen, int fatal) + const unsigned char *label, size_t labellen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outlen, int fatal) { -#ifdef CHARSET_EBCDIC - static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 }; -#else - static const unsigned char label_prefix[] = "tls13 "; -#endif - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, + s->ctx->propq); + EVP_KDF_CTX *kctx; + OSSL_PARAM params[7], *p = params; + int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY; + const char *mdname = EVP_MD_get0_name(md); int ret; - size_t hkdflabellen; size_t hashlen; - /* - * 2 bytes for length of derived secret + 1 byte for length of combined - * prefix and label + bytes for the label itself + 1 byte length of hash - * + bytes for the hash itself - */ - unsigned char hkdflabel[sizeof(uint16_t) + sizeof(uint8_t) - + (sizeof(label_prefix) - 1) + TLS13_MAX_LABEL_LEN - + 1 + EVP_MAX_MD_SIZE]; - WPACKET pkt; - if (pctx == NULL) + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) return 0; if (labellen > TLS13_MAX_LABEL_LEN) { if (fatal) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); } else { /* * Probably we have been called from SSL_export_keying_material(), * or SSL_export_keying_material_early(). */ - SSLerr(SSL_F_TLS13_HKDF_EXPAND, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); + ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); } - EVP_PKEY_CTX_free(pctx); + EVP_KDF_CTX_free(kctx); return 0; } - hashlen = EVP_MD_size(md); - - if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0) - || !WPACKET_put_bytes_u16(&pkt, outlen) - || !WPACKET_start_sub_packet_u8(&pkt) - || !WPACKET_memcpy(&pkt, label_prefix, sizeof(label_prefix) - 1) - || !WPACKET_memcpy(&pkt, label, labellen) - || !WPACKET_close(&pkt) - || !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen) - || !WPACKET_get_total_written(&pkt, &hkdflabellen) - || !WPACKET_finish(&pkt)) { - EVP_PKEY_CTX_free(pctx); - WPACKET_cleanup(&pkt); + if ((ret = EVP_MD_get_size(md)) <= 0) { + EVP_KDF_CTX_free(kctx); if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); else - SSLerr(SSL_F_TLS13_HKDF_EXPAND, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } - - ret = EVP_PKEY_derive_init(pctx) <= 0 - || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) - <= 0 - || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0 - || EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, hashlen) <= 0 - || EVP_PKEY_CTX_add1_hkdf_info(pctx, hkdflabel, hkdflabellen) <= 0 - || EVP_PKEY_derive(pctx, out, &outlen) <= 0; - - EVP_PKEY_CTX_free(pctx); + hashlen = (size_t)ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)secret, hashlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, + (unsigned char *)label_prefix, + sizeof(label_prefix) - 1); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL, + (unsigned char *)label, labellen); + if (data != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA, + (unsigned char *)data, + datalen); + *p++ = OSSL_PARAM_construct_end(); + + ret = EVP_KDF_derive(kctx, out, outlen, params) <= 0; + EVP_KDF_CTX_free(kctx); if (ret != 0) { if (fatal) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); else - SSLerr(SSL_F_TLS13_HKDF_EXPAND, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); } return ret == 0; @@ -168,87 +162,61 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, size_t insecretlen, unsigned char *outsecret) { - size_t mdlen, prevsecretlen; + size_t mdlen; int mdleni; int ret; - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + EVP_KDF *kdf; + EVP_KDF_CTX *kctx; + OSSL_PARAM params[7], *p = params; + int mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY; + const char *mdname = EVP_MD_get0_name(md); #ifdef CHARSET_EBCDIC static const char derived_secret_label[] = { 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x00 }; #else static const char derived_secret_label[] = "derived"; #endif - unsigned char preextractsec[EVP_MAX_MD_SIZE]; - if (pctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, - ERR_R_INTERNAL_ERROR); + kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, s->ctx->propq); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - mdleni = EVP_MD_size(md); + mdleni = EVP_MD_get_size(md); /* Ensure cast to size_t is safe */ if (!ossl_assert(mdleni >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, - ERR_R_INTERNAL_ERROR); - EVP_PKEY_CTX_free(pctx); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_KDF_CTX_free(kctx); return 0; } mdlen = (size_t)mdleni; - if (insecret == NULL) { - insecret = default_zeros; - insecretlen = mdlen; - } - if (prevsecret == NULL) { - prevsecret = default_zeros; - prevsecretlen = 0; - } else { - EVP_MD_CTX *mctx = EVP_MD_CTX_new(); - unsigned char hash[EVP_MAX_MD_SIZE]; - - /* The pre-extract derive step uses a hash of no messages */ - if (mctx == NULL - || EVP_DigestInit_ex(mctx, md, NULL) <= 0 - || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, - ERR_R_INTERNAL_ERROR); - EVP_MD_CTX_free(mctx); - EVP_PKEY_CTX_free(pctx); - return 0; - } - EVP_MD_CTX_free(mctx); - - /* Generate the pre-extract secret */ - if (!tls13_hkdf_expand(s, md, prevsecret, - (unsigned char *)derived_secret_label, - sizeof(derived_secret_label) - 1, hash, mdlen, - preextractsec, mdlen, 1)) { - /* SSLfatal() already called */ - EVP_PKEY_CTX_free(pctx); - return 0; - } - - prevsecret = preextractsec; - prevsecretlen = mdlen; - } - - ret = EVP_PKEY_derive_init(pctx) <= 0 - || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) - <= 0 - || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0 - || EVP_PKEY_CTX_set1_hkdf_key(pctx, insecret, insecretlen) <= 0 - || EVP_PKEY_CTX_set1_hkdf_salt(pctx, prevsecret, prevsecretlen) - <= 0 - || EVP_PKEY_derive(pctx, outsecret, &mdlen) - <= 0; + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + if (insecret != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)insecret, + insecretlen); + if (prevsecret != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (unsigned char *)prevsecret, mdlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, + (unsigned char *)label_prefix, + sizeof(label_prefix) - 1); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL, + (unsigned char *)derived_secret_label, + sizeof(derived_secret_label) - 1); + *p++ = OSSL_PARAM_construct_end(); + + ret = EVP_KDF_derive(kctx, outsecret, mdlen, params) <= 0; if (ret != 0) - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - EVP_PKEY_CTX_free(pctx); - if (prevsecret == preextractsec) - OPENSSL_cleanse(preextractsec, mdlen); + EVP_KDF_CTX_free(kctx); return ret == 0; } @@ -277,7 +245,7 @@ int tls13_generate_master_secret(SSL *s, unsigned char *out, { const EVP_MD *md = ssl_handshake_md(s); - *secret_size = EVP_MD_size(md); + *secret_size = EVP_MD_get_size(md); /* Calls SSLfatal() if required */ return tls13_generate_secret(s, md, prev, NULL, 0, out); } @@ -290,10 +258,22 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, unsigned char *out) { const EVP_MD *md = ssl_handshake_md(s); + const char *mdname = EVP_MD_get0_name(md); unsigned char hash[EVP_MAX_MD_SIZE]; - size_t hashlen, ret = 0; - EVP_PKEY *key = NULL; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + unsigned char finsecret[EVP_MAX_MD_SIZE]; + unsigned char *key = NULL; + size_t len = 0, hashlen; + OSSL_PARAM params[2], *p = params; + + if (md == NULL) + return 0; + + /* Safe to cast away const here since we're not "getting" any data */ + if (s->ctx->propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES, + (char *)s->ctx->propq, + 0); + *p = OSSL_PARAM_construct_end(); if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { /* SSLfatal() already called */ @@ -301,39 +281,28 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen, } if (str == s->method->ssl3_enc->server_finished_label) { - key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, - s->server_finished_secret, hashlen); + key = s->server_finished_secret; } else if (SSL_IS_FIRST_HANDSHAKE(s)) { - key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, - s->client_finished_secret, hashlen); + key = s->client_finished_secret; } else { - unsigned char finsecret[EVP_MAX_MD_SIZE]; - - if (!tls13_derive_finishedkey(s, ssl_handshake_md(s), + if (!tls13_derive_finishedkey(s, md, s->client_app_traffic_secret, finsecret, hashlen)) goto err; - - key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret, - hashlen); - OPENSSL_cleanse(finsecret, sizeof(finsecret)); + key = finsecret; } - if (key == NULL - || ctx == NULL - || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0 - || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0 - || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC, - ERR_R_INTERNAL_ERROR); + if (!EVP_Q_mac(s->ctx->libctx, "HMAC", s->ctx->propq, mdname, + params, key, hashlen, hash, hashlen, + /* outsize as per sizeof(peer_finish_md) */ + out, EVP_MAX_MD_SIZE * 2, &len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - ret = hashlen; err: - EVP_PKEY_free(key); - EVP_MD_CTX_free(ctx); - return ret; + OPENSSL_cleanse(finsecret, sizeof(finsecret)); + return len; } /* @@ -345,15 +314,18 @@ int tls13_setup_key_block(SSL *s) const EVP_CIPHER *c; const EVP_MD *hash; - s->session->cipher = s->s3->tmp.new_cipher; - if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, NULL, 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_SETUP_KEY_BLOCK, - SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + s->session->cipher = s->s3.tmp.new_cipher; + if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, NULL, + 0)) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; } - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; + ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); + s->s3.tmp.new_sym_enc = c; + ssl_evp_md_free(s->s3.tmp.new_hash); + s->s3.tmp.new_hash = hash; return 1; } @@ -364,35 +336,33 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, const unsigned char *hash, const unsigned char *label, size_t labellen, unsigned char *secret, - unsigned char *iv, EVP_CIPHER_CTX *ciph_ctx) + unsigned char *key, unsigned char *iv, + EVP_CIPHER_CTX *ciph_ctx) { - unsigned char key[EVP_MAX_KEY_LENGTH]; size_t ivlen, keylen, taglen; - int hashleni = EVP_MD_size(md); + int hashleni = EVP_MD_get_size(md); size_t hashlen; /* Ensure cast to size_t is safe */ if (!ossl_assert(hashleni >= 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, - ERR_R_EVP_LIB); - goto err; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; } hashlen = (size_t)hashleni; if (!tls13_hkdf_expand(s, md, insecret, label, labellen, hash, hashlen, secret, hashlen, 1)) { /* SSLfatal() already called */ - goto err; + return 0; } - /* TODO(size_t): convert me */ - keylen = EVP_CIPHER_key_length(ciph); - if (EVP_CIPHER_mode(ciph) == EVP_CIPH_CCM_MODE) { + keylen = EVP_CIPHER_get_key_length(ciph); + if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) { uint32_t algenc; ivlen = EVP_CCM_TLS_IV_LEN; - if (s->s3->tmp.new_cipher != NULL) { - algenc = s->s3->tmp.new_cipher->algorithm_enc; + if (s->s3.tmp.new_cipher != NULL) { + algenc = s->s3.tmp.new_cipher->algorithm_enc; } else if (s->session->cipher != NULL) { /* We've not selected a cipher yet - we must be doing early data */ algenc = s->session->cipher->algorithm_enc; @@ -400,39 +370,34 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, /* We must be doing early data with out-of-band PSK */ algenc = s->psksession->cipher->algorithm_enc; } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, - ERR_R_EVP_LIB); - goto err; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; } if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) taglen = EVP_CCM8_TLS_TAG_LEN; else taglen = EVP_CCM_TLS_TAG_LEN; } else { - ivlen = EVP_CIPHER_iv_length(ciph); + ivlen = EVP_CIPHER_get_iv_length(ciph); taglen = 0; } if (!tls13_derive_key(s, md, secret, key, keylen) || !tls13_derive_iv(s, md, secret, iv, ivlen)) { /* SSLfatal() already called */ - goto err; + return 0; } if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0 - || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) - || (taglen != 0 && !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, - taglen, NULL)) + || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0 + || (taglen != 0 && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, + taglen, NULL) <= 0) || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, - ERR_R_EVP_LIB); - goto err; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; } return 1; - err: - OPENSSL_cleanse(key, sizeof(key)); - return 0; } int tls13_change_cipher_state(SSL *s, int which) @@ -457,6 +422,7 @@ int tls13_change_cipher_state(SSL *s, int which) static const unsigned char early_exporter_master_secret[] = "e exp master"; #endif unsigned char *iv; + unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; unsigned char *hash = hashval; @@ -470,6 +436,10 @@ int tls13_change_cipher_state(SSL *s, int which) int ret = 0; const EVP_MD *md = NULL; const EVP_CIPHER *cipher = NULL; +#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) + ktls_crypto_info_t crypto_info; + BIO *bio; +#endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) { @@ -477,8 +447,7 @@ int tls13_change_cipher_state(SSL *s, int which) } else { s->enc_read_ctx = EVP_CIPHER_CTX_new(); if (s->enc_read_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } } @@ -493,8 +462,7 @@ int tls13_change_cipher_state(SSL *s, int which) } else { s->enc_write_ctx = EVP_CIPHER_CTX_new(); if (s->enc_write_ctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } } @@ -518,11 +486,9 @@ int tls13_change_cipher_state(SSL *s, int which) labellen = sizeof(client_early_traffic) - 1; log_label = CLIENT_EARLY_LABEL; - handlen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + handlen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata); if (handlen <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, - SSL_R_BAD_HANDSHAKE_LENGTH); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH); goto err; } @@ -537,16 +503,13 @@ int tls13_change_cipher_state(SSL *s, int which) if (!ossl_assert(s->psksession != NULL && s->max_early_data == s->psksession->ext.max_early_data)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } sslcipher = SSL_SESSION_get0_cipher(s->psksession); } if (sslcipher == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, SSL_R_BAD_PSK); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); goto err; } @@ -557,17 +520,26 @@ int tls13_change_cipher_state(SSL *s, int which) */ mdctx = EVP_MD_CTX_new(); if (mdctx == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This ups the ref count on cipher so we better make sure we free + * it again + */ + if (!ssl_cipher_get_evp_cipher(s->ctx, sslcipher, &cipher)) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); + EVP_MD_CTX_free(mdctx); goto err; } - cipher = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(sslcipher)); - md = ssl_md(sslcipher->algorithm2); + + md = ssl_md(s->ctx, sslcipher->algorithm2); if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL) || !EVP_DigestUpdate(mdctx, hdata, handlen) || !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); EVP_MD_CTX_free(mdctx); goto err; } @@ -580,8 +552,7 @@ int tls13_change_cipher_state(SSL *s, int which) hashval, hashlen, s->early_exporter_master_secret, hashlen, 1)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -593,7 +564,7 @@ int tls13_change_cipher_state(SSL *s, int which) } else if (which & SSL3_CC_HANDSHAKE) { insecret = s->handshake_secret; finsecret = s->client_finished_secret; - finsecretlen = EVP_MD_size(ssl_handshake_md(s)); + finsecretlen = EVP_MD_get_size(ssl_handshake_md(s)); label = client_handshake_traffic; labellen = sizeof(client_handshake_traffic) - 1; log_label = CLIENT_HANDSHAKE_LABEL; @@ -625,7 +596,7 @@ int tls13_change_cipher_state(SSL *s, int which) if (which & SSL3_CC_HANDSHAKE) { insecret = s->handshake_secret; finsecret = s->server_finished_secret; - finsecretlen = EVP_MD_size(ssl_handshake_md(s)); + finsecretlen = EVP_MD_get_size(ssl_handshake_md(s)); label = server_handshake_traffic; labellen = sizeof(server_handshake_traffic) - 1; log_label = SERVER_HANDSHAKE_LABEL; @@ -639,7 +610,7 @@ int tls13_change_cipher_state(SSL *s, int which) if (!(which & SSL3_CC_EARLY)) { md = ssl_handshake_md(s); - cipher = s->s3->tmp.new_sym_enc; + cipher = s->s3.tmp.new_sym_enc; if (!ssl3_digest_cached_records(s, 1) || !ssl_handshake_hash(s, hashval, sizeof(hashval), &hashlen)) { /* SSLfatal() already called */; @@ -672,9 +643,13 @@ int tls13_change_cipher_state(SSL *s, int which) } } + /* check whether cipher is known */ + if(!ossl_assert(cipher != NULL)) + goto err; + if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, - insecret, hash, label, labellen, secret, iv, - ciph_ctx)) { + insecret, hash, label, labellen, secret, key, + iv, ciph_ctx)) { /* SSLfatal() already called */ goto err; } @@ -715,8 +690,55 @@ int tls13_change_cipher_state(SSL *s, int which) s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; else s->statem.enc_write_state = ENC_WRITE_STATE_VALID; +#ifndef OPENSSL_NO_KTLS +# if defined(OPENSSL_KTLS_TLS13) + if (!(which & SSL3_CC_WRITE) + || !(which & SSL3_CC_APPLICATION) + || (s->options & SSL_OP_ENABLE_KTLS) == 0) + goto skip_ktls; + + /* ktls supports only the maximum fragment size */ + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) + goto skip_ktls; + + /* ktls does not support record padding */ + if (s->record_padding_cb != NULL) + goto skip_ktls; + + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) + goto skip_ktls; + + bio = s->wbio; + + if (!ossl_assert(bio != NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ + if (BIO_flush(bio) <= 0) + goto skip_ktls; + + /* configure kernel crypto structure */ + if (!ktls_configure_crypto(s, cipher, ciph_ctx, + RECORD_LAYER_get_write_sequence(&s->rlayer), + &crypto_info, NULL, iv, key, NULL, 0)) + goto skip_ktls; + + /* ktls works with user provided buffers directly */ + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) + ssl3_release_write_buffer(s); +skip_ktls: +# endif +#endif ret = 1; err: + if ((which & SSL3_CC_EARLY) != 0) { + /* We up-refed this so now we need to down ref */ + ssl_evp_cipher_free(cipher); + } + OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); return ret; } @@ -729,11 +751,19 @@ int tls13_update_key(SSL *s, int sending) static const unsigned char application_traffic[] = "traffic upd"; #endif const EVP_MD *md = ssl_handshake_md(s); - size_t hashlen = EVP_MD_size(md); + size_t hashlen; + unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char *insecret, *iv; unsigned char secret[EVP_MAX_MD_SIZE]; + char *log_label; EVP_CIPHER_CTX *ciph_ctx; - int ret = 0; + int ret = 0, l; + + if ((l = EVP_MD_get_size(md)) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + hashlen = (size_t)l; if (s->server == sending) insecret = s->server_app_traffic_secret; @@ -751,20 +781,28 @@ int tls13_update_key(SSL *s, int sending) RECORD_LAYER_reset_read_sequence(&s->rlayer); } - if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s), - s->s3->tmp.new_sym_enc, insecret, NULL, + if (!derive_secret_key_and_iv(s, sending, md, + s->s3.tmp.new_sym_enc, insecret, NULL, application_traffic, - sizeof(application_traffic) - 1, secret, iv, - ciph_ctx)) { + sizeof(application_traffic) - 1, secret, key, + iv, ciph_ctx)) { /* SSLfatal() already called */ goto err; } memcpy(insecret, secret, hashlen); + /* Call Key log on successful traffic secret update */ + log_label = s->server == sending ? SERVER_APPLICATION_N_LABEL : CLIENT_APPLICATION_N_LABEL; + if (!ssl_log_secret(s, log_label, secret, hashlen)) { + /* SSLfatal() already called */ + goto err; + } + s->statem.enc_write_state = ENC_WRITE_STATE_VALID; ret = 1; err: + OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); return ret; } @@ -795,7 +833,7 @@ int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen, unsigned int hashsize, datalen; int ret = 0; - if (ctx == NULL || !ossl_statem_export_allowed(s)) + if (ctx == NULL || md == NULL || !ossl_statem_export_allowed(s)) goto err; if (!use_context) @@ -847,7 +885,7 @@ int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, else sslcipher = SSL_SESSION_get0_cipher(s->session); - md = ssl_md(sslcipher->algorithm2); + md = ssl_md(s->ctx, sslcipher->algorithm2); /* * Calculate the hash value and store it in |data|. The reason why @@ -864,7 +902,8 @@ int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, * * Here Transcript-Hash is the cipher suite hash algorithm. */ - if (EVP_DigestInit_ex(ctx, md, NULL) <= 0 + if (md == NULL + || EVP_DigestInit_ex(ctx, md, NULL) <= 0 || EVP_DigestUpdate(ctx, context, contextlen) <= 0 || EVP_DigestFinal_ex(ctx, hash, &hashsize) <= 0 || EVP_DigestInit_ex(ctx, md, NULL) <= 0 diff --git a/ssl/tls_depr.c b/ssl/tls_depr.c new file mode 100644 index 000000000000..1761ba1d8ef1 --- /dev/null +++ b/ssl/tls_depr.c @@ -0,0 +1,207 @@ +/* + * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * + * 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 + */ + +/* We need to use some engine and HMAC deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include <openssl/engine.h> +#include "ssl_local.h" + +/* + * Engine APIs are only used to support applications that still use ENGINEs. + * Once ENGINE is removed completely, all of this code can also be removed. + */ + +#ifndef OPENSSL_NO_ENGINE +void tls_engine_finish(ENGINE *e) +{ + ENGINE_finish(e); +} +#endif + +const EVP_CIPHER *tls_get_cipher_from_engine(int nid) +{ + const EVP_CIPHER *ret = NULL; +#ifndef OPENSSL_NO_ENGINE + ENGINE *eng; + + /* + * If there is an Engine available for this cipher we use the "implicit" + * form to ensure we use that engine later. + */ + eng = ENGINE_get_cipher_engine(nid); + if (eng != NULL) { + ret = ENGINE_get_cipher(eng, nid); + ENGINE_finish(eng); + } +#endif + return ret; +} + +const EVP_MD *tls_get_digest_from_engine(int nid) +{ + const EVP_MD *ret = NULL; +#ifndef OPENSSL_NO_ENGINE + ENGINE *eng; + + /* + * If there is an Engine available for this digest we use the "implicit" + * form to ensure we use that engine later. + */ + eng = ENGINE_get_digest_engine(nid); + if (eng != NULL) { + ret = ENGINE_get_digest(eng, nid); + ENGINE_finish(eng); + } +#endif + return ret; +} + +#ifndef OPENSSL_NO_ENGINE +int tls_engine_load_ssl_client_cert(SSL *s, X509 **px509, EVP_PKEY **ppkey) +{ + return ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, + SSL_get_client_CA_list(s), + px509, ppkey, NULL, NULL, NULL); +} +#endif + +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) +{ + if (!ENGINE_init(e)) { + ERR_raise(ERR_LIB_SSL, ERR_R_ENGINE_LIB); + return 0; + } + if (!ENGINE_get_ssl_client_cert_function(e)) { + ERR_raise(ERR_LIB_SSL, SSL_R_NO_CLIENT_CERT_METHOD); + ENGINE_finish(e); + return 0; + } + ctx->client_cert_engine = e; + return 1; +} +#endif + +/* + * The HMAC APIs below are only used to support the deprecated public API + * macro SSL_CTX_set_tlsext_ticket_key_cb(). The application supplied callback + * takes an HMAC_CTX in its argument list. The preferred alternative is + * SSL_CTX_set_tlsext_ticket_key_evp_cb(). Once + * SSL_CTX_set_tlsext_ticket_key_cb() is removed, then all of this code can also + * be removed. + */ +#ifndef OPENSSL_NO_DEPRECATED_3_0 +int ssl_hmac_old_new(SSL_HMAC *ret) +{ + ret->old_ctx = HMAC_CTX_new(); + if (ret->old_ctx == NULL) + return 0; + + return 1; +} + +void ssl_hmac_old_free(SSL_HMAC *ctx) +{ + HMAC_CTX_free(ctx->old_ctx); +} + +int ssl_hmac_old_init(SSL_HMAC *ctx, void *key, size_t len, char *md) +{ + return HMAC_Init_ex(ctx->old_ctx, key, len, EVP_get_digestbyname(md), NULL); +} + +int ssl_hmac_old_update(SSL_HMAC *ctx, const unsigned char *data, size_t len) +{ + return HMAC_Update(ctx->old_ctx, data, len); +} + +int ssl_hmac_old_final(SSL_HMAC *ctx, unsigned char *md, size_t *len) +{ + unsigned int l; + + if (HMAC_Final(ctx->old_ctx, md, &l) > 0) { + if (len != NULL) + *len = l; + return 1; + } + + return 0; +} + +size_t ssl_hmac_old_size(const SSL_HMAC *ctx) +{ + return HMAC_size(ctx->old_ctx); +} + +HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx) +{ + return ctx->old_ctx; +} + +/* Some deprecated public APIs pass DH objects */ +EVP_PKEY *ssl_dh_to_pkey(DH *dh) +{ +# ifndef OPENSSL_NO_DH + EVP_PKEY *ret; + + if (dh == NULL) + return NULL; + ret = EVP_PKEY_new(); + if (EVP_PKEY_set1_DH(ret, dh) <= 0) { + EVP_PKEY_free(ret); + return NULL; + } + return ret; +# else + return NULL; +# endif +} + +/* Some deprecated public APIs pass EC_KEY objects */ +int ssl_set_tmp_ecdh_groups(uint16_t **pext, size_t *pextlen, + void *key) +{ +# ifndef OPENSSL_NO_EC + const EC_GROUP *group = EC_KEY_get0_group((const EC_KEY *)key); + int nid; + + if (group == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS); + return 0; + } + nid = EC_GROUP_get_curve_name(group); + if (nid == NID_undef) + return 0; + return tls1_set_groups(pext, pextlen, &nid, 1); +# else + return 0; +# endif +} + +/* + * Set the callback for generating temporary DH keys. + * ctx: the SSL context. + * dh: the callback + */ +# if !defined(OPENSSL_NO_DH) +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); +} + +void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); +} +# endif +#endif /* OPENSSL_NO_DEPRECATED */ diff --git a/ssl/tls_srp.c b/ssl/tls_srp.c index ede7427ff89d..872d1b66f8af 100644 --- a/ssl/tls_srp.c +++ b/ssl/tls_srp.c @@ -1,8 +1,8 @@ /* - * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. 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 @@ -11,6 +11,12 @@ * for the EdelKey project. */ +/* + * We need to use the SRP deprecated APIs in order to implement the SSL SRP + * APIs - which are themselves deprecated. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include <openssl/crypto.h> #include <openssl/rand.h> #include <openssl/err.h> @@ -19,7 +25,11 @@ #ifndef OPENSSL_NO_SRP # include <openssl/srp.h> -int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) +/* + * The public API SSL_CTX_SRP_CTX_free() is deprecated so we use + * ssl_ctx_srp_ctx_free_intern() internally. + */ +int ssl_ctx_srp_ctx_free_intern(SSL_CTX *ctx) { if (ctx == NULL) return 0; @@ -38,7 +48,16 @@ int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) return 1; } -int SSL_SRP_CTX_free(struct ssl_st *s) +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx) +{ + return ssl_ctx_srp_ctx_free_intern(ctx); +} + +/* + * The public API SSL_SRP_CTX_free() is deprecated so we use + * ssl_srp_ctx_free_intern() internally. + */ +int ssl_srp_ctx_free_intern(SSL *s) { if (s == NULL) return 0; @@ -57,7 +76,16 @@ int SSL_SRP_CTX_free(struct ssl_st *s) return 1; } -int SSL_SRP_CTX_init(struct ssl_st *s) +int SSL_SRP_CTX_free(SSL *s) +{ + return ssl_srp_ctx_free_intern(s); +} + +/* + * The public API SSL_SRP_CTX_init() is deprecated so we use + * ssl_srp_ctx_init_intern() internally. + */ +int ssl_srp_ctx_init_intern(SSL *s) { SSL_CTX *ctx; @@ -95,17 +123,17 @@ int SSL_SRP_CTX_init(struct ssl_st *s) ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || ((ctx->srp_ctx.b != NULL) && ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); + ERR_raise(ERR_LIB_SSL, ERR_R_BN_LIB); goto err; } if ((ctx->srp_ctx.login != NULL) && ((s->srp_ctx.login = OPENSSL_strdup(ctx->srp_ctx.login)) == NULL)) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); goto err; } if ((ctx->srp_ctx.info != NULL) && - ((s->srp_ctx.info = BUF_strdup(ctx->srp_ctx.info)) == NULL)) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); + ((s->srp_ctx.info = OPENSSL_strdup(ctx->srp_ctx.info)) == NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); goto err; } s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; @@ -126,7 +154,16 @@ int SSL_SRP_CTX_init(struct ssl_st *s) return 0; } -int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) +int SSL_SRP_CTX_init(SSL *s) +{ + return ssl_srp_ctx_init_intern(s); +} + +/* + * The public API SSL_CTX_SRP_CTX_init() is deprecated so we use + * ssl_ctx_srp_ctx_init_intern() internally. + */ +int ssl_ctx_srp_ctx_init_intern(SSL_CTX *ctx) { if (ctx == NULL) return 0; @@ -137,8 +174,17 @@ int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) return 1; } +int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx) +{ + return ssl_ctx_srp_ctx_init_intern(ctx); +} + /* server side */ -int SSL_srp_server_param_with_username(SSL *s, int *ad) +/* + * The public API SSL_srp_server_param_with_username() is deprecated so we use + * ssl_srp_server_param_with_username_intern() internally. + */ +int ssl_srp_server_param_with_username_intern(SSL *s, int *ad) { unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; int al; @@ -157,7 +203,7 @@ int SSL_srp_server_param_with_username(SSL *s, int *ad) (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) return SSL3_AL_FATAL; - if (RAND_priv_bytes(b, sizeof(b)) <= 0) + if (RAND_priv_bytes_ex(s->ctx->libctx, b, sizeof(b), 0) <= 0) return SSL3_AL_FATAL; s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); OPENSSL_cleanse(b, sizeof(b)); @@ -165,11 +211,16 @@ int SSL_srp_server_param_with_username(SSL *s, int *ad) /* Calculate: B = (kv + g^b) % N */ return ((s->srp_ctx.B = - SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, - s->srp_ctx.v)) != + SRP_Calc_B_ex(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, + s->srp_ctx.v, s->ctx->libctx, s->ctx->propq)) != NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; } +int SSL_srp_server_param_with_username(SSL *s, int *ad) +{ + return ssl_srp_server_param_with_username_intern(s, ad); +} + /* * If the server just has the raw password, make up a verifier entry on the * fly @@ -186,8 +237,9 @@ int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, s->srp_ctx.v = NULL; BN_clear_free(s->srp_ctx.s); s->srp_ctx.s = NULL; - if (!SRP_create_verifier_BN - (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) + if (!SRP_create_verifier_BN_ex(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, + s->srp_ctx.N, s->srp_ctx.g, s->ctx->libctx, + s->ctx->propq)) return -1; return 1; @@ -235,7 +287,7 @@ int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, if (info != NULL) { if (s->srp_ctx.info) OPENSSL_free(s->srp_ctx.info); - if ((s->srp_ctx.info = BUF_strdup(info)) == NULL) + if ((s->srp_ctx.info = OPENSSL_strdup(info)) == NULL) return -1; } @@ -249,12 +301,13 @@ int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, int srp_generate_server_master_secret(SSL *s) { BIGNUM *K = NULL, *u = NULL; - int ret = -1, tmp_len = 0; + int ret = 0, tmp_len = 0; unsigned char *tmp = NULL; if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) goto err; - if ((u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)) == NULL) + if ((u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N, + s->ctx->libctx, s->ctx->propq)) == NULL) goto err; if ((K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)) == NULL) @@ -262,8 +315,7 @@ int srp_generate_server_master_secret(SSL *s) tmp_len = BN_num_bytes(K); if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } BN_bn2bin(K, tmp); @@ -279,7 +331,7 @@ int srp_generate_server_master_secret(SSL *s) int srp_generate_client_master_secret(SSL *s) { BIGNUM *x = NULL, *u = NULL, *K = NULL; - int ret = -1, tmp_len = 0; + int ret = 0, tmp_len = 0; char *passwd = NULL; unsigned char *tmp = NULL; @@ -287,34 +339,33 @@ int srp_generate_client_master_secret(SSL *s) * Checks if b % n == 0 */ if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0 - || (u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)) + || (u = SRP_Calc_u_ex(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N, + s->ctx->libctx, s->ctx->propq)) == NULL || s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } if ((passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET, - SSL_R_CALLBACK_FAILED); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_CALLBACK_FAILED); goto err; } - if ((x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd)) == NULL - || (K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, - s->srp_ctx.g, x, - s->srp_ctx.a, u)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET, ERR_R_INTERNAL_ERROR); + if ((x = SRP_Calc_x_ex(s->srp_ctx.s, s->srp_ctx.login, passwd, + s->ctx->libctx, s->ctx->propq)) == NULL + || (K = SRP_Calc_client_key_ex(s->srp_ctx.N, s->srp_ctx.B, + s->srp_ctx.g, x, + s->srp_ctx.a, u, + s->ctx->libctx, + s->ctx->propq)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } tmp_len = BN_num_bytes(K); if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } BN_bn2bin(K, tmp); @@ -338,26 +389,22 @@ int srp_verify_server_param(SSL *s) */ if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 || BN_is_zero(srp->B)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SRP_VERIFY_SERVER_PARAM, - SSL_R_BAD_DATA); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DATA); return 0; } if (BN_num_bits(srp->N) < srp->strength) { - SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_F_SRP_VERIFY_SERVER_PARAM, - SSL_R_INSUFFICIENT_SECURITY); + SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_INSUFFICIENT_SECURITY); return 0; } if (srp->SRP_verify_param_callback) { if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { - SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, - SSL_F_SRP_VERIFY_SERVER_PARAM, - SSL_R_CALLBACK_FAILED); + SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_CALLBACK_FAILED); return 0; } } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { - SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_F_SRP_VERIFY_SERVER_PARAM, + SSLfatal(s, SSL_AD_INSUFFICIENT_SECURITY, SSL_R_INSUFFICIENT_SECURITY); return 0; } @@ -365,11 +412,15 @@ int srp_verify_server_param(SSL *s) return 1; } -int SRP_Calc_A_param(SSL *s) +/* + * The public API SRP_Calc_A_param() is deprecated so we use + * ssl_srp_calc_a_param_intern() internally. + */ +int ssl_srp_calc_a_param_intern(SSL *s) { unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; - if (RAND_priv_bytes(rnd, sizeof(rnd)) <= 0) + if (RAND_priv_bytes_ex(s->ctx->libctx, rnd, sizeof(rnd), 0) <= 0) return 0; s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); OPENSSL_cleanse(rnd, sizeof(rnd)); @@ -380,6 +431,11 @@ int SRP_Calc_A_param(SSL *s) return 1; } +int SRP_Calc_A_param(SSL *s) +{ + return ssl_srp_calc_a_param_intern(s); +} + BIGNUM *SSL_get_srp_g(SSL *s) { if (s->srp_ctx.g != NULL) |