Преглед на файлове

[crypto] Allow client certificate to be changed without a rebuild

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown преди 12 години
родител
ревизия
63d9cc28b9
променени са 2 файла, в които са добавени 98 реда и са изтрити 9 реда
  1. 92
    9
      src/crypto/clientcert.c
  2. 6
    0
      src/include/ipxe/dhcp.h

+ 92
- 9
src/crypto/clientcert.c Целия файл

@@ -19,6 +19,10 @@
19 19
 FILE_LICENCE ( GPL2_OR_LATER );
20 20
 
21 21
 #include <stdint.h>
22
+#include <stdlib.h>
23
+#include <string.h>
24
+#include <ipxe/dhcp.h>
25
+#include <ipxe/settings.h>
22 26
 #include <ipxe/clientcert.h>
23 27
 
24 28
 /** @file
@@ -55,12 +59,6 @@ __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
55 59
 	  ".equ client_certificate_len, ( . - client_certificate_data )\n\t"
56 60
 	  ".previous\n\t" );
57 61
 
58
-/** Client certificate */
59
-struct client_certificate client_certificate = {
60
-	.data = client_certificate_data,
61
-	.len = ( ( size_t ) client_certificate_len ),
62
-};
63
-
64 62
 /* Raw client private key data */
65 63
 extern char client_private_key_data[];
66 64
 extern char client_private_key_len[];
@@ -73,8 +71,93 @@ __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t"
73 71
 	  ".equ client_private_key_len, ( . - client_private_key_data )\n\t"
74 72
 	  ".previous\n\t" );
75 73
 
74
+/** Client certificate */
75
+struct client_certificate client_certificate;
76
+
76 77
 /** Client private key */
77
-struct client_private_key client_private_key = {
78
-	.data = client_private_key_data,
79
-	.len = ( ( size_t ) client_private_key_len ),
78
+struct client_private_key client_private_key;
79
+
80
+/** Client certificate setting */
81
+struct setting cert_setting __setting ( SETTING_CRYPTO ) = {
82
+	.name = "cert",
83
+	.description = "Client certificate",
84
+	.tag = DHCP_EB_CERT,
85
+	.type = &setting_type_hex,
86
+};
87
+
88
+/** Client private key setting */
89
+struct setting key_setting __setting ( SETTING_CRYPTO ) = {
90
+	.name = "key",
91
+	.description = "Client private key",
92
+	.tag = DHCP_EB_KEY,
93
+	.type = &setting_type_hex,
94
+};
95
+
96
+/**
97
+ * Apply client certificate store configuration settings
98
+ *
99
+ * @ret rc		Return status code
100
+ */
101
+static int clientcert_apply_settings ( void ) {
102
+	static void *cert;
103
+	static void *key;
104
+	int len;
105
+	int rc;
106
+
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;
141
+	}
142
+
143
+	/* Debug */
144
+	if ( have_client_certificate() ) {
145
+		DBGC ( &client_certificate, "CLIENTCERT using %s "
146
+		       "certificate:\n", ( cert ? "external" : "built-in" ) );
147
+		DBGC_HDA ( &client_certificate, 0, client_certificate.data,
148
+			   client_certificate.len );
149
+		DBGC ( &client_certificate, "CLIENTCERT using %s private "
150
+		       "key:\n", ( key ? "external" : "built-in" ) );
151
+		DBGC_HDA ( &client_certificate, 0, client_private_key.data,
152
+			   client_private_key.len );
153
+	} else {
154
+		DBGC ( &client_certificate, "CLIENTCERT has no certificate\n" );
155
+	}
156
+
157
+	return 0;
158
+}
159
+
160
+/** Client certificate store settings applicator */
161
+struct settings_applicator clientcert_applicator __settings_applicator = {
162
+	.apply = clientcert_apply_settings,
80 163
 };

+ 6
- 0
src/include/ipxe/dhcp.h Целия файл

@@ -358,6 +358,12 @@ struct dhcp_client_uuid {
358 358
 /** Trusted root certficate fingerprints */
359 359
 #define DHCP_EB_TRUST DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5a )
360 360
 
361
+/** Client certficate */
362
+#define DHCP_EB_CERT DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5b )
363
+
364
+/** Client private key */
365
+#define DHCP_EB_KEY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0x5c )
366
+
361 367
 /** Skip PXE DHCP protocol extensions such as ProxyDHCP
362 368
  *
363 369
  * If set to a non-zero value, iPXE will not wait for ProxyDHCP offers

Loading…
Отказ
Запис