#include "common.h"
#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
#include "mbedtls/platform.h"
#include "mbedtls/ssl.h"
#include "ssl_client.h"
#include "ssl_misc.h"
#include "debug_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/constant_time.h"
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa_util_internal.h"
#include "psa/crypto.h"
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
static int local_err_translation(psa_status_t status)
{
return psa_status_to_mbedtls(status, psa_to_ssl_errors,
ARRAY_LENGTH(psa_to_ssl_errors),
psa_generic_status_to_mbedtls);
}
#define PSA_TO_MBEDTLS_ERR …
#endif
#endif
#include <string.h>
#include <stdint.h>
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
#include "mbedtls/platform_util.h"
#endif
#if defined(MBEDTLS_SSL_RENEGOTIATION)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
size_t kkpp_len = 0;
*olen = 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (ssl->handshake->psa_pake_ctx_is_ok != 1) {
return 0;
}
#else
if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) {
return 0;
}
#endif
MBEDTLS_SSL_DEBUG_MSG(3,
("client hello, adding ecjpake_kkpp extension"));
MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
p += 2;
if (ssl->handshake->ecjpake_cache == NULL ||
ssl->handshake->ecjpake_cache_len == 0) {
MBEDTLS_SSL_DEBUG_MSG(3, ("generating new ecjpake parameters"));
#if defined(MBEDTLS_USE_PSA_CRYPTO)
ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
p + 2, end - p - 2, &kkpp_len,
MBEDTLS_ECJPAKE_ROUND_ONE);
if (ret != 0) {
psa_destroy_key(ssl->handshake->psa_pake_password);
psa_pake_abort(&ssl->handshake->psa_pake_ctx);
MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
return ret;
}
#else
ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1,
"mbedtls_ecjpake_write_round_one", ret);
return ret;
}
#endif
ssl->handshake->ecjpake_cache = mbedtls_calloc(1, kkpp_len);
if (ssl->handshake->ecjpake_cache == NULL) {
MBEDTLS_SSL_DEBUG_MSG(1, ("allocation failed"));
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
memcpy(ssl->handshake->ecjpake_cache, p + 2, kkpp_len);
ssl->handshake->ecjpake_cache_len = kkpp_len;
} else {
MBEDTLS_SSL_DEBUG_MSG(3, ("re-using cached ecjpake parameters"));
kkpp_len = ssl->handshake->ecjpake_cache_len;
MBEDTLS_SSL_CHK_BUF_PTR(p + 2, end, kkpp_len);
memcpy(p + 2, ssl->handshake->ecjpake_cache, kkpp_len);
}
MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
p += 2;
*olen = kkpp_len + 4;
return 0;
}
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_cid_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{ … }
#endif
#if defined(MBEDTLS_SSL_DTLS_SRTP)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
size_t *olen)
{
unsigned char *p = buf;
size_t protection_profiles_index = 0, ext_len = 0;
uint16_t mki_len = 0, profile_value = 0;
*olen = 0;
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;
}
if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
mki_len = ssl->dtls_srtp_info.mki_len;
}
ext_len = 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len;
MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding use_srtp extension"));
MBEDTLS_SSL_CHK_BUF_PTR(p, end, ext_len + 4);
MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, p, 0);
p += 2;
MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
p += 2;
*p++ = 0;
*p++ = MBEDTLS_BYTE_0(2 * ssl->conf->dtls_srtp_profile_list_len);
for (protection_profiles_index = 0;
protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
protection_profiles_index++) {
profile_value = mbedtls_ssl_check_srtp_profile_value
(ssl->conf->dtls_srtp_profile_list[protection_profiles_index]);
if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_write_use_srtp_ext, add profile: %04x",
profile_value));
MBEDTLS_PUT_UINT16_BE(profile_value, p, 0);
p += 2;
} else {
MBEDTLS_SSL_DEBUG_MSG(3,
("client hello, "
"illegal DTLS-SRTP protection profile %d",
ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
));
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
}
*p++ = mki_len & 0xFF;
if (mki_len != 0) {
memcpy(p, ssl->dtls_srtp_info.mki_value, mki_len);
p += mki_len;
MBEDTLS_SSL_DEBUG_BUF(3, "sending mki", ssl->dtls_srtp_info.mki_value,
ssl->dtls_srtp_info.mki_len);
}
*olen = p - buf;
return 0;
}
#endif
int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
int uses_ec,
size_t *out_len)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#endif
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#endif
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if (ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension"));
return 0;
}
mbedtls_free(ssl->handshake->ecjpake_cache);
ssl->handshake->ecjpake_cache = NULL;
ssl->handshake->ecjpake_cache_len = 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if ((ret = mbedtls_psa_ecjpake_read_round(
&ssl->handshake->psa_pake_ctx, buf, len,
MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) {
psa_destroy_key(ssl->handshake->psa_pake_password);
psa_pake_abort(&ssl->handshake->psa_pake_ctx);
MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret);
mbedtls_ssl_send_alert_message(
ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
return ret;
}
return 0;
#else
if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx,
buf, len)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret);
mbedtls_ssl_send_alert_message(
ssl,
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
return ret;
}
return 0;
#endif
}
#endif
#if defined(MBEDTLS_SSL_ALPN)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_alpn_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len)
{ … }
#endif
#if defined(MBEDTLS_SSL_DTLS_SRTP)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len)
{
mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
size_t i, mki_len = 0;
uint16_t server_protection_profile_value = 0;
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;
}
if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
mki_len = ssl->dtls_srtp_info.mki_len;
}
if ((len < 5) || (len != (buf[4] + 5u))) {
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
if ((buf[0] != 0) || (buf[1] != 2)) {
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
server_protection_profile_value = (buf[2] << 8) | buf[3];
server_protection = mbedtls_ssl_check_srtp_profile_value(
server_protection_profile_value);
if (server_protection != MBEDTLS_TLS_SRTP_UNSET) {
MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s",
mbedtls_ssl_get_srtp_profile_as_string(
server_protection)));
}
ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) {
if (server_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(
server_protection)));
break;
}
}
if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) {
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
if (len == 5) {
ssl->dtls_srtp_info.mki_len = 0;
}
if (len > 5 && (buf[4] != mki_len ||
(memcmp(ssl->dtls_srtp_info.mki_value, &buf[5], mki_len)))) {
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
}
#if defined(MBEDTLS_DEBUG_C)
if (len > 5) {
MBEDTLS_SSL_DEBUG_BUF(3, "received mki", ssl->dtls_srtp_info.mki_value,
ssl->dtls_srtp_info.mki_len);
}
#endif
return 0;
}
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
{ … }
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_dh_params(mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end)
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
size_t dhm_actual_bitlen;
if ((ret = mbedtls_dhm_read_params(&ssl->handshake->dhm_ctx,
p, end)) != 0) {
MBEDTLS_SSL_DEBUG_RET(2, ("mbedtls_dhm_read_params"), ret);
return ret;
}
dhm_actual_bitlen = mbedtls_dhm_get_bitlen(&ssl->handshake->dhm_ctx);
if (dhm_actual_bitlen < ssl->conf->dhm_min_bitlen) {
MBEDTLS_SSL_DEBUG_MSG(1, ("DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
dhm_actual_bitlen,
ssl->conf->dhm_min_bitlen));
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
return ret;
}
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end)
{
uint16_t tls_id;
size_t ecpoint_len;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
size_t ec_bits = 0;
if (end - *p < 4) {
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
if (*(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) {
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
tls_id = MBEDTLS_GET_UINT16_BE(*p, 0);
*p += 2;
if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) {
MBEDTLS_SSL_DEBUG_MSG(2,
("bad server key exchange message (ECDHE curve): %u",
(unsigned) tls_id));
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
if (mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
&ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
handshake->xxdh_psa_type = key_type;
handshake->xxdh_psa_bits = ec_bits;
ecpoint_len = *(*p)++;
if ((size_t) (end - *p) < ecpoint_len) {
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
}
memcpy(handshake->xxdh_psa_peerkey, *p, ecpoint_len);
handshake->xxdh_psa_peerkey_len = ecpoint_len;
*p += ecpoint_len;
return 0;
}
#endif
#else
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_check_server_ecdh_params(const mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end)
{ … }
#endif
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl,
size_t offset, size_t *olen,
size_t pms_offset)
{ … }
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl)
{ … }
#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
ssl->state++;
return 0;
}
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
#else
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
{ … }
#endif
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl)
{ … }
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl)
{ … }
#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->handshake->ciphersuite_info;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
return ret;
}
if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
ssl->state++;
return 0;
}
MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
#else
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
{ … }
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl)
{ … }
#endif
int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl)
{ … }
#endif