mbedTLS: Update to version 2.28.10

(cherry picked from commit cdb875257a)
This commit is contained in:
Rémi Verschelde 2025-03-24 23:31:45 +01:00 committed by lawnjelly
parent aecec0f347
commit 55d22086e1
16 changed files with 390 additions and 124 deletions

View file

@ -283,7 +283,7 @@ Files extracted from upstream source:
## mbedtls
- Upstream: https://github.com/Mbed-TLS/mbedtls
- Version: 2.28.9 (5e146adef63b326b04282252639bebc2730939c6, 2024)
- Version: 2.28.10 (2fc8413bfcb51354c8e679141b17b3f1a5942561, 2025)
- License: Apache 2.0
File extracted from upstream release tarball:

View file

@ -1713,6 +1713,46 @@
*/
//#define MBEDTLS_SSL_ASYNC_PRIVATE
/** \def MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
*
* In TLS clients, when a client authenticates a server through its
* certificate, the client normally checks three things:
* - the certificate chain must be valid;
* - the chain must start from a trusted CA;
* - the certificate must cover the server name that is expected by the client.
*
* Omitting any of these checks is generally insecure, and can allow a
* malicious server to impersonate a legitimate server.
*
* The third check may be safely skipped in some unusual scenarios,
* such as networks where eavesdropping is a risk but not active attacks,
* or a private PKI where the client equally trusts all servers that are
* accredited by the root CA.
*
* You should call mbedtls_ssl_set_hostname() with the expected server name
* before starting a TLS handshake on a client (unless the client is
* set up to only use PSK-based authentication, which does not rely on the
* host name). This configuration option controls what happens if a TLS client
* is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED
* (default), certificate authentication is enabled and the client does not
* call mbedtls_ssl_set_hostname():
*
* - If this option is unset (default), the connection attempt is aborted
* with the error #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME.
* - If this option is set, the TLS library does not check the server name
* that the certificate is valid for. This is the historical behavior
* of Mbed TLS, but may be insecure as explained above.
*
* Enable this option for strict backward compatibility if you have
* determined that it is secure in the scenario where you are using
* Mbed TLS.
*
* \deprecated This option exists only for backward compatibility and will
* be removed in the next major version of Mbed TLS.
*
*/
//#define MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
/**
* \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
*
@ -2290,6 +2330,10 @@
* That is, the APIs enabled by this option are not covered by the usual
* promises of API stability.
*
* \warning In multithreaded applications, you must also enable
* #MBEDTLS_THREADING_C, unless only one thread ever calls PSA functions
* (`psa_xxx()`), including indirect calls through SSL/TLS, X.509 or PK.
*
* Requires: MBEDTLS_PSA_CRYPTO_C.
*
* Uncomment this to enable internal use of PSA Crypto and new associated APIs.
@ -3389,6 +3433,14 @@
*
* Enable the Platform Security Architecture cryptography API.
*
* \note In multithreaded applications, you must enable #MBEDTLS_THREADING_C,
* unless only one thread ever calls `psa_xxx()` functions.
* That includes indirect calls, such as:
* - indirect calls from PK, X.509 or SSL functions when
* #MBEDTLS_USE_PSA_CRYPTO is enabled;
* - any other call to a function that requires calling psa_crypto_init()
* beforehand.
*
* Module: library/psa_crypto.c
*
* Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
@ -3605,11 +3657,29 @@
/**
* \def MBEDTLS_THREADING_C
*
* Enable the threading abstraction layer.
* By default Mbed TLS assumes it is used in a non-threaded environment or that
* contexts are not shared between threads. If you do intend to use contexts
* Traditionally, Mbed TLS assumes it is used in a non-threaded environment or
* that contexts are not shared between threads. If you do intend to use contexts
* between threads, you will need to enable this layer to prevent race
* conditions. See also our Knowledge Base article about threading:
* conditions.
*
* The PSA subsystem has an implicit shared context. Therefore, you must
* enable this option if more than one thread may use any part of
* Mbed TLS that is implemented on top of the PSA subsystem.
*
* You must enable this option in multithreaded applications where more than
* one thread performs any of the following operations:
*
* - Any call to a PSA function (`psa_xxx()`).
* - Any call to a TLS, X.509 or PK function (`mbedtls_ssl_xxx()`,
* `mbedtls_x509_xxx()`, `mbedtls_pkcs7_xxx()`, `mbedtls_pk_xxx()`)
* if `MBEDTLS_USE_PSA_CRYPTO` is enabled (regardless of whether individual
* TLS, X.509 or PK contexts are shared between threads).
* - Any use of a cryptographic context if the same context is used in
* multiple threads.
* - Any call to a function where the documentation specifies that
* psa_crypto_init() must be called prior to that function.
*
* See also our Knowledge Base article about threading:
* https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading
*
* Module: library/threading.c

View file

@ -108,16 +108,16 @@
*
* This module provides debugging functions.
*/
#if (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800)
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)
#include <inttypes.h>
#define MBEDTLS_PRINTF_SIZET PRIuPTR
#define MBEDTLS_PRINTF_LONGLONG "I64d"
#else \
/* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
/* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */
#define MBEDTLS_PRINTF_SIZET "zu"
#define MBEDTLS_PRINTF_LONGLONG "lld"
#endif \
/* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
/* defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900) */
#ifdef __cplusplus
extern "C" {

View file

@ -92,7 +92,7 @@
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
* SSL 5 2 (Started from 0x5F00)
* SSL 5 3 (Started from 0x5F00)
* CIPHER 6 8 (Started from 0x6080)
* SSL 6 24 (Started from top, plus 0x6000)
* SSL 7 32

View file

@ -107,10 +107,9 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
/**
* \brief This function performs GCM encryption or decryption of a buffer.
*
* \note For encryption, the output buffer can be the same as the
* input buffer. For decryption, the output buffer cannot be
* the same as input buffer. If the buffers overlap, the output
* buffer must trail at least 8 Bytes behind the input buffer.
* \note The output buffer \p output can be the same as the input
* buffer \p input. If \p output is greater than \p input, they
* cannot overlap.
*
* \warning When this function performs a decryption, it outputs the
* authentication tag and does not verify that the data is
@ -171,9 +170,11 @@ int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
* \brief This function performs a GCM authenticated decryption of a
* buffer.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
* \note The output buffer \p output can be the same as the input
* buffer \p input. If \p output is greater than \p input, they
* cannot overlap. Implementations which require
* MBEDTLS_GCM_ALT to be enabled may not provide support for
* overlapping buffers.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the ciphertext to decrypt, which is also
@ -243,9 +244,11 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
* Bytes. Only the last call before calling
* mbedtls_gcm_finish() can be less than 16 Bytes.
*
* \note For decryption, the output buffer cannot be the same as
* input buffer. If the buffers overlap, the output buffer
* must trail at least 8 Bytes behind the input buffer.
* \note The output buffer \p output can be the same as the input
* buffer \p input. If \p output is greater than \p input, they
* cannot overlap. Implementations which require
* MBEDTLS_GCM_ALT to be enabled may not provide support for
* overlapping buffers.
*
* \param ctx The GCM context. This must be initialized.
* \param length The length of the input data. This must be a multiple of

View file

@ -226,7 +226,7 @@ int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len);
/**
* \brief Write at most 'len' characters. If no error occurs,
* the actual amount read is returned.
* the actual amount written is returned.
*
* \param ctx Socket
* \param buf The buffer to read from

View file

@ -183,6 +183,41 @@
#define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80
/** Cache entry not found */
#define MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND -0x5E00
/** Attempt to verify a certificate without an expected hostname.
* This is usually insecure.
*
* In TLS clients, when a client authenticates a server through its
* certificate, the client normally checks three things:
* - the certificate chain must be valid;
* - the chain must start from a trusted CA;
* - the certificate must cover the server name that is expected by the client.
*
* Omitting any of these checks is generally insecure, and can allow a
* malicious server to impersonate a legitimate server.
*
* The third check may be safely skipped in some unusual scenarios,
* such as networks where eavesdropping is a risk but not active attacks,
* or a private PKI where the client equally trusts all servers that are
* accredited by the root CA.
*
* You should call mbedtls_ssl_set_hostname() with the expected server name
* before starting a TLS handshake on a client (unless the client is
* set up to only use PSK-based authentication, which does not rely on the
* host name). If you have determined that server name verification is not
* required for security in your scenario, call mbedtls_ssl_set_hostname()
* with \p NULL as the server name.
*
* This error is raised if all of the following conditions are met:
*
* - A TLS client is configured with the authentication mode
* #MBEDTLS_SSL_VERIFY_REQUIRED (default).
* - Certificate authentication is enabled.
* - The client does not call mbedtls_ssl_set_hostname().
* - The configuration option
* #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
* is not enabled.
*/
#define MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME -0x5D80
/*
* Various constants
@ -1403,8 +1438,36 @@ struct mbedtls_ssl_context {
* User settings
*/
#if defined(MBEDTLS_X509_CRT_PARSE_C)
char *hostname; /*!< expected peer CN for verification
(and SNI if available) */
/** Expected peer CN for verification.
*
* Also used on clients for SNI.
*
* The value of this field can be:
* - \p NULL in a newly initialized or reset context.
* - A heap-allocated copy of the last value passed to
* mbedtls_ssl_set_hostname(), if the last call had a non-null
* \p hostname argument.
* - A special value to indicate that mbedtls_ssl_set_hostname()
* was called with \p NULL (as opposed to never having been called).
*
* If you need to obtain the value passed to
* mbedtls_ssl_set_hostname() even if it may have been called with
* \p NULL, call mbedtls_ssl_get_hostname_pointer().
*
* If this field contains the value \p NULL and the configuration option
* #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
* is unset, on a TLS client, attempting to verify a server certificate
* results in the error
* #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME.
*
* If this field contains the special value described above, or if
* the value is \p NULL and the configuration option
* #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
* is set, then the peer name verification is skipped, which may be
* insecure, especially on a client. Furthermore, on a client, the
* server_name extension is not sent.
*/
char *hostname;
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_ALPN)
@ -1535,6 +1598,14 @@ void mbedtls_ssl_init(mbedtls_ssl_context *ssl);
* Calling mbedtls_ssl_setup again is not supported, even
* if no session is active.
*
* \warning After setting up a client context, if certificate-based
* authentication is enabled, you should call
* mbedtls_ssl_set_hostname() to specifiy the expected
* name of the server. Without this, in most scenarios,
* the TLS connection is insecure. See
* #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
* for more information.
*
* \note If #MBEDTLS_USE_PSA_CRYPTO is enabled, the PSA crypto
* subsystem must have been initialized by calling
* psa_crypto_init() before calling this function.
@ -3107,16 +3178,29 @@ void mbedtls_ssl_conf_sig_hashes(mbedtls_ssl_config *conf,
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Set or reset the hostname to check against the received
* server certificate. It sets the ServerName TLS extension,
* too, if that extension is enabled. (client-side only)
* peer certificate. On a client, this also sets the
* ServerName TLS extension, if that extension is enabled.
* On a TLS 1.3 client, this also sets the server name in
* the session resumption ticket, if that feature is enabled.
*
* \param ssl SSL context
* \param hostname the server hostname, may be NULL to clear hostname
* \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN.
* \param hostname The server hostname. This may be \c NULL to clear
* the hostname.
*
* \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on
* allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on
* \note Maximum hostname length #MBEDTLS_SSL_MAX_HOST_NAME_LEN.
*
* \note If the hostname is \c NULL on a client, then the server
* is not authenticated: it only needs to have a valid
* certificate, not a certificate matching its name.
* Therefore you should always call this function on a client,
* unless the connection is set up to only allow
* pre-shared keys, or in scenarios where server
* impersonation is not a concern. See the documentation of
* #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
* for more details.
*
* \return 0 if successful, #MBEDTLS_ERR_SSL_ALLOC_FAILED on
* allocation failure, #MBEDTLS_ERR_SSL_BAD_INPUT_DATA on
* too long input hostname.
*
* Hostname set to the one provided on success (cleared

View file

@ -467,7 +467,8 @@ struct mbedtls_ssl_handshake_params {
void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
MBEDTLS_CHECK_RETURN_CRITICAL
int (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
mbedtls_ssl_tls_prf_cb *tls_prf;
#if defined(MBEDTLS_DHM_C)
@ -1214,6 +1215,16 @@ static inline size_t mbedtls_ssl_hs_hdr_len(const mbedtls_ssl_context *ssl)
return 4;
}
/** Get the host name from the SSL context.
*
* \param[in] ssl SSL context
*
* \return The \p hostname pointer from the SSL context.
* \c NULL if mbedtls_ssl_set_hostname() has never been called on
* \p ssl or if it was last called with \p NULL.
*/
const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl);
#if defined(MBEDTLS_SSL_PROTO_DTLS)
void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl);
void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl);

