Compare commits

...

26 Commits

Author SHA1 Message Date
v1rtu3x
88f98f1b0d
Merge c4a5ad3f126b6bc27b92d296c32565623b80015f into 03e1438089654fb884ac48e0f3cd0049cfe2c102 2026-10-27 10:46:03 -04:00
Gilles Peskine
03e1438089
Merge pull request #10926 from bjwtaylor/tl13-transform-resource-leak
Fix resource leak in populate transform
2026-10-27 12:34:54 +00:00
Valerio Setti
cac9589a97
Merge pull request #10654 from bjwtaylor/no-program-failure
Add fix for -DENABLE_PROGRAMS=OFF build error
2026-10-21 15:41:31 +00:00
Gilles Peskine
159d6120cf
Merge pull request #10974 from MechatronikMonkey/fix-empty-authority-key-id
x509_crt: accept empty AuthorityKeyIdentifier sequence
2026-10-21 15:12:30 +00:00
Gilles Peskine
cb6f98ee6f
Merge pull request #10833 from nvxbug/tls12-handshake-len-bounds
Fix off-by-one over-read in TLS 1.2 ClientHello and CertificateRequest
2026-10-21 15:08:28 +00:00
Gilles Peskine
270eea420e
Merge pull request #11008 from v1rtu3x/fix-x509-basic-constraints-integer-first
x509: Accept basic Constraints with omitted CA
2026-10-21 15:07:39 +00:00
Valerio Setti
d2d82feb11
Merge pull request #10972 from rohankl-arm/mldsa-899
MLDSA support: pqcp include path and mldsa key slot component test
2026-10-20 14:04:33 +00:00
v1rtu3x
1b3bbfd4a2 tests: Clarify pathLenConstraint values in test descriptions
Signed-off-by: v1rtu3x <149050962+v1rtu3x@users.noreply.github.com>
2026-10-20 11:50:52 +03:00
Rohan Luchmun
74497a9fe5 Updated framework and tf-psa-crypto submodule pointers
Signed-off-by: Rohan Luchmun <Rohan.Luchmun@arm.com>
2026-10-19 14:36:36 +01:00
Rohan Luchmun
4972da7059 Removed explicit include path from consistency check
Signed-off-by: Rohan Luchmun <Rohan.Luchmun@arm.com>
2026-10-19 14:12:30 +01:00
Rohan Luchmun
7f9525b141 Removed static key slot component test
Signed-off-by: Rohan Luchmun <Rohan.Luchmun@arm.com>
2026-10-19 14:12:27 +01:00
Rohan Luchmun
d23fcce12c Removed debugging print
Signed-off-by: Rohan Luchmun <Rohan.Luchmun@arm.com>
2026-10-19 14:11:16 +01:00
Rohan Luchmun
662ffe3141 Added pqcp to include path
Signed-off-by: Rohan Luchmun <Rohan.Luchmun@arm.com>
2026-10-19 14:11:16 +01:00
v1rtu3x
62dd8a556c x509: Accept basicConstraints with omitted cA
RFC 5280 defines cA as BOOLEAN DEFAULT FALSE, so a basicConstraints
extension containing only pathLenConstraint (SEQUENCE { INTEGER n })
is syntactically valid and must be interpreted as cA=FALSE. The fix
for CVE-2026-49300 rejected this encoding outright, breaking
compatibility with certificates emitted by devices such as
Eaton/CODESYS PLCs.

Tolerate MBEDTLS_ERR_ASN1_UNEXPECTED_TAG from the cA BOOLEAN parse,
keeping cA FALSE and letting the existing INTEGER parser validate
pathLenConstraint. The INTEGER value is never used to determine cA,
so the CVE fix is preserved.

Fixes #11006

