16f971622SJuan Castillo /* 2bb41eb7aSMasahiro Yamada * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 36f971622SJuan Castillo * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 56f971622SJuan Castillo */ 66f971622SJuan Castillo 7159807e2SJuan Castillo #include <assert.h> 8159807e2SJuan Castillo #include <ctype.h> 96f971622SJuan Castillo #include <getopt.h> 106f971622SJuan Castillo #include <stdio.h> 116f971622SJuan Castillo #include <stdlib.h> 126f971622SJuan Castillo #include <string.h> 136f971622SJuan Castillo 146f971622SJuan Castillo #include <openssl/conf.h> 156f971622SJuan Castillo #include <openssl/engine.h> 166f971622SJuan Castillo #include <openssl/err.h> 176f971622SJuan Castillo #include <openssl/pem.h> 186f971622SJuan Castillo #include <openssl/sha.h> 196f971622SJuan Castillo #include <openssl/x509v3.h> 206f971622SJuan Castillo 21bb41eb7aSMasahiro Yamada #if USE_TBBR_DEFS 22bb41eb7aSMasahiro Yamada #include <tbbr_oid.h> 23bb41eb7aSMasahiro Yamada #else 24bb41eb7aSMasahiro Yamada #include <platform_oid.h> 25bb41eb7aSMasahiro Yamada #endif 26bb41eb7aSMasahiro Yamada 276f971622SJuan Castillo #include "cert.h" 28ad2c1a9aSJuan Castillo #include "cmd_opt.h" 296f971622SJuan Castillo #include "debug.h" 306f971622SJuan Castillo #include "ext.h" 316f971622SJuan Castillo #include "key.h" 326f971622SJuan Castillo #include "sha.h" 3355e291a4SJuan Castillo #include "tbbr/tbb_cert.h" 342a4b4b71SIsla Mitchell #include "tbbr/tbb_ext.h" 3555e291a4SJuan Castillo #include "tbbr/tbb_key.h" 366f971622SJuan Castillo 376f971622SJuan Castillo /* 386f971622SJuan Castillo * Helper macros to simplify the code. This macro assigns the return value of 396f971622SJuan Castillo * the 'fn' function to 'v' and exits if the value is NULL. 406f971622SJuan Castillo */ 416f971622SJuan Castillo #define CHECK_NULL(v, fn) \ 426f971622SJuan Castillo do { \ 436f971622SJuan Castillo v = fn; \ 446f971622SJuan Castillo if (v == NULL) { \ 456f971622SJuan Castillo ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \ 466f971622SJuan Castillo exit(1); \ 476f971622SJuan Castillo } \ 486f971622SJuan Castillo } while (0) 496f971622SJuan Castillo 506f971622SJuan Castillo /* 516f971622SJuan Castillo * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the 526f971622SJuan Castillo * NID is undefined. 536f971622SJuan Castillo */ 546f971622SJuan Castillo #define CHECK_OID(v, oid) \ 556f971622SJuan Castillo do { \ 566f971622SJuan Castillo v = OBJ_txt2nid(oid); \ 576f971622SJuan Castillo if (v == NID_undef) { \ 586f971622SJuan Castillo ERROR("Cannot find TBB extension %s\n", oid); \ 596f971622SJuan Castillo exit(1); \ 606f971622SJuan Castillo } \ 616f971622SJuan Castillo } while (0) 626f971622SJuan Castillo 636f971622SJuan Castillo #define MAX_FILENAME_LEN 1024 646f971622SJuan Castillo #define VAL_DAYS 7300 656f971622SJuan Castillo #define ID_TO_BIT_MASK(id) (1 << id) 66ccbf890eSJuan Castillo #define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0]))) 67159807e2SJuan Castillo #define HELP_OPT_MAX_LEN 128 686f971622SJuan Castillo 696f971622SJuan Castillo /* Global options */ 70ccbf890eSJuan Castillo static int key_alg; 716f971622SJuan Castillo static int new_keys; 726f971622SJuan Castillo static int save_keys; 736f971622SJuan Castillo static int print_cert; 746f971622SJuan Castillo 756f971622SJuan Castillo /* Info messages created in the Makefile */ 766f971622SJuan Castillo extern const char build_msg[]; 776f971622SJuan Castillo extern const char platform_msg[]; 786f971622SJuan Castillo 796f971622SJuan Castillo 806f971622SJuan Castillo static char *strdup(const char *str) 816f971622SJuan Castillo { 826f971622SJuan Castillo int n = strlen(str) + 1; 836f971622SJuan Castillo char *dup = malloc(n); 846f971622SJuan Castillo if (dup) { 856f971622SJuan Castillo strcpy(dup, str); 866f971622SJuan Castillo } 876f971622SJuan Castillo return dup; 886f971622SJuan Castillo } 896f971622SJuan Castillo 90ccbf890eSJuan Castillo static const char *key_algs_str[] = { 91ccbf890eSJuan Castillo [KEY_ALG_RSA] = "rsa", 92*a8eb286aSSoby Mathew [KEY_ALG_RSA_1_5] = "rsa_1_5", 93ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC 94ccbf890eSJuan Castillo [KEY_ALG_ECDSA] = "ecdsa" 95ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */ 96ccbf890eSJuan Castillo }; 97ccbf890eSJuan Castillo 98ad2c1a9aSJuan Castillo static void print_help(const char *cmd, const struct option *long_opt) 996f971622SJuan Castillo { 100159807e2SJuan Castillo int rem, i = 0; 101159807e2SJuan Castillo const struct option *opt; 102159807e2SJuan Castillo char line[HELP_OPT_MAX_LEN]; 103159807e2SJuan Castillo char *p; 104159807e2SJuan Castillo 105159807e2SJuan Castillo assert(cmd != NULL); 106159807e2SJuan Castillo assert(long_opt != NULL); 107159807e2SJuan Castillo 1086f971622SJuan Castillo printf("\n\n"); 1096f971622SJuan Castillo printf("The certificate generation tool loads the binary images and\n" 1106f971622SJuan Castillo "optionally the RSA keys, and outputs the key and content\n" 1116f971622SJuan Castillo "certificates properly signed to implement the chain of trust.\n" 1126f971622SJuan Castillo "If keys are provided, they must be in PEM format.\n" 1136f971622SJuan Castillo "Certificates are generated in DER format.\n"); 1146f971622SJuan Castillo printf("\n"); 115159807e2SJuan Castillo printf("Usage:\n"); 116159807e2SJuan Castillo printf("\t%s [OPTIONS]\n\n", cmd); 117159807e2SJuan Castillo 118159807e2SJuan Castillo printf("Available options:\n"); 119159807e2SJuan Castillo opt = long_opt; 120159807e2SJuan Castillo while (opt->name) { 121159807e2SJuan Castillo p = line; 122159807e2SJuan Castillo rem = HELP_OPT_MAX_LEN; 123159807e2SJuan Castillo if (isalpha(opt->val)) { 124159807e2SJuan Castillo /* Short format */ 125159807e2SJuan Castillo sprintf(p, "-%c,", (char)opt->val); 126159807e2SJuan Castillo p += 3; 127159807e2SJuan Castillo rem -= 3; 1286f971622SJuan Castillo } 129159807e2SJuan Castillo snprintf(p, rem, "--%s %s", opt->name, 130159807e2SJuan Castillo (opt->has_arg == required_argument) ? "<arg>" : ""); 131159807e2SJuan Castillo printf("\t%-32s %s\n", line, cmd_opt_get_help_msg(i)); 132159807e2SJuan Castillo opt++; 133159807e2SJuan Castillo i++; 134159807e2SJuan Castillo } 1356f971622SJuan Castillo printf("\n"); 1366f971622SJuan Castillo 1376f971622SJuan Castillo exit(0); 1386f971622SJuan Castillo } 1396f971622SJuan Castillo 140ccbf890eSJuan Castillo static int get_key_alg(const char *key_alg_str) 141ccbf890eSJuan Castillo { 142ccbf890eSJuan Castillo int i; 143ccbf890eSJuan Castillo 144ccbf890eSJuan Castillo for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) { 145ccbf890eSJuan Castillo if (0 == strcmp(key_alg_str, key_algs_str[i])) { 146ccbf890eSJuan Castillo return i; 147ccbf890eSJuan Castillo } 148ccbf890eSJuan Castillo } 149ccbf890eSJuan Castillo 150ccbf890eSJuan Castillo return -1; 151ccbf890eSJuan Castillo } 152ccbf890eSJuan Castillo 1536f971622SJuan Castillo static void check_cmd_params(void) 1546f971622SJuan Castillo { 155dfc90e26SJuan Castillo cert_t *cert; 156dfc90e26SJuan Castillo ext_t *ext; 157dfc90e26SJuan Castillo key_t *key; 158dfc90e26SJuan Castillo int i, j; 159dfc90e26SJuan Castillo 160ccbf890eSJuan Castillo /* Only save new keys */ 161ccbf890eSJuan Castillo if (save_keys && !new_keys) { 162ccbf890eSJuan Castillo ERROR("Only new keys can be saved to disk\n"); 163ccbf890eSJuan Castillo exit(1); 164ccbf890eSJuan Castillo } 165ccbf890eSJuan Castillo 166dfc90e26SJuan Castillo /* Check that all required options have been specified in the 167dfc90e26SJuan Castillo * command line */ 168dfc90e26SJuan Castillo for (i = 0; i < num_certs; i++) { 169dfc90e26SJuan Castillo cert = &certs[i]; 170dfc90e26SJuan Castillo if (cert->fn == NULL) { 171dfc90e26SJuan Castillo /* Certificate not requested. Skip to the next one */ 172dfc90e26SJuan Castillo continue; 173dfc90e26SJuan Castillo } 174dfc90e26SJuan Castillo 175dfc90e26SJuan Castillo /* Check that all parameters required to create this certificate 176dfc90e26SJuan Castillo * have been specified in the command line */ 177dfc90e26SJuan Castillo for (j = 0; j < cert->num_ext; j++) { 178dfc90e26SJuan Castillo ext = &extensions[cert->ext[j]]; 179dfc90e26SJuan Castillo switch (ext->type) { 18096103d5aSJuan Castillo case EXT_TYPE_NVCOUNTER: 18196103d5aSJuan Castillo /* Counter value must be specified */ 18296103d5aSJuan Castillo if ((!ext->optional) && (ext->arg == NULL)) { 18396103d5aSJuan Castillo ERROR("Value for '%s' not specified\n", 18496103d5aSJuan Castillo ext->ln); 18596103d5aSJuan Castillo exit(1); 18696103d5aSJuan Castillo } 18796103d5aSJuan Castillo break; 188dfc90e26SJuan Castillo case EXT_TYPE_PKEY: 189dfc90e26SJuan Castillo /* Key filename must be specified */ 19096103d5aSJuan Castillo key = &keys[ext->attr.key]; 191dfc90e26SJuan Castillo if (!new_keys && key->fn == NULL) { 192dfc90e26SJuan Castillo ERROR("Key '%s' required by '%s' not " 193dfc90e26SJuan Castillo "specified\n", key->desc, 194dfc90e26SJuan Castillo cert->cn); 1956f971622SJuan Castillo exit(1); 1966f971622SJuan Castillo } 197dfc90e26SJuan Castillo break; 198dfc90e26SJuan Castillo case EXT_TYPE_HASH: 199cebe1f23SYatharth Kochar /* 200cebe1f23SYatharth Kochar * Binary image must be specified 201cebe1f23SYatharth Kochar * unless it is explicitly made optional. 202cebe1f23SYatharth Kochar */ 20396103d5aSJuan Castillo if ((!ext->optional) && (ext->arg == NULL)) { 204dfc90e26SJuan Castillo ERROR("Image for '%s' not specified\n", 205dfc90e26SJuan Castillo ext->ln); 2066f971622SJuan Castillo exit(1); 2076f971622SJuan Castillo } 208dfc90e26SJuan Castillo break; 209dfc90e26SJuan Castillo default: 21096103d5aSJuan Castillo ERROR("Unknown extension type '%d' in '%s'\n", 21196103d5aSJuan Castillo ext->type, ext->ln); 2126f971622SJuan Castillo exit(1); 213dfc90e26SJuan Castillo break; 2146f971622SJuan Castillo } 2156f971622SJuan Castillo } 2166f971622SJuan Castillo } 2176f971622SJuan Castillo } 2186f971622SJuan Castillo 219159807e2SJuan Castillo /* Common command line options */ 220159807e2SJuan Castillo static const cmd_opt_t common_cmd_opt[] = { 221159807e2SJuan Castillo { 222159807e2SJuan Castillo { "help", no_argument, NULL, 'h' }, 223159807e2SJuan Castillo "Print this message and exit" 224159807e2SJuan Castillo }, 225159807e2SJuan Castillo { 226159807e2SJuan Castillo { "key-alg", required_argument, NULL, 'a' }, 227*a8eb286aSSoby Mathew "Key algorithm: 'rsa' (default) - RSAPSS scheme as per \ 228*a8eb286aSSoby Mathew PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'" 229159807e2SJuan Castillo }, 230159807e2SJuan Castillo { 231159807e2SJuan Castillo { "save-keys", no_argument, NULL, 'k' }, 232159807e2SJuan Castillo "Save key pairs into files. Filenames must be provided" 233159807e2SJuan Castillo }, 234159807e2SJuan Castillo { 235159807e2SJuan Castillo { "new-keys", no_argument, NULL, 'n' }, 236159807e2SJuan Castillo "Generate new key pairs if no key files are provided" 237159807e2SJuan Castillo }, 238159807e2SJuan Castillo { 239159807e2SJuan Castillo { "print-cert", no_argument, NULL, 'p' }, 240159807e2SJuan Castillo "Print the certificates in the standard output" 241159807e2SJuan Castillo } 242159807e2SJuan Castillo }; 243159807e2SJuan Castillo 2446f971622SJuan Castillo int main(int argc, char *argv[]) 2456f971622SJuan Castillo { 246c893c733SMasahiro Yamada STACK_OF(X509_EXTENSION) * sk; 247c893c733SMasahiro Yamada X509_EXTENSION *cert_ext; 248c893c733SMasahiro Yamada ext_t *ext; 249c893c733SMasahiro Yamada key_t *key; 250c893c733SMasahiro Yamada cert_t *cert; 251c893c733SMasahiro Yamada FILE *file; 25296103d5aSJuan Castillo int i, j, ext_nid, nvctr; 2536f971622SJuan Castillo int c, opt_idx = 0; 254ad2c1a9aSJuan Castillo const struct option *cmd_opt; 255ad2c1a9aSJuan Castillo const char *cur_opt; 256ccbf890eSJuan Castillo unsigned int err_code; 2576f971622SJuan Castillo unsigned char md[SHA256_DIGEST_LENGTH]; 258c3da66b1SJuan Castillo const EVP_MD *md_info; 2596f971622SJuan Castillo 2606f971622SJuan Castillo NOTICE("CoT Generation Tool: %s\n", build_msg); 2616f971622SJuan Castillo NOTICE("Target platform: %s\n", platform_msg); 2626f971622SJuan Castillo 263ccbf890eSJuan Castillo /* Set default options */ 264ccbf890eSJuan Castillo key_alg = KEY_ALG_RSA; 265ccbf890eSJuan Castillo 266ad2c1a9aSJuan Castillo /* Add common command line options */ 267159807e2SJuan Castillo for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) { 268159807e2SJuan Castillo cmd_opt_add(&common_cmd_opt[i]); 269159807e2SJuan Castillo } 270ad2c1a9aSJuan Castillo 271ad2c1a9aSJuan Castillo /* Initialize the certificates */ 272ad2c1a9aSJuan Castillo if (cert_init() != 0) { 273ad2c1a9aSJuan Castillo ERROR("Cannot initialize certificates\n"); 274ad2c1a9aSJuan Castillo exit(1); 275ad2c1a9aSJuan Castillo } 276ad2c1a9aSJuan Castillo 277ad2c1a9aSJuan Castillo /* Initialize the keys */ 278ad2c1a9aSJuan Castillo if (key_init() != 0) { 279ad2c1a9aSJuan Castillo ERROR("Cannot initialize keys\n"); 280ad2c1a9aSJuan Castillo exit(1); 281ad2c1a9aSJuan Castillo } 282ad2c1a9aSJuan Castillo 283ad2c1a9aSJuan Castillo /* Initialize the new types and register OIDs for the extensions */ 284ad2c1a9aSJuan Castillo if (ext_init() != 0) { 285ad2c1a9aSJuan Castillo ERROR("Cannot initialize TBB extensions\n"); 286ad2c1a9aSJuan Castillo exit(1); 287ad2c1a9aSJuan Castillo } 288ad2c1a9aSJuan Castillo 289ad2c1a9aSJuan Castillo /* Get the command line options populated during the initialization */ 290ad2c1a9aSJuan Castillo cmd_opt = cmd_opt_get_array(); 291ad2c1a9aSJuan Castillo 2926f971622SJuan Castillo while (1) { 2936f971622SJuan Castillo /* getopt_long stores the option index here. */ 294159807e2SJuan Castillo c = getopt_long(argc, argv, "a:hknp", cmd_opt, &opt_idx); 2956f971622SJuan Castillo 2966f971622SJuan Castillo /* Detect the end of the options. */ 2976f971622SJuan Castillo if (c == -1) { 2986f971622SJuan Castillo break; 2996f971622SJuan Castillo } 3006f971622SJuan Castillo 3016f971622SJuan Castillo switch (c) { 302ccbf890eSJuan Castillo case 'a': 303ccbf890eSJuan Castillo key_alg = get_key_alg(optarg); 304ccbf890eSJuan Castillo if (key_alg < 0) { 305ccbf890eSJuan Castillo ERROR("Invalid key algorithm '%s'\n", optarg); 306ccbf890eSJuan Castillo exit(1); 307ccbf890eSJuan Castillo } 308ccbf890eSJuan Castillo break; 3096f971622SJuan Castillo case 'h': 310ad2c1a9aSJuan Castillo print_help(argv[0], cmd_opt); 3116f971622SJuan Castillo break; 3126f971622SJuan Castillo case 'k': 3136f971622SJuan Castillo save_keys = 1; 3146f971622SJuan Castillo break; 3156f971622SJuan Castillo case 'n': 3166f971622SJuan Castillo new_keys = 1; 3176f971622SJuan Castillo break; 3186f971622SJuan Castillo case 'p': 3196f971622SJuan Castillo print_cert = 1; 3206f971622SJuan Castillo break; 321ad2c1a9aSJuan Castillo case CMD_OPT_EXT: 322ad2c1a9aSJuan Castillo cur_opt = cmd_opt_get_name(opt_idx); 323ad2c1a9aSJuan Castillo ext = ext_get_by_opt(cur_opt); 32496103d5aSJuan Castillo ext->arg = strdup(optarg); 3256f971622SJuan Castillo break; 326ad2c1a9aSJuan Castillo case CMD_OPT_KEY: 327ad2c1a9aSJuan Castillo cur_opt = cmd_opt_get_name(opt_idx); 328ad2c1a9aSJuan Castillo key = key_get_by_opt(cur_opt); 329ad2c1a9aSJuan Castillo key->fn = strdup(optarg); 3306f971622SJuan Castillo break; 331ad2c1a9aSJuan Castillo case CMD_OPT_CERT: 332ad2c1a9aSJuan Castillo cur_opt = cmd_opt_get_name(opt_idx); 333ad2c1a9aSJuan Castillo cert = cert_get_by_opt(cur_opt); 334ad2c1a9aSJuan Castillo cert->fn = strdup(optarg); 3356f971622SJuan Castillo break; 3366f971622SJuan Castillo case '?': 3376f971622SJuan Castillo default: 338159807e2SJuan Castillo print_help(argv[0], cmd_opt); 3396f971622SJuan Castillo exit(1); 3406f971622SJuan Castillo } 3416f971622SJuan Castillo } 3426f971622SJuan Castillo 3436f971622SJuan Castillo /* Check command line arguments */ 3446f971622SJuan Castillo check_cmd_params(); 3456f971622SJuan Castillo 346c3da66b1SJuan Castillo /* Indicate SHA256 as image hash algorithm in the certificate 347c3da66b1SJuan Castillo * extension */ 348c3da66b1SJuan Castillo md_info = EVP_sha256(); 349c3da66b1SJuan Castillo 3506f971622SJuan Castillo /* Load private keys from files (or generate new ones) */ 35155e291a4SJuan Castillo for (i = 0 ; i < num_keys ; i++) { 352762f1ebeSMasahiro Yamada if (!key_new(&keys[i])) { 353762f1ebeSMasahiro Yamada ERROR("Failed to allocate key container\n"); 354762f1ebeSMasahiro Yamada exit(1); 355762f1ebeSMasahiro Yamada } 356762f1ebeSMasahiro Yamada 357ccbf890eSJuan Castillo /* First try to load the key from disk */ 358ccbf890eSJuan Castillo if (key_load(&keys[i], &err_code)) { 359ccbf890eSJuan Castillo /* Key loaded successfully */ 360ccbf890eSJuan Castillo continue; 361ccbf890eSJuan Castillo } 362ccbf890eSJuan Castillo 363ccbf890eSJuan Castillo /* Key not loaded. Check the error code */ 364762f1ebeSMasahiro Yamada if (err_code == KEY_ERR_LOAD) { 365ccbf890eSJuan Castillo /* File exists, but it does not contain a valid private 366ccbf890eSJuan Castillo * key. Abort. */ 367ccbf890eSJuan Castillo ERROR("Error loading '%s'\n", keys[i].fn); 3686f971622SJuan Castillo exit(1); 3696f971622SJuan Castillo } 370ccbf890eSJuan Castillo 371ccbf890eSJuan Castillo /* File does not exist, could not be opened or no filename was 372ccbf890eSJuan Castillo * given */ 373ccbf890eSJuan Castillo if (new_keys) { 374ccbf890eSJuan Castillo /* Try to create a new key */ 375ccbf890eSJuan Castillo NOTICE("Creating new key for '%s'\n", keys[i].desc); 376ccbf890eSJuan Castillo if (!key_create(&keys[i], key_alg)) { 377ccbf890eSJuan Castillo ERROR("Error creating key '%s'\n", keys[i].desc); 378ccbf890eSJuan Castillo exit(1); 3796f971622SJuan Castillo } 3806f971622SJuan Castillo } else { 381ccbf890eSJuan Castillo if (err_code == KEY_ERR_OPEN) { 382ccbf890eSJuan Castillo ERROR("Error opening '%s'\n", keys[i].fn); 383ccbf890eSJuan Castillo } else { 384ccbf890eSJuan Castillo ERROR("Key '%s' not specified\n", keys[i].desc); 3856f971622SJuan Castillo } 386ccbf890eSJuan Castillo exit(1); 3876f971622SJuan Castillo } 3886f971622SJuan Castillo } 3896f971622SJuan Castillo 39055e291a4SJuan Castillo /* Create the certificates */ 39155e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 39255e291a4SJuan Castillo 39355e291a4SJuan Castillo cert = &certs[i]; 39455e291a4SJuan Castillo 39555e291a4SJuan Castillo /* Create a new stack of extensions. This stack will be used 39655e291a4SJuan Castillo * to create the certificate */ 3976f971622SJuan Castillo CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); 3986f971622SJuan Castillo 39955e291a4SJuan Castillo for (j = 0 ; j < cert->num_ext ; j++) { 4006f971622SJuan Castillo 40155e291a4SJuan Castillo ext = &extensions[cert->ext[j]]; 40255e291a4SJuan Castillo 40355e291a4SJuan Castillo /* Get OpenSSL internal ID for this extension */ 40455e291a4SJuan Castillo CHECK_OID(ext_nid, ext->oid); 40555e291a4SJuan Castillo 40655e291a4SJuan Castillo /* 40755e291a4SJuan Castillo * Three types of extensions are currently supported: 40855e291a4SJuan Castillo * - EXT_TYPE_NVCOUNTER 40955e291a4SJuan Castillo * - EXT_TYPE_HASH 41055e291a4SJuan Castillo * - EXT_TYPE_PKEY 41155e291a4SJuan Castillo */ 41255e291a4SJuan Castillo switch (ext->type) { 41355e291a4SJuan Castillo case EXT_TYPE_NVCOUNTER: 414f16db56aSYatharth Kochar if (ext->arg) { 41596103d5aSJuan Castillo nvctr = atoi(ext->arg); 41655e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid, 41796103d5aSJuan Castillo EXT_CRIT, nvctr)); 418f16db56aSYatharth Kochar } 41955e291a4SJuan Castillo break; 42055e291a4SJuan Castillo case EXT_TYPE_HASH: 42196103d5aSJuan Castillo if (ext->arg == NULL) { 422cebe1f23SYatharth Kochar if (ext->optional) { 423cebe1f23SYatharth Kochar /* Include a hash filled with zeros */ 424cebe1f23SYatharth Kochar memset(md, 0x0, SHA256_DIGEST_LENGTH); 425cebe1f23SYatharth Kochar } else { 426cebe1f23SYatharth Kochar /* Do not include this hash in the certificate */ 42755e291a4SJuan Castillo break; 42855e291a4SJuan Castillo } 429cebe1f23SYatharth Kochar } else { 430cebe1f23SYatharth Kochar /* Calculate the hash of the file */ 43196103d5aSJuan Castillo if (!sha_file(ext->arg, md)) { 43255e291a4SJuan Castillo ERROR("Cannot calculate hash of %s\n", 43396103d5aSJuan Castillo ext->arg); 4346f971622SJuan Castillo exit(1); 4356f971622SJuan Castillo } 436cebe1f23SYatharth Kochar } 43755e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_hash(ext_nid, 43855e291a4SJuan Castillo EXT_CRIT, md_info, md, 4396f971622SJuan Castillo SHA256_DIGEST_LENGTH)); 44055e291a4SJuan Castillo break; 44155e291a4SJuan Castillo case EXT_TYPE_PKEY: 44255e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_key(ext_nid, 44396103d5aSJuan Castillo EXT_CRIT, keys[ext->attr.key].key)); 44455e291a4SJuan Castillo break; 44555e291a4SJuan Castillo default: 44696103d5aSJuan Castillo ERROR("Unknown extension type '%d' in %s\n", 44796103d5aSJuan Castillo ext->type, cert->cn); 44855e291a4SJuan Castillo exit(1); 44955e291a4SJuan Castillo } 45055e291a4SJuan Castillo 45155e291a4SJuan Castillo /* Push the extension into the stack */ 45255e291a4SJuan Castillo sk_X509_EXTENSION_push(sk, cert_ext); 45355e291a4SJuan Castillo } 4546f971622SJuan Castillo 455*a8eb286aSSoby Mathew /* Create certificate. Signed with corresponding key */ 456*a8eb286aSSoby Mathew if (cert->fn && !cert_new(key_alg, cert, VAL_DAYS, 0, sk)) { 45755e291a4SJuan Castillo ERROR("Cannot create %s\n", cert->cn); 4586f971622SJuan Castillo exit(1); 4596f971622SJuan Castillo } 4606f971622SJuan Castillo 4616f971622SJuan Castillo sk_X509_EXTENSION_free(sk); 4626f971622SJuan Castillo } 4636f971622SJuan Castillo 4646f971622SJuan Castillo 4656f971622SJuan Castillo /* Print the certificates */ 4666f971622SJuan Castillo if (print_cert) { 46755e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 4686f971622SJuan Castillo if (!certs[i].x) { 4696f971622SJuan Castillo continue; 4706f971622SJuan Castillo } 4716f971622SJuan Castillo printf("\n\n=====================================\n\n"); 4726f971622SJuan Castillo X509_print_fp(stdout, certs[i].x); 4736f971622SJuan Castillo } 4746f971622SJuan Castillo } 4756f971622SJuan Castillo 4766f971622SJuan Castillo /* Save created certificates to files */ 47755e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 4786f971622SJuan Castillo if (certs[i].x && certs[i].fn) { 4796f971622SJuan Castillo file = fopen(certs[i].fn, "w"); 4806f971622SJuan Castillo if (file != NULL) { 4816f971622SJuan Castillo i2d_X509_fp(file, certs[i].x); 4826f971622SJuan Castillo fclose(file); 4836f971622SJuan Castillo } else { 4846f971622SJuan Castillo ERROR("Cannot create file %s\n", certs[i].fn); 4856f971622SJuan Castillo } 4866f971622SJuan Castillo } 4876f971622SJuan Castillo } 4886f971622SJuan Castillo 4896f971622SJuan Castillo /* Save keys */ 4906f971622SJuan Castillo if (save_keys) { 49155e291a4SJuan Castillo for (i = 0 ; i < num_keys ; i++) { 4926f971622SJuan Castillo if (!key_store(&keys[i])) { 4936f971622SJuan Castillo ERROR("Cannot save %s\n", keys[i].desc); 4946f971622SJuan Castillo } 4956f971622SJuan Castillo } 4966f971622SJuan Castillo } 4976f971622SJuan Castillo 4986f971622SJuan Castillo #ifndef OPENSSL_NO_ENGINE 4996f971622SJuan Castillo ENGINE_cleanup(); 5006f971622SJuan Castillo #endif 5016f971622SJuan Castillo CRYPTO_cleanup_all_ex_data(); 5026f971622SJuan Castillo 5036f971622SJuan Castillo return 0; 5046f971622SJuan Castillo } 505