timing_load_creds.c 5.8 KB

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