xref: /openssl/test/timing_load_creds.c (revision 45479dce)
1 /*
2  * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #ifndef _WIN32
14 # include <sys/stat.h>
15 # include <openssl/pem.h>
16 # include <openssl/x509.h>
17 # include <openssl/err.h>
18 # include <openssl/bio.h>
19 # include <../include/internal/e_os.h>
20 # if defined(OPENSSL_SYS_UNIX)
21 #  include <sys/resource.h>
22 # endif
23 
24 static char *prog;
25 
readx509(const char * contents,int size)26 static void readx509(const char *contents, int size)
27 {
28     X509 *x = NULL;
29     BIO *b = BIO_new_mem_buf(contents, size);
30 
31     if (b == NULL) {
32         ERR_print_errors_fp(stderr);
33         exit(EXIT_FAILURE);
34     }
35     PEM_read_bio_X509(b, &x, 0, NULL);
36     if (x == NULL) {
37         ERR_print_errors_fp(stderr);
38         exit(EXIT_FAILURE);
39     }
40     X509_free(x);
41     BIO_free(b);
42 }
43 
readpkey(const char * contents,int size)44 static void readpkey(const char *contents, int size)
45 {
46     BIO *b = BIO_new_mem_buf(contents, size);
47     EVP_PKEY *pkey;
48 
49     if (b == NULL) {
50         ERR_print_errors_fp(stderr);
51         exit(EXIT_FAILURE);
52     }
53     pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
54     if (pkey == NULL) {
55         ERR_print_errors_fp(stderr);
56         exit(EXIT_FAILURE);
57     }
58 
59     EVP_PKEY_free(pkey);
60     BIO_free(b);
61 }
62 
print_timeval(const char * what,struct timeval * tp)63 static void print_timeval(const char *what, struct timeval *tp)
64 {
65     printf("%s %d sec %d microsec\n", what, (int)tp->tv_sec, (int)tp->tv_usec);
66 }
67 
usage(void)68 static void usage(void)
69 {
70     fprintf(stderr, "Usage: %s [flags] pem-file\n", prog);
71     fprintf(stderr, "Flags, with the default being '-wc':\n");
72     fprintf(stderr, "  -c #  Repeat count\n");
73     fprintf(stderr, "  -d    Debugging output (minimal)\n");
74     fprintf(stderr, "  -w<T> What to load T is a single character:\n");
75     fprintf(stderr, "          c for cert\n");
76     fprintf(stderr, "          p for private key\n");
77     exit(EXIT_FAILURE);
78 }
79 #endif
80 
main(int ac,char ** av)81 int main(int ac, char **av)
82 {
83 #ifndef _WIN32
84     int i, debug = 0, count = 100, what = 'c';
85     struct stat sb;
86     FILE *fp;
87     char *contents;
88     struct rusage start, end, elapsed;
89     struct timeval e_start, e_end, e_elapsed;
90 
91     /* Parse JCL. */
92     prog = av[0];
93     while ((i = getopt(ac, av, "c:dw:")) != EOF) {
94         switch (i) {
95         default:
96             usage();
97             break;
98         case 'c':
99             if ((count = atoi(optarg)) < 0)
100                 usage();
101             break;
102         case 'd':
103             debug = 1;
104             break;
105         case 'w':
106             if (optarg[1] != '\0')
107                 usage();
108             switch (*optarg) {
109             default:
110                 usage();
111                 break;
112             case 'c':
113             case 'p':
114                 what = *optarg;
115                 break;
116             }
117             break;
118         }
119     }
120     ac -= optind;
121     av += optind;
122 
123     /* Read input file. */
124     if (av[0] == NULL)
125         usage();
126     if (stat(av[0], &sb) < 0) {
127         perror(av[0]);
128         exit(EXIT_FAILURE);
129     }
130     contents = OPENSSL_malloc(sb.st_size + 1);
131     if (contents == NULL) {
132         perror("malloc");
133         exit(EXIT_FAILURE);
134     }
135     fp = fopen(av[0], "r");
136     if ((long)fread(contents, 1, sb.st_size, fp) != sb.st_size) {
137         perror("fread");
138         exit(EXIT_FAILURE);
139     }
140     contents[sb.st_size] = '\0';
141     fclose(fp);
142     if (debug)
143         printf(">%s<\n", contents);
144 
145     /* Try to prep system cache, etc. */
146     for (i = 10; i > 0; i--) {
147         switch (what) {
148         case 'c':
149             readx509(contents, (int)sb.st_size);
150             break;
151         case 'p':
152             readpkey(contents, (int)sb.st_size);
153             break;
154         }
155     }
156 
157     if (gettimeofday(&e_start, NULL) < 0) {
158         perror("elapsed start");
159         exit(EXIT_FAILURE);
160     }
161     if (getrusage(RUSAGE_SELF, &start) < 0) {
162         perror("start");
163         exit(EXIT_FAILURE);
164     }
165     for (i = count; i > 0; i--) {
166         switch (what) {
167         case 'c':
168             readx509(contents, (int)sb.st_size);
169             break;
170         case 'p':
171             readpkey(contents, (int)sb.st_size);
172             break;
173         }
174     }
175     if (getrusage(RUSAGE_SELF, &end) < 0) {
176         perror("getrusage");
177         exit(EXIT_FAILURE);
178     }
179     if (gettimeofday(&e_end, NULL) < 0) {
180         perror("gettimeofday");
181         exit(EXIT_FAILURE);
182     }
183 
184     timersub(&end.ru_utime, &start.ru_stime, &elapsed.ru_stime);
185     timersub(&end.ru_utime, &start.ru_utime, &elapsed.ru_utime);
186     timersub(&e_end, &e_start, &e_elapsed);
187     print_timeval("user     ", &elapsed.ru_utime);
188     print_timeval("sys      ", &elapsed.ru_stime);
189     if (debug)
190         print_timeval("elapsed??", &e_elapsed);
191 
192     OPENSSL_free(contents);
193     return EXIT_SUCCESS;
194 #else
195     fprintf(stderr, "This tool is not supported on Windows\n");
196     exit(EXIT_FAILURE);
197 #endif
198 }
199