mirror of https://github.com/ipxe/ipxe.git
[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>pull/108/head
parent
447e5cd447
commit
b28ccfc725
|
@ -47,6 +47,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
|||
#include <ipxe/certstore.h>
|
||||
#include <ipxe/rbg.h>
|
||||
#include <ipxe/validator.h>
|
||||
#include <ipxe/job.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/* Disambiguate the various error causes */
|
||||
|
@ -2570,12 +2571,31 @@ static int tls_plainstream_deliver ( struct tls_connection *tls,
|
|||
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 */
|
||||
static struct interface_operation tls_plainstream_ops[] = {
|
||||
INTF_OP ( xfer_deliver, struct tls_connection *,
|
||||
tls_plainstream_deliver ),
|
||||
INTF_OP ( xfer_window, struct tls_connection *,
|
||||
tls_plainstream_window ),
|
||||
INTF_OP ( job_progress, struct tls_connection *, tls_progress ),
|
||||
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/crc32.h>
|
||||
#include <ipxe/ocsp.h>
|
||||
#include <ipxe/job.h>
|
||||
#include <ipxe/validator.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 */
|
||||
struct validator {
|
||||
/** Reference count */
|
||||
|
@ -67,9 +79,16 @@ struct validator {
|
|||
struct ocsp_check *ocsp;
|
||||
/** Data buffer */
|
||||
struct xfer_buffer buffer;
|
||||
/** Action to take upon completed transfer */
|
||||
int ( * done ) ( struct validator *validator, const void *data,
|
||||
size_t len );
|
||||
|
||||
/** Current action */
|
||||
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 */
|
||||
static struct interface_operation validator_job_operations[] = {
|
||||
INTF_OP ( job_progress, struct validator *, validator_progress ),
|
||||
INTF_OP ( intf_close, struct validator *, validator_finished ),
|
||||
};
|
||||
|
||||
|
@ -236,6 +276,12 @@ static int validator_append ( struct validator *validator,
|
|||
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
|
||||
*
|
||||
|
@ -285,7 +331,8 @@ static int validator_start_download ( struct validator *validator,
|
|||
x509_name ( cert ), uri_string );
|
||||
|
||||
/* Set completion handler */
|
||||
validator->done = validator_append;
|
||||
validator->action = &validator_crosscert;
|
||||
validator->cert = cert;
|
||||
|
||||
/* Open URI */
|
||||
if ( ( rc = xfer_open_uri_string ( &validator->xfer,
|
||||
|
@ -350,6 +397,12 @@ static int validator_ocsp_validate ( struct validator *validator,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** OCSP validator action */
|
||||
static const struct validator_action validator_ocsp = {
|
||||
.name = "OCSP",
|
||||
.done = validator_ocsp_validate,
|
||||
};
|
||||
|
||||
/**
|
||||
* Start OCSP check
|
||||
*
|
||||
|
@ -374,7 +427,8 @@ static int validator_start_ocsp ( struct validator *validator,
|
|||
}
|
||||
|
||||
/* Set completion handler */
|
||||
validator->done = validator_ocsp_validate;
|
||||
validator->action = &validator_ocsp;
|
||||
validator->cert = cert;
|
||||
|
||||
/* Open URI */
|
||||
uri_string = validator->ocsp->uri_string;
|
||||
|
@ -421,9 +475,9 @@ static void validator_xfer_close ( struct validator *validator, int rc ) {
|
|||
validator, validator_name ( validator ) );
|
||||
|
||||
/* Process completed download */
|
||||
assert ( validator->done != NULL );
|
||||
if ( ( rc = validator->done ( validator, validator->buffer.data,
|
||||
validator->buffer.len ) ) != 0 )
|
||||
assert ( validator->action != NULL );
|
||||
if ( ( rc = validator->action->done ( validator, validator->buffer.data,
|
||||
validator->buffer.len ) ) != 0 )
|
||||
goto err_append;
|
||||
|
||||
/* Free downloaded data */
|
||||
|
|
Loading…
Reference in New Issue