1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Root CA reading application 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "mbedtls/build_info.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 11a8e1175bSopenharmony_ci 12a8e1175bSopenharmony_ci#if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \ 13a8e1175bSopenharmony_ci !defined(MBEDTLS_TIMING_C) 14a8e1175bSopenharmony_ciint main(void) 15a8e1175bSopenharmony_ci{ 16a8e1175bSopenharmony_ci mbedtls_printf("MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_FS_IO and/or " 17a8e1175bSopenharmony_ci "MBEDTLS_TIMING_C not defined.\n"); 18a8e1175bSopenharmony_ci mbedtls_exit(0); 19a8e1175bSopenharmony_ci} 20a8e1175bSopenharmony_ci#else 21a8e1175bSopenharmony_ci 22a8e1175bSopenharmony_ci#include "mbedtls/error.h" 23a8e1175bSopenharmony_ci#include "mbedtls/timing.h" 24a8e1175bSopenharmony_ci#include "mbedtls/x509_crt.h" 25a8e1175bSopenharmony_ci 26a8e1175bSopenharmony_ci#include <stdio.h> 27a8e1175bSopenharmony_ci#include <stdlib.h> 28a8e1175bSopenharmony_ci#include <string.h> 29a8e1175bSopenharmony_ci 30a8e1175bSopenharmony_ci#define DFL_ITERATIONS 1 31a8e1175bSopenharmony_ci#define DFL_PRIME_CACHE 1 32a8e1175bSopenharmony_ci 33a8e1175bSopenharmony_ci#define USAGE \ 34a8e1175bSopenharmony_ci "\n usage: load_roots param=<>... [--] FILE...\n" \ 35a8e1175bSopenharmony_ci "\n acceptable parameters:\n" \ 36a8e1175bSopenharmony_ci " iterations=%%d Iteration count (not including cache priming); default: 1\n" \ 37a8e1175bSopenharmony_ci " prime=%%d Prime the disk read cache? Default: 1 (yes)\n" \ 38a8e1175bSopenharmony_ci "\n" 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_ci 41a8e1175bSopenharmony_ci/* 42a8e1175bSopenharmony_ci * global options 43a8e1175bSopenharmony_ci */ 44a8e1175bSopenharmony_cistruct options { 45a8e1175bSopenharmony_ci const char **filenames; /* NULL-terminated list of file names */ 46a8e1175bSopenharmony_ci unsigned iterations; /* Number of iterations to time */ 47a8e1175bSopenharmony_ci int prime_cache; /* Prime the disk read cache? */ 48a8e1175bSopenharmony_ci} opt; 49a8e1175bSopenharmony_ci 50a8e1175bSopenharmony_ci 51a8e1175bSopenharmony_ciint read_certificates(const char *const *filenames) 52a8e1175bSopenharmony_ci{ 53a8e1175bSopenharmony_ci mbedtls_x509_crt cas; 54a8e1175bSopenharmony_ci int ret = 0; 55a8e1175bSopenharmony_ci const char *const *cur; 56a8e1175bSopenharmony_ci 57a8e1175bSopenharmony_ci mbedtls_x509_crt_init(&cas); 58a8e1175bSopenharmony_ci 59a8e1175bSopenharmony_ci for (cur = filenames; *cur != NULL; cur++) { 60a8e1175bSopenharmony_ci ret = mbedtls_x509_crt_parse_file(&cas, *cur); 61a8e1175bSopenharmony_ci if (ret != 0) { 62a8e1175bSopenharmony_ci#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) 63a8e1175bSopenharmony_ci char error_message[200]; 64a8e1175bSopenharmony_ci mbedtls_strerror(ret, error_message, sizeof(error_message)); 65a8e1175bSopenharmony_ci printf("\n%s: -0x%04x (%s)\n", 66a8e1175bSopenharmony_ci *cur, (unsigned) -ret, error_message); 67a8e1175bSopenharmony_ci#else 68a8e1175bSopenharmony_ci printf("\n%s: -0x%04x\n", 69a8e1175bSopenharmony_ci *cur, (unsigned) -ret); 70a8e1175bSopenharmony_ci#endif 71a8e1175bSopenharmony_ci goto exit; 72a8e1175bSopenharmony_ci } 73a8e1175bSopenharmony_ci } 74a8e1175bSopenharmony_ci 75a8e1175bSopenharmony_ciexit: 76a8e1175bSopenharmony_ci mbedtls_x509_crt_free(&cas); 77a8e1175bSopenharmony_ci return ret == 0; 78a8e1175bSopenharmony_ci} 79a8e1175bSopenharmony_ci 80a8e1175bSopenharmony_ciint main(int argc, char *argv[]) 81a8e1175bSopenharmony_ci{ 82a8e1175bSopenharmony_ci int exit_code = MBEDTLS_EXIT_FAILURE; 83a8e1175bSopenharmony_ci unsigned i, j; 84a8e1175bSopenharmony_ci struct mbedtls_timing_hr_time timer; 85a8e1175bSopenharmony_ci unsigned long ms; 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 88a8e1175bSopenharmony_ci psa_status_t status = psa_crypto_init(); 89a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 90a8e1175bSopenharmony_ci mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n", 91a8e1175bSopenharmony_ci (int) status); 92a8e1175bSopenharmony_ci goto exit; 93a8e1175bSopenharmony_ci } 94a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 95a8e1175bSopenharmony_ci 96a8e1175bSopenharmony_ci if (argc <= 1) { 97a8e1175bSopenharmony_ci mbedtls_printf(USAGE); 98a8e1175bSopenharmony_ci goto exit; 99a8e1175bSopenharmony_ci } 100a8e1175bSopenharmony_ci 101a8e1175bSopenharmony_ci opt.filenames = NULL; 102a8e1175bSopenharmony_ci opt.iterations = DFL_ITERATIONS; 103a8e1175bSopenharmony_ci opt.prime_cache = DFL_PRIME_CACHE; 104a8e1175bSopenharmony_ci 105a8e1175bSopenharmony_ci for (i = 1; i < (unsigned) argc; i++) { 106a8e1175bSopenharmony_ci char *p = argv[i]; 107a8e1175bSopenharmony_ci char *q = NULL; 108a8e1175bSopenharmony_ci 109a8e1175bSopenharmony_ci if (strcmp(p, "--") == 0) { 110a8e1175bSopenharmony_ci break; 111a8e1175bSopenharmony_ci } 112a8e1175bSopenharmony_ci if ((q = strchr(p, '=')) == NULL) { 113a8e1175bSopenharmony_ci break; 114a8e1175bSopenharmony_ci } 115a8e1175bSopenharmony_ci *q++ = '\0'; 116a8e1175bSopenharmony_ci 117a8e1175bSopenharmony_ci for (j = 0; p + j < q; j++) { 118a8e1175bSopenharmony_ci if (argv[i][j] >= 'A' && argv[i][j] <= 'Z') { 119a8e1175bSopenharmony_ci argv[i][j] |= 0x20; 120a8e1175bSopenharmony_ci } 121a8e1175bSopenharmony_ci } 122a8e1175bSopenharmony_ci 123a8e1175bSopenharmony_ci if (strcmp(p, "iterations") == 0) { 124a8e1175bSopenharmony_ci opt.iterations = atoi(q); 125a8e1175bSopenharmony_ci } else if (strcmp(p, "prime") == 0) { 126a8e1175bSopenharmony_ci opt.iterations = atoi(q) != 0; 127a8e1175bSopenharmony_ci } else { 128a8e1175bSopenharmony_ci mbedtls_printf("Unknown option: %s\n", p); 129a8e1175bSopenharmony_ci mbedtls_printf(USAGE); 130a8e1175bSopenharmony_ci goto exit; 131a8e1175bSopenharmony_ci } 132a8e1175bSopenharmony_ci } 133a8e1175bSopenharmony_ci 134a8e1175bSopenharmony_ci opt.filenames = (const char **) argv + i; 135a8e1175bSopenharmony_ci if (*opt.filenames == 0) { 136a8e1175bSopenharmony_ci mbedtls_printf("Missing list of certificate files to parse\n"); 137a8e1175bSopenharmony_ci goto exit; 138a8e1175bSopenharmony_ci } 139a8e1175bSopenharmony_ci 140a8e1175bSopenharmony_ci mbedtls_printf("Parsing %u certificates", argc - i); 141a8e1175bSopenharmony_ci if (opt.prime_cache) { 142a8e1175bSopenharmony_ci if (!read_certificates(opt.filenames)) { 143a8e1175bSopenharmony_ci goto exit; 144a8e1175bSopenharmony_ci } 145a8e1175bSopenharmony_ci mbedtls_printf(" "); 146a8e1175bSopenharmony_ci } 147a8e1175bSopenharmony_ci 148a8e1175bSopenharmony_ci (void) mbedtls_timing_get_timer(&timer, 1); 149a8e1175bSopenharmony_ci for (i = 1; i <= opt.iterations; i++) { 150a8e1175bSopenharmony_ci if (!read_certificates(opt.filenames)) { 151a8e1175bSopenharmony_ci goto exit; 152a8e1175bSopenharmony_ci } 153a8e1175bSopenharmony_ci mbedtls_printf("."); 154a8e1175bSopenharmony_ci } 155a8e1175bSopenharmony_ci ms = mbedtls_timing_get_timer(&timer, 0); 156a8e1175bSopenharmony_ci mbedtls_printf("\n%u iterations -> %lu ms\n", opt.iterations, ms); 157a8e1175bSopenharmony_ci exit_code = MBEDTLS_EXIT_SUCCESS; 158a8e1175bSopenharmony_ci 159a8e1175bSopenharmony_ciexit: 160a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 161a8e1175bSopenharmony_ci mbedtls_psa_crypto_free(); 162a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 163a8e1175bSopenharmony_ci mbedtls_exit(exit_code); 164a8e1175bSopenharmony_ci} 165a8e1175bSopenharmony_ci#endif /* necessary configuration */ 166