Merge f94e525b3c21c1682707da1fe1ed39100b25f2f3 into 3bb373867917b674265067cbd38b9d252c43d014

This commit is contained in:
Eyüp Can Akman 2026-07-20 21:01:31 +01:00 committed by GitHub
commit d28d69c4aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 73 additions and 38 deletions

View File

@ -0,0 +1,6 @@
Bugfix
* Fix mbedtls_x509_dn_gets() returning MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
for a Distinguished Name whose escaped or hex-encoded form is longer than
256 bytes, even when the output buffer was large enough. The rendered
value is now written straight to the output buffer instead of a fixed-size
internal buffer. Fixes #10753.

View File

@ -891,7 +891,7 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size,
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j, n, asn1_len_size, asn1_tag_size, asn1_tag_len_buf_start;
size_t i, n, asn1_len_size, asn1_tag_size, asn1_tag_len_buf_start;
/* 6 is enough as our asn1 write functions only write one byte for the tag and at most five bytes for the length*/
unsigned char asn1_tag_len_buf[6];
unsigned char *asn1_len_p;
@ -899,11 +899,9 @@ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
const mbedtls_x509_name *name;
const char *short_name = NULL;
char lowbits, highbits;
char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
char *p;
int print_hexstring;
memset(s, 0, sizeof(s));
name = dn;
p = buf;
n = size;
@ -940,7 +938,8 @@ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
MBEDTLS_X509_SAFE_SNPRINTF;
if (print_hexstring) {
s[0] = '#';
ret = mbedtls_snprintf(p, n, "#");
MBEDTLS_X509_SAFE_SNPRINTF;
asn1_len_p = asn1_tag_len_buf + sizeof(asn1_tag_len_buf);
if ((ret = mbedtls_asn1_write_len(&asn1_len_p, asn1_tag_len_buf, name->val.len)) < 0) {
@ -952,32 +951,26 @@ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
}
asn1_tag_size = ret;
asn1_tag_len_buf_start = sizeof(asn1_tag_len_buf) - asn1_len_size - asn1_tag_size;
for (i = 0, j = 1; i < asn1_len_size + asn1_tag_size; i++) {
if (j + 1 >= sizeof(s) - 1) {
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
for (i = 0; i < asn1_len_size + asn1_tag_size; i++) {
c = asn1_tag_len_buf[asn1_tag_len_buf_start+i];
lowbits = (c & 0x0F);
highbits = c >> 4;
s[j++] = nibble_to_hex_digit(highbits);
s[j++] = nibble_to_hex_digit(lowbits);
ret = mbedtls_snprintf(p, n, "%c%c",
nibble_to_hex_digit(highbits),
nibble_to_hex_digit(lowbits));
MBEDTLS_X509_SAFE_SNPRINTF;
}
for (i = 0; i < name->val.len; i++) {
if (j + 1 >= sizeof(s) - 1) {
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
c = name->val.p[i];
lowbits = (c & 0x0F);
highbits = c >> 4;
s[j++] = nibble_to_hex_digit(highbits);
s[j++] = nibble_to_hex_digit(lowbits);
ret = mbedtls_snprintf(p, n, "%c%c",
nibble_to_hex_digit(highbits),
nibble_to_hex_digit(lowbits));
MBEDTLS_X509_SAFE_SNPRINTF;
}
} else {
for (i = 0, j = 0; i < name->val.len; i++, j++) {
if (j >= sizeof(s) - 1) {
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
for (i = 0; i < name->val.len; i++) {
c = name->val.p[i];
// Special characters requiring escaping, RFC 4514 Section 2.4
if (c == '\0') {
@ -986,29 +979,23 @@ int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
if (strchr(",=+<>;\"\\", c) ||
((i == 0) && strchr("# ", c)) ||
((i == name->val.len-1) && (c == ' '))) {
if (j + 1 >= sizeof(s) - 1) {
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
s[j++] = '\\';
ret = mbedtls_snprintf(p, n, "%c", '\\');
MBEDTLS_X509_SAFE_SNPRINTF;
}
}
if (c < 32 || c >= 127) {
if (j + 3 >= sizeof(s) - 1) {
return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
}
s[j++] = '\\';
lowbits = (c & 0x0F);
highbits = c >> 4;
s[j++] = nibble_to_hex_digit(highbits);
s[j] = nibble_to_hex_digit(lowbits);
ret = mbedtls_snprintf(p, n, "\\%c%c",
nibble_to_hex_digit(highbits),
nibble_to_hex_digit(lowbits));
MBEDTLS_X509_SAFE_SNPRINTF;
} else {
s[j] = c;
ret = mbedtls_snprintf(p, n, "%c", c);
MBEDTLS_X509_SAFE_SNPRINTF;
}
}
}
s[j] = '\0';
ret = mbedtls_snprintf(p, n, "%s", s);
MBEDTLS_X509_SAFE_SNPRINTF;
merge = name->next_merged;
name = name->next;

View File

@ -469,15 +469,15 @@ mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"1234
X509 Get Modified DN #3 Name exceeds 255 bytes
depends_on:MBEDTLS_PEM_PARSE_C:PSA_HAVE_ALG_SOME_RSA_VERIFY:PSA_WANT_ALG_SHA_1
mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456":"":MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456":"C=NL, O=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456, CN=PolarSSL Server 1":0
X509 Get Modified DN #4 Name exactly 255 bytes, with comma requiring escaping
depends_on:MBEDTLS_PEM_PARSE_C:PSA_HAVE_ALG_SOME_RSA_VERIFY:PSA_WANT_ALG_SHA_1
mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"1234567890,1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234":"":MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"1234567890,1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234":"C=NL, O=1234567890\\,1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234, CN=PolarSSL Server 1":0
X509 Get Modified DN #5 Name exactly 255 bytes, ending with comma requiring escaping
depends_on:MBEDTLS_PEM_PARSE_C:PSA_HAVE_ALG_SOME_RSA_VERIFY:PSA_WANT_ALG_SHA_1
mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234,":"":MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
mbedtls_x509_dn_gets_subject_replace:"../framework/data_files/server1.crt":"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234,":"C=NL, O=12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\\,, CN=PolarSSL Server 1":0
X509 Get Next DN #1 No Multivalue RDNs
mbedtls_x509_dn_get_next:"C=NL, O=PolarSSL, CN=PolarSSL Server 1":0:"C O CN":3:"C=NL, O=PolarSSL, CN=PolarSSL Server 1"
@ -491,6 +491,12 @@ mbedtls_x509_dn_get_next:"C=NL, O=PolarSSL, CN=PolarSSL Server 1":0x03:"C":1:"C=
X509 Get Next DN #4 Consecutive Multivalue RDNs
mbedtls_x509_dn_get_next:"C=NL, O=PolarSSL, title=Example, CN=PolarSSL Server 1":0x05:"C title":2:"C=NL + O=PolarSSL, title=Example + CN=PolarSSL Server 1"
X509 Get Distinguished Name escaped value longer than 256 bytes
mbedtls_x509_dn_gets_long_value:"CN=\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3":"CN=\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3\\C3"
X509 Get Distinguished Name hex value longer than 256 bytes
mbedtls_x509_dn_gets_long_value:"CN=#148182ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB":"CN=#148182ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB"
# Parse the following valid DN:
#
# 31 0B <- Set of

View File

@ -1048,6 +1048,42 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C:MBEDTLS_X509_CRT_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */
void mbedtls_x509_dn_gets_long_value(char *name_str, char *exp_dn_gets)
{
int ret = 0;
size_t len = 0;
mbedtls_asn1_named_data *names = NULL;
mbedtls_x509_name parsed;
memset(&parsed, 0, sizeof(parsed));
/* Holds the DER encoding of the test name. */
unsigned char buf[512] = { 0 };
unsigned char *c = buf + sizeof(buf);
char out[1024] = { 0 };
USE_PSA_INIT();
TEST_EQUAL(mbedtls_x509_string_to_names(&names, name_str), 0);
ret = mbedtls_x509_write_names(&c, buf, names);
TEST_LE_S(0, ret);
TEST_EQUAL(mbedtls_asn1_get_tag(&c, buf + sizeof(buf), &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), 0);
TEST_EQUAL(mbedtls_x509_get_name(&c, buf + sizeof(buf), &parsed), 0);
/* The rendered value is longer than the old fixed 256-byte buffer. */
ret = mbedtls_x509_dn_gets(out, sizeof(out), &parsed);
TEST_LE_S(0, ret);
TEST_EQUAL(strcmp(out, exp_dn_gets), 0);
exit:
mbedtls_asn1_free_named_data_list(&names);
mbedtls_asn1_free_named_data_list_shallow(parsed.next);
USE_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */
void mbedtls_x509_time_is_past(char *crt_file, char *entity, int result)
{