Skip to content

Commit

Permalink
Merge pull request #3243 from ndilieto/development
Browse files Browse the repository at this point in the history
New mbedtls_x509_crt_parse_der_with_ext_cb() routine
  • Loading branch information
mpg authored Jun 10, 2020
2 parents 15fee93 + 110a794 commit 87a51aa
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Features
* Add new mbedtls_x509_crt_parse_der_with_ext_cb() routine which allows
parsing unsupported certificate extensions via user provided callback.
Contributed by Nicola Di Lieto <[email protected]> in #3243 as
a solution to #3241.
76 changes: 76 additions & 0 deletions include/mbedtls/x509_crt.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,82 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen );

/**
* \brief The type of certificate extension callbacks.
*
* Callbacks of this type are passed to and used by the
* mbedtls_x509_crt_parse_der_with_ext_cb() routine when
* it encounters an unsupported extension.
*
* \param p_ctx An opaque context passed to the callback.
* \param crt The certificate being parsed.
* \param oid The OID of the extension.
* \param critical Whether the extension is critical.
* \param p Pointer to the start of the extension value
* (the content of the OCTET STRING).
* \param end End of extension value.
*
* \note The callback must fail and return a negative error code
* if it can not parse or does not support the extension.
* When the callback fails to parse a critical extension
* mbedtls_x509_crt_parse_der_with_ext_cb() also fails.
* When the callback fails to parse a non critical extension
* mbedtls_x509_crt_parse_der_with_ext_cb() simply skips
* the extension and continues parsing.
*
* \return \c 0 on success.
* \return A negative error code on failure.
*/
typedef int (*mbedtls_x509_crt_ext_cb_t)( void *p_ctx,
mbedtls_x509_crt const *crt,
mbedtls_x509_buf const *oid,
int critical,
const unsigned char *p,
const unsigned char *end );

/**
* \brief Parse a single DER formatted certificate and add it
* to the end of the provided chained list.
*
* \param chain The pointer to the start of the CRT chain to attach to.
* When parsing the first CRT in a chain, this should point
* to an instance of ::mbedtls_x509_crt initialized through
* mbedtls_x509_crt_init().
* \param buf The buffer holding the DER encoded certificate.
* \param buflen The size in Bytes of \p buf.
* \param make_copy When not zero this function makes an internal copy of the
* CRT buffer \p buf. In particular, \p buf may be destroyed
* or reused after this call returns.
* When zero this function avoids duplicating the CRT buffer
* by taking temporary ownership thereof until the CRT
* is destroyed (like mbedtls_x509_crt_parse_der_nocopy())
* \param cb A callback invoked for every unsupported certificate
* extension.
* \param p_ctx An opaque context passed to the callback.
*
* \note This call is functionally equivalent to
* mbedtls_x509_crt_parse_der(), and/or
* mbedtls_x509_crt_parse_der_nocopy()
* but it calls the callback with every unsupported
* certificate extension.
* The callback must return a negative error code if it
* does not know how to handle such an extension.
* When the callback fails to parse a critical extension
* mbedtls_x509_crt_parse_der_with_ext_cb() also fails.
* When the callback fails to parse a non critical extension
* mbedtls_x509_crt_parse_der_with_ext_cb() simply skips
* the extension and continues parsing.
*
* \return \c 0 if successful.
* \return A negative error code on failure.
*/
int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx );

