From bb3607abc861d44ae8a01b9afa9e52c1163ecbef Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Fri, 2 Dec 2022 07:43:51 -0500 Subject: [PATCH] Use memcmp() to parse version numbers This makes the code shorter and more efficient, at the expense of less useful error messages. Also reject explicit encodings of the default version number (1), which must be omitted as per ASN.1 DER. Signed-off-by: Demi Marie Obenour --- library/x509_crt.c | 48 +++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/library/x509_crt.c b/library/x509_crt.c index 9c44ba6a4b..5576dcaf03 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -409,31 +409,30 @@ static int x509_get_version(unsigned char **p, const unsigned char *end, int *ver) { - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t len; + unsigned char raw_ver = 0; + unsigned char const prefix[4] = { + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0, + 3, + MBEDTLS_ASN1_INTEGER, + 1, + }; - if ((ret = mbedtls_asn1_get_tag(p, end, &len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | - 0)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - *ver = 0; - return 0; + if ((end - *p) < 6) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, + MBEDTLS_ERR_ASN1_OUT_OF_DATA); + } + if (memcmp(*p, prefix, sizeof(prefix)) == 0) { + raw_ver = (*p)[4]; + if (raw_ver > 2) { + return MBEDTLS_ERR_X509_UNKNOWN_VERSION; } - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret); + if (raw_ver <= 0) { + return MBEDTLS_ERR_X509_INVALID_VERSION; + } + *p += 5; } - - end = *p + len; - - if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret); - } - - if (*p != end) { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); - } - + *ver = raw_ver + 1; return 0; } @@ -1171,13 +1170,6 @@ static int x509_crt_parse_der_core(mbedtls_x509_crt *crt, return ret; } - if (crt->version < 0 || crt->version > 2) { - mbedtls_x509_crt_free(crt); - return MBEDTLS_ERR_X509_UNKNOWN_VERSION; - } - - crt->version++; - if ((ret = mbedtls_x509_get_sig_alg(&crt->sig_oid, &sig_params1, &crt->sig_md, &crt->sig_pk, &crt->sig_opts)) != 0) {