blob: d770026ecd6d4260bed291c7c0512f54b3ccb55f [file] [log] [blame]
Randall Spanglerd55c6452010-06-10 12:43:51 -07001#include <getopt.h>
2#include <inttypes.h> /* For PRIu64 */
3#include <stdio.h>
4#include <stdlib.h>
5
6#include "cryptolib.h"
7#include "host_common.h"
8#include "vboot_common.h"
9
10
11/* Command line options */
12enum {
13 OPT_IN = 1000,
14 OPT_OUT,
15 OPT_KEY_VERSION,
16 OPT_ALGORITHM,
17 OPT_MODE_PACK,
18 OPT_MODE_UNPACK,
19};
20
21static struct option long_opts[] = {
22 {"in", 1, 0, OPT_IN },
23 {"out", 1, 0, OPT_OUT },
24 {"version", 1, 0, OPT_KEY_VERSION },
25 {"algorithm", 1, 0, OPT_ALGORITHM },
26 {"pack", 0, 0, OPT_MODE_PACK },
27 {"unpack", 0, 0, OPT_MODE_UNPACK },
28 {NULL, 0, 0, 0}
29};
30
31
32/* Print help and return error */
33static int PrintHelp(void) {
34 int i;
35
36 puts("vbutil_key - Verified boot key utility\n"
37 "\n"
38 "Usage: vbutil_key <--pack|--unpack> [OPTIONS]\n"
39 "\n"
40 "For '--pack', required OPTIONS are:\n"
41 " --in <infile> Input key in .keyb format\n"
42 " --out <outfile> Output file for .vbpubk format\n"
43 " --version <number> Key version number\n"
44 " --algorithm <algoid> Signing algorithm for key, one of:");
45
46 for (i = 0; i < kNumAlgorithms; i++)
47 printf(" %d (%s)\n", i, algo_strings[i]);
48
49 puts("\n"
50 "For '--unpack', required OPTIONS are:\n"
51 " --in <infile> Input key in .vbpubk format\n"
52 "Optional OPTIONS are:\n"
53 " --out <outfile> Output file for .keyb format\n"
54 "");
55 return 1;
56}
57
58
59/* Pack a .keyb file into a .vbpubk */
60static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
61 uint64_t version) {
62 VbPublicKey* key;
63
64 if (!infile || !outfile) {
65 fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
66 return 1;
67 }
68
69 key = PublicKeyReadKeyb(infile, algorithm, version);
70 if (!key) {
71 fprintf(stderr, "vbutil_key: Error reading key.\n");
72 return 1;
73 }
74
75 if (0 != PublicKeyWrite(outfile, key)) {
76 fprintf(stderr, "vbutil_key: Error writing key.\n");
77 return 1;
78 }
79
80 Free(key);
81 return 0;
82}
83
84
85/* Unpack a .vbpubk */
86static int Unpack(const char *infile, const char *outfile) {
87 VbPublicKey* key;
88
89 if (!infile) {
90 fprintf(stderr, "vbutil_key: Must specify --in\n");
91 return 1;
92 }
93
94 key = PublicKeyRead(infile);
95 if (!key) {
96 fprintf(stderr, "vbutil_key: Error reading key.\n");
97 return 1;
98 }
99
100 printf("Key file: %s\n", infile);
101 printf("Algorithm: %" PRIu64 " %s\n", key->algorithm,
102 (key->algorithm < kNumAlgorithms ?
103 algo_strings[key->algorithm] : "(invalid)"));
104 printf("Version: %" PRIu64 "\n", key->key_version);
105
106 /* TODO: write key data, if any */
107
108 Free(key);
109 return 0;
110}
111
112
113int main(int argc, char* argv[]) {
114
115 char *infile = NULL;
116 char *outfile = NULL;
117 int mode = 0;
118 int parse_error = 0;
119 uint64_t version = 1;
120 uint64_t algorithm = kNumAlgorithms;
121 char* e;
122 int i;
123
124 while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
125 switch (i) {
126 case '?':
127 /* Unhandled option */
128 printf("Unknown option\n");
129 parse_error = 1;
130 break;
131
132 case OPT_IN:
133 infile = optarg;
134 break;
135
136 case OPT_OUT:
137 outfile = optarg;
138 break;
139
140 case OPT_KEY_VERSION:
141 version = strtoul(optarg, &e, 0);
142 if (!*optarg || (e && *e)) {
143 printf("Invalid --version\n");
144 parse_error = 1;
145 }
146 break;
147
148 case OPT_ALGORITHM:
149 algorithm = strtoul(optarg, &e, 0);
150 if (!*optarg || (e && *e)) {
151 printf("Invalid --algorithm\n");
152 parse_error = 1;
153 }
154 break;
155
156 case OPT_MODE_PACK:
157 case OPT_MODE_UNPACK:
158 mode = i;
159 break;
160 }
161 }
162
163 if (parse_error)
164 return PrintHelp();
165
166 switch(mode) {
167 case OPT_MODE_PACK:
168 return Pack(infile, outfile, algorithm, version);
169 case OPT_MODE_UNPACK:
170 return Unpack(infile, outfile);
171 default:
172 printf("Must specify a mode.\n");
173 return PrintHelp();
174 }
175}