From e375cbd094f8040cbf96630f8e065a974090e4d6 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Tue, 21 Dec 2021 12:54:05 +0100 Subject: Bump mbedTLS version to 2.28.0 (new LTS). Keep applying the windows entropy patch (UWP support). Remove no longer needed padlock patch. Update thirdparty README to reflect changes, and new source inclusion criteria. --- thirdparty/mbedtls/library/ssl_srv.c | 949 ++++++++++++++++++++++++----------- 1 file changed, 664 insertions(+), 285 deletions(-) (limited to 'thirdparty/mbedtls/library/ssl_srv.c') diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c index cbf6142ac2..1a63173204 100644 --- a/thirdparty/mbedtls/library/ssl_srv.c +++ b/thirdparty/mbedtls/library/ssl_srv.c @@ -2,13 +2,7 @@ * SSLv3/TLSv1 server-side functions * * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - * - * This file is provided under the Apache License 2.0, or the - * GNU General Public License v2.0 or later. - * - * ********** - * Apache License 2.0: + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. @@ -21,34 +15,9 @@ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * - * ********** - * - * ********** - * GNU General Public License v2.0 or later: - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * ********** */ -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif +#include "common.h" #if defined(MBEDTLS_SSL_SRV_C) @@ -60,10 +29,13 @@ #define mbedtls_free free #endif -#include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" +#include "mbedtls/debug.h" +#include "mbedtls/error.h" #include "mbedtls/platform_util.h" +#include "constant_time_internal.h" +#include "mbedtls/constant_time.h" #include @@ -110,7 +82,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t servername_list_size, hostname_len; const unsigned char *p; @@ -174,6 +146,48 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) +static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf ) +{ + if( conf->f_psk != NULL ) + return( 1 ); + + if( conf->psk_identity_len == 0 || conf->psk_identity == NULL ) + return( 0 ); + + if( conf->psk != NULL && conf->psk_len != 0 ) + return( 1 ); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) ) + return( 1 ); +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + + return( 0 ); +} + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) +{ + if( ssl->conf->f_psk != NULL ) + { + /* If we've used a callback to select the PSK, + * the static configuration is irrelevant. */ + + if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) ) + return( 1 ); + + return( 0 ); + } + + if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) ) + return( 1 ); + + return( 0 ); +} +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ + static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -184,7 +198,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, /* Check verify-data in constant-time. The length OTOH is no secret */ if( len != 1 + ssl->verify_data_len || buf[0] != ssl->verify_data_len || - mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data, + mbedtls_ct_memcmp( buf + 1, ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); @@ -211,7 +225,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, } #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) /* * Status of the implementation of signature-algorithms extension: @@ -286,20 +300,20 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, { mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" - " match sig %d and hash %d", - sig_cur, md_cur ) ); + " match sig %u and hash %u", + (unsigned) sig_cur, (unsigned) md_cur ) ); } else { MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: " - "hash alg %d not supported", md_cur ) ); + "hash alg %u not supported", (unsigned) md_cur ) ); } } return( 0 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -415,7 +429,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) { @@ -458,6 +472,78 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t peer_cid_len; + + /* CID extension only makes sense in DTLS */ + if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Quoting draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * struct { + * opaque cid<0..2^8-1>; + * } ConnectionId; + */ + + if( len < 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + peer_cid_len = *buf++; + len--; + + if( len != peer_cid_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Ignore CID if the user has disabled its use. */ + if( ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) + { + /* Leave ssl->handshake->cid_in_use in its default + * value of MBEDTLS_SSL_CID_DISABLED. */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Client sent CID extension, but CID disabled" ) ); + return( 0 ); + } + + if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; + ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; + memcpy( ssl->handshake->peer_cid, buf, peer_cid_len ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "Client CID", buf, peer_cid_len ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, @@ -535,7 +621,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_ssl_session session; mbedtls_ssl_session_init( &session ); @@ -549,7 +635,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, /* Remember the client asked us to send a new ticket */ ssl->handshake->new_session_ticket = 1; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, len ) ); if( len == 0 ) return( 0 ); @@ -692,6 +778,126 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) +static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET; + size_t i,j; + size_t profile_length; + uint16_t mki_length; + /*! 2 bytes for profile length and 1 byte for mki len */ + const size_t size_of_lengths = 3; + + /* If use_srtp is not configured, just ignore the extension */ + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->conf->dtls_srtp_profile_list == NULL ) || + ( ssl->conf->dtls_srtp_profile_list_len == 0 ) ) + { + return( 0 ); + } + + /* RFC5764 section 4.1.1 + * uint8 SRTPProtectionProfile[2]; + * + * struct { + * SRTPProtectionProfiles SRTPProtectionProfiles; + * opaque srtp_mki<0..255>; + * } UseSRTPData; + + * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; + */ + + /* + * Min length is 5: at least one protection profile(2 bytes) + * and length(2 bytes) + srtp_mki length(1 byte) + * Check here that we have at least 2 bytes of protection profiles length + * and one of srtp_mki length + */ + if( len < size_of_lengths ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; + + /* first 2 bytes are protection profile length(in bytes) */ + profile_length = ( buf[0] << 8 ) | buf[1]; + buf += 2; + + /* The profile length cannot be bigger than input buffer size - lengths fields */ + if( profile_length > len - size_of_lengths || + profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */ + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + /* + * parse the extension list values are defined in + * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml + */ + for( j = 0; j < profile_length; j += 2 ) + { + uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1]; + client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value ); + + if( client_protection != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + client_protection ) ) ); + } + else + { + continue; + } + /* check if suggested profile is in our list */ + for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) + { + if( client_protection == ssl->conf->dtls_srtp_profile_list[i] ) + { + ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s", + mbedtls_ssl_get_srtp_profile_as_string( + client_protection ) ) ); + break; + } + } + if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET ) + break; + } + buf += profile_length; /* buf points to the mki length */ + mki_length = *buf; + buf++; + + if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH || + mki_length + profile_length + size_of_lengths != len ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Parse the mki only if present and mki is supported locally */ + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED && + mki_length > 0 ) + { + ssl->dtls_srtp_info.mki_len = mki_length; + + memcpy( ssl->dtls_srtp_info.mki_value, buf, mki_length ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "using mki", ssl->dtls_srtp_info.mki_value, + ssl->dtls_srtp_info.mki_len ); + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + /* * Auxiliary functions for ServerHello parsing and related actions */ @@ -750,6 +956,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, for( cur = list; cur != NULL; cur = cur->next ) { + flags = 0; MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", cur->cert ); @@ -831,7 +1038,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, const mbedtls_ssl_ciphersuite_t *suite_info; #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) mbedtls_pk_type_t sig_type; #endif @@ -842,7 +1049,8 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %#04x (%s)", + (unsigned int) suite_id, suite_info->name ) ); if( suite_info->min_minor_ver > ssl->minor_ver || suite_info->max_minor_ver < ssl->minor_ver ) @@ -888,13 +1096,11 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, } #endif -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) /* If the ciphersuite requires a pre-shared key and we don't * have one, skip it now rather than failing later */ if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && - ssl->conf->f_psk == NULL && - ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || - ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) + ssl_conf_has_psk_or_cb( ssl->conf ) == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) ); return( 0 ); @@ -902,7 +1108,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, #endif #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) /* If the ciphersuite requires signing, check whether * a suitable hash algorithm is present. */ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) @@ -912,13 +1118,13 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm " - "for signature algorithm %d", sig_type ) ); + "for signature algorithm %u", (unsigned) sig_type ) ); return( 0 ); } } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_X509_CRT_PARSE_C) /* @@ -1043,7 +1249,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) sess_len = ( buf[2] << 8 ) | buf[3]; chal_len = ( buf[4] << 8 ) | buf[5]; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %u, sess_len: %u, chal_len: %u", ciph_len, sess_len, chal_len ) ); /* @@ -1118,8 +1324,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) { if( p[0] == 0 && - p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && - p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) + MBEDTLS_GET_UINT16_BE(p, 1) != MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); @@ -1150,8 +1355,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) #endif { if( p[0] != 0 || - p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) + MBEDTLS_GET_UINT16_BE(p, 1) != ciphersuites[i] ) continue; got_common_suite = 1; @@ -1180,7 +1384,7 @@ have_ciphersuite_v2: MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; + ssl->handshake->ciphersuite_info = ciphersuite_info; /* * SSLv2 Client Hello relevant renegotiation security checks @@ -1228,10 +1432,10 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) * we need to fall back to the default values for allowed * signature-hash pairs. */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) int sig_hash_alg_ext_present = 0; #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); @@ -1265,7 +1469,7 @@ read_record_header: return( ssl_parse_client_hello_v2( ssl ) ); #endif - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); + MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_in_hdr_len( ssl ) ); /* * SSLv3/TLS Client Hello @@ -1354,7 +1558,7 @@ read_record_header: } if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) + mbedtls_ssl_in_hdr_len( ssl ) + msg_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); @@ -1363,7 +1567,7 @@ read_record_header: /* Done reading this record, get ready for the next one */ #if defined(MBEDTLS_SSL_PROTO_DTLS) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); + ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len( ssl ); else #endif ssl->in_left = 0; @@ -1425,7 +1629,7 @@ read_record_header: if( cli_msg_seq != ssl->handshake->in_msg_seq ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: " - "%d (expected %d)", cli_msg_seq, + "%u (expected %u)", cli_msg_seq, ssl->handshake->in_msg_seq ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1683,8 +1887,7 @@ read_record_header: ext_len = ( buf[ext_offset + 0] << 8 ) | ( buf[ext_offset + 1] ); - if( ( ext_len > 0 && ext_len < 4 ) || - msg_len != ext_offset + 2 + ext_len ) + if( msg_len != ext_offset + 2 + ext_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, @@ -1744,7 +1947,7 @@ read_record_header: break; #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) case MBEDTLS_TLS_EXT_SIG_ALG: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); @@ -1755,7 +1958,7 @@ read_record_header: sig_hash_alg_ext_present = 1; break; #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -1808,6 +2011,16 @@ read_record_header: break; #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + case MBEDTLS_TLS_EXT_CID: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) ); + + ret = ssl_parse_cid_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); @@ -1848,21 +2061,23 @@ read_record_header: break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_DTLS_SRTP) + case MBEDTLS_TLS_EXT_USE_SRTP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) ); + + ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + default: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", + MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %u (ignoring)", ext_id ) ); } ext_len -= 4 + ext_size; ext += 4 + ext_size; - - if( ext_len > 0 && ext_len < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } } #if defined(MBEDTLS_SSL_PROTO_SSL3) } @@ -1871,8 +2086,7 @@ read_record_header: #if defined(MBEDTLS_SSL_FALLBACK_SCSV) for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) { - if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && - p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) + if( MBEDTLS_GET_UINT16_BE( p, 0 ) == MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) ); @@ -1892,7 +2106,7 @@ read_record_header: #endif /* MBEDTLS_SSL_FALLBACK_SCSV */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) /* * Try to fall back to default hash SHA1 if the client @@ -1909,7 +2123,7 @@ read_record_header: } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && - MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ /* * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV @@ -1990,8 +2204,7 @@ read_record_header: for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) #endif { - if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) + if( MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i] ) continue; got_common_suite = 1; @@ -2024,7 +2237,7 @@ have_ciphersuite: MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); ssl->session_negotiate->ciphersuite = ciphersuites[i]; - ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; + ssl->handshake->ciphersuite_info = ciphersuite_info; ssl->state++; @@ -2036,7 +2249,7 @@ have_ciphersuite: /* Debugging-only output for testsuite */ #if defined(MBEDTLS_DEBUG_C) && \ defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info ); @@ -2050,7 +2263,7 @@ have_ciphersuite: else { MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm " - "%d - should not happen", sig_alg ) ); + "%u - should not happen", (unsigned) sig_alg ) ); } } #endif @@ -2075,8 +2288,8 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 ); + p += 2; *p++ = 0x00; *p++ = 0x00; @@ -2085,6 +2298,53 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + size_t ext_len; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + + *olen = 0; + + /* Skip writing the extension if we don't want to use it or if + * the client hasn't offered it. */ + if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED ) + return; + + /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX + * which is at most 255, so the increment cannot overflow. */ + if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) ); + + /* + * Quoting draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * struct { + * opaque cid<0..2^8-1>; + * } ConnectionId; + */ + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 ); + p += 2; + ext_len = (size_t) ssl->own_cid_len + 1; + MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 ); + p += 2; + + *p++ = (uint8_t) ssl->own_cid_len; + memcpy( p, ssl->own_cid, ssl->own_cid_len ); + + *olen = ssl->own_cid_len + 5; +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, @@ -2118,8 +2378,8 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 ); + p += 2; *p++ = 0x00; *p++ = 0x00; @@ -2145,8 +2405,8 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret " "extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 ); + p += 2; *p++ = 0x00; *p++ = 0x00; @@ -2170,8 +2430,8 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 ); + p += 2; *p++ = 0x00; *p++ = 0x00; @@ -2194,8 +2454,8 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 ); + p += 2; #if defined(MBEDTLS_SSL_RENEGOTIATION) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) @@ -2235,8 +2495,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 ); + p += 2; *p++ = 0x00; *p++ = 1; @@ -2265,8 +2525,8 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 ); + p += 2; *p++ = 0x00; *p++ = 2; @@ -2283,7 +2543,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *p = buf; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t kkpp_len; @@ -2291,7 +2551,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, *olen = 0; /* Skip costly computation if not needed */ - if( ssl->transform_negotiate->ciphersuite_info->key_exchange != + if( ssl->handshake->ciphersuite_info->key_exchange != MBEDTLS_KEY_EXCHANGE_ECJPAKE ) return; @@ -2303,8 +2563,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, return; } - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 ); + p += 2; ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, p + 2, end - p - 2, &kkpp_len, @@ -2315,8 +2575,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, return; } - *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 ); + p += 2; *olen = kkpp_len + 4; } @@ -2341,27 +2601,93 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, * 6 . 6 protocol name length * 7 . 7+n protocol name */ - buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); - buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, buf, 0); *olen = 7 + strlen( ssl->alpn_chosen ); - buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); - buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 ); - buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); - buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 ); - buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); + buf[6] = MBEDTLS_BYTE_0( *olen - 7 ); memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); } #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS) +static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + size_t mki_len = 0, ext_len = 0; + uint16_t profile_value = 0; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + + *olen = 0; + + if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) || + ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) ); + + if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED ) + { + mki_len = ssl->dtls_srtp_info.mki_len; + } + + /* The extension total size is 9 bytes : + * - 2 bytes for the extension tag + * - 2 bytes for the total size + * - 2 bytes for the protection profile length + * - 2 bytes for the protection profile + * - 1 byte for the mki length + * + the actual mki length + * Check we have enough room in the output buffer */ + if( (size_t)( end - buf ) < mki_len + 9 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* extension */ + MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0 ); + /* + * total length 5 and mki value: only one profile(2 bytes) + * and length(2 bytes) and srtp_mki ) + */ + ext_len = 5 + mki_len; + MBEDTLS_PUT_UINT16_BE( ext_len, buf, 2 ); + + /* protection profile length: 2 */ + buf[4] = 0x00; + buf[5] = 0x02; + profile_value = mbedtls_ssl_check_srtp_profile_value( + ssl->dtls_srtp_info.chosen_dtls_srtp_profile ); + if( profile_value != MBEDTLS_TLS_SRTP_UNSET ) + { + MBEDTLS_PUT_UINT16_BE( profile_value, buf, 6 ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) ); + return; + } + + buf[8] = mki_len & 0xFF; + memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len ); + + *olen = 9 + mki_len; +} +#endif /* MBEDTLS_SSL_DTLS_SRTP */ + #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *p = ssl->out_msg + 4; unsigned char *cookie_len_byte; @@ -2430,12 +2756,61 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +static void ssl_handle_id_based_session_resumption( mbedtls_ssl_context *ssl ) +{ + int ret; + mbedtls_ssl_session session_tmp; + mbedtls_ssl_session * const session = ssl->session_negotiate; + + /* Resume is 0 by default, see ssl_handshake_init(). + * It may be already set to 1 by ssl_parse_session_ticket_ext(). */ + if( ssl->handshake->resume == 1 ) + return; + if( session->id_len == 0 ) + return; + if( ssl->conf->f_get_cache == NULL ) + return; +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + return; +#endif + + mbedtls_ssl_session_init( &session_tmp ); + + session_tmp.id_len = session->id_len; + memcpy( session_tmp.id, session->id, session->id_len ); + + ret = ssl->conf->f_get_cache( ssl->conf->p_cache, + &session_tmp ); + if( ret != 0 ) + goto exit; + + if( session->ciphersuite != session_tmp.ciphersuite || + session->compression != session_tmp.compression ) + { + /* Mismatch between cached and negotiated session */ + goto exit; + } + + /* Move semantics */ + mbedtls_ssl_session_free( session ); + *session = session_tmp; + memset( &session_tmp, 0, sizeof( session_tmp ) ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); + ssl->handshake->resume = 1; + +exit: + + mbedtls_ssl_session_free( &session_tmp ); +} + static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_HAVE_TIME) mbedtls_time_t t; #endif - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t olen, ext_len = 0, n; unsigned char *buf, *p; @@ -2477,12 +2852,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_HAVE_TIME) t = mbedtls_time( NULL ); - *p++ = (unsigned char)( t >> 24 ); - *p++ = (unsigned char)( t >> 16 ); - *p++ = (unsigned char)( t >> 8 ); - *p++ = (unsigned char)( t ); + MBEDTLS_PUT_UINT32_BE( t, p, 0 ); + p += 4; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %" MBEDTLS_PRINTF_LONGLONG, + (long long) t ) ); #else if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) return( ret ); @@ -2499,22 +2873,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); - /* - * Resume is 0 by default, see ssl_handshake_init(). - * It may be already set to 1 by ssl_parse_session_ticket_ext(). - * If not, try looking up session ID in our cache. - */ - if( ssl->handshake->resume == 0 && -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && -#endif - ssl->session_negotiate->id_len != 0 && - ssl->conf->f_get_cache != NULL && - ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); - ssl->handshake->resume = 1; - } + ssl_handle_id_based_session_resumption( ssl ); if( ssl->handshake->resume == 0 ) { @@ -2570,19 +2929,19 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len ); p += ssl->session_negotiate->id_len; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", ssl->handshake->resume ? "a" : "no" ) ); - *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); - *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); - *p++ = (unsigned char)( ssl->session_negotiate->compression ); + MBEDTLS_PUT_UINT16_BE( ssl->session_negotiate->ciphersuite, p, 0 ); + p += 2; + *p++ = MBEDTLS_BYTE_0( ssl->session_negotiate->compression ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", - ssl->session_negotiate->compression ) ); + (unsigned int) ssl->session_negotiate->compression ) ); /* Do not write the extensions if the protocol is SSLv3 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) @@ -2606,6 +2965,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; @@ -2641,13 +3005,18 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif - MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); +#if defined(MBEDTLS_SSL_DTLS_SRTP) + ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, + ext_len ) ); if( ext_len > 0 ) { - *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); - *p++ = (unsigned char)( ( ext_len ) & 0xFF ); - p += ext_len; + MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 ); + p += 2 + ext_len; } #if defined(MBEDTLS_SSL_PROTO_SSL3) @@ -2665,24 +3034,15 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) return( ret ); } -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; + ssl->handshake->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); ssl->state++; @@ -2692,13 +3052,13 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else +#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; - size_t dn_size, total_dn_size; /* excluding length bytes */ + ssl->handshake->ciphersuite_info; + uint16_t dn_size, total_dn_size; /* excluding length bytes */ size_t ct_len, sa_len; /* including length bytes */ unsigned char *buf, *p; const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; @@ -2716,11 +3076,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) #endif authmode = ssl->conf->authmode; - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || + if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) || authmode == MBEDTLS_SSL_VERIFY_NONE ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); @@ -2799,8 +3155,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) #endif } - p[0] = (unsigned char)( sa_len >> 8 ); - p[1] = (unsigned char)( sa_len ); + MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 ); sa_len += 2; p += sa_len; } @@ -2816,6 +3171,11 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) { + /* NOTE: If trusted certificates are provisioned + * via a CA callback (configured through + * `mbedtls_ssl_conf_ca_cb()`, then the + * CertificateRequest is currently left empty. */ + #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if( ssl->handshake->sni_ca_chain != NULL ) crt = ssl->handshake->sni_ca_chain; @@ -2825,18 +3185,18 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) while( crt != NULL && crt->version != 0 ) { - dn_size = crt->subject_raw.len; + /* It follows from RFC 5280 A.1 that this length + * can be represented in at most 11 bits. */ + dn_size = (uint16_t) crt->subject_raw.len; - if( end < p || - (size_t)( end - p ) < dn_size || - (size_t)( end - p ) < 2 + dn_size ) + if( end < p || (size_t)( end - p ) < 2 + (size_t) dn_size ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); break; } - *p++ = (unsigned char)( dn_size >> 8 ); - *p++ = (unsigned char)( dn_size ); + MBEDTLS_PUT_UINT16_BE( dn_size, p, 0 ); + p += 2; memcpy( p, crt->subject_raw.p, dn_size ); p += dn_size; @@ -2850,8 +3210,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) ssl->out_msglen = p - buf; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; - ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); - ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); + MBEDTLS_PUT_UINT16_BE( total_dn_size, ssl->out_msg, 4 + ct_len + sa_len ); ret = mbedtls_ssl_write_handshake_msg( ssl ); @@ -2859,18 +3218,13 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) return( ret ); } -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) ) { @@ -2891,7 +3245,7 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \ defined(MBEDTLS_SSL_ASYNC_PRIVATE) static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, size_t *signature_len ) @@ -2914,7 +3268,7 @@ static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); return( ret ); } -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && +#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ /* Prepare the ServerKeyExchange message, up to and including @@ -2924,17 +3278,18 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, size_t *signature_len ) { const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) + ssl->handshake->ciphersuite_info; + +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) unsigned char *dig_signed = NULL; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ (void) ciphersuite_info; /* unused in some configurations */ -#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) (void) signature_len; -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ @@ -2950,7 +3305,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; ret = mbedtls_ecjpake_write_round_two( @@ -2987,10 +3342,10 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, /* * - DHE key exchanges */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) @@ -3026,7 +3381,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, return( ret ); } -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) dig_signed = ssl->out_msg + ssl->out_msglen; #endif @@ -3037,12 +3392,12 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */ /* * - ECDHE key exchanges */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) ) { /* @@ -3055,7 +3410,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, */ const mbedtls_ecp_curve_info **curve = NULL; const mbedtls_ecp_group_id *gid; - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t len = 0; /* Match our preference list against the offered curves */ @@ -3090,7 +3445,7 @@ curve_matching_done: return( ret ); } -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) dig_signed = ssl->out_msg + ssl->out_msglen; #endif @@ -3099,7 +3454,7 @@ curve_matching_done: MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, MBEDTLS_DEBUG_ECDH_Q ); } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */ /* * @@ -3107,13 +3462,17 @@ curve_matching_done: * exchange parameters, compute and add the signature here. * */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) { size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed; size_t hashlen = 0; +#if defined(MBEDTLS_USE_PSA_CRYPTO) + unsigned char hash[PSA_HASH_MAX_SIZE]; +#else unsigned char hash[MBEDTLS_MD_MAX_SIZE]; - int ret; +#endif + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; /* * 2.1: Choose hash algorithm: @@ -3160,7 +3519,7 @@ curve_matching_done: md_alg = MBEDTLS_MD_NONE; } - MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %u for signing", (unsigned) md_alg ) ); /* * 2.2: Compute the hash to be signed @@ -3275,7 +3634,7 @@ curve_matching_done: return( ret ); } } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ return( 0 ); } @@ -3286,28 +3645,28 @@ curve_matching_done: * machine. */ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t signature_len = 0; -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ + ssl->handshake->ciphersuite_info; +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) /* Extract static ECDH parameters and abort if ServerKeyExchange * is not needed. */ if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) { /* For suites involving ECDH, extract DH parameters * from certificate at this point. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) { ssl_get_ecdh_params_from_cert( ssl ); } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ /* Key exchanges not involving ephemeral keys don't use * ServerKeyExchange, so end here. */ @@ -3315,9 +3674,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ssl->state++; return( 0 ); } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \ defined(MBEDTLS_SSL_ASYNC_PRIVATE) /* If we have already prepared the message and there is an ongoing * signature operation, resume signing. */ @@ -3327,7 +3686,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) ret = ssl_resume_server_key_exchange( ssl, &signature_len ); } else -#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && +#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ { /* ServerKeyExchange is needed. Prepare the message. */ @@ -3350,11 +3709,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) /* If there is a signature, write its length. * ssl_prepare_server_key_exchange already wrote the signature * itself at its proper place in the output buffer. */ -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) if( signature_len != 0 ) { - ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 ); - ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len ); + ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1( signature_len ); + ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0( signature_len ); MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", ssl->out_msg + ssl->out_msglen, @@ -3363,7 +3722,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) /* Skip over the already-written signature */ ssl->out_msglen += signature_len; } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ /* Add header and send. */ ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; @@ -3383,7 +3742,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) ); @@ -3487,7 +3846,7 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, size_t *peer_pmslen, size_t peer_pmssize ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; size_t len = mbedtls_pk_get_len( public_key ); @@ -3510,12 +3869,13 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) { - if ( p + 2 > end ) { + if ( p + 2 > end ) + { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } - if( *p++ != ( ( len >> 8 ) & 0xFF ) || - *p++ != ( ( len ) & 0xFF ) ) + if( *p++ != MBEDTLS_BYTE_1( len ) || + *p++ != MBEDTLS_BYTE_0( len ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); @@ -3576,7 +3936,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, const unsigned char *end, size_t pms_offset ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char *pms = ssl->handshake->premaster + pms_offset; unsigned char ver[2]; unsigned char fake_pms[48], peer_pms[48]; @@ -3617,16 +3977,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, diff |= peer_pms[1] ^ ver[1]; /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif + mask = mbedtls_ct_uint_mask( diff ); /* * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding @@ -3668,16 +4019,14 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p, const unsigned char *end ) { int ret = 0; - size_t n; + uint16_t n; - if( ssl->conf->f_psk == NULL && - ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || - ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) + if( ssl_conf_has_psk_or_cb( ssl->conf ) == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); @@ -3695,7 +4044,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha n = ( (*p)[0] << 8 ) | (*p)[1]; *p += 2; - if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) ) + if( n == 0 || n > end - *p ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); @@ -3711,7 +4060,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha /* Identity is not a big secret since clients send it in the clear, * but treat it carefully anyway, just in case */ if( n != ssl->conf->psk_identity_len || - mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) + mbedtls_ct_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) { ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; } @@ -3729,15 +4078,15 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha return( 0 ); } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; unsigned char *p, *end; - ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + ciphersuite_info = ssl->handshake->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); @@ -3857,6 +4206,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } +#if defined(MBEDTLS_USE_PSA_CRYPTO) + /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically + * and skip the intermediate PMS. */ + if( ssl_use_opaque_psk( ssl ) == 1 ) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) ); + else +#endif /* MBEDTLS_USE_PSA_CRYPTO */ if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, ciphersuite_info->key_exchange ) ) != 0 ) { @@ -3888,6 +4244,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) return( ret ); } +#if defined(MBEDTLS_USE_PSA_CRYPTO) + /* Opaque PSKs are currently only supported for PSK-only. */ + if( ssl_use_opaque_psk( ssl ) == 1 ) + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +#endif + if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); @@ -3917,6 +4279,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) return( ret ); } +#if defined(MBEDTLS_USE_PSA_CRYPTO) + /* Opaque PSKs are currently only supported for PSK-only. */ + if( ssl_use_opaque_psk( ssl ) == 1 ) + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +#endif + if( p != end ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); @@ -3948,6 +4316,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); } +#if defined(MBEDTLS_USE_PSA_CRYPTO) + /* Opaque PSKs are currently only supported for PSK-only. */ + if( ssl_use_opaque_psk( ssl ) == 1 ) + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +#endif + MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx, MBEDTLS_DEBUG_ECDH_QP ); @@ -4011,24 +4385,15 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) return( 0 ); } -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; + ssl->handshake->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); ssl->state++; @@ -4038,7 +4403,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else +#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; @@ -4051,21 +4416,33 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) #endif mbedtls_md_type_t md_alg; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = - ssl->transform_negotiate->ciphersuite_info; + ssl->handshake->ciphersuite_info; + mbedtls_pk_context * peer_pk; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || - ssl->session_negotiate->peer_cert == NULL ) + if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } + +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } +#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + if( ssl->session_negotiate->peer_cert_digest == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); ssl->state++; return( 0 ); } +#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ /* Read the message without adding it to the checksum */ ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ ); @@ -4087,6 +4464,17 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) i = mbedtls_ssl_hs_hdr_len( ssl ); +#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + peer_pk = &ssl->handshake->peer_pubkey; +#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + if( ssl->session_negotiate->peer_cert == NULL ) + { + /* Should never happen */ + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + peer_pk = &ssl->session_negotiate->peer_cert->pk; +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + /* * struct { * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only @@ -4101,8 +4489,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) hashlen = 36; /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ - if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, - MBEDTLS_PK_ECDSA ) ) + if( mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECDSA ) ) { hash_start += 16; hashlen -= 16; @@ -4157,7 +4544,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) /* * Check the certificate's key type matches the signature alg */ - if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) + if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); @@ -4188,9 +4575,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) } /* Calculate hash and verify signature */ - ssl->handshake->calc_verify( ssl, hash ); + { + size_t dummy_hlen; + ssl->handshake->calc_verify( ssl, hash, &dummy_hlen ); + } - if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, + if( ( ret = mbedtls_pk_verify( peer_pk, md_alg, hash_start, hashlen, ssl->in_msg + i, sig_len ) ) != 0 ) { @@ -4204,17 +4594,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) return( ret ); } -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) { - int ret; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t tlen; uint32_t lifetime; @@ -4244,14 +4629,8 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) tlen = 0; } - ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; - ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; - ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; - ssl->out_msg[7] = ( lifetime ) & 0xFF; - - ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); - ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); - + MBEDTLS_PUT_UINT32_BE( lifetime, ssl->out_msg, 4 ); + MBEDTLS_PUT_UINT16_BE( tlen, ssl->out_msg, 8 ); ssl->out_msglen = 10 + tlen; /* -- cgit v1.2.3