mirror of
https://github.com/ipxe/ipxe
synced 2025-12-23 21:41:43 +03:00
[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:
@@ -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;
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
Reference in New Issue
Block a user