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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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 */
46 struct cert_options {
47  /** Certificate subject name */
48  char *name;
49  /** Keep certificate file after parsing */
50  int keep;
51 };
52 
53 /** "cert<xxx>" option list */
54 static 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,
64  struct cert_options, name, parse_string ),
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  */
109 static 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 */
131  tmp = list_first_entry ( &certstore.links, struct x509_certificate,
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  */
207 static 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  */
225 static 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  */
236 static 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  */
256 static 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  */
267 static 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  */
287 static int certfree_exec ( int argc, char **argv ) {
288 
289  return cert_exec ( argc, argv, &certfree_cmd );
290 }
291 
292 /** Certificate management commands */
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
FILE_SECBOOT(PERMITTED)
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:465
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition: x509.h:267
static int certstat_exec(int argc, char **argv)
The "certstat" command.
Definition: cert_cmd.c:225
int optind
Current option index.
Definition: getopt.c:52
static int cert_exec(int argc, char **argv, struct cert_command_descriptor *certcmd)
Execute "cert<xxx>" command.
Definition: cert_cmd.c:109
static int certstore_exec(int argc, char **argv)
The "certstore" command.
Definition: cert_cmd.c:256
int(* payload)(struct x509_certificate *cert)
Payload.
Definition: cert_cmd.c:79
Error codes.
static struct cert_command_descriptor certfree_cmd
"certfree" command descriptor
Definition: cert_cmd.c:276
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition: x509.c:1564
static struct cert_command_descriptor certstore_cmd
"certstore" command descriptor
Definition: cert_cmd.c:245
int keep
Keep certificate file after parsing.
Definition: cert_cmd.c:50
#define ENOENT
No such file or directory.
Definition: errno.h:515
#define list_next_entry(pos, head, member)
Get the container of the next entry in a list.
Definition: list.h:360
int parse_options(int argc, char **argv, struct command_descriptor *cmd, void *opts)
Parse command-line options.
Definition: parseopt.c:485
void certstore_del(struct x509_certificate *cert)
Remove certificate from store.
Definition: certstore.c:116
An executable image.
Definition: image.h:24
A command descriptor.
Definition: parseopt.h:78
struct option_descriptor certstat[1]
Definition: cert_cmd.c:58
unsigned int flags
Flags.
Definition: x509.h:224
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
Certificate store.
Parse command-line options.
int parse_string(char *text, char **value)
Parse string value.
Definition: parseopt.c:74
Executable images.
struct option_descriptor certfree[1]
Definition: cert_cmd.c:60
COMMAND(certstat, certstat_exec)
Certificate management commands.
static int certstore_payload(struct x509_certificate *cert)
"certstore" payload
Definition: cert_cmd.c:236
#define CERT_COMMAND_DESC(_struct, _options, _min_args, _max_args, _usage, _payload)
Construct "cert<xxx>" command descriptor.
Definition: cert_cmd.c:93
static unsigned int count
Number of entries.
Definition: dwmac.h:225
A "cert<xxx>" command descriptor.
Definition: cert_cmd.c:71
int parse_flag(char *text __unused, int *flag)
Parse flag.
Definition: parseopt.c:227
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An X.509 certificate.
Definition: x509.h:216
size_t len
Length of raw file image.
Definition: image.h:56
"cert<xxx>" options
Definition: cert_cmd.c:46
Command line option parsing.
Option does not take an argument.
Definition: getopt.h:17
static int certstat_payload(struct x509_certificate *cert)
"certstat" payload
Definition: cert_cmd.c:207
Certificate management.
X.509 certificates.
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
struct command_descriptor cmd
Command descriptor.
Definition: cert_cmd.c:73
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:358
char * name
Certificate subject name.
Definition: cert_cmd.c:48
Image management.
struct option_descriptor certstore[2]
Certificate store.
Definition: cert_cmd.c:56
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:278
static struct cert_command_descriptor certstat_cmd
"certstat" command descriptor
Definition: cert_cmd.c:214
#define OPTION_DESC(_longopt, _shortopt, _has_arg, _struct, _field, _parse)
Construct option descriptor.
Definition: parseopt.h:68
Option requires an argument.
Definition: getopt.h:19
A command-line option descriptor.
Definition: parseopt.h:24
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct x509_link store
Link in certificate store.
Definition: x509.h:221
static union @447 opts
"cert<xxx>" option list
int image_x509(struct image *image, size_t offset, struct x509_certificate **cert)
Extract X.509 certificate object from image.
Definition: x509.c:1961
static int certfree_payload(struct x509_certificate *cert)
"certfree" payload
Definition: cert_cmd.c:267
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct golan_eqe_cmd cmd
Definition: CIB_PRM.h:29
Certificate was added explicitly at run time.
Definition: x509.h:257
String functions.
int imgacquire(const char *name_uri, unsigned long timeout, struct image **image)
Acquire an image.
Definition: imgmgmt.c:143
static int certfree_exec(int argc, char **argv)
The "certfree" command.
Definition: cert_cmd.c:287