Fix segfault in mbedtls_oid_get_numeric_string

When passed an empty OID, mbedtls_oid_get_numeric_string would read one
byte from the zero-sized buffer and return an error code that depends on
its value.  This is demonstrated by the test suite changes, which
check that an OID with length zero and an invalid buffer pointer does
not cause Mbed TLS to segfault.

Also check that second and subsequent subidentifiers are terminated, and
add a test case for that.  Furthermore, stop relying on integer division
by 40, use the same loop for both the first and subsequent
subidentifiers, and add additional tests.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
This commit is contained in:
Demi Marie Obenour 2023-03-11 17:45:28 -05:00
parent 8d60574b7b
commit 889534a4d2
4 changed files with 65 additions and 53 deletions

View file

@ -101,12 +101,30 @@ oid_get_numeric_string:"81010000863A00":0:"2.49.0.0.826.0"
OID get numeric string - multi-byte first subidentifier
oid_get_numeric_string:"8837":0:"2.999"
OID get numeric string - second subidentifier not terminated
oid_get_numeric_string:"0081":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
OID get numeric string - empty oid buffer
oid_get_numeric_string:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
OID get numeric string - no final / all bytes have top bit set
oid_get_numeric_string:"818181":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
OID get numeric string - 0.39
oid_get_numeric_string:"27":0:"0.39"
OID get numeric string - 1.0
oid_get_numeric_string:"28":0:"1.0"
OID get numeric string - 1.39
oid_get_numeric_string:"4f":0:"1.39"
OID get numeric string - 2.0
oid_get_numeric_string:"50":0:"2.0"
OID get numeric string - 1 byte first subidentifier beyond 2.39
oid_get_numeric_string:"7f":0:"2.47"
# Encodes the number 0x0400000000 as a subidentifier which overflows 32-bits
OID get numeric string - 32-bit overflow
oid_get_numeric_string:"C080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:""

View file

@ -105,13 +105,16 @@ void oid_get_numeric_string(data_t *oid, int error_ret, char *result_str)
int ret;
input_oid.tag = MBEDTLS_ASN1_OID;
input_oid.p = oid->x;
/* Test that an empty OID is not dereferenced */
input_oid.p = oid->len ? oid->x : (void *) 1;
input_oid.len = oid->len;
ret = mbedtls_oid_get_numeric_string(buf, sizeof(buf), &input_oid);
if (error_ret == 0) {
TEST_ASSERT(strcmp(buf, result_str) == 0);
TEST_EQUAL(ret, strlen(result_str));
TEST_ASSERT(ret >= 3);
TEST_EQUAL(strcmp(buf, result_str), 0);
} else {
TEST_EQUAL(ret, error_ret);
}