New mbedtls_x509_crt_parse_der_ext() routine
This routine is functionally equivalent to mbedtls_x509_crt_parse_der(), but it accepts an additional callback function which it calls with every unsupported certificate extension. Proposed solution to https://github.com/ARMmbed/mbedtls/issues/3241 Signed-off-by: Nicola Di Lieto <nicola.dilieto@gmail.com>
This commit is contained in:
parent
b1c8e41ae3
commit
502d4b4510
@ -303,6 +303,62 @@ 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_ext() routine when it encounters
|
||||
* an unsupported extension.
|
||||
*
|
||||
* \param crt Pointer to the certificate being parsed
|
||||
* \param oid Extension's OID
|
||||
* \param critical If the extension is critical (per the RFC's definition)
|
||||
* \param p On entry \c *p points to the start of the extension ASN.1
|
||||
* data. On successful completion \c *p must point to the
|
||||
* first byte after it.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of extension data.
|
||||
*
|
||||
* \note The callback must fail and return a negative error code if
|
||||
* it can not parse or does not support the extension.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
typedef int (*mbedtls_x509_crt_ext_cb_t)( mbedtls_x509_crt const *crt,
|
||||
mbedtls_x509_buf const *oid,
|
||||
int critical,
|
||||
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 cb A callback invoked for every unsupported certificate
|
||||
* extension.
|
||||
*
|
||||
* \note This call is functionally equivalent to
|
||||
* mbedtls_x509_crt_parse_der(), 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.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_x509_crt_parse_der_ext( mbedtls_x509_crt *chain,
|
||||
const unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_x509_crt_ext_cb_t cb
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Parse a single DER formatted certificate and add it
|
||||
* to the end of the provided chained list. This is a
|
||||
|
@ -892,7 +892,8 @@ 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 )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
@ -955,6 +956,10 @@ 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 && cb(crt, &extn_oid, is_critical, p, end_ext_octet) == 0)
|
||||
continue;
|
||||
|
||||
/* No parser found, skip extension */
|
||||
*p = end_ext_octet;
|
||||
|
||||
@ -1061,7 +1066,8 @@ 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 )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
size_t len;
|
||||
@ -1260,7 +1266,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 );
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_x509_crt_free( crt );
|
||||
@ -1323,7 +1329,8 @@ 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 )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
mbedtls_x509_crt *crt = chain, *prev = NULL;
|
||||
@ -1355,7 +1362,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 );
|
||||
if( ret != 0 )
|
||||
{
|
||||
if( prev )
|
||||
prev->next = NULL;
|
||||
@ -1373,14 +1381,22 @@ 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 ) );
|
||||
}
|
||||
|
||||
int mbedtls_x509_crt_parse_der_ext( mbedtls_x509_crt *chain,
|
||||
const unsigned char *buf,
|
||||
size_t buflen,
|
||||
mbedtls_x509_crt_ext_cb_t cb )
|
||||
{
|
||||
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1, cb ) );
|
||||
}
|
||||
|
||||
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 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user