mirror of
https://github.com/ipxe/ipxe
synced 2026-02-07 08:02:49 +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:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
Reference in New Issue
Block a user