Compare commits

...

43 Commits

Author SHA1 Message Date
Johnson Ajibi
a74a627ee8
Merge 968cc72440ef4bca300e55dd86405362d67d0be8 into 4fdb917aae2fb5876e04f88621630712a906a067 2026-10-27 10:46:19 -04:00
Gilles Peskine
4fdb917aae
Merge pull request #10966 from bjwtaylor/tl13-transform-resource-leak-3.6
Backport 3.6: Fix resource leak in populate transform
2026-10-27 12:34:56 +00:00
Ben Taylor
afa648aa44 Fix non-PSA TLS 1.3 transform cleanup
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-10-22 11:34:25 +01:00
Valerio Setti
a96c1dffcd
Merge pull request #10655 from bjwtaylor/no-program-failure-3.6
Backport 3.6: Add fix for -DENABLE_PROGRAMS=OFF build error
2026-10-21 15:41:20 +00:00
Gilles Peskine
2a96043825
Merge pull request #10984 from MechatronikMonkey/fix-empty-authority-key-id-3.6
Backport 3.6: x509_crt: accept empty AuthorityKeyIdentifier sequence
2026-10-21 15:12:17 +00:00
Gilles Peskine
c78fb2bb80
Merge pull request #10928 from nvxbug/tls12-handshake-len-bounds-3.6
Backport 3.6: Fix off-by-one over-read in TLS 1.2 ClientHello and CertificateRequest
2026-10-21 15:08:34 +00:00
Gilles Peskine
e7bbfb86ff
Merge pull request #11011 from v1rtu3x/fix-x509-basic-constraints-integer-first-3.6
Fix x509 basic constraints integer first 3.6
2026-10-21 15:07:35 +00:00
v1rtu3x
07192886c1 tests: Clarify pathLenConstraint values in test descriptions
Signed-off-by: v1rtu3x <149050962+v1rtu3x@users.noreply.github.com>
(cherry picked from commit 1b3bbfd4a24b3d3c17cf5ac94c4576bba81f6ce5)
2026-10-21 13:44:32 +03:00
v1rtu3x
5af05a964a 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>
(cherry picked from commit 62dd8a556c01cc289d4fb3f19352a78ede90dac2)
2026-10-21 13:09:57 +03:00
Ben Taylor
23370efdea Add comment explaining the derivation of the number of keys
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
(cherry picked from commit e0766f1b4a2133ea043e10cef86cc1c76f69b49b)
2026-10-21 08:24:45 +01:00
Ben Taylor
ad282114a1 Add ChangeLog for transform resource leak
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
(cherry picked from commit 5b4be7edaffe86553b4875f80c78c3befe4ae618)
2026-10-21 08:24:45 +01:00
Ben Taylor
3626aa2d34 Add fix for transform setup resource leak
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
(cherry picked from commit 0ad86e77b2e73100aa65f5148ea865a12caa87f0)
2026-10-21 08:24:45 +01:00
Ben Taylor
86ba516295 Add test for tansform setup resource leak
This is a manual backport, not a direct cherry-pick, because 3.6 can build TLS without PSA-backed transforms. Gate the regression on MBEDTLS_USE_PSA_CRYPTO.

Signed-off-by: Ben Taylor <ben.taylor@linaro.org>

(cherry picked from commit 95e95268a4c26608612f34f2bb76ff1dfa9ded0a)
2026-10-21 08:24:45 +01:00
Manuel Pégourié-Gonnard
8a04fc0861
Merge pull request #10998 from jan-bruckner/mbedtls-3.6
Backport 3.6: Add linkage guard to constant_time.h
2026-10-16 07:20:38 +00:00
Jan Bruckner
622b850ac5 Add linebreak to changelog entry
Signed-off-by: Jan Bruckner <jan@janbruckner.de>
2026-10-15 15:10:28 +02:00
Manuel Pégourié-Gonnard
e6e126523b
Merge pull request #11000 from mpg/rsa-revert-keygen-hardening-3.6
[3.6] Fix RSA Key Generation performance regression
2026-10-14 11:01:24 +00:00
Manuel Pégourié-Gonnard
b11a53c506
Merge pull request #10996 from subotac/fix/numeric-oid-overflow-3.6
Backport 3.6: Reject overflowing numeric OID components
2026-10-13 09:24:35 +00:00
Manuel Pégourié-Gonnard
e42ac5aafe Add ChangeLog entry for reversal
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-10-09 09:51:00 +02:00
Manuel Pégourié-Gonnard
4344ca4417 Revert "Fix side-channel in prime checking/generation"
This reverts commit 7a29052238b176b02b82d54d9f929fd4c368c008.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-10-09 09:50:47 +02:00
Manuel Pégourié-Gonnard
311c4dff5a Revert "bignum: make small primes product static"
This reverts commit 1a3cfa5fe7c1e4b1702d6f9ea573fa4fa8d84ce4.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-10-09 09:50:47 +02:00
Manuel Pégourié-Gonnard
9585f8201e Revert "bignum: compact primality check for small values"
This reverts commit 075e76b65ba1e25002f60e46460e397462c3667a.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-10-09 09:50:47 +02:00
Manuel Pégourié-Gonnard
ddb5a7d197 Revert "bignum: fix a typo in a comment"
This reverts commit c6a1f9c83899cefd94612b59da682d4d9856a63a.

Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2026-10-09 09:50:47 +02:00
Jan Bruckner
0dcca172bb Add linkage guard to constant_time.h
Signed-off-by: Jan Bruckner <jan@janbruckner.de>
2026-10-08 11:45:04 +02:00
Manuel Pégourié-Gonnard
bd39c1b7c6
Merge pull request #10975 from Johnsonajibi/fix-sha256-4gib-overflow
sha256: fold high bits of ilen into total[1] on 64-bit platforms
2026-10-08 07:03:33 +00:00
subotac
83a9004401 Reject overflowing numeric OID components
Backport of f79eac885dec294d6e441bada15be1605dcb75b0. Adapt the check and tests to the 3.6 OID parser.

