From 98dc01ba6762d2c8c80246b4efc77990c7841799 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Fri, 25 Aug 2017 12:20:11 +0100 Subject: [PATCH] Parse CertStatus in OCSP response Populate the function x509_ocsp_get_cert_status() with code that parses the following ASN.1 structure: CertStatus ::= CHOICE { good [0] IMPLICIT NULL, revoked [1] IMPLICIT RevokedInfo, unknown [2] IMPLICIT UnknownInfo } x509_ocsp_get_cert_status() parses the top level CHOICE and IMPLICIT components. In the case of status good and unknown, their value is both expected to be NULL because according to RFC 6960 Section 4.2: UnknownInfo ::= NULL Therefore, no further parsing is needed here. In the case of status revoked, the parsing of Revoked info is delegated to a helper function. --- include/mbedtls/x509_ocsp.h | 5 ++++ library/x509_ocsp.c | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/mbedtls/x509_ocsp.h b/include/mbedtls/x509_ocsp.h index 45e73712fd..ac9ea88c45 100644 --- a/include/mbedtls/x509_ocsp.h +++ b/include/mbedtls/x509_ocsp.h @@ -38,6 +38,7 @@ #define MBEDTLS_ERR_X509_OCSP_INVALID_RESPONSE_STATUS -0x2A00 /**< The OCSP response status is invalid */ #define MBEDTLS_ERR_X509_OCSP_INVALID_RESPONSE_TYPE -0x2A10 /**< The OCSP response type is invalid */ +#define MBEDTLS_ERR_X509_OCSP_INVALID_CERT_STATUS -0x2A20 /**< A SingleResponse in the OCSP response specifies an invalid certificate status value */ /* OCSP response status values as defined in RFC 6960 Section 4.2.1 */ #define MBEDTLS_X509_OCSP_RESPONSE_STATUS_SUCCESSFUL 0 @@ -52,6 +53,10 @@ #define MBEDTLS_X509_OCSP_RESPONDER_ID_TYPE_NAME 1 #define MBEDTLS_X509_OCSP_RESPONDER_ID_TYPE_KEY_HASH 2 +#define MBEDTLS_X509_OCSP_CERT_STATUS_GOOD 0 +#define MBEDTLS_X509_OCSP_CERT_STATUS_REVOKED 1 +#define MBEDTLS_X509_OCSP_CERT_STATUS_UNKNOWN 2 + /** * \addtogroup x509_module * \{ diff --git a/library/x509_ocsp.c b/library/x509_ocsp.c index 64b9e863c3..81418a91b4 100644 --- a/library/x509_ocsp.c +++ b/library/x509_ocsp.c @@ -335,10 +335,66 @@ static int x509_ocsp_get_cert_id( unsigned char **p, return( 0 ); } +static int x509_ocsp_get_revoked_info( unsigned char **p, + const unsigned char *end, + mbedtls_x509_ocsp_single_response *single_resp ) +{ + return( 0 ); +} + static int x509_ocsp_get_cert_status( unsigned char **p, const unsigned char *end, mbedtls_x509_ocsp_single_response *single_resp ) { + int ret; + size_t len; + unsigned char tag; + const unsigned char status_good = MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_PRIMITIVE | + MBEDTLS_X509_OCSP_CERT_STATUS_GOOD; + const unsigned char status_unknown = MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_PRIMITIVE | + MBEDTLS_X509_OCSP_CERT_STATUS_UNKNOWN; + const unsigned char status_revoked = MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_X509_OCSP_CERT_STATUS_REVOKED; + + /* + * CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + */ + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + tag = **p; + ( *p )++; + + if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + end = *p + len; + + if( tag == status_good ) + single_resp->cert_status = MBEDTLS_X509_OCSP_CERT_STATUS_GOOD; + else if( tag == status_unknown ) + single_resp->cert_status = MBEDTLS_X509_OCSP_CERT_STATUS_UNKNOWN; + else if( tag == status_revoked ) + { + single_resp->cert_status = MBEDTLS_X509_OCSP_CERT_STATUS_REVOKED; + + if( ( ret = x509_ocsp_get_revoked_info( p, end, single_resp ) ) != 0 ) + return( ret ); + } + else + return( MBEDTLS_ERR_X509_OCSP_INVALID_CERT_STATUS ); + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + return( 0 ); }