blob: 29bf4528c1e580bd0f0a4fd5726dad7c9a56ce24 [file] [log] [blame]
Juan Castillo11abdcd2014-10-21 11:30:42 +01001/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <getopt.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include <openssl/conf.h>
37#include <openssl/engine.h>
38#include <openssl/err.h>
39#include <openssl/pem.h>
40#include <openssl/sha.h>
41#include <openssl/x509v3.h>
42
43#include "cert.h"
44#include "debug.h"
45#include "ext.h"
46#include "key.h"
47#include "platform_oid.h"
48#include "sha.h"
Juan Castilloe6d30e92015-06-12 11:27:59 +010049#include "tbbr/tbb_ext.h"
50#include "tbbr/tbb_cert.h"
51#include "tbbr/tbb_key.h"
Juan Castillo11abdcd2014-10-21 11:30:42 +010052
53/*
54 * Helper macros to simplify the code. This macro assigns the return value of
55 * the 'fn' function to 'v' and exits if the value is NULL.
56 */
57#define CHECK_NULL(v, fn) \
58 do { \
59 v = fn; \
60 if (v == NULL) { \
61 ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
62 exit(1); \
63 } \
64 } while (0)
65
66/*
67 * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
68 * NID is undefined.
69 */
70#define CHECK_OID(v, oid) \
71 do { \
72 v = OBJ_txt2nid(oid); \
73 if (v == NID_undef) { \
74 ERROR("Cannot find TBB extension %s\n", oid); \
75 exit(1); \
76 } \
77 } while (0)
78
79#define MAX_FILENAME_LEN 1024
80#define VAL_DAYS 7300
81#define ID_TO_BIT_MASK(id) (1 << id)
Juan Castillof9f39c32015-06-01 16:34:23 +010082#define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0])))
Juan Castillo11abdcd2014-10-21 11:30:42 +010083
84/* Files */
85enum {
86 /* Image file names (inputs) */
87 BL2_ID = 0,
88 BL30_ID,
89 BL31_ID,
90 BL32_ID,
91 BL33_ID,
92 /* Certificate file names (outputs) */
93 BL2_CERT_ID,
94 TRUSTED_KEY_CERT_ID,
95 BL30_KEY_CERT_ID,
96 BL30_CERT_ID,
97 BL31_KEY_CERT_ID,
98 BL31_CERT_ID,
99 BL32_KEY_CERT_ID,
100 BL32_CERT_ID,
101 BL33_KEY_CERT_ID,
102 BL33_CERT_ID,
103 /* Key file names (input/output) */
104 ROT_KEY_ID,
105 TRUSTED_WORLD_KEY_ID,
106 NON_TRUSTED_WORLD_KEY_ID,
107 BL30_KEY_ID,
108 BL31_KEY_ID,
109 BL32_KEY_ID,
110 BL33_KEY_ID,
111 NUM_OPTS
112};
113
114/* Global options */
Juan Castillof9f39c32015-06-01 16:34:23 +0100115static int key_alg;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100116static int new_keys;
117static int save_keys;
118static int print_cert;
119static int bl30_present;
120static int bl32_present;
121
Juan Castillo11abdcd2014-10-21 11:30:42 +0100122/* Info messages created in the Makefile */
123extern const char build_msg[];
124extern const char platform_msg[];
125
126
127static char *strdup(const char *str)
128{
129 int n = strlen(str) + 1;
130 char *dup = malloc(n);
131 if (dup) {
132 strcpy(dup, str);
133 }
134 return dup;
135}
136
Juan Castillof9f39c32015-06-01 16:34:23 +0100137static const char *key_algs_str[] = {
138 [KEY_ALG_RSA] = "rsa",
Juan Castilloa2224ab2015-06-30 13:36:57 +0100139#ifndef OPENSSL_NO_EC
Juan Castillof9f39c32015-06-01 16:34:23 +0100140 [KEY_ALG_ECDSA] = "ecdsa"
Juan Castilloa2224ab2015-06-30 13:36:57 +0100141#endif /* OPENSSL_NO_EC */
Juan Castillof9f39c32015-06-01 16:34:23 +0100142};
143
Juan Castillo11abdcd2014-10-21 11:30:42 +0100144/* Command line options */
145static const struct option long_opt[] = {
146 /* Binary images */
147 {"bl2", required_argument, 0, BL2_ID},
148 {"bl30", required_argument, 0, BL30_ID},
149 {"bl31", required_argument, 0, BL31_ID},
150 {"bl32", required_argument, 0, BL32_ID},
151 {"bl33", required_argument, 0, BL33_ID},
152 /* Certificate files */
153 {"bl2-cert", required_argument, 0, BL2_CERT_ID},
154 {"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
155 {"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
156 {"bl30-cert", required_argument, 0, BL30_CERT_ID},
157 {"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
158 {"bl31-cert", required_argument, 0, BL31_CERT_ID},
159 {"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
160 {"bl32-cert", required_argument, 0, BL32_CERT_ID},
161 {"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
162 {"bl33-cert", required_argument, 0, BL33_CERT_ID},
163 /* Private key files */
164 {"rot-key", required_argument, 0, ROT_KEY_ID},
165 {"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
166 {"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
167 {"bl30-key", required_argument, 0, BL30_KEY_ID},
168 {"bl31-key", required_argument, 0, BL31_KEY_ID},
169 {"bl32-key", required_argument, 0, BL32_KEY_ID},
170 {"bl33-key", required_argument, 0, BL33_KEY_ID},
171 /* Common options */
Juan Castillof9f39c32015-06-01 16:34:23 +0100172 {"key-alg", required_argument, 0, 'a'},
Juan Castillo11abdcd2014-10-21 11:30:42 +0100173 {"help", no_argument, 0, 'h'},
174 {"save-keys", no_argument, 0, 'k'},
175 {"new-chain", no_argument, 0, 'n'},
176 {"print-cert", no_argument, 0, 'p'},
177 {0, 0, 0, 0}
178};
179
180static void print_help(const char *cmd)
181{
182 int i = 0;
183 printf("\n\n");
184 printf("The certificate generation tool loads the binary images and\n"
185 "optionally the RSA keys, and outputs the key and content\n"
186 "certificates properly signed to implement the chain of trust.\n"
187 "If keys are provided, they must be in PEM format.\n"
188 "Certificates are generated in DER format.\n");
189 printf("\n");
190 printf("Usage:\n\n");
191 printf(" %s [-hknp] \\\n", cmd);
192 for (i = 0; i < NUM_OPTS; i++) {
193 printf(" --%s <file> \\\n", long_opt[i].name);
194 }
195 printf("\n");
Juan Castillof9f39c32015-06-01 16:34:23 +0100196 printf("-a Key algorithm: rsa (default), ecdsa\n");
Juan Castillo11abdcd2014-10-21 11:30:42 +0100197 printf("-h Print help and exit\n");
198 printf("-k Save key pairs into files. Filenames must be provided\n");
199 printf("-n Generate new key pairs if no key files are provided\n");
200 printf("-p Print the certificates in the standard output\n");
201 printf("\n");
202
203 exit(0);
204}
205
Juan Castillof9f39c32015-06-01 16:34:23 +0100206static int get_key_alg(const char *key_alg_str)
207{
208 int i;
209
210 for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
211 if (0 == strcmp(key_alg_str, key_algs_str[i])) {
212 return i;
213 }
214 }
215
216 return -1;
217}
218
Juan Castillo11abdcd2014-10-21 11:30:42 +0100219static void check_cmd_params(void)
220{
Juan Castillof9f39c32015-06-01 16:34:23 +0100221 /* Only save new keys */
222 if (save_keys && !new_keys) {
223 ERROR("Only new keys can be saved to disk\n");
224 exit(1);
225 }
226
Juan Castillo11abdcd2014-10-21 11:30:42 +0100227 /* BL2, BL31 and BL33 are mandatory */
Juan Castilloe6d30e92015-06-12 11:27:59 +0100228 if (extensions[BL2_HASH_EXT].data.fn == NULL) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100229 ERROR("BL2 image not specified\n");
230 exit(1);
231 }
232
Juan Castilloe6d30e92015-06-12 11:27:59 +0100233 if (extensions[BL31_HASH_EXT].data.fn == NULL) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100234 ERROR("BL31 image not specified\n");
235 exit(1);
236 }
237
Juan Castilloe6d30e92015-06-12 11:27:59 +0100238 if (extensions[BL33_HASH_EXT].data.fn == NULL) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100239 ERROR("BL33 image not specified\n");
240 exit(1);
241 }
242
243 /* BL30 and BL32 are optional */
Juan Castilloe6d30e92015-06-12 11:27:59 +0100244 if (extensions[BL30_HASH_EXT].data.fn != NULL) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100245 bl30_present = 1;
246 }
247
Juan Castilloe6d30e92015-06-12 11:27:59 +0100248 if (extensions[BL32_HASH_EXT].data.fn != NULL) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100249 bl32_present = 1;
250 }
251
252 /* TODO: Certificate filenames */
253
254 /* Filenames to store keys must be specified */
255 if (save_keys || !new_keys) {
256 if (keys[ROT_KEY].fn == NULL) {
257 ERROR("ROT key not specified\n");
258 exit(1);
259 }
260
261 if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
262 ERROR("Trusted World key not specified\n");
263 exit(1);
264 }
265
266 if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
267 ERROR("Non-trusted World key not specified\n");
268 exit(1);
269 }
270
271 if (keys[BL31_KEY].fn == NULL) {
272 ERROR("BL31 key not specified\n");
273 exit(1);
274 }
275
276 if (keys[BL33_KEY].fn == NULL) {
277 ERROR("BL33 key not specified\n");
278 exit(1);
279 }
280
281 if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
282 ERROR("BL30 key not specified\n");
283 exit(1);
284 }
285
286 if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
287 ERROR("BL32 key not specified\n");
288 exit(1);
289 }
290 }
291}
292
293int main(int argc, char *argv[])
294{
295 STACK_OF(X509_EXTENSION) * sk = NULL;
Juan Castilloe6d30e92015-06-12 11:27:59 +0100296 X509_EXTENSION *cert_ext = NULL;
297 ext_t *ext = NULL;
298 cert_t *cert;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100299 FILE *file = NULL;
Juan Castilloe6d30e92015-06-12 11:27:59 +0100300 int i, j, ext_nid;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100301 int c, opt_idx = 0;
Juan Castillof9f39c32015-06-01 16:34:23 +0100302 unsigned int err_code;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100303 unsigned char md[SHA256_DIGEST_LENGTH];
Juan Castilloac402932015-03-05 14:30:00 +0000304 const EVP_MD *md_info;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100305
306 NOTICE("CoT Generation Tool: %s\n", build_msg);
307 NOTICE("Target platform: %s\n", platform_msg);
308
Juan Castillof9f39c32015-06-01 16:34:23 +0100309 /* Set default options */
310 key_alg = KEY_ALG_RSA;
311
Juan Castillo11abdcd2014-10-21 11:30:42 +0100312 while (1) {
313 /* getopt_long stores the option index here. */
Juan Castillof9f39c32015-06-01 16:34:23 +0100314 c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100315
316 /* Detect the end of the options. */
317 if (c == -1) {
318 break;
319 }
320
321 switch (c) {
Juan Castillof9f39c32015-06-01 16:34:23 +0100322 case 'a':
323 key_alg = get_key_alg(optarg);
324 if (key_alg < 0) {
325 ERROR("Invalid key algorithm '%s'\n", optarg);
326 exit(1);
327 }
328 break;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100329 case 'h':
330 print_help(argv[0]);
331 break;
332 case 'k':
333 save_keys = 1;
334 break;
335 case 'n':
336 new_keys = 1;
337 break;
338 case 'p':
339 print_cert = 1;
340 break;
341 case BL2_ID:
Juan Castilloe6d30e92015-06-12 11:27:59 +0100342 extensions[BL2_HASH_EXT].data.fn = strdup(optarg);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100343 break;
344 case BL30_ID:
Juan Castilloe6d30e92015-06-12 11:27:59 +0100345 extensions[BL30_HASH_EXT].data.fn = strdup(optarg);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100346 break;
347 case BL31_ID:
Juan Castilloe6d30e92015-06-12 11:27:59 +0100348 extensions[BL31_HASH_EXT].data.fn = strdup(optarg);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100349 break;
350 case BL32_ID:
Juan Castilloe6d30e92015-06-12 11:27:59 +0100351 extensions[BL32_HASH_EXT].data.fn = strdup(optarg);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100352 break;
353 case BL33_ID:
Juan Castilloe6d30e92015-06-12 11:27:59 +0100354 extensions[BL33_HASH_EXT].data.fn = strdup(optarg);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100355 break;
356 case BL2_CERT_ID:
357 certs[BL2_CERT].fn = strdup(optarg);
358 break;
359 case TRUSTED_KEY_CERT_ID:
360 certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
361 break;
362 case BL30_KEY_CERT_ID:
363 certs[BL30_KEY_CERT].fn = strdup(optarg);
364 break;
365 case BL30_CERT_ID:
366 certs[BL30_CERT].fn = strdup(optarg);
367 break;
368 case BL31_KEY_CERT_ID:
369 certs[BL31_KEY_CERT].fn = strdup(optarg);
370 break;
371 case BL31_CERT_ID:
372 certs[BL31_CERT].fn = strdup(optarg);
373 break;
374 case BL32_KEY_CERT_ID:
375 certs[BL32_KEY_CERT].fn = strdup(optarg);
376 break;
377 case BL32_CERT_ID:
378 certs[BL32_CERT].fn = strdup(optarg);
379 break;
380 case BL33_KEY_CERT_ID:
381 certs[BL33_KEY_CERT].fn = strdup(optarg);
382 break;
383 case BL33_CERT_ID:
384 certs[BL33_CERT].fn = strdup(optarg);
385 break;
386 case ROT_KEY_ID:
387 keys[ROT_KEY].fn = strdup(optarg);
388 break;
389 case TRUSTED_WORLD_KEY_ID:
390 keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
391 break;
392 case NON_TRUSTED_WORLD_KEY_ID:
393 keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
394 break;
395 case BL30_KEY_ID:
396 keys[BL30_KEY].fn = strdup(optarg);
397 break;
398 case BL31_KEY_ID:
399 keys[BL31_KEY].fn = strdup(optarg);
400 break;
401 case BL32_KEY_ID:
402 keys[BL32_KEY].fn = strdup(optarg);
403 break;
404 case BL33_KEY_ID:
405 keys[BL33_KEY].fn = strdup(optarg);
406 break;
407 case '?':
408 default:
409 printf("%s\n", optarg);
410 exit(1);
411 }
412 }
413
Juan Castillo11abdcd2014-10-21 11:30:42 +0100414 /* Check command line arguments */
415 check_cmd_params();
416
417 /* Register the new types and OIDs for the extensions */
Juan Castilloe6d30e92015-06-12 11:27:59 +0100418 if (ext_register(extensions) != 0) {
419 ERROR("Cannot register TBB extensions\n");
Juan Castillo11abdcd2014-10-21 11:30:42 +0100420 exit(1);
421 }
422
Juan Castilloac402932015-03-05 14:30:00 +0000423 /* Indicate SHA256 as image hash algorithm in the certificate
424 * extension */
425 md_info = EVP_sha256();
426
Juan Castillo11abdcd2014-10-21 11:30:42 +0100427 /* Load private keys from files (or generate new ones) */
Juan Castilloe6d30e92015-06-12 11:27:59 +0100428 for (i = 0 ; i < num_keys ; i++) {
Juan Castillof9f39c32015-06-01 16:34:23 +0100429 /* First try to load the key from disk */
430 if (key_load(&keys[i], &err_code)) {
431 /* Key loaded successfully */
432 continue;
433 }
434
435 /* Key not loaded. Check the error code */
436 if (err_code == KEY_ERR_MALLOC) {
437 /* Cannot allocate memory. Abort. */
438 ERROR("Malloc error while loading '%s'\n", keys[i].fn);
439 exit(1);
440 } else if (err_code == KEY_ERR_LOAD) {
441 /* File exists, but it does not contain a valid private
442 * key. Abort. */
443 ERROR("Error loading '%s'\n", keys[i].fn);
444 exit(1);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100445 }
Juan Castillof9f39c32015-06-01 16:34:23 +0100446
447 /* File does not exist, could not be opened or no filename was
448 * given */
449 if (new_keys) {
450 /* Try to create a new key */
451 NOTICE("Creating new key for '%s'\n", keys[i].desc);
452 if (!key_create(&keys[i], key_alg)) {
453 ERROR("Error creating key '%s'\n", keys[i].desc);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100454 exit(1);
455 }
Juan Castillof9f39c32015-06-01 16:34:23 +0100456 } else {
457 if (err_code == KEY_ERR_OPEN) {
458 ERROR("Error opening '%s'\n", keys[i].fn);
459 } else {
460 ERROR("Key '%s' not specified\n", keys[i].desc);
461 }
462 exit(1);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100463 }
464 }
Juan Castillo11abdcd2014-10-21 11:30:42 +0100465
Juan Castilloe6d30e92015-06-12 11:27:59 +0100466 /* Create the certificates */
467 for (i = 0 ; i < num_certs ; i++) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100468
Juan Castilloe6d30e92015-06-12 11:27:59 +0100469 cert = &certs[i];
Juan Castillo11abdcd2014-10-21 11:30:42 +0100470
Juan Castilloe6d30e92015-06-12 11:27:59 +0100471 /* Create a new stack of extensions. This stack will be used
472 * to create the certificate */
Juan Castillo11abdcd2014-10-21 11:30:42 +0100473 CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
Juan Castillo11abdcd2014-10-21 11:30:42 +0100474
Juan Castilloe6d30e92015-06-12 11:27:59 +0100475 for (j = 0 ; j < cert->num_ext ; j++) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100476
Juan Castilloe6d30e92015-06-12 11:27:59 +0100477 ext = &extensions[cert->ext[j]];
Juan Castillo11abdcd2014-10-21 11:30:42 +0100478
Juan Castilloe6d30e92015-06-12 11:27:59 +0100479 /* Get OpenSSL internal ID for this extension */
480 CHECK_OID(ext_nid, ext->oid);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100481
Juan Castilloe6d30e92015-06-12 11:27:59 +0100482 /*
483 * Three types of extensions are currently supported:
484 * - EXT_TYPE_NVCOUNTER
485 * - EXT_TYPE_HASH
486 * - EXT_TYPE_PKEY
487 */
488 switch (ext->type) {
489 case EXT_TYPE_NVCOUNTER:
490 CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid,
491 EXT_CRIT, ext->data.nvcounter));
492 break;
493 case EXT_TYPE_HASH:
494 if (ext->data.fn == NULL) {
495 break;
496 }
497 if (!sha_file(ext->data.fn, md)) {
498 ERROR("Cannot calculate hash of %s\n",
499 ext->data.fn);
500 exit(1);
501 }
502 CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
503 EXT_CRIT, md_info, md,
504 SHA256_DIGEST_LENGTH));
505 break;
506 case EXT_TYPE_PKEY:
507 CHECK_NULL(cert_ext, ext_new_key(ext_nid,
508 EXT_CRIT, keys[ext->data.key].key));
509 break;
510 default:
511 ERROR("Unknown extension type in %s\n",
512 cert->cn);
513 exit(1);
514 }
Juan Castillo11abdcd2014-10-21 11:30:42 +0100515
Juan Castilloe6d30e92015-06-12 11:27:59 +0100516 /* Push the extension into the stack */
517 sk_X509_EXTENSION_push(sk, cert_ext);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100518 }
Juan Castillo11abdcd2014-10-21 11:30:42 +0100519
Juan Castilloe6d30e92015-06-12 11:27:59 +0100520 /* Create certificate. Signed with ROT key */
521 if (!cert_new(cert, VAL_DAYS, 0, sk)) {
522 ERROR("Cannot create %s\n", cert->cn);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100523 exit(1);
524 }
525
526 sk_X509_EXTENSION_free(sk);
527 }
528
Juan Castillo11abdcd2014-10-21 11:30:42 +0100529
530 /* Print the certificates */
531 if (print_cert) {
Juan Castilloe6d30e92015-06-12 11:27:59 +0100532 for (i = 0 ; i < num_certs ; i++) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100533 if (!certs[i].x) {
534 continue;
535 }
536 printf("\n\n=====================================\n\n");
537 X509_print_fp(stdout, certs[i].x);
538 }
539 }
540
541 /* Save created certificates to files */
Juan Castilloe6d30e92015-06-12 11:27:59 +0100542 for (i = 0 ; i < num_certs ; i++) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100543 if (certs[i].x && certs[i].fn) {
544 file = fopen(certs[i].fn, "w");
545 if (file != NULL) {
546 i2d_X509_fp(file, certs[i].x);
547 fclose(file);
548 } else {
549 ERROR("Cannot create file %s\n", certs[i].fn);
550 }
551 }
552 }
553
554 /* Save keys */
555 if (save_keys) {
Juan Castilloe6d30e92015-06-12 11:27:59 +0100556 for (i = 0 ; i < num_keys ; i++) {
Juan Castillo11abdcd2014-10-21 11:30:42 +0100557 if (!key_store(&keys[i])) {
558 ERROR("Cannot save %s\n", keys[i].desc);
559 }
560 }
561 }
562
Juan Castillo11abdcd2014-10-21 11:30:42 +0100563#ifndef OPENSSL_NO_ENGINE
564 ENGINE_cleanup();
565#endif
566 CRYPTO_cleanup_all_ex_data();
567
568 return 0;
569}