mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-25 19:25:45 +01:00
- Improved certificate validation and validation against the available CRLs
This commit is contained in:
parent
43ca69c38a
commit
76fd75a3de
@ -8,9 +8,11 @@ Note: Most of these features have been donated by Fox-IT
|
|||||||
for integration with OpenVPN
|
for integration with OpenVPN
|
||||||
* Added reading of DHM context from memory and file
|
* Added reading of DHM context from memory and file
|
||||||
* Added verification callback on certificate chain
|
* Added verification callback on certificate chain
|
||||||
verification to allow external blacklisting.
|
verification to allow external blacklisting
|
||||||
* Improved X509 certificate parsing to include extended
|
* Improved X509 certificate parsing to include extended
|
||||||
certificate fields, including Key Usage.
|
certificate fields, including Key Usage
|
||||||
|
* Improved certificate verification and verification
|
||||||
|
against the available CRLs
|
||||||
* Detection for DES weak keys and parity bits added
|
* Detection for DES weak keys and parity bits added
|
||||||
|
|
||||||
= Version 0.14.0 released on 2010-08-16
|
= Version 0.14.0 released on 2010-08-16
|
||||||
|
@ -2626,6 +2626,69 @@ static void x509_hash( const unsigned char *in, int len, int alg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the given certificate is valid accoring to the CRL.
|
||||||
|
*/
|
||||||
|
static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
|
||||||
|
x509_crl *crl_list)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
int hash_id;
|
||||||
|
unsigned char hash[64];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: What happens if no CRL is present?
|
||||||
|
* Suggestion: Revocation state should be unknown if no CRL is present.
|
||||||
|
* For backwards compatibility this is not yet implemented.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
|
||||||
|
{
|
||||||
|
if( crl_list->issuer_raw.len != ca->subject_raw.len ||
|
||||||
|
memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
|
||||||
|
crl_list->issuer_raw.len ) != 0 )
|
||||||
|
{
|
||||||
|
crl_list = crl_list->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if CRL is correctly signed by the trusted CA
|
||||||
|
*/
|
||||||
|
hash_id = crl_list->sig_alg;
|
||||||
|
|
||||||
|
x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
|
||||||
|
|
||||||
|
if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
|
||||||
|
0, hash, crl_list->sig.p ) == 0 )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* CRL is not trusted
|
||||||
|
*/
|
||||||
|
flags |= BADCRL_NOT_TRUSTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for validity of CRL (Do not drop out)
|
||||||
|
*/
|
||||||
|
if( x509parse_time_expired( &crl_list->next_update ) )
|
||||||
|
flags |= BADCRL_EXPIRED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if certificate is revoked
|
||||||
|
*/
|
||||||
|
if( x509parse_revoked(crt, crl_list) )
|
||||||
|
{
|
||||||
|
flags |= BADCERT_REVOKED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
crl_list = crl_list->next;
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify the certificate validity
|
* Verify the certificate validity
|
||||||
*/
|
*/
|
||||||
@ -2639,7 +2702,7 @@ int x509parse_verify( x509_cert *crt,
|
|||||||
int cn_len;
|
int cn_len;
|
||||||
int hash_id;
|
int hash_id;
|
||||||
int pathlen;
|
int pathlen;
|
||||||
x509_cert *cur;
|
x509_cert *parent;
|
||||||
x509_name *name;
|
x509_name *name;
|
||||||
unsigned char hash[64];
|
unsigned char hash[64];
|
||||||
|
|
||||||
@ -2667,26 +2730,22 @@ int x509parse_verify( x509_cert *crt,
|
|||||||
*flags |= BADCERT_CN_MISMATCH;
|
*flags |= BADCERT_CN_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
*flags |= BADCERT_NOT_TRUSTED;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterate upwards in the given cert chain,
|
* Iterate upwards in the given cert chain,
|
||||||
* ignoring any upper cert with CA != TRUE.
|
* ignoring any upper cert with CA != TRUE.
|
||||||
*/
|
*/
|
||||||
cur = crt->next;
|
parent = crt->next;
|
||||||
|
|
||||||
pathlen = 1;
|
pathlen = 1;
|
||||||
|
|
||||||
while( cur != NULL && cur->version != 0 )
|
while( parent != NULL && parent->version != 0 )
|
||||||
{
|
{
|
||||||
int verify_ok = 1;
|
if( parent->ca_istrue == 0 ||
|
||||||
|
crt->issuer_raw.len != parent->subject_raw.len ||
|
||||||
if( cur->ca_istrue == 0 ||
|
memcmp( crt->issuer_raw.p, parent->subject_raw.p,
|
||||||
crt->issuer_raw.len != cur->subject_raw.len ||
|
|
||||||
memcmp( crt->issuer_raw.p, cur->subject_raw.p,
|
|
||||||
crt->issuer_raw.len ) != 0 )
|
crt->issuer_raw.len ) != 0 )
|
||||||
{
|
{
|
||||||
cur = cur->next;
|
parent = parent->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2694,28 +2753,35 @@ int x509parse_verify( x509_cert *crt,
|
|||||||
|
|
||||||
x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
|
x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
|
||||||
|
|
||||||
if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
|
if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
|
||||||
0, hash, crt->sig.p ) != 0 )
|
crt->sig.p ) != 0 )
|
||||||
verify_ok = 0;
|
*flags |= BADCERT_NOT_TRUSTED;
|
||||||
|
|
||||||
|
/* Check trusted CA's CRL for the given crt */
|
||||||
|
*flags |= x509parse_verifycrl(crt, parent, ca_crl);
|
||||||
|
|
||||||
/* crt is verified to be a child of the parent cur, call verify callback */
|
/* crt is verified to be a child of the parent cur, call verify callback */
|
||||||
if( NULL != f_vrfy )
|
if( NULL != f_vrfy )
|
||||||
{
|
{
|
||||||
if ( f_vrfy( p_vrfy, crt, pathlen-1, verify_ok ) != 0 )
|
if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
|
||||||
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
|
||||||
} else if ( verify_ok == 0 ) {
|
|
||||||
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
||||||
|
else
|
||||||
|
*flags = 0;
|
||||||
}
|
}
|
||||||
|
else if( *flags != 0 )
|
||||||
|
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
||||||
|
|
||||||
pathlen++;
|
pathlen++;
|
||||||
|
|
||||||
crt = cur;
|
crt = parent;
|
||||||
cur = crt->next;
|
parent = crt->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atempt to validate topmost cert with our CA chain.
|
* Attempt to validate topmost cert with our CA chain.
|
||||||
*/
|
*/
|
||||||
|
*flags |= BADCERT_NOT_TRUSTED;
|
||||||
|
|
||||||
while( trust_ca != NULL && trust_ca->version != 0 )
|
while( trust_ca != NULL && trust_ca->version != 0 )
|
||||||
{
|
{
|
||||||
if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
|
if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
|
||||||
@ -2747,71 +2813,19 @@ int x509parse_verify( x509_cert *crt,
|
|||||||
trust_ca = trust_ca->next;
|
trust_ca = trust_ca->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Check trusted CA's CRL for the given crt */
|
||||||
* TODO: What happens if no CRL is present?
|
*flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
|
||||||
* Suggestion: Revocation state should be unknown if no CRL is present.
|
|
||||||
* For backwards compatibility this is not yet implemented.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if the topmost certificate is revoked if the trusted CA is
|
|
||||||
* determined.
|
|
||||||
*/
|
|
||||||
while( trust_ca != NULL && ca_crl != NULL && ca_crl->version != 0 )
|
|
||||||
{
|
|
||||||
if( ca_crl->issuer_raw.len != trust_ca->subject_raw.len ||
|
|
||||||
memcmp( ca_crl->issuer_raw.p, trust_ca->subject_raw.p,
|
|
||||||
ca_crl->issuer_raw.len ) != 0 )
|
|
||||||
{
|
|
||||||
ca_crl = ca_crl->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if CRL is correctry signed by the trusted CA
|
|
||||||
*/
|
|
||||||
hash_id = ca_crl->sig_alg;
|
|
||||||
|
|
||||||
x509_hash( ca_crl->tbs.p, ca_crl->tbs.len, hash_id, hash );
|
|
||||||
|
|
||||||
if( !rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
|
|
||||||
0, hash, ca_crl->sig.p ) == 0 )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* CRL is not trusted
|
|
||||||
*/
|
|
||||||
*flags |= BADCRL_NOT_TRUSTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for validity of CRL (Do not drop out)
|
|
||||||
*/
|
|
||||||
if( x509parse_time_expired( &ca_crl->next_update ) )
|
|
||||||
*flags |= BADCRL_EXPIRED;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if certificate is revoked
|
|
||||||
*/
|
|
||||||
if( x509parse_revoked(crt, ca_crl) )
|
|
||||||
{
|
|
||||||
*flags |= BADCERT_REVOKED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ca_crl = ca_crl->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( *flags != 0 )
|
|
||||||
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
|
||||||
|
|
||||||
|
|
||||||
/* Verification succeeded, call callback on top cert */
|
/* Verification succeeded, call callback on top cert */
|
||||||
if( NULL != f_vrfy )
|
if( NULL != f_vrfy )
|
||||||
{
|
{
|
||||||
if ( f_vrfy(p_vrfy, crt, pathlen - 1, 1) != 0 )
|
if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 )
|
||||||
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
||||||
|
else
|
||||||
|
*flags = 0;
|
||||||
}
|
}
|
||||||
|
else if( *flags != 0 )
|
||||||
|
return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ depends_on:POLARSSL_SHA4_C
|
|||||||
x509_verify:"data_files/cert_sha512.crt":"data_files/test-ca.crt":"data_files/crl.pem":NULL:POLARSSL_ERR_X509_CERT_VERIFY_FAILED:0:&verify_none
|
x509_verify:"data_files/cert_sha512.crt":"data_files/test-ca.crt":"data_files/crl.pem":NULL:POLARSSL_ERR_X509_CERT_VERIFY_FAILED:0:&verify_none
|
||||||
|
|
||||||
X509 Certificate verification #20 (Not trusted Cert, allowing callback)
|
X509 Certificate verification #20 (Not trusted Cert, allowing callback)
|
||||||
x509_verify:"data_files/server2.crt":"data_files/server1.crt":"data_files/crl_expired.pem":NULL:POLARSSL_ERR_X509_CERT_VERIFY_FAILED:BADCERT_NOT_TRUSTED:&verify_all
|
x509_verify:"data_files/server2.crt":"data_files/server1.crt":"data_files/crl_expired.pem":NULL:0:0:&verify_all
|
||||||
|
|
||||||
X509 Parse Selftest
|
X509 Parse Selftest
|
||||||
depends_on:POLARSSL_MD5_C
|
depends_on:POLARSSL_MD5_C
|
||||||
|
Loading…
Reference in New Issue
Block a user