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 #define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
9 
10 #include "mbedtls/build_info.h"
11 
12 #include "mbedtls/platform.h"
13 
14 #if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) ||  \
15     !defined(MBEDTLS_TIMING_C)
main(void)16 int main(void)
17 {
18     mbedtls_printf("MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_FS_IO and/or "
19                    "MBEDTLS_TIMING_C not defined.\n");
20     mbedtls_exit(0);
21 }
22 #else
23 
24 #include "mbedtls/error.h"
25 #include "mbedtls/timing.h"
26 #include "mbedtls/x509_crt.h"
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #define DFL_ITERATIONS          1
33 #define DFL_PRIME_CACHE         1
34 
35 #define USAGE \
36     "\n usage: load_roots param=<>... [--] FILE...\n"   \
37     "\n acceptable parameters:\n"                       \
38     "    iterations=%%d        Iteration count (not including cache priming); default: 1\n"  \
39     "    prime=%%d             Prime the disk read cache? Default: 1 (yes)\n"  \
40     "\n"
41 
42 
43 /*
44  * global options
45  */
46 struct options {
47     const char **filenames;     /* NULL-terminated list of file names */
48     unsigned iterations;        /* Number of iterations to time */
49     int prime_cache;            /* Prime the disk read cache? */
50 } opt;
51 
52 
read_certificates(const char * const * filenames)53 static int read_certificates(const char *const *filenames)
54 {
55     mbedtls_x509_crt cas;
56     int ret = 0;
57     const char *const *cur;
58 
59     mbedtls_x509_crt_init(&cas);
60 
61     for (cur = filenames; *cur != NULL; cur++) {
62         ret = mbedtls_x509_crt_parse_file(&cas, *cur);
63         if (ret != 0) {
64 #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
65             char error_message[200];
66             mbedtls_strerror(ret, error_message, sizeof(error_message));
67             printf("\n%s: -0x%04x (%s)\n",
68                    *cur, (unsigned) -ret, error_message);
69 #else
70             printf("\n%s: -0x%04x\n",
71                    *cur, (unsigned) -ret);
72 #endif
73             goto exit;
74         }
75     }
76 
77 exit:
78     mbedtls_x509_crt_free(&cas);
79     return ret == 0;
80 }
81 
main(int argc,char * argv[])82 int main(int argc, char *argv[])
83 {
84     int exit_code = MBEDTLS_EXIT_FAILURE;
85     unsigned i, j;
86     struct mbedtls_timing_hr_time timer;
87     unsigned long ms;
88 
89     psa_status_t status = psa_crypto_init();
90     if (status != PSA_SUCCESS) {
91         mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
92                         (int) status);
93         goto exit;
94     }
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 
159 exit:
160     mbedtls_psa_crypto_free();
161     mbedtls_exit(exit_code);
162 }
163 #endif /* necessary configuration */
164