Browse Source

[cmdline] Add certificate management commands

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
eed1258038
4 changed files with 309 additions and 0 deletions
  1. 3
    0
      src/config/config.c
  2. 1
    0
      src/config/general.h
  3. 304
    0
      src/hci/commands/cert_cmd.c
  4. 1
    0
      src/include/ipxe/errfile.h

+ 3
- 0
src/config/config.c View File

@@ -275,6 +275,9 @@ REQUIRE_OBJECT ( profstat_cmd );
275 275
 #ifdef NTP_CMD
276 276
 REQUIRE_OBJECT ( ntp_cmd );
277 277
 #endif
278
+#ifdef CERT_CMD
279
+REQUIRE_OBJECT ( cert_cmd );
280
+#endif
278 281
 
279 282
 /*
280 283
  * Drag in miscellaneous objects

+ 1
- 0
src/config/general.h View File

@@ -150,6 +150,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
150 150
 //#define IPSTAT_CMD		/* IP statistics commands */
151 151
 //#define PROFSTAT_CMD		/* Profiling commands */
152 152
 //#define NTP_CMD		/* NTP commands */
153
+//#define CERT_CMD		/* Certificate management commands */
153 154
 
154 155
 /*
155 156
  * ROM-specific options

+ 304
- 0
src/hci/commands/cert_cmd.c View File

@@ -0,0 +1,304 @@
1
+/*
2
+ * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ *
19
+ * You can also choose to distribute this program under the terms of
20
+ * the Unmodified Binary Distribution Licence (as given in the file
21
+ * COPYING.UBDL), provided that you have satisfied its requirements.
22
+ */
23
+
24
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
+
26
+#include <stdio.h>
27
+#include <errno.h>
28
+#include <getopt.h>
29
+#include <ipxe/x509.h>
30
+#include <ipxe/certstore.h>
31
+#include <ipxe/image.h>
32
+#include <ipxe/command.h>
33
+#include <ipxe/parseopt.h>
34
+#include <usr/imgmgmt.h>
35
+#include <usr/certmgmt.h>
36
+
37
+/** @file
38
+ *
39
+ * Certificate management commands
40
+ *
41
+ */
42
+
43
+/** "cert<xxx>" options */
44
+struct cert_options {
45
+	/** Certificate subject name */
46
+	char *name;
47
+	/** Keep certificate file after parsing */
48
+	int keep;
49
+};
50
+
51
+/** "cert<xxx>" option list */
52
+static union {
53
+	/* "certstore" takes both options */
54
+	struct option_descriptor certstore[2];
55
+	/* "certstat" takes only --subject */
56
+	struct option_descriptor certstat[1];
57
+	/* "certfree" takes only --subject */
58
+	struct option_descriptor certfree[1];
59
+} opts = {
60
+	.certstore = {
61
+		OPTION_DESC ( "subject", 's', required_argument,
62
+			      struct cert_options, name, parse_string ),
63
+		OPTION_DESC ( "keep", 'k', no_argument,
64
+			      struct cert_options, keep, parse_flag ),
65
+	},
66
+};
67
+
68
+/** A "cert<xxx>" command descriptor */
69
+struct cert_command_descriptor {
70
+	/** Command descriptor */
71
+	struct command_descriptor cmd;
72
+	/** Payload
73
+	 *
74
+	 * @v cert		X.509 certificate
75
+	 * @ret rc		Return status code
76
+	 */
77
+	int ( * payload ) ( struct x509_certificate *cert );
78
+};
79
+
80
+/**
81
+ * Construct "cert<xxx>" command descriptor
82
+ *
83
+ * @v _struct		Options structure type
84
+ * @v _options		Option descriptor array
85
+ * @v _min_args		Minimum number of non-option arguments
86
+ * @v _max_args		Maximum number of non-option arguments
87
+ * @v _usage		Command usage
88
+ * @v _payload		Payload method
89
+ * @ret _command	Command descriptor
90
+ */
91
+#define CERT_COMMAND_DESC( _struct, _options, _min_args, _max_args,	\
92
+			   _usage, _payload )				\
93
+	{								\
94
+		.cmd = COMMAND_DESC ( _struct, _options, _min_args,	\
95
+				      _max_args, _usage ),		\
96
+		.payload = _payload,					\
97
+	}
98
+
99
+/**
100
+ * Execute "cert<xxx>" command
101
+ *
102
+ * @v argc		Argument count
103
+ * @v argv		Argument list
104
+ * @v certcmd		Command descriptor
105
+ * @ret rc		Return status code
106
+ */
107
+static int cert_exec ( int argc, char **argv,
108
+		       struct cert_command_descriptor *certcmd ) {
109
+	struct command_descriptor *cmd = &certcmd->cmd;
110
+	struct cert_options opts;
111
+	struct image *image = NULL;
112
+	struct x509_certificate *cert;
113
+	struct x509_certificate *tmp;
114
+	unsigned int count = 0;
115
+	size_t offset = 0;
116
+	int next;
117
+	int rc;
118
+
119
+	/* Parse options */
120
+	if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
121
+		goto err_parse;
122
+
123
+	/* Acquire image, if applicable */
124
+	if ( ( optind < argc ) &&
125
+	     ( ( rc = imgacquire ( argv[optind], 0, &image ) ) != 0 ) )
126
+		goto err_acquire;
127
+
128
+	/* Get first entry in certificate store */
129
+	tmp = list_first_entry ( &certstore.links, struct x509_certificate,
130
+				 store.list );
131
+
132
+	/* Iterate over certificates */
133
+	while ( 1 ) {
134
+
135
+		/* Get next certificate from image or store as applicable */
136
+		if ( image ) {
137
+
138
+			/* Get next certificate from image */
139
+			if ( offset >= image->len )
140
+				break;
141
+			next = image_x509 ( image, offset, &cert );
142
+			if ( next < 0 ) {
143
+				rc = next;
144
+				printf ( "Could not parse certificate: %s\n",
145
+					 strerror ( rc ) );
146
+				goto err_x509;
147
+			}
148
+			offset = next;
149
+
150
+		} else {
151
+
152
+			/* Get next certificate from store */
153
+			cert = tmp;
154
+			if ( ! cert )
155
+				break;
156
+			tmp = list_next_entry ( tmp, &certstore.links,
157
+						store.list );
158
+			x509_get ( cert );
159
+		}
160
+
161
+		/* Skip non-matching names, if a name was specified */
162
+		if ( opts.name && ( x509_check_name ( cert, opts.name ) != 0 )){
163
+			x509_put ( cert );
164
+			continue;
165
+		}
166
+
167
+		/* Execute payload */
168
+		if ( ( rc = certcmd->payload ( cert ) ) != 0 ) {
169
+			x509_put ( cert );
170
+			goto err_payload;
171
+		}
172
+
173
+		/* Count number of certificates processed */
174
+		count++;
175
+
176
+		/* Drop reference to certificate */
177
+		x509_put ( cert );
178
+	}
179
+
180
+	/* Fail if a name was specified and no matching certificates
181
+	 * were found.
182
+	 */
183
+	if ( opts.name && ( count == 0 ) ) {
184
+		printf ( "\"%s\" : no such certificate\n", opts.name );
185
+		rc = -ENOENT;
186
+		goto err_none;
187
+	}
188
+
189
+ err_none:
190
+ err_payload:
191
+ err_x509:
192
+	if ( image && ( ! opts.keep ) )
193
+		unregister_image ( image );
194
+ err_acquire:
195
+ err_parse:
196
+	return rc;
197
+}
198
+
199
+/**
200
+ * "certstat" payload
201
+ *
202
+ * @v cert		X.509 certificate
203
+ * @ret rc		Return status code
204
+ */
205
+static int certstat_payload ( struct x509_certificate *cert ) {
206
+
207
+	certstat ( cert );
208
+	return 0;
209
+}
210
+
211
+/** "certstat" command descriptor */
212
+static struct cert_command_descriptor certstat_cmd =
213
+	CERT_COMMAND_DESC ( struct cert_options, opts.certstat, 0, 0, NULL,
214
+			    certstat_payload );
215
+
216
+/**
217
+ * The "certstat" command
218
+ *
219
+ * @v argc		Argument count
220
+ * @v argv		Argument list
221
+ * @ret rc		Return status code
222
+ */
223
+static int certstat_exec ( int argc, char **argv ) {
224
+
225
+	return cert_exec ( argc, argv, &certstat_cmd );
226
+}
227
+
228
+/**
229
+ * "certstore" payload
230
+ *
231
+ * @v cert		X.509 certificate
232
+ * @ret rc		Return status code
233
+ */
234
+static int certstore_payload ( struct x509_certificate *cert ) {
235
+
236
+	/* Mark certificate as having been added explicitly */
237
+	cert->flags |= X509_FL_EXPLICIT;
238
+
239
+	return 0;
240
+}
241
+
242
+/** "certstore" command descriptor */
243
+static struct cert_command_descriptor certstore_cmd =
244
+	CERT_COMMAND_DESC ( struct cert_options, opts.certstore, 0, 1,
245
+			    "[<uri|image>]", certstore_payload );
246
+
247
+/**
248
+ * The "certstore" command
249
+ *
250
+ * @v argc		Argument count
251
+ * @v argv		Argument list
252
+ * @ret rc		Return status code
253
+ */
254
+static int certstore_exec ( int argc, char **argv ) {
255
+
256
+	return cert_exec ( argc, argv, &certstore_cmd );
257
+}
258
+
259
+/**
260
+ * "certfree" payload
261
+ *
262
+ * @v cert		X.509 certificate
263
+ * @ret rc		Return status code
264
+ */
265
+static int certfree_payload ( struct x509_certificate *cert ) {
266
+
267
+	/* Remove from certificate store */
268
+	certstore_del ( cert );
269
+
270
+	return 0;
271
+}
272
+
273
+/** "certfree" command descriptor */
274
+static struct cert_command_descriptor certfree_cmd =
275
+	CERT_COMMAND_DESC ( struct cert_options, opts.certfree, 0, 0, NULL,
276
+			    certfree_payload );
277
+
278
+/**
279
+ * The "certfree" command
280
+ *
281
+ * @v argc		Argument count
282
+ * @v argv		Argument list
283
+ * @ret rc		Return status code
284
+ */
285
+static int certfree_exec ( int argc, char **argv ) {
286
+
287
+	return cert_exec ( argc, argv, &certfree_cmd );
288
+}
289
+
290
+/** Certificate management commands */
291
+struct command certmgmt_commands[] __command = {
292
+	{
293
+		.name = "certstat",
294
+		.exec = certstat_exec,
295
+	},
296
+	{
297
+		.name = "certstore",
298
+		.exec = certstore_exec,
299
+	},
300
+	{
301
+		.name = "certfree",
302
+		.exec = certfree_exec,
303
+	},
304
+};

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -359,6 +359,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
359 359
 #define ERRFILE_efi_fbcon	      ( ERRFILE_OTHER | 0x004c0000 )
360 360
 #define ERRFILE_efi_local	      ( ERRFILE_OTHER | 0x004d0000 )
361 361
 #define ERRFILE_efi_entropy	      ( ERRFILE_OTHER | 0x004e0000 )
362
+#define ERRFILE_cert_cmd	      ( ERRFILE_OTHER | 0x004f0000 )
362 363
 
363 364
 /** @} */
364 365
 

Loading…
Cancel
Save