| OLD | NEW |
| 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 utility | 5 * Verified boot key utility |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include <getopt.h> | 8 #include <getopt.h> |
| 9 #include <inttypes.h> /* For PRIu64 */ | 9 #include <inttypes.h> /* For PRIu64 */ |
| 10 #include <stdarg.h> | 10 #include <stdarg.h> |
| 11 #include <stdio.h> | 11 #include <stdio.h> |
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include "cryptolib.h" | 15 #include "cryptolib.h" |
| 16 #include "host_common.h" | 16 #include "host_common.h" |
| 17 #include "vboot_common.h" | 17 #include "vboot_common.h" |
| 18 | 18 |
| 19 | 19 |
| 20 /* Command line options */ | 20 /* Command line options */ |
| 21 enum { | 21 enum { |
| 22 OPT_INKEY = 1000, | 22 OPT_INKEY = 1000, |
| 23 OPT_KEY_VERSION, | 23 OPT_KEY_VERSION, |
| 24 OPT_ALGORITHM, | 24 OPT_ALGORITHM, |
| 25 OPT_MODE_PACK, | 25 OPT_MODE_PACK, |
| 26 OPT_MODE_UNPACK, | 26 OPT_MODE_UNPACK, |
| 27 OPT_COPYTO, |
| 27 }; | 28 }; |
| 28 | 29 |
| 29 static struct option long_opts[] = { | 30 static struct option long_opts[] = { |
| 30 {"key", 1, 0, OPT_INKEY }, | 31 {"key", 1, 0, OPT_INKEY }, |
| 31 {"version", 1, 0, OPT_KEY_VERSION }, | 32 {"version", 1, 0, OPT_KEY_VERSION }, |
| 32 {"algorithm", 1, 0, OPT_ALGORITHM }, | 33 {"algorithm", 1, 0, OPT_ALGORITHM }, |
| 33 {"pack", 1, 0, OPT_MODE_PACK }, | 34 {"pack", 1, 0, OPT_MODE_PACK }, |
| 34 {"unpack", 1, 0, OPT_MODE_UNPACK }, | 35 {"unpack", 1, 0, OPT_MODE_UNPACK }, |
| 36 {"copyto", 1, 0, OPT_COPYTO }, |
| 35 {NULL, 0, 0, 0} | 37 {NULL, 0, 0, 0} |
| 36 }; | 38 }; |
| 37 | 39 |
| 38 | 40 |
| 39 /* Print help and return error */ | 41 /* Print help and return error */ |
| 40 static int PrintHelp(char *progname) { | 42 static int PrintHelp(char *progname) { |
| 41 int i; | 43 int i; |
| 42 | 44 |
| 43 fprintf(stderr, | 45 fprintf(stderr, |
| 44 "This program wraps RSA keys with verified boot headers\n"); | 46 "This program wraps RSA keys with verified boot headers\n"); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 55 | 57 |
| 56 for (i = 0; i < kNumAlgorithms; i++) { | 58 for (i = 0; i < kNumAlgorithms; i++) { |
| 57 fprintf(stderr, | 59 fprintf(stderr, |
| 58 " %d = (%s)\n", | 60 " %d = (%s)\n", |
| 59 i, algo_strings[i]); | 61 i, algo_strings[i]); |
| 60 } | 62 } |
| 61 | 63 |
| 62 fprintf(stderr, | 64 fprintf(stderr, |
| 63 "\nOR\n\n" | 65 "\nOR\n\n" |
| 64 "Usage: %s --unpack <infile>\n" | 66 "Usage: %s --unpack <infile>\n" |
| 67 "\n" |
| 68 " Optional parameters:\n" |
| 69 " --copyto <file> " |
| 70 "Write a copy of the key to this file.\n" |
| 65 "\n", | 71 "\n", |
| 66 progname); | 72 progname); |
| 67 | 73 |
| 68 return 1; | 74 return 1; |
| 69 } | 75 } |
| 70 | 76 |
| 71 /* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */ | 77 /* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */ |
| 72 static int Pack(const char *infile, const char *outfile, uint64_t algorithm, | 78 static int Pack(const char *infile, const char *outfile, uint64_t algorithm, |
| 73 uint64_t version) { | 79 uint64_t version) { |
| 74 VbPublicKey* pubkey; | 80 VbPublicKey* pubkey; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 88 return 0; | 94 return 0; |
| 89 } | 95 } |
| 90 | 96 |
| 91 if ((privkey = PrivateKeyReadPem(infile, algorithm))) { | 97 if ((privkey = PrivateKeyReadPem(infile, algorithm))) { |
| 92 if (0 != PrivateKeyWrite(outfile, privkey)) { | 98 if (0 != PrivateKeyWrite(outfile, privkey)) { |
| 93 fprintf(stderr, "vbutil_key: Error writing key.\n"); | 99 fprintf(stderr, "vbutil_key: Error writing key.\n"); |
| 94 return 1; | 100 return 1; |
| 95 } | 101 } |
| 96 Free(privkey); | 102 Free(privkey); |
| 97 return 0; | 103 return 0; |
| 98 } | 104 } |
| 99 | 105 |
| 100 error("Unable to parse either .keyb or .pem from %s\n", infile); | 106 error("Unable to parse either .keyb or .pem from %s\n", infile); |
| 101 return 1; | 107 return 1; |
| 102 } | 108 } |
| 103 | 109 |
| 104 | 110 |
| 111 static void PrintDigest(const uint8_t* buf, uint64_t buflen) { |
| 112 uint8_t *digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM); |
| 113 int i; |
| 114 for (i=0; i<SHA1_DIGEST_SIZE; i++) |
| 115 printf("%02x", digest[i]); |
| 116 printf("\n"); |
| 117 Free(digest); |
| 118 } |
| 119 |
| 105 /* Unpack a .vbpubk or .vbprivk */ | 120 /* Unpack a .vbpubk or .vbprivk */ |
| 106 static int Unpack(const char *infile, const char *outfile) { | 121 static int Unpack(const char *infile, const char *outfile) { |
| 107 VbPublicKey* pubkey; | 122 VbPublicKey* pubkey; |
| 108 VbPrivateKey* privkey; | 123 VbPrivateKey* privkey; |
| 109 | 124 |
| 110 if (!infile) { | 125 if (!infile) { |
| 111 fprintf(stderr, "Need file to unpack\n"); | 126 fprintf(stderr, "Need file to unpack\n"); |
| 112 return 1; | 127 return 1; |
| 113 } | 128 } |
| 114 | 129 |
| 115 if ((pubkey = PublicKeyRead(infile))) { | 130 if ((pubkey = PublicKeyRead(infile))) { |
| 116 printf("Public Key file: %s\n", infile); | 131 printf("Public Key file: %s\n", infile); |
| 117 printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm, | 132 printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm, |
| 118 (pubkey->algorithm < kNumAlgorithms ? | 133 (pubkey->algorithm < kNumAlgorithms ? |
| 119 algo_strings[pubkey->algorithm] : "(invalid)")); | 134 algo_strings[pubkey->algorithm] : "(invalid)")); |
| 120 printf("Key Version: %" PRIu64 "\n", pubkey->key_version); | 135 printf("Key Version: %" PRIu64 "\n", pubkey->key_version); |
| 136 printf("Key sha1sum: "); |
| 137 PrintDigest(((uint8_t *)pubkey) + pubkey->key_offset, pubkey->key_size); |
| 138 if (outfile) { |
| 139 if (0 != PublicKeyWrite(outfile, pubkey)) { |
| 140 fprintf(stderr, "vbutil_key: Error writing key copy.\n"); |
| 141 Free(pubkey); |
| 142 return 1; |
| 143 } |
| 144 } |
| 121 Free(pubkey); | 145 Free(pubkey); |
| 122 return 0; | 146 return 0; |
| 123 } | 147 } |
| 124 | 148 |
| 125 | 149 |
| 126 if ((privkey = PrivateKeyRead(infile))) { | 150 if ((privkey = PrivateKeyRead(infile))) { |
| 127 printf("Private Key file: %s\n", infile); | 151 printf("Private Key file: %s\n", infile); |
| 128 printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm, | 152 printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm, |
| 129 (privkey->algorithm < kNumAlgorithms ? | 153 (privkey->algorithm < kNumAlgorithms ? |
| 130 algo_strings[privkey->algorithm] : "(invalid)")); | 154 algo_strings[privkey->algorithm] : "(invalid)")); |
| 155 if (outfile) { |
| 156 if (0 != PrivateKeyWrite(outfile, privkey)) { |
| 157 fprintf(stderr, "vbutil_key: Error writing key copy.\n"); |
| 158 Free(privkey); |
| 159 return 1; |
| 160 } |
| 161 } |
| 131 Free(privkey); | 162 Free(privkey); |
| 132 return 0; | 163 return 0; |
| 133 } | 164 } |
| 134 | 165 |
| 135 | |
| 136 /* TODO: write key data, if any */ | |
| 137 | |
| 138 error("Unable to parse either .vbpubk or vbprivk from %s\n", infile); | 166 error("Unable to parse either .vbpubk or vbprivk from %s\n", infile); |
| 139 return 1; | 167 return 1; |
| 140 } | 168 } |
| 141 | 169 |
| 142 | 170 |
| 143 int main(int argc, char* argv[]) { | 171 int main(int argc, char* argv[]) { |
| 144 | 172 |
| 145 char *infile = NULL; | 173 char *infile = NULL; |
| 146 char *outfile = NULL; | 174 char *outfile = NULL; |
| 147 int mode = 0; | 175 int mode = 0; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 | 215 |
| 188 case OPT_MODE_PACK: | 216 case OPT_MODE_PACK: |
| 189 mode = i; | 217 mode = i; |
| 190 outfile = optarg; | 218 outfile = optarg; |
| 191 break; | 219 break; |
| 192 | 220 |
| 193 case OPT_MODE_UNPACK: | 221 case OPT_MODE_UNPACK: |
| 194 mode = i; | 222 mode = i; |
| 195 infile = optarg; | 223 infile = optarg; |
| 196 break; | 224 break; |
| 225 |
| 226 case OPT_COPYTO: |
| 227 outfile = optarg; |
| 228 break; |
| 197 } | 229 } |
| 198 } | 230 } |
| 199 | 231 |
| 200 if (parse_error) | 232 if (parse_error) |
| 201 return PrintHelp(progname); | 233 return PrintHelp(progname); |
| 202 | 234 |
| 203 switch(mode) { | 235 switch(mode) { |
| 204 case OPT_MODE_PACK: | 236 case OPT_MODE_PACK: |
| 205 return Pack(infile, outfile, algorithm, version); | 237 return Pack(infile, outfile, algorithm, version); |
| 206 case OPT_MODE_UNPACK: | 238 case OPT_MODE_UNPACK: |
| 207 return Unpack(infile, outfile); | 239 return Unpack(infile, outfile); |
| 208 default: | 240 default: |
| 209 printf("Must specify a mode.\n"); | 241 printf("Must specify a mode.\n"); |
| 210 return PrintHelp(progname); | 242 return PrintHelp(progname); |
| 211 } | 243 } |
| 212 } | 244 } |
| OLD | NEW |