diff --git a/include/mbedtls/x509_ocsp.h b/include/mbedtls/x509_ocsp.h index f1fe2b7ab6..45e73712fd 100644 --- a/include/mbedtls/x509_ocsp.h +++ b/include/mbedtls/x509_ocsp.h @@ -81,6 +81,23 @@ typedef struct mbedtls_x509_ocsp_responder_id { * Container for an X.509 OCSP SingleResponse. */ typedef struct mbedtls_x509_ocsp_single_response { + mbedtls_x509_buf md_oid; /**< Hash algorithm used to generate issuerHashName and issuesKeyHash */ + mbedtls_md_type_t md_alg; /**< Internal representation of the MD algorithm of the hash algorithm, e.g. MBEDTLS_MD_SHA256 */ + mbedtls_x509_buf issuer_name_hash; /**< Hash of the issues's distinduished name (DN) */ + mbedtls_x509_buf issues_key_hash; /**< Hash of issuer's public key */ + mbedtls_x509_buf serial; /**< The serial of the certificate that this SingleResponse corresponds to */ + + uint8_t cert_status; /**< The revocation status of the certificate with CertID, e.g. good, revoked, unknown */ + uint8_t revocation_reason; /**< Optional value that identifies the reason for the certificate revocation, e.g. keyCompromise, cACompromise, etc */ + int has_revocation_reason; /**< Whether the revocationReason value is present in the OCSP resposne */ + mbedtls_x509_time revocation_time; /**< The time at which the certificate was revoked or placed on hold */ + + mbedtls_x509_time this_update; /**< The most recent time at which the status is known to the responder to have been correct */ + + mbedtls_x509_time next_update; /**< The time at or before which newer information will be available about the status of the certificate */ + int has_next_update; /**< Whether the nextUpdate value is present in the OCSP response */ + + struct mbedtls_x509_ocsp_single_response *next; /**< Next SingleResponse in the list */ } mbedtls_x509_ocsp_single_response; /** diff --git a/library/x509_ocsp.c b/library/x509_ocsp.c index f1dbc3ef24..4d32fcaafb 100644 --- a/library/x509_ocsp.c +++ b/library/x509_ocsp.c @@ -251,10 +251,63 @@ static int x509_ocsp_get_generalized_time( unsigned char **p, return( 0 ); } +static int x509_ocsp_get_single_response( unsigned char **p, + const unsigned char *end, + mbedtls_x509_ocsp_single_response *cur ) +{ + return( 0 ); +} + static int x509_ocsp_get_responses( unsigned char **p, const unsigned char *end, mbedtls_x509_ocsp_single_response *single_resp ) { + int ret; + size_t len; + mbedtls_x509_ocsp_single_response *cur = single_resp; + + /* + * responses SEQUENCE OF SingleResponse + * + * Note: the standard allows an OCSPResponse that has no responses + */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + end = *p + len; + + while( *p < end ) + { + /* Allocate space for the next SingleResponse if necessary */ + if( cur->md_oid.p != NULL ) + { + /* + * This check prevents errors when populating an already used + * mbedtls_x509_ocsp_single_response + */ + if( cur->next != NULL ) + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + + cur->next = mbedtls_calloc( 1, + sizeof( mbedtls_x509_ocsp_single_response ) ); + if( cur->next == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + cur = cur->next; + } + + /* Parse SingleResponse and populate cur */ + if( ( ret = x509_ocsp_get_single_response( p, end, cur ) ) != 0 ) + return( ret ); + } + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + return( 0 ); }