Bladeren bron

[crypto] Do not allow build-time cryptography settings to be overridden

If a root certificate has been explicitly specified at build time
using TRUST=/path/to/cert then do not allow this to be overridden even
from a trustworthy settings source (such as VMware GuestInfo).

Similarly, if a client certificate (and private key) has been
explicitly specified at build time, then do not allow it to be
overridden at runtime.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 jaren geleden
bovenliggende
commit
bd16deaa87
2 gewijzigde bestanden met toevoegingen van 101 en 63 verwijderingen
  1. 59
    40
      src/crypto/clientcert.c
  2. 42
    23
      src/crypto/rootcert.c

+ 59
- 40
src/crypto/clientcert.c Bestand weergeven

@@ -47,6 +47,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
47 47
 #warning "Attempting to embed private key with no corresponding certificate"
48 48
 #endif
49 49
 
50
+/* Allow client certificates to be overridden if not explicitly specified */
51
+#ifdef CERTIFICATE
52
+#define ALLOW_CERT_OVERRIDE 0
53
+#else
54
+#define ALLOW_CERT_OVERRIDE 1
55
+#endif
56
+
50 57
 /* Raw client certificate data */
51 58
 extern char client_certificate_data[];
52 59
 extern char client_certificate_len[];
@@ -72,13 +79,19 @@ __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
72 79
 	  ".previous\n\t" );
73 80
 
74 81
 /** Client certificate */
75
-struct client_certificate client_certificate;
82
+struct client_certificate client_certificate = {
83
+	.data = client_certificate_data,
84
+	.len = ( ( size_t ) client_certificate_len ),
85
+};
76 86
 
77 87
 /** Client private key */
78
-struct client_private_key client_private_key;
88
+struct client_private_key client_private_key = {
89
+	.data = client_private_key_data,
90
+	.len = ( ( size_t ) client_private_key_len ),
91
+};
79 92
 
80 93
 /** Client certificate setting */