/**
* \brief Parse a single DER formatted certificate and add it
* to the end of the provided chained list. This is a
Expand Down
41 changes: 34 additions & 7 deletions library/x509_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,9 @@ static int x509_get_certificate_policies( unsigned char **p,
*/
static int x509_get_crt_ext( unsigned char **p,
const unsigned char *end,
mbedtls_x509_crt *crt )
mbedtls_x509_crt *crt,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
Expand Down Expand Up @@ -951,6 +953,16 @@ static int x509_get_crt_ext( unsigned char **p,

if( ret != 0 )
{
/* Give the callback (if any) a chance to handle the extension */
if( cb != NULL )
{
ret = cb( p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet );
if( ret != 0 && is_critical )
return( ret );
*p = end_ext_octet;
continue;
}

/* No parser found, skip extension */
*p = end_ext_octet;

Expand Down Expand Up @@ -1057,7 +1069,9 @@ static int x509_get_crt_ext( unsigned char **p,
static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
const unsigned char *buf,
size_t buflen,
int make_copy )
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
Expand Down Expand Up @@ -1256,7 +1270,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
if( crt->version == 3 )
#endif
{
ret = x509_get_crt_ext( &p, end, crt );
ret = x509_get_crt_ext( &p, end, crt, cb, p_ctx );
if( ret != 0 )
{
mbedtls_x509_crt_free( crt );
Expand Down Expand Up @@ -1319,7 +1333,9 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
int make_copy )
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *crt = chain, *prev = NULL;
Expand Down Expand Up @@ -1351,7 +1367,8 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
crt = crt->next;
}

if( ( ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy ) ) != 0 )
ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy, cb, p_ctx );
if( ret != 0 )
{
if( prev )
prev->next = NULL;
Expand All @@ -1369,14 +1386,24 @@ int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen )
{
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0 ) );
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0, NULL, NULL ) );
}

int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx )
{
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, make_copy, cb, p_ctx ) );
}

int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen )
{
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1 ) );
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1, NULL, NULL ) );
}

