/*
 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/conf.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/x509v3.h>

#include "cert.h"
#include "debug.h"
#include "ext.h"
#include "key.h"
#include "platform_oid.h"
#include "sha.h"
#include "tbb_ext.h"
#include "tbb_cert.h"
#include "tbb_key.h"

/*
 * Helper macros to simplify the code. This macro assigns the return value of
 * the 'fn' function to 'v' and exits if the value is NULL.
 */
#define CHECK_NULL(v, fn) \
	do { \
		v = fn; \
		if (v == NULL) { \
			ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
			exit(1); \
		} \
	} while (0)

/*
 * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
 * NID is undefined.
 */
#define CHECK_OID(v, oid) \
	do { \
		v = OBJ_txt2nid(oid); \
		if (v == NID_undef) { \
			ERROR("Cannot find TBB extension %s\n", oid); \
			exit(1); \
		} \
	} while (0)

#define MAX_FILENAME_LEN		1024
#define VAL_DAYS			7300
#define ID_TO_BIT_MASK(id)		(1 << id)
#define NVCOUNTER_VALUE			0
#define NUM_ELEM(x)			((sizeof(x)) / (sizeof(x[0])))

/* Files */
enum {
	/* Image file names (inputs) */
	BL2_ID = 0,
	BL30_ID,
	BL31_ID,
	BL32_ID,
	BL33_ID,
	/* Certificate file names (outputs) */
	BL2_CERT_ID,
	TRUSTED_KEY_CERT_ID,
	BL30_KEY_CERT_ID,
	BL30_CERT_ID,
	BL31_KEY_CERT_ID,
	BL31_CERT_ID,
	BL32_KEY_CERT_ID,
	BL32_CERT_ID,
	BL33_KEY_CERT_ID,
	BL33_CERT_ID,
	/* Key file names (input/output) */
	ROT_KEY_ID,
	TRUSTED_WORLD_KEY_ID,
	NON_TRUSTED_WORLD_KEY_ID,
	BL30_KEY_ID,
	BL31_KEY_ID,
	BL32_KEY_ID,
	BL33_KEY_ID,
	NUM_OPTS
};

/* Global options */
static int key_alg;
static int new_keys;
static int save_keys;
static int print_cert;
static int bl30_present;
static int bl32_present;

/* We are not checking nvcounters in TF. Include them in the certificates but
 * the value will be set to 0 */
static int tf_nvcounter;
static int non_tf_nvcounter;

/* Info messages created in the Makefile */
extern const char build_msg[];
extern const char platform_msg[];


static char *strdup(const char *str)
{
	int n = strlen(str) + 1;
	char *dup = malloc(n);
	if (dup) {
		strcpy(dup, str);
	}
	return dup;
}

static const char *key_algs_str[] = {
	[KEY_ALG_RSA] = "rsa",
#ifndef OPENSSL_NO_EC
	[KEY_ALG_ECDSA] = "ecdsa"
#endif /* OPENSSL_NO_EC */
};

/* Command line options */
static const struct option long_opt[] = {
	/* Binary images */
	{"bl2", required_argument, 0, BL2_ID},
	{"bl30", required_argument, 0, BL30_ID},
	{"bl31", required_argument, 0, BL31_ID},
	{"bl32", required_argument, 0, BL32_ID},
	{"bl33", required_argument, 0, BL33_ID},
	/* Certificate files */
	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
	/* Private key files */
	{"rot-key", required_argument, 0, ROT_KEY_ID},
	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
	{"bl30-key", required_argument, 0, BL30_KEY_ID},
	{"bl31-key", required_argument, 0, BL31_KEY_ID},
	{"bl32-key", required_argument, 0, BL32_KEY_ID},
	{"bl33-key", required_argument, 0, BL33_KEY_ID},
	/* Common options */
	{"key-alg", required_argument, 0, 'a'},
	{"help", no_argument, 0, 'h'},
	{"save-keys", no_argument, 0, 'k'},
	{"new-chain", no_argument, 0, 'n'},
	{"print-cert", no_argument, 0, 'p'},
	{0, 0, 0, 0}
};

