[x509] Record root of trust used when validating a certificate

Record the root of trust used at the point that a certificate is
validated, redefine validation as checking a certificate against a
specific root of trust, and pass an explicit root of trust when
creating a TLS connection.

This allows a custom TLS connection to be used with a custom root of
trust, without causing any validated certificates to be treated as
valid for normal purposes.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2020-12-08 14:58:46 +00:00
parent 6e92d6213d
commit 39f5293492
13 changed files with 60 additions and 33 deletions

View File

@@ -284,7 +284,7 @@ int ocsp_check ( struct x509_certificate *cert,
/* Sanity checks */
assert ( cert != NULL );
assert ( issuer != NULL );
assert ( x509_is_valid ( issuer ) );
assert ( issuer->root != NULL );
/* Allocate and initialise check */
*ocsp = zalloc ( sizeof ( **ocsp ) );
@@ -915,7 +915,7 @@ int ocsp_validate ( struct ocsp_check *ocsp, time_t time ) {
*/
x509_invalidate ( signer );
if ( ( rc = x509_validate ( signer, ocsp->issuer, time,
NULL ) ) != 0 ) {
ocsp->issuer->root ) ) != 0 ) {
DBGC ( ocsp, "OCSP %p \"%s\" could not validate ",
ocsp, x509_name ( ocsp->cert ) );
DBGC ( ocsp, "signer \"%s\": %s\n",
@@ -961,7 +961,7 @@ int ocsp_validate ( struct ocsp_check *ocsp, time_t time ) {
/* Validate certificate against issuer */
if ( ( rc = x509_validate ( ocsp->cert, ocsp->issuer, time,
NULL ) ) != 0 ) {
ocsp->issuer->root ) ) != 0 ) {
DBGC ( ocsp, "OCSP %p \"%s\" could not validate certificate: "
"%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
return rc;

View File

@@ -1295,6 +1295,21 @@ int x509_check_time ( struct x509_certificate *cert, time_t time ) {
return 0;
}
/**
* Check if X.509 certificate is valid
*
* @v cert X.509 certificate
* @v root Root certificate list, or NULL to use default
*/
int x509_is_valid ( struct x509_certificate *cert, struct x509_root *root ) {
/* Use default root certificate store if none specified */
if ( ! root )
root = &root_certificates;
return ( cert->root == root );
}
/**
* Validate X.509 certificate
*
@@ -1321,7 +1336,7 @@ int x509_validate ( struct x509_certificate *cert,
root = &root_certificates;
/* Return success if certificate has already been validated */
if ( x509_is_valid ( cert ) )
if ( x509_is_valid ( cert, root ) )
return 0;
/* Fail if certificate is invalid at specified time */
@@ -1330,7 +1345,7 @@ int x509_validate ( struct x509_certificate *cert,
/* Succeed if certificate is a trusted root certificate */
if ( x509_check_root ( cert, root ) == 0 ) {
cert->flags |= X509_FL_VALIDATED;
cert->root = root;
cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
return 0;
}
@@ -1343,7 +1358,7 @@ int x509_validate ( struct x509_certificate *cert,
}
/* Fail unless issuer has already been validated */
if ( ! x509_is_valid ( issuer ) ) {
if ( ! x509_is_valid ( issuer, root ) ) {
DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
issuer, x509_name ( issuer ) );
@@ -1376,7 +1391,7 @@ int x509_validate ( struct x509_certificate *cert,
cert->path_remaining = max_path_remaining;
/* Mark certificate as valid */
cert->flags |= X509_FL_VALIDATED;
cert->root = root;
DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
cert, x509_name ( cert ) );