iPXE
cert_cmd.c
Go to the documentation of this file.
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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdio.h>
28#include <string.h>
29#include <errno.h>
30#include <getopt.h>
31#include <ipxe/x509.h>
32#include <ipxe/certstore.h>
33#include <ipxe/image.h>
34#include <ipxe/command.h>
35#include <ipxe/parseopt.h>
36#include <usr/imgmgmt.h>
37#include <usr/certmgmt.h>
38
39/** @file
40 *
41 * Certificate management commands
42 *
43 */
44
45/** "cert<xxx>" options */
47 /** Certificate subject name */
48 char *name;
49 /** Keep certificate file after parsing */
50 int keep;
51};
52
53/** "cert<xxx>" option list */
54static union {
55 /* "certstore" takes both options */
57 /* "certstat" takes only --subject */
59 /* "certfree" takes only --subject */
61} opts = {
62 .certstore = {
63 OPTION_DESC ( "subject", 's', required_argument,
65 OPTION_DESC ( "keep", 'k', no_argument,
66 struct cert_options, keep, parse_flag ),
67 },
68};
69
70/** A "cert<xxx>" command descriptor */
72 /** Command descriptor */
74 /** Payload
75 *
76 * @v cert X.509 certificate
77 * @ret rc Return status code
78 */
79 int ( * payload ) ( struct x509_certificate *cert );
80};
81
82/**
83 * Construct "cert<xxx>" command descriptor
84 *
85 * @v _struct Options structure type
86 * @v _options Option descriptor array
87 * @v _min_args Minimum number of non-option arguments
88 * @v _max_args Maximum number of non-option arguments
89 * @v _usage Command usage
90 * @v _payload Payload method
91 * @ret _command Command descriptor
92 */
93#define CERT_COMMAND_DESC( _struct, _options, _min_args, _max_args, \
94 _usage, _payload ) \
95 { \
96 .cmd = COMMAND_DESC ( _struct, _options, _min_args, \
97 _max_args, _usage ), \
98 .payload = _payload, \
99 }
100
101/**
102 * Execute "cert<xxx>" command
103 *
104 * @v argc Argument count
105 * @v argv Argument list
106 * @v certcmd Command descriptor
107 * @ret rc Return status code
108 */
109static int cert_exec ( int argc, char **argv,
110 struct cert_command_descriptor *certcmd ) {
111 struct command_descriptor *cmd = &certcmd->cmd;
112 struct cert_options opts;
113 struct image *image = NULL;
114 struct x509_certificate *cert;
115 struct x509_certificate *tmp;
116 unsigned int count = 0;
117 size_t offset = 0;
118 int next;
119 int rc;
120
121 /* Parse options */
122 if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
123 goto err_parse;
124
125 /* Acquire image, if applicable */
126 if ( ( optind < argc ) &&
127 ( ( rc = imgacquire ( argv[optind], 0, &image ) ) != 0 ) )
128 goto err_acquire;
129
130 /* Get first entry in certificate store */
132 store.list );
133
134 /* Iterate over certificates */
135 while ( 1 ) {
136
137 /* Get next certificate from image or store as applicable */
138 if ( image ) {
139
140 /* Get next certificate from image */
141 if ( offset >= image->len )
142 break;
143 next = image_x509 ( image, offset, &cert );
144 if ( next < 0 ) {
145 rc = next;
146 printf ( "Could not parse certificate: %s\n",
147 strerror ( rc ) );
148 goto err_x509;
149 }
150 offset = next;
151
152 } else {
153
154 /* Get next certificate from store */
155 cert = tmp;
156 if ( ! cert )
157 break;
158 tmp = list_next_entry ( tmp, &certstore.links,
159 store.list );
160 x509_get ( cert );
161 }
162
163 /* Skip non-matching names, if a name was specified */
164 if ( opts.name && ( x509_check_name ( cert, opts.name ) != 0 )){
165 x509_put ( cert );
166 continue;
167 }
168
169 /* Execute payload */
170 if ( ( rc = certcmd->payload ( cert ) ) != 0 ) {
171 x509_put ( cert );
172 goto err_payload;
173 }
174
175 /* Count number of certificates processed */
176 count++;
177
178 /* Drop reference to certificate */
179 x509_put ( cert );
180 }
181
182 /* Fail if a name was specified and no matching certificates
183 * were found.
184 */
185 if ( opts.name && ( count == 0 ) ) {
186 printf ( "\"%s\" : no such certificate\n", opts.name );
187 rc = -ENOENT;
188 goto err_none;
189 }
190
191 err_none:
192 err_payload:
193 err_x509:
194 if ( image && ( ! opts.keep ) )
196 err_acquire:
197 err_parse:
198 return rc;
199}
200
201/**
202 * "certstat" payload
203 *
204 * @v cert X.509 certificate
205 * @ret rc Return status code
206 */
207static int certstat_payload ( struct x509_certificate *cert ) {
208
209 certstat ( cert );
210 return 0;
211}
212
213/** "certstat" command descriptor */
215 CERT_COMMAND_DESC ( struct cert_options, opts.certstat, 0, 0, NULL,
217
218/**
219 * The "certstat" command
220 *
221 * @v argc Argument count
222 * @v argv Argument list
223 * @ret rc Return status code
224 */
225static int certstat_exec ( int argc, char **argv ) {
226
227 return cert_exec ( argc, argv, &certstat_cmd );
228}
229
230/**
231 * "certstore" payload
232 *
233 * @v cert X.509 certificate
234 * @ret rc Return status code
235 */
236static int certstore_payload ( struct x509_certificate *cert ) {
237
238 /* Mark certificate as having been added explicitly */
239 cert->flags |= X509_FL_EXPLICIT;
240
241 return 0;
242}
243
244/** "certstore" command descriptor */
246 CERT_COMMAND_DESC ( struct cert_options, opts.certstore, 0, 1,
247 "[<uri|image>]", certstore_payload );
248
249/**
250 * The "certstore" command
251 *
252 * @v argc Argument count
253 * @v argv Argument list
254 * @ret rc Return status code
255 */
256static int certstore_exec ( int argc, char **argv ) {
257
258 return cert_exec ( argc, argv, &certstore_cmd );
259}
260
261/**
262 * "certfree" payload
263 *
264 * @v cert X.509 certificate
265 * @ret rc Return status code
266 */
267static int certfree_payload ( struct x509_certificate *cert ) {
268
269 /* Remove from certificate store */
270 certstore_del ( cert );
271
272 return 0;
273}
274
275/** "certfree" command descriptor */
277 CERT_COMMAND_DESC ( struct cert_options, opts.certfree, 0, 0, NULL,
279
280/**
281 * The "certfree" command
282 *
283 * @v argc Argument count
284 * @v argv Argument list
285 * @ret rc Return status code
286 */
287static int certfree_exec ( int argc, char **argv ) {
288
289 return cert_exec ( argc, argv, &certfree_cmd );
290}
291
292/** Certificate management commands */
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
const char * name
Definition ath9k_hw.c:1986
uint16_t offset
Offset to command line.
Definition bzimage.h:3
static struct cert_command_descriptor certstat_cmd
"certstat" command descriptor
Definition cert_cmd.c:214
#define CERT_COMMAND_DESC(_struct, _options, _min_args, _max_args, _usage, _payload)
Construct "cert<xxx>" command descriptor.
Definition cert_cmd.c:93
static int certfree_exec(int argc, char **argv)
The "certfree" command.
Definition cert_cmd.c:287
static union @024010030001061367220137227263210031030210157031 opts
"cert<xxx>" option list
static struct cert_command_descriptor certstore_cmd
"certstore" command descriptor
Definition cert_cmd.c:245
static int certstore_payload(struct x509_certificate *cert)
"certstore" payload
Definition cert_cmd.c:236
static int cert_exec(int argc, char **argv, struct cert_command_descriptor *certcmd)
Execute "cert<xxx>" command.
Definition cert_cmd.c:109
static int certstat_exec(int argc, char **argv)
The "certstat" command.
Definition cert_cmd.c:225
static int certstore_exec(int argc, char **argv)
The "certstore" command.
Definition cert_cmd.c:256
static struct cert_command_descriptor certfree_cmd
"certfree" command descriptor
Definition cert_cmd.c:276
struct option_descriptor certfree[1]
Definition cert_cmd.c:60
static int certstat_payload(struct x509_certificate *cert)
"certstat" payload
Definition cert_cmd.c:207
struct option_descriptor certstat[1]
Definition cert_cmd.c:58
static int certfree_payload(struct x509_certificate *cert)
"certfree" payload
Definition cert_cmd.c:267
Certificate management.
void certstore_del(struct x509_certificate *cert)
Remove certificate from store.
Definition certstore.c:116
struct x509_chain certstore
Certificate store.
Definition certstore.c:90
Certificate store.
#define COMMAND(name, exec)
Definition command.h:27
uint32_t next
Next descriptor address.
Definition dwmac.h:11
Error codes.
int optind
Current option index.
Definition getopt.c:52
Parse command-line options.
@ required_argument
Option requires an argument.
Definition getopt.h:19
@ no_argument
Option does not take an argument.
Definition getopt.h:17
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOENT
No such file or directory.
Definition errno.h:515
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
void unregister_image(struct image *image)
Unregister executable image.
Definition image.c:358
Executable images.
int imgacquire(const char *name_uri, unsigned long timeout, struct image **image)
Acquire an image.
Definition imgmgmt.c:143
Image management.
String functions.
unsigned long tmp
Definition linux_pci.h:65
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
#define list_next_entry(pos, head, member)
Get the container of the next entry in a list.
Definition list.h:360
int parse_flag(char *text __unused, int *flag)
Parse flag.
Definition parseopt.c:227
int parse_string(char *text, char **value)
Parse string value.
Definition parseopt.c:74
int parse_options(int argc, char **argv, struct command_descriptor *cmd, void *opts)
Parse command-line options.
Definition parseopt.c:485
Command line option parsing.
#define OPTION_DESC(_longopt, _shortopt, _has_arg, _struct, _field, _parse)
Construct option descriptor.
Definition parseopt.h:68
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A "cert<xxx>" command descriptor.
Definition cert_cmd.c:71
struct command_descriptor cmd
Command descriptor.
Definition cert_cmd.c:73
int(* payload)(struct x509_certificate *cert)
Payload.
Definition cert_cmd.c:79
"cert<xxx>" options
Definition cert_cmd.c:46
int keep
Keep certificate file after parsing.
Definition cert_cmd.c:50
char * name
Certificate subject name.
Definition cert_cmd.c:48
A command descriptor.
Definition parseopt.h:78
An executable image.
Definition image.h:24
size_t len
Length of raw file image.
Definition image.h:56
A command-line option descriptor.
Definition parseopt.h:24
An X.509 certificate.
Definition x509.h:216
unsigned int flags
Flags.
Definition x509.h:224
struct x509_link store
Link in certificate store.
Definition x509.h:221
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465
int image_x509(struct image *image, size_t offset, struct x509_certificate **cert)
Extract X.509 certificate object from image.
Definition x509.c:1961
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition x509.c:1564
X.509 certificates.
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition x509.h:267
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition x509.h:278
@ X509_FL_EXPLICIT
Certificate was added explicitly at run time.
Definition x509.h:257