/*
Expand Down
20 changes: 20 additions & 0 deletions tests/suites/test_suite_x509parse.data
Original file line number Diff line number Diff line change
Expand Up @@ -2012,6 +2012,26 @@ X509 CRT ASN1 (RSA signature, EC key)
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_SHA1_C:MBEDTLS_RSA_C
x509parse_crt:"3081e430819f020104300d06092a864886f70d0101050500300f310d300b0603550403130454657374301e170d3133303731303135303233375a170d3233303730383135303233375a300f310d300b06035504031304546573743049301306072a8648ce3d020106082a8648ce3d03010103320004e962551a325b21b50cf6b990e33d4318fd16677130726357a196e3efe7107bcb6bdc6d9db2a4df7c964acfe81798433d300d06092a864886f70d01010505000331001a6c18cd1e457474b2d3912743f44b571341a7859a0122774a8e19a671680878936949f904c9255bdd6fffdb33a7e6d8":"cert. version \: 1\nserial number \: 04\nissuer name \: CN=Test\nsubject name \: CN=Test\nissued on \: 2013-07-10 15\:02\:37\nexpires on \: 2023-07-08 15\:02\:37\nsigned using \: RSA with SHA1\nEC key size \: 192 bits\n":0

X509 CRT ASN1 (Unsupported critical extension)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C:!MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
x509parse_crt:"308203353082021da00302010202104d3ebbb8a870f9c78c55a8a7e12fd516300d06092a864886f70d01010b05003010310e300c06035504030c0564756d6d79301e170d3230303432383137343234335a170d3230303632373137343234335a3010310e300c06035504030c0564756d6d7930820122300d06092a864886f70d01010105000382010f003082010a0282010100a51b75b3f7da2d60ea1b0fc077f0dbb2bbb6fe1b474028368af8dc2664672896efff171033b0aede0b323a89d5c6db4d517404bc97b65264e41b9e9e86a6f40ace652498d4b3b859544d1bacfd7f86325503eed046f517406545c0ffb5560f83446dedce0fcafcc41ac8495488a6aa912ae45192ef7e3efa20d0f7403b0baa62c7e2e5404c620c5793623132aa20f624f08d88fbf0985af39433f5a24d0b908e5219d8ba6a404d3ee8418203b62a40c8eb18837354d50281a6a2bf5012e505c419482787b7a81e5935613ceea0c6d93e86f76282b6aa406fb3a1796c56b32e8a22afc3f7a3c9daa8f0e2846ff0d50abfc862a52f6cf0aaece6066c860376f3ed0203010001a3818a308187300c0603551d13040530030101ff30130603551d110101ff04093007820564756d6d79301206082b0601050507011f0101ff0403040100300e0603551d0f0101ff040403020184301d0603551d0e04160414e6e451ec8d19d9677b2d272a9d73b939fa2d915a301f0603551d23041830168014e6e451ec8d19d9677b2d272a9d73b939fa2d915a300d06092a864886f70d01010b0500038201010056d06047b7f48683e2347ca726997d9700b4f2cf1d8bc0ef17addac8445d38ffd7f8079055ead878b6a74c8384d0e30150c8990aa74f59cda6ebcb49465d8991ffa16a4c927a26e4639d1875a3ac396c7455c7eda40dbe66054a03d27f961c15e86bd5b06db6b26572977bcda93453b6b6a88ef96b31996a7bd17323525b33050d28deec9c33a3f9765a11fb99d0e222bd39a6db3a788474c9ca347377688f837d42f5841667bffcbe6b473e6f229f286a0829963e591a99aa7f67e9d20c36ccd2ac84cb85b7a8b3396a6cbe59a573ffff726f373197c230de5c92a52c5bc87e29c20bdf6e89609764a60c649022aabd768f3557661b083ae00e6afc8a5bf2ed":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG

X509 CRT ASN1 (Unsupported critical extension recognized by callback)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crt_cb:"308203353082021da00302010202104d3ebbb8a870f9c78c55a8a7e12fd516300d06092a864886f70d01010b05003010310e300c06035504030c0564756d6d79301e170d3230303432383137343234335a170d3230303632373137343234335a3010310e300c06035504030c0564756d6d7930820122300d06092a864886f70d01010105000382010f003082010a0282010100a51b75b3f7da2d60ea1b0fc077f0dbb2bbb6fe1b474028368af8dc2664672896efff171033b0aede0b323a89d5c6db4d517404bc97b65264e41b9e9e86a6f40ace652498d4b3b859544d1bacfd7f86325503eed046f517406545c0ffb5560f83446dedce0fcafcc41ac8495488a6aa912ae45192ef7e3efa20d0f7403b0baa62c7e2e5404c620c5793623132aa20f624f08d88fbf0985af39433f5a24d0b908e5219d8ba6a404d3ee8418203b62a40c8eb18837354d50281a6a2bf5012e505c419482787b7a81e5935613ceea0c6d93e86f76282b6aa406fb3a1796c56b32e8a22afc3f7a3c9daa8f0e2846ff0d50abfc862a52f6cf0aaece6066c860376f3ed0203010001a3818a308187300c0603551d13040530030101ff30130603551d110101ff04093007820564756d6d79301206082b0601050507011f0101ff0403040100300e0603551d0f0101ff040403020184301d0603551d0e04160414e6e451ec8d19d9677b2d272a9d73b939fa2d915a301f0603551d23041830168014e6e451ec8d19d9677b2d272a9d73b939fa2d915a300d06092a864886f70d01010b0500038201010056d06047b7f48683e2347ca726997d9700b4f2cf1d8bc0ef17addac8445d38ffd7f8079055ead878b6a74c8384d0e30150c8990aa74f59cda6ebcb49465d8991ffa16a4c927a26e4639d1875a3ac396c7455c7eda40dbe66054a03d27f961c15e86bd5b06db6b26572977bcda93453b6b6a88ef96b31996a7bd17323525b33050d28deec9c33a3f9765a11fb99d0e222bd39a6db3a788474c9ca347377688f837d42f5841667bffcbe6b473e6f229f286a0829963e591a99aa7f67e9d20c36ccd2ac84cb85b7a8b3396a6cbe59a573ffff726f373197c230de5c92a52c5bc87e29c20bdf6e89609764a60c649022aabd768f3557661b083ae00e6afc8a5bf2ed":"cert. version \: 3\nserial number \: 4D\:3E\:BB\:B8\:A8\:70\:F9\:C7\:8C\:55\:A8\:A7\:E1\:2F\:D5\:16\nissuer name \: CN=dummy\nsubject name \: CN=dummy\nissued on \: 2020-04-28 17\:42\:43\nexpires on \: 2020-06-27 17\:42\:43\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\nsubject alt name \:\n dNSName \: dummy\nkey usage \: Digital Signature, Key Cert Sign\n":0

X509 CRT ASN1 (Unsupported critical extension not recognized by callback)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crt_cb:"308203353082021da00302010202104d3ebbb8a870f9c78c55a8a7e12fd516300d06092a864886f70d01010b05003010310e300c06035504030c0564756d6d79301e170d3230303432383137343234335a170d3230303632373137343234335a3010310e300c06035504030c0564756d6d7930820122300d06092a864886f70d01010105000382010f003082010a0282010100a51b75b3f7da2d60ea1b0fc077f0dbb2bbb6fe1b474028368af8dc2664672896efff171033b0aede0b323a89d5c6db4d517404bc97b65264e41b9e9e86a6f40ace652498d4b3b859544d1bacfd7f86325503eed046f517406545c0ffb5560f83446dedce0fcafcc41ac8495488a6aa912ae45192ef7e3efa20d0f7403b0baa62c7e2e5404c620c5793623132aa20f624f08d88fbf0985af39433f5a24d0b908e5219d8ba6a404d3ee8418203b62a40c8eb18837354d50281a6a2bf5012e505c419482787b7a81e5935613ceea0c6d93e86f76282b6aa406fb3a1796c56b32e8a22afc3f7a3c9daa8f0e2846ff0d50abfc862a52f6cf0aaece6066c860376f3ed0203010001a3818a308187300c0603551d13040530030101ff30130603551d110101ff04093007820564756d6d79301206082b0601050507011e0101ff0403040100300e0603551d0f0101ff040403020184301d0603551d0e04160414e6e451ec8d19d9677b2d272a9d73b939fa2d915a301f0603551d23041830168014e6e451ec8d19d9677b2d272a9d73b939fa2d915a300d06092a864886f70d01010b0500038201010056d06047b7f48683e2347ca726997d9700b4f2cf1d8bc0ef17addac8445d38ffd7f8079055ead878b6a74c8384d0e30150c8990aa74f59cda6ebcb49465d8991ffa16a4c927a26e4639d1875a3ac396c7455c7eda40dbe66054a03d27f961c15e86bd5b06db6b26572977bcda93453b6b6a88ef96b31996a7bd17323525b33050d28deec9c33a3f9765a11fb99d0e222bd39a6db3a788474c9ca347377688f837d42f5841667bffcbe6b473e6f229f286a0829963e591a99aa7f67e9d20c36ccd2ac84cb85b7a8b3396a6cbe59a573ffff726f373197c230de5c92a52c5bc87e29c20bdf6e89609764a60c649022aabd768f3557661b083ae00e6afc8a5bf2ed":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG

X509 CRT ASN1 (Unsupported non critical extension recognized by callback)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crt_cb:"308203353082021da00302010202104d3ebbb8a870f9c78c55a8a7e12fd516300d06092a864886f70d01010b05003010310e300c06035504030c0564756d6d79301e170d3230303432383137343234335a170d3230303632373137343234335a3010310e300c06035504030c0564756d6d7930820122300d06092a864886f70d01010105000382010f003082010a0282010100a51b75b3f7da2d60ea1b0fc077f0dbb2bbb6fe1b474028368af8dc2664672896efff171033b0aede0b323a89d5c6db4d517404bc97b65264e41b9e9e86a6f40ace652498d4b3b859544d1bacfd7f86325503eed046f517406545c0ffb5560f83446dedce0fcafcc41ac8495488a6aa912ae45192ef7e3efa20d0f7403b0baa62c7e2e5404c620c5793623132aa20f624f08d88fbf0985af39433f5a24d0b908e5219d8ba6a404d3ee8418203b62a40c8eb18837354d50281a6a2bf5012e505c419482787b7a81e5935613ceea0c6d93e86f76282b6aa406fb3a1796c56b32e8a22afc3f7a3c9daa8f0e2846ff0d50abfc862a52f6cf0aaece6066c860376f3ed0203010001a3818a308187300c0603551d13040530030101ff30130603551d110101ff04093007820564756d6d79301206082b0601050507011f0101000403040100300e0603551d0f0101ff040403020184301d0603551d0e04160414e6e451ec8d19d9677b2d272a9d73b939fa2d915a301f0603551d23041830168014e6e451ec8d19d9677b2d272a9d73b939fa2d915a300d06092a864886f70d01010b0500038201010056d06047b7f48683e2347ca726997d9700b4f2cf1d8bc0ef17addac8445d38ffd7f8079055ead878b6a74c8384d0e30150c8990aa74f59cda6ebcb49465d8991ffa16a4c927a26e4639d1875a3ac396c7455c7eda40dbe66054a03d27f961c15e86bd5b06db6b26572977bcda93453b6b6a88ef96b31996a7bd17323525b33050d28deec9c33a3f9765a11fb99d0e222bd39a6db3a788474c9ca347377688f837d42f5841667bffcbe6b473e6f229f286a0829963e591a99aa7f67e9d20c36ccd2ac84cb85b7a8b3396a6cbe59a573ffff726f373197c230de5c92a52c5bc87e29c20bdf6e89609764a60c649022aabd768f3557661b083ae00e6afc8a5bf2ed":"cert. version \: 3\nserial number \: 4D\:3E\:BB\:B8\:A8\:70\:F9\:C7\:8C\:55\:A8\:A7\:E1\:2F\:D5\:16\nissuer name \: CN=dummy\nsubject name \: CN=dummy\nissued on \: 2020-04-28 17\:42\:43\nexpires on \: 2020-06-27 17\:42\:43\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\nsubject alt name \:\n dNSName \: dummy\nkey usage \: Digital Signature, Key Cert Sign\n":0

X509 CRT ASN1 (Unsupported non critical extension not recognized by callback)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crt_cb:"308203353082021da00302010202104d3ebbb8a870f9c78c55a8a7e12fd516300d06092a864886f70d01010b05003010310e300c06035504030c0564756d6d79301e170d3230303432383137343234335a170d3230303632373137343234335a3010310e300c06035504030c0564756d6d7930820122300d06092a864886f70d01010105000382010f003082010a0282010100a51b75b3f7da2d60ea1b0fc077f0dbb2bbb6fe1b474028368af8dc2664672896efff171033b0aede0b323a89d5c6db4d517404bc97b65264e41b9e9e86a6f40ace652498d4b3b859544d1bacfd7f86325503eed046f517406545c0ffb5560f83446dedce0fcafcc41ac8495488a6aa912ae45192ef7e3efa20d0f7403b0baa62c7e2e5404c620c5793623132aa20f624f08d88fbf0985af39433f5a24d0b908e5219d8ba6a404d3ee8418203b62a40c8eb18837354d50281a6a2bf5012e505c419482787b7a81e5935613ceea0c6d93e86f76282b6aa406fb3a1796c56b32e8a22afc3f7a3c9daa8f0e2846ff0d50abfc862a52f6cf0aaece6066c860376f3ed0203010001a3818a308187300c0603551d13040530030101ff30130603551d110101ff04093007820564756d6d79301206082b0601050507011e0101000403040100300e0603551d0f0101ff040403020184301d0603551d0e04160414e6e451ec8d19d9677b2d272a9d73b939fa2d915a301f0603551d23041830168014e6e451ec8d19d9677b2d272a9d73b939fa2d915a300d06092a864886f70d01010b0500038201010056d06047b7f48683e2347ca726997d9700b4f2cf1d8bc0ef17addac8445d38ffd7f8079055ead878b6a74c8384d0e30150c8990aa74f59cda6ebcb49465d8991ffa16a4c927a26e4639d1875a3ac396c7455c7eda40dbe66054a03d27f961c15e86bd5b06db6b26572977bcda93453b6b6a88ef96b31996a7bd17323525b33050d28deec9c33a3f9765a11fb99d0e222bd39a6db3a788474c9ca347377688f837d42f5841667bffcbe6b473e6f229f286a0829963e591a99aa7f67e9d20c36ccd2ac84cb85b7a8b3396a6cbe59a573ffff726f373197c230de5c92a52c5bc87e29c20bdf6e89609764a60c649022aabd768f3557661b083ae00e6afc8a5bf2ed":"cert. version \: 3\nserial number \: 4D\:3E\:BB\:B8\:A8\:70\:F9\:C7\:8C\:55\:A8\:A7\:E1\:2F\:D5\:16\nissuer name \: CN=dummy\nsubject name \: CN=dummy\nissued on \: 2020-04-28 17\:42\:43\nexpires on \: 2020-06-27 17\:42\:43\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\nsubject alt name \:\n dNSName \: dummy\nkey usage \: Digital Signature, Key Cert Sign\n":0

X509 CRL ASN1 (Incorrect first tag)
x509parse_crl:"":"":MBEDTLS_ERR_X509_INVALID_FORMAT

Expand Down
Loading

0 comments on commit 87a51aa

Please sign in to comment.