xref: /rk3399_ARM-atf/tools/cert_create/src/main.c (revision 55e291a4058633300deafabe62db7e2885f0afb5)
16f971622SJuan Castillo /*
26f971622SJuan Castillo  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
36f971622SJuan Castillo  *
46f971622SJuan Castillo  * Redistribution and use in source and binary forms, with or without
56f971622SJuan Castillo  * modification, are permitted provided that the following conditions are met:
66f971622SJuan Castillo  *
76f971622SJuan Castillo  * Redistributions of source code must retain the above copyright notice, this
86f971622SJuan Castillo  * list of conditions and the following disclaimer.
96f971622SJuan Castillo  *
106f971622SJuan Castillo  * Redistributions in binary form must reproduce the above copyright notice,
116f971622SJuan Castillo  * this list of conditions and the following disclaimer in the documentation
126f971622SJuan Castillo  * and/or other materials provided with the distribution.
136f971622SJuan Castillo  *
146f971622SJuan Castillo  * Neither the name of ARM nor the names of its contributors may be used
156f971622SJuan Castillo  * to endorse or promote products derived from this software without specific
166f971622SJuan Castillo  * prior written permission.
176f971622SJuan Castillo  *
186f971622SJuan Castillo  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
196f971622SJuan Castillo  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
206f971622SJuan Castillo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
216f971622SJuan Castillo  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
226f971622SJuan Castillo  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
236f971622SJuan Castillo  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
246f971622SJuan Castillo  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
256f971622SJuan Castillo  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
266f971622SJuan Castillo  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
276f971622SJuan Castillo  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
286f971622SJuan Castillo  * POSSIBILITY OF SUCH DAMAGE.
296f971622SJuan Castillo  */
306f971622SJuan Castillo 
316f971622SJuan Castillo #include <getopt.h>
326f971622SJuan Castillo #include <stdio.h>
336f971622SJuan Castillo #include <stdlib.h>
346f971622SJuan Castillo #include <string.h>
356f971622SJuan Castillo 
366f971622SJuan Castillo #include <openssl/conf.h>
376f971622SJuan Castillo #include <openssl/engine.h>
386f971622SJuan Castillo #include <openssl/err.h>
396f971622SJuan Castillo #include <openssl/pem.h>
406f971622SJuan Castillo #include <openssl/sha.h>
416f971622SJuan Castillo #include <openssl/x509v3.h>
426f971622SJuan Castillo 
436f971622SJuan Castillo #include "cert.h"
446f971622SJuan Castillo #include "debug.h"
456f971622SJuan Castillo #include "ext.h"
466f971622SJuan Castillo #include "key.h"
476f971622SJuan Castillo #include "platform_oid.h"
486f971622SJuan Castillo #include "sha.h"
49*55e291a4SJuan Castillo #include "tbbr/tbb_ext.h"
50*55e291a4SJuan Castillo #include "tbbr/tbb_cert.h"
51*55e291a4SJuan Castillo #include "tbbr/tbb_key.h"
526f971622SJuan Castillo 
536f971622SJuan Castillo /*
546f971622SJuan Castillo  * Helper macros to simplify the code. This macro assigns the return value of
556f971622SJuan Castillo  * the 'fn' function to 'v' and exits if the value is NULL.
566f971622SJuan Castillo  */
576f971622SJuan Castillo #define CHECK_NULL(v, fn) \
586f971622SJuan Castillo 	do { \
596f971622SJuan Castillo 		v = fn; \
606f971622SJuan Castillo 		if (v == NULL) { \
616f971622SJuan Castillo 			ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
626f971622SJuan Castillo 			exit(1); \
636f971622SJuan Castillo 		} \
646f971622SJuan Castillo 	} while (0)
656f971622SJuan Castillo 
666f971622SJuan Castillo /*
676f971622SJuan Castillo  * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
686f971622SJuan Castillo  * NID is undefined.
696f971622SJuan Castillo  */
706f971622SJuan Castillo #define CHECK_OID(v, oid) \
716f971622SJuan Castillo 	do { \
726f971622SJuan Castillo 		v = OBJ_txt2nid(oid); \
736f971622SJuan Castillo 		if (v == NID_undef) { \
746f971622SJuan Castillo 			ERROR("Cannot find TBB extension %s\n", oid); \
756f971622SJuan Castillo 			exit(1); \
766f971622SJuan Castillo 		} \
776f971622SJuan Castillo 	} while (0)
786f971622SJuan Castillo 
796f971622SJuan Castillo #define MAX_FILENAME_LEN		1024
806f971622SJuan Castillo #define VAL_DAYS			7300
816f971622SJuan Castillo #define ID_TO_BIT_MASK(id)		(1 << id)
82ccbf890eSJuan Castillo #define NUM_ELEM(x)			((sizeof(x)) / (sizeof(x[0])))
836f971622SJuan Castillo 
846f971622SJuan Castillo /* Files */
856f971622SJuan Castillo enum {
866f971622SJuan Castillo 	/* Image file names (inputs) */
876f971622SJuan Castillo 	BL2_ID = 0,
886f971622SJuan Castillo 	BL30_ID,
896f971622SJuan Castillo 	BL31_ID,
906f971622SJuan Castillo 	BL32_ID,
916f971622SJuan Castillo 	BL33_ID,
926f971622SJuan Castillo 	/* Certificate file names (outputs) */
936f971622SJuan Castillo 	BL2_CERT_ID,
946f971622SJuan Castillo 	TRUSTED_KEY_CERT_ID,
956f971622SJuan Castillo 	BL30_KEY_CERT_ID,
966f971622SJuan Castillo 	BL30_CERT_ID,
976f971622SJuan Castillo 	BL31_KEY_CERT_ID,
986f971622SJuan Castillo 	BL31_CERT_ID,
996f971622SJuan Castillo 	BL32_KEY_CERT_ID,
1006f971622SJuan Castillo 	BL32_CERT_ID,
1016f971622SJuan Castillo 	BL33_KEY_CERT_ID,
1026f971622SJuan Castillo 	BL33_CERT_ID,
1036f971622SJuan Castillo 	/* Key file names (input/output) */
1046f971622SJuan Castillo 	ROT_KEY_ID,
1056f971622SJuan Castillo 	TRUSTED_WORLD_KEY_ID,
1066f971622SJuan Castillo 	NON_TRUSTED_WORLD_KEY_ID,
1076f971622SJuan Castillo 	BL30_KEY_ID,
1086f971622SJuan Castillo 	BL31_KEY_ID,
1096f971622SJuan Castillo 	BL32_KEY_ID,
1106f971622SJuan Castillo 	BL33_KEY_ID,
1116f971622SJuan Castillo 	NUM_OPTS
1126f971622SJuan Castillo };
1136f971622SJuan Castillo 
1146f971622SJuan Castillo /* Global options */
115ccbf890eSJuan Castillo static int key_alg;
1166f971622SJuan Castillo static int new_keys;
1176f971622SJuan Castillo static int save_keys;
1186f971622SJuan Castillo static int print_cert;
1196f971622SJuan Castillo static int bl30_present;
1206f971622SJuan Castillo static int bl32_present;
1216f971622SJuan Castillo 
1226f971622SJuan Castillo /* Info messages created in the Makefile */
1236f971622SJuan Castillo extern const char build_msg[];
1246f971622SJuan Castillo extern const char platform_msg[];
1256f971622SJuan Castillo 
1266f971622SJuan Castillo 
1276f971622SJuan Castillo static char *strdup(const char *str)
1286f971622SJuan Castillo {
1296f971622SJuan Castillo 	int n = strlen(str) + 1;
1306f971622SJuan Castillo 	char *dup = malloc(n);
1316f971622SJuan Castillo 	if (dup) {
1326f971622SJuan Castillo 		strcpy(dup, str);
1336f971622SJuan Castillo 	}
1346f971622SJuan Castillo 	return dup;
1356f971622SJuan Castillo }
1366f971622SJuan Castillo 
137ccbf890eSJuan Castillo static const char *key_algs_str[] = {
138ccbf890eSJuan Castillo 	[KEY_ALG_RSA] = "rsa",
139ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC
140ccbf890eSJuan Castillo 	[KEY_ALG_ECDSA] = "ecdsa"
141ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */
142ccbf890eSJuan Castillo };
143ccbf890eSJuan Castillo 
1446f971622SJuan Castillo /* Command line options */
1456f971622SJuan Castillo static const struct option long_opt[] = {
1466f971622SJuan Castillo 	/* Binary images */
1476f971622SJuan Castillo 	{"bl2", required_argument, 0, BL2_ID},
1486f971622SJuan Castillo 	{"bl30", required_argument, 0, BL30_ID},
1496f971622SJuan Castillo 	{"bl31", required_argument, 0, BL31_ID},
1506f971622SJuan Castillo 	{"bl32", required_argument, 0, BL32_ID},
1516f971622SJuan Castillo 	{"bl33", required_argument, 0, BL33_ID},
1526f971622SJuan Castillo 	/* Certificate files */
1536f971622SJuan Castillo 	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
1546f971622SJuan Castillo 	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
1556f971622SJuan Castillo 	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
1566f971622SJuan Castillo 	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
1576f971622SJuan Castillo 	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
1586f971622SJuan Castillo 	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
1596f971622SJuan Castillo 	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
1606f971622SJuan Castillo 	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
1616f971622SJuan Castillo 	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
1626f971622SJuan Castillo 	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
1636f971622SJuan Castillo 	/* Private key files */
1646f971622SJuan Castillo 	{"rot-key", required_argument, 0, ROT_KEY_ID},
1656f971622SJuan Castillo 	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
1666f971622SJuan Castillo 	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
1676f971622SJuan Castillo 	{"bl30-key", required_argument, 0, BL30_KEY_ID},
1686f971622SJuan Castillo 	{"bl31-key", required_argument, 0, BL31_KEY_ID},
1696f971622SJuan Castillo 	{"bl32-key", required_argument, 0, BL32_KEY_ID},
1706f971622SJuan Castillo 	{"bl33-key", required_argument, 0, BL33_KEY_ID},
1716f971622SJuan Castillo 	/* Common options */
172ccbf890eSJuan Castillo 	{"key-alg", required_argument, 0, 'a'},
1736f971622SJuan Castillo 	{"help", no_argument, 0, 'h'},
1746f971622SJuan Castillo 	{"save-keys", no_argument, 0, 'k'},
1756f971622SJuan Castillo 	{"new-chain", no_argument, 0, 'n'},
1766f971622SJuan Castillo 	{"print-cert", no_argument, 0, 'p'},
1776f971622SJuan Castillo 	{0, 0, 0, 0}
1786f971622SJuan Castillo };
1796f971622SJuan Castillo 
1806f971622SJuan Castillo static void print_help(const char *cmd)
1816f971622SJuan Castillo {
1826f971622SJuan Castillo 	int i = 0;
1836f971622SJuan Castillo 	printf("\n\n");
1846f971622SJuan Castillo 	printf("The certificate generation tool loads the binary images and\n"
1856f971622SJuan Castillo 	       "optionally the RSA keys, and outputs the key and content\n"
1866f971622SJuan Castillo 	       "certificates properly signed to implement the chain of trust.\n"
1876f971622SJuan Castillo 	       "If keys are provided, they must be in PEM format.\n"
1886f971622SJuan Castillo 	       "Certificates are generated in DER format.\n");
1896f971622SJuan Castillo 	printf("\n");
1906f971622SJuan Castillo 	printf("Usage:\n\n");
1916f971622SJuan Castillo 	printf("    %s [-hknp] \\\n", cmd);
1926f971622SJuan Castillo 	for (i = 0; i < NUM_OPTS; i++) {
1936f971622SJuan Castillo 		printf("        --%s <file>  \\\n", long_opt[i].name);
1946f971622SJuan Castillo 	}
1956f971622SJuan Castillo 	printf("\n");
196ccbf890eSJuan Castillo 	printf("-a    Key algorithm: rsa (default), ecdsa\n");
1976f971622SJuan Castillo 	printf("-h    Print help and exit\n");
1986f971622SJuan Castillo 	printf("-k    Save key pairs into files. Filenames must be provided\n");
1996f971622SJuan Castillo 	printf("-n    Generate new key pairs if no key files are provided\n");
2006f971622SJuan Castillo 	printf("-p    Print the certificates in the standard output\n");
2016f971622SJuan Castillo 	printf("\n");
2026f971622SJuan Castillo 
2036f971622SJuan Castillo 	exit(0);
2046f971622SJuan Castillo }
2056f971622SJuan Castillo 
206ccbf890eSJuan Castillo static int get_key_alg(const char *key_alg_str)
207ccbf890eSJuan Castillo {
208ccbf890eSJuan Castillo 	int i;
209ccbf890eSJuan Castillo 
210ccbf890eSJuan Castillo 	for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
211ccbf890eSJuan Castillo 		if (0 == strcmp(key_alg_str, key_algs_str[i])) {
212ccbf890eSJuan Castillo 			return i;
213ccbf890eSJuan Castillo 		}
214ccbf890eSJuan Castillo 	}
215ccbf890eSJuan Castillo 
216ccbf890eSJuan Castillo 	return -1;
217ccbf890eSJuan Castillo }
218ccbf890eSJuan Castillo 
2196f971622SJuan Castillo static void check_cmd_params(void)
2206f971622SJuan Castillo {
221ccbf890eSJuan Castillo 	/* Only save new keys */
222ccbf890eSJuan Castillo 	if (save_keys && !new_keys) {
223ccbf890eSJuan Castillo 		ERROR("Only new keys can be saved to disk\n");
224ccbf890eSJuan Castillo 		exit(1);
225ccbf890eSJuan Castillo 	}
226ccbf890eSJuan Castillo 
2276f971622SJuan Castillo 	/* BL2, BL31 and BL33 are mandatory */
228*55e291a4SJuan Castillo 	if (extensions[BL2_HASH_EXT].data.fn == NULL) {
2296f971622SJuan Castillo 		ERROR("BL2 image not specified\n");
2306f971622SJuan Castillo 		exit(1);
2316f971622SJuan Castillo 	}
2326f971622SJuan Castillo 
233*55e291a4SJuan Castillo 	if (extensions[BL31_HASH_EXT].data.fn == NULL) {
2346f971622SJuan Castillo 		ERROR("BL31 image not specified\n");
2356f971622SJuan Castillo 		exit(1);
2366f971622SJuan Castillo 	}
2376f971622SJuan Castillo 
238*55e291a4SJuan Castillo 	if (extensions[BL33_HASH_EXT].data.fn == NULL) {
2396f971622SJuan Castillo 		ERROR("BL33 image not specified\n");
2406f971622SJuan Castillo 		exit(1);
2416f971622SJuan Castillo 	}
2426f971622SJuan Castillo 
2436f971622SJuan Castillo 	/* BL30 and BL32 are optional */
244*55e291a4SJuan Castillo 	if (extensions[BL30_HASH_EXT].data.fn != NULL) {
2456f971622SJuan Castillo 		bl30_present = 1;
2466f971622SJuan Castillo 	}
2476f971622SJuan Castillo 
248*55e291a4SJuan Castillo 	if (extensions[BL32_HASH_EXT].data.fn != NULL) {
2496f971622SJuan Castillo 		bl32_present = 1;
2506f971622SJuan Castillo 	}
2516f971622SJuan Castillo 
2526f971622SJuan Castillo 	/* TODO: Certificate filenames */
2536f971622SJuan Castillo 
2546f971622SJuan Castillo 	/* Filenames to store keys must be specified */
2556f971622SJuan Castillo 	if (save_keys || !new_keys) {
2566f971622SJuan Castillo 		if (keys[ROT_KEY].fn == NULL) {
2576f971622SJuan Castillo 			ERROR("ROT key not specified\n");
2586f971622SJuan Castillo 			exit(1);
2596f971622SJuan Castillo 		}
2606f971622SJuan Castillo 
2616f971622SJuan Castillo 		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
2626f971622SJuan Castillo 			ERROR("Trusted World key not specified\n");
2636f971622SJuan Castillo 			exit(1);
2646f971622SJuan Castillo 		}
2656f971622SJuan Castillo 
2666f971622SJuan Castillo 		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
2676f971622SJuan Castillo 			ERROR("Non-trusted World key not specified\n");
2686f971622SJuan Castillo 			exit(1);
2696f971622SJuan Castillo 		}
2706f971622SJuan Castillo 
2716f971622SJuan Castillo 		if (keys[BL31_KEY].fn == NULL) {
2726f971622SJuan Castillo 			ERROR("BL31 key not specified\n");
2736f971622SJuan Castillo 			exit(1);
2746f971622SJuan Castillo 		}
2756f971622SJuan Castillo 
2766f971622SJuan Castillo 		if (keys[BL33_KEY].fn == NULL) {
2776f971622SJuan Castillo 			ERROR("BL33 key not specified\n");
2786f971622SJuan Castillo 			exit(1);
2796f971622SJuan Castillo 		}
2806f971622SJuan Castillo 
2816f971622SJuan Castillo 		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
2826f971622SJuan Castillo 			ERROR("BL30 key not specified\n");
2836f971622SJuan Castillo 			exit(1);
2846f971622SJuan Castillo 		}
2856f971622SJuan Castillo 
2866f971622SJuan Castillo 		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
2876f971622SJuan Castillo 			ERROR("BL32 key not specified\n");
2886f971622SJuan Castillo 			exit(1);
2896f971622SJuan Castillo 		}
2906f971622SJuan Castillo 	}
2916f971622SJuan Castillo }
2926f971622SJuan Castillo 
2936f971622SJuan Castillo int main(int argc, char *argv[])
2946f971622SJuan Castillo {
2956f971622SJuan Castillo 	STACK_OF(X509_EXTENSION) * sk = NULL;
296*55e291a4SJuan Castillo 	X509_EXTENSION *cert_ext = NULL;
297*55e291a4SJuan Castillo 	ext_t *ext = NULL;
298*55e291a4SJuan Castillo 	cert_t *cert;
2996f971622SJuan Castillo 	FILE *file = NULL;
300*55e291a4SJuan Castillo 	int i, j, ext_nid;
3016f971622SJuan Castillo 	int c, opt_idx = 0;
302ccbf890eSJuan Castillo 	unsigned int err_code;
3036f971622SJuan Castillo 	unsigned char md[SHA256_DIGEST_LENGTH];
304c3da66b1SJuan Castillo 	const EVP_MD *md_info;
3056f971622SJuan Castillo 
3066f971622SJuan Castillo 	NOTICE("CoT Generation Tool: %s\n", build_msg);
3076f971622SJuan Castillo 	NOTICE("Target platform: %s\n", platform_msg);
3086f971622SJuan Castillo 
309ccbf890eSJuan Castillo 	/* Set default options */
310ccbf890eSJuan Castillo 	key_alg = KEY_ALG_RSA;
311ccbf890eSJuan Castillo 
3126f971622SJuan Castillo 	while (1) {
3136f971622SJuan Castillo 		/* getopt_long stores the option index here. */
314ccbf890eSJuan Castillo 		c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
3156f971622SJuan Castillo 
3166f971622SJuan Castillo 		/* Detect the end of the options. */
3176f971622SJuan Castillo 		if (c == -1) {
3186f971622SJuan Castillo 			break;
3196f971622SJuan Castillo 		}
3206f971622SJuan Castillo 
3216f971622SJuan Castillo 		switch (c) {
322ccbf890eSJuan Castillo 		case 'a':
323ccbf890eSJuan Castillo 			key_alg = get_key_alg(optarg);
324ccbf890eSJuan Castillo 			if (key_alg < 0) {
325ccbf890eSJuan Castillo 				ERROR("Invalid key algorithm '%s'\n", optarg);
326ccbf890eSJuan Castillo 				exit(1);
327ccbf890eSJuan Castillo 			}
328ccbf890eSJuan Castillo 			break;
3296f971622SJuan Castillo 		case 'h':
3306f971622SJuan Castillo 			print_help(argv[0]);
3316f971622SJuan Castillo 			break;
3326f971622SJuan Castillo 		case 'k':
3336f971622SJuan Castillo 			save_keys = 1;
3346f971622SJuan Castillo 			break;
3356f971622SJuan Castillo 		case 'n':
3366f971622SJuan Castillo 			new_keys = 1;
3376f971622SJuan Castillo 			break;
3386f971622SJuan Castillo 		case 'p':
3396f971622SJuan Castillo 			print_cert = 1;
3406f971622SJuan Castillo 			break;
3416f971622SJuan Castillo 		case BL2_ID:
342*55e291a4SJuan Castillo 			extensions[BL2_HASH_EXT].data.fn = strdup(optarg);
3436f971622SJuan Castillo 			break;
3446f971622SJuan Castillo 		case BL30_ID:
345*55e291a4SJuan Castillo 			extensions[BL30_HASH_EXT].data.fn = strdup(optarg);
3466f971622SJuan Castillo 			break;
3476f971622SJuan Castillo 		case BL31_ID:
348*55e291a4SJuan Castillo 			extensions[BL31_HASH_EXT].data.fn = strdup(optarg);
3496f971622SJuan Castillo 			break;
3506f971622SJuan Castillo 		case BL32_ID:
351*55e291a4SJuan Castillo 			extensions[BL32_HASH_EXT].data.fn = strdup(optarg);
3526f971622SJuan Castillo 			break;
3536f971622SJuan Castillo 		case BL33_ID:
354*55e291a4SJuan Castillo 			extensions[BL33_HASH_EXT].data.fn = strdup(optarg);
3556f971622SJuan Castillo 			break;
3566f971622SJuan Castillo 		case BL2_CERT_ID:
3576f971622SJuan Castillo 			certs[BL2_CERT].fn = strdup(optarg);
3586f971622SJuan Castillo 			break;
3596f971622SJuan Castillo 		case TRUSTED_KEY_CERT_ID:
3606f971622SJuan Castillo 			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
3616f971622SJuan Castillo 			break;
3626f971622SJuan Castillo 		case BL30_KEY_CERT_ID:
3636f971622SJuan Castillo 			certs[BL30_KEY_CERT].fn = strdup(optarg);
3646f971622SJuan Castillo 			break;
3656f971622SJuan Castillo 		case BL30_CERT_ID:
3666f971622SJuan Castillo 			certs[BL30_CERT].fn = strdup(optarg);
3676f971622SJuan Castillo 			break;
3686f971622SJuan Castillo 		case BL31_KEY_CERT_ID:
3696f971622SJuan Castillo 			certs[BL31_KEY_CERT].fn = strdup(optarg);
3706f971622SJuan Castillo 			break;
3716f971622SJuan Castillo 		case BL31_CERT_ID:
3726f971622SJuan Castillo 			certs[BL31_CERT].fn = strdup(optarg);
3736f971622SJuan Castillo 			break;
3746f971622SJuan Castillo 		case BL32_KEY_CERT_ID:
3756f971622SJuan Castillo 			certs[BL32_KEY_CERT].fn = strdup(optarg);
3766f971622SJuan Castillo 			break;
3776f971622SJuan Castillo 		case BL32_CERT_ID:
3786f971622SJuan Castillo 			certs[BL32_CERT].fn = strdup(optarg);
3796f971622SJuan Castillo 			break;
3806f971622SJuan Castillo 		case BL33_KEY_CERT_ID:
3816f971622SJuan Castillo 			certs[BL33_KEY_CERT].fn = strdup(optarg);
3826f971622SJuan Castillo 			break;
3836f971622SJuan Castillo 		case BL33_CERT_ID:
3846f971622SJuan Castillo 			certs[BL33_CERT].fn = strdup(optarg);
3856f971622SJuan Castillo 			break;
3866f971622SJuan Castillo 		case ROT_KEY_ID:
3876f971622SJuan Castillo 			keys[ROT_KEY].fn = strdup(optarg);
3886f971622SJuan Castillo 			break;
3896f971622SJuan Castillo 		case TRUSTED_WORLD_KEY_ID:
3906f971622SJuan Castillo 			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
3916f971622SJuan Castillo 			break;
3926f971622SJuan Castillo 		case NON_TRUSTED_WORLD_KEY_ID:
3936f971622SJuan Castillo 			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
3946f971622SJuan Castillo 			break;
3956f971622SJuan Castillo 		case BL30_KEY_ID:
3966f971622SJuan Castillo 			keys[BL30_KEY].fn = strdup(optarg);
3976f971622SJuan Castillo 			break;
3986f971622SJuan Castillo 		case BL31_KEY_ID:
3996f971622SJuan Castillo 			keys[BL31_KEY].fn = strdup(optarg);
4006f971622SJuan Castillo 			break;
4016f971622SJuan Castillo 		case BL32_KEY_ID:
4026f971622SJuan Castillo 			keys[BL32_KEY].fn = strdup(optarg);
4036f971622SJuan Castillo 			break;
4046f971622SJuan Castillo 		case BL33_KEY_ID:
4056f971622SJuan Castillo 			keys[BL33_KEY].fn = strdup(optarg);
4066f971622SJuan Castillo 			break;
4076f971622SJuan Castillo 		case '?':
4086f971622SJuan Castillo 		default:
4096f971622SJuan Castillo 			printf("%s\n", optarg);
4106f971622SJuan Castillo 			exit(1);
4116f971622SJuan Castillo 		}
4126f971622SJuan Castillo 	}
4136f971622SJuan Castillo 
4146f971622SJuan Castillo 	/* Check command line arguments */
4156f971622SJuan Castillo 	check_cmd_params();
4166f971622SJuan Castillo 
4176f971622SJuan Castillo 	/* Register the new types and OIDs for the extensions */
418*55e291a4SJuan Castillo 	if (ext_register(extensions) != 0) {
419*55e291a4SJuan Castillo 		ERROR("Cannot register TBB extensions\n");
4206f971622SJuan Castillo 		exit(1);
4216f971622SJuan Castillo 	}
4226f971622SJuan Castillo 
423c3da66b1SJuan Castillo 	/* Indicate SHA256 as image hash algorithm in the certificate
424c3da66b1SJuan Castillo 	 * extension */
425c3da66b1SJuan Castillo 	md_info = EVP_sha256();
426c3da66b1SJuan Castillo 
4276f971622SJuan Castillo 	/* Load private keys from files (or generate new ones) */
428*55e291a4SJuan Castillo 	for (i = 0 ; i < num_keys ; i++) {
429ccbf890eSJuan Castillo 		/* First try to load the key from disk */
430ccbf890eSJuan Castillo 		if (key_load(&keys[i], &err_code)) {
431ccbf890eSJuan Castillo 			/* Key loaded successfully */
432ccbf890eSJuan Castillo 			continue;
433ccbf890eSJuan Castillo 		}
434ccbf890eSJuan Castillo 
435ccbf890eSJuan Castillo 		/* Key not loaded. Check the error code */
436ccbf890eSJuan Castillo 		if (err_code == KEY_ERR_MALLOC) {
437ccbf890eSJuan Castillo 			/* Cannot allocate memory. Abort. */
438ccbf890eSJuan Castillo 			ERROR("Malloc error while loading '%s'\n", keys[i].fn);
439ccbf890eSJuan Castillo 			exit(1);
440ccbf890eSJuan Castillo 		} else if (err_code == KEY_ERR_LOAD) {
441ccbf890eSJuan Castillo 			/* File exists, but it does not contain a valid private
442ccbf890eSJuan Castillo 			 * key. Abort. */
443ccbf890eSJuan Castillo 			ERROR("Error loading '%s'\n", keys[i].fn);
4446f971622SJuan Castillo 			exit(1);
4456f971622SJuan Castillo 		}
446ccbf890eSJuan Castillo 
447ccbf890eSJuan Castillo 		/* File does not exist, could not be opened or no filename was
448ccbf890eSJuan Castillo 		 * given */
449ccbf890eSJuan Castillo 		if (new_keys) {
450ccbf890eSJuan Castillo 			/* Try to create a new key */
451ccbf890eSJuan Castillo 			NOTICE("Creating new key for '%s'\n", keys[i].desc);
452ccbf890eSJuan Castillo 			if (!key_create(&keys[i], key_alg)) {
453ccbf890eSJuan Castillo 				ERROR("Error creating key '%s'\n", keys[i].desc);
454ccbf890eSJuan Castillo 				exit(1);
4556f971622SJuan Castillo 			}
4566f971622SJuan Castillo 		} else {
457ccbf890eSJuan Castillo 			if (err_code == KEY_ERR_OPEN) {
458ccbf890eSJuan Castillo 				ERROR("Error opening '%s'\n", keys[i].fn);
459ccbf890eSJuan Castillo 			} else {
460ccbf890eSJuan Castillo 				ERROR("Key '%s' not specified\n", keys[i].desc);
4616f971622SJuan Castillo 			}
462ccbf890eSJuan Castillo 			exit(1);
4636f971622SJuan Castillo 		}
4646f971622SJuan Castillo 	}
4656f971622SJuan Castillo 
466*55e291a4SJuan Castillo 	/* Create the certificates */
467*55e291a4SJuan Castillo 	for (i = 0 ; i < num_certs ; i++) {
468*55e291a4SJuan Castillo 
469*55e291a4SJuan Castillo 		cert = &certs[i];
470*55e291a4SJuan Castillo 
471*55e291a4SJuan Castillo 		/* Create a new stack of extensions. This stack will be used
472*55e291a4SJuan Castillo 		 * to create the certificate */
4736f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
4746f971622SJuan Castillo 
475*55e291a4SJuan Castillo 		for (j = 0 ; j < cert->num_ext ; j++) {
4766f971622SJuan Castillo 
477*55e291a4SJuan Castillo 			ext = &extensions[cert->ext[j]];
478*55e291a4SJuan Castillo 
479*55e291a4SJuan Castillo 			/* Get OpenSSL internal ID for this extension */
480*55e291a4SJuan Castillo 			CHECK_OID(ext_nid, ext->oid);
481*55e291a4SJuan Castillo 
482*55e291a4SJuan Castillo 			/*
483*55e291a4SJuan Castillo 			 * Three types of extensions are currently supported:
484*55e291a4SJuan Castillo 			 *     - EXT_TYPE_NVCOUNTER
485*55e291a4SJuan Castillo 			 *     - EXT_TYPE_HASH
486*55e291a4SJuan Castillo 			 *     - EXT_TYPE_PKEY
487*55e291a4SJuan Castillo 			 */
488*55e291a4SJuan Castillo 			switch (ext->type) {
489*55e291a4SJuan Castillo 			case EXT_TYPE_NVCOUNTER:
490*55e291a4SJuan Castillo 				CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid,
491*55e291a4SJuan Castillo 						EXT_CRIT, ext->data.nvcounter));
492*55e291a4SJuan Castillo 				break;
493*55e291a4SJuan Castillo 			case EXT_TYPE_HASH:
494*55e291a4SJuan Castillo 				if (ext->data.fn == NULL) {
495*55e291a4SJuan Castillo 					break;
496*55e291a4SJuan Castillo 				}
497*55e291a4SJuan Castillo 				if (!sha_file(ext->data.fn, md)) {
498*55e291a4SJuan Castillo 					ERROR("Cannot calculate hash of %s\n",
499*55e291a4SJuan Castillo 						ext->data.fn);
5006f971622SJuan Castillo 					exit(1);
5016f971622SJuan Castillo 				}
502*55e291a4SJuan Castillo 				CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
503*55e291a4SJuan Castillo 						EXT_CRIT, md_info, md,
5046f971622SJuan Castillo 						SHA256_DIGEST_LENGTH));
505*55e291a4SJuan Castillo 				break;
506*55e291a4SJuan Castillo 			case EXT_TYPE_PKEY:
507*55e291a4SJuan Castillo 				CHECK_NULL(cert_ext, ext_new_key(ext_nid,
508*55e291a4SJuan Castillo 					EXT_CRIT, keys[ext->data.key].key));
509*55e291a4SJuan Castillo 				break;
510*55e291a4SJuan Castillo 			default:
511*55e291a4SJuan Castillo 				ERROR("Unknown extension type in %s\n",
512*55e291a4SJuan Castillo 						cert->cn);
513*55e291a4SJuan Castillo 				exit(1);
514*55e291a4SJuan Castillo 			}
515*55e291a4SJuan Castillo 
516*55e291a4SJuan Castillo 			/* Push the extension into the stack */
517*55e291a4SJuan Castillo 			sk_X509_EXTENSION_push(sk, cert_ext);
518*55e291a4SJuan Castillo 		}
5196f971622SJuan Castillo 
5206f971622SJuan Castillo 		/* Create certificate. Signed with ROT key */
521*55e291a4SJuan Castillo 		if (!cert_new(cert, VAL_DAYS, 0, sk)) {
522*55e291a4SJuan Castillo 			ERROR("Cannot create %s\n", cert->cn);
5236f971622SJuan Castillo 			exit(1);
5246f971622SJuan Castillo 		}
5256f971622SJuan Castillo 
5266f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
5276f971622SJuan Castillo 	}
5286f971622SJuan Castillo 
5296f971622SJuan Castillo 
5306f971622SJuan Castillo 	/* Print the certificates */
5316f971622SJuan Castillo 	if (print_cert) {
532*55e291a4SJuan Castillo 		for (i = 0 ; i < num_certs ; i++) {
5336f971622SJuan Castillo 			if (!certs[i].x) {
5346f971622SJuan Castillo 				continue;
5356f971622SJuan Castillo 			}
5366f971622SJuan Castillo 			printf("\n\n=====================================\n\n");
5376f971622SJuan Castillo 			X509_print_fp(stdout, certs[i].x);
5386f971622SJuan Castillo 		}
5396f971622SJuan Castillo 	}
5406f971622SJuan Castillo 
5416f971622SJuan Castillo 	/* Save created certificates to files */
542*55e291a4SJuan Castillo 	for (i = 0 ; i < num_certs ; i++) {
5436f971622SJuan Castillo 		if (certs[i].x && certs[i].fn) {
5446f971622SJuan Castillo 			file = fopen(certs[i].fn, "w");
5456f971622SJuan Castillo 			if (file != NULL) {
5466f971622SJuan Castillo 				i2d_X509_fp(file, certs[i].x);
5476f971622SJuan Castillo 				fclose(file);
5486f971622SJuan Castillo 			} else {
5496f971622SJuan Castillo 				ERROR("Cannot create file %s\n", certs[i].fn);
5506f971622SJuan Castillo 			}
5516f971622SJuan Castillo 		}
5526f971622SJuan Castillo 	}
5536f971622SJuan Castillo 
5546f971622SJuan Castillo 	/* Save keys */
5556f971622SJuan Castillo 	if (save_keys) {
556*55e291a4SJuan Castillo 		for (i = 0 ; i < num_keys ; i++) {
5576f971622SJuan Castillo 			if (!key_store(&keys[i])) {
5586f971622SJuan Castillo 				ERROR("Cannot save %s\n", keys[i].desc);
5596f971622SJuan Castillo 			}
5606f971622SJuan Castillo 		}
5616f971622SJuan Castillo 	}
5626f971622SJuan Castillo 
5636f971622SJuan Castillo #ifndef OPENSSL_NO_ENGINE
5646f971622SJuan Castillo 	ENGINE_cleanup();
5656f971622SJuan Castillo #endif
5666f971622SJuan Castillo 	CRYPTO_cleanup_all_ex_data();
5676f971622SJuan Castillo 
5686f971622SJuan Castillo 	return 0;
5696f971622SJuan Castillo }
570