Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: utility/vbutil_keyblock.c

Issue 4194003: Add support for using external signing application and .pem private key files to vbutil_keyblock. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git
Patch Set: fix read() bug Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/run_vbutil_tests.sh ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * Verified boot key block utility 5 * Verified boot key block utility
6 */ 6 */
7 7
8 #include <getopt.h> 8 #include <getopt.h>
9 #include <inttypes.h> /* For PRIu64 */ 9 #include <stdint.h>
10 #include <stdio.h> 10 #include <stdio.h>
11 #include <stdlib.h> 11 #include <stdlib.h>
12 #include <string.h> 12 #include <string.h>
13 13
14 #include "cryptolib.h" 14 #include "cryptolib.h"
15 #include "host_common.h" 15 #include "host_common.h"
16 #include "vboot_common.h" 16 #include "vboot_common.h"
17 17
18 18
19 /* Command line options */ 19 /* Command line options */
20 enum { 20 enum {
21 OPT_MODE_PACK = 1000, 21 OPT_MODE_PACK = 1000,
22 OPT_MODE_UNPACK, 22 OPT_MODE_UNPACK,
23 OPT_DATAPUBKEY, 23 OPT_DATAPUBKEY,
24 OPT_SIGNPUBKEY, 24 OPT_SIGNPUBKEY,
25 OPT_SIGNPRIVATE, 25 OPT_SIGNPRIVATE,
26 OPT_SIGNPRIVATE_PEM,
27 OPT_PEM_ALGORITHM,
28 OPT_EXTERNAL_SIGNER,
26 OPT_FLAGS, 29 OPT_FLAGS,
27 }; 30 };
28 31
29 static struct option long_opts[] = { 32 static struct option long_opts[] = {
30 {"pack", 1, 0, OPT_MODE_PACK }, 33 {"pack", 1, 0, OPT_MODE_PACK },
31 {"unpack", 1, 0, OPT_MODE_UNPACK }, 34 {"unpack", 1, 0, OPT_MODE_UNPACK },
32 {"datapubkey", 1, 0, OPT_DATAPUBKEY }, 35 {"datapubkey", 1, 0, OPT_DATAPUBKEY },
33 {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, 36 {"signpubkey", 1, 0, OPT_SIGNPUBKEY },
34 {"signprivate", 1, 0, OPT_SIGNPRIVATE }, 37 {"signprivate", 1, 0, OPT_SIGNPRIVATE },
38 {"signprivate_pem", 1, 0, OPT_SIGNPRIVATE_PEM },
39 {"pem_algorithm", 1, 0, OPT_PEM_ALGORITHM },
40 {"externalsigner", 1, 0, OPT_EXTERNAL_SIGNER },
35 {"flags", 1, 0, OPT_FLAGS }, 41 {"flags", 1, 0, OPT_FLAGS },
36 {NULL, 0, 0, 0} 42 {NULL, 0, 0, 0}
37 }; 43 };
38 44
39 45
40 /* Print help and return error */ 46 /* Print help and return error */
41 static int PrintHelp(char *progname) { 47 static int PrintHelp(char *progname) {
42 fprintf(stderr, 48 fprintf(stderr,
43 "Verified boot key block utility\n" 49 "Verified boot key block utility\n"
44 "\n" 50 "\n"
45 "Usage: %s <--pack|--unpack> <file> [OPTIONS]\n" 51 "Usage: %s <--pack|--unpack> <file> [OPTIONS]\n"
46 "\n" 52 "\n"
47 "For '--pack <file>', required OPTIONS are:\n" 53 "For '--pack <file>', required OPTIONS are:\n"
48 " --datapubkey <file> Data public key in .vbpubk format\n" 54 " --datapubkey <file> Data public key in .vbpubk format\n"
49 "\n" 55 "\n"
50 "Optional OPTIONS are:\n" 56 "Optional OPTIONS are:\n"
51 " --signprivate <file>" 57 " --signprivate <file>"
52 " Signing private key in .vbprivk format. Without this arg,\n" 58 " Signing private key in .vbprivk format.\n"
53 " the keyblock will not be signed.\n" 59 "OR\n"
60 " --signprivate_pem <file>\n"
61 " --pem_algorithm <algo>\n"
62 " Signing private key in .pem format and algorithm id.\n"
63 "(If one of the above arguments is not specified, the keyblock will\n"
64 "not be signed.)\n"
65 "\n"
54 " --flags <number> Specifies allowed use conditions.\n" 66 " --flags <number> Specifies allowed use conditions.\n"
67 " --externalsigner \"cmd\""
68 " Use an external program cmd to calculate the signatures.\n"
55 "\n" 69 "\n"
56 "For '--unpack <file>', optional OPTIONS are:\n" 70 "For '--unpack <file>', optional OPTIONS are:\n"
57 " --signpubkey <file>" 71 " --signpubkey <file>"
58 " Signing public key in .vbpubk format. This is required to\n" 72 " Signing public key in .vbpubk format. This is required to\n"
59 " verify a signed keyblock.\n" 73 " verify a signed keyblock.\n"
60 " --datapubkey <file>" 74 " --datapubkey <file>"
61 " Write the data public key to this file.\n", 75 " Write the data public key to this file.\n",
62 progname); 76 progname);
63 return 1; 77 return 1;
64 } 78 }
65 79
66
67 /* Pack a .keyblock */ 80 /* Pack a .keyblock */
68 static int Pack(const char* outfile, const char* datapubkey, 81 static int Pack(const char* outfile, const char* datapubkey,
69 const char* signprivate, uint64_t flags) { 82 const char* signprivate,
83 const char* signprivate_pem, uint64_t pem_algorithm,
84 uint64_t flags,
85 const char* external_signer) {
70 VbPublicKey* data_key; 86 VbPublicKey* data_key;
71 VbPrivateKey* signing_key = NULL; 87 VbPrivateKey* signing_key = NULL;
72 VbKeyBlockHeader* block; 88 VbKeyBlockHeader* block;
73 89
74 if (!outfile) { 90 if (!outfile) {
75 fprintf(stderr, "vbutil_keyblock: Must specify output filename.\n"); 91 fprintf(stderr, "vbutil_keyblock: Must specify output filename.\n");
76 return 1; 92 return 1;
77 } 93 }
78 if (!datapubkey) { 94 if (!datapubkey) {
79 fprintf(stderr, "vbutil_keyblock: Must specify data public key.\n"); 95 fprintf(stderr, "vbutil_keyblock: Must specify data public key.\n");
80 return 1; 96 return 1;
81 } 97 }
82 98
83 data_key = PublicKeyRead(datapubkey); 99 data_key = PublicKeyRead(datapubkey);
84 if (!data_key) { 100 if (!data_key) {
85 fprintf(stderr, "vbutil_keyblock: Error reading data key.\n"); 101 fprintf(stderr, "vbutil_keyblock: Error reading data key.\n");
86 return 1; 102 return 1;
87 } 103 }
88 104
89 if (signprivate) { 105 if (signprivate_pem) {
90 signing_key = PrivateKeyRead(signprivate); 106 if (pem_algorithm >= kNumAlgorithms) {
91 if (!signing_key) { 107 fprintf(stderr, "vbutil_keyblock: Invalid --pem_algorithm %" PRIu64 "\n",
92 fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n"); 108 pem_algorithm);
93 return 1; 109 return 1;
94 } 110 }
111 if (external_signer) {
112 /* External signing uses the PEM file directly. */
113 block = KeyBlockCreate_external(data_key,
114 signprivate_pem, pem_algorithm,
115 flags,
116 external_signer);
117 } else {
118 signing_key = PrivateKeyReadPem(signprivate, pem_algorithm);
119 if (!signing_key) {
120 fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n");
121 return 1;
122 }
123 block = KeyBlockCreate(data_key, signing_key, flags);
124 }
125 } else {
126 if (signprivate) {
127 signing_key = PrivateKeyRead(signprivate);
128 if (!signing_key) {
129 fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n");
130 return 1;
131 }
132 }
133 block = KeyBlockCreate(data_key, signing_key, flags);
95 } 134 }
96 135
97 block = KeyBlockCreate(data_key, signing_key, flags);
98 Free(data_key); 136 Free(data_key);
99 if (signing_key) 137 if (signing_key)
100 Free(signing_key); 138 Free(signing_key);
101 139
102 if (0 != KeyBlockWrite(outfile, block)) { 140 if (0 != KeyBlockWrite(outfile, block)) {
103 fprintf(stderr, "vbutil_keyblock: Error writing key block.\n"); 141 fprintf(stderr, "vbutil_keyblock: Error writing key block.\n");
104 return 1; 142 return 1;
105 } 143 }
106 Free(block); 144 Free(block);
107 return 0; 145 return 0;
108 } 146 }
109 147
110
111 static int Unpack(const char* infile, const char* datapubkey, 148 static int Unpack(const char* infile, const char* datapubkey,
112 const char* signpubkey) { 149 const char* signpubkey) {
113 VbPublicKey* data_key; 150 VbPublicKey* data_key;
114 VbPublicKey* sign_key = NULL; 151 VbPublicKey* sign_key = NULL;
115 VbKeyBlockHeader* block; 152 VbKeyBlockHeader* block;
116 153
117 if (!infile) { 154 if (!infile) {
118 fprintf(stderr, "vbutil_keyblock: Must specify filename\n"); 155 fprintf(stderr, "vbutil_keyblock: Must specify filename\n");
119 return 1; 156 return 1;
120 } 157 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 return 0; 211 return 0;
175 } 212 }
176 213
177 214
178 int main(int argc, char* argv[]) { 215 int main(int argc, char* argv[]) {
179 216
180 char* filename = NULL; 217 char* filename = NULL;
181 char* datapubkey = NULL; 218 char* datapubkey = NULL;
182 char* signpubkey = NULL; 219 char* signpubkey = NULL;
183 char* signprivate = NULL; 220 char* signprivate = NULL;
221 char* signprivate_pem = NULL;
222 char* external_signer = NULL;
184 uint64_t flags = 0; 223 uint64_t flags = 0;
224 uint64_t pem_algorithm = 0;
225 int is_pem_algorithm = 0;
185 int mode = 0; 226 int mode = 0;
186 int parse_error = 0; 227 int parse_error = 0;
187 char* e; 228 char* e;
188 int i; 229 int i;
189 230
190 char *progname = strrchr(argv[0], '/'); 231 char *progname = strrchr(argv[0], '/');
191 if (progname) 232 if (progname)
192 progname++; 233 progname++;
193 else 234 else
194 progname = argv[0]; 235 progname = argv[0];
(...skipping 17 matching lines...) Expand all
212 break; 253 break;
213 254
214 case OPT_SIGNPUBKEY: 255 case OPT_SIGNPUBKEY:
215 signpubkey = optarg; 256 signpubkey = optarg;
216 break; 257 break;
217 258
218 case OPT_SIGNPRIVATE: 259 case OPT_SIGNPRIVATE:
219 signprivate = optarg; 260 signprivate = optarg;
220 break; 261 break;
221 262
263 case OPT_SIGNPRIVATE_PEM:
264 signprivate_pem = optarg;
265 break;
266
267 case OPT_PEM_ALGORITHM:
268 pem_algorithm = strtoul(optarg, &e, 0);
269 if (!*optarg || (e && *e)) {
270 fprintf(stderr, "Invalid --pem_algorithm\n");
271 parse_error = 1;
272 } else {
273 is_pem_algorithm = 1;
274 }
275 break;
276
277 case OPT_EXTERNAL_SIGNER:
278 external_signer = optarg;
279 break;
280
222 case OPT_FLAGS: 281 case OPT_FLAGS:
223 flags = strtoul(optarg, &e, 0); 282 flags = strtoul(optarg, &e, 0);
224 if (!*optarg || (e && *e)) { 283 if (!*optarg || (e && *e)) {
225 printf("Invalid --flags\n"); 284 fprintf(stderr, "Invalid --flags\n");
226 parse_error = 1; 285 parse_error = 1;
227 } 286 }
228 break; 287 break;
229 } 288 }
230 } 289 }
231 290
291 /* Check if the right combination of options was provided. */
292 if (signprivate && signprivate_pem) {
293 fprintf(stderr, "Only one of --signprivate or --signprivate_pem must"
294 " be specified\n");
295 parse_error = 1;
296 }
297
298 if (signprivate_pem && !is_pem_algorithm) {
299 fprintf(stderr, "--pem_algorithm must be used with --signprivate_pem\n");
300 parse_error = 1;
301 }
302
303 if (external_signer && !signprivate_pem) {
304 fprintf(stderr, "--externalsigner must be used with --signprivate_pem"
305 "\n");
306 parse_error = 1;
307 }
308
232 if (parse_error) 309 if (parse_error)
233 return PrintHelp(progname); 310 return PrintHelp(progname);
234 311
235 switch(mode) { 312 switch(mode) {
236 case OPT_MODE_PACK: 313 case OPT_MODE_PACK:
237 return Pack(filename, datapubkey, signprivate, flags); 314 return Pack(filename, datapubkey, signprivate,
315 signprivate_pem, pem_algorithm,
316 flags,
317 external_signer);
238 case OPT_MODE_UNPACK: 318 case OPT_MODE_UNPACK:
239 return Unpack(filename, datapubkey, signpubkey); 319 return Unpack(filename, datapubkey, signpubkey);
240 default: 320 default:
241 printf("Must specify a mode.\n"); 321 printf("Must specify a mode.\n");
242 return PrintHelp(progname); 322 return PrintHelp(progname);
243 } 323 }
244 } 324 }
OLDNEW
« no previous file with comments | « tests/run_vbutil_tests.sh ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698