View file

@ -26,16 +26,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 28
#define MBEDTLS_VERSION_PATCH 9
#define MBEDTLS_VERSION_PATCH 10
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
#define MBEDTLS_VERSION_NUMBER 0x021C0900
#define MBEDTLS_VERSION_STRING "2.28.9"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 2.28.9"
#define MBEDTLS_VERSION_NUMBER 0x021C0A00
#define MBEDTLS_VERSION_STRING "2.28.10"
#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 2.28.10"
#if defined(MBEDTLS_VERSION_C)

View file

@ -460,7 +460,7 @@ int mbedtls_aesni_crypt_ecb(mbedtls_aes_context *ctx,
"movdqu %%xmm0, (%4) \n\t" // export output
:
: "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output)
: "memory", "cc", "xmm0", "xmm1");
: "memory", "cc", "xmm0", "xmm1", "0", "1");
return 0;
@ -648,7 +648,7 @@ static void aesni_setkey_enc_128(unsigned char *rk,
AESKEYGENA(xmm0_xmm1, "0x36") "call 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0");
: "memory", "cc", "xmm0", "xmm1", "0");
}
/*
@ -705,7 +705,7 @@ static void aesni_setkey_enc_192(unsigned char *rk,
:
: "r" (rk), "r" (key)
: "memory", "cc", "0");
: "memory", "cc", "xmm0", "xmm1", "xmm2", "0");
}
/*
@ -771,7 +771,7 @@ static void aesni_setkey_enc_256(unsigned char *rk,
AESKEYGENA(xmm1_xmm2, "0x40") "call 1b \n\t"
:
: "r" (rk), "r" (key)
: "memory", "cc", "0");
: "memory", "cc", "xmm0", "xmm1", "xmm2", "0");
}
#endif /* MBEDTLS_AESNI_HAVE_CODE */

