Parse top-level OCSP ResponseData

Populate the function x509_ocsp_get_response_data() with code that
parses the following ASN.1 structure:

   ResponseData ::= SEQUENCE {
      version              [0] EXPLICIT Version DEFAULT v1,
      responderID              ResponderID,
      producedAt               GeneralizedTime,
      responses                SEQUENCE OF SingleResponse,
      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }

x509_ocsp_get_response_data() will parse the top-level SEQUENCE and the
two EXPLICIT tags. It delegates the parsing of the individual
subcomponents to x509_ocsp_get_version(), x509_ocsp_get_responder_id(),
x509_ocsp_get_generalized_time(), x509_ocsp_get_responses() and
x509_ocsp_get_extensions().
This commit is contained in:
Andres Amaya Garcia
2017-08-25 10:46:38 +01:00
committed by Andres Amaya Garcia
parent 8f1e390a36
commit 4775cd3827
2 changed files with 144 additions and 9 deletions

View File

@@ -47,6 +47,8 @@
#define MBEDTLS_X509_OCSP_RESPONSE_STATUS_SIG_REQUIRED 5
#define MBEDTLS_X509_OCSP_RESPONSE_STATUS_UNAUTHORIZED 6
#define MBEDTLS_X509_OCSP_VERSION_1 0
/**
* \addtogroup x509_module
* \{
@@ -61,24 +63,41 @@ extern "C" {
* \{
*/
/**
* Container for an X.509 OCSP ResponderID.
*/
typedef struct mbedtls_x509_ocsp_responder_id {
} mbedtls_x509_ocsp_responder_id;
/**
* Container for an X.509 OCSP SingleResponse.
*/
typedef struct mbedtls_x509_ocsp_single_response {
} mbedtls_x509_ocsp_single_response;
/**
* Container for an X.509 OCSP response.
*/
typedef struct mbedtls_x509_ocsp_response {
mbedtls_x509_buf raw; /**< The raw response data (DER). */
mbedtls_x509_buf raw; /**< The raw response data (DER). */
mbedtls_x509_buf resp_type; /**< The type of response e.g. OCSP or BASIC */
uint8_t resp_status; /**< The OCSP response status */
uint8_t resp_status; /**< The OCSP response status */
mbedtls_x509_buf resp_type; /**< The type of response e.g. OCSP or BASIC */
mbedtls_x509_buf sig; /**< Signature computed on the hash of the ResponseData */
int version; /**< The OCSP response version. (0=v1) */
mbedtls_x509_ocsp_responder_id responder_id; /**< Internal representation of the ResponderID */
mbedtls_x509_time produced_at; /**< The time at which the OCSP responder signed this response */
mbedtls_x509_ocsp_single_response single_resp; /**< List of SingleResponse containers each containing the revocation status of a certificate */
mbedtls_x509_buf sig_oid; /**< Signature algorithm OID, e.g. sha1RSA */
mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
void *sig_opts; /**< Signature options passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
mbedtls_x509_buf sig; /**< Signature computed on the hash of the ResponseData */
mbedtls_x509_crt certs; /**< List of certificates included in the OCSP response */
mbedtls_x509_buf sig_oid; /**< Signature algorithm OID, e.g. sha1RSA */
mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
void *sig_opts; /**< Signature options passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
mbedtls_x509_crt certs; /**< List of certificates included in the OCSP response */
} mbedtls_x509_ocsp_response;
/**

View File

@@ -44,6 +44,11 @@
#include <stdint.h>
#include <string.h>
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
void mbedtls_x509_ocsp_response_init( mbedtls_x509_ocsp_response *resp )
{
}
@@ -113,9 +118,120 @@ static int x509_ocsp_get_response_type( unsigned char **p,
return( 0 );
}
static int x509_ocsp_get_extensions( unsigned char **p,
const unsigned char *end )
{
return( 0 );
}
static int x509_ocsp_get_response_version( unsigned char **p,
const unsigned char *end,
int *version )
{
return( 0 );
}
static int x509_ocsp_get_responder_id( unsigned char **p,
const unsigned char *end,
mbedtls_x509_ocsp_responder_id *responder_id )
{
return( 0 );
}
static int x509_ocsp_get_generalized_time( unsigned char **p,
const unsigned char *end,
mbedtls_x509_time *t )
{
return( 0 );
}
static int x509_ocsp_get_responses( unsigned char **p,
const unsigned char *end,
mbedtls_x509_ocsp_single_response *single_resp )
{
return( 0 );
}
static int x509_ocsp_get_response_data( mbedtls_x509_ocsp_response *resp,
unsigned char **p, const unsigned char *end )
{
int ret;
size_t len;
/*
* ResponseData ::= SEQUENCE {
* version [0] EXPLICIT Version DEFAULT v1,
* responderID ResponderID,
* producedAt GeneralizedTime,
* responses SEQUENCE OF SingleResponse,
* responseExtensions [1] EXPLICIT Extensions OPTIONAL }
*/
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;
/* Get the subcomponent [0] EXPLICIT ... DEFAULT v1 */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
{
/*
* Note that DEFAULT means that the version might not be present, in
* which case the value defaults to v1
*/
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
resp->version = MBEDTLS_X509_OCSP_VERSION_1;
else
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
}
/* Parse version */
else if( ( ret = x509_ocsp_get_response_version( p, *p + len,
&resp->version ) ) != 0 )
{
return( ret );
}
/* Parse responderID */
if( ( ret = x509_ocsp_get_responder_id( p, end,
&resp->responder_id ) ) != 0 )
{
return( ret );
}
/* Parse producedAt */
if( ( ret = x509_ocsp_get_generalized_time( p, end,
&resp->produced_at ) ) != 0 )
{
return( ret );
}
/* Parse responses */
if( ( ret = x509_ocsp_get_responses( p, end, &resp->single_resp ) ) != 0 )
return( ret );
/* responseExtensions is optional, so find out if there is more data */
if( *p == end )
return( 0 );
/* Get the [1] EXPLICIT tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_CONTEXT_SPECIFIC | 1 ) ) != 0 )
{
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
}
/* Parse responseExtensions */
if( ( ret = x509_ocsp_get_extensions( p, *p + len ) ) != 0 )
return( ret );
if( *p != end )
return( MBEDTLS_ERR_X509_INVALID_FORMAT +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}