s_time.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.]
  56. */
  57. #define NO_SHUTDOWN
  58. /* ----------------------------------------
  59. s_time - SSL client connection timer program
  60. Written and donated by Larry Streepy <streepy@healthcare.com>
  61. -----------------------------------------*/
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include <string.h>
  65. #define USE_SOCKETS
  66. #include "apps.h"
  67. #include <openssl/x509.h>
  68. #include <openssl/ssl.h>
  69. #include <openssl/pem.h>
  70. #include "s_apps.h"
  71. #include <openssl/err.h>
  72. #if !defined(OPENSSL_SYS_MSDOS)
  73. # include OPENSSL_UNISTD
  74. #endif
  75. #undef ioctl
  76. #define ioctl ioctlsocket
  77. #define SSL_CONNECT_NAME "localhost:4433"
  78. /* no default cert. */
  79. /*
  80. * #define TEST_CERT "client.pem"
  81. */
  82. #undef BUFSIZZ
  83. #define BUFSIZZ 1024*10
  84. #define MYBUFSIZ 1024*8
  85. #undef min
  86. #undef max
  87. #define min(a,b) (((a) < (b)) ? (a) : (b))
  88. #define max(a,b) (((a) > (b)) ? (a) : (b))
  89. #undef SECONDS
  90. #define SECONDS 30
  91. #define SECONDSSTR "30"
  92. extern int verify_depth;
  93. extern int verify_error;
  94. static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx);
  95. typedef enum OPTION_choice {
  96. OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
  97. OPT_CONNECT, OPT_CIPHER, OPT_CERT, OPT_KEY, OPT_CAPATH,
  98. OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, OPT_BUGS,
  99. OPT_VERIFY, OPT_TIME, OPT_SSL3,
  100. OPT_WWW
  101. } OPTION_CHOICE;
  102. OPTIONS s_time_options[] = {
  103. {"help", OPT_HELP, '-', "Display this summary"},
  104. {"connect", OPT_CONNECT, 's',
  105. "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"},
  106. {"cipher", OPT_CIPHER, 's', "Cipher to use, see 'openssl ciphers'"},
  107. {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"},
  108. {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"},
  109. {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
  110. {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"},
  111. {"no-CAfile", OPT_NOCAFILE, '-',
  112. "Do not load the default certificates file"},
  113. {"no-CApath", OPT_NOCAPATH, '-',
  114. "Do not load certificates from the default certificates directory"},
  115. {"new", OPT_NEW, '-', "Just time new connections"},
  116. {"reuse", OPT_REUSE, '-', "Just time connection reuse"},
  117. {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"},
  118. {"verify", OPT_VERIFY, 'p',
  119. "Turn on peer certificate verification, set depth"},
  120. {"time", OPT_TIME, 'p', "Sf seconds to collect data, default" SECONDSSTR},
  121. {"www", OPT_WWW, 's', "Fetch specified page from the site"},
  122. #ifndef OPENSSL_NO_SSL3
  123. {"ssl3", OPT_SSL3, '-', "Just use SSLv3"},
  124. #endif
  125. {NULL}
  126. };
  127. #define START 0
  128. #define STOP 1
  129. static double tm_Time_F(int s)
  130. {
  131. return app_tminterval(s, 1);
  132. }
  133. int s_time_main(int argc, char **argv)
  134. {
  135. char buf[1024 * 8];
  136. SSL *scon = NULL;
  137. SSL_CTX *ctx = NULL;
  138. const SSL_METHOD *meth = NULL;
  139. char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *www_path = NULL;
  140. char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog;
  141. double totalTime = 0.0;
  142. int noCApath = 0, noCAfile = 0;
  143. int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs =
  144. 0, ver;
  145. long bytes_read = 0, finishtime = 0;
  146. OPTION_CHOICE o;
  147. meth = TLS_client_method();
  148. verify_depth = 0;
  149. verify_error = X509_V_OK;
  150. prog = opt_init(argc, argv, s_time_options);
  151. while ((o = opt_next()) != OPT_EOF) {
  152. switch (o) {
  153. case OPT_EOF:
  154. case OPT_ERR:
  155. opthelp:
  156. BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
  157. goto end;
  158. case OPT_HELP:
  159. opt_help(s_time_options);
  160. ret = 0;
  161. goto end;
  162. case OPT_CONNECT:
  163. host = opt_arg();
  164. break;
  165. case OPT_REUSE:
  166. perform = 2;
  167. break;
  168. case OPT_NEW:
  169. perform = 1;
  170. break;
  171. case OPT_VERIFY:
  172. if (!opt_int(opt_arg(), &verify_depth))
  173. goto opthelp;
  174. BIO_printf(bio_err, "%s: verify depth is %d\n",
  175. prog, verify_depth);
  176. break;
  177. case OPT_CERT:
  178. certfile = opt_arg();
  179. break;
  180. case OPT_KEY:
  181. keyfile = opt_arg();
  182. break;
  183. case OPT_CAPATH:
  184. CApath = opt_arg();
  185. break;
  186. case OPT_CAFILE:
  187. CAfile = opt_arg();
  188. break;
  189. case OPT_NOCAPATH:
  190. noCApath = 1;
  191. break;
  192. case OPT_NOCAFILE:
  193. noCAfile = 1;
  194. break;
  195. case OPT_CIPHER:
  196. cipher = opt_arg();
  197. break;
  198. case OPT_BUGS:
  199. st_bugs = 1;
  200. break;
  201. case OPT_TIME:
  202. if (!opt_int(opt_arg(), &maxtime))
  203. goto opthelp;
  204. break;
  205. case OPT_WWW:
  206. www_path = opt_arg();
  207. if (strlen(www_path) > MYBUFSIZ - 100) {
  208. BIO_printf(bio_err, "%s: -www option too long\n", prog);
  209. goto end;
  210. }
  211. break;
  212. case OPT_SSL3:
  213. #ifndef OPENSSL_NO_SSL3
  214. meth = SSLv3_client_method();
  215. #endif
  216. break;
  217. }
  218. }
  219. argc = opt_num_rest();
  220. argv = opt_rest();
  221. if (cipher == NULL)
  222. cipher = getenv("SSL_CIPHER");
  223. if (cipher == NULL) {
  224. BIO_printf(bio_err, "No CIPHER specified\n");
  225. goto end;
  226. }
  227. if ((ctx = SSL_CTX_new(meth)) == NULL)
  228. goto end;
  229. SSL_CTX_set_quiet_shutdown(ctx, 1);
  230. if (st_bugs)
  231. SSL_CTX_set_options(ctx, SSL_OP_ALL);
  232. if (!SSL_CTX_set_cipher_list(ctx, cipher))
  233. goto end;
  234. if (!set_cert_stuff(ctx, certfile, keyfile))
  235. goto end;
  236. if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
  237. ERR_print_errors(bio_err);
  238. goto end;
  239. }
  240. if (!(perform & 1))
  241. goto next;
  242. printf("Collecting connection statistics for %d seconds\n", maxtime);
  243. /* Loop and time how long it takes to make connections */
  244. bytes_read = 0;
  245. finishtime = (long)time(NULL) + maxtime;
  246. tm_Time_F(START);
  247. for (;;) {
  248. if (finishtime < (long)time(NULL))
  249. break;
  250. if ((scon = doConnection(NULL, host, ctx)) == NULL)
  251. goto end;
  252. if (www_path != NULL) {
  253. BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n",
  254. www_path);
  255. if (SSL_write(scon, buf, strlen(buf)) <= 0)
  256. goto end;
  257. while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
  258. bytes_read += i;
  259. }
  260. #ifdef NO_SHUTDOWN
  261. SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
  262. #else
  263. SSL_shutdown(scon);
  264. #endif
  265. SHUTDOWN2(SSL_get_fd(scon));
  266. nConn += 1;
  267. if (SSL_session_reused(scon))
  268. ver = 'r';
  269. else {
  270. ver = SSL_version(scon);
  271. if (ver == TLS1_VERSION)
  272. ver = 't';
  273. else if (ver == SSL3_VERSION)
  274. ver = '3';
  275. else
  276. ver = '*';
  277. }
  278. fputc(ver, stdout);
  279. fflush(stdout);
  280. SSL_free(scon);
  281. scon = NULL;
  282. }
  283. totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
  284. i = (int)((long)time(NULL) - finishtime + maxtime);
  285. printf
  286. ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
  287. nConn, totalTime, ((double)nConn / totalTime), bytes_read);
  288. printf
  289. ("%d connections in %ld real seconds, %ld bytes read per connection\n",
  290. nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
  291. /*
  292. * Now loop and time connections using the same session id over and over
  293. */
  294. next:
  295. if (!(perform & 2))
  296. goto end;
  297. printf("\n\nNow timing with session id reuse.\n");
  298. /* Get an SSL object so we can reuse the session id */
  299. if ((scon = doConnection(NULL, host, ctx)) == NULL) {
  300. BIO_printf(bio_err, "Unable to get connection\n");
  301. goto end;
  302. }
  303. if (www_path != NULL) {
  304. BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", www_path);
  305. if (SSL_write(scon, buf, strlen(buf)) <= 0)
  306. goto end;
  307. while (SSL_read(scon, buf, sizeof(buf)) > 0)
  308. continue;
  309. }
  310. #ifdef NO_SHUTDOWN
  311. SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
  312. #else
  313. SSL_shutdown(scon);
  314. #endif
  315. SHUTDOWN2(SSL_get_fd(scon));
  316. nConn = 0;
  317. totalTime = 0.0;
  318. finishtime = (long)time(NULL) + maxtime;
  319. printf("starting\n");
  320. bytes_read = 0;
  321. tm_Time_F(START);
  322. for (;;) {
  323. if (finishtime < (long)time(NULL))
  324. break;
  325. if ((doConnection(scon, host, ctx)) == NULL)
  326. goto end;
  327. if (www_path) {
  328. BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n",
  329. www_path);
  330. if (SSL_write(scon, buf, strlen(buf)) <= 0)
  331. goto end;
  332. while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
  333. bytes_read += i;
  334. }
  335. #ifdef NO_SHUTDOWN
  336. SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
  337. #else
  338. SSL_shutdown(scon);
  339. #endif
  340. SHUTDOWN2(SSL_get_fd(scon));
  341. nConn += 1;
  342. if (SSL_session_reused(scon))
  343. ver = 'r';
  344. else {
  345. ver = SSL_version(scon);
  346. if (ver == TLS1_VERSION)
  347. ver = 't';
  348. else if (ver == SSL3_VERSION)
  349. ver = '3';
  350. else
  351. ver = '*';
  352. }
  353. fputc(ver, stdout);
  354. fflush(stdout);
  355. }
  356. totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
  357. printf
  358. ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
  359. nConn, totalTime, ((double)nConn / totalTime), bytes_read);
  360. printf
  361. ("%d connections in %ld real seconds, %ld bytes read per connection\n",
  362. nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
  363. ret = 0;
  364. end:
  365. SSL_free(scon);
  366. SSL_CTX_free(ctx);
  367. return (ret);
  368. }
  369. /*-
  370. * doConnection - make a connection
  371. */
  372. static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
  373. {
  374. BIO *conn;
  375. SSL *serverCon;
  376. int width, i;
  377. fd_set readfds;
  378. if ((conn = BIO_new(BIO_s_connect())) == NULL)
  379. return (NULL);
  380. BIO_set_conn_hostname(conn, host);
  381. if (scon == NULL)
  382. serverCon = SSL_new(ctx);
  383. else {
  384. serverCon = scon;
  385. SSL_set_connect_state(serverCon);
  386. }
  387. SSL_set_bio(serverCon, conn, conn);
  388. /* ok, lets connect */
  389. for (;;) {
  390. i = SSL_connect(serverCon);
  391. if (BIO_sock_should_retry(i)) {
  392. BIO_printf(bio_err, "DELAY\n");
  393. i = SSL_get_fd(serverCon);
  394. width = i + 1;
  395. FD_ZERO(&readfds);
  396. openssl_fdset(i, &readfds);
  397. /*
  398. * Note: under VMS with SOCKETSHR the 2nd parameter is currently
  399. * of type (int *) whereas under other systems it is (void *) if
  400. * you don't have a cast it will choke the compiler: if you do
  401. * have a cast then you can either go for (int *) or (void *).
  402. */
  403. select(width, (void *)&readfds, NULL, NULL, NULL);
  404. continue;
  405. }
  406. break;
  407. }
  408. if (i <= 0) {
  409. BIO_printf(bio_err, "ERROR\n");
  410. if (verify_error != X509_V_OK)
  411. BIO_printf(bio_err, "verify error:%s\n",
  412. X509_verify_cert_error_string(verify_error));
  413. else
  414. ERR_print_errors(bio_err);
  415. if (scon == NULL)
  416. SSL_free(serverCon);
  417. return NULL;
  418. }
  419. return serverCon;
  420. }