/*
 * Copyright 2014 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.
 */

#include <openssl/rsa.h>

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "2sysincludes.h"
#include "2api.h"
#include "2common.h"
#include "2sha.h"
#include "file_type.h"
#include "file_type_bios.h"
#include "fmap.h"
#include "futility.h"
#include "futility_options.h"
#include "host_common.h"
#include "host_key2.h"
#include "util_misc.h"
#include "vb1_helper.h"
#include "vb2_common.h"

/* Options */
struct show_option_s show_option = {
	.padding = 65536,
	.type = FILE_TYPE_UNKNOWN,
};

/* Shared work buffer */
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE];
static struct vb2_workbuf wb;

void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp)
{
	printf("%sVboot API:           1.0\n", sp);
	printf("%sAlgorithm:           %d %s\n", sp, pubkey->algorithm,
	       vb2_get_crypto_algorithm_name(pubkey->algorithm));
	printf("%sKey Version:         %d\n", sp, pubkey->key_version);
	printf("%sKey sha1sum:         %s\n",
	       sp, packed_key_sha1_string(pubkey));
}

static void show_keyblock(struct vb2_keyblock *keyblock, const char *name,
			  int sign_key, int good_sig)
{
	if (name)
		printf("Key block:               %s\n", name);
	else
		printf("Key block:\n");
	printf("  Signature:             %s\n",
	       sign_key ? (good_sig ? "valid" : "invalid") : "ignored");
	printf("  Size:                  0x%x\n", keyblock->keyblock_size);
	printf("  Flags:                 %d ", keyblock->keyblock_flags);
	if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_DEVELOPER_0)
		printf(" !DEV");
	if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_DEVELOPER_1)
		printf(" DEV");
	if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_RECOVERY_0)
		printf(" !REC");
	if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_RECOVERY_1)
		printf(" REC");
	printf("\n");

	struct vb2_packed_key *data_key = &keyblock->data_key;
	printf("  Data key algorithm:    %d %s\n", data_key->algorithm,
	       vb2_get_crypto_algorithm_name(data_key->algorithm));
	printf("  Data key version:      %d\n", data_key->key_version);
	printf("  Data key sha1sum:      %s\n",
	       packed_key_sha1_string(data_key));
}

int ft_show_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf;

	if (!packed_key_looks_ok(pubkey, len)) {
		printf("%s looks bogus\n", name);
		return 1;
	}

	printf("Public Key file:       %s\n", name);
	show_pubkey(pubkey, "  ");

	return 0;
}

int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	struct vb2_packed_private_key *pkey =
		(struct vb2_packed_private_key *)buf;
	struct vb2_private_key key;
	const unsigned char *start = pkey->key_data;

	if (len <= sizeof(*pkey)) {
		printf("%s looks bogus\n", name);
		return 1;
	}
	len -= sizeof(*pkey);
	key.rsa_private_key = d2i_RSAPrivateKey(NULL, &start, len);

	printf("Private Key file:      %s\n", name);
	printf("  Vboot API:           1.0\n");
	printf("  Algorithm:           %u %s\n", pkey->algorithm,
	       vb2_get_crypto_algorithm_name(pkey->algorithm));
	printf("  Key sha1sum:         %s\n",
	       private_key_sha1_string(&key));

	return 0;
}

int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	struct vb2_keyblock *block = (struct vb2_keyblock *)buf;
	struct vb2_public_key *sign_key = show_option.k;
	int good_sig = 0;
	int retval = 0;

	/* Check the hash only first */
	if (0 != vb2_verify_keyblock_hash(block, len, &wb)) {
		printf("%s is invalid\n", name);
		return 1;
	}

	/* Check the signature if we have one */
	if (sign_key &&
	    VB2_SUCCESS == vb2_verify_keyblock(block, len, sign_key, &wb))
		good_sig = 1;

	if (show_option.strict && (!sign_key || !good_sig))
		retval = 1;

	show_keyblock(block, name, !!sign_key, good_sig);

	return retval;
}

