| Index: utility/vbutil_key.c
|
| diff --git a/utility/vbutil_key.c b/utility/vbutil_key.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d770026ecd6d4260bed291c7c0512f54b3ccb55f
|
| --- /dev/null
|
| +++ b/utility/vbutil_key.c
|
| @@ -0,0 +1,175 @@
|
| +#include <getopt.h>
|
| +#include <inttypes.h> /* For PRIu64 */
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +
|
| +#include "cryptolib.h"
|
| +#include "host_common.h"
|
| +#include "vboot_common.h"
|
| +
|
| +
|
| +/* Command line options */
|
| +enum {
|
| + OPT_IN = 1000,
|
| + OPT_OUT,
|
| + OPT_KEY_VERSION,
|
| + OPT_ALGORITHM,
|
| + OPT_MODE_PACK,
|
| + OPT_MODE_UNPACK,
|
| +};
|
| +
|
| +static struct option long_opts[] = {
|
| + {"in", 1, 0, OPT_IN },
|
| + {"out", 1, 0, OPT_OUT },
|
| + {"version", 1, 0, OPT_KEY_VERSION },
|
| + {"algorithm", 1, 0, OPT_ALGORITHM },
|
| + {"pack", 0, 0, OPT_MODE_PACK },
|
| + {"unpack", 0, 0, OPT_MODE_UNPACK },
|
| + {NULL, 0, 0, 0}
|
| +};
|
| +
|
| +
|
| +/* Print help and return error */
|
| +static int PrintHelp(void) {
|
| + int i;
|
| +
|
| + puts("vbutil_key - Verified boot key utility\n"
|
| + "\n"
|
| + "Usage: vbutil_key <--pack|--unpack> [OPTIONS]\n"
|
| + "\n"
|
| + "For '--pack', required OPTIONS are:\n"
|
| + " --in <infile> Input key in .keyb format\n"
|
| + " --out <outfile> Output file for .vbpubk format\n"
|
| + " --version <number> Key version number\n"
|
| + " --algorithm <algoid> Signing algorithm for key, one of:");
|
| +
|
| + for (i = 0; i < kNumAlgorithms; i++)
|
| + printf(" %d (%s)\n", i, algo_strings[i]);
|
| +
|
| + puts("\n"
|
| + "For '--unpack', required OPTIONS are:\n"
|
| + " --in <infile> Input key in .vbpubk format\n"
|
| + "Optional OPTIONS are:\n"
|
| + " --out <outfile> Output file for .keyb format\n"
|
| + "");
|
| + return 1;
|
| +}
|
| +
|
| +
|
| +/* Pack a .keyb file into a .vbpubk */
|
| +static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
|
| + uint64_t version) {
|
| + VbPublicKey* key;
|
| +
|
| + if (!infile || !outfile) {
|
| + fprintf(stderr, "vbutil_key: Must specify --in and --out\n");
|
| + return 1;
|
| + }
|
| +
|
| + key = PublicKeyReadKeyb(infile, algorithm, version);
|
| + if (!key) {
|
| + fprintf(stderr, "vbutil_key: Error reading key.\n");
|
| + return 1;
|
| + }
|
| +
|
| + if (0 != PublicKeyWrite(outfile, key)) {
|
| + fprintf(stderr, "vbutil_key: Error writing key.\n");
|
| + return 1;
|
| + }
|
| +
|
| + Free(key);
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +/* Unpack a .vbpubk */
|
| +static int Unpack(const char *infile, const char *outfile) {
|
| + VbPublicKey* key;
|
| +
|
| + if (!infile) {
|
| + fprintf(stderr, "vbutil_key: Must specify --in\n");
|
| + return 1;
|
| + }
|
| +
|
| + key = PublicKeyRead(infile);
|
| + if (!key) {
|
| + fprintf(stderr, "vbutil_key: Error reading key.\n");
|
| + return 1;
|
| + }
|
| +
|
| + printf("Key file: %s\n", infile);
|
| + printf("Algorithm: %" PRIu64 " %s\n", key->algorithm,
|
| + (key->algorithm < kNumAlgorithms ?
|
| + algo_strings[key->algorithm] : "(invalid)"));
|
| + printf("Version: %" PRIu64 "\n", key->key_version);
|
| +
|
| + /* TODO: write key data, if any */
|
| +
|
| + Free(key);
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +int main(int argc, char* argv[]) {
|
| +
|
| + char *infile = NULL;
|
| + char *outfile = NULL;
|
| + int mode = 0;
|
| + int parse_error = 0;
|
| + uint64_t version = 1;
|
| + uint64_t algorithm = kNumAlgorithms;
|
| + char* e;
|
| + int i;
|
| +
|
| + while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
|
| + switch (i) {
|
| + case '?':
|
| + /* Unhandled option */
|
| + printf("Unknown option\n");
|
| + parse_error = 1;
|
| + break;
|
| +
|
| + case OPT_IN:
|
| + infile = optarg;
|
| + break;
|
| +
|
| + case OPT_OUT:
|
| + outfile = optarg;
|
| + break;
|
| +
|
| + case OPT_KEY_VERSION:
|
| + version = strtoul(optarg, &e, 0);
|
| + if (!*optarg || (e && *e)) {
|
| + printf("Invalid --version\n");
|
| + parse_error = 1;
|
| + }
|
| + break;
|
| +
|
| + case OPT_ALGORITHM:
|
| + algorithm = strtoul(optarg, &e, 0);
|
| + if (!*optarg || (e && *e)) {
|
| + printf("Invalid --algorithm\n");
|
| + parse_error = 1;
|
| + }
|
| + break;
|
| +
|
| + case OPT_MODE_PACK:
|
| + case OPT_MODE_UNPACK:
|
| + mode = i;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (parse_error)
|
| + return PrintHelp();
|
| +
|
| + switch(mode) {
|
| + case OPT_MODE_PACK:
|
| + return Pack(infile, outfile, algorithm, version);
|
| + case OPT_MODE_UNPACK:
|
| + return Unpack(infile, outfile);
|
| + default:
|
| + printf("Must specify a mode.\n");
|
| + return PrintHelp();
|
| + }
|
| +}
|
|
|