From 4f869eda64e2c6c4e02bfef74448bca4bf80279f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Sun, 24 Feb 2019 16:47:57 +0000 Subject: [PATCH] Make use of CRT acquire/release in mbedtls_x509_crt_info() This commit adapts `mbedtls_x509_crt_info()` to no longer access structure fields from `mbedtls_x509_crt` directly, but to instead query for a `mbedtls_x509_crt_frame` and `mbedtls_pk_context` and use these to extract the required CRT information. --- library/x509_crt.c | 265 ++++++++++++++++++++++++++++----------------- 1 file changed, 168 insertions(+), 97 deletions(-) diff --git a/library/x509_crt.c b/library/x509_crt.c index aa82c2cb2..63823d300 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1762,81 +1762,204 @@ static int x509_info_ext_key_usage( char **buf, size_t *size, return( 0 ); } +typedef struct mbedtls_x509_crt_sig_info +{ + mbedtls_md_type_t sig_md; + mbedtls_pk_type_t sig_pk; + void *sig_opts; + uint8_t crt_hash[MBEDTLS_MD_MAX_SIZE]; + size_t crt_hash_len; + mbedtls_x509_buf_raw sig; + mbedtls_x509_buf_raw issuer_raw; +} mbedtls_x509_crt_sig_info; + +static void x509_crt_free_sig_info( mbedtls_x509_crt_sig_info *info ) +{ +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + mbedtls_free( info->sig_opts ); +#else + ((void) info); +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ +} + +static int x509_crt_get_sig_info( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_crt_sig_info *info ) +{ + const mbedtls_md_info_t *md_info; + + md_info = mbedtls_md_info_from_type( frame->sig_md ); + if( mbedtls_md( md_info, frame->tbs.p, frame->tbs.len, + info->crt_hash ) != 0 ) + { + /* Note: this can't happen except after an internal error */ + return( -1 ); + } + + info->crt_hash_len = mbedtls_md_get_size( md_info ); + + /* Make sure that this function leaves the target structure + * ready to be freed, regardless of success of failure. */ + info->sig_opts = NULL; + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + { + int ret; + unsigned char *alg_start = frame->sig_alg.p; + unsigned char *alg_end = alg_start + frame->sig_alg.len; + + /* Get signature options -- currently only + * necessary for RSASSA-PSS. */ + ret = mbedtls_x509_get_sig_alg_raw( &alg_start, alg_end, &info->sig_md, + &info->sig_pk, &info->sig_opts ); + if( ret != 0 ) + { + /* Note: this can't happen except after an internal error */ + return( -1 ); + } + } +#else /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + info->sig_md = frame->sig_md; + info->sig_pk = frame->sig_pk; +#endif /* !MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + + info->issuer_raw = frame->issuer_raw; + info->sig = frame->sig; + return( 0 ); +} + /* * Return an informational string about the certificate. */ #define BEFORE_COLON 18 #define BC "18" int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ) + const mbedtls_x509_crt *crt_raw ) { int ret; size_t n; char *p; char key_size_str[BEFORE_COLON]; + mbedtls_x509_crt_frame *crt; + mbedtls_pk_context *pk; + + mbedtls_x509_name issuer, subject; + mbedtls_x509_sequence ext_key_usage, subject_alt_names; + mbedtls_x509_crt_sig_info sig_info; p = buf; n = size; - if( NULL == crt ) + memset( &sig_info, 0, sizeof( mbedtls_x509_crt_sig_info ) ); + if( NULL == crt_raw ) { ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; return( (int) ( size - n ) ); } + ret = x509_crt_frame_acquire( crt_raw, &crt ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + ret = x509_crt_pk_acquire( (mbedtls_x509_crt*) crt_raw, &pk ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = x509_crt_get_sig_info( crt, &sig_info ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = x509_crt_subject_from_frame( crt, &subject ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = x509_crt_issuer_from_frame( crt, &issuer ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = x509_crt_subject_alt_from_frame( crt, &subject_alt_names ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = x509_crt_ext_key_usage_from_frame( crt, &ext_key_usage ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", prefix, crt->version ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_snprintf( p, n, "%sserial number : ", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; - ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); - MBEDTLS_X509_SAFE_SNPRINTF; + { + mbedtls_x509_buf serial; + serial.p = crt->serial.p; + serial.len = crt->serial.len; + ret = mbedtls_snprintf( p, n, "%sserial number : ", + prefix ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; + ret = mbedtls_x509_serial_gets( p, n, &serial ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; + } ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; + ret = mbedtls_x509_dn_gets( p, n, &issuer ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; + ret = mbedtls_x509_dn_gets( p, n, &subject ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, crt->valid_from.year, crt->valid_from.mon, crt->valid_from.day, crt->valid_from.hour, crt->valid_from.min, crt->valid_from.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, crt->valid_to.year, crt->valid_to.mon, crt->valid_to.day, crt->valid_to.hour, crt->valid_to.min, crt->valid_to.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; ret = mbedtls_x509_sig_alg_gets( p, n, sig_info.sig_pk, sig_info.sig_md, sig_info.sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; /* Key size */ if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, - mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) + mbedtls_pk_get_name( pk ) ) ) != 0 ) { return( ret ); } ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &crt->pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF; + (int) mbedtls_pk_get_bitlen( pk ) ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; /* * Optional extensions @@ -1846,29 +1969,29 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, { ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, crt->ca_istrue ? "true" : "false" ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; if( crt->max_pathlen > 0 ) { ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; } } if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) { ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; if( ( ret = x509_info_subject_alt_name( &p, &n, - &crt->subject_alt_names ) ) != 0 ) + &subject_alt_names ) ) != 0 ) return( ret ); } if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) { ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) return( ret ); @@ -1877,7 +2000,7 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) { ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) return( ret ); @@ -1886,17 +2009,30 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) { ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; if( ( ret = x509_info_ext_key_usage( &p, &n, - &crt->ext_key_usage ) ) != 0 ) + &ext_key_usage ) ) != 0 ) return( ret ); } ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_ERROR; - return( (int) ( size - n ) ); + ret = (int) ( size - n ); + +cleanup: + + x509_crt_frame_release( crt_raw, crt ); + x509_crt_pk_release( (mbedtls_x509_crt*) crt_raw, pk ); + + x509_crt_free_sig_info( &sig_info ); + x509_free_name( issuer.next ); + x509_free_name( subject.next ); + x509_free_sequence( ext_key_usage.next ); + x509_free_sequence( subject_alt_names.next ); + + return( ret ); } struct x509_crt_verify_string { @@ -2273,71 +2409,6 @@ static int x509_crt_check_parent( const mbedtls_x509_crt_sig_info *sig_info, return( 0 ); } -typedef struct mbedtls_x509_crt_sig_info -{ - mbedtls_md_type_t sig_md; - mbedtls_pk_type_t sig_pk; - void *sig_opts; - uint8_t crt_hash[MBEDTLS_MD_MAX_SIZE]; - size_t crt_hash_len; - mbedtls_x509_buf_raw sig; - mbedtls_x509_buf_raw issuer_raw; -} mbedtls_x509_crt_sig_info; - -static void x509_crt_free_sig_info( mbedtls_x509_crt_sig_info *info ) -{ -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - mbedtls_free( info->sig_opts ); -#else - ((void) info); -#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ -} - -static int x509_crt_get_sig_info( mbedtls_x509_crt_frame const *frame, - mbedtls_x509_crt_sig_info *info ) -{ - const mbedtls_md_info_t *md_info; - - md_info = mbedtls_md_info_from_type( frame->sig_md ); - if( mbedtls_md( md_info, frame->tbs.p, frame->tbs.len, - info->crt_hash ) != 0 ) - { - /* Note: this can't happen except after an internal error */ - return( -1 ); - } - - info->crt_hash_len = mbedtls_md_get_size( md_info ); - - /* Make sure that this function leaves the target structure - * ready to be freed, regardless of success of failure. */ - info->sig_opts = NULL; - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) - { - int ret; - unsigned char *alg_start = frame->sig_alg.p; - unsigned char *alg_end = alg_start + frame->sig_alg.len; - - /* Get signature options -- currently only - * necessary for RSASSA-PSS. */ - ret = mbedtls_x509_get_sig_alg_raw( &alg_start, alg_end, &info->sig_md, - &info->sig_pk, &info->sig_opts ); - if( ret != 0 ) - { - /* Note: this can't happen except after an internal error */ - return( -1 ); - } - } -#else /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - info->sig_md = frame->sig_md; - info->sig_pk = frame->sig_pk; -#endif /* !MBEDTLS_X509_RSASSA_PSS_SUPPORT */ - - info->issuer_raw = frame->issuer_raw; - info->sig = frame->sig; - return( 0 ); -} - /* * Find a suitable parent for child in candidates, or return NULL. *