int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len,
			void *data)
{
	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
	struct bios_state_s *state = (struct bios_state_s *)data;
	struct vb2_public_key *sign_key = show_option.k;
	uint8_t *fv_data = show_option.fv;
	uint64_t fv_size = show_option.fv_size;
	struct bios_area_s *fw_body_area = 0;
	int good_sig = 0;
	int retval = 0;

	/* Check the hash... */
	if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
		printf("%s keyblock component is invalid\n", name);
		return 1;
	}

	/*
	 * If we're being invoked while poking through a BIOS, we should
	 * be given the keys and data to verify as part of the state. If we
	 * have no state, then we're just looking at a standalone fw_preamble,
	 * so we'll have to get any keys or data from options.
	 */
	struct vb2_public_key root_key;
	if (state) {
		if (!sign_key &&
		    state->rootkey.is_valid &&
		    VB2_SUCCESS == vb2_unpack_key_buffer(&root_key,
							 state->rootkey.buf,
							 state->rootkey.len)) {
			/* BIOS should have a rootkey in the GBB */
			sign_key = &root_key;
		}

		/* Identify the firmware body for this VBLOCK */
		enum bios_component body_c = state->c == BIOS_FMAP_VBLOCK_A
			? BIOS_FMAP_FW_MAIN_A
			: BIOS_FMAP_FW_MAIN_B;
		fw_body_area = &state->area[body_c];
	}

	/* If we have a key, check the signature too */
	if (sign_key && VB2_SUCCESS ==
	    vb2_verify_keyblock(keyblock, len, sign_key, &wb))
		good_sig = 1;

	show_keyblock(keyblock, name, !!sign_key, good_sig);

	if (show_option.strict && (!sign_key || !good_sig))
		retval = 1;

	struct vb2_public_key data_key;
	if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
		fprintf(stderr, "Error parsing data key in %s\n", name);
		return 1;
	}

	uint32_t more = keyblock->keyblock_size;
	struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(buf + more);
	if (VB2_SUCCESS != vb2_verify_fw_preamble(pre2, len - more,
						  &data_key, &wb)) {
		printf("%s is invalid\n", name);
		return 1;
	}

	uint32_t flags = pre2->flags;
	if (pre2->header_version_minor < 1)
		flags = 0;  /* Old 2.0 structure didn't have flags */

	printf("Firmware Preamble:\n");
	printf("  Size:                  %d\n", pre2->preamble_size);
	printf("  Header version:        %d.%d\n",
	       pre2->header_version_major, pre2->header_version_minor);
	printf("  Firmware version:      %d\n", pre2->firmware_version);

	struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey;
	printf("  Kernel key algorithm:  %d %s\n",
	       kernel_subkey->algorithm,
	       vb2_get_crypto_algorithm_name(kernel_subkey->algorithm));
	if (kernel_subkey->algorithm >= VB2_ALG_COUNT)
		retval = 1;
	printf("  Kernel key version:    %d\n", kernel_subkey->key_version);
	printf("  Kernel key sha1sum:    %s\n",
	       packed_key_sha1_string(kernel_subkey));
	printf("  Firmware body size:    %d\n", pre2->body_signature.data_size);
	printf("  Preamble flags:        %d\n", flags);

	if (flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
		printf("Preamble requests USE_RO_NORMAL;"
		       " skipping body verification.\n");
		goto done;
	}

	/* We'll need to get the firmware body from somewhere... */
	if (fw_body_area && fw_body_area->is_valid) {
		fv_data = fw_body_area->buf;
		fv_size = fw_body_area->len;
	}

	if (!fv_data) {
		printf("No firmware body available to verify.\n");
		if (show_option.strict)
			return 1;
		return 0;
	}

	if (VB2_SUCCESS !=
	    vb2_verify_data(fv_data, fv_size, &pre2->body_signature,
			    &data_key, &wb)) {
		fprintf(stderr, "Error verifying firmware body.\n");
		return 1;
	}

