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 | #include <openssl/e_os2.h>
|
---|
14 |
|
---|
15 | #ifdef OPENSSL_SYS_UNIX
|
---|
16 | # include <sys/stat.h>
|
---|
17 | # include <sys/resource.h>
|
---|
18 | # include <openssl/pem.h>
|
---|
19 | # include <openssl/x509.h>
|
---|
20 | # include <openssl/err.h>
|
---|
21 | # include <openssl/bio.h>
|
---|
22 | # include "internal/e_os.h"
|
---|
23 | # if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
|
---|
24 |
|
---|
25 | # ifndef timersub
|
---|
26 | /* struct timeval * subtraction; a must be greater than or equal to b */
|
---|
27 | # define timersub(a, b, res) \
|
---|
28 | do { \
|
---|
29 | (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
---|
30 | if ((a)->tv_usec < (b)->tv_usec) { \
|
---|
31 | (res)->tv_usec = (a)->tv_usec + 1000000 - (b)->tv_usec; \
|
---|
32 | --(res)->tv_sec; \
|
---|
33 | } else { \
|
---|
34 | (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
---|
35 | } \
|
---|
36 | } while(0)
|
---|
37 | # endif
|
---|
38 |
|
---|
39 | static char *prog;
|
---|
40 |
|
---|
41 | static void readx509(const char *contents, int size)
|
---|
42 | {
|
---|
43 | X509 *x = NULL;
|
---|
44 | BIO *b = BIO_new_mem_buf(contents, size);
|
---|
45 |
|
---|
46 | if (b == NULL) {
|
---|
47 | ERR_print_errors_fp(stderr);
|
---|
48 | exit(EXIT_FAILURE);
|
---|
49 | }
|
---|
50 | PEM_read_bio_X509(b, &x, 0, NULL);
|
---|
51 | if (x == NULL) {
|
---|
52 | ERR_print_errors_fp(stderr);
|
---|
53 | exit(EXIT_FAILURE);
|
---|
54 | }
|
---|
55 | X509_free(x);
|
---|
56 | BIO_free(b);
|
---|
57 | }
|
---|
58 |
|
---|
59 | static void readpkey(const char *contents, int size)
|
---|
60 | {
|
---|
61 | BIO *b = BIO_new_mem_buf(contents, size);
|
---|
62 | EVP_PKEY *pkey;
|
---|
63 |
|
---|
64 | if (b == NULL) {
|
---|
65 | ERR_print_errors_fp(stderr);
|
---|
66 | exit(EXIT_FAILURE);
|
---|
67 | }
|
---|
68 | pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
|
---|
69 | if (pkey == NULL) {
|
---|
70 | ERR_print_errors_fp(stderr);
|
---|
71 | exit(EXIT_FAILURE);
|
---|
72 | }
|
---|
73 |
|
---|
74 | EVP_PKEY_free(pkey);
|
---|
75 | BIO_free(b);
|
---|
76 | }
|
---|
77 |
|
---|
78 | static void print_timeval(const char *what, struct timeval *tp)
|
---|
79 | {
|
---|
80 | printf("%s %d sec %d microsec\n", what, (int)tp->tv_sec, (int)tp->tv_usec);
|
---|
81 | }
|
---|
82 |
|
---|
83 | static void usage(void)
|
---|
84 | {
|
---|
85 | fprintf(stderr, "Usage: %s [flags] pem-file\n", prog);
|
---|
86 | fprintf(stderr, "Flags, with the default being '-wc':\n");
|
---|
87 | fprintf(stderr, " -c # Repeat count\n");
|
---|
88 | fprintf(stderr, " -d Debugging output (minimal)\n");
|
---|
89 | fprintf(stderr, " -w<T> What to load T is a single character:\n");
|
---|
90 | fprintf(stderr, " c for cert\n");
|
---|
91 | fprintf(stderr, " p for private key\n");
|
---|
92 | exit(EXIT_FAILURE);
|
---|
93 | }
|
---|
94 | # endif
|
---|
95 | #endif
|
---|
96 |
|
---|
97 | int main(int ac, char **av)
|
---|
98 | {
|
---|
99 | #if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
|
---|
100 | int i, debug = 0, count = 100, what = 'c';
|
---|
101 | struct stat sb;
|
---|
102 | FILE *fp;
|
---|
103 | char *contents;
|
---|
104 | struct rusage start, end, elapsed;
|
---|
105 | struct timeval e_start, e_end, e_elapsed;
|
---|
106 |
|
---|
107 | /* Parse JCL. */
|
---|
108 | prog = av[0];
|
---|
109 | while ((i = getopt(ac, av, "c:dw:")) != EOF) {
|
---|
110 | switch (i) {
|
---|
111 | default:
|
---|
112 | usage();
|
---|
113 | break;
|
---|
114 | case 'c':
|
---|
115 | if ((count = atoi(optarg)) < 0)
|
---|
116 | usage();
|
---|
117 | break;
|
---|
118 | case 'd':
|
---|
119 | debug = 1;
|
---|
120 | break;
|
---|
121 | case 'w':
|
---|
122 | if (optarg[1] != '\0')
|
---|
123 | usage();
|
---|
124 | switch (*optarg) {
|
---|
125 | default:
|
---|
126 | usage();
|
---|
127 | break;
|
---|
128 | case 'c':
|
---|
129 | case 'p':
|
---|
130 | what = *optarg;
|
---|
131 | break;
|
---|
132 | }
|
---|
133 | break;
|
---|
134 | }
|
---|
135 | }
|
---|
136 | ac -= optind;
|
---|
137 | av += optind;
|
---|
138 |
|
---|
139 | /* Read input file. */
|
---|
140 | if (av[0] == NULL)
|
---|
141 | usage();
|
---|
142 | if (stat(av[0], &sb) < 0) {
|
---|
143 | perror(av[0]);
|
---|
144 | exit(EXIT_FAILURE);
|
---|
145 | }
|
---|
146 | contents = OPENSSL_malloc(sb.st_size + 1);
|
---|
147 | if (contents == NULL) {
|
---|
148 | perror("malloc");
|
---|
149 | exit(EXIT_FAILURE);
|
---|
150 | }
|
---|
151 | fp = fopen(av[0], "r");
|
---|
152 | if ((long)fread(contents, 1, sb.st_size, fp) != sb.st_size) {
|
---|
153 | perror("fread");
|
---|
154 | exit(EXIT_FAILURE);
|
---|
155 | }
|
---|
156 | contents[sb.st_size] = '\0';
|
---|
157 | fclose(fp);
|
---|
158 | if (debug)
|
---|
159 | printf(">%s<\n", contents);
|
---|
160 |
|
---|
161 | /* Try to prep system cache, etc. */
|
---|
162 | for (i = 10; i > 0; i--) {
|
---|
163 | switch (what) {
|
---|
164 | case 'c':
|
---|
165 | readx509(contents, (int)sb.st_size);
|
---|
166 | break;
|
---|
167 | case 'p':
|
---|
168 | readpkey(contents, (int)sb.st_size);
|
---|
169 | break;
|
---|
170 | }
|
---|
171 | }
|
---|
172 |
|
---|
173 | if (gettimeofday(&e_start, NULL) < 0) {
|
---|
174 | perror("elapsed start");
|
---|
175 | exit(EXIT_FAILURE);
|
---|
176 | }
|
---|
177 | if (getrusage(RUSAGE_SELF, &start) < 0) {
|
---|
178 | perror("start");
|
---|
179 | exit(EXIT_FAILURE);
|
---|
180 | }
|
---|
181 | for (i = count; i > 0; i--) {
|
---|
182 | switch (what) {
|
---|
183 | case 'c':
|
---|
184 | readx509(contents, (int)sb.st_size);
|
---|
185 | break;
|
---|
186 | case 'p':
|
---|
187 | readpkey(contents, (int)sb.st_size);
|
---|
188 | break;
|
---|
189 | }
|
---|
190 | }
|
---|
191 | if (getrusage(RUSAGE_SELF, &end) < 0) {
|
---|
192 | perror("getrusage");
|
---|
193 | exit(EXIT_FAILURE);
|
---|
194 | }
|
---|
195 | if (gettimeofday(&e_end, NULL) < 0) {
|
---|
196 | perror("gettimeofday");
|
---|
197 | exit(EXIT_FAILURE);
|
---|
198 | }
|
---|
199 |
|
---|
200 | timersub(&end.ru_utime, &start.ru_stime, &elapsed.ru_stime);
|
---|
201 | timersub(&end.ru_utime, &start.ru_utime, &elapsed.ru_utime);
|
---|
202 | timersub(&e_end, &e_start, &e_elapsed);
|
---|
203 | print_timeval("user ", &elapsed.ru_utime);
|
---|
204 | print_timeval("sys ", &elapsed.ru_stime);
|
---|
205 | if (debug)
|
---|
206 | print_timeval("elapsed??", &e_elapsed);
|
---|
207 |
|
---|
208 | OPENSSL_free(contents);
|
---|
209 | return EXIT_SUCCESS;
|
---|
210 | #else
|
---|
211 | fprintf(stderr,
|
---|
212 | "This tool is not supported on this platform for lack of POSIX1.2001 support\n");
|
---|
213 | exit(EXIT_FAILURE);
|
---|
214 | #endif
|
---|
215 | }
|
---|