/* Copyright 2015 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/pem.h>

#include "2common.h"
#include "2id.h"
#include "2rsa.h"
#include "2sha.h"
#include "2sysincludes.h"
#include "file_type.h"
#include "futility.h"
#include "futility_options.h"
#include "host_common.h"
#include "host_common21.h"
#include "host_key21.h"
#include "host_misc21.h"
#include "openssl_compat.h"
#include "util_misc.h"

int vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *alg)
{
	const struct vb2_text_vs_enum *entry;
	uint32_t val;
	char *e;

	/* try string first */
	entry = vb2_lookup_by_name(vb2_text_vs_hash, str);
	if (entry) {
		*alg = entry->num;
		return 1;
	}

	/* fine, try number */
	val = strtoul(str, &e, 0);
	if (!*str || (e && *e))
		/* that's not a number */
		return 0;

	if (!vb2_lookup_by_num(vb2_text_vs_hash, val))
		/* That's not a valid alg */
		return 0;

	*alg = val;
	return 1;
}

enum futil_file_type ft_recognize_vb21_key(uint8_t *buf, uint32_t len)
{
	struct vb2_public_key pubkey;
	struct vb2_private_key *privkey = 0;

	/* The pubkey points into buf, so nothing to free */
	if (VB2_SUCCESS == vb21_unpack_key(&pubkey, buf, len))
		return FILE_TYPE_VB2_PUBKEY;

	/* The private key unpacks into new structs */
	if (VB2_SUCCESS == vb21_private_key_unpack(&privkey, buf, len)) {
		vb2_private_key_free(privkey);
		return FILE_TYPE_VB2_PRIVKEY;
	}

	return FILE_TYPE_UNKNOWN;
}

static inline void vb2_print_bytes(const void *ptr, uint32_t len)
{
	const uint8_t *buf = (const uint8_t *)ptr;
	int i;
	for (i = 0; i < len; i++)
		printf("%02x", *buf++);
}

static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest)
{
	struct vb21_packed_key *pkey;

	if (vb21_public_key_pack(&pkey, key))
		return 0;

	vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size,
			  VB2_HASH_SHA1, digest, VB2_SHA1_DIGEST_SIZE);

	free(pkey);
	return 1;
}

int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len,
			void *data)
{
	struct vb2_public_key key;
	uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];

	/* The key's members will point into the state buffer after this. Don't
	 * free anything. */
	if (VB2_SUCCESS != vb21_unpack_key(&key, buf, len))
		return 1;

	printf("Public Key file:       %s\n", name);
	printf("  Vboot API:           2.1\n");
	printf("  Desc:                \"%s\"\n", key.desc);
	printf("  Signature Algorithm: %d %s\n", key.sig_alg,
	       vb2_get_sig_algorithm_name(key.sig_alg));
	printf("  Hash Algorithm:      %d %s\n", key.hash_alg,
	       vb2_get_hash_algorithm_name(key.hash_alg));
	printf("  Version:             0x%08x\n", key.version);
	printf("  ID:                  ");
	vb2_print_bytes(key.id, sizeof(*key.id));
	printf("\n");
	if (vb2_public_key_sha1sum(&key, sha1sum) &&
	    memcmp(key.id, sha1sum, sizeof(*key.id))) {
		printf("  Key sha1sum:         ");
		vb2_print_bytes(sha1sum, sizeof(sha1sum));
		printf("\n");
	}
	return 0;
}

static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
{
	uint8_t *buf;
	uint32_t buflen;

	if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen))
		return 0;

	vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest,
			  VB2_SHA1_DIGEST_SIZE);

	free(buf);
	return 1;
}

int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len,
			 void *data)
{
	struct vb2_private_key *key = 0;
	uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];

	if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len))
		return 1;

	printf("Private key file:      %s\n", name);
	printf("  Vboot API:           2.1\n");
	printf("  Desc:                \"%s\"\n", key->desc ? key->desc : "");
	printf("  Signature Algorithm: %d %s\n", key->sig_alg,
	       vb2_get_sig_algorithm_name(key->sig_alg));
	printf("  Hash Algorithm:      %d %s\n", key->hash_alg,
	       vb2_get_hash_algorithm_name(key->hash_alg));
	printf("  ID:                  ");
	vb2_print_bytes(&key->id, sizeof(key->id));
	printf("\n");
	if (vb2_private_key_sha1sum(key, sha1sum) &&
	    memcmp(&key->id, sha1sum, sizeof(key->id))) {
		printf("  Key sha1sum:         ");
		vb2_print_bytes(sha1sum, sizeof(sha1sum));
		printf("\n");
	}
	vb2_private_key_free(key);
	return 0;
}

static RSA *rsa_from_buffer(uint8_t *buf, uint32_t len)
{
	BIO *bp;
	RSA *rsa_key;

	bp = BIO_new_mem_buf(buf, len);
	if (!bp)
		return 0;

	rsa_key = PEM_read_bio_RSAPrivateKey(bp, NULL, NULL, NULL);
	if (!rsa_key) {
		if (BIO_reset(bp) < 0)
			return 0;
		rsa_key = PEM_read_bio_RSA_PUBKEY(bp, NULL, NULL, NULL);
	}
	if (!rsa_key) {
		BIO_free(bp);
		return 0;
	}

	BIO_free(bp);

	return rsa_key;
}

enum futil_file_type ft_recognize_pem(uint8_t *buf, uint32_t len)
{
	RSA *rsa_key = rsa_from_buffer(buf, len);

	if (rsa_key) {
		RSA_free(rsa_key);
		return FILE_TYPE_PEM;
	}

	return FILE_TYPE_UNKNOWN;
}

int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
{
	RSA *rsa_key;
	uint8_t *keyb;
	uint8_t digest[VB2_SHA1_DIGEST_SIZE];
	uint32_t keyb_len;
	int i, bits;
	const BIGNUM *rsa_key_n, *rsa_key_d;

	/* We're called only after ft_recognize_pem, so this should work. */
	rsa_key = rsa_from_buffer(buf, len);
	if (!rsa_key)
		FATAL("No RSA key found in buffer\n");

	/* Use to presence of the private exponent to decide if it's public */
	RSA_get0_key(rsa_key, &rsa_key_n, NULL, &rsa_key_d);
	printf("%s Key file:      %s\n", rsa_key_d ? "Private" : "Public",
					 name);

	bits = BN_num_bits(rsa_key_n);
	printf("  Key length:          %d\n", bits);

	if (vb_keyb_from_rsa(rsa_key, &keyb, &keyb_len)) {
		printf("  Key sha1sum:         <error>");
		RSA_free(rsa_key);
		return 1;
	}

	printf("  Key sha1sum:         ");
	vb2_digest_buffer(keyb, keyb_len, VB2_HASH_SHA1,
			  digest, sizeof(digest));
	for (i = 0; i < sizeof(digest); i++)
		printf("%02x", digest[i]);
	printf("\n");

	free(keyb);
	RSA_free(rsa_key);
	return 0;
}
