[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

@@ -46,7 +46,7 @@ FEATURE ( FEATURE_PROTOCOL, "HTTPS", DHCP_EB_FEATURE_HTTPS, 1 );
*/
static int https_filter ( struct http_connection *conn ) {
return add_tls ( &conn->socket, conn->uri->host );
return add_tls ( &conn->socket, conn->uri->host, NULL );
}
/** HTTPS URI opener */

View File

@@ -246,7 +246,7 @@ static int apply_syslogs_settings ( void ) {
}
/* Add TLS filter */
if ( ( rc = add_tls ( &syslogs, server ) ) != 0 ) {
if ( ( rc = add_tls ( &syslogs, server, NULL ) ) != 0 ) {
DBG ( "SYSLOGS cannot create TLS filter: %s\n",
strerror ( rc ) );
goto err_add_tls;

View File

@@ -1938,7 +1938,8 @@ static int tls_new_server_hello_done ( struct tls_connection *tls,
}
/* Begin certificate validation */
if ( ( rc = create_validator ( &tls->validator, tls->chain ) ) != 0 ) {
if ( ( rc = create_validator ( &tls->validator, tls->chain,
tls->root ) ) != 0 ) {
DBGC ( tls, "TLS %p could not start certificate validation: "
"%s\n", tls, strerror ( rc ) );
return rc;
@@ -3140,9 +3141,11 @@ static int tls_session ( struct tls_connection *tls, const char *name ) {
*
* @v xfer Data transfer interface
* @v name Host name
* @v root Root of trust (or NULL to use default)
* @ret rc Return status code
*/
int add_tls ( struct interface *xfer, const char *name ) {
int add_tls ( struct interface *xfer, const char *name,
struct x509_root *root ) {
struct tls_connection *tls;
int rc;
@@ -3160,6 +3163,7 @@ int add_tls ( struct interface *xfer, const char *name ) {
intf_init ( &tls->validator, &tls_validator_desc, &tls->refcnt );
process_init_stopped ( &tls->process, &tls_process_desc,
&tls->refcnt );
tls->root = root;
tls->version = TLS_VERSION_TLS_1_2;
tls_clear_cipher ( tls, &tls->tx_cipherspec );
tls_clear_cipher ( tls, &tls->tx_cipherspec_pending );

View File

@@ -73,6 +73,8 @@ struct validator {
/** Process */
struct process process;
/** Root of trust (or NULL to use default) */
struct x509_root *root;
/** X.509 certificate chain */
struct x509_chain *chain;
/** OCSP check */
@@ -554,7 +556,7 @@ static void validator_step ( struct validator *validator ) {
*/
now = time ( NULL );
if ( ( rc = x509_validate_chain ( validator->chain, now, NULL,
NULL ) ) == 0 ) {
validator->root ) ) == 0 ) {
DBGC ( validator, "VALIDATOR %p \"%s\" validated\n",
validator, validator_name ( validator ) );
validator_finished ( validator, 0 );
@@ -569,7 +571,7 @@ static void validator_step ( struct validator *validator ) {
issuer = link->cert;
if ( ! cert )
continue;
if ( ! x509_is_valid ( issuer ) )
if ( ! x509_is_valid ( issuer, validator->root ) )
continue;
/* The issuer is valid, but this certificate is not
* yet valid. If OCSP is applicable, start it.
@@ -621,9 +623,11 @@ static struct process_descriptor validator_process_desc =
*
* @v job Job control interface
* @v chain X.509 certificate chain
* @v root Root of trust, or NULL to use default
* @ret rc Return status code
*/
int create_validator ( struct interface *job, struct x509_chain *chain ) {
int create_validator ( struct interface *job, struct x509_chain *chain,
struct x509_root *root ) {
struct validator *validator;
int rc;
@@ -646,6 +650,7 @@ int create_validator ( struct interface *job, struct x509_chain *chain ) {
&validator->refcnt );
process_init ( &validator->process, &validator_process_desc,
&validator->refcnt );
validator->root = root;
validator->chain = x509_chain_get ( chain );
xferbuf_malloc_init ( &validator->buffer );