done:
	/* Can't trust the BIOS unless everything is signed (in which case
	 * we've already returned), but standalone files are okay. */
	if (state || (sign_key && good_sig)) {
		if (!(flags & VB2_FIRMWARE_PREAMBLE_USE_RO_NORMAL))
			printf("Body verification succeeded.\n");
		if (state)
			state->area[state->c].is_valid = 1;
	} else {
		printf("Seems legit, but the signature is unverified.\n");
		if (show_option.strict)
			retval = 1;
	}

	return retval;
}

int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len,
			    void *data)
{
	struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf;
	struct vb2_public_key *sign_key = show_option.k;
	int retval = 0;

	/* Check the hash... */
	if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) {
		printf("%s keyblock component is invalid\n", name);
		return 1;
	}

	/* If we have a key, check the signature too */
	int good_sig = 0;
	if (sign_key && VB2_SUCCESS ==
	    vb2_verify_keyblock(keyblock, len, sign_key, &wb))
		good_sig = 1;

	printf("Kernel partition:        %s\n", name);
	show_keyblock(keyblock, NULL, !!sign_key, good_sig);

	if (show_option.strict && (!sign_key || !good_sig))
		retval = 1;

	struct vb2_public_key data_key;
	if (VB2_SUCCESS != vb2_unpack_key(&data_key, &keyblock->data_key)) {
		fprintf(stderr, "Error parsing data key in %s\n", name);
		return 1;
	}

	uint32_t more = keyblock->keyblock_size;
	struct vb2_kernel_preamble *pre2 =
		(struct vb2_kernel_preamble *)(buf + more);

	if (VB2_SUCCESS != vb2_verify_kernel_preamble(pre2, len - more,
						      &data_key, &wb)) {
		printf("%s is invalid\n", name);
		return 1;
	}

	printf("Kernel Preamble:\n");
	printf("  Size:                  0x%x\n", pre2->preamble_size);
	printf("  Header version:        %u.%u\n",
	       pre2->header_version_major,
	       pre2->header_version_minor);
	printf("  Kernel version:        %u\n", pre2->kernel_version);
	printf("  Body load address:     0x%" PRIx64 "\n",
	       pre2->body_load_address);
	printf("  Body size:             0x%x\n",
	       pre2->body_signature.data_size);
	printf("  Bootloader address:    0x%" PRIx64 "\n",
	       pre2->bootloader_address);
	printf("  Bootloader size:       0x%x\n", pre2->bootloader_size);

	uint64_t vmlinuz_header_address = 0;
	uint32_t vmlinuz_header_size = 0;
	vb2_kernel_get_vmlinuz_header(pre2,
				      &vmlinuz_header_address,
				      &vmlinuz_header_size);
	if (vmlinuz_header_size) {
		printf("  Vmlinuz_header address:    0x%" PRIx64 "\n",
		       vmlinuz_header_address);
		printf("  Vmlinuz header size:       0x%x\n",
		       vmlinuz_header_size);
	}

	printf("  Flags:                 0x%x\n", vb2_kernel_get_flags(pre2));

	/* Verify kernel body */
	uint8_t *kernel_blob = 0;
	uint64_t kernel_size = 0;
	if (show_option.fv) {
		/* It's in a separate file, which we've already read in */
		kernel_blob = show_option.fv;
		kernel_size = show_option.fv_size;
	} else if (len > show_option.padding) {
		/* It should be at an offset within the input file. */
		kernel_blob = buf + show_option.padding;
		kernel_size = len - show_option.padding;
	}

	if (!kernel_blob) {
		/* TODO: Is this always a failure? The preamble is okay. */
		fprintf(stderr, "No kernel blob available to verify.\n");
		return 1;
	}

	if (VB2_SUCCESS !=
	    vb2_verify_data(kernel_blob, kernel_size, &pre2->body_signature,
			    &data_key, &wb)) {
		fprintf(stderr, "Error verifying kernel body.\n");
		return 1;
	}

	printf("Body verification succeeded.\n");

	printf("Config:\n%s\n", kernel_blob + kernel_cmd_line_offset(pre2));

	return retval;
}