Signed-off-by: v1rtu3x <149050962+v1rtu3x@users.noreply.github.com>
2026-10-16 13:53:40 +03:00
Ben Taylor
e0766f1b4a Add comment explaining the derivation of the number of keys
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-10-12 14:08:14 +01:00
Ben Taylor
f0435600c0 Add ChangeLog for transform resource leak
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-10-12 14:08:14 +01:00
Ben Taylor
113010a9d6 Add fix for transform setup resource leak
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-10-12 14:08:14 +01:00
Ben Taylor
4006e94e21 Add test for tansform setup resource leak
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-10-12 14:08:14 +01:00
Christopher Müller
16bd0ff4c6 Add ChangeLog entry for empty AuthorityKeyIdentifier
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Christopher Müller <chris@mechatronikmonkey.de>
2026-09-26 10:27:11 +02:00
Christopher Müller
10e40b70ad tests: x509parse: add empty and truncated AuthorityKeyIdentifier tests
An empty AuthorityKeyIdentifier SEQUENCE must parse. A [0] tag without
a length must still be rejected; that case already passed before the
fix and guards against loosening the check too much.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Christopher Müller <chris@mechatronikmonkey.de>
2026-09-26 10:27:11 +02:00
Christopher Müller
6c9478b2ed x509_crt: accept empty AuthorityKeyIdentifier sequence
All fields of AuthorityKeyIdentifier are OPTIONAL, so an empty SEQUENCE
(30 00) is syntactically valid. It was rejected with
MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_OUT_OF_DATA,
because mbedtls_asn1_get_tag() reports OUT_OF_DATA rather than
UNEXPECTED_TAG when there is nothing left to parse.

Check for the empty sequence explicitly instead of treating OUT_OF_DATA
as an absent keyIdentifier: OUT_OF_DATA is also returned for a [0] tag
with a missing or truncated length, which must still be rejected.

Fixes #10253.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Christopher Müller <chris@mechatronikmonkey.de>
2026-09-26 10:27:10 +02:00
Naveed
77343dc0e5 rework handshake length checks per review
ClientHello: narrow the session-id check to the session id itself, check
the cookie length byte before reading it, and let the ciphersuite-list
length check cover both transports.

CertificateRequest: make the signature-algorithms check also reserve the
two certificate-authorities length bytes instead of adding a separate
check, use the available < needed pattern throughout, and reject an
odd-length signature-algorithms list.

Add injected truncated-ClientHello test cases (TLS 1.2-only builds).

Signed-off-by: Naveed <naveed@bugqore.com>
2026-08-07 15:48:03 +05:30
Naveed
a0053fe8a9 bound two-byte length reads in tls 1.2 handshake parsing
Signed-off-by: Naveed <naveed@bugqore.com>
2026-07-15 18:01:32 +05:30
Ben Taylor
f37696d87f Update Changelog
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-06-30 15:36:19 +01:00
Ben Taylor
9ac82ec38c Add changelog
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-06-30 15:36:19 +01:00
Ben Taylor
a8375cf065 Add fix for -DENABLE_PROGRAMS=OFF build error
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-06-30 15:36:19 +01:00
19 changed files with 275 additions and 56 deletions

View File

@ -0,0 +1,2 @@
Bugfix
* Fix failure of cmake -DENABLE_PROGRAMS=OFF. Fixes #10587.

View File

@ -0,0 +1,10 @@
Bugfix
* Fix a buffer over-read when parsing a TLS 1.2 ClientHello or
CertificateRequest that is truncated inside the two-byte length field
of the ciphersuite list (server side) or of the certificate
authorities list (client side): the length checks preceding those
fields reserved too few bytes, so the length field could be read past
the end of the message. Such messages are now rejected before the
read.
* The TLS 1.2 client now rejects a CertificateRequest message whose
supported_signature_algorithms list has an odd length.

View File

@ -0,0 +1,4 @@
Bugfix
* Fix a resource leak in TLS 1.3 transform setup when importing the
decryption traffic key fails after the encryption traffic key has already
been imported. Fixes #10917.

View File

