summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/crypto/rootcert.c65
-rw-r--r--src/include/ipxe/dhcp.h3
-rw-r--r--src/include/ipxe/settings.h3
3 files changed, 69 insertions, 2 deletions
diff --git a/src/crypto/rootcert.c b/src/crypto/rootcert.c
index 99ee9c87c..6a9e594cc 100644
--- a/src/crypto/rootcert.c
+++ b/src/crypto/rootcert.c
@@ -18,9 +18,13 @@
FILE_LICENCE ( GPL2_OR_LATER );
+#include <stdlib.h>
#include <ipxe/crypto.h>
#include <ipxe/sha256.h>
#include <ipxe/x509.h>
+#include <ipxe/settings.h>
+#include <ipxe/dhcp.h>
+#include <ipxe/init.h>
#include <ipxe/rootcert.h>
/** @file
@@ -29,6 +33,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
+/** Length of a root certificate fingerprint */
+#define FINGERPRINT_LEN SHA256_DIGEST_SIZE
+
/* Use iPXE root CA if no trusted certificates are explicitly specified */
#ifndef TRUSTED
#define TRUSTED \
@@ -42,9 +49,65 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** Root certificate fingerprints */
static const uint8_t fingerprints[] = { TRUSTED };
+/** Root certificate fingerprint setting */
+struct setting trust_setting __setting ( SETTING_CRYPTO ) = {
+ .name = "trust",
+ .description = "Trusted root certificate fingerprint",
+ .tag = DHCP_EB_TRUST,
+ .type = &setting_type_hex,
+};
+
/** Root certificates */
struct x509_root root_certificates = {
.digest = &sha256_algorithm,
- .count = ( sizeof ( fingerprints ) / SHA256_DIGEST_SIZE ),
+ .count = ( sizeof ( fingerprints ) / FINGERPRINT_LEN ),
.fingerprints = fingerprints,
};
+
+/**
+ * Initialise root certificate
+ *
+ * We allow the list of trusted root certificate fingerprints to be
+ * overridden using the "trust" setting, but only at the point of iPXE
+ * initialisation. This prevents untrusted sources of settings
+ * (e.g. DHCP) from subverting the chain of trust, while allowing
+ * trustworthy sources (e.g. VMware GuestInfo or non-volatile stored
+ * options) to change the trusted root certificate without requiring a
+ * rebuild.
+ */
+static void rootcert_init ( void ) {
+ void *external;
+ int len;
+ int rc;
+
+ /* Fetch copy of "trust" setting, if it exists. This memory
+ * will never be freed.
+ */
+ len = fetch_setting_copy ( NULL, &trust_setting, &external );
+ if ( len < 0 ) {
+ rc = len;
+ DBGC ( &root_certificates, "ROOTCERT cannot fetch trusted "
+ "root certificate fingerprints: %s\n", strerror ( rc ) );
+ /* No way to prevent startup; fail safe by trusting no
+ * certificates.
+ */
+ root_certificates.count = 0;
+ return;
+ }
+
+ /* Use certificates from "trust" setting, if present */
+ if ( external ) {
+ root_certificates.fingerprints = external;
+ root_certificates.count = ( len / FINGERPRINT_LEN );
+ }
+
+ DBGC ( &root_certificates, "ROOTCERT using %d %s certificate(s):\n",
+ root_certificates.count, ( external ? "external" : "built-in" ));
+ DBGC_HDA ( &root_certificates, 0, root_certificates.fingerprints,
+ ( root_certificates.count * FINGERPRINT_LEN ) );
+}
+
+/** Root certificate initialiser */
+struct init_fn rootcert_init_fn __init_fn ( INIT_LATE ) = {
+ .initialise = rootcert_init,
+};
diff --git a/src/include/ipxe/dhcp.h b/src/include/ipxe/dhcp.h
index f5b3136ac..cc594ab1e 100644
--- a/src/include/ipxe/dhcp.h
+++ b/src/include/ipxe/dhcp.h
@@ -355,6 +355,9 @@ struct dhcp_client_uuid {
/** Encrypted syslog server */
#define DHCP_EB_SYSLOGS_SERVER DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x55 )
+/** Trusted root certficate fingerprints */
+#define DHCP_EB_TRUST DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5a )
+
/** Skip PXE DHCP protocol extensions such as ProxyDHCP
*
* If set to a non-zero value, iPXE will not wait for ProxyDHCP offers
diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h
index 34c0ed477..d0a142fad 100644
--- a/src/include/ipxe/settings.h
+++ b/src/include/ipxe/settings.h
@@ -83,7 +83,8 @@ struct setting {
#define SETTING_HOST_EXTRA 10 /**< Host identity additional settings */
#define SETTING_AUTH 11 /**< Authentication settings */
#define SETTING_AUTH_EXTRA 12 /**< Authentication additional settings */
-#define SETTING_MISC 13 /**< Miscellaneous settings */
+#define SETTING_CRYPTO 13 /**< Cryptography settings */
+#define SETTING_MISC 14 /**< Miscellaneous settings */
/** @} */