enum no_short_opts {
	OPT_PADDING = 1000,
	OPT_TYPE,
	OPT_PUBKEY,
	OPT_HELP,
};

static const char usage[] = "\n"
	"Usage:  " MYNAME " %s [OPTIONS] FILE [...]\n"
	"\n"
	"Where FILE could be\n"
	"\n"
	"  a boot descriptor block (BDB)\n"
	"  a keyblock (.keyblock)\n"
	"  a firmware preamble signature (VBLOCK_A/B)\n"
	"  a firmware image (bios.bin)\n"
	"  a kernel partition (/dev/sda2, /dev/mmcblk0p2)\n"
	"  keys in various formats (.vbpubk, .vbprivk, .pem)\n"
	"  several other file types related to verified boot\n"
	"\n"
	"Options:\n"
	"  -t                               Just show the type of each file\n"
	"  --type           TYPE            Override the detected file type\n"
	"                                     Use \"--type help\" for a list\n"
	"Type-specific options:\n"
	"  -k|--publickey   FILE.vbpubk     Public key in vb1 format\n"
	"  --pubkey         FILE.vpubk2     Public key in vb2 format\n"
	"  -f|--fv          FILE            Verify this payload (FW_MAIN_A/B)\n"
	"  --pad            NUM             Kernel vblock padding size\n"
	"  --strict                         "
	"Fail unless all signatures are valid\n"
	"\n";

static void print_help(int argc, char *argv[])
{
	if (!strcmp(argv[0], "verify"))
		printf("\nUsage:  " MYNAME " %s [OPTIONS] FILE [...]\n\n"
		       "This is just an alias for\n\n"
		       "  " MYNAME " show --strict\n\n",
		       argv[0]);

	printf(usage, "show");
}

static const struct option long_opts[] = {
	/* name    hasarg *flag val */
	{"publickey",   1, 0, 'k'},
	{"fv",          1, 0, 'f'},
	{"pad",         1, NULL, OPT_PADDING},
	{"type",        1, NULL, OPT_TYPE},
	{"strict",      0, &show_option.strict, 1},
	{"pubkey",      1, NULL, OPT_PUBKEY},
	{"help",        0, NULL, OPT_HELP},
	{NULL, 0, NULL, 0},
};
static char *short_opts = ":f:k:t";


static int show_type(char *filename)
{
	enum futil_file_err err;
	enum futil_file_type type;
	err = futil_file_type(filename, &type);
	switch (err) {
	case FILE_ERR_NONE:
		printf("%s:\t%s\n", filename, futil_file_type_name(type));
		/* Only our recognized types return success */
		return 0;
	case FILE_ERR_DIR:
		printf("%s:\t%s\n", filename, "directory");
		break;
	case FILE_ERR_CHR:
		printf("%s:\t%s\n", filename, "character special");
		break;
	case FILE_ERR_FIFO:
		printf("%s:\t%s\n", filename, "FIFO");
		break;
	case FILE_ERR_SOCK:
		printf("%s:\t%s\n", filename, "socket");
		break;
	default:
		break;
	}
	/* Everything else is an error */
	return 1;
}