@ -0,0 +1,5 @@
Bugfix
* Accept a basicConstraints extension that omits cA and contains only
pathLenConstraint, interpreting it as cA=FALSE as specified by RFC 5280.
This restores compatibility with certificates emitted by some devices
without accepting them as CA certificates. Fixes #11006.

View File

@ -0,0 +1,7 @@
Bugfix
* Accept X.509 certificates whose AuthorityKeyIdentifier extension is an
empty SEQUENCE. All of its fields are optional, so such certificates
are syntactically valid, but they were rejected with
MBEDTLS_ERR_X509_INVALID_EXTENSIONS. This affected, for example, the
root certificate that some antivirus products install for HTTPS
scanning. Reported by CodingMarkus. Fixes #10253.

@ -1 +1 @@
Subproject commit 7d726d145d678aa7f5a7df3b9e7ee3dbce6ea1bf
Subproject commit ced31491c5ec907a6be533512f19dc1779230ac1

View File

@ -2217,7 +2217,7 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
buf = ssl->in_msg;
/* certificate_types */
if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl)) {
if (ssl->in_hslen < mbedtls_ssl_hs_hdr_len(ssl) + 1) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
@ -2227,16 +2227,10 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
n = cert_type_len;
/*
* In the subsequent code there are two paths that read from buf:
* * the length of the signature algorithms field (if minor version of
* SSL is 3),
* * distinguished name length otherwise.
* Both reach at most the index:
* ...hdr_len + 2 + n,
* therefore the buffer length at this point must be greater than that
* regardless of the actual code path.
* The two-byte supported_signature_algorithms length is read next,
* at offset ...hdr_len + 1 + n.
*/
if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 2 + n) {
if (ssl->in_hslen < mbedtls_ssl_hs_hdr_len(ssl) + 1 + n + 2) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
@ -2247,18 +2241,13 @@ static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
sig_alg_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n);
/*
* The furthest access in buf is in the loop few lines below:
* sig_alg[i + 1],
* where:
* sig_alg = buf + ...hdr_len + 3 + n,
* max(i) = sig_alg_len - 1.
* Therefore the furthest access is:
* buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
* which reduces to:
* buf[...hdr_len + 3 + n + sig_alg_len],
* which is one less than we need the buf to be.
* The list is a sequence of two-byte values, so its length must be
* even. The message must have room for the list itself, plus the
* two-byte certificate_authorities length that follows it and is
* read below.
*/
if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 3 + n + sig_alg_len) {
if (sig_alg_len % 2 != 0 ||
ssl->in_hslen < mbedtls_ssl_hs_hdr_len(ssl) + 1 + n + 2 + sig_alg_len + 2) {
MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
mbedtls_ssl_send_alert_message(
ssl,

View File

@ -1016,7 +1016,7 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
sess_len = buf[34];
if (sess_len > sizeof(ssl->session_negotiate->id) ||
sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */
sess_len + 35 > msg_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_DECODE_ERROR);
@ -1037,9 +1037,16 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
cookie_offset = 35 + sess_len;
if (cookie_offset + 1 > msg_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_DECODE_ERROR);
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
cookie_len = buf[cookie_offset];
if (cookie_offset + 1 + cookie_len + 2 > msg_len) {
if (cookie_offset + 1 + cookie_len > msg_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_DECODE_ERROR);
@ -1085,6 +1092,16 @@ static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
#endif /* MBEDTLS_SSL_PROTO_DTLS */
ciph_offset = 35 + sess_len;
/* The two-byte ciphersuite list length field must be within the
* message: the checks above only guarantee that the fields before it
* (session id, and for DTLS the cookie) are. */
if (ciph_offset + 2 > msg_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_DECODE_ERROR);
return MBEDTLS_ERR_SSL_DECODE_ERROR;
}
ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset);
if (ciph_len < 2 ||

View File

@ -1077,6 +1077,8 @@ int mbedtls_ssl_tls13_populate_transform(
&transform->psa_key_dec)) != PSA_SUCCESS) {
MBEDTLS_SSL_DEBUG_RET(
1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
psa_destroy_key(transform->psa_key_enc);
transform->psa_key_enc = MBEDTLS_SVC_KEY_ID_INIT;
return PSA_TO_MBEDTLS_ERR(status);
}
}

View File

@ -518,17 +518,19 @@ static int x509_get_basic_constraints(unsigned char **p,
}
if ((ret = mbedtls_asn1_get_bool(p, end, ca_istrue)) != 0) {
/* If the SEQUENCE starts with an INTEGER and not a BOOLEAN,
* according to RFC 5280, it's syntactically valid, but it's
* something that a CA MUST NOT produce. So we reject it.
/* cA is DEFAULT FALSE. If it is absent, the first element must
* be pathLenConstraint. Keep cA false and let the INTEGER parser
* below validate the element.
*
* Note: historically, from XySSL 0.9 to Mbed TLS 3.6.6/4.1.0,
* `SEQUENCE { INTEGER n }` was interpreted as cA=FALSE if n == 0
* and cA=TRUE if n != 0. This was dangerous since
* `SEQUENCE { INTEGER n }` should be parsed as cA=FALSE
* according to RFC 5280, so we stopped doing it.
* according to RFC 5280.
*/
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
}
}
/* `SEQUENCE { BOOLEAN FALSE }` is not DER since default-value fields
* must be omitted in DER. But it seems harmless, and Mbed TLS has
@ -638,6 +640,11 @@ static int x509_get_authority_key_id(unsigned char **p,
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
}
/* All fields are OPTIONAL, so an empty SEQUENCE is valid. */
if (*p == end) {
return 0;
}
ret = mbedtls_asn1_get_tag(p, end, &len,
MBEDTLS_ASN1_CONTEXT_SPECIFIC);

