aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/validator.c
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2012-05-08 12:10:01 +0100
committerMichael Brown <mcb30@ipxe.org>2012-05-08 12:49:01 +0100
commit29dcb0631b1c914fc74114dd3c6add39b508953f (patch)
tree67c95f2e62bd1a57effa32bb360169be92dc0265 /src/net/validator.c
parent1a5f025ad85c484697718eeba13680dc4ffebd24 (diff)
downloadipxe-29dcb0631b1c914fc74114dd3c6add39b508953f.tar.gz
[crypto] Add asynchronous certificate validator
To allow for automatic download of cross-signing certificates and for OCSP, the validation of certificates must be an asynchronous process. Create a stub validator which uses a job-control interface to report the result of certificate validation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/validator.c')
-rw-r--r--src/net/validator.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/net/validator.c b/src/net/validator.c
new file mode 100644
index 000000000..b6b52a213
--- /dev/null
+++ b/src/net/validator.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <string.h>
+#include <errno.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/malloc.h>
+#include <ipxe/interface.h>
+#include <ipxe/process.h>
+#include <ipxe/x509.h>
+#include <ipxe/validator.h>
+
+/** @file
+ *
+ * Certificate validator
+ *
+ */
+
+/** A certificate validator */
+struct validator {
+ /** Reference count */
+ struct refcnt refcnt;
+ /** Job control interface */
+ struct interface job;
+ /** Process */
+ struct process process;
+ /** X.509 certificate chain */
+ struct x509_chain *chain;
+};
+
+/**
+ * Free certificate validator
+ *
+ * @v refcnt Reference count
+ */
+static void validator_free ( struct refcnt *refcnt ) {
+ struct validator *validator =
+ container_of ( refcnt, struct validator, refcnt );
+
+ DBGC ( validator, "VALIDATOR %p freed\n", validator );
+ x509_chain_put ( validator->chain );
+ free ( validator );
+}
+
+/**
+ * Mark certificate validation as finished
+ *
+ * @v validator Certificate validator
+ * @v rc Reason for finishing
+ */
+static void validator_finished ( struct validator *validator, int rc ) {
+
+ /* Remove process */
+ process_del ( &validator->process );
+
+ /* Close all interfaces */
+ intf_shutdown ( &validator->job, rc );
+}
+
+/****************************************************************************
+ *
+ * Job control interface
+ *
+ */
+
+/** Certificate validator job control interface operations */
+static struct interface_operation validator_job_operations[] = {
+ INTF_OP ( intf_close, struct validator *, validator_finished ),
+};
+
+/** Certificate validator job control interface descriptor */
+static struct interface_descriptor validator_job_desc =
+ INTF_DESC ( struct validator, job, validator_job_operations );
+
+/****************************************************************************
+ *
+ * Validation process
+ *
+ */
+
+/**
+ * Certificate validation process
+ *
+ * @v validator Certificate validator
+ */
+static void validator_step ( struct validator *validator ) {
+ time_t now;
+ int rc;
+
+ /* Attempt to validate certificate chain */
+ now = time ( NULL );
+ if ( ( rc = x509_validate_chain ( validator->chain, now,
+ NULL ) ) != 0 ) {
+ DBGC ( validator, "VALIDATOR %p could not validate chain: %s\n",
+ validator, strerror ( rc ) );
+ goto err_validate;
+ }
+
+ /* Mark validation as complete */
+ validator_finished ( validator, 0 );
+
+ return;
+
+ err_validate:
+ validator_finished ( validator, rc );
+}
+
+/** Certificate validator process descriptor */
+static struct process_descriptor validator_process_desc =
+ PROC_DESC_ONCE ( struct validator, process, validator_step );
+
+/****************************************************************************
+ *
+ * Instantiator
+ *
+ */
+
+/**
+ * Instantiate a certificate validator
+ *
+ * @v job Job control interface
+ * @v chain X.509 certificate chain
+ * @ret rc Return status code
+ */
+int create_validator ( struct interface *job, struct x509_chain *chain ) {
+ struct validator *validator;
+ int rc;
+
+ /* Sanity check */
+ if ( ! chain ) {
+ rc = -EINVAL;
+ goto err_sanity;
+ }
+
+ /* Allocate and initialise structure */
+ validator = zalloc ( sizeof ( *validator ) );
+ if ( ! validator ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
+ ref_init ( &validator->refcnt, validator_free );
+ intf_init ( &validator->job, &validator_job_desc,
+ &validator->refcnt );
+ process_init ( &validator->process, &validator_process_desc,
+ &validator->refcnt );
+ validator->chain = x509_chain_get ( chain );
+
+ /* Attach parent interface, mortalise self, and return */
+ intf_plug_plug ( &validator->job, job );
+ ref_put ( &validator->refcnt );
+ DBGC ( validator, "VALIDATOR %p validating X509 chain %p\n",
+ validator, validator->chain );
+ return 0;
+
+ validator_finished ( validator, rc );
+ ref_put ( &validator->refcnt );
+ err_alloc:
+ err_sanity:
+ return rc;
+}