From c239f478b70c190193c78f85bb517ff59e94f10a Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Sat, 11 Nov 2017 11:21:02 +0000 Subject: [PATCH] Store raw SubjectPublicKeyInfo when parsing cert Modify the x509_crt.c and pkparse.c slightly so that the certificate parsing (and mbedtls_x509_crt) keeps a pointer to the raw DER structure containing the SubjectPublicKeyInfo. This improves the efficiency of the OCSP response verification because we have to take the hash of the certificate's key. --- include/mbedtls/pk.h | 18 ++++++++++++++++++ include/mbedtls/x509_crt.h | 1 + library/pkparse.c | 16 ++++++++++++++++ library/x509_crt.c | 3 ++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index f9f9b9bb09..2d692d5f32 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -44,6 +44,8 @@ #include "ecdsa.h" #endif +#include "asn1.h" + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -584,6 +586,22 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_ */ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, mbedtls_pk_context *pk ); + +/** + * \brief Parse a SubjectPublicKeyInfo DER structure and store a + * pointer to the raw data + * + * \param p the position in the ASN.1 data + * \param end end of the buffer + * \param pk the key to fill + * \param buf the ASN.1 buffer pointing to the start of the raw DER + * + * \return 0 if successful, or a specific PK error code + */ +int mbedtls_pk_parse_subpubkey_with_buf( unsigned char **p, + const unsigned char *end, + mbedtls_pk_context *pk, + mbedtls_asn1_buf *buf ); #endif /* MBEDTLS_PK_PARSE_C */ #if defined(MBEDTLS_PK_WRITE_C) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 52c0d54591..f37aeccf0d 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -67,6 +67,7 @@ typedef struct mbedtls_x509_crt mbedtls_x509_time valid_from; /**< Start time of certificate validity. */ mbedtls_x509_time valid_to; /**< End time of certificate validity. */ + mbedtls_x509_buf pk_raw; mbedtls_pk_context pk; /**< Container for the public key context. */ mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ diff --git a/library/pkparse.c b/library/pkparse.c index efdf437466..d11bd55e74 100644 --- a/library/pkparse.c +++ b/library/pkparse.c @@ -578,6 +578,14 @@ static int pk_get_pk_alg( unsigned char **p, */ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, mbedtls_pk_context *pk ) +{ + return( mbedtls_pk_parse_subpubkey_with_buf( p, end, pk, NULL ) ); +} + +int mbedtls_pk_parse_subpubkey_with_buf( unsigned char **p, + const unsigned char *end, + mbedtls_pk_context *pk, + mbedtls_x509_buf *buf ) { int ret; size_t len; @@ -599,6 +607,14 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); + /* Keep track of the raw bitstring bytes */ + if( buf != NULL ) + { + buf->len = len; + buf->p = *p; + buf->tag = MBEDTLS_ASN1_BIT_STRING; + } + if( *p + len != end ) return( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); diff --git a/library/x509_crt.c b/library/x509_crt.c index 67cf44574e..6b48a68d23 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -948,7 +948,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char * /* * SubjectPublicKeyInfo */ - if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) + if( ( ret = mbedtls_pk_parse_subpubkey_with_buf( &p, end, &crt->pk, + &crt->pk_raw ) ) != 0 ) { mbedtls_x509_crt_free( crt ); return( ret );