View File

@ -66,7 +66,9 @@ if(GEN_FILES)
add_custom_target(handshake-generated.sh
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/opt-testcases/handshake-generated.sh)
set_target_properties(handshake-generated.sh PROPERTIES EXCLUDE_FROM_ALL NO)
if(ENABLE_PROGRAMS)
add_dependencies(${ssl_opt_target} handshake-generated.sh)
endif()
add_custom_command(
OUTPUT
@ -79,10 +81,12 @@ if(GEN_FILES)
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/../framework/scripts/generate_tls13_compat_tests.py
)
if(ENABLE_PROGRAMS)
add_custom_target(tls13-compat.sh
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/opt-testcases/tls13-compat.sh)
set_target_properties(tls13-compat.sh PROPERTIES EXCLUDE_FROM_ALL NO)
add_dependencies(${ssl_opt_target} tls13-compat.sh)
endif()
else()
foreach(file ${all_generated_data_files})

View File

@ -34,27 +34,6 @@ component_test_psa_assume_exclusive_buffers () {
make test
}
component_test_crypto_with_static_key_slots() {
msg "build: crypto full + MBEDTLS_PSA_STATIC_KEY_SLOTS"
scripts/config.py crypto_full
scripts/config.py set MBEDTLS_PSA_STATIC_KEY_SLOTS
# Intentionally set MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE to a value that
# is enough to contain:
# - all RSA public keys up to 4096 bits (max of PSA_VENDOR_RSA_MAX_KEY_BITS).
# - RSA key pairs up to 1024 bits, but not 2048 or larger.
# - all FFDH key pairs and public keys up to 8192 bits (max of PSA_VENDOR_FFDH_MAX_KEY_BITS).
# - all EC key pairs and public keys up to 521 bits (max of PSA_VENDOR_ECC_MAX_CURVE_BITS).
scripts/config.py set MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE 1212
# Disable the fully dynamic key store (default on) since it conflicts
# with the static behavior that we're testing here.
scripts/config.py unset MBEDTLS_PSA_KEY_STORE_DYNAMIC
msg "test: crypto full + MBEDTLS_PSA_STATIC_KEY_SLOTS"
CC=$ASAN_CC cmake -D CMAKE_BUILD_TYPE:String=Asan .
cmake --build .
ctest
}
# check_renamed_symbols HEADER LIB
# Check that if HEADER contains '#define MACRO ...' then MACRO is not a symbol
# name in LIB.