Refs Mbed-TLS/mbedtls#10911.

Signed-off-by: subotac <73706465+subotac@users.noreply.github.com>
2026-10-06 23:18:23 +03:00
Manuel Pégourié-Gonnard
27e5c190dc
Merge pull request #10994 from saadgodikat/backport-10973-3.6
[3.6] Fix DER certificate output on Windows
2026-10-06 09:38:27 +00:00
Ronald Cron
8396312553
Merge pull request #10990 from nvxbug/ssl-context-load-alpn-bounds-3.6
Backport 3.6: Reject out-of-bounds ALPN length in ssl_context_load
2026-10-05 11:39:59 +00:00
saadgodikat
955c52b246 Add changelog for DER certificate output fix
Signed-off-by: saadgodikat <saadgodikat601@gmail.com>
2026-10-05 16:19:05 +05:30
saadgodikat
d8fd242a72 Fix DER certificate output on Windows
Fixes #10152

Signed-off-by: saadgodikat <saadgodikat601@gmail.com>
2026-10-05 16:17:00 +05:30
Naveed
ebcb95c130 Add regression tests for ssl_context_load length checks
Backport the ssl_context_load_rejects_oob_length test function from
development in its final form, with cases for the serialized in_cid,
out_cid and ALPN lengths.

mbedtls_test_ssl_dtls_join_endpoints() and
mbedtls_test_ssl_perform_connection() do not exist on this branch, so
set up the DTLS endpoints and run the handshake with the helpers that
do: mbedtls_test_ssl_endpoint_init() with message queues,
mbedtls_test_mock_socket_connect() and
mbedtls_test_move_handshake_to_state(). Exchange application data
explicitly before saving the context, as
mbedtls_test_ssl_perform_connection() does on development: the server
keeps its handshake structure until then, and
mbedtls_ssl_context_save() refuses to run while it exists.

Signed-off-by: Naveed <naveed@bugqore.com>
2026-10-04 22:53:31 +05:30
Naveed
f0e6883dd9 Reject out-of-bounds ALPN length in ssl_context_load
The serialized ALPN length was passed to memcmp() against each configured protocol without checking it against the remaining serialized data, so a malformed context could read past the end of the buffer. Bound it before the comparison, like the adjacent CID fields.

Signed-off-by: Naveed <naveed@bugqore.com>
2026-10-04 22:49:43 +05:30
Christopher Müller
7701d43f47 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-10-03 14:28:29 +02:00
Christopher Müller
a8c0f87bfb 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.

Backport to 3.6: the dependencies use the legacy configuration macros
(MBEDTLS_PK_CAN_ECDSA_SOME, MBEDTLS_ECP_HAVE_SECP256R1,
MBEDTLS_MD_CAN_SHA256) instead of PSA_WANT_*, and the expected error is
written as a sum, like the neighbouring AuthorityKeyIdentifier tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Christopher Müller <chris@mechatronikmonkey.de>
2026-10-03 14:28:29 +02:00
Christopher Müller
955de69ed5 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-10-03 14:28:29 +02:00
Johnson Ajibi
320fd18555 changelog: list every affected API explicitly per review feedback
Previous wording only named the four low-level update() functions
directly touched by the fix. mpg pointed out a normal user calling
mbedtls_md_update(), psa_hash_compare(), or any of the one-shot
wrappers (mbedtls_md5(), mbedtls_sha256(), psa_hash_compute(), etc.)
has no way to tell from that wording whether they are affected, and
that SHA-224 should be listed explicitly even though it shares
mbedtls_sha256_update() under the hood, since that implementation
detail should not be something a ChangeLog reader needs to already
know.

Signed-off-by: Johnson Ajibi <ajibijohnson@gmail.com>
2026-10-02 22:03:47 +01:00
Johnson Ajibi
23a2fa734b md5/sha1/ripemd160: fix the same 4GiB ilen truncation as sha256
Per mpg's review, MD5, SHA-1 and RIPEMD-160 have the exact same bug as
SHA-256: mbedtls_*_update() truncates ilen to its low 32 bits before
adding it to ctx->total[0], and the overflow check right after only
catches the single wraparound of that 32-bit addition -- neither step
folds in bits 32 and up of ilen itself when a single update() call is
passed >= 2^32 bytes on a 64-bit platform.

SHA-512 does not have this bug (confirmed by TimothyPMann and
independently by me): it tracks its 128-bit byte count in two
uint64_t words, so ilen (a 64-bit size_t at most) can never overflow
the low word before the carry-in step even runs.

Applied the identical fix to all three: fold ilen >> 32 into total[1],
guarded on SIZE_MAX so 32-bit platforms are unaffected.

Verified live with the same method as the SHA-256 fix: hashed a real
4GiB + 64 byte file with mbedtls_md5_update()/sha1_update()/
ripemd160_update() in a single call and compared against md5sum(1),
sha1sum(1), and `openssl dgst -rmd160`.

  algorithm    before fix (wrong)                          after fix (matches reference tool)
  MD5          0e8b3fdad1980e2c4e66ef714abc3f0c             8b647773014d9f640da9887274f444cd
  SHA-1        b190a761fceaafdc19b62cbcc729ec22b02e7d0c     703fe5b4441eb203af67ed4fbc20263d44bc5f5c
  RIPEMD-160   68956d1517f2ebcef4761d2c0fddf11331a1e6b6     d14d7e80c32ddc603c677151bfd59fd8cf867c42

Also reworded the ChangeLog entry per feedback to cover all four
functions concisely instead of describing the SHA-256 internals in
detail.

Signed-off-by: Johnson Ajibi <ajibijohnson@gmail.com>
2026-09-30 22:20:09 +01:00
Johnson Ajibi
33a1fa3a2c sha256: fold high bits of ilen into total[1] on 64-bit platforms
mbedtls_sha256_update() tracks the running byte count in a 64-bit
counter split across ctx->total[0]/[1] (32 bits each), used at
finalization to encode the message length into the padding.

