mirror of
https://github.com/ipxe/ipxe
synced 2025-12-14 16:01:38 +03:00
[tls] Display cross-certificate and OCSP status messages
TLS connections will almost always create background connections to perform cross-signed certificate downloads and OCSP checks. There is currently no direct visibility into which checks are taking place, which makes troubleshooting difficult in the absence of either a packet capture or a debug build. Use the job progress message buffer to report the current cross-signed certificate download or OCSP status check, where applicable. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -47,6 +47,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||||||
#include <ipxe/certstore.h>
|
#include <ipxe/certstore.h>
|
||||||
#include <ipxe/rbg.h>
|
#include <ipxe/rbg.h>
|
||||||
#include <ipxe/validator.h>
|
#include <ipxe/validator.h>
|
||||||
|
#include <ipxe/job.h>
|
||||||
#include <ipxe/tls.h>
|
#include <ipxe/tls.h>
|
||||||
|
|
||||||
/* Disambiguate the various error causes */
|
/* Disambiguate the various error causes */
|
||||||
@@ -2570,12 +2571,31 @@ static int tls_plainstream_deliver ( struct tls_connection *tls,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report job progress
|
||||||
|
*
|
||||||
|
* @v tls TLS connection
|
||||||
|
* @v progress Progress report to fill in
|
||||||
|
* @ret ongoing_rc Ongoing job status code (if known)
|
||||||
|
*/
|
||||||
|
static int tls_progress ( struct tls_connection *tls,
|
||||||
|
struct job_progress *progress ) {
|
||||||
|
|
||||||
|
/* Return cipherstream or validator progress as applicable */
|
||||||
|
if ( tls_ready ( tls ) ) {
|
||||||
|
return job_progress ( &tls->cipherstream, progress );
|
||||||
|
} else {
|
||||||
|
return job_progress ( &tls->validator, progress );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** TLS plaintext stream interface operations */
|
/** TLS plaintext stream interface operations */
|
||||||
static struct interface_operation tls_plainstream_ops[] = {
|
static struct interface_operation tls_plainstream_ops[] = {
|
||||||
INTF_OP ( xfer_deliver, struct tls_connection *,
|
INTF_OP ( xfer_deliver, struct tls_connection *,
|
||||||
tls_plainstream_deliver ),
|
tls_plainstream_deliver ),
|
||||||
INTF_OP ( xfer_window, struct tls_connection *,
|
INTF_OP ( xfer_window, struct tls_connection *,
|
||||||
tls_plainstream_window ),
|
tls_plainstream_window ),
|
||||||
|
INTF_OP ( job_progress, struct tls_connection *, tls_progress ),
|
||||||
INTF_OP ( intf_close, struct tls_connection *, tls_close ),
|
INTF_OP ( intf_close, struct tls_connection *, tls_close ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ipxe/base64.h>
|
#include <ipxe/base64.h>
|
||||||
#include <ipxe/crc32.h>
|
#include <ipxe/crc32.h>
|
||||||
#include <ipxe/ocsp.h>
|
#include <ipxe/ocsp.h>
|
||||||
|
#include <ipxe/job.h>
|
||||||
#include <ipxe/validator.h>
|
#include <ipxe/validator.h>
|
||||||
#include <config/crypto.h>
|
#include <config/crypto.h>
|
||||||
|
|
||||||
@@ -49,6 +50,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct validator;
|
||||||
|
|
||||||
|
/** A certificate validator action */
|
||||||
|
struct validator_action {
|
||||||
|
/** Name */
|
||||||
|
const char *name;
|
||||||
|
/** Action to take upon completed transfer */
|
||||||
|
int ( * done ) ( struct validator *validator, const void *data,
|
||||||
|
size_t len );
|
||||||
|
};
|
||||||
|
|
||||||
/** A certificate validator */
|
/** A certificate validator */
|
||||||
struct validator {
|
struct validator {
|
||||||
/** Reference count */
|
/** Reference count */
|
||||||
@@ -67,9 +79,16 @@ struct validator {
|
|||||||
struct ocsp_check *ocsp;
|
struct ocsp_check *ocsp;
|
||||||
/** Data buffer */
|
/** Data buffer */
|
||||||
struct xfer_buffer buffer;
|
struct xfer_buffer buffer;
|
||||||
/** Action to take upon completed transfer */
|
|
||||||
int ( * done ) ( struct validator *validator, const void *data,
|
/** Current action */
|
||||||
size_t len );
|
const struct validator_action *action;
|
||||||
|
/** Current certificate
|
||||||
|
*
|
||||||
|
* This will always be present within the certificate chain
|
||||||
|
* and so this pointer does not hold a reference to the
|
||||||
|
* certificate.
|
||||||
|
*/
|
||||||
|
struct x509_certificate *cert;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,8 +142,29 @@ static void validator_finished ( struct validator *validator, int rc ) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report job progress
|
||||||
|
*
|
||||||
|
* @v validator Certificate validator
|
||||||
|
* @v progress Progress report to fill in
|
||||||
|
* @ret ongoing_rc Ongoing job status code (if known)
|
||||||
|
*/
|
||||||
|
static int validator_progress ( struct validator *validator,
|
||||||
|
struct job_progress *progress ) {
|
||||||
|
|
||||||
|
/* Report current action, if applicable */
|
||||||
|
if ( validator->action ) {
|
||||||
|
snprintf ( progress->message, sizeof ( progress->message ),
|
||||||
|
"%s %s", validator->action->name,
|
||||||
|
x509_name ( validator->cert ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Certificate validator job control interface operations */
|
/** Certificate validator job control interface operations */
|
||||||
static struct interface_operation validator_job_operations[] = {
|
static struct interface_operation validator_job_operations[] = {
|
||||||
|
INTF_OP ( job_progress, struct validator *, validator_progress ),
|
||||||
INTF_OP ( intf_close, struct validator *, validator_finished ),
|
INTF_OP ( intf_close, struct validator *, validator_finished ),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -236,6 +276,12 @@ static int validator_append ( struct validator *validator,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Cross-signing certificate download validator action */
|
||||||
|
static const struct validator_action validator_crosscert = {
|
||||||
|
.name = "XCRT",
|
||||||
|
.done = validator_append,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start download of cross-signing certificate
|
* Start download of cross-signing certificate
|
||||||
*
|
*
|
||||||
@@ -285,7 +331,8 @@ static int validator_start_download ( struct validator *validator,
|
|||||||
x509_name ( cert ), uri_string );
|
x509_name ( cert ), uri_string );
|
||||||
|
|
||||||
/* Set completion handler */
|
/* Set completion handler */
|
||||||
validator->done = validator_append;
|
validator->action = &validator_crosscert;
|
||||||
|
validator->cert = cert;
|
||||||
|
|
||||||
/* Open URI */
|
/* Open URI */
|
||||||
if ( ( rc = xfer_open_uri_string ( &validator->xfer,
|
if ( ( rc = xfer_open_uri_string ( &validator->xfer,
|
||||||
@@ -350,6 +397,12 @@ static int validator_ocsp_validate ( struct validator *validator,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** OCSP validator action */
|
||||||
|
static const struct validator_action validator_ocsp = {
|
||||||
|
.name = "OCSP",
|
||||||
|
.done = validator_ocsp_validate,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start OCSP check
|
* Start OCSP check
|
||||||
*
|
*
|
||||||
@@ -374,7 +427,8 @@ static int validator_start_ocsp ( struct validator *validator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set completion handler */
|
/* Set completion handler */
|
||||||
validator->done = validator_ocsp_validate;
|
validator->action = &validator_ocsp;
|
||||||
|
validator->cert = cert;
|
||||||
|
|
||||||
/* Open URI */
|
/* Open URI */
|
||||||
uri_string = validator->ocsp->uri_string;
|
uri_string = validator->ocsp->uri_string;
|
||||||
@@ -421,9 +475,9 @@ static void validator_xfer_close ( struct validator *validator, int rc ) {
|
|||||||
validator, validator_name ( validator ) );
|
validator, validator_name ( validator ) );
|
||||||
|
|
||||||
/* Process completed download */
|
/* Process completed download */
|
||||||
assert ( validator->done != NULL );
|
assert ( validator->action != NULL );
|
||||||
if ( ( rc = validator->done ( validator, validator->buffer.data,
|
if ( ( rc = validator->action->done ( validator, validator->buffer.data,
|
||||||
validator->buffer.len ) ) != 0 )
|
validator->buffer.len ) ) != 0 )
|
||||||
goto err_append;
|
goto err_append;
|
||||||
|
|
||||||
/* Free downloaded data */
|
/* Free downloaded data */
|
||||||
|
|||||||
Reference in New Issue
Block a user