summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2019-03-07 16:23:19 +0100
committerMichael Brown2019-03-07 16:23:19 +0100
commitb28ccfc725c9a52401aaa09de0734a44bd44a02d (patch)
tree71079a5df8b8cee17161876081b746f908ee5b38
parent[crypto] Use x509_name() in validator debug messages (diff)
downloadipxe-b28ccfc725c9a52401aaa09de0734a44bd44a02d.tar.gz
ipxe-b28ccfc725c9a52401aaa09de0734a44bd44a02d.tar.xz
ipxe-b28ccfc725c9a52401aaa09de0734a44bd44a02d.zip
[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>
-rw-r--r--src/net/tls.c20
-rw-r--r--src/net/validator.c70
2 files changed, 82 insertions, 8 deletions
diff --git a/src/net/tls.c b/src/net/tls.c
index 1cd37e77..510bef8c 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -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 ),
};
diff --git a/src/net/validator.c b/src/net/validator.c
index 25d81bd2..f6b03ff4 100644
--- a/src/net/validator.c
+++ b/src/net/validator.c
@@ -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 */