123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Verified boot key utility
- */
- #include <getopt.h>
- #include <inttypes.h> /* For PRIu64 */
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "futility.h"
- #include "host_common.h"
- #include "host_key2.h"
- #include "util_misc.h"
- #include "vb1_helper.h"
- #include "vb2_common.h"
- #include "vboot_common.h"
- /* Command line options */
- enum {
- OPT_INKEY = 1000,
- OPT_KEY_VERSION,
- OPT_ALGORITHM,
- OPT_MODE_PACK,
- OPT_MODE_UNPACK,
- OPT_COPYTO,
- OPT_HELP,
- };
- static const struct option long_opts[] = {
- {"key", 1, 0, OPT_INKEY},
- {"version", 1, 0, OPT_KEY_VERSION},
- {"algorithm", 1, 0, OPT_ALGORITHM},
- {"pack", 1, 0, OPT_MODE_PACK},
- {"unpack", 1, 0, OPT_MODE_UNPACK},
- {"copyto", 1, 0, OPT_COPYTO},
- {"help", 0, 0, OPT_HELP},
- {NULL, 0, 0, 0}
- };
- static void print_help(int argc, char *argv[])
- {
- int i;
- printf("\n"
- "Usage: " MYNAME " %s --pack <outfile> [PARAMETERS]\n"
- "\n"
- " Required parameters:\n"
- " --key <infile> RSA key file (.keyb or .pem)\n"
- " --version <number> Key version number "
- "(required for .keyb,\n"
- " ignored for .pem)\n"
- " --algorithm <number> "
- "Signing algorithm to use with key:\n", argv[0]);
- for (i = 0; i < VB2_ALG_COUNT; i++) {
- printf(" %d = (%s)\n",
- i, vb2_get_crypto_algorithm_name(i));
- }
- printf("\nOR\n\n"
- "Usage: " MYNAME " %s --unpack <infile>\n"
- "\n"
- " Optional parameters:\n"
- " --copyto <file> "
- "Write a copy of the key to this file.\n\n", argv[0]);
- }
- /* Pack a .keyb file into a .vbpubk, or a .pem into a .vbprivk */
- static int do_pack(const char *infile, const char *outfile, uint32_t algorithm,
- uint32_t version)
- {
- if (!infile || !outfile) {
- fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
- return 1;
- }
- struct vb2_packed_key *pubkey =
- vb2_read_packed_keyb(infile, algorithm, version);
- if (pubkey) {
- if (0 != vb2_write_packed_key(outfile, pubkey)) {
- fprintf(stderr, "vbutil_key: Error writing key.\n");
- free(pubkey);
- return 1;
- }
- free(pubkey);
- return 0;
- }
- struct vb2_private_key *privkey =
- vb2_read_private_key_pem(infile, algorithm);
- if (privkey) {
- if (VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) {
- fprintf(stderr, "vbutil_key: Error writing key.\n");
- free(privkey);
- return 1;
- }
- free(privkey);
- return 0;
- }
- VbExError("Unable to parse either .keyb or .pem from %s\n", infile);
- return 1;
- }
- /* Unpack a .vbpubk or .vbprivk */
- static int do_unpack(const char *infile, const char *outfile)
- {
- struct vb2_packed_key *pubkey;
- if (!infile) {
- fprintf(stderr, "Need file to unpack\n");
- return 1;
- }
- pubkey = vb2_read_packed_key(infile);
- if (pubkey) {
- printf("Public Key file: %s\n", infile);
- printf("Algorithm: %u %s\n", pubkey->algorithm,
- vb2_get_crypto_algorithm_name(pubkey->algorithm));
- printf("Key Version: %u\n", pubkey->key_version);
- printf("Key sha1sum: %s\n",
- packed_key_sha1_string(pubkey));
- if (outfile &&
- VB2_SUCCESS != vb2_write_packed_key(outfile, pubkey)) {
- fprintf(stderr, "butil_key: Error writing key copy\n");
- free(pubkey);
- return 1;
- }
- free(pubkey);
- return 0;
- }
- struct vb2_private_key *privkey = vb2_read_private_key(infile);
- if (privkey) {
- printf("Private Key file: %s\n", infile);
- enum vb2_crypto_algorithm alg =
- vb2_get_crypto_algorithm(privkey->hash_alg,
- privkey->sig_alg);
- printf("Algorithm: %u %s\n", alg,
- vb2_get_crypto_algorithm_name(alg));
- if (outfile &&
- VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) {
- fprintf(stderr,"vbutil_key: Error writing key copy\n");
- free(privkey);
- return 1;
- }
- free(privkey);
- return 0;
- }
- VbExError("Unable to parse either .vbpubk or vbprivk from %s\n",
- infile);
- return 1;
- }
- static int do_vbutil_key(int argc, char *argv[])
- {
- char *infile = NULL;
- char *outfile = NULL;
- int mode = 0;
- int parse_error = 0;
- uint32_t version = 1;
- uint32_t algorithm = VB2_ALG_COUNT;
- char *e;
- int i;
- while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
- switch (i) {
- case '?':
- /* Unhandled option */
- VbExError("Unknown option\n");
- parse_error = 1;
- break;
- case OPT_HELP:
- print_help(argc, argv);
- return !!parse_error;
- case OPT_INKEY:
- infile = optarg;
- break;
- case OPT_KEY_VERSION:
- version = strtoul(optarg, &e, 0);
- if (!*optarg || (e && *e)) {
- VbExError("Invalid --version\n");
- parse_error = 1;
- }
- break;
- case OPT_ALGORITHM:
- algorithm = strtoul(optarg, &e, 0);
- if (!*optarg || (e && *e)) {
- VbExError("Invalid --algorithm\n");
- parse_error = 1;
- }
- break;
- case OPT_MODE_PACK:
- mode = i;
- outfile = optarg;
- break;
- case OPT_MODE_UNPACK:
- mode = i;
- infile = optarg;
- break;
- case OPT_COPYTO:
- outfile = optarg;
- break;
- }
- }
- if (parse_error) {
- print_help(argc, argv);
- return 1;
- }
- switch (mode) {
- case OPT_MODE_PACK:
- return do_pack(infile, outfile, algorithm, version);
- case OPT_MODE_UNPACK:
- return do_unpack(infile, outfile);
- default:
- printf("Must specify a mode.\n");
- print_help(argc, argv);
- return 1;
- }
- }
- DECLARE_FUTIL_COMMAND(vbutil_key, do_vbutil_key, VBOOT_VERSION_1_0,
- "Wraps RSA keys with vboot headers");
|