static void print_help(const char *cmd)
{
	int i = 0;
	printf("\n\n");
	printf("The certificate generation tool loads the binary images and\n"
	       "optionally the RSA keys, and outputs the key and content\n"
	       "certificates properly signed to implement the chain of trust.\n"
	       "If keys are provided, they must be in PEM format.\n"
	       "Certificates are generated in DER format.\n");
	printf("\n");
	printf("Usage:\n\n");
	printf("    %s [-hknp] \\\n", cmd);
	for (i = 0; i < NUM_OPTS; i++) {
		printf("        --%s <file>  \\\n", long_opt[i].name);
	}
	printf("\n");
	printf("-a    Key algorithm: rsa (default), ecdsa\n");
	printf("-h    Print help and exit\n");
	printf("-k    Save key pairs into files. Filenames must be provided\n");
	printf("-n    Generate new key pairs if no key files are provided\n");
	printf("-p    Print the certificates in the standard output\n");
	printf("\n");

	exit(0);
}

static int get_key_alg(const char *key_alg_str)
{
	int i;

	for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
		if (0 == strcmp(key_alg_str, key_algs_str[i])) {
			return i;
		}
	}

	return -1;
}

static void check_cmd_params(void)
{
	/* Only save new keys */
	if (save_keys && !new_keys) {
		ERROR("Only new keys can be saved to disk\n");
		exit(1);
	}

	/* BL2, BL31 and BL33 are mandatory */
	if (certs[BL2_CERT].bin == NULL) {
		ERROR("BL2 image not specified\n");
		exit(1);
	}

	if (certs[BL31_CERT].bin == NULL) {
		ERROR("BL31 image not specified\n");
		exit(1);
	}

	if (certs[BL33_CERT].bin == NULL) {
		ERROR("BL33 image not specified\n");
		exit(1);
	}

	/* BL30 and BL32 are optional */
	if (certs[BL30_CERT].bin != NULL) {
		bl30_present = 1;
	}

	if (certs[BL32_CERT].bin != NULL) {
		bl32_present = 1;
	}

	/* TODO: Certificate filenames */

	/* Filenames to store keys must be specified */
	if (save_keys || !new_keys) {
		if (keys[ROT_KEY].fn == NULL) {
			ERROR("ROT key not specified\n");
			exit(1);
		}

		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
			ERROR("Trusted World key not specified\n");
			exit(1);
		}

		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
			ERROR("Non-trusted World key not specified\n");
			exit(1);
		}

		if (keys[BL31_KEY].fn == NULL) {
			ERROR("BL31 key not specified\n");
			exit(1);
		}

		if (keys[BL33_KEY].fn == NULL) {
			ERROR("BL33 key not specified\n");
			exit(1);
		}

		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
			ERROR("BL30 key not specified\n");
			exit(1);
		}

		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
			ERROR("BL32 key not specified\n");
			exit(1);
		}
	}
}