ctx->total[0] += (uint32_t) ilen truncates ilen to its low 32 bits
before adding, and the overflow check right after (ctx->total[0] <
(uint32_t) ilen) only detects the single wraparound of that 32-bit
addition. Neither step ever looks at bits 32 and up of ilen itself.
So when a single update() call is passed >= 2^32 bytes on a 64-bit
platform (size_t wider than 32 bits), every byte is correctly hashed
into the message, but the length folded into the final padding block
is wrong by a multiple of 2^32 bytes, producing an incorrect digest
despite no error being returned.

Fold ilen>>32 into total[1] directly, guarded on SIZE_MAX so 32-bit
platforms (where ilen cannot exceed 2^32-1 and the shift would be
UB-adjacent) are unaffected.

Verified live: generated a 4GiB+64 byte random file, hashed it with
mbedtls_sha256_update() in a single call both before and after this
fix, and compared against sha256sum of the same file.
  - before: 803ab176fbafaf3cf345cbe22e2a35715c3ae8f7fbf241a00677d4d733db0214 (wrong)
  - after:  21a1f671cd9797227f341a243fed82c8fe95a769a58a6f3965e958f047e969d6 (matches sha256sum)
Also re-verified normal-sized inputs (empty string, "abc") against
known SHA-256 vectors, and that a two-call split of a 100-byte input
still agrees with a single whole-buffer call.

Fixes #10964.

Signed-off-by: Johnson Ajibi <ajibijohnson@gmail.com>
2026-09-27 09:52:45 +01:00
Naveed
3500aaa3f3 adapt test dependencies to 3.6 macro names
Signed-off-by: Naveed <naveed@bugqore.com>
2026-08-24 21:58:33 +05:30
Naveed
6cffad7e1b 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-24 21:58:01 +05:30
Naveed
94d46cdb00 bound two-byte length reads in tls 1.2 handshake parsing
Signed-off-by: Naveed <naveed@bugqore.com>
2026-08-24 21:58:01 +05:30
Ben Taylor
b21300b7c2 Update Changelog
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-07-02 13:25:38 +01:00
Ben Taylor
f4dbfc21e6 Add changelog
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-07-02 13:25:38 +01:00
Ben Taylor
c606923ce5 Add fix for -DENABLE_PROGRAMS=OFF build error
Signed-off-by: Ben Taylor <ben.taylor@linaro.org>
2026-07-02 13:25:38 +01:00
31 changed files with 664 additions and 92 deletions

View File

@ -0,0 +1,4 @@
Bugfix
* Add extern "C" guard to constant_time.h. Fixes
https://github.com/Mbed-TLS/TF-PSA-Crypto/issues/930.

View File

@ -0,0 +1,3 @@
Bugfix
* Fix corruption of DER certificates generated by the `cert_write`
sample program on Windows. #10152

View File

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

View File

@ -0,0 +1,3 @@
Bugfix
* Reject numeric OID components that exceed the range of unsigned int
instead of silently encoding a different value. Fixes #10910.

View File

@ -0,0 +1,4 @@
Bugfix
* Revert hardening of RSA keygen introduced in the previous release, that
caused an unacceptable performance regression on platforms with higher
memory latency. #10830

View File

@ -0,0 +1,12 @@
Bugfix
* Fix MD5, SHA1, SHA224, SHA256 and RIPEMD160 computing the wrong
digest when 4GiB of data or more are processed in a single call.
That can happen either when using the one-shot APIs
(psa_hash_compute(), psa_hash_compare(), mbedtls_md(),
mbedtls_md5(), mbedtls_sha1(), mbedtls_ripemd160(),
mbedtls_sha256()) with more than 4GiB of input, or when using the
streaming API and passing more than 4GiB in a single call to the
update function (psa_hash_update(), mbedtls_md_update(),
mbedtls_md5_update(), mbedtls_sha1_update(),
mbedtls_ripemd160_update(), mbedtls_sha256_update()). Reported by
TimothyPMann in #10964.

View File

@ -0,0 +1,4 @@
Bugfix
* Reject serialized SSL contexts whose ALPN protocol length exceeds the
remaining serialized data, instead of reading past the end of the buffer
in mbedtls_ssl_context_load().

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 resource leaks in TLS 1.3 transform setup when a setup step fails
after allocating cipher contexts or importing the encryption traffic key.
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.

View File

@ -11,6 +11,10 @@
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Constant-time buffer comparison without branches.
*
* This is equivalent to the standard memcmp function, but is likely to be
@ -33,4 +37,8 @@ int mbedtls_ct_memcmp(const void *a,
const void *b,
size_t n);
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CONSTANT_TIME_H */

View File