View file

@ -3125,7 +3125,7 @@ int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp,
/* see RFC 7748 sec. 5 para. 5 */
if (mbedtls_mpi_get_bit(d, 0) != 0 ||
mbedtls_mpi_get_bit(d, 1) != 0 ||
mbedtls_mpi_bitlen(d) - 1 != grp->nbits) { /* mbedtls_mpi_bitlen is one-based! */
mbedtls_mpi_bitlen(d) != grp->nbits + 1) { /* mbedtls_mpi_bitlen is one-based! */
return MBEDTLS_ERR_ECP_INVALID_KEY;
}

View file

@ -508,6 +508,8 @@ const char *mbedtls_high_level_strerr(int error_code)
return( "SSL - Invalid value in SSL config" );
case -(MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND):
return( "SSL - Cache entry not found" );
case -(MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME):
return( "SSL - Attempt to verify a certificate without an expected hostname. This is usually insecure. In TLS clients, when a client authenticates a server through its certificate, the client normally checks three things: - the certificate chain must be valid; - the chain must start from a trusted CA; - the certificate must cover the server name that is expected by the client. Omitting any of these checks is generally insecure, and can allow a malicious server to impersonate a legitimate server. The third check may be safely skipped in some unusual scenarios, such as networks where eavesdropping is a risk but not active attacks, or a private PKI where the client equally trusts all servers that are accredited by the root CA. You should call mbedtls_ssl_set_hostname() with the expected server name before starting a TLS handshake on a client (unless the client is set up to only use PSK-based authentication, which does not rely on the host name). If you have determined that server name verification is not required for security in your scenario, call mbedtls_ssl_set_hostname() with \\p NULL as the server name. This error is raised if all of the following conditions are met: - A TLS client is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED (default). - Certificate authentication is enabled. - The client does not call mbedtls_ssl_set_hostname(). - The configuration option #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME is not enabled" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)

