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

Unified Diff: utility/vbutil_keyblock.c

Issue 2748008: Add vbutil_keyblock (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Created 10 years, 6 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « utility/Makefile ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utility/vbutil_keyblock.c
diff --git a/utility/vbutil_keyblock.c b/utility/vbutil_keyblock.c
new file mode 100644
index 0000000000000000000000000000000000000000..37754c9239cb3ec7b53c708fd651d0df5d96df87
--- /dev/null
+++ b/utility/vbutil_keyblock.c
@@ -0,0 +1,222 @@
+#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_MODE_PACK = 1000,
+ OPT_MODE_UNPACK,
+ OPT_DATAPUBKEY,
+ OPT_SIGNPUBKEY,
+ OPT_SIGNPRIVATE,
+ OPT_ALGORITHM,
+ OPT_FLAGS,
+};
+
+static struct option long_opts[] = {
+ {"pack", 1, 0, OPT_MODE_PACK },
+ {"unpack", 1, 0, OPT_MODE_UNPACK },
+ {"datapubkey", 1, 0, OPT_DATAPUBKEY },
+ {"signpubkey", 1, 0, OPT_SIGNPUBKEY },
+ {"signprivate", 1, 0, OPT_SIGNPRIVATE },
+ {"algorithm", 1, 0, OPT_ALGORITHM },
+ {"flags", 1, 0, OPT_FLAGS },
+ {NULL, 0, 0, 0}
+};
+
+
+/* Print help and return error */
+static int PrintHelp(void) {
+ int i;
+
+ puts("vbutil_keyblock - Verified boot key block utility\n"
+ "\n"
+ "Usage: vbutil_keyblock <--pack|--unpack> <file> [OPTIONS]\n"
+ "\n"
+ "For '--pack <file>', required OPTIONS are:\n"
+ " --datapubkey <file> Data public key in .vbpubk format\n"
+ " --signprivate <file> Signing private key in .pem format\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"
+ "Optional OPTIONS are:\n"
+ " --flags <number> Flags\n"
+ "\n"
+ "For '--unpack <file>', required OPTIONS are:\n"
+ " --signpubkey <file> Signing public key in .vbpubk format\n"
+ "Optional OPTIONS are:\n"
+ " --datapubkey <file> Data public key output file\n"
+ "");
+ return 1;
+}
+
+
+/* Pack a .keyblock */
+static int Pack(const char* outfile, const char* datapubkey,
+ const char* signprivate, uint64_t algorithm,
+ uint64_t flags) {
+ VbPublicKey* data_key;
+ VbPrivateKey* signing_key;
+ VbKeyBlockHeader* block;
+
+ if (!outfile) {
+ fprintf(stderr, "vbutil_keyblock: Must specify output filename\n");
+ return 1;
+ }
+ if (!datapubkey || !signprivate) {
+ fprintf(stderr, "vbutil_keyblock: Must specify all keys\n");
+ return 1;
+ }
+ if (algorithm >= kNumAlgorithms) {
+ fprintf(stderr, "Invalid algorithm\n");
+ return 1;
+ }
+
+ data_key = PublicKeyRead(datapubkey);
+ if (!data_key) {
+ fprintf(stderr, "vbutil_keyblock: Error reading data key.\n");
+ return 1;
+ }
+ signing_key = PrivateKeyRead(signprivate, algorithm);
+ if (!signing_key) {
+ fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n");
+ return 1;
+ }
+
+ block = CreateKeyBlock(data_key, signing_key, flags);
+ Free(data_key);
+ Free(signing_key);
+
+ if (0 != WriteFile(outfile, block, block->key_block_size)) {
+ fprintf(stderr, "vbutil_keyblock: Error writing key block.\n");
+ return 1;
+ }
+ Free(block);
+ return 0;
+}
+
+
+static int Unpack(const char* infile, const char* datapubkey,
+ const char* signpubkey) {
+ VbPublicKey* data_key;
+ VbPublicKey* sign_key;
+ VbKeyBlockHeader* block;
+ uint64_t block_size;
+
+ if (!infile || !signpubkey) {
+ fprintf(stderr, "vbutil_keyblock: Must specify filename and signpubkey\n");
+ return 1;
+ }
+
+ sign_key = PublicKeyRead(signpubkey);
+ if (!sign_key) {
+ fprintf(stderr, "vbutil_keyblock: Error reading signpubkey.\n");
+ return 1;
+ }
+
+ block = (VbKeyBlockHeader*)ReadFile(infile, &block_size);
+ if (!block) {
+ fprintf(stderr, "vbutil_keyblock: Error reading key block.\n");
+ return 1;
+ }
+ if (0 != VerifyKeyBlock(block, block_size, sign_key)) {
+ fprintf(stderr, "vbutil_keyblock: Error verifying key block.\n");
+ return 1;
+ }
+ Free(sign_key);
+
+ printf("Key block file: %s\n", infile);
+ printf("Flags: %" PRIu64 "\n", block->key_block_flags);
+
+ data_key = &block->data_key;
+ printf("Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm,
+ (data_key->algorithm < kNumAlgorithms ?
+ algo_strings[data_key->algorithm] : "(invalid)"));
+ printf("Data key version: %" PRIu64 "\n", data_key->key_version);
+
+ /* TODO: write key data, if output file specified */
+
+ Free(block);
+ return 0;
+}
+
+
+int main(int argc, char* argv[]) {
+
+ char* filename = NULL;
+ char* datapubkey = NULL;
+ char* signpubkey = NULL;
+ char* signprivate = NULL;
+ uint64_t flags = 0;
+ uint64_t algorithm = kNumAlgorithms;
+ int mode = 0;
+ int parse_error = 0;
+ 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_MODE_PACK:
+ case OPT_MODE_UNPACK:
+ mode = i;
+ filename = optarg;
+ break;
+
+ case OPT_DATAPUBKEY:
+ datapubkey = optarg;
+ break;
+
+ case OPT_SIGNPUBKEY:
+ signpubkey = optarg;
+ break;
+
+ case OPT_SIGNPRIVATE:
+ signprivate = optarg;
+ break;
+
+ case OPT_ALGORITHM:
+ algorithm = strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e)) {
+ printf("Invalid --algorithm\n");
+ parse_error = 1;
+ }
+ break;
+
+ case OPT_FLAGS:
+ flags = strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e)) {
+ printf("Invalid --flags\n");
+ parse_error = 1;
+ }
+ break;
+ }
+ }
+
+ if (parse_error)
+ return PrintHelp();
+
+ switch(mode) {
+ case OPT_MODE_PACK:
+ return Pack(filename, datapubkey, signprivate, algorithm, flags);
+ case OPT_MODE_UNPACK:
+ return Unpack(filename, datapubkey, signpubkey);
+ default:
+ printf("Must specify a mode.\n");
+ return PrintHelp();
+ }
+}
« no previous file with comments | « utility/Makefile ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698