@ -2059,38 +2059,30 @@ int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
#if defined(MBEDTLS_GENPRIME)
static const mbedtls_mpi_sint small_primes_limit = 997;
/* Product of small primes up to small_primes_limit included */
static const mbedtls_mpi_uint small_primes_product_limbs[] = {
MBEDTLS_BYTES_TO_T_UINT_8(0x4b, 0x13, 0x6a, 0x97, 0xbb, 0xd0, 0xdf, 0x95),
MBEDTLS_BYTES_TO_T_UINT_8(0xa7, 0x2c, 0x10, 0xa4, 0x20, 0xa4, 0x9f, 0x7b),
MBEDTLS_BYTES_TO_T_UINT_8(0x9d, 0x18, 0xd6, 0xdf, 0xc0, 0xf5, 0x61, 0x65),
MBEDTLS_BYTES_TO_T_UINT_8(0xfc, 0x35, 0x79, 0xfb, 0x30, 0xa8, 0xd5, 0xbf),
MBEDTLS_BYTES_TO_T_UINT_8(0xdb, 0x37, 0xba, 0x2c, 0xfb, 0xbb, 0x89, 0xfb),
MBEDTLS_BYTES_TO_T_UINT_8(0xad, 0xc2, 0x8c, 0x1d, 0x99, 0x18, 0xe8, 0xe5),
MBEDTLS_BYTES_TO_T_UINT_8(0x8d, 0x77, 0xc9, 0x5d, 0x96, 0x8a, 0x61, 0x9d),
MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x41, 0x3e, 0xf4, 0x34, 0x07, 0x57, 0xe0),
MBEDTLS_BYTES_TO_T_UINT_8(0x4a, 0xf1, 0x54, 0x3a, 0x43, 0x67, 0x46, 0xa2),
MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x0c, 0xe5, 0x31, 0xa2, 0xfc, 0x05, 0x45),
MBEDTLS_BYTES_TO_T_UINT_8(0xf0, 0x1d, 0x66, 0xfc, 0x7a, 0x85, 0x37, 0xe1),
MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xe0, 0x80, 0x62, 0x0d, 0xa2, 0xbc, 0x32),
MBEDTLS_BYTES_TO_T_UINT_8(0x6d, 0xce, 0x84, 0x68, 0x00, 0xb5, 0xe3, 0x35),
MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x19, 0x0d, 0xe4, 0x92, 0xd5, 0xd8, 0xdf),
MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x1c, 0x7d, 0x38, 0x3b, 0xe8, 0xd9, 0xa8),
MBEDTLS_BYTES_TO_T_UINT_8(0xf6, 0xac, 0x11, 0xe6, 0xb4, 0x03, 0xf7, 0x6c),
MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x3d, 0xf2, 0x3a, 0x8f, 0xf9, 0x2f, 0x6a),
MBEDTLS_BYTES_TO_T_UINT_8(0x7b, 0x72, 0x66, 0xa9, 0x48, 0xe4, 0x6d, 0x02),
MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xc7, 0x32, 0xcb, 0xf2, 0xf7, 0xa9, 0x0b),
MBEDTLS_BYTES_TO_T_UINT_8(0xd3, 0x52, 0x72, 0x9d, 0xbf, 0x54, 0xea, 0xc7),
MBEDTLS_BYTES_TO_T_UINT_8(0xf5, 0xf3, 0x8a, 0xc5, 0xf0, 0xe1, 0x21, 0x81),
MBEDTLS_BYTES_TO_T_UINT_8(0x8e, 0x61, 0x78, 0xf0, 0x05, 0x00, 0x00, 0x00),
};
/* Could make ECP_MPI_INIT_ARRAY() available outside ecp, but not doing it now
* as it would lead to conflicts with other in-flight PRs. */
static const mbedtls_mpi small_primes_product = {
.p = (mbedtls_mpi_uint *) small_primes_product_limbs,
.s = 1,
.n = sizeof(small_primes_product_limbs) / sizeof(mbedtls_mpi_uint),
/* Gaps between primes, starting at 3. https://oeis.org/A001223 */
static const unsigned char small_prime_gaps[] = {
2, 2, 4, 2, 4, 2, 4, 6,
2, 6, 4, 2, 4, 6, 6, 2,
6, 4, 2, 6, 4, 6, 8, 4,
2, 4, 2, 4, 14, 4, 6, 2,
10, 2, 6, 6, 4, 6, 6, 2,
10, 2, 4, 2, 12, 12, 4, 2,
4, 6, 2, 10, 6, 6, 6, 2,
6, 4, 2, 10, 14, 4, 2, 4,
14, 6, 10, 2, 4, 6, 8, 6,
6, 4, 6, 8, 4, 8, 10, 2,
10, 2, 6, 4, 6, 8, 4, 2,
4, 12, 8, 4, 8, 4, 6, 12,
2, 18, 6, 10, 6, 6, 2, 6,
10, 6, 6, 2, 6, 6, 4, 2,
12, 10, 2, 4, 6, 6, 2, 12,
4, 6, 8, 10, 8, 10, 8, 6,
6, 4, 8, 6, 4, 8, 4, 14,
10, 12, 2, 10, 2, 4, 2, 10,
14, 4, 2, 4, 14, 4, 2, 4,
20, 4, 8, 10, 8, 4, 6, 6,
14, 4, 6, 6, 8, 6, /*reaches 997*/
0 /* the last entry is effectively unused */
};
/*
@ -2105,43 +2097,26 @@ static const mbedtls_mpi small_primes_product = {
static int mpi_check_small_factors(const mbedtls_mpi *X)
{
int ret = 0;
mbedtls_mpi g;
mbedtls_mpi_init(&g);
size_t i;
mbedtls_mpi_uint r;
unsigned p = 3; /* The first odd prime */
if ((X->p[0] & 1) == 0) {
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
/* The GCD test below only works if X > small_primes_limit.
* Below this limit, use trial division: numbers that small are of no
* interest for cryptography, so we don't care about performance or side
* channels. We're supporting them only for backwards compatibility, so
* let's not waste code size on those. */
if (mbedtls_mpi_cmp_int(X, small_primes_limit) <= 0) {
mbedtls_mpi_uint x = X->p[0];
mbedtls_mpi_uint d = 2;
while (x % d != 0) {
++d;
for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));
if (r == 0) {
if (mbedtls_mpi_cmp_int(X, p) == 0) {
return 1;
} else {
return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
}
return x == d ? 1 : MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
/* We can't directly use mbedtls_mpi_gcd_modinv_odd() because we don't know
* if X is larger than prod or not (prod is 1380 bits). So, use this generic
* wrapper - it does a bit more than what we need (handles even inputs as
* well, while we know our inputs are both odd), but that's OK. */
MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&g, &small_primes_product, X));
if (mbedtls_mpi_cmp_int(&g, 1) == 0) {
/* X is not divisible by a small prime */
ret = 0;
} else {
ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
}
cleanup:
mbedtls_mpi_free(&g);
return ret;
}

