Merge pull request #1080 from gilles-peskine-arm/parse_attribute_value_der_encoded-buffer_overflow

Fix buffer overflow in parse_attribute_value_der_encoded
This commit is contained in:
Gilles Peskine 2023-09-26 16:32:36 +02:00 committed by GitHub
commit 641250f42b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 176 additions and 73 deletions

View file

@ -185,51 +185,107 @@ static int parse_attribute_value_string(const char *s,
return 0;
}
static int parse_attribute_value_der_encoded(const char *s,
int len,
unsigned char *data,
size_t *data_len,
int *tag)
/** Parse a hexstring containing a DER-encoded string.
*
* \param s A string of \p len bytes hexadecimal digits.
* \param len Number of bytes to read from \p s.
* \param data Output buffer of size \p data_size.
* On success, it contains the payload that's DER-encoded
* in the input (content without the tag and length).
* If the DER tag is a string tag, the payload is guaranteed
* not to contain null bytes.
* \param data_size Length of the \p data buffer.
* \param data_len On success, the length of the parsed string.
* It is guaranteed to be less than
* #MBEDTLS_X509_MAX_DN_NAME_SIZE.
* \param tag The ASN.1 tag that the payload in \p data is encoded in.
*
* \retval 0 on success.
* \retval #MBEDTLS_ERR_X509_INVALID_NAME if \p s does not contain
* a valid hexstring,
* or if the decoded hexstring is not valid DER,
* or if the payload does not fit in \p data,
* or if the payload is more than
* #MBEDTLS_X509_MAX_DN_NAME_SIZE bytes,
* of if \p *tag is an ASN.1 string tag and the payload
* contains a null byte.
* \retval #MBEDTLS_ERR_X509_ALLOC_FAILED on low memory.
*/
static int parse_attribute_value_hex_der_encoded(const char *s,
size_t len,
unsigned char *data,
size_t data_size,
size_t *data_len,
int *tag)
{
const char *c = s;
const char *end = c + len;
unsigned char asn1_der_buf[MBEDTLS_X509_MAX_DN_NAME_SIZE];
unsigned char *asn1_der_end;
unsigned char *p;
unsigned char *d = data;
int n;
/* Step 1: preliminary length checks. */
/* Each byte is encoded by exactly two hexadecimal digits. */
if (len % 2 != 0) {
/* Odd number of hex digits */
return MBEDTLS_ERR_X509_INVALID_NAME;
}
size_t const der_length = len / 2;
if (der_length > MBEDTLS_X509_MAX_DN_NAME_SIZE + 4) {
/* The payload would be more than MBEDTLS_X509_MAX_DN_NAME_SIZE
* (after subtracting the ASN.1 tag and length). Reject this early
* to avoid allocating a large intermediate buffer. */
return MBEDTLS_ERR_X509_INVALID_NAME;
}
if (der_length < 1) {
/* Avoid empty-buffer shenanigans. A valid DER encoding is never
* empty. */
return MBEDTLS_ERR_X509_INVALID_NAME;
}
/* Converting from hexstring to raw binary so we can use asn1parse.c */
if ((len < 5) || (*c != '#')) {
return MBEDTLS_ERR_X509_INVALID_NAME;
/* Step 2: Decode the hex string into an intermediate buffer. */
unsigned char *der = mbedtls_calloc(1, der_length);
if (der == NULL) {
return MBEDTLS_ERR_X509_ALLOC_FAILED;
}
c++;
if ((*tag = hexpair_to_int(c)) == -1) {
return MBEDTLS_ERR_X509_INVALID_NAME;
}
c += 2;
p = asn1_der_buf;
for (p = asn1_der_buf; c < end; c += 2) {
if ((c + 1 >= end) || (n = hexpair_to_int(c)) == -1) {
return MBEDTLS_ERR_X509_INVALID_NAME;
/* Beyond this point, der needs to be freed on exit. */
for (size_t i = 0; i < der_length; i++) {
int c = hexpair_to_int(s + 2 * i);
if (c < 0) {
goto error;
}
if (MBEDTLS_ASN1_IS_STRING_TAG(*tag) && n == 0) {
return MBEDTLS_ERR_X509_INVALID_NAME;
der[i] = c;
}
/* Step 3: decode the DER. */
/* We've checked that der_length >= 1 above. */
*tag = der[0];
unsigned char *p = der + 1;
if (mbedtls_asn1_get_len(&p, der + der_length, data_len) != 0) {
goto error;
}
/* Now p points to the first byte of the payload inside der,
* and *data_len is the length of the payload. */
/* Step 4: payload validation */
if (*data_len > MBEDTLS_X509_MAX_DN_NAME_SIZE) {
goto error;
}
/* Strings must not contain null bytes. */
if (MBEDTLS_ASN1_IS_STRING_TAG(*tag)) {
for (size_t i = 0; i < *data_len; i++) {
if (p[i] == 0) {
goto error;
}
}
*(p++) = n;
}
asn1_der_end = p;
p = asn1_der_buf;
if (mbedtls_asn1_get_len(&p, asn1_der_end, data_len) != 0) {
return MBEDTLS_ERR_X509_INVALID_NAME;
}
while (p < asn1_der_end) {
*(d++) = *(p++);
/* Step 5: output the payload. */
if (*data_len > data_size) {
goto error;
}
memcpy(data, p, *data_len);
mbedtls_free(der);
return 0;
error:
mbedtls_free(der);
return MBEDTLS_ERR_X509_INVALID_NAME;
}
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name)
@ -273,11 +329,14 @@ int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *nam
mbedtls_free(oid.p);
return MBEDTLS_ERR_X509_INVALID_NAME;
} else if (*s == '#') {
if ((parse_ret =
parse_attribute_value_der_encoded(s, (int) (c - s), data, &data_len,
&tag)) != 0) {
/* We know that c >= s (loop invariant) and c != s (in this
* else branch), hence c - s - 1 >= 0. */
parse_ret = parse_attribute_value_hex_der_encoded(
s + 1, c - s - 1,
data, sizeof(data), &data_len, &tag);
if (parse_ret != 0) {
mbedtls_free(oid.p);
return MBEDTLS_ERR_X509_INVALID_NAME;
return parse_ret;
}
} else {
if (numericoid) {

View file

@ -167,73 +167,101 @@ depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"01":"20190210144406":"20290210144406":MBEDTLS_MD_SHA1:0:0:"NULL":0:0:1:-1:"data_files/server1.allSubjectAltNames.crt":0:0:"data_files/test-ca.crt":1
X509 String to Names #1
mbedtls_x509_string_to_names:"C=NL,O=Offspark\\, Inc., OU=PolarSSL":"C=NL, O=Offspark\\, Inc., OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL,O=Offspark\\, Inc., OU=PolarSSL":"C=NL, O=Offspark\\, Inc., OU=PolarSSL":0:0
X509 String to Names #2
mbedtls_x509_string_to_names:"C=NL, O=Offspark, Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=Offspark, Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #3 (Name precisely 255 bytes)
mbedtls_x509_string_to_names:"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345,OU=PolarSSL":"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345,OU=PolarSSL":"C=NL, O=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345, OU=PolarSSL":0:0
X509 String to Names #4 (Name larger than 255 bytes)
mbedtls_x509_string_to_names:"C=NL, O=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #5 (Escape non-allowed characters)
mbedtls_x509_string_to_names:"C=NL, O=Offspark\\a Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=Offspark\\a Inc., OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #6 (Escape at end)
mbedtls_x509_string_to_names:"C=NL, O=Offspark\\":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=Offspark\\":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #7 (Invalid, no '=' or ',')
mbedtls_x509_string_to_names:"ABC123":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"ABC123":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #8 (Escaped valid characters)
mbedtls_x509_string_to_names:"C=NL, O=Offspark\\+ \\> \\=, OU=PolarSSL":"C=NL, O=Offspark\\+ \\> \\=, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, O=Offspark\\+ \\> \\=, OU=PolarSSL":"C=NL, O=Offspark\\+ \\> \\=, OU=PolarSSL":0:0
X509 String to Names #9 (Escaped ascii hexpairs uppercase encoded)
mbedtls_x509_string_to_names:"C=NL, O=\\4F\\66\\66\\73\\70\\61\\72\\6B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, O=\\4F\\66\\66\\73\\70\\61\\72\\6B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0:0
X509 String to Names #10 (Escaped ascii hexpairs lowercase encoded)
mbedtls_x509_string_to_names:"C=NL, O=\\4f\\66\\66\\73\\70\\61\\72\\6b, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, O=\\4f\\66\\66\\73\\70\\61\\72\\6b, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0:0
X509 String to Names #11 (Invalid hexpair escape at end of string)
mbedtls_x509_string_to_names:"C=NL, O=\\4f\\66\\66\\73\\70\\61\\72\\6, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=\\4f\\66\\66\\73\\70\\61\\72\\6, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #12 (Reject escaped null hexpair)
mbedtls_x509_string_to_names:"C=NL, O=Of\\00spark, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=Of\\00spark, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #13 (Invalid hexpairs)
mbedtls_x509_string_to_names:"C=NL, O=Of\\flspark, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=Of\\flspark, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #14 (Accept numercoid/hexstring)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0:0
# TODO: Should the trailing garbage be ignored?
X509 String to Names (hexstring: trailing garbage after DER is ignored)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726Baa, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0:0
X509 String to Names: long hexstring (payload=256 bytes)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C82010041414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141, OU=PolarSSL":"C=NL, O=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, OU=PolarSSL":0:MAY_FAIL_DN_GETS
X509 String to Names: long hexstring (payload=257 bytes)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C820101aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #15 (Odd length DER hexstring)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C084F6666737061726, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #16 (Length mismatch DER hexstring)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C0B4F6666737061726B, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
X509 String to Names (empty DER hexstring)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #17 (Invalid OID)
mbedtls_x509_string_to_names:"C=NL, 10.5.4.10=#0C084F6666737061726B, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
X509 String to Names (empty DER hexstring at end)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names (1-byte DER hexstring)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names (1-byte DER hexstring at end)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #16 (hexstring: DER length exceeds available data)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#0C0B4F6666737061726B, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #17 (hexstring: Invalid OID)
mbedtls_x509_string_to_names:"C=NL, 10.5.4.10=#0C084F6666737061726B, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names #18 (short name and hexstring)
mbedtls_x509_string_to_names:"C=NL, O=#0C084F6666737061726B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, O=#0C084F6666737061726B, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":0:0
X509 String to Names (null byte in hexstring with string type)
mbedtls_x509_string_to_names:"C=NL, O=#0C0100, OU=PolarSSL":"C=NL, O=Offspark, OU=PolarSSL":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 String to Names (null byte in hexstring with non-string type)
mbedtls_x509_string_to_names:"C=NL, O=#040100, OU=PolarSSL":"C=NL, O=\\x00, OU=PolarSSL":0:MAY_FAIL_GET_NAME
X509 String to Names #19 (Accept non-ascii hexpairs)
mbedtls_x509_string_to_names:"C=NL, O=Of\\CCspark, OU=PolarSSL":"C=NL, O=Of\\CCspark, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, O=Of\\CCspark, OU=PolarSSL":"C=NL, O=Of\\CCspark, OU=PolarSSL":0:0
X509 String to Names #20 (Reject empty AttributeValue)
mbedtls_x509_string_to_names:"C=NL, O=, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME
mbedtls_x509_string_to_names:"C=NL, O=, OU=PolarSSL":"":MBEDTLS_ERR_X509_INVALID_NAME:0
X509 Round trip test (Escaped characters)
mbedtls_x509_string_to_names:"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":0
mbedtls_x509_string_to_names:"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":"CN=Lu\\C4\\8Di\\C4\\87, O=Offspark, OU=PolarSSL":0:0
X509 Round trip test (hexstring output for non string input)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#03084F6666737061726B, OU=PolarSSL":"C=NL, O=#03084F6666737061726B, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10=#03084F6666737061726B, OU=PolarSSL":"C=NL, O=#03084F6666737061726B, OU=PolarSSL":0:0
X509 Round trip test (numercoid hexstring output for unknown OID)
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=PolarSSL":"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=PolarSSL":0
mbedtls_x509_string_to_names:"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=PolarSSL":"C=NL, 2.5.4.10.234.532=#0C084F6666737061726B, OU=PolarSSL":0:0
Check max serial length
x509_set_serial_check:

View file

@ -125,6 +125,12 @@ static int csr_set_extended_key_usage(mbedtls_x509write_csr *ctx,
return ret;
}
#endif /* MBEDTLS_X509_CSR_WRITE_C */
/* Due to inconsistencies in the input size limits applied by different
* library functions, some write-parse tests may fail. */
#define MAY_FAIL_GET_NAME 0x0001
#define MAY_FAIL_DN_GETS 0x0002
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@ -687,8 +693,8 @@ exit:
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
void mbedtls_x509_string_to_names(char *name, char *parsed_name, int result
)
void mbedtls_x509_string_to_names(char *name, char *parsed_name,
int result, int may_fail)
{
int ret;
size_t len = 0;
@ -704,22 +710,32 @@ void mbedtls_x509_string_to_names(char *name, char *parsed_name, int result
c = buf + sizeof(buf);
ret = mbedtls_x509_string_to_names(&names, name);
TEST_ASSERT(ret == result);
TEST_EQUAL(ret, result);
if (ret != 0) {
goto exit;
}
ret = mbedtls_x509_write_names(&c, buf, names);
TEST_ASSERT(ret > 0);
TEST_LE_S(1, ret);
TEST_ASSERT(mbedtls_asn1_get_tag(&c, buf + sizeof(buf), &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0);
TEST_ASSERT(mbedtls_x509_get_name(&c, buf + sizeof(buf), &parsed) == 0);
TEST_EQUAL(mbedtls_asn1_get_tag(&c, buf + sizeof(buf), &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), 0);
ret = mbedtls_x509_get_name(&c, buf + sizeof(buf), &parsed);
if ((may_fail & MAY_FAIL_GET_NAME) && ret < 0) {
/* Validation inconsistency between mbedtls_x509_string_to_names() and
* mbedtls_x509_get_name(). Accept it for now. */
goto exit;
}
TEST_EQUAL(ret, 0);
ret = mbedtls_x509_dn_gets((char *) out, sizeof(out), &parsed);
TEST_ASSERT(ret > 0);
if ((may_fail & MAY_FAIL_DN_GETS) && ret < 0) {
/* Validation inconsistency between mbedtls_x509_string_to_names() and
* mbedtls_x509_dn_gets(). Accept it for now. */
goto exit;
}
TEST_LE_S(1, ret);
TEST_ASSERT(strcmp((char *) out, parsed_name) == 0);
exit: