mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-04-06 04:25:43 +02:00
Add verification for each OCSP SingleResponse
Add code that loops through every requested certificate and finds out the corresponding SingleResponse in the OCSP response. This code is the skeleton for the verification of each SingleResponse. However, at this stage the verification code is very minimal.
This commit is contained in:
@@ -995,6 +995,26 @@ int mbedtls_x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compare two X.509 certificate serial numbers
|
||||
*
|
||||
* See RFC 5380 Section 4.1.2.2. The encoding of a serial number is an ASN.1
|
||||
* integer. According to ISO/IEC 8825-1:2003, the encoding rules ensure that an
|
||||
* integer value is always encoded in the smallest possible number of octets.
|
||||
* Therefore, we do not have to worry about leading zeros.
|
||||
*
|
||||
* Return 0 if equal, -1 otherwise.
|
||||
*/
|
||||
int mbedtls_x509_serial_cmp( const mbedtls_x509_buf *a,
|
||||
const mbedtls_x509_buf *b )
|
||||
{
|
||||
if( a->len != b->len )
|
||||
return( -1 );
|
||||
|
||||
return( memcmp( a->p, b->p, a->len ) != 0 ? -1 : 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
||||
/*
|
||||
* Set the time structure to the current time.
|
||||
|
||||
@@ -1351,10 +1351,91 @@ exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int x509_ocsp_find_single_response( mbedtls_x509_crt *crt,
|
||||
mbedtls_x509_ocsp_single_response *chain,
|
||||
mbedtls_x509_ocsp_single_response **single_resp )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_ocsp_single_response *cur;
|
||||
|
||||
*single_resp = NULL;
|
||||
|
||||
/*
|
||||
*
|
||||
* TODO: This code will find the first SingleResponse element whose
|
||||
* certificate ID matches the current certificate being processed. If
|
||||
* the verification code below fails, then we do not look if there is
|
||||
* another SingleResponse for the same certificate that actually
|
||||
* checks out. However, this seems a bit strange and I am not sure if
|
||||
* it would happen in practice.
|
||||
*/
|
||||
for( cur = chain; cur != NULL; cur = cur->next )
|
||||
{
|
||||
/* Compare certificate and SingleResponse serial numbers */
|
||||
if( mbedtls_x509_serial_cmp( &crt->serial, &cur->serial ) != 0 )
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Ensure the certificate's issuer matches the SingleResponse
|
||||
* issuerNameHash in the certID
|
||||
*/
|
||||
ret = x509_ocsp_mdcmp( cur->md_alg, crt->issuer_raw.p,
|
||||
crt->issuer_raw.len, cur->issuer_name_hash.p );
|
||||
if( ret < 0 )
|
||||
return( ret );
|
||||
else if( ret != 0 )
|
||||
continue;
|
||||
|
||||
/* All checks passed, found SingleResponse that matches certificate */
|
||||
*single_resp = cur;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int x509_ocsp_verify_responses( mbedtls_x509_ocsp_response *resp,
|
||||
mbedtls_x509_crt *req_chain,
|
||||
mbedtls_x509_crt *chain,
|
||||
mbedtls_x509_crt *trust_ca,
|
||||
mbedtls_x509_crt *issuer,
|
||||
uint32_t *flags )
|
||||
{
|
||||
int ret;
|
||||
mbedtls_x509_crt *cur;
|
||||
mbedtls_x509_ocsp_single_response *single_resp;
|
||||
|
||||
/*
|
||||
* RFC 6960 Section 4.2.2.3: The response MUST include SingleResponse for
|
||||
* each certificate in the request. The response SHOULD NOT include any
|
||||
* additional SingleResponse elements...
|
||||
*/
|
||||
for( cur = req_chain; cur != NULL; cur = cur->next )
|
||||
{
|
||||
/* Identify the SingleResponse for this certificate */
|
||||
if( ( ret = x509_ocsp_find_single_response( cur, &resp->single_resp,
|
||||
&single_resp ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
else if( single_resp == NULL )
|
||||
{
|
||||
/* Flag if the SingleResponse for this certificate is not found */
|
||||
*flags |= MBEDTLS_X509_BADOCSP_RESPONSE_INCOMPLETE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* - We cannot accept locally configured signing authority for each CA
|
||||
* - We cannot accept a tolerance value for timestamps
|
||||
* - We cannot configure parameters such as allowed signature algorithms, etc
|
||||
* - Do not have an auth_mode=optional flag
|
||||
*/
|
||||
int mbedtls_x509_ocsp_verify_response( mbedtls_x509_ocsp_response *resp,
|
||||
mbedtls_x509_crt *req_chain,
|
||||
@@ -1404,6 +1485,13 @@ int mbedtls_x509_ocsp_verify_response( mbedtls_x509_ocsp_response *resp,
|
||||
if( ( ret = x509_ocsp_verify_sig( resp, issuer, flags ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/* Verify each of the responses */
|
||||
if( ( ret = x509_ocsp_verify_responses( resp, req_chain, chain, trust_ca,
|
||||
issuer, flags ) ) != 0 )
|
||||
{
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Fail if something does not check out */
|
||||
if( *flags != 0 )
|
||||
return( MBEDTLS_ERR_X509_OCSP_RESPONSE_VERIFY_FAILED );
|
||||
|
||||
Reference in New Issue
Block a user