Merge 920c861cdd83bdee7760b54e052e8f89471fe21d into 03e1438089654fb884ac48e0f3cd0049cfe2c102

This commit is contained in:
Ray Chern 2026-10-27 10:46:00 -04:00 committed by GitHub
commit 153d225cbe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 3 deletions

View File

@ -0,0 +1,13 @@
Bugfix
* Fix mbedtls_x509write_crt_set_serial_raw() silently accepting a
zero-length serial number, and mbedtls_x509write_crt_der() silently
encoding it as a syntactically invalid ASN.1 INTEGER (zero content
octets, which X.690 8.3.1 forbids) for the certificate's
CertificateSerialNumber field instead of failing. Certificates
generated this way (either by explicitly passing a zero-length
serial, or by never calling mbedtls_x509write_crt_set_serial_raw()
at all) could be rejected by other, stricter X.509/ASN.1 parsers.
mbedtls_x509write_crt_set_serial_raw() now returns
MBEDTLS_ERR_X509_BAD_INPUT_DATA for a zero-length serial, and
mbedtls_x509write_crt_der() now also rejects a zero-length serial
as a defense-in-depth check.

View File

@ -957,8 +957,8 @@ void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx, int version)
* input buffer
*
* \return 0 if successful, or
* #MBEDTLS_ERR_X509_BAD_INPUT_DATA if the provided input buffer
* is too big (longer than MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN)
* #MBEDTLS_ERR_X509_BAD_INPUT_DATA if \p serial_len is 0 or
* too big (longer than MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN)
*/
int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx,
const unsigned char *serial, size_t serial_len);

View File

@ -95,7 +95,7 @@ int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx,
const unsigned char *serial, size_t serial_len)
{
if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) {
if (serial_len == 0 || serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) {
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
@ -512,7 +512,18 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
* - if MSb of "serial" is 1, then prepend an extra 0x00 byte
* - 1 byte for the length
* - 1 byte for the TAG
*
* ctx->serial_len == 0 (the zeroed state left by
* mbedtls_x509write_crt_init() if mbedtls_x509write_crt_set_serial_raw()
* was never called) must be rejected here: an INTEGER with zero content
* octets is not valid DER (X.690 8.3.1 requires at least one octet), so
* letting it through would silently write a syntactically invalid
* `02 00` CertificateSerialNumber field instead of failing loudly.
*/
if (ctx->serial_len == 0) {
return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf,
ctx->serial, ctx->serial_len));
if (*c & 0x80) {

View File

@ -565,6 +565,7 @@ void x509_set_serial_check()
{
mbedtls_x509write_cert ctx;
uint8_t invalid_serial[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN + 1];
uint8_t zero_len_serial[1] = { 0x2a };
USE_PSA_INIT();
memset(invalid_serial, 0x01, sizeof(invalid_serial));
@ -573,6 +574,12 @@ void x509_set_serial_check()
sizeof(invalid_serial)),
MBEDTLS_ERR_X509_BAD_INPUT_DATA);
/* A zero-length serial must also be rejected: an ASN.1 INTEGER with
* zero content octets is not valid DER (X.690 8.3.1), so
* mbedtls_x509write_crt_der() must never be allowed to encode one. */
TEST_EQUAL(mbedtls_x509write_crt_set_serial_raw(&ctx, zero_len_serial, 0),
MBEDTLS_ERR_X509_BAD_INPUT_DATA);
exit:
;
USE_PSA_DONE();