/* 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"

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 show_vb21_pubkey_buf(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;
}

int ft_show_vb21_pubkey(const char *name, void *data)
{
	int fd = -1;
	uint8_t *buf;
	uint32_t len;
	int rv;

	if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
		return 1;

	rv = show_vb21_pubkey_buf(name, buf, len, data);

	futil_unmap_and_close_file(fd, FILE_RO, buf, len);
	return rv;
}

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, void *data)
{
	struct vb2_private_key *key = 0;
	uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
	int fd = -1;
	uint8_t *buf;
	uint32_t len;
	int rv = 0;

	if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
		return 1;

	if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len)) {
		rv = 1;
		goto done;
	}

	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);
done:
	futil_unmap_and_close_file(fd, FILE_RO, buf, len);
	return rv;
}

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, 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;
	int fd = -1;
	uint8_t *buf;
	uint32_t len;
	int rv = 0;

	if (futil_open_and_map_file(name, &fd, FILE_RO, &buf, &len))
		return 1;

	/* 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);
		rv = 1;
		goto done;
	}

	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);
done:
	futil_unmap_and_close_file(fd, FILE_RO, buf, len);
	return rv;
}