static int do_show(int argc, char *argv[])
{
	uint8_t *pubkbuf = NULL;
	struct vb2_public_key pubk2;
	char *infile = 0;
	int ifd, i;
	int errorcnt = 0;
	uint8_t *buf;
	uint32_t len;
	char *e = 0;
	int type_override = 0;
	enum futil_file_type type;

	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));

	opterr = 0;		/* quiet, you */
	while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
		switch (i) {
		case 'f':
			show_option.fv = ReadFile(optarg,
						  &show_option.fv_size);
			if (!show_option.fv) {
				fprintf(stderr, "Error reading %s: %s\n",
					optarg, strerror(errno));
				errorcnt++;
			}
			break;
		case 'k':
			if (VB2_SUCCESS !=
			    vb2_read_file(optarg, &pubkbuf, &len)) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
				break;
			}

			if (VB2_SUCCESS !=
			    vb2_unpack_key_buffer(&pubk2, pubkbuf, len)) {
				fprintf(stderr, "Error unpacking %s\n", optarg);
				errorcnt++;
				break;
			}

			show_option.k = &pubk2;
			break;
		case 't':
			show_option.t_flag = 1;
			break;
		case OPT_PADDING:
			show_option.padding = strtoul(optarg, &e, 0);
			if (!*optarg || (e && *e)) {
				fprintf(stderr,
					"Invalid --padding \"%s\"\n", optarg);
				errorcnt++;
			}
			break;
		case OPT_TYPE:
			if (!futil_str_to_file_type(optarg,
						    &show_option.type)) {
				if (!strcasecmp("help", optarg))
					print_file_types_and_exit(errorcnt);
				fprintf(stderr,
					"Invalid --type \"%s\"\n", optarg);
				errorcnt++;
			}
			type_override = 1;
			break;
		case OPT_PUBKEY:
			if (vb21_packed_key_read(&show_option.pkey, optarg)) {
				fprintf(stderr, "Error reading %s\n", optarg);
				errorcnt++;
			}
			break;
		case OPT_HELP:
			print_help(argc, argv);
			return !!errorcnt;

		case '?':
			if (optopt)
				fprintf(stderr, "Unrecognized option: -%c\n",
					optopt);
			else
				fprintf(stderr, "Unrecognized option\n");
			errorcnt++;
			break;
		case ':':
			fprintf(stderr, "Missing argument to -%c\n", optopt);
			errorcnt++;
			break;
		case 0:				/* handled option */
			break;
		default:
			DIE;
		}
	}

	if (errorcnt) {
		print_help(argc, argv);
		return 1;
	}

	if (argc - optind < 1) {
		fprintf(stderr, "ERROR: missing input filename\n");
		print_help(argc, argv);
		return 1;
	}

	if (show_option.t_flag) {
		for (i = optind; i < argc; i++)
			errorcnt += show_type(argv[i]);
		goto done;
	}

	for (i = optind; i < argc; i++) {
		infile = argv[i];
		ifd = open(infile, O_RDONLY);
		if (ifd < 0) {
			errorcnt++;
			fprintf(stderr, "Can't open %s: %s\n",
				infile, strerror(errno));
			continue;
		}

		if (0 != futil_map_file(ifd, MAP_RO, &buf, &len)) {
			errorcnt++;
			goto boo;
		}

		/* Allow the user to override the type */
		if (type_override)
			type = show_option.type;
		else
			type = futil_file_type_buf(buf, len);

		errorcnt += futil_file_type_show(type, infile, buf, len);

		errorcnt += futil_unmap_file(ifd, MAP_RO, buf, len);
boo:
		if (close(ifd)) {
			errorcnt++;
			fprintf(stderr, "Error when closing %s: %s\n",
				infile, strerror(errno));
		}
	}

done:
	if (pubkbuf)
		free(pubkbuf);
	if (show_option.fv)
		free(show_option.fv);

	return !!errorcnt;
}

DECLARE_FUTIL_COMMAND(show, do_show, VBOOT_VERSION_ALL,
		      "Display the content of various binary components");

static int do_verify(int argc, char *argv[])
{
	show_option.strict = 1;
	return do_show(argc, argv);
}

DECLARE_FUTIL_COMMAND(verify, do_verify,
		      VBOOT_VERSION_ALL,
		      "Verify the signatures of various binary components");