View File

@ -59,6 +59,7 @@ from mbedtls_framework import c_build_helper
from mbedtls_framework import crypto_knowledge
from mbedtls_framework import psa_information
class Colors: # pylint: disable=too-few-public-methods
"""Minimalistic support for colored output.
Each field of an object of this class is either None if colored output
@ -188,15 +189,13 @@ If what is False, announce that the job has failed.'''
header += f'defined({option})\n'
header += f'#error "{option}"\n'
header += '#endif\n'
include_path = ['include', 'tf-psa-crypto/include',
'tf-psa-crypto/drivers/builtin/include']
try:
# Generate a C file, build and run it
c_file, c_name, exe_name = c_build_helper.create_c_file(self.name)
c_build_helper.generate_c_file(c_file, 'depends.py', header, lambda x: '')
c_file.close()
c_build_helper.compile_c_file(c_name, exe_name, include_path)
c_build_helper.compile_c_file(c_name, exe_name)
return True
except c_build_helper.CompileError as e:

View File

@ -2856,6 +2856,9 @@ SSL TLS 1.3 Record Encryption RFC 8448 Example #2
depends_on:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_GCM:PSA_WANT_ALG_SHA_256
ssl_tls13_record_protection:MBEDTLS_TLS1_3_AES_128_GCM_SHA256:MBEDTLS_SSL_IS_SERVER:1:1:"9f02283b6c9c07efc26bb9f2ac92e356":"cf782b88dd83549aadf1e984":"17422dda596ed5d9acd890e3c63f5051":"5b78923dee08579033e523d9":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031":"2e937e11ef4ac740e538ad36005fc4a46932fc3225d05f82aa1b36e30efaf97d90e6dffc602dcb501a59a8fcc49c4bf2e5f0a21c0047c2abf332540dd032e167c2955d"
TLS 1.3 transform frees encryption key if decryption key import fails
ssl_tls13_populate_transform_second_key_import_failure
SSL TLS 1.3 Key schedule: Application secrets derivation helper
# Vector from RFC 8448
depends_on:PSA_WANT_ALG_SHA_256

View File

@ -8,6 +8,7 @@
#endif /* MBEDTLS_PK_HAVE_PRIVATE_HEADER */
#include <ssl_tls13_keys.h>
#include <ssl_tls13_invasive.h>
#include <psa_crypto_slot_management.h>
#include <test/ssl_helpers.h>
#include <test/ssl_helpers_internal.h>
@ -36,6 +37,35 @@
#define TEST_SSL_CONTEXT_LOAD_OOB_IN_CID 0
#define TEST_SSL_CONTEXT_LOAD_OOB_OUT_CID 1
#define TEST_SSL_CONTEXT_LOAD_OOB_ALPN 2
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_SSL_CLI_C) && \
defined(MBEDTLS_PSA_CRYPTO_C)
#define SSL_TEST_KEY_SLICE_1_LENGTH 4
#define SSL_TEST_KEY_SLICE_2_LENGTH 10
static size_t ssl_test_tiny_key_slice_length(size_t slice_idx)
{
switch (slice_idx) {
case 1: return SSL_TEST_KEY_SLICE_1_LENGTH;
case 2: return SSL_TEST_KEY_SLICE_2_LENGTH;
default: return 1;
}
}
/* In the below definition SSL_TEST_KEY_SLICE_1_LENGTH has 4 slots and
* SSL_TEST_KEY_SLICE_2_LENGTH has 10 all other slices have 1.
* psa_key_slot_volatile_slice_count() returns the total number of slices.
* However we have already countes slices 1 and 2, so we mustr subtract 2 from
* this number to avoid double counting.
*/
#define SSL_TEST_MAX_VOLATILE_KEYS \
(SSL_TEST_KEY_SLICE_1_LENGTH + \
SSL_TEST_KEY_SLICE_2_LENGTH + \
psa_key_slot_volatile_slice_count() - 2)
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_SSL_CLI_C */
#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
#define SSL_TEST_MAX_VOLATILE_KEYS MBEDTLS_PSA_KEY_SLOT_COUNT
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_SSL_SESSION_TICKETS) && \
@ -2489,6 +2519,85 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:SSL_TEST_MAX_VOLATILE_KEYS:MBEDTLS_PSA_CRYPTO_C */
void ssl_tls13_populate_transform_second_key_import_failure(void)
{
mbedtls_ssl_key_set traffic_keys;
mbedtls_ssl_transform transform;
mbedtls_svc_key_id_t *keys = NULL;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_psa_stats_t stats_before, stats_after;
psa_status_t status = PSA_SUCCESS;
size_t i = 0;
memset(&traffic_keys, 0, sizeof(traffic_keys));
mbedtls_ssl_transform_init(&transform);
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
mbedtls_test_hook_psa_volatile_key_slice_length =
ssl_test_tiny_key_slice_length;
#endif
PSA_INIT();
TEST_CALLOC(keys, SSL_TEST_MAX_VOLATILE_KEYS + 1);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
/* Allow one more attempt than the maximum number of volatile keys so
* that the loop ends because the key store is full. */
while (i <= SSL_TEST_MAX_VOLATILE_KEYS) {
status = psa_import_key(&attributes,
(const uint8_t *) &i, sizeof(i),
&keys[i]);
if (status == PSA_ERROR_INSUFFICIENT_MEMORY) {
break;
}
PSA_ASSERT(status);
i++;
}
TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
TEST_ASSERT(i > 0);
/* Leave exactly one slot free: the encryption key import consumes it,
* then the decryption key import fails. */
PSA_ASSERT(psa_destroy_key(keys[--i]));
keys[i] = MBEDTLS_SVC_KEY_ID_INIT;
mbedtls_psa_get_stats(&stats_before);
traffic_keys.key_len = 16;
traffic_keys.iv_len = 12;
TEST_ASSERT(mbedtls_ssl_tls13_populate_transform(
&transform, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_TLS1_3_AES_128_GCM_SHA256,
&traffic_keys, NULL) != 0);
/* The first import must be rolled back when the second one fails. */
TEST_ASSERT(mbedtls_svc_key_id_is_null(transform.psa_key_enc));
/* Also check the key store itself: the failed operation must neither
* consume a slot nor leave the only free slot unusable. */
mbedtls_psa_get_stats(&stats_after);
TEST_EQUAL(stats_after.volatile_slots, stats_before.volatile_slots);
TEST_EQUAL(stats_after.empty_slots, stats_before.empty_slots);
PSA_ASSERT(psa_import_key(&attributes,
(const uint8_t *) &i, sizeof(i),
&keys[i]));
i++;
exit:
mbedtls_ssl_transform_free(&transform);
while (i > 0) {
psa_destroy_key(keys[--i]);
}
mbedtls_free(keys);
PSA_DONE();
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
mbedtls_test_hook_psa_volatile_key_slice_length = NULL;
#endif
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3 */
void ssl_tls13_key_evolution(int hash_alg,
data_t *secret,

View File

@ -63,6 +63,26 @@ Inject ClientHello - TLS 1.2 unknown ciphersuite (for reference)
depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_GCM:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_1
inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303002f0100002b03030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef000002cccc01000000":"got no ciphersuites in common":MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE
# See "ClientHello breakdown" above
# ClientHello body ending right after the session id: version (2) +
# random (32) + session id length (1) + session id (3) = 38 bytes, the
# minimum accepted, with the ciphersuite list length field missing
# entirely. Only run in TLS 1.2-only builds: when TLS 1.3 is enabled,
# the TLS 1.3 code parses the ClientHello first and rejects it itself.
Inject ClientHello - TLS 1.2 truncated after session id
depends_on:MBEDTLS_SSL_PROTO_TLS1_2:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_GCM:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_1
inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303002a0100002603030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef035f5f5f":"bad client hello message":MBEDTLS_ERR_SSL_DECODE_ERROR
# See "ClientHello breakdown" above
# ClientHello body ending inside the ciphersuite list length: version (2) +
# random (32) + session id length (1) + session id (2) + first length
# byte (1) = 38 bytes. Reading the full two-byte length field used to
# over-read one byte past the end of the message.
# Only run in TLS 1.2-only builds, see above.
Inject ClientHello - TLS 1.2 truncated inside ciphersuite list length
depends_on:MBEDTLS_SSL_PROTO_TLS1_2:!MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED:PSA_WANT_KEY_TYPE_AES:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_GCM:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384:PSA_WANT_ALG_SHA_1
inject_client_content_on_the_wire:MBEDTLS_PK_ECDSA:MBEDTLS_SSL_CLIENT_HELLO:"160303002a0100002603030123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef025f5f00":"bad client hello message":MBEDTLS_ERR_SSL_DECODE_ERROR
# See "ClientHello breakdown" above
# ephemeral with secp256r1 + MBEDTLS_TLS1_3_AES_128_GCM_SHA256
Inject ClientHello - TLS 1.3 good (for reference)

View File

@ -2062,11 +2062,27 @@ mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-c
X509 CRT ASN1: basicConstraints: no cA but pathLenConstraint (bad signature)
depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.badsign.crt":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):0
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.badsign.crt":0:1
X509 CRT ASN1: basicConstraints: no cA, pathLenConstraint=1
depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
mbedtls_x509_get_ca_istrue:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.badsign.crt":0
X509 CRT ASN1: basicConstraints: no cA but pathLenConstraint (good self signature)
depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.selfsigned.crt":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):0
mbedtls_x509_crt_parse_file:"../framework/data_files/parse_input/server5.basic-constraints-integer-first.selfsigned.crt":0:1
X509 CRT ASN1: basicConstraints: no cA but pathLenConstraint=0
depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff04053003020100300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":0:0:0
X509 CRT ASN1: basicConstraints: invalid cA BOOLEAN length
depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff040530030100ff300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_INVALID_LENGTH):0:0
X509 CRT ASN1: basicConstraints: neither cA nor pathLenConstraint
depends_on:PSA_HAVE_ALG_ECDSA_VERIFY:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff04053003050100300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):0:0
X509 CRT ASN1 (TBS, inv extBasicConstraint, no pathlen length)
depends_on:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:PSA_WANT_ALG_SHA_256
@ -3471,6 +3487,30 @@ X509 CRT parse Authority Key Id - Wrong Issuer sequence
depends_on:PSA_WANT_ALG_MD5:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
x509_crt_parse_authoritykeyid:"../framework/data_files/clusterfuzz-testcase-minimized-fuzz_x509crt-6666050834661376.crt.der":"":"":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_OUT_OF_DATA)
# Self-signed certificate whose AuthorityKeyIdentifier is an empty SEQUENCE (30 00).
# All fields of AuthorityKeyIdentifier are OPTIONAL in the ASN.1 module (RFC 5280,
# Appendix A.2), so this is syntactically valid; some antivirus products install
# such a root for HTTPS scanning. Generated with Python cryptography:
# key = ec.generate_private_key(ec.SECP256R1())
# name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "Test")])
# cert = (x509.CertificateBuilder().subject_name(name).issuer_name(name)
# .public_key(key.public_key()).serial_number(1)
# .not_valid_before(datetime.datetime(2025, 1, 1))
# .not_valid_after(datetime.datetime(2035, 1, 1))
# .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
# .add_extension(x509.UnrecognizedExtension(ObjectIdentifier("2.5.29.35"),
# b"\x30\x00"), critical=False)
# .sign(key, hashes.SHA256()))
X509 CRT parse Authority Key Id - Empty sequence
depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
x509parse_crt:"3082012b3081d1a003020102020101300a06082a8648ce3d040302300f310d300b06035504030c0454657374301e170d3235303130313030303030305a170d3335303130313030303030305a300f310d300b06035504030c04546573743059301306072a8648ce3d020106082a8648ce3d03010703420004f8cf6bd9eb57f5fdc8771103e9f75becb6a865b1a5de8492b3233170f49e1ff388d25d24376d130c86a8acb5b0478d7c49b83f07ffbd0684c26a0da42c752256a31e301c300f0603551d130101ff040530030101ff30090603551d2304023000300a06082a8648ce3d0403020349003046022100cffb50bdb73287649de96d4c48fcbb5d6e1eb468c72c5016776a9fdf0dc3d295022100e1b4b7ecba9ca1b43882a688c6fd93ffc99112247cf3ebb852b07f09d7c76be2":"cert. version \: 3\nserial number \: 01\nissuer name \: CN=Test\nsubject name \: CN=Test\nissued on \: 2025-01-01 00\:00\:00\nexpires on \: 2035-01-01 00\:00\:00\nsigned using \: ECDSA with SHA256\nEC key size \: 256 bits\nbasic constraints \: CA=true\n":0
# Generated the same way as above, with extension value b"\x30\x01\x80":
# a [0] tag without a length. This must still be rejected.
X509 CRT parse Authority Key Id - Truncated keyIdentifier
depends_on:PSA_HAVE_ALG_SOME_ECDSA:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_SHA_256
x509parse_crt:"3082012b3081d2a003020102020101300a06082a8648ce3d040302300f310d300b06035504030c0454657374301e170d3235303130313030303030305a170d3335303130313030303030305a300f310d300b06035504030c04546573743059301306072a8648ce3d020106082a8648ce3d03010703420004eba1e439f91038837190c4da3703001dff24411b90bf6998f56cba76c753c19ca9158f3c243ccb2118f8b6a78b6eb507962e855bf7c13dbafc314dc56d5d27d8a31f301d300f0603551d130101ff040530030101ff300a0603551d230403300180300a06082a8648ce3d040302034800304502205443c61342f55d3d4cec26df92b7614a5e67177f057efd4f6fb9d7a1a47f5d110221008f05c4c193e203d78a322455132f1b4428388904874dd329fc60a68a37a559b4":"":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, MBEDTLS_ERR_ASN1_OUT_OF_DATA)
OID get numeric string - hardware module name
oid_get_numeric_string:"2B06010505070804":0:"1.3.6.1.5.5.7.8.4"

View File

@ -1127,6 +1127,28 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
void x509_crt_parse_basic_constraints(data_t *buf, int result,
int ca_istrue, int path_len_constraint)
{
mbedtls_x509_crt crt;
mbedtls_x509_crt_init(&crt);
USE_PSA_INIT();
TEST_EQUAL(mbedtls_x509_crt_parse_der(&crt, buf->x, buf->len), result);
if (result == 0) {
TEST_EQUAL(mbedtls_x509_crt_get_ca_istrue(&crt), ca_istrue);
/* max_pathlen is 1 higher than pathLenConstraint. */
TEST_EQUAL(crt.max_pathlen, path_len_constraint + 1);
}
exit:
mbedtls_x509_crt_free(&crt);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
void x509parse_crt(data_t *buf, char *result_str, int result)
{

@ -1 +1 @@
Subproject commit a22ae75f6f09a9b395454e1182547fa06710f0b3
Subproject commit 607ef78f93568d15d8f9b56d09401b4b9e177f93