View File

@ -222,6 +222,10 @@ int mbedtls_md5_update(mbedtls_md5_context *ctx,
ctx->total[1]++;
}
#if SIZE_MAX > 0xFFFFFFFF
ctx->total[1] += (uint32_t) (ilen >> 32);
#endif
if (left && ilen >= fill) {
memcpy((void *) (ctx->buffer + left), input, fill);
if ((ret = mbedtls_internal_md5_process(ctx, ctx->buffer)) != 0) {

View File

@ -995,7 +995,7 @@ static int oid_parse_number(unsigned int *num, const char **p, const char *bound
while (*p < bound && **p >= '0' && **p <= '9') {
ret = 0;
if (*num > (UINT_MAX / 10)) {
if (*num > (UINT_MAX - (unsigned int) (**p - '0')) / 10) {
return MBEDTLS_ERR_ASN1_INVALID_DATA;
}
*num *= 10;

View File

@ -285,6 +285,10 @@ int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
ctx->total[1]++;
}
#if SIZE_MAX > 0xFFFFFFFF
ctx->total[1] += (uint32_t) (ilen >> 32);
#endif
if (left && ilen >= fill) {
memcpy((void *) (ctx->buffer + left), input, fill);

View File

@ -257,6 +257,10 @@ int mbedtls_sha1_update(mbedtls_sha1_context *ctx,
ctx->total[1]++;
}
#if SIZE_MAX > 0xFFFFFFFF
ctx->total[1] += (uint32_t) (ilen >> 32);
#endif
if (left && ilen >= fill) {
memcpy((void *) (ctx->buffer + left), input, fill);

View File

@ -667,6 +667,10 @@ int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
ctx->total[1]++;
}
#if SIZE_MAX > 0xFFFFFFFF
ctx->total[1] += (uint32_t) (ilen >> 32);
#endif
if (left && ilen >= fill) {
memcpy((void *) (ctx->buffer + left), input, fill);

View File

@ -5539,6 +5539,10 @@ static int ssl_context_load(mbedtls_ssl_context *ssl,
alpn_len = *p++;
if ((size_t) (end - p) < alpn_len) {
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
}
if (alpn_len != 0 && ssl->conf->alpn_list != NULL) {
/* alpn_chosen should point to an item in the configured list */
for (cur = ssl->conf->alpn_list; *cur != NULL; cur++) {

View File

@ -2637,7 +2637,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);
@ -2647,16 +2647,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);
@ -2667,18 +2661,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

@ -1049,7 +1049,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);
@ -1070,9 +1070,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);
@ -1118,6 +1125,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

@ -977,6 +977,7 @@ int mbedtls_ssl_tls13_populate_transform(
if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec,
cipher_info)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
mbedtls_ssl_transform_free(transform);
return ret;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
@ -999,6 +1000,9 @@ int mbedtls_ssl_tls13_populate_transform(
#endif /* MBEDTLS_SSL_CLI_C */
{
/* should not happen */
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_ssl_transform_free(transform);
#endif
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
}
@ -1010,6 +1014,7 @@ int mbedtls_ssl_tls13_populate_transform(
key_enc, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info),
MBEDTLS_ENCRYPT)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
mbedtls_ssl_transform_free(transform);
return ret;
}
@ -1017,6 +1022,7 @@ int mbedtls_ssl_tls13_populate_transform(
key_dec, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info),
MBEDTLS_DECRYPT)) != 0) {
MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
mbedtls_ssl_transform_free(transform);
return ret;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
@ -1081,6 +1087,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

@ -519,17 +519,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
@ -639,6 +641,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

@ -235,7 +235,11 @@ static int write_certificate(mbedtls_x509write_cert *crt, const char *output_fil
output_start = output_buf;
}
if ((f = fopen(output_file, "w")) == NULL) {
/*
* DER output is binary data. Use binary mode on Windows to prevent
* text-mode newline translation.
*/
if ((f = fopen(output_file, opt.format == FORMAT_DER ? "wb" : "w")) == NULL) {
return -1;
}

View File

@ -140,7 +140,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
@ -195,8 +197,11 @@ if(GEN_FILES)
)
add_custom_target(tls13-compat.sh
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/opt-testcases/tls13-compat.sh)
if(ENABLE_PROGRAMS)
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

@ -202,6 +202,15 @@ oid_from_numeric_string:"2.4294967215":0:"8FFFFFFF7F"
OID from numeric string - OID with overflowing subidentifier
oid_from_numeric_string:"2.4294967216":MBEDTLS_ERR_ASN1_INVALID_DATA:""
OID from numeric string - numeric component overflows on final digit
oid_from_numeric_string:"2.4294967296":MBEDTLS_ERR_ASN1_INVALID_DATA:""
OID from numeric string - numeric component overflows to nonzero value
oid_from_numeric_string:"2.4294967299":MBEDTLS_ERR_ASN1_INVALID_DATA:""
OID from numeric string - numeric component continues after overflow
oid_from_numeric_string:"2.42949672966":MBEDTLS_ERR_ASN1_INVALID_DATA:""
mbedtls_oid_get_md_hmac - RIPEMD160
depends_on:MBEDTLS_MD_CAN_RIPEMD160
mbedtls_oid_get_md_hmac:"2B06010505080104":MBEDTLS_MD_RIPEMD160

View File

@ -3003,6 +3003,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
@ -3211,6 +3214,18 @@ TLS 1.3: Session serialization rejects ALPN without terminator
depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_SRV_C:MBEDTLS_SSL_EARLY_DATA:MBEDTLS_SSL_ALPN
ssl_session_load_rejects_bad_serialized_data:MBEDTLS_SSL_VERSION_TLS1_3:MBEDTLS_SSL_IS_SERVER:TEST_TLS13_SESSION_LOAD_ALPN_NO_NUL
SSL context serialization rejects out-of-bounds DTLS in_cid length
depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID
ssl_context_load_rejects_oob_length:TEST_SSL_CONTEXT_LOAD_OOB_IN_CID
SSL context serialization rejects out-of-bounds DTLS out_cid length
depends_on:MBEDTLS_SSL_DTLS_CONNECTION_ID
ssl_context_load_rejects_oob_length:TEST_SSL_CONTEXT_LOAD_OOB_OUT_CID
SSL context serialization rejects out-of-bounds ALPN length
depends_on:MBEDTLS_SSL_ALPN
ssl_context_load_rejects_oob_length:TEST_SSL_CONTEXT_LOAD_OOB_ALPN
TLS 1.2: Session serialization rejects out-of-bounds session ID length (client)
depends_on:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_SSL_CLI_C
ssl_session_load_rejects_bad_serialized_data:MBEDTLS_SSL_VERSION_TLS1_2:MBEDTLS_SSL_IS_CLIENT:TEST_TLS12_SESSION_LOAD_OOB_ID_LEN

View File

@ -5,6 +5,7 @@
#include <mbedtls/pk.h>
#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>
@ -29,6 +30,44 @@
#define TEST_TLS13_SESSION_LOAD_ALPN_NO_NUL 2
#define TEST_TLS12_SESSION_LOAD_OOB_ID_LEN 3
/* Corrupted length fields for ssl_context_load_rejects_oob_length */
#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) && defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
#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 &&
MBEDTLS_PSA_CRYPTO_C && MBEDTLS_SSL_PROTO_TLS1_3 &&
MBEDTLS_USE_PSA_CRYPTO */
#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) && \
defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SRV_C) && \
@ -2456,6 +2495,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:MBEDTLS_USE_PSA_CRYPTO */
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,
@ -3010,6 +3128,263 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED:MBEDTLS_PKCS1_V15:MBEDTLS_SSL_PROTO_TLS1_2:MBEDTLS_RSA_C:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_SSL_PROTO_DTLS:MBEDTLS_SSL_CONTEXT_SERIALIZATION:MBEDTLS_MD_CAN_SHA256:MBEDTLS_CAN_HANDLE_RSA_TEST_KEY */
void ssl_context_load_rejects_oob_length(int field)
{
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
/* Sentinel CIDs so we can find their location inside the serialized
* buffer. The server's own CID is serialized as in_cid and the client's
* as out_cid; they have different lengths so that the two fields can be
* told apart. */
const unsigned char server_cid[] = {
0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x9A
};
const unsigned char client_cid[] = {
0x9A, 0x78, 0x56, 0x34, 0x12, 0xEF,
0xCD, 0xAB, 0x10, 0x32, 0x54, 0x76
};
#endif
#if defined(MBEDTLS_SSL_ALPN)
/* The negotiated protocol (alpn[0]) is the last field in the serialized
* context, so exactly strlen(alpn[0]) bytes remain after its length byte.
* On load, ssl_context_load() only memcmp()s configured protocols whose
* strlen() equals the length byte, so the corrupted length has to match a
* configured protocol to reach the memcmp(): alpn[1] is one character
* longer than alpn[0], which makes the corrupted length point exactly one
* byte past the end of the serialized data. It shares alpn[0]'s prefix so
* that all in-bounds bytes match and the memcmp() cannot stop before
* reading past the end of the buffer. */
const char negotiated[] = "alpnsentinel";
const char *alpn[] = { negotiated, "alpnsentinel2", NULL };
#endif
enum { BUFFSIZE = 17000 };
mbedtls_test_handshake_test_options options;
mbedtls_test_ssl_endpoint client_ep, server_ep;
mbedtls_test_ssl_message_queue server_queue, client_queue;
mbedtls_test_message_socket_context server_context, client_context;
#if defined(MBEDTLS_TIMING_C)
mbedtls_timing_delay_context timer_client, timer_server;
#endif
unsigned char *context_buf = NULL;
unsigned char *load_buf = NULL;
size_t context_buf_len, load_len, field_off, i;
const unsigned char *sentinel = NULL;
size_t sentinel_len = 0;
unsigned char corrupt_len = 0;
unsigned char *len_p = NULL;
memset(&client_ep, 0, sizeof(client_ep));
memset(&server_ep, 0, sizeof(server_ep));
mbedtls_test_message_socket_init(&server_context);
mbedtls_test_message_socket_init(&client_context);
MD_OR_USE_PSA_INIT();
mbedtls_test_init_handshake_options(&options);
options.dtls = 1;
options.expected_negotiated_version = MBEDTLS_SSL_VERSION_TLS1_2;
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(
&client_ep, MBEDTLS_SSL_IS_CLIENT, &options,
&client_context, &client_queue, &server_queue), 0);
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(
&server_ep, MBEDTLS_SSL_IS_SERVER, &options,
&server_context, &server_queue, &client_queue), 0);
#if defined(MBEDTLS_TIMING_C)
mbedtls_ssl_set_timer_cb(&client_ep.ssl, &timer_client,
mbedtls_timing_set_delay,
mbedtls_timing_get_delay);
mbedtls_ssl_set_timer_cb(&server_ep.ssl, &timer_server,
mbedtls_timing_set_delay,
mbedtls_timing_get_delay);
#endif
switch (field) {
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
case TEST_SSL_CONTEXT_LOAD_OOB_IN_CID:
case TEST_SSL_CONTEXT_LOAD_OOB_OUT_CID:
/* Each peer's own CID has to fit in MBEDTLS_SSL_CID_IN_LEN_MAX and
* its peer's CID in MBEDTLS_SSL_CID_OUT_LEN_MAX. */
TEST_ASSUME(MBEDTLS_SSL_CID_IN_LEN_MAX >= sizeof(server_cid) &&
MBEDTLS_SSL_CID_IN_LEN_MAX >= sizeof(client_cid));
TEST_ASSUME(MBEDTLS_SSL_CID_OUT_LEN_MAX >= sizeof(server_cid) &&
MBEDTLS_SSL_CID_OUT_LEN_MAX >= sizeof(client_cid));
/* Configure CID with unique patterns so we can locate the length
* bytes in the serialized context. On each peer the length passed
* to conf_cid() must match the one passed to set_cid(). */
TEST_EQUAL(mbedtls_ssl_conf_cid(
&client_ep.conf, sizeof(client_cid),
MBEDTLS_SSL_UNEXPECTED_CID_FAIL), 0);
TEST_EQUAL(mbedtls_ssl_conf_cid(
&server_ep.conf, sizeof(server_cid),
MBEDTLS_SSL_UNEXPECTED_CID_FAIL), 0);
TEST_EQUAL(mbedtls_ssl_set_cid(
&client_ep.ssl, MBEDTLS_SSL_CID_ENABLED,
client_cid, sizeof(client_cid)), 0);
TEST_EQUAL(mbedtls_ssl_set_cid(
&server_ep.ssl, MBEDTLS_SSL_CID_ENABLED,
server_cid, sizeof(server_cid)), 0);
/* The corrupted length is the smallest one that overflows the
* in_cid or out_cid array in the SSL transform, so the size check
* on that array, not the in-buffer bounds check before it, is
* what must reject it. The loaded data gets the field grown to
* this many bytes (see the construction of load_buf below) so
* that the in-buffer bounds check indeed passes. A one-byte
* serialized length cannot overflow a 255-byte CID array. */
if (field == TEST_SSL_CONTEXT_LOAD_OOB_IN_CID) {
TEST_ASSUME(MBEDTLS_SSL_CID_IN_LEN_MAX < 255);
sentinel = server_cid;
sentinel_len = sizeof(server_cid);
corrupt_len = (unsigned char) (MBEDTLS_SSL_CID_IN_LEN_MAX + 1);
} else {
TEST_ASSUME(MBEDTLS_SSL_CID_OUT_LEN_MAX < 255);
sentinel = client_cid;
sentinel_len = sizeof(client_cid);
corrupt_len = (unsigned char) (MBEDTLS_SSL_CID_OUT_LEN_MAX + 1);
}
break;
#endif
#if defined(MBEDTLS_SSL_ALPN)
case TEST_SSL_CONTEXT_LOAD_OOB_ALPN:
/* Offer the same protocol list on both peers so alpn[0] is
* negotiated and serialized into the context. */
TEST_EQUAL(mbedtls_ssl_conf_alpn_protocols(&client_ep.conf, alpn),
0);
TEST_EQUAL(mbedtls_ssl_conf_alpn_protocols(&server_ep.conf, alpn),
0);
sentinel = (const unsigned char *) negotiated;
sentinel_len = strlen(negotiated);
/* One byte past the end of the serialized data; see the
* declaration of alpn[] above. */
corrupt_len = (unsigned char) strlen(alpn[1]);
break;
#endif
default:
TEST_ASSERT(0);
}
TEST_EQUAL(mbedtls_test_mock_socket_connect(&client_ep.socket,
&server_ep.socket,
BUFFSIZE), 0);
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&client_ep.ssl, &server_ep.ssl,
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
/* Make sure server state is moved to HANDSHAKE_OVER also. */
TEST_EQUAL(mbedtls_test_move_handshake_to_state(
&server_ep.ssl, &client_ep.ssl,
MBEDTLS_SSL_HANDSHAKE_OVER), 0);
/* The server keeps its handshake structure around, in case it has to
* resend its last flight, until it receives application data, and
* mbedtls_ssl_context_save() refuses to run while that structure
* exists. */
TEST_EQUAL(mbedtls_test_ssl_exchange_data(
&client_ep.ssl, options.cli_msg_len,
options.expected_cli_fragments,
&server_ep.ssl, options.srv_msg_len,
options.expected_srv_fragments), 0);
#if defined(MBEDTLS_SSL_ALPN)
if (field == TEST_SSL_CONTEXT_LOAD_OOB_ALPN) {
TEST_ASSERT(server_ep.ssl.alpn_chosen != NULL);
TEST_EQUAL(strcmp(server_ep.ssl.alpn_chosen, negotiated), 0);
}
#endif
/* Serialize the post-handshake server context. */
TEST_EQUAL(mbedtls_ssl_context_save(&server_ep.ssl, NULL, 0,
&context_buf_len),
MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL);
TEST_CALLOC(context_buf, context_buf_len);
TEST_EQUAL(mbedtls_ssl_context_save(&server_ep.ssl, context_buf,
context_buf_len, &context_buf_len), 0);
/* Double-check that the serialized data loads cleanly before it gets
* corrupted. */
mbedtls_ssl_free(&server_ep.ssl);
mbedtls_ssl_init(&server_ep.ssl);
TEST_EQUAL(mbedtls_ssl_setup(&server_ep.ssl, &server_ep.conf), 0);
TEST_EQUAL(mbedtls_ssl_context_load(&server_ep.ssl, context_buf,
context_buf_len), 0);
/* Both fields are serialized as [length byte][data bytes]; locate the
* length byte by searching for the sentinel data. */
for (i = 1; i + sentinel_len <= context_buf_len; i++) {
if (context_buf[i - 1] == (unsigned char) sentinel_len &&
memcmp(context_buf + i, sentinel, sentinel_len) == 0) {
len_p = context_buf + i - 1;
break;
}
}
TEST_ASSERT(len_p != NULL);
field_off = (size_t) (len_p + 1 - context_buf);
if (field == TEST_SSL_CONTEXT_LOAD_OOB_IN_CID ||
field == TEST_SSL_CONTEXT_LOAD_OOB_OUT_CID) {
/* The CID fields sit in the middle of the serialized data, so a
* corrupted length cannot reach past the end of the buffer. Instead
* grow the field itself: keep its bytes, pad it to corrupt_len bytes
* and append the untouched rest of the serialized data, so that the
* in-buffer bounds check passes and the size check on the CID array
* is reached. */
load_len = context_buf_len + corrupt_len - sentinel_len;
TEST_CALLOC(load_buf, load_len);
memcpy(load_buf, context_buf, field_off + sentinel_len);
memset(load_buf + field_off + sentinel_len, 0xA5,
(size_t) corrupt_len - sentinel_len);
memcpy(load_buf + field_off + corrupt_len,
context_buf + field_off + sentinel_len,
context_buf_len - field_off - sentinel_len);
/* Double-check that corrupt_len bytes of field data plus the next
* byte are present, which is the most the in-buffer bounds checks
* require (the in_cid one also accounts for the out_cid length
* byte). */
TEST_ASSERT(load_len - field_off >= (size_t) corrupt_len + 1);
} else {
/* The ALPN field is the last one saved, so the buffer already ends
* right after it and the corrupted length reaches exactly one byte
* past the end. Load from a tightly allocated copy, so that reading
* even one byte past the end of the data overruns the allocation and
* gets caught by ASan or Valgrind. */
TEST_EQUAL((size_t) corrupt_len, context_buf_len - field_off + 1);
load_len = context_buf_len;
TEST_CALLOC(load_buf, load_len);
memcpy(load_buf, context_buf, load_len);
}
load_buf[field_off - 1] = corrupt_len;
/* Reinitialise the server SSL context so we can load into a fresh one. */
mbedtls_ssl_free(&server_ep.ssl);
mbedtls_ssl_init(&server_ep.ssl);
TEST_EQUAL(mbedtls_ssl_setup(&server_ep.ssl, &server_ep.conf), 0);
/* How a regression is caught differs between the two cases. In the ALPN
* case, without the bounds check the load still fails, because the
* out-of-bounds bytes are unlikely to match a configured protocol; what
* the missing check leaks is the out-of-bounds read in memcmp() itself,
* so that case catches a regression only when the test suite runs under
* ASan or Valgrind. In the CID cases, without the size check the
* memcpy() overflows the in_cid or out_cid array inside the SSL
* transform (which stays within the enclosing struct, invisible to
* ASan), the rest of the data then parses correctly aligned and the
* load succeeds, so the check below catches a regression on its own. */
TEST_EQUAL(mbedtls_ssl_context_load(&server_ep.ssl, load_buf, load_len),
MBEDTLS_ERR_SSL_BAD_INPUT_DATA);
exit:
mbedtls_test_ssl_endpoint_free(&client_ep, &client_context);
mbedtls_test_ssl_endpoint_free(&server_ep, &server_context);
mbedtls_test_free_handshake_options(&options);
mbedtls_free(context_buf);
mbedtls_free(load_buf);
MD_OR_USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE */
void ssl_session_serialize_version_check(int corrupt_major,
int corrupt_minor,

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:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_MD_CAN_SHA1
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:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_MD_CAN_SHA1
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:MBEDTLS_SSL_HAVE_AES:MBEDTLS_MD_CAN_SHA256:MBEDTLS_SSL_HAVE_GCM:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_ECP_HAVE_SECP384R1:MBEDTLS_MD_CAN_SHA1
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

@ -2070,11 +2070,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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509_crt_parse_basic_constraints:"308201573081fea003020102020c53a2cb4b124ead837da894b2300a06082a8648ce3d040302300e310c300a06035504030c03457665301e170d3236303531323039353330345a170d3336303531323039353330345a300e310c300a06035504030c034576653059301306072a8648ce3d020106082a8648ce3d0301070342000437cc56d976091e5a723ec7592dff206eee7cf9069174d0ad14b5f768225962924ee500d82311ffea2fd2345d5d16bd8a88c26b770d55cd8a2a0efa01c8b4edffa3423040300f0603551d130101ff04053003020100300e0603551d0f0101ff040403020780301d0603551d0e041604145061a58fd407d9d782010ce5657f8c6346a713be300a06082a8648ce3d0403020348003045022100d67d572af0aa540cd0f9d86d43788c178ca9501d8c0f4f6690c773f4b82c4b9a022011620feee62aca3944b8321636849030014ef80604550031312bb707b7f2bf04":0:0:0
X509 CRT ASN1: basicConstraints: invalid cA BOOLEAN length
depends_on:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
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:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256
@ -3462,3 +3478,27 @@ x509_crt_parse_authoritykeyid:"../framework/data_files/authorityKeyId_subjectKey
X509 CRT parse Authority Key Id - Wrong Issuer sequence
depends_on:MBEDTLS_MD_CAN_MD5:MBEDTLS_RSA_C
x509_crt_parse_authoritykeyid:"../framework/data_files/clusterfuzz-testcase-minimized-fuzz_x509crt-6666050834661376.crt.der":"":"":"":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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
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:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_HAVE_SECP256R1:MBEDTLS_MD_CAN_SHA256
x509parse_crt:"3082012b3081d2a003020102020101300a06082a8648ce3d040302300f310d300b06035504030c0454657374301e170d3235303130313030303030305a170d3335303130313030303030305a300f310d300b06035504030c04546573743059301306072a8648ce3d020106082a8648ce3d03010703420004eba1e439f91038837190c4da3703001dff24411b90bf6998f56cba76c753c19ca9158f3c243ccb2118f8b6a78b6eb507962e855bf7c13dbafc314dc56d5d27d8a31f301d300f0603551d130101ff040530030101ff300a0603551d230403300180300a06082a8648ce3d040302034800304502205443c61342f55d3d4cec26df92b7614a5e67177f057efd4f6fb9d7a1a47f5d110221008f05c4c193e203d78a322455132f1b4428388904874dd329fc60a68a37a559b4":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_OUT_OF_DATA

View File

@ -1121,6 +1121,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)
{