View file

@ -195,7 +195,7 @@ int mbedtls_net_connect(mbedtls_net_context *ctx, const char *host,
break;
}
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
}
@ -242,13 +242,13 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *
n = 1;
if (setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof(n)) != 0) {
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
if (bind(ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen) != 0) {
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_BIND_FAILED;
continue;
}
@ -256,7 +256,7 @@ int mbedtls_net_bind(mbedtls_net_context *ctx, const char *bind_ip, const char *
/* Listen only makes sense for TCP */
if (proto == MBEDTLS_NET_PROTO_TCP) {
if (listen(ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG) != 0) {
close(ctx->fd);
mbedtls_net_close(ctx);
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
continue;
}
@ -529,8 +529,8 @@ void mbedtls_net_usleep(unsigned long usec)
#else
struct timeval tv;
tv.tv_sec = usec / 1000000;
#if defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))
#if (defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))) && !defined(__DJGPP__)
tv.tv_usec = (suseconds_t) usec % 1000000;
#else
tv.tv_usec = usec % 1000000;

View file

@ -83,19 +83,20 @@ static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl,
size_t *olen)
{
unsigned char *p = buf;
const char *hostname = mbedtls_ssl_get_hostname_pointer(ssl);
size_t hostname_len;
*olen = 0;
if (ssl->hostname == NULL) {
if (hostname == NULL) {
return 0;
}
MBEDTLS_SSL_DEBUG_MSG(3,
("client hello, adding server name extension: %s",
ssl->hostname));
hostname));
hostname_len = strlen(ssl->hostname);
hostname_len = strlen(hostname);
MBEDTLS_SSL_CHK_BUF_PTR(p, end, hostname_len + 9);
@ -139,7 +140,7 @@ static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl,
MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
p += 2;
memcpy(p, ssl->hostname, hostname_len);
memcpy(p, hostname, hostname_len);
*olen = hostname_len + 9;

View file

@ -38,6 +38,92 @@
#include "mbedtls/oid.h"
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/* A magic value for `ssl->hostname` indicating that
* mbedtls_ssl_set_hostname() has been called with `NULL`.
* If mbedtls_ssl_set_hostname() has never been called on `ssl`, then
* `ssl->hostname == NULL`. */
static const char *const ssl_hostname_skip_cn_verification = "";
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/** Whether mbedtls_ssl_set_hostname() has been called.
*
* \param[in] ssl SSL context
*
* \return \c 1 if mbedtls_ssl_set_hostname() has been called on \p ssl
* (including `mbedtls_ssl_set_hostname(ssl, NULL)`),
* otherwise \c 0.
*/
static int mbedtls_ssl_has_set_hostname_been_called(
const mbedtls_ssl_context *ssl)
{
return ssl->hostname != NULL;
}
#endif
const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl)
{
if (ssl->hostname == ssl_hostname_skip_cn_verification) {
return NULL;
}
return ssl->hostname;
}
static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl)
{
if (ssl->hostname != NULL &&
ssl->hostname != ssl_hostname_skip_cn_verification) {
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
mbedtls_free(ssl->hostname);
}
ssl->hostname = NULL;
}
int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
{
/* Initialize to suppress unnecessary compiler warning */
size_t hostname_len = 0;
/* Check if new hostname is valid before
* making any change to current one */
if (hostname != NULL) {
hostname_len = strlen(hostname);
if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
}
/* Now it's clear that we will overwrite the old hostname,
* so we can free it safely */
mbedtls_ssl_free_hostname(ssl);
if (hostname == NULL) {
/* Passing NULL as hostname clears the old one, but leaves a
* special marker to indicate that mbedtls_ssl_set_hostname()
* has been called. */
/* ssl->hostname should be const, but isn't. We won't actually
* write to the buffer, so it's ok to cast away the const. */
ssl->hostname = (char *) ssl_hostname_skip_cn_verification;
} else {
ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
if (ssl->hostname == NULL) {
/* mbedtls_ssl_set_hostname() has been called, but unsuccessfully.
* Leave ssl->hostname in the same state as if the function had
* not been called, i.e. a null pointer. */
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
memcpy(ssl->hostname, hostname, hostname_len);
ssl->hostname[hostname_len] = '\0';
}
return 0;
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
@ -538,6 +624,23 @@ exit:
}
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_USE_PSA_CRYPTO)
static int mbedtls_ssl_md_error_from_psa(psa_status_t status)
{
switch (status) {
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
case PSA_ERROR_BUFFER_TOO_SMALL:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
case PSA_ERROR_INSUFFICIENT_MEMORY:
return MBEDTLS_ERR_MD_ALLOC_FAILED;
default:
return MBEDTLS_ERR_MD_HW_ACCEL_FAILED;
}
}
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -806,25 +909,25 @@ static void ssl_update_checksum_md5sha1(mbedtls_ssl_context *, const unsigned ch
#if defined(MBEDTLS_SSL_PROTO_SSL3)
static void ssl_calc_verify_ssl(const mbedtls_ssl_context *, unsigned char *, size_t *);
static void ssl_calc_finished_ssl(mbedtls_ssl_context *, unsigned char *, int);
static int ssl_calc_finished_ssl(mbedtls_ssl_context *, unsigned char *, int);
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
static void ssl_calc_verify_tls(const mbedtls_ssl_context *, unsigned char *, size_t *);
static void ssl_calc_finished_tls(mbedtls_ssl_context *, unsigned char *, int);
static int ssl_calc_finished_tls(mbedtls_ssl_context *, unsigned char *, int);
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
static void ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t);
static void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *);
static void ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int);
#endif
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t);
static void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *);
static void ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int);
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@ -2521,13 +2624,33 @@ static int ssl_parse_certificate_coordinate(mbedtls_ssl_context *ssl,
return SSL_CERTIFICATE_EXPECTED;
}
static int get_hostname_for_verification(mbedtls_ssl_context *ssl,
const char **hostname)
{
if (!mbedtls_ssl_has_set_hostname_been_called(ssl)) {
MBEDTLS_SSL_DEBUG_MSG(1, ("Certificate verification without having set hostname"));
#if !defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED) {
return MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME;
}
#endif
}
*hostname = mbedtls_ssl_get_hostname_pointer(ssl);
if (*hostname == NULL) {
MBEDTLS_SSL_DEBUG_MSG(2, ("Certificate verification without CN verification"));
}
return 0;
}
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
int authmode,
mbedtls_x509_crt *chain,
void *rs_ctx)
{
int ret = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->handshake->ciphersuite_info;
int have_ca_chain = 0;
@ -2549,6 +2672,13 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
p_vrfy = ssl->conf->p_vrfy;
}
const char *hostname = "";
int ret = get_hostname_for_verification(ssl, &hostname);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "get_hostname_for_verification", ret);
return ret;
}
/*
* Main check: verify certificate
*/
@ -2563,7 +2693,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
ssl->conf->f_ca_cb,
ssl->conf->p_ca_cb,
ssl->conf->cert_profile,
ssl->hostname,
hostname,
&ssl->session_negotiate->verify_result,
f_vrfy, p_vrfy);
} else
@ -2591,7 +2721,7 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl,
chain,
ca_chain, ca_crl,
ssl->conf->cert_profile,
ssl->hostname,
hostname,
&ssl->session_negotiate->verify_result,
f_vrfy, p_vrfy, rs_ctx);
}
@ -3023,7 +3153,7 @@ static void ssl_update_checksum_sha384(mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_SSL_PROTO_SSL3)
static void ssl_calc_finished_ssl(
static int ssl_calc_finished_ssl(
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{
const char *sender;
@ -3105,11 +3235,13 @@ static void ssl_calc_finished_ssl(
mbedtls_platform_zeroize(sha1sum, sizeof(sha1sum));
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
return 0;
}
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
static void ssl_calc_finished_tls(
static int ssl_calc_finished_tls(
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{
int len = 12;
@ -3165,12 +3297,14 @@ static void ssl_calc_finished_tls(
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
return 0;
}
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
static void ssl_calc_finished_tls_sha256(
static int ssl_calc_finished_tls_sha256(
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{
int len = 12;
@ -3201,13 +3335,13 @@ static void ssl_calc_finished_tls_sha256(
status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
return;
return mbedtls_ssl_md_error_from_psa(status);
}
status = psa_hash_finish(&sha256_psa, padbuf, sizeof(padbuf), &hash_size);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
return;
return mbedtls_ssl_md_error_from_psa(status);
}
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 32);
#else
@ -3241,12 +3375,14 @@ static void ssl_calc_finished_tls_sha256(
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
return 0;
}
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_calc_finished_tls_sha384(
static int ssl_calc_finished_tls_sha384(
mbedtls_ssl_context *ssl, unsigned char *buf, int from)
{
int len = 12;
@ -3277,13 +3413,13 @@ static void ssl_calc_finished_tls_sha384(
status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed"));
return;
return mbedtls_ssl_md_error_from_psa(status);
}
status = psa_hash_finish(&sha384_psa, padbuf, sizeof(padbuf), &hash_size);
if (status != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed"));
return;
return mbedtls_ssl_md_error_from_psa(status);
}
MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 48);
#else
@ -3328,6 +3464,8 @@ static void ssl_calc_finished_tls_sha384(
mbedtls_platform_zeroize(padbuf, sizeof(padbuf));
MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished"));
return 0;
}
#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@ -3422,7 +3560,12 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl)
mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate);
ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint);
ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4,
ssl->conf->endpoint);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
return ret;
}
/*
* RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
@ -3551,7 +3694,11 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl)
#endif
hash_len = 12;
ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1);
if (ret != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret);
goto exit;
}
if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
@ -4617,49 +4764,6 @@ void mbedtls_ssl_conf_curves(mbedtls_ssl_config *conf,
}
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
{
/* Initialize to suppress unnecessary compiler warning */
size_t hostname_len = 0;
/* Check if new hostname is valid before
* making any change to current one */
if (hostname != NULL) {
hostname_len = strlen(hostname);
if (hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
}
/* Now it's clear that we will overwrite the old hostname,
* so we can free it safely */
if (ssl->hostname != NULL) {
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
mbedtls_free(ssl->hostname);
}
/* Passing NULL as hostname shall clear the old one */
if (hostname == NULL) {
ssl->hostname = NULL;
} else {
ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
if (ssl->hostname == NULL) {
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
}
memcpy(ssl->hostname, hostname, hostname_len);
ssl->hostname[hostname_len] = '\0';
}
return 0;
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
void mbedtls_ssl_conf_sni(mbedtls_ssl_config *conf,
int (*f_sni)(void *, mbedtls_ssl_context *,
@ -6816,10 +6920,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl)
}
#if defined(MBEDTLS_X509_CRT_PARSE_C)
if (ssl->hostname != NULL) {
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
mbedtls_free(ssl->hostname);
}
mbedtls_ssl_free_hostname(ssl);
#endif
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
@ -7559,17 +7660,8 @@ exit:
if (status != PSA_SUCCESS) {
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
switch (status) {
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
case PSA_ERROR_BUFFER_TOO_SMALL:
return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
case PSA_ERROR_INSUFFICIENT_MEMORY:
return MBEDTLS_ERR_MD_ALLOC_FAILED;
default:
return MBEDTLS_ERR_MD_HW_ACCEL_FAILED;
}
return mbedtls_ssl_md_error_from_psa(status);
}
return 0;
}

View file

@ -486,6 +486,9 @@ static const char * const features[] = {
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
"MBEDTLS_SSL_ASYNC_PRIVATE",
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
"MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME",
#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
"MBEDTLS_SSL_CONTEXT_SERIALIZATION",
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */