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" 44*ad2c1a9aSJuan Castillo #include "cmd_opt.h" 456f971622SJuan Castillo #include "debug.h" 466f971622SJuan Castillo #include "ext.h" 476f971622SJuan Castillo #include "key.h" 486f971622SJuan Castillo #include "platform_oid.h" 496f971622SJuan Castillo #include "sha.h" 5055e291a4SJuan Castillo #include "tbbr/tbb_ext.h" 5155e291a4SJuan Castillo #include "tbbr/tbb_cert.h" 5255e291a4SJuan Castillo #include "tbbr/tbb_key.h" 536f971622SJuan Castillo 546f971622SJuan Castillo /* 556f971622SJuan Castillo * Helper macros to simplify the code. This macro assigns the return value of 566f971622SJuan Castillo * the 'fn' function to 'v' and exits if the value is NULL. 576f971622SJuan Castillo */ 586f971622SJuan Castillo #define CHECK_NULL(v, fn) \ 596f971622SJuan Castillo do { \ 606f971622SJuan Castillo v = fn; \ 616f971622SJuan Castillo if (v == NULL) { \ 626f971622SJuan Castillo ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \ 636f971622SJuan Castillo exit(1); \ 646f971622SJuan Castillo } \ 656f971622SJuan Castillo } while (0) 666f971622SJuan Castillo 676f971622SJuan Castillo /* 686f971622SJuan Castillo * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the 696f971622SJuan Castillo * NID is undefined. 706f971622SJuan Castillo */ 716f971622SJuan Castillo #define CHECK_OID(v, oid) \ 726f971622SJuan Castillo do { \ 736f971622SJuan Castillo v = OBJ_txt2nid(oid); \ 746f971622SJuan Castillo if (v == NID_undef) { \ 756f971622SJuan Castillo ERROR("Cannot find TBB extension %s\n", oid); \ 766f971622SJuan Castillo exit(1); \ 776f971622SJuan Castillo } \ 786f971622SJuan Castillo } while (0) 796f971622SJuan Castillo 806f971622SJuan Castillo #define MAX_FILENAME_LEN 1024 816f971622SJuan Castillo #define VAL_DAYS 7300 826f971622SJuan Castillo #define ID_TO_BIT_MASK(id) (1 << id) 83ccbf890eSJuan Castillo #define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0]))) 846f971622SJuan Castillo 856f971622SJuan Castillo /* Files */ 866f971622SJuan Castillo enum { 876f971622SJuan Castillo /* Image file names (inputs) */ 886f971622SJuan Castillo BL2_ID = 0, 896f971622SJuan Castillo BL30_ID, 906f971622SJuan Castillo BL31_ID, 916f971622SJuan Castillo BL32_ID, 926f971622SJuan Castillo BL33_ID, 936f971622SJuan Castillo /* Certificate file names (outputs) */ 946f971622SJuan Castillo BL2_CERT_ID, 956f971622SJuan Castillo TRUSTED_KEY_CERT_ID, 966f971622SJuan Castillo BL30_KEY_CERT_ID, 976f971622SJuan Castillo BL30_CERT_ID, 986f971622SJuan Castillo BL31_KEY_CERT_ID, 996f971622SJuan Castillo BL31_CERT_ID, 1006f971622SJuan Castillo BL32_KEY_CERT_ID, 1016f971622SJuan Castillo BL32_CERT_ID, 1026f971622SJuan Castillo BL33_KEY_CERT_ID, 1036f971622SJuan Castillo BL33_CERT_ID, 1046f971622SJuan Castillo /* Key file names (input/output) */ 1056f971622SJuan Castillo ROT_KEY_ID, 1066f971622SJuan Castillo TRUSTED_WORLD_KEY_ID, 1076f971622SJuan Castillo NON_TRUSTED_WORLD_KEY_ID, 1086f971622SJuan Castillo BL30_KEY_ID, 1096f971622SJuan Castillo BL31_KEY_ID, 1106f971622SJuan Castillo BL32_KEY_ID, 1116f971622SJuan Castillo BL33_KEY_ID, 1126f971622SJuan Castillo NUM_OPTS 1136f971622SJuan Castillo }; 1146f971622SJuan Castillo 1156f971622SJuan Castillo /* Global options */ 116ccbf890eSJuan Castillo static int key_alg; 1176f971622SJuan Castillo static int new_keys; 1186f971622SJuan Castillo static int save_keys; 1196f971622SJuan Castillo static int print_cert; 1206f971622SJuan Castillo 1216f971622SJuan Castillo /* Info messages created in the Makefile */ 1226f971622SJuan Castillo extern const char build_msg[]; 1236f971622SJuan Castillo extern const char platform_msg[]; 1246f971622SJuan Castillo 1256f971622SJuan Castillo 1266f971622SJuan Castillo static char *strdup(const char *str) 1276f971622SJuan Castillo { 1286f971622SJuan Castillo int n = strlen(str) + 1; 1296f971622SJuan Castillo char *dup = malloc(n); 1306f971622SJuan Castillo if (dup) { 1316f971622SJuan Castillo strcpy(dup, str); 1326f971622SJuan Castillo } 1336f971622SJuan Castillo return dup; 1346f971622SJuan Castillo } 1356f971622SJuan Castillo 136ccbf890eSJuan Castillo static const char *key_algs_str[] = { 137ccbf890eSJuan Castillo [KEY_ALG_RSA] = "rsa", 138ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC 139ccbf890eSJuan Castillo [KEY_ALG_ECDSA] = "ecdsa" 140ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */ 141ccbf890eSJuan Castillo }; 142ccbf890eSJuan Castillo 143*ad2c1a9aSJuan Castillo static void print_help(const char *cmd, const struct option *long_opt) 1446f971622SJuan Castillo { 1456f971622SJuan Castillo int i = 0; 1466f971622SJuan Castillo printf("\n\n"); 1476f971622SJuan Castillo printf("The certificate generation tool loads the binary images and\n" 1486f971622SJuan Castillo "optionally the RSA keys, and outputs the key and content\n" 1496f971622SJuan Castillo "certificates properly signed to implement the chain of trust.\n" 1506f971622SJuan Castillo "If keys are provided, they must be in PEM format.\n" 1516f971622SJuan Castillo "Certificates are generated in DER format.\n"); 1526f971622SJuan Castillo printf("\n"); 1536f971622SJuan Castillo printf("Usage:\n\n"); 1546f971622SJuan Castillo printf(" %s [-hknp] \\\n", cmd); 1556f971622SJuan Castillo for (i = 0; i < NUM_OPTS; i++) { 1566f971622SJuan Castillo printf(" --%s <file> \\\n", long_opt[i].name); 1576f971622SJuan Castillo } 1586f971622SJuan Castillo printf("\n"); 159ccbf890eSJuan Castillo printf("-a Key algorithm: rsa (default), ecdsa\n"); 1606f971622SJuan Castillo printf("-h Print help and exit\n"); 1616f971622SJuan Castillo printf("-k Save key pairs into files. Filenames must be provided\n"); 1626f971622SJuan Castillo printf("-n Generate new key pairs if no key files are provided\n"); 1636f971622SJuan Castillo printf("-p Print the certificates in the standard output\n"); 1646f971622SJuan Castillo printf("\n"); 1656f971622SJuan Castillo 1666f971622SJuan Castillo exit(0); 1676f971622SJuan Castillo } 1686f971622SJuan Castillo 169ccbf890eSJuan Castillo static int get_key_alg(const char *key_alg_str) 170ccbf890eSJuan Castillo { 171ccbf890eSJuan Castillo int i; 172ccbf890eSJuan Castillo 173ccbf890eSJuan Castillo for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) { 174ccbf890eSJuan Castillo if (0 == strcmp(key_alg_str, key_algs_str[i])) { 175ccbf890eSJuan Castillo return i; 176ccbf890eSJuan Castillo } 177ccbf890eSJuan Castillo } 178ccbf890eSJuan Castillo 179ccbf890eSJuan Castillo return -1; 180ccbf890eSJuan Castillo } 181ccbf890eSJuan Castillo 1826f971622SJuan Castillo static void check_cmd_params(void) 1836f971622SJuan Castillo { 184dfc90e26SJuan Castillo cert_t *cert; 185dfc90e26SJuan Castillo ext_t *ext; 186dfc90e26SJuan Castillo key_t *key; 187dfc90e26SJuan Castillo int i, j; 188dfc90e26SJuan Castillo 189ccbf890eSJuan Castillo /* Only save new keys */ 190ccbf890eSJuan Castillo if (save_keys && !new_keys) { 191ccbf890eSJuan Castillo ERROR("Only new keys can be saved to disk\n"); 192ccbf890eSJuan Castillo exit(1); 193ccbf890eSJuan Castillo } 194ccbf890eSJuan Castillo 195dfc90e26SJuan Castillo /* Check that all required options have been specified in the 196dfc90e26SJuan Castillo * command line */ 197dfc90e26SJuan Castillo for (i = 0; i < num_certs; i++) { 198dfc90e26SJuan Castillo cert = &certs[i]; 199dfc90e26SJuan Castillo if (cert->fn == NULL) { 200dfc90e26SJuan Castillo /* Certificate not requested. Skip to the next one */ 201dfc90e26SJuan Castillo continue; 202dfc90e26SJuan Castillo } 203dfc90e26SJuan Castillo 204dfc90e26SJuan Castillo /* Check that all parameters required to create this certificate 205dfc90e26SJuan Castillo * have been specified in the command line */ 206dfc90e26SJuan Castillo for (j = 0; j < cert->num_ext; j++) { 207dfc90e26SJuan Castillo ext = &extensions[cert->ext[j]]; 208dfc90e26SJuan Castillo switch (ext->type) { 209dfc90e26SJuan Castillo case EXT_TYPE_PKEY: 210dfc90e26SJuan Castillo /* Key filename must be specified */ 211dfc90e26SJuan Castillo key = &keys[ext->data.key]; 212dfc90e26SJuan Castillo if (!new_keys && key->fn == NULL) { 213dfc90e26SJuan Castillo ERROR("Key '%s' required by '%s' not " 214dfc90e26SJuan Castillo "specified\n", key->desc, 215dfc90e26SJuan Castillo cert->cn); 2166f971622SJuan Castillo exit(1); 2176f971622SJuan Castillo } 218dfc90e26SJuan Castillo break; 219dfc90e26SJuan Castillo case EXT_TYPE_HASH: 220dfc90e26SJuan Castillo /* Binary image must be specified */ 221dfc90e26SJuan Castillo if (ext->data.fn == NULL) { 222dfc90e26SJuan Castillo ERROR("Image for '%s' not specified\n", 223dfc90e26SJuan Castillo ext->ln); 2246f971622SJuan Castillo exit(1); 2256f971622SJuan Castillo } 226dfc90e26SJuan Castillo break; 227dfc90e26SJuan Castillo default: 228dfc90e26SJuan Castillo ERROR("Unknown extension type in '%s'\n", 229dfc90e26SJuan Castillo ext->ln); 2306f971622SJuan Castillo exit(1); 231dfc90e26SJuan Castillo break; 2326f971622SJuan Castillo } 2336f971622SJuan Castillo } 2346f971622SJuan Castillo } 2356f971622SJuan Castillo } 2366f971622SJuan Castillo 2376f971622SJuan Castillo int main(int argc, char *argv[]) 2386f971622SJuan Castillo { 2396f971622SJuan Castillo STACK_OF(X509_EXTENSION) * sk = NULL; 24055e291a4SJuan Castillo X509_EXTENSION *cert_ext = NULL; 24155e291a4SJuan Castillo ext_t *ext = NULL; 242*ad2c1a9aSJuan Castillo key_t *key = NULL; 243*ad2c1a9aSJuan Castillo cert_t *cert = NULL; 2446f971622SJuan Castillo FILE *file = NULL; 24555e291a4SJuan Castillo int i, j, ext_nid; 2466f971622SJuan Castillo int c, opt_idx = 0; 247*ad2c1a9aSJuan Castillo const struct option *cmd_opt; 248*ad2c1a9aSJuan Castillo const char *cur_opt; 249ccbf890eSJuan Castillo unsigned int err_code; 2506f971622SJuan Castillo unsigned char md[SHA256_DIGEST_LENGTH]; 251c3da66b1SJuan Castillo const EVP_MD *md_info; 2526f971622SJuan Castillo 2536f971622SJuan Castillo NOTICE("CoT Generation Tool: %s\n", build_msg); 2546f971622SJuan Castillo NOTICE("Target platform: %s\n", platform_msg); 2556f971622SJuan Castillo 256ccbf890eSJuan Castillo /* Set default options */ 257ccbf890eSJuan Castillo key_alg = KEY_ALG_RSA; 258ccbf890eSJuan Castillo 259*ad2c1a9aSJuan Castillo /* Add common command line options */ 260*ad2c1a9aSJuan Castillo cmd_opt_add("key-alg", required_argument, 'a'); 261*ad2c1a9aSJuan Castillo cmd_opt_add("help", no_argument, 'h'); 262*ad2c1a9aSJuan Castillo cmd_opt_add("save-keys", no_argument, 'k'); 263*ad2c1a9aSJuan Castillo cmd_opt_add("new-chain", no_argument, 'n'); 264*ad2c1a9aSJuan Castillo cmd_opt_add("print-cert", no_argument, 'p'); 265*ad2c1a9aSJuan Castillo 266*ad2c1a9aSJuan Castillo /* Initialize the certificates */ 267*ad2c1a9aSJuan Castillo if (cert_init() != 0) { 268*ad2c1a9aSJuan Castillo ERROR("Cannot initialize certificates\n"); 269*ad2c1a9aSJuan Castillo exit(1); 270*ad2c1a9aSJuan Castillo } 271*ad2c1a9aSJuan Castillo 272*ad2c1a9aSJuan Castillo /* Initialize the keys */ 273*ad2c1a9aSJuan Castillo if (key_init() != 0) { 274*ad2c1a9aSJuan Castillo ERROR("Cannot initialize keys\n"); 275*ad2c1a9aSJuan Castillo exit(1); 276*ad2c1a9aSJuan Castillo } 277*ad2c1a9aSJuan Castillo 278*ad2c1a9aSJuan Castillo /* Initialize the new types and register OIDs for the extensions */ 279*ad2c1a9aSJuan Castillo if (ext_init() != 0) { 280*ad2c1a9aSJuan Castillo ERROR("Cannot initialize TBB extensions\n"); 281*ad2c1a9aSJuan Castillo exit(1); 282*ad2c1a9aSJuan Castillo } 283*ad2c1a9aSJuan Castillo 284*ad2c1a9aSJuan Castillo /* Get the command line options populated during the initialization */ 285*ad2c1a9aSJuan Castillo cmd_opt = cmd_opt_get_array(); 286*ad2c1a9aSJuan Castillo 2876f971622SJuan Castillo while (1) { 2886f971622SJuan Castillo /* getopt_long stores the option index here. */ 289*ad2c1a9aSJuan Castillo c = getopt_long(argc, argv, "ahknp", cmd_opt, &opt_idx); 2906f971622SJuan Castillo 2916f971622SJuan Castillo /* Detect the end of the options. */ 2926f971622SJuan Castillo if (c == -1) { 2936f971622SJuan Castillo break; 2946f971622SJuan Castillo } 2956f971622SJuan Castillo 2966f971622SJuan Castillo switch (c) { 297ccbf890eSJuan Castillo case 'a': 298ccbf890eSJuan Castillo key_alg = get_key_alg(optarg); 299ccbf890eSJuan Castillo if (key_alg < 0) { 300ccbf890eSJuan Castillo ERROR("Invalid key algorithm '%s'\n", optarg); 301ccbf890eSJuan Castillo exit(1); 302ccbf890eSJuan Castillo } 303ccbf890eSJuan Castillo break; 3046f971622SJuan Castillo case 'h': 305*ad2c1a9aSJuan Castillo print_help(argv[0], cmd_opt); 3066f971622SJuan Castillo break; 3076f971622SJuan Castillo case 'k': 3086f971622SJuan Castillo save_keys = 1; 3096f971622SJuan Castillo break; 3106f971622SJuan Castillo case 'n': 3116f971622SJuan Castillo new_keys = 1; 3126f971622SJuan Castillo break; 3136f971622SJuan Castillo case 'p': 3146f971622SJuan Castillo print_cert = 1; 3156f971622SJuan Castillo break; 316*ad2c1a9aSJuan Castillo case CMD_OPT_EXT: 317*ad2c1a9aSJuan Castillo cur_opt = cmd_opt_get_name(opt_idx); 318*ad2c1a9aSJuan Castillo ext = ext_get_by_opt(cur_opt); 319*ad2c1a9aSJuan Castillo ext->data.fn = strdup(optarg); 3206f971622SJuan Castillo break; 321*ad2c1a9aSJuan Castillo case CMD_OPT_KEY: 322*ad2c1a9aSJuan Castillo cur_opt = cmd_opt_get_name(opt_idx); 323*ad2c1a9aSJuan Castillo key = key_get_by_opt(cur_opt); 324*ad2c1a9aSJuan Castillo key->fn = strdup(optarg); 3256f971622SJuan Castillo break; 326*ad2c1a9aSJuan Castillo case CMD_OPT_CERT: 327*ad2c1a9aSJuan Castillo cur_opt = cmd_opt_get_name(opt_idx); 328*ad2c1a9aSJuan Castillo cert = cert_get_by_opt(cur_opt); 329*ad2c1a9aSJuan Castillo cert->fn = strdup(optarg); 3306f971622SJuan Castillo break; 3316f971622SJuan Castillo case '?': 3326f971622SJuan Castillo default: 3336f971622SJuan Castillo printf("%s\n", optarg); 3346f971622SJuan Castillo exit(1); 3356f971622SJuan Castillo } 3366f971622SJuan Castillo } 3376f971622SJuan Castillo 3386f971622SJuan Castillo /* Check command line arguments */ 3396f971622SJuan Castillo check_cmd_params(); 3406f971622SJuan Castillo 341c3da66b1SJuan Castillo /* Indicate SHA256 as image hash algorithm in the certificate 342c3da66b1SJuan Castillo * extension */ 343c3da66b1SJuan Castillo md_info = EVP_sha256(); 344c3da66b1SJuan Castillo 3456f971622SJuan Castillo /* Load private keys from files (or generate new ones) */ 34655e291a4SJuan Castillo for (i = 0 ; i < num_keys ; i++) { 347ccbf890eSJuan Castillo /* First try to load the key from disk */ 348ccbf890eSJuan Castillo if (key_load(&keys[i], &err_code)) { 349ccbf890eSJuan Castillo /* Key loaded successfully */ 350ccbf890eSJuan Castillo continue; 351ccbf890eSJuan Castillo } 352ccbf890eSJuan Castillo 353ccbf890eSJuan Castillo /* Key not loaded. Check the error code */ 354ccbf890eSJuan Castillo if (err_code == KEY_ERR_MALLOC) { 355ccbf890eSJuan Castillo /* Cannot allocate memory. Abort. */ 356ccbf890eSJuan Castillo ERROR("Malloc error while loading '%s'\n", keys[i].fn); 357ccbf890eSJuan Castillo exit(1); 358ccbf890eSJuan Castillo } else if (err_code == KEY_ERR_LOAD) { 359ccbf890eSJuan Castillo /* File exists, but it does not contain a valid private 360ccbf890eSJuan Castillo * key. Abort. */ 361ccbf890eSJuan Castillo ERROR("Error loading '%s'\n", keys[i].fn); 3626f971622SJuan Castillo exit(1); 3636f971622SJuan Castillo } 364ccbf890eSJuan Castillo 365ccbf890eSJuan Castillo /* File does not exist, could not be opened or no filename was 366ccbf890eSJuan Castillo * given */ 367ccbf890eSJuan Castillo if (new_keys) { 368ccbf890eSJuan Castillo /* Try to create a new key */ 369ccbf890eSJuan Castillo NOTICE("Creating new key for '%s'\n", keys[i].desc); 370ccbf890eSJuan Castillo if (!key_create(&keys[i], key_alg)) { 371ccbf890eSJuan Castillo ERROR("Error creating key '%s'\n", keys[i].desc); 372ccbf890eSJuan Castillo exit(1); 3736f971622SJuan Castillo } 3746f971622SJuan Castillo } else { 375ccbf890eSJuan Castillo if (err_code == KEY_ERR_OPEN) { 376ccbf890eSJuan Castillo ERROR("Error opening '%s'\n", keys[i].fn); 377ccbf890eSJuan Castillo } else { 378ccbf890eSJuan Castillo ERROR("Key '%s' not specified\n", keys[i].desc); 3796f971622SJuan Castillo } 380ccbf890eSJuan Castillo exit(1); 3816f971622SJuan Castillo } 3826f971622SJuan Castillo } 3836f971622SJuan Castillo 38455e291a4SJuan Castillo /* Create the certificates */ 38555e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 38655e291a4SJuan Castillo 38755e291a4SJuan Castillo cert = &certs[i]; 38855e291a4SJuan Castillo 38955e291a4SJuan Castillo /* Create a new stack of extensions. This stack will be used 39055e291a4SJuan Castillo * to create the certificate */ 3916f971622SJuan Castillo CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); 3926f971622SJuan Castillo 39355e291a4SJuan Castillo for (j = 0 ; j < cert->num_ext ; j++) { 3946f971622SJuan Castillo 39555e291a4SJuan Castillo ext = &extensions[cert->ext[j]]; 39655e291a4SJuan Castillo 39755e291a4SJuan Castillo /* Get OpenSSL internal ID for this extension */ 39855e291a4SJuan Castillo CHECK_OID(ext_nid, ext->oid); 39955e291a4SJuan Castillo 40055e291a4SJuan Castillo /* 40155e291a4SJuan Castillo * Three types of extensions are currently supported: 40255e291a4SJuan Castillo * - EXT_TYPE_NVCOUNTER 40355e291a4SJuan Castillo * - EXT_TYPE_HASH 40455e291a4SJuan Castillo * - EXT_TYPE_PKEY 40555e291a4SJuan Castillo */ 40655e291a4SJuan Castillo switch (ext->type) { 40755e291a4SJuan Castillo case EXT_TYPE_NVCOUNTER: 40855e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid, 40955e291a4SJuan Castillo EXT_CRIT, ext->data.nvcounter)); 41055e291a4SJuan Castillo break; 41155e291a4SJuan Castillo case EXT_TYPE_HASH: 41255e291a4SJuan Castillo if (ext->data.fn == NULL) { 41355e291a4SJuan Castillo break; 41455e291a4SJuan Castillo } 41555e291a4SJuan Castillo if (!sha_file(ext->data.fn, md)) { 41655e291a4SJuan Castillo ERROR("Cannot calculate hash of %s\n", 41755e291a4SJuan Castillo ext->data.fn); 4186f971622SJuan Castillo exit(1); 4196f971622SJuan Castillo } 42055e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_hash(ext_nid, 42155e291a4SJuan Castillo EXT_CRIT, md_info, md, 4226f971622SJuan Castillo SHA256_DIGEST_LENGTH)); 42355e291a4SJuan Castillo break; 42455e291a4SJuan Castillo case EXT_TYPE_PKEY: 42555e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_key(ext_nid, 42655e291a4SJuan Castillo EXT_CRIT, keys[ext->data.key].key)); 42755e291a4SJuan Castillo break; 42855e291a4SJuan Castillo default: 42955e291a4SJuan Castillo ERROR("Unknown extension type in %s\n", 43055e291a4SJuan Castillo cert->cn); 43155e291a4SJuan Castillo exit(1); 43255e291a4SJuan Castillo } 43355e291a4SJuan Castillo 43455e291a4SJuan Castillo /* Push the extension into the stack */ 43555e291a4SJuan Castillo sk_X509_EXTENSION_push(sk, cert_ext); 43655e291a4SJuan Castillo } 4376f971622SJuan Castillo 4386f971622SJuan Castillo /* Create certificate. Signed with ROT key */ 439dfc90e26SJuan Castillo if (cert->fn && !cert_new(cert, VAL_DAYS, 0, sk)) { 44055e291a4SJuan Castillo ERROR("Cannot create %s\n", cert->cn); 4416f971622SJuan Castillo exit(1); 4426f971622SJuan Castillo } 4436f971622SJuan Castillo 4446f971622SJuan Castillo sk_X509_EXTENSION_free(sk); 4456f971622SJuan Castillo } 4466f971622SJuan Castillo 4476f971622SJuan Castillo 4486f971622SJuan Castillo /* Print the certificates */ 4496f971622SJuan Castillo if (print_cert) { 45055e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 4516f971622SJuan Castillo if (!certs[i].x) { 4526f971622SJuan Castillo continue; 4536f971622SJuan Castillo } 4546f971622SJuan Castillo printf("\n\n=====================================\n\n"); 4556f971622SJuan Castillo X509_print_fp(stdout, certs[i].x); 4566f971622SJuan Castillo } 4576f971622SJuan Castillo } 4586f971622SJuan Castillo 4596f971622SJuan Castillo /* Save created certificates to files */ 46055e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 4616f971622SJuan Castillo if (certs[i].x && certs[i].fn) { 4626f971622SJuan Castillo file = fopen(certs[i].fn, "w"); 4636f971622SJuan Castillo if (file != NULL) { 4646f971622SJuan Castillo i2d_X509_fp(file, certs[i].x); 4656f971622SJuan Castillo fclose(file); 4666f971622SJuan Castillo } else { 4676f971622SJuan Castillo ERROR("Cannot create file %s\n", certs[i].fn); 4686f971622SJuan Castillo } 4696f971622SJuan Castillo } 4706f971622SJuan Castillo } 4716f971622SJuan Castillo 4726f971622SJuan Castillo /* Save keys */ 4736f971622SJuan Castillo if (save_keys) { 47455e291a4SJuan Castillo for (i = 0 ; i < num_keys ; i++) { 4756f971622SJuan Castillo if (!key_store(&keys[i])) { 4766f971622SJuan Castillo ERROR("Cannot save %s\n", keys[i].desc); 4776f971622SJuan Castillo } 4786f971622SJuan Castillo } 4796f971622SJuan Castillo } 4806f971622SJuan Castillo 4816f971622SJuan Castillo #ifndef OPENSSL_NO_ENGINE 4826f971622SJuan Castillo ENGINE_cleanup(); 4836f971622SJuan Castillo #endif 4846f971622SJuan Castillo CRYPTO_cleanup_all_ex_data(); 4856f971622SJuan Castillo 4866f971622SJuan Castillo return 0; 4876f971622SJuan Castillo } 488