int main(int argc, char *argv[])
{
	STACK_OF(X509_EXTENSION) * sk = NULL;
	X509_EXTENSION *hash_ext = NULL;
	X509_EXTENSION *nvctr_ext = NULL;
	X509_EXTENSION *trusted_key_ext = NULL;
	X509_EXTENSION *non_trusted_key_ext = NULL;
	FILE *file = NULL;
	int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
	int c, opt_idx = 0;
	unsigned int err_code;
	unsigned char md[SHA256_DIGEST_LENGTH];
	const EVP_MD *md_info;

	NOTICE("CoT Generation Tool: %s\n", build_msg);
	NOTICE("Target platform: %s\n", platform_msg);

	/* Set default options */
	key_alg = KEY_ALG_RSA;

	while (1) {
		/* getopt_long stores the option index here. */
		c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);

		/* Detect the end of the options. */
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'a':
			key_alg = get_key_alg(optarg);
			if (key_alg < 0) {
				ERROR("Invalid key algorithm '%s'\n", optarg);
				exit(1);
			}
			break;
		case 'h':
			print_help(argv[0]);
			break;
		case 'k':
			save_keys = 1;
			break;
		case 'n':
			new_keys = 1;
			break;
		case 'p':
			print_cert = 1;
			break;
		case BL2_ID:
			certs[BL2_CERT].bin = strdup(optarg);
			break;
		case BL30_ID:
			certs[BL30_CERT].bin = strdup(optarg);
			break;
		case BL31_ID:
			certs[BL31_CERT].bin = strdup(optarg);
			break;
		case BL32_ID:
			certs[BL32_CERT].bin = strdup(optarg);
			break;
		case BL33_ID:
			certs[BL33_CERT].bin = strdup(optarg);
			break;
		case BL2_CERT_ID:
			certs[BL2_CERT].fn = strdup(optarg);
			break;
		case TRUSTED_KEY_CERT_ID:
			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
			break;
		case BL30_KEY_CERT_ID:
			certs[BL30_KEY_CERT].fn = strdup(optarg);
			break;
		case BL30_CERT_ID:
			certs[BL30_CERT].fn = strdup(optarg);
			break;
		case BL31_KEY_CERT_ID:
			certs[BL31_KEY_CERT].fn = strdup(optarg);
			break;
		case BL31_CERT_ID:
			certs[BL31_CERT].fn = strdup(optarg);
			break;
		case BL32_KEY_CERT_ID:
			certs[BL32_KEY_CERT].fn = strdup(optarg);
			break;
		case BL32_CERT_ID:
			certs[BL32_CERT].fn = strdup(optarg);
			break;
		case BL33_KEY_CERT_ID:
			certs[BL33_KEY_CERT].fn = strdup(optarg);
			break;
		case BL33_CERT_ID:
			certs[BL33_CERT].fn = strdup(optarg);
			break;
		case ROT_KEY_ID:
			keys[ROT_KEY].fn = strdup(optarg);
			break;
		case TRUSTED_WORLD_KEY_ID:
			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
			break;
		case NON_TRUSTED_WORLD_KEY_ID:
			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
			break;
		case BL30_KEY_ID:
			keys[BL30_KEY].fn = strdup(optarg);
			break;
		case BL31_KEY_ID:
			keys[BL31_KEY].fn = strdup(optarg);
			break;
		case BL32_KEY_ID:
			keys[BL32_KEY].fn = strdup(optarg);
			break;
		case BL33_KEY_ID:
			keys[BL33_KEY].fn = strdup(optarg);
			break;
		case '?':
		default:
			printf("%s\n", optarg);
			exit(1);
		}
	}

	/* Set the value of the NVCounters */
	tf_nvcounter = NVCOUNTER_VALUE;
	non_tf_nvcounter = NVCOUNTER_VALUE;

	/* Check command line arguments */
	check_cmd_params();

	/* Register the new types and OIDs for the extensions */
	if (ext_init(tbb_ext) != 0) {
		ERROR("Cannot initialize TBB extensions\n");
		exit(1);
	}

	/* Indicate SHA256 as image hash algorithm in the certificate
	 * extension */
	md_info = EVP_sha256();

	/* Get non-volatile counters NIDs */
	CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID);
	CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);

	/* Load private keys from files (or generate new ones) */
	for (i = 0 ; i < NUM_KEYS ; i++) {
		/* First try to load the key from disk */
		if (key_load(&keys[i], &err_code)) {
			/* Key loaded successfully */
			continue;
		}

		/* Key not loaded. Check the error code */
		if (err_code == KEY_ERR_MALLOC) {
			/* Cannot allocate memory. Abort. */
			ERROR("Malloc error while loading '%s'\n", keys[i].fn);
			exit(1);
		} else if (err_code == KEY_ERR_LOAD) {
			/* File exists, but it does not contain a valid private
			 * key. Abort. */
			ERROR("Error loading '%s'\n", keys[i].fn);
			exit(1);
		}

		/* File does not exist, could not be opened or no filename was
		 * given */
		if (new_keys) {
			/* Try to create a new key */
			NOTICE("Creating new key for '%s'\n", keys[i].desc);
			if (!key_create(&keys[i], key_alg)) {
				ERROR("Error creating key '%s'\n", keys[i].desc);
				exit(1);
			}
		} else {
			if (err_code == KEY_ERR_OPEN) {
				ERROR("Error opening '%s'\n", keys[i].fn);
			} else {
				ERROR("Key '%s' not specified\n", keys[i].desc);
			}
			exit(1);
		}
	}

	/* *********************************************************************
	 * BL2 certificate (Trusted Boot Firmware certificate):
	 *     - Self-signed with OEM ROT private key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - BL2 hash
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());

	/* Add the NVCounter as a critical extension */
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);

	/* Add hash of BL2 as an extension */
	if (!sha_file(certs[BL2_CERT].bin, md)) {
		ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin);
		exit(1);
	}
	CHECK_OID(hash_nid, BL2_HASH_OID);
	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
			SHA256_DIGEST_LENGTH));
	sk_X509_EXTENSION_push(sk, hash_ext);

	/* Create certificate. Signed with ROT key */
	if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL2_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * Trusted Key certificate:
	 *     - Self-signed with OEM ROT private key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - TrustedWorldPK
	 *         - NonTrustedWorldPK
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);
	CHECK_OID(pk_nid, TZ_WORLD_PK_OID);
	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[TRUSTED_WORLD_KEY].key));
	sk_X509_EXTENSION_push(sk, trusted_key_ext);
	CHECK_OID(pk_nid, NTZ_WORLD_PK_OID);
	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[NON_TRUSTED_WORLD_KEY].key));
	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
	if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL30 Key certificate (Trusted SCP Firmware Key certificate):
	 *     - Self-signed with Trusted World key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - SCPFirmwareContentCertPK
	 **********************************************************************/
	if (bl30_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);
		CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID);
		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
				keys[BL30_KEY].key));
		sk_X509_EXTENSION_push(sk, trusted_key_ext);
		if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn);
			exit(1);
		}
		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL30 certificate (SCP Firmware Content certificate):
	 *     - Signed with Trusted World Key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - SCPFirmwareHash
	 **********************************************************************/
	if (bl30_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);

		if (!sha_file(certs[BL30_CERT].bin, md)) {
			ERROR("Cannot calculate the hash of %s\n",
					certs[BL30_CERT].bin);
			exit(1);
		}
		CHECK_OID(hash_nid, BL30_HASH_OID);
		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info,
				md, SHA256_DIGEST_LENGTH));
		sk_X509_EXTENSION_push(sk, hash_ext);

		if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL30_CERT].cn);
			exit(1);
		}

		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL31 Key certificate (Trusted SoC Firmware Key certificate):
	 *     - Self-signed with Trusted World key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - SoCFirmwareContentCertPK
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);
	CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID);
	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[BL31_KEY].key));
	sk_X509_EXTENSION_push(sk, trusted_key_ext);
	if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL31 certificate (SOC Firmware Content certificate):
	 *     - Signed with Trusted World Key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - BL31 hash
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
			tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);

	if (!sha_file(certs[BL31_CERT].bin, md)) {
		ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin);
		exit(1);
	}
	CHECK_OID(hash_nid, BL31_HASH_OID);
	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
			SHA256_DIGEST_LENGTH));
	sk_X509_EXTENSION_push(sk, hash_ext);

	if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL31_CERT].cn);
		exit(1);
	}

	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL32 Key certificate (Trusted OS Firmware Key certificate):
	 *     - Self-signed with Trusted World key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - TrustedOSFirmwareContentCertPK
	 **********************************************************************/
	if (bl32_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);
		CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID);
		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
				keys[BL32_KEY].key));
		sk_X509_EXTENSION_push(sk, trusted_key_ext);
		if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn);
			exit(1);
		}
		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL32 certificate (TrustedOS Firmware Content certificate):
	 *     - Signed with Trusted World Key
	 *     - Extensions:
	 *         - TrustedFirmwareNVCounter (TODO)
	 *         - BL32 hash
	 **********************************************************************/
	if (bl32_present) {
		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
				tf_nvcounter));
		sk_X509_EXTENSION_push(sk, nvctr_ext);

		if (!sha_file(certs[BL32_CERT].bin, md)) {
			ERROR("Cannot calculate the hash of %s\n",
					certs[BL32_CERT].bin);
			exit(1);
		}
		CHECK_OID(hash_nid, BL32_HASH_OID);
		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info,
				md, SHA256_DIGEST_LENGTH));
		sk_X509_EXTENSION_push(sk, hash_ext);

		if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) {
			ERROR("Cannot create %s\n", certs[BL32_CERT].cn);
			exit(1);
		}

		sk_X509_EXTENSION_free(sk);
	}

	/* *********************************************************************
	 * BL33 Key certificate (Non Trusted Firmware Key certificate):
	 *     - Self-signed with Non Trusted World key
	 *     - Extensions:
	 *         - NonTrustedFirmwareNVCounter (TODO)
	 *         - NonTrustedFirmwareContentCertPK
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
			non_tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);
	CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID);
	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
			keys[BL33_KEY].key));
	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
	if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* *********************************************************************
	 * BL33 certificate (Non-Trusted World Content certificate):
	 *     - Signed with Non-Trusted World Key
	 *     - Extensions:
	 *         - NonTrustedFirmwareNVCounter (TODO)
	 *         - BL33 hash
	 **********************************************************************/
	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
			non_tf_nvcounter));
	sk_X509_EXTENSION_push(sk, nvctr_ext);

	if (!sha_file(certs[BL33_CERT].bin, md)) {
		ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin);
		exit(1);
	}
	CHECK_OID(hash_nid, BL33_HASH_OID);
	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
			SHA256_DIGEST_LENGTH));
	sk_X509_EXTENSION_push(sk, hash_ext);

	if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) {
		ERROR("Cannot create %s\n", certs[BL33_CERT].cn);
		exit(1);
	}
	sk_X509_EXTENSION_free(sk);

	/* Print the certificates */
	if (print_cert) {
		for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
			if (!certs[i].x) {
				continue;
			}
			printf("\n\n=====================================\n\n");
			X509_print_fp(stdout, certs[i].x);
		}
	}

	/* Save created certificates to files */
	for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
		if (certs[i].x && certs[i].fn) {
			file = fopen(certs[i].fn, "w");
			if (file != NULL) {
				i2d_X509_fp(file, certs[i].x);
				fclose(file);
			} else {
				ERROR("Cannot create file %s\n", certs[i].fn);
			}
		}
	}

	/* Save keys */
	if (save_keys) {
		for (i = 0 ; i < NUM_KEYS ; i++) {
			if (!key_store(&keys[i])) {
				ERROR("Cannot save %s\n", keys[i].desc);
			}
		}
	}

	X509_EXTENSION_free(hash_ext);
	X509_EXTENSION_free(nvctr_ext);
	X509_EXTENSION_free(trusted_key_ext);
	X509_EXTENSION_free(non_trusted_key_ext);

#ifndef OPENSSL_NO_ENGINE
	ENGINE_cleanup();
#endif
	CRYPTO_cleanup_all_ex_data();

	return 0;
}
