diff options
author | Bill Richardson <wfrichar@chromium.org> | 2010-06-30 21:59:43 -0700 |
---|---|---|
committer | Bill Richardson <wfrichar@chromium.org> | 2010-06-30 21:59:43 -0700 |
commit | a08b5c9d032be485fe6e2790c23e8c9bb9fca2ad (patch) | |
tree | 1bc8a3a828540e5efad996fb22444a707026fd08 | |
parent | 2a80e8a41627b367946480c72cb8c389df8d0cb3 (diff) | |
download | vboot-a08b5c9d032be485fe6e2790c23e8c9bb9fca2ad.tar.gz |
Adding --repack and --headeronly options to vbutil_kernel
The --repack option lets us sign a previously signed kernel blob with a new
kernel data key.
The --headeronly option is so we can emit the new verification header
separately from the kernel blob.
More work to come...
Review URL: http://codereview.chromium.org/2812034
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | host/include/host_key.h | 4 | ||||
-rw-r--r-- | host/lib/host_key.c | 8 | ||||
-rw-r--r-- | host/linktest/main.c | 2 | ||||
-rw-r--r-- | tests/vboot_common2_tests.c | 2 | ||||
-rw-r--r-- | tests/vboot_common3_tests.c | 2 | ||||
-rw-r--r-- | utility/vbutil_firmware.c | 2 | ||||
-rw-r--r-- | utility/vbutil_kernel.c | 414 | ||||
-rw-r--r-- | utility/vbutil_keyblock.c | 2 |
9 files changed, 330 insertions, 108 deletions
@@ -4,7 +4,7 @@ export CC ?= gcc export CXX ?= g++ -export CFLAGS = -Wall -DNDEBUG -O3 -Werror -DCHROMEOS_ENVIRONMENT -DVBOOT_DEBUG +export CFLAGS = -Wall -DNDEBUG -O3 -Werror -DCHROMEOS_ENVIRONMENT export TOP = $(shell pwd) export FWDIR=$(TOP)/firmware export HOSTDIR=$(TOP)/host diff --git a/host/include/host_key.h b/host/include/host_key.h index 9ce1fa56..e7b18155 100644 --- a/host/include/host_key.h +++ b/host/include/host_key.h @@ -22,9 +22,9 @@ typedef struct VbPrivateKey { } VbPrivateKey; -/* Read a private key from a file. Caller owns the returned pointer, +/* Read a private key from a .pem file. Caller owns the returned pointer, * and must free it with PrivateKeyFree(). */ -VbPrivateKey* PrivateKeyRead(const char* filename, uint64_t algorithm); +VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm); /* Free a private key. */ diff --git a/host/lib/host_key.c b/host/lib/host_key.c index da350fd4..fd25afd9 100644 --- a/host/lib/host_key.c +++ b/host/lib/host_key.c @@ -24,27 +24,27 @@ #include "vboot_common.h" -VbPrivateKey* PrivateKeyRead(const char* filename, uint64_t algorithm) { +VbPrivateKey* PrivateKeyReadPem(const char* filename, uint64_t algorithm) { VbPrivateKey* key; RSA* rsa_key; FILE* f; if (algorithm >= kNumAlgorithms) { - debug("PrivateKeyRead() called with invalid algorithm!\n"); + debug("%s() called with invalid algorithm!\n", __FUNCTION__); return NULL; } /* Read private key */ f = fopen(filename, "r"); if (!f) { - debug("PrivateKeyRead(): Couldn't open key file: %s\n", filename); + debug("%s(): Couldn't open key file: %s\n", __FUNCTION__, filename); return NULL; } rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL); fclose(f); if (!rsa_key) { - debug("PrivateKeyRead(): Couldn't read private key from file: %s\n", + debug("%s(): Couldn't read private key from file: %s\n", __FUNCTION__, filename); return NULL; } diff --git a/host/linktest/main.c b/host/linktest/main.c index 93c5ac2a..a067e1bd 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -7,7 +7,7 @@ int main(void) { /* host_key.h */ - PrivateKeyRead(0, 0); + PrivateKeyReadPem(0, 0); PrivateKeyFree(0); PublicKeyAlloc(0, 0, 0); PublicKeyRead(0); diff --git a/tests/vboot_common2_tests.c b/tests/vboot_common2_tests.c index 89ba1f87..f5815741 100644 --- a/tests/vboot_common2_tests.c +++ b/tests/vboot_common2_tests.c @@ -213,7 +213,7 @@ int main(int argc, char* argv[]) { /* Read verification keys and create a test image. */ key_algorithm = atoi(argv[1]); - private_key = PrivateKeyRead(argv[2], key_algorithm); + private_key = PrivateKeyReadPem(argv[2], key_algorithm); if (!private_key) { fprintf(stderr, "Error reading private_key"); return 1; diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c index ff75906a..8b7e4702 100644 --- a/tests/vboot_common3_tests.c +++ b/tests/vboot_common3_tests.c @@ -264,7 +264,7 @@ int main(int argc, char* argv[]) { signing_key_algorithm = atoi(argv[1]); data_key_algorithm = atoi(argv[2]); - signing_private_key = PrivateKeyRead(argv[3], signing_key_algorithm); + signing_private_key = PrivateKeyReadPem(argv[3], signing_key_algorithm); if (!signing_private_key) { fprintf(stderr, "Error reading signing_private_key"); return 1; diff --git a/utility/vbutil_firmware.c b/utility/vbutil_firmware.c index efc91276..4966e198 100644 --- a/utility/vbutil_firmware.c +++ b/utility/vbutil_firmware.c @@ -101,7 +101,7 @@ static int Vblock(const char* outfile, const char* keyblock_file, return 1; } - signing_key = PrivateKeyRead(signprivate, key_block->data_key.algorithm); + signing_key = PrivateKeyReadPem(signprivate, key_block->data_key.algorithm); if (!signing_key) { error("Error reading signing key.\n"); return 1; diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c index 81b9e445..8b670514 100644 --- a/utility/vbutil_kernel.c +++ b/utility/vbutil_kernel.c @@ -5,12 +5,16 @@ * Verified boot kernel utility */ +#include <errno.h> #include <getopt.h> #include <inttypes.h> /* For PRIu64 */ #include <stdarg.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> #include "cryptolib.h" @@ -22,11 +26,14 @@ /* Global opt */ static int opt_debug = 0; +static const int DEFAULT_PADDING = 65536; /* Command line options */ enum { OPT_MODE_PACK = 1000, + OPT_MODE_REPACK, OPT_MODE_VERIFY, + OPT_OLDBLOB, OPT_KEYBLOCK, OPT_SIGNPUBKEY, OPT_SIGNPRIVATE, @@ -34,12 +41,15 @@ enum { OPT_VMLINUZ, OPT_BOOTLOADER, OPT_CONFIG, + OPT_VBLOCKONLY, OPT_PAD, }; static struct option long_opts[] = { {"pack", 1, 0, OPT_MODE_PACK }, + {"repack", 1, 0, OPT_MODE_REPACK }, {"verify", 1, 0, OPT_MODE_VERIFY }, + {"oldblob", 1, 0, OPT_OLDBLOB }, {"keyblock", 1, 0, OPT_KEYBLOCK }, {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, {"signprivate", 1, 0, OPT_SIGNPRIVATE }, @@ -47,6 +57,7 @@ static struct option long_opts[] = { {"vmlinuz", 1, 0, OPT_VMLINUZ }, {"bootloader", 1, 0, OPT_BOOTLOADER }, {"config", 1, 0, OPT_CONFIG }, + {"vblockonly", 0, 0, OPT_VBLOCKONLY }, {"pad", 1, 0, OPT_PAD }, {"debug", 0, &opt_debug, 1 }, {NULL, 0, 0, 0} @@ -54,25 +65,46 @@ static struct option long_opts[] = { /* Print help and return error */ -static int PrintHelp(void) { - - puts("vbutil_kernel - Verified boot key block utility\n" - "\n" - "Usage: vbutil_kernel <--pack|--verify> <file> [OPTIONS]\n" - "\n" - "For '--pack <file>', required OPTIONS are:\n" - " --keyblock <file> Key block in .keyblock format\n" - " --signprivate <file> Signing private key in .pem format\n" - " --version <number> Kernel version\n" - " --vmlinuz <file> Linux kernel image\n" - " --bootloader <file> Bootloader stub\n" - " --config <file> Config file\n" - "Optional OPTIONS are:\n" - " --pad <number> Padding size in bytes\n" - "\n" - "For '--verify <file>', required OPTIONS are:\n" - " --signpubkey <file> Signing public key in .vbpubk format\n" - ""); +static int PrintHelp(char *progname) { + fprintf(stderr, + "This program creates, signs, and verifies the kernel blob\n"); + fprintf(stderr, + "\n" + "Usage: %s --pack <file> [PARAMETERS]\n" + "\n" + " Required parameters:\n" + " --keyblock <file> Key block in .keyblock format\n" + " --signprivate <file> Signing private key in .pem format\n" + " --version <number> Kernel version\n" + " --vmlinuz <file> Linux kernel bzImage file\n" + " --bootloader <file> Bootloader stub\n" + " --config <file> Config file\n" + "\n" + " Optional:\n" + " --pad <number> Verification padding size in bytes\n" + " --vblockonly Emit just the verification blob\n", + progname); + fprintf(stderr, + "\nOR\n\n" + "Usage: %s --repack <file> [PARAMETERS]\n" + "\n" + " Required parameters:\n" + " --keyblock <file> Key block in .keyblock format\n" + " --signprivate <file> Signing private key in .pem format\n" + " --oldblob <file> Previously packed kernel blob\n" + "\n" + " Optional:\n" + " --pad <number> Verification padding size in bytes\n" + " --vblockonly Emit just the verification blob\n", + progname); + fprintf(stderr, + "\nOR\n\n" + "Usage: %s --verify <file> [PARAMETERS]\n" + "\n" + " Required parameters:\n" + " --signpubkey <file> Signing public key in .vbpubk format\n" + "\n", + progname); return 1; } @@ -121,76 +153,68 @@ static unsigned int find_cmdline_start(char *input, unsigned int max_len) { } -/* Pack a .kernel */ -static int Pack(const char* outfile, const char* keyblock_file, - const char* signprivate, uint64_t version, - const char* vmlinuz, const char* bootloader_file, - const char* config_file, uint64_t pad) { +typedef struct blob_s { + /* Stuff needed by VbKernelPreambleHeader */ + uint64_t kernel_version; + uint64_t bootloader_address; + uint64_t bootloader_size; + /* Raw kernel blob data */ + uint64_t blob_size; + uint8_t *blob; +} blob_t; + +static void FreeBlob(blob_t *bp) { + if (bp) { + if (bp->blob) + Free(bp->blob); + Free(bp); + } +} + +/* Create a blob from its components */ +static blob_t *NewBlob(uint64_t version, + const char* vmlinuz, + const char* bootloader_file, + const char* config_file) { + blob_t *bp; struct linux_kernel_header *lh = 0; struct linux_kernel_params *params = 0; - VbPrivateKey* signing_key; - VbSignature* body_sig; - VbKernelPreambleHeader* preamble; - VbKeyBlockHeader* key_block; - uint64_t key_block_size; uint8_t* config_buf; uint64_t config_size; uint8_t* bootloader_buf; uint64_t bootloader_size; - uint64_t bootloader_mem_start; - uint64_t bootloader_mem_size; uint8_t* kernel_buf; uint64_t kernel_size; uint64_t kernel32_start = 0; uint64_t kernel32_size = 0; uint32_t cmdline_addr; uint8_t* blob = NULL; - uint64_t blob_size; uint64_t now = 0; - FILE* f; uint64_t i; - if (!outfile) { - error("Must specify output filename\n"); - return 1; - } - if (!keyblock_file || !signprivate) { - error("Must specify all keys\n"); - return 1; - } if (!vmlinuz || !bootloader_file || !config_file) { error("Must specify all input files\n"); - return 1; + return 0; } - /* Read the key block and private key */ - key_block = (VbKeyBlockHeader*)ReadFile(keyblock_file, &key_block_size); - if (!key_block) { - error("Error reading key block.\n"); - return 1; - } - if (pad < key_block->key_block_size) { - error("Pad too small\n"); - return 1; - } - - signing_key = PrivateKeyRead(signprivate, key_block->data_key.algorithm); - if (!signing_key) { - error("Error reading signing key.\n"); - return 1; + bp = (blob_t *)Malloc(sizeof(blob_t)); + if (!bp) { + error("Couldn't allocate bytes for blob_t.\n"); + return 0; } + bp->kernel_version = version; /* Read the config file */ Debug("Reading %s\n", config_file); config_buf = ReadFile(config_file, &config_size); if (!config_buf) - return 1; + return 0; Debug(" config file size=0x%" PRIx64 "\n", config_size); if (CROS_CONFIG_SIZE <= config_size) { /* need room for trailing '\0' */ error("Config file %s is too large (>= %d bytes)\n", config_file, CROS_CONFIG_SIZE); - return 1; + return 0; } /* Replace newlines with spaces */ for (i = 0; i < config_size; i++) @@ -201,18 +225,18 @@ static int Pack(const char* outfile, const char* keyblock_file, Debug("Reading %s\n", bootloader_file); bootloader_buf = ReadFile(bootloader_file, &bootloader_size); if (!bootloader_buf) - return 1; + return 0; Debug(" bootloader file size=0x%" PRIx64 "\n", bootloader_size); /* Read the kernel */ Debug("Reading %s\n", vmlinuz); kernel_buf = ReadFile(vmlinuz, &kernel_size); if (!kernel_buf) - return 1; + return 0; Debug(" kernel file size=0x%" PRIx64 "\n", kernel_size); if (!kernel_size) { error("Empty kernel file\n"); - return 1; + return 0; } /* The first part of vmlinuz is a header, followed by a real-mode @@ -221,24 +245,25 @@ static int Pack(const char* outfile, const char* keyblock_file, kernel32_start = (lh->setup_sects + 1) << 9; if (kernel32_start >= kernel_size) { error("Malformed kernel\n"); - return 1; + return 0; } kernel32_size = kernel_size - kernel32_start; Debug(" kernel32_start=0x%" PRIx64 "\n", kernel32_start); Debug(" kernel32_size=0x%" PRIx64 "\n", kernel32_size); /* Allocate and zero the blob we need. */ - blob_size = roundup(kernel32_size, CROS_ALIGN) + + bp->blob_size = roundup(kernel32_size, CROS_ALIGN) + CROS_CONFIG_SIZE + CROS_PARAMS_SIZE + roundup(bootloader_size, CROS_ALIGN); - blob = (uint8_t *)Malloc(blob_size); - Debug("blob_size=0x%" PRIx64 "\n", blob_size); + blob = (uint8_t *)Malloc(bp->blob_size); + Debug("blob_size=0x%" PRIx64 "\n", bp->blob_size); if (!blob) { - error("Couldn't allocate %ld bytes.\n", blob_size); - return 1; + error("Couldn't allocate %ld bytes.\n", bp->blob_size); + return 0; } - Memset(blob, 0, blob_size); + Memset(blob, 0, bp->blob_size); + bp->blob = blob; /* Copy the 32-bit kernel. */ Debug("kernel goes at blob+=0x%" PRIx64 "\n", now); @@ -273,13 +298,13 @@ static int Pack(const char* outfile, const char* keyblock_file, /* Finally, append the bootloader. Remember where it will load in * memory, too. */ Debug("bootloader goes at blob+=0x%" PRIx64 "\n", now); - bootloader_mem_start = CROS_32BIT_ENTRY_ADDR + now; - bootloader_mem_size = roundup(bootloader_size, CROS_ALIGN); - Debug(" bootloader_mem_start=0x%" PRIx64 "\n", bootloader_mem_start); - Debug(" bootloader_mem_size=0x%" PRIx64 "\n", bootloader_mem_size); + bp->bootloader_address = CROS_32BIT_ENTRY_ADDR + now; + bp->bootloader_size = roundup(bootloader_size, CROS_ALIGN); + Debug(" bootloader_address=0x%" PRIx64 "\n", bp->bootloader_address); + Debug(" bootloader_size=0x%" PRIx64 "\n", bp->bootloader_size); if (bootloader_size) Memcpy(blob + now, bootloader_buf, bootloader_size); - now += bootloader_mem_size; + now += bp->bootloader_size; Debug("end of blob is 0x%" PRIx64 "\n", now); /* Free input buffers */ @@ -287,18 +312,172 @@ static int Pack(const char* outfile, const char* keyblock_file, Free(config_buf); Free(bootloader_buf); + /* Success */ + return bp; +} + + +/* Pull the blob_t stuff out of a prepacked kernel blob file */ +static blob_t *OldBlob(const char* filename) { + FILE* fp; + blob_t *bp; + struct stat statbuf; + VbKeyBlockHeader* key_block; + VbKernelPreambleHeader* preamble; + uint64_t now = 0; + uint8_t buf[DEFAULT_PADDING]; + + if (!filename) { + error("Must specify prepacked blob to read\n"); + return 0; + } + + if (0 != stat(filename, &statbuf)) { + error("unable to stat %s: %s\n", filename, strerror(errno)); + return 0; + } + + Debug("%s size is 0x%" PRIx64 "\n", filename, statbuf.st_size); + if (statbuf.st_size < DEFAULT_PADDING) { + error("%s is too small to be a valid kernel blob\n"); + return 0; + } + + Debug("Reading %s\n", filename); + fp = fopen(filename, "rb"); + if (!fp) { + error("Unable to open file %s: %s\n", filename, strerror(errno)); + return 0; + } + + if (1 != fread(buf, sizeof(buf), 1, fp)) { + error("Unable to read header from %s: %s\n", filename, strerror(errno)); + fclose(fp); + return 0; + } + + /* Skip the key block */ + key_block = (VbKeyBlockHeader*)buf; + Debug("Keyblock is 0x%" PRIx64 " bytes\n", key_block->key_block_size); + now += key_block->key_block_size; + if (now > statbuf.st_size) { + error("key_block_size advances past the end of the blob\n"); + return 0; + } + + /* Skip the preamble */ + preamble = (VbKernelPreambleHeader*)(buf + now); + Debug("Preamble is 0x%" PRIx64 " bytes\n", preamble->preamble_size); + now += preamble->preamble_size; + if (now > statbuf.st_size) { + error("preamble_size advances past the end of the blob\n"); + return 0; + } + + /* Go find the kernel blob */ + Debug("kernel blob is at offset 0x%" PRIx64 "\n", now); + if (0 != fseek(fp, now, SEEK_SET)) { + error("Unable to seek to 0x%" PRIx64 " in %s: %s\n", now, filename, + strerror(errno)); + fclose(fp); + return 0; + } + + /* Remember what we've got */ + bp = (blob_t *)Malloc(sizeof(blob_t)); + if (!bp) { + error("Couldn't allocate bytes for blob_t.\n"); + fclose(fp); + return 0; + } + + bp->kernel_version = preamble->kernel_version; + bp->bootloader_address = preamble->bootloader_address; + bp->bootloader_size = preamble->bootloader_size; + bp->blob_size = preamble->body_signature.data_size; + + Debug(" kernel_version = %d\n", bp->kernel_version); + Debug(" bootloader_address = 0x%" PRIx64 "\n", bp->bootloader_address); + Debug(" bootloader_size = 0x%" PRIx64 "\n", bp->bootloader_size); + Debug(" blob_size = 0x%" PRIx64 "\n", bp->blob_size); + + bp->blob = (uint8_t *)Malloc(bp->blob_size); + if (!bp->blob) { + error("Couldn't allocate 0x%" PRIx64 " bytes for blob_t.\n", bp->blob_size); + fclose(fp); + Free(bp); + return 0; + } + + /* read it in */ + if (1 != fread(bp->blob, bp->blob_size, 1, fp)) { + error("Unable to read kernel blob from %s: %s\n", filename, strerror(errno)); + fclose(fp); + Free(bp); + return 0; + } + + /* done */ + fclose(fp); + + return bp; +} + + +/* Pack a .kernel */ +static int Pack(const char* outfile, const char* keyblock_file, + const char* signprivate, blob_t *bp, uint64_t pad, + int vblockonly) { + VbPrivateKey* signing_key; + VbSignature* body_sig; + VbKernelPreambleHeader* preamble; + VbKeyBlockHeader* key_block; + uint64_t key_block_size; + FILE* f; + uint64_t i; + + if (!outfile) { + error("Must specify output filename\n"); + return 1; + } + if (!keyblock_file || !signprivate) { + error("Must specify all keys\n"); + return 1; + } + if (!bp) { + error("Refusing to pack invalid kernel blob\n"); + return 1; + } + + /* Read the key block and private key */ + key_block = (VbKeyBlockHeader*)ReadFile(keyblock_file, &key_block_size); + if (!key_block) { + error("Error reading key block.\n"); + return 1; + } + if (pad < key_block->key_block_size) { + error("Pad too small\n"); + return 1; + } + + signing_key = PrivateKeyReadPem(signprivate, key_block->data_key.algorithm); + if (!signing_key) { + error("Error reading signing key.\n"); + return 1; + } + /* Sign the kernel data */ - body_sig = CalculateSignature(blob, blob_size, signing_key); + body_sig = CalculateSignature(bp->blob, bp->blob_size, signing_key); if (!body_sig) { error("Error calculating body signature\n"); return 1; } /* Create preamble */ - preamble = CreateKernelPreamble(version, + preamble = CreateKernelPreamble(bp->kernel_version, CROS_32BIT_ENTRY_ADDR, - bootloader_mem_start, - bootloader_mem_size, + bp->bootloader_address, + bp->bootloader_size, body_sig, pad - key_block_size, signing_key); @@ -316,17 +495,28 @@ static int Pack(const char* outfile, const char* keyblock_file, } Debug("0x%" PRIx64 " bytes of key_block\n", key_block_size); Debug("0x%" PRIx64 " bytes of preamble\n", preamble->preamble_size); - Debug("0x%" PRIx64 " bytes of blob\n", blob_size); i = ((1 != fwrite(key_block, key_block_size, 1, f)) || - (1 != fwrite(preamble, preamble->preamble_size, 1, f)) || - (1 != fwrite(blob, blob_size, 1, f))); - fclose(f); + (1 != fwrite(preamble, preamble->preamble_size, 1, f))); if (i) { error("Can't write output file %s\n", outfile); + fclose(f); unlink(outfile); return 1; } + if (!vblockonly) { + Debug("0x%" PRIx64 " bytes of blob\n", bp->blob_size); + i = (1 != fwrite(bp->blob, bp->blob_size, 1, f)); + if (i) { + error("Can't write output file %s\n", outfile); + fclose(f); + unlink(outfile); + return 1; + } + } + + fclose(f); + /* Success */ return 0; } @@ -373,7 +563,7 @@ static int Verify(const char* infile, const char* signpubkey) { printf("Key block:\n"); data_key = &key_block->data_key; - printf(" Size: %" PRIu64 "\n", key_block->key_block_size); + printf(" Size: 0x%" PRIx64 "\n", key_block->key_block_size); printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, (data_key->algorithm < kNumAlgorithms ? algo_strings[data_key->algorithm] : "(invalid)")); @@ -395,7 +585,7 @@ static int Verify(const char* infile, const char* signpubkey) { now += preamble->preamble_size; printf("Preamble:\n"); - printf(" Size: %" PRIu64 "\n", preamble->preamble_size); + printf(" Size: 0x%" PRIx64 "\n", preamble->preamble_size); printf(" Header version: %" PRIu32 ".%" PRIu32"\n", preamble->header_version_major, preamble->header_version_minor); printf(" Kernel version: %" PRIu64 "\n", preamble->kernel_version); @@ -416,8 +606,8 @@ static int Verify(const char* infile, const char* signpubkey) { int main(int argc, char* argv[]) { - char* filename = NULL; + char* oldfile = NULL; char* key_block_file = NULL; char* signpubkey = NULL; char* signprivate = NULL; @@ -425,26 +615,39 @@ int main(int argc, char* argv[]) { char* vmlinuz = NULL; char* bootloader = NULL; char* config_file = NULL; - uint64_t pad = 65536; + int vblockonly = 0; + uint64_t pad = DEFAULT_PADDING; int mode = 0; int parse_error = 0; char* e; - int i; + int i,r; + blob_t *bp; - while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { + + char *progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + 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_REPACK: case OPT_MODE_VERIFY: mode = i; filename = optarg; break; + case OPT_OLDBLOB: + oldfile = optarg; + break; + case OPT_KEYBLOCK: key_block_file = optarg; break; @@ -469,10 +672,14 @@ int main(int argc, char* argv[]) { config_file = optarg; break; + case OPT_VBLOCKONLY: + vblockonly = 1; + break; + case OPT_VERSION: version = strtoul(optarg, &e, 0); if (!*optarg || (e && *e)) { - printf("Invalid --version\n"); + fprintf(stderr, "Invalid --version\n"); parse_error = 1; } break; @@ -480,7 +687,7 @@ int main(int argc, char* argv[]) { case OPT_PAD: pad = strtoul(optarg, &e, 0); if (!*optarg || (e && *e)) { - printf("Invalid --pad\n"); + fprintf(stderr, "Invalid --pad\n"); parse_error = 1; } break; @@ -488,16 +695,31 @@ int main(int argc, char* argv[]) { } if (parse_error) - return PrintHelp(); + return PrintHelp(progname); switch(mode) { case OPT_MODE_PACK: - return Pack(filename, key_block_file, signprivate, version, vmlinuz, - bootloader, config_file, pad); + bp = NewBlob(version, vmlinuz, bootloader, config_file); + if (!bp) + return 1; + r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); + FreeBlob(bp); + return r; + + case OPT_MODE_REPACK: + bp = OldBlob(oldfile); + if (!bp) + return 1; + r = Pack(filename, key_block_file, signprivate, bp, pad, vblockonly); + FreeBlob(bp); + return r; + case OPT_MODE_VERIFY: return Verify(filename, signpubkey); + default: - printf("Must specify a mode.\n"); - return PrintHelp(); + fprintf(stderr, + "You must specify a mode: --pack, --repack or --verify\n"); + return PrintHelp(progname); } } diff --git a/utility/vbutil_keyblock.c b/utility/vbutil_keyblock.c index 43c5f061..dbdcbd3f 100644 --- a/utility/vbutil_keyblock.c +++ b/utility/vbutil_keyblock.c @@ -93,7 +93,7 @@ static int Pack(const char* outfile, const char* datapubkey, fprintf(stderr, "vbutil_keyblock: Error reading data key.\n"); return 1; } - signing_key = PrivateKeyRead(signprivate, algorithm); + signing_key = PrivateKeyReadPem(signprivate, algorithm); if (!signing_key) { fprintf(stderr, "vbutil_keyblock: Error reading signing key.\n"); return 1; |