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