diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index 83a6954aac..9c3d4370fd 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -297,6 +297,14 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); */ int mbedtls_x509_self_test( int verbose ); +/* + * Internal module structs. + */ +typedef struct x509_verify_string { + int code; + const char *string; +} mbedtls_x509_verify_string; + /* * Internal module functions. You probably do not want to use these unless you * know you do. @@ -340,6 +348,9 @@ int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, const char *oid, size_t oid_len, unsigned char *sig, size_t size ); +int mbedtls_x509_verify_info( char *buf, size_t size, const char *prefix, + uint32_t flags, + const mbedtls_x509_verify_string *strings ); #define MBEDTLS_X509_SAFE_SNPRINTF \ do { \ diff --git a/include/mbedtls/x509_ocsp.h b/include/mbedtls/x509_ocsp.h index 1c63234f35..06875928f4 100644 --- a/include/mbedtls/x509_ocsp.h +++ b/include/mbedtls/x509_ocsp.h @@ -157,6 +157,23 @@ int mbedtls_x509_ocsp_response_info( char *buf, size_t size, const char *prefix, const mbedtls_x509_ocsp_response *resp ); +/** + * \brief Returns an informational string about the + * verification status of an OCSP response. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param flags Verification flags created by + * mbedtls_x509_ocsp_response_verify() + * + * \return The length of the string written (not including the + * terminated nul byte), or a negative error code. + */ +int mbedtls_x509_ocsp_response_verify_info( char *buf, size_t size, + const char *prefix, + uint32_t flags ); + /** * \brief Parse a single OCSP response * diff --git a/library/x509.c b/library/x509.c index 062d25c7c3..1729aa1e56 100644 --- a/library/x509.c +++ b/library/x509.c @@ -883,6 +883,39 @@ int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *s return( (int)( size - n ) ); } +/* + * Helper for constructing a human-readable string from verification flags + * created with mbedtls_x509_*_verify() e.g mbedtls_x509_cert_verify_info() + */ +int mbedtls_x509_verify_info( char *buf, size_t size, const char *prefix, + uint32_t flags, + const mbedtls_x509_verify_string *strings ) +{ + int ret; + const mbedtls_x509_verify_string *cur; + char *p = buf; + size_t n = size; + + for( cur = strings; cur->string != NULL ; cur++ ) + { + if( ( flags & cur->code ) == 0 ) + continue; + + ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); + MBEDTLS_X509_SAFE_SNPRINTF; + flags ^= cur->code; + } + + if( flags != 0 ) + { + ret = mbedtls_snprintf( p, n, "%sUnknown reason " + "(this should not happen)\n", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + } + + return( (int) ( size - n ) ); +} + /* * Helper for writing "RSA key size", "EC key size", etc */ diff --git a/library/x509_crt.c b/library/x509_crt.c index 6b48a68d23..1136ff7712 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -1713,12 +1713,7 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, return( (int) ( size - n ) ); } -struct x509_crt_verify_string { - int code; - const char *string; -}; - -static const struct x509_crt_verify_string x509_crt_verify_strings[] = { +static const mbedtls_x509_verify_string x509_crt_verify_strings[] = { { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, @@ -1745,29 +1740,8 @@ static const struct x509_crt_verify_string x509_crt_verify_strings[] = { int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, uint32_t flags ) { - int ret; - const struct x509_crt_verify_string *cur; - char *p = buf; - size_t n = size; - - for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) - { - if( ( flags & cur->code ) == 0 ) - continue; - - ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); - MBEDTLS_X509_SAFE_SNPRINTF; - flags ^= cur->code; - } - - if( flags != 0 ) - { - ret = mbedtls_snprintf( p, n, "%sUnknown reason " - "(this should not happen)\n", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - } - - return( (int) ( size - n ) ); + return( mbedtls_x509_verify_info( buf, size, prefix, flags, + x509_crt_verify_strings ) ); } #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) diff --git a/library/x509_ocsp.c b/library/x509_ocsp.c index 8559082cad..ee9f7d7113 100644 --- a/library/x509_ocsp.c +++ b/library/x509_ocsp.c @@ -2210,6 +2210,26 @@ int mbedtls_x509_ocsp_response_info( char *buf, size_t size, return( (int)( size - n ) ); } +static const mbedtls_x509_verify_string x509_ocsp_response_verify_strings[] = { + { MBEDTLS_X509_BADOCSP_RESPONSE_FUTURE, "The response validity starts in the future" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_BAD_RESPONSE_STATUS, "The response status is an exception value (i.e it is not 'success')" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_ISSUER_NOT_TRUSTED, "The response issuer certificate was not found or failed the acceptance requirements" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_NOT_TRUSTED, "The response is not correctly signed by an authorized responder" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_INCOMPLETE, "The response does not contain the status of all queried certificates" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_EXPIRED, "The response validity has expired" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_REVOKED_CERT, "The revocation status of at least one queried certificate is 'revoked'" }, + { MBEDTLS_X509_BADOCSP_RESPONSE_UNKNOWN_CERT, "The revocation status of at least one queried certificate is 'unknown'" }, + { 0, NULL }, +}; + +int mbedtls_x509_ocsp_response_verify_info( char *buf, size_t size, + const char *prefix, + uint32_t flags ) +{ + return( mbedtls_x509_verify_info( buf, size, prefix, flags, + x509_ocsp_response_verify_strings ) ); +} + int mbedtls_x509_ocsp_response_parse_file( mbedtls_x509_ocsp_response *resp, const char *path ) {