81
-struct setting cert_setting __setting ( SETTING_CRYPTO ) = {
94
+static struct setting cert_setting __setting ( SETTING_CRYPTO ) = {
82 95
 	.name = "cert",
83 96
 	.description = "Client certificate",
84 97
 	.tag = DHCP_EB_CERT,
@@ -86,7 +99,7 @@ struct setting cert_setting __setting ( SETTING_CRYPTO ) = {
86 99
 };
87 100
 
88 101
 /** Client private key setting */
89
-struct setting key_setting __setting ( SETTING_CRYPTO ) = {
102
+static struct setting key_setting __setting ( SETTING_CRYPTO ) = {
90 103
 	.name = "key",
91 104
 	.description = "Client private key",
92 105
 	.tag = DHCP_EB_KEY,
@@ -99,45 +112,51 @@ struct setting key_setting __setting ( SETTING_CRYPTO ) = {
99 112
  * @ret rc		Return status code
100 113
  */
101 114
 static int clientcert_apply_settings ( void ) {
102
-	static void *cert;
103
-	static void *key;
115
+	static void *cert = NULL;
116
+	static void *key = NULL;
104 117
 	int len;
105 118
 	int rc;
106 119
 
107
-	/* Restore default client certificate */
108
-	client_certificate.data = client_certificate_data;
109
-	client_certificate.len = ( ( size_t ) client_certificate_len );
110
-
111
-	/* Fetch new client certificate, if any */
112
-	free ( cert );
113
-	len = fetch_setting_copy ( NULL, &cert_setting, &cert );
114
-	if ( len < 0 ) {
115
-		rc = len;
116
-		DBGC ( &client_certificate, "CLIENTCERT cannot fetch client "
117
-		       "certificate: %s\n", strerror ( rc ) );
118
-		return rc;
119
-	}
120
-	if ( cert ) {
121
-		client_certificate.data = cert;
122
-		client_certificate.len = len;
123
-	}
124
-
125
-	/* Restore default client private key */
126
-	client_private_key.data = client_private_key_data;
127
-	client_private_key.len = ( ( size_t ) client_private_key_len );
128
-
129
-	/* Fetch new client private key, if any */
130
-	free ( key );
131
-	len = fetch_setting_copy ( NULL, &key_setting, &key );
132
-	if ( len < 0 ) {
133
-		rc = len;
134
-		DBGC ( &client_certificate, "CLIENTCERT cannot fetch client "
135
-		       "private key: %s\n", strerror ( rc ) );
136
-		return rc;
137
-	}
138
-	if ( key ) {
139
-		client_private_key.data = key;
140
-		client_private_key.len = len;
120
+	/* Allow client certificate to be overridden only if
121
+	 * not explicitly specified at build time.
122
+	 */
123
+	if ( ALLOW_CERT_OVERRIDE ) {
124
+
125
+		/* Restore default client certificate */
126
+		client_certificate.data = client_certificate_data;
127
+		client_certificate.len = ( ( size_t ) client_certificate_len );
128
+
129
+		/* Fetch new client certificate, if any */
130
+		free ( cert );
131
+		len = fetch_setting_copy ( NULL, &cert_setting, &cert );
132
+		if ( len < 0 ) {
133
+			rc = len;
134
+			DBGC ( &client_certificate, "CLIENTCERT cannot fetch "
135
+			       "client certificate: %s\n", strerror ( rc ) );
136
+			return rc;
137
+		}
138
+		if ( cert ) {
139
+			client_certificate.data = cert;
140
+			client_certificate.len = len;
141
+		}
142
+
143
+		/* Restore default client private key */
144
+		client_private_key.data = client_private_key_data;
145
+		client_private_key.len = ( ( size_t ) client_private_key_len );
146
+
147
+		/* Fetch new client private key, if any */
148
+		free ( key );
149
+		len = fetch_setting_copy ( NULL, &key_setting, &key );
150
+		if ( len < 0 ) {
151
+			rc = len;
152
+			DBGC ( &client_certificate, "CLIENTCERT cannot fetch "
153
+			       "client private key: %s\n", strerror ( rc ) );
154
+			return rc;
155
+		}
156
+		if ( key ) {
157
+			client_private_key.data = key;
158
+			client_private_key.len = len;
159
+		}
141 160
 	}
142 161
 
143 162
 	/* Debug */

+ 42
- 23
src/crypto/rootcert.c Bestand weergeven

@@ -36,6 +36,13 @@ FILE_LICENCE ( GPL2_OR_LATER );
36 36
 /** Length of a root certificate fingerprint */
37 37
 #define FINGERPRINT_LEN SHA256_DIGEST_SIZE
38 38
 
39
+/* Allow trusted certificates to be overridden if not explicitly specified */
40
+#ifdef TRUSTED
41
+#define ALLOW_TRUST_OVERRIDE 0
42
+#else
43
+#define ALLOW_TRUST_OVERRIDE 1
44
+#endif
45
+
39 46
 /* Use iPXE root CA if no trusted certificates are explicitly specified */
40 47
 #ifndef TRUSTED
41 48
 #define TRUSTED								\
@@ -50,9 +57,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
50 57
 static const uint8_t fingerprints[] = { TRUSTED };
51 58
 
52 59
 /** Root certificate fingerprint setting */
53
-struct setting trust_setting __setting ( SETTING_CRYPTO ) = {
60
+static struct setting trust_setting __setting ( SETTING_CRYPTO ) = {
54 61
 	.name = "trust",
55
-	.description = "Trusted root certificate fingerprint",
62
+	.description = "Trusted root certificate fingerprints",
56 63
 	.tag = DHCP_EB_TRUST,
57 64
 	.type = &setting_type_hex,
58 65
 };
@@ -67,38 +74,50 @@ struct x509_root root_certificates = {
67 74
 /**
68 75
  * Initialise root certificate
69 76
  *
70
- * We allow the list of trusted root certificate fingerprints to be
71
- * overridden using the "trust" setting, but only at the point of iPXE
77
+ * The list of trusted root certificates can be specified at build
78
+ * time using the TRUST= build parameter.  If no certificates are
79
+ * specified, then the default iPXE root CA certificate is trusted.
80
+ *
81
+ * If no certificates were explicitly specified, then we allow the
82
+ * list of trusted root certificate fingerprints to be overridden
83
+ * using the "trust" setting, but only at the point of iPXE
72 84
  * initialisation.  This prevents untrusted sources of settings
73 85
  * (e.g. DHCP) from subverting the chain of trust, while allowing
74 86
  * trustworthy sources (e.g. VMware GuestInfo or non-volatile stored
75
- * options) to change the trusted root certificate without requiring a
76
- * rebuild.
87
+ * options) to specify the trusted root certificate without requiring
88
+ * a rebuild.
77 89
  */
78 90
 static void rootcert_init ( void ) {
79
-	void *external;
91
+	void *external = NULL;
80 92
 	int len;
81 93
 	int rc;
82 94
 
83
-	/* Fetch copy of "trust" setting, if it exists.  This memory
84
-	 * will never be freed.
95
+	/* Allow trusted root certificates to be overridden only if
96
+	 * not explicitly specified at build time.
85 97
 	 */
86
-	len = fetch_setting_copy ( NULL, &trust_setting, &external );
87
-	if ( len < 0 ) {
88
-		rc = len;
89
-		DBGC ( &root_certificates, "ROOTCERT cannot fetch trusted "
90
-		       "root certificate fingerprints: %s\n", strerror ( rc ) );
91
-		/* No way to prevent startup; fail safe by trusting no
92
-		 * certificates.
98
+	if ( ALLOW_TRUST_OVERRIDE ) {
99
+
100
+		/* Fetch copy of "trust" setting, if it exists.  This
101
+		 * memory will never be freed.
93 102
 		 */
94
-		root_certificates.count = 0;
95
-		return;
96
-	}
103
+		len = fetch_setting_copy ( NULL, &trust_setting, &external );
104
+		if ( len < 0 ) {
105
+			rc = len;
106
+			DBGC ( &root_certificates, "ROOTCERT cannot fetch "
107
+			       "trusted root certificate fingerprints: %s\n",
108
+			       strerror ( rc ) );
109
+			/* No way to prevent startup; fail safe by
110
+			 * trusting no certificates.
111
+			 */
112
+			root_certificates.count = 0;
113
+			return;
114
+		}
97 115
 
98
-	/* Use certificates from "trust" setting, if present */
99
-	if ( external ) {
100
-		root_certificates.fingerprints = external;
101
-		root_certificates.count = ( len / FINGERPRINT_LEN );
116
+		/* Use certificates from "trust" setting, if present */
117
+		if ( external ) {
118
+			root_certificates.fingerprints = external;
119
+			root_certificates.count = ( len / FINGERPRINT_LEN );
120
+		}
102 121
 	}
103 122
 
104 123
 	DBGC ( &root_certificates, "ROOTCERT using %d %s certificate(s):\n",

Laden…
Annuleren
Opslaan