Annotation of src/usr.bin/openssl/s_time.c, Revision 1.1
1.1 ! jsing 1: /* $OpenBSD: s_time.c,v 1.35 2014/08/24 16:07:29 bcook Exp $ */
! 2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
! 3: * All rights reserved.
! 4: *
! 5: * This package is an SSL implementation written
! 6: * by Eric Young (eay@cryptsoft.com).
! 7: * The implementation was written so as to conform with Netscapes SSL.
! 8: *
! 9: * This library is free for commercial and non-commercial use as long as
! 10: * the following conditions are aheared to. The following conditions
! 11: * apply to all code found in this distribution, be it the RC4, RSA,
! 12: * lhash, DES, etc., code; not just the SSL code. The SSL documentation
! 13: * included with this distribution is covered by the same copyright terms
! 14: * except that the holder is Tim Hudson (tjh@cryptsoft.com).
! 15: *
! 16: * Copyright remains Eric Young's, and as such any Copyright notices in
! 17: * the code are not to be removed.
! 18: * If this package is used in a product, Eric Young should be given attribution
! 19: * as the author of the parts of the library used.
! 20: * This can be in the form of a textual message at program startup or
! 21: * in documentation (online or textual) provided with the package.
! 22: *
! 23: * Redistribution and use in source and binary forms, with or without
! 24: * modification, are permitted provided that the following conditions
! 25: * are met:
! 26: * 1. Redistributions of source code must retain the copyright
! 27: * notice, this list of conditions and the following disclaimer.
! 28: * 2. Redistributions in binary form must reproduce the above copyright
! 29: * notice, this list of conditions and the following disclaimer in the
! 30: * documentation and/or other materials provided with the distribution.
! 31: * 3. All advertising materials mentioning features or use of this software
! 32: * must display the following acknowledgement:
! 33: * "This product includes cryptographic software written by
! 34: * Eric Young (eay@cryptsoft.com)"
! 35: * The word 'cryptographic' can be left out if the rouines from the library
! 36: * being used are not cryptographic related :-).
! 37: * 4. If you include any Windows specific code (or a derivative thereof) from
! 38: * the apps directory (application code) you must include an acknowledgement:
! 39: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
! 40: *
! 41: * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
! 42: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 43: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 44: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 45: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 46: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 47: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 48: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 49: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 50: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 51: * SUCH DAMAGE.
! 52: *
! 53: * The licence and distribution terms for any publically available version or
! 54: * derivative of this code cannot be changed. i.e. this code cannot simply be
! 55: * copied and put under another distribution licence
! 56: * [including the GNU Public Licence.]
! 57: */
! 58:
! 59: #define NO_SHUTDOWN
! 60:
! 61: /*-----------------------------------------
! 62: s_time - SSL client connection timer program
! 63: Written and donated by Larry Streepy <streepy@healthcare.com>
! 64: -----------------------------------------*/
! 65:
! 66: #include <sys/select.h>
! 67: #include <sys/socket.h>
! 68:
! 69: #include <stdio.h>
! 70: #include <stdlib.h>
! 71: #include <limits.h>
! 72: #include <string.h>
! 73: #include <unistd.h>
! 74:
! 75: #include "apps.h"
! 76:
! 77: #include <openssl/err.h>
! 78: #include <openssl/pem.h>
! 79: #include <openssl/ssl.h>
! 80: #include <openssl/x509.h>
! 81:
! 82: #include "s_apps.h"
! 83:
! 84: #define SSL_CONNECT_NAME "localhost:4433"
! 85:
! 86: /*#define TEST_CERT "client.pem" *//* no default cert. */
! 87:
! 88: #define BUFSIZZ 1024*10
! 89:
! 90: #define MYBUFSIZ 1024*8
! 91:
! 92: #undef min
! 93: #undef max
! 94: #define min(a,b) (((a) < (b)) ? (a) : (b))
! 95: #define max(a,b) (((a) > (b)) ? (a) : (b))
! 96:
! 97: #define SECONDS 30
! 98: extern int verify_depth;
! 99: extern int verify_error;
! 100:
! 101: static void s_time_usage(void);
! 102: static int parseArgs(int argc, char **argv);
! 103: static SSL *doConnection(SSL * scon);
! 104: static void s_time_init(void);
! 105:
! 106: /***********************************************************************
! 107: * Static data declarations
! 108: */
! 109:
! 110: /* static char *port=PORT_STR;*/
! 111: static char *host = SSL_CONNECT_NAME;
! 112: static char *t_cert_file = NULL;
! 113: static char *t_key_file = NULL;
! 114: static char *CApath = NULL;
! 115: static char *CAfile = NULL;
! 116: static char *tm_cipher = NULL;
! 117: static int tm_verify = SSL_VERIFY_NONE;
! 118: static int maxTime = SECONDS;
! 119: static SSL_CTX *tm_ctx = NULL;
! 120: static const SSL_METHOD *s_time_meth = NULL;
! 121: static char *s_www_path = NULL;
! 122: static long bytes_read = 0;
! 123: static int st_bugs = 0;
! 124: static int perform = 0;
! 125: static int t_nbio = 0;
! 126:
! 127: static void
! 128: s_time_init(void)
! 129: {
! 130: host = SSL_CONNECT_NAME;
! 131: t_cert_file = NULL;
! 132: t_key_file = NULL;
! 133: CApath = NULL;
! 134: CAfile = NULL;
! 135: tm_cipher = NULL;
! 136: tm_verify = SSL_VERIFY_NONE;
! 137: maxTime = SECONDS;
! 138: tm_ctx = NULL;
! 139: s_time_meth = NULL;
! 140: s_www_path = NULL;
! 141: bytes_read = 0;
! 142: st_bugs = 0;
! 143: perform = 0;
! 144:
! 145: t_nbio = 0;
! 146: }
! 147:
! 148: /***********************************************************************
! 149: * usage - display usage message
! 150: */
! 151: static void
! 152: s_time_usage(void)
! 153: {
! 154: static const char umsg[] = "\
! 155: -time arg - max number of seconds to collect data, default %d\n\
! 156: -verify arg - turn on peer certificate verification, arg == depth\n\
! 157: -cert arg - certificate file to use, PEM format assumed\n\
! 158: -key arg - RSA file to use, PEM format assumed, key is in cert file\n\
! 159: file if not specified by this option\n\
! 160: -CApath arg - PEM format directory of CA's\n\
! 161: -CAfile arg - PEM format file of CA's\n\
! 162: -cipher - preferred cipher to use, play with 'openssl ciphers'\n\n";
! 163:
! 164: printf("usage: s_time <args>\n\n");
! 165:
! 166: printf("-connect host:port - host:port to connect to (default is %s)\n", SSL_CONNECT_NAME);
! 167: printf("-nbio - Run with non-blocking IO\n");
! 168: printf("-ssl2 - Just use SSLv2\n");
! 169: printf("-ssl3 - Just use SSLv3\n");
! 170: printf("-bugs - Turn on SSL bug compatibility\n");
! 171: printf("-new - Just time new connections\n");
! 172: printf("-reuse - Just time connection reuse\n");
! 173: printf("-www page - Retrieve 'page' from the site\n");
! 174: printf(umsg, SECONDS);
! 175: }
! 176:
! 177: /***********************************************************************
! 178: * parseArgs - Parse command line arguments and initialize data
! 179: *
! 180: * Returns 0 if ok, -1 on bad args
! 181: */
! 182: static int
! 183: parseArgs(int argc, char **argv)
! 184: {
! 185: int badop = 0;
! 186: const char *errstr;
! 187:
! 188: verify_depth = 0;
! 189: verify_error = X509_V_OK;
! 190:
! 191: argc--;
! 192: argv++;
! 193:
! 194: while (argc >= 1) {
! 195: if (strcmp(*argv, "-connect") == 0) {
! 196: if (--argc < 1)
! 197: goto bad;
! 198: host = *(++argv);
! 199: }
! 200: #if 0
! 201: else if (strcmp(*argv, "-host") == 0) {
! 202: if (--argc < 1)
! 203: goto bad;
! 204: host = *(++argv);
! 205: } else if (strcmp(*argv, "-port") == 0) {
! 206: if (--argc < 1)
! 207: goto bad;
! 208: port = *(++argv);
! 209: }
! 210: #endif
! 211: else if (strcmp(*argv, "-reuse") == 0)
! 212: perform = 2;
! 213: else if (strcmp(*argv, "-new") == 0)
! 214: perform = 1;
! 215: else if (strcmp(*argv, "-verify") == 0) {
! 216: const char *errstr;
! 217:
! 218: tm_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
! 219: if (--argc < 1)
! 220: goto bad;
! 221: verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr);
! 222: if (errstr)
! 223: goto bad;
! 224: BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
! 225:
! 226: } else if (strcmp(*argv, "-cert") == 0) {
! 227:
! 228: if (--argc < 1)
! 229: goto bad;
! 230: t_cert_file = *(++argv);
! 231:
! 232: } else if (strcmp(*argv, "-key") == 0) {
! 233:
! 234: if (--argc < 1)
! 235: goto bad;
! 236: t_key_file = *(++argv);
! 237:
! 238: } else if (strcmp(*argv, "-CApath") == 0) {
! 239:
! 240: if (--argc < 1)
! 241: goto bad;
! 242: CApath = *(++argv);
! 243:
! 244: } else if (strcmp(*argv, "-CAfile") == 0) {
! 245:
! 246: if (--argc < 1)
! 247: goto bad;
! 248: CAfile = *(++argv);
! 249:
! 250: } else if (strcmp(*argv, "-cipher") == 0) {
! 251:
! 252: if (--argc < 1)
! 253: goto bad;
! 254: tm_cipher = *(++argv);
! 255: }
! 256: else if (strcmp(*argv, "-nbio") == 0) {
! 257: t_nbio = 1;
! 258: }
! 259: else if (strcmp(*argv, "-www") == 0) {
! 260: if (--argc < 1)
! 261: goto bad;
! 262: s_www_path = *(++argv);
! 263: if (strlen(s_www_path) > MYBUFSIZ - 100) {
! 264: BIO_printf(bio_err, "-www option too long\n");
! 265: badop = 1;
! 266: }
! 267: } else if (strcmp(*argv, "-bugs") == 0)
! 268: st_bugs = 1;
! 269: else if (strcmp(*argv, "-ssl3") == 0)
! 270: s_time_meth = SSLv3_client_method();
! 271: else if (strcmp(*argv, "-time") == 0) {
! 272:
! 273: if (--argc < 1)
! 274: goto bad;
! 275: maxTime = strtonum(*(++argv), 0, INT_MAX, &errstr);
! 276: if (errstr)
! 277: goto bad;
! 278: } else {
! 279: BIO_printf(bio_err, "unknown option %s\n", *argv);
! 280: badop = 1;
! 281: break;
! 282: }
! 283:
! 284: argc--;
! 285: argv++;
! 286: }
! 287:
! 288: if (perform == 0)
! 289: perform = 3;
! 290:
! 291: if (badop) {
! 292: bad:
! 293: s_time_usage();
! 294: return -1;
! 295: }
! 296: return 0; /* Valid args */
! 297: }
! 298:
! 299: /***********************************************************************
! 300: * TIME - time functions
! 301: */
! 302: #define START 0
! 303: #define STOP 1
! 304:
! 305: static double
! 306: tm_Time_F(int s)
! 307: {
! 308: return app_tminterval(s, 1);
! 309: }
! 310:
! 311: /***********************************************************************
! 312: * MAIN - main processing area for client
! 313: * real name depends on MONOLITH
! 314: */
! 315: int s_time_main(int, char **);
! 316:
! 317: int
! 318: s_time_main(int argc, char **argv)
! 319: {
! 320: double totalTime = 0.0;
! 321: int nConn = 0;
! 322: SSL *scon = NULL;
! 323: long finishtime = 0;
! 324: int ret = 1, i;
! 325: char buf[1024 * 8];
! 326: int ver;
! 327:
! 328: s_time_init();
! 329:
! 330: s_time_meth = SSLv23_client_method();
! 331:
! 332: /* parse the command line arguments */
! 333: if (parseArgs(argc, argv) < 0)
! 334: goto end;
! 335:
! 336: if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL)
! 337: return (1);
! 338:
! 339: SSL_CTX_set_quiet_shutdown(tm_ctx, 1);
! 340:
! 341: if (st_bugs)
! 342: SSL_CTX_set_options(tm_ctx, SSL_OP_ALL);
! 343: SSL_CTX_set_cipher_list(tm_ctx, tm_cipher);
! 344: if (!set_cert_stuff(tm_ctx, t_cert_file, t_key_file))
! 345: goto end;
! 346:
! 347: if ((!SSL_CTX_load_verify_locations(tm_ctx, CAfile, CApath)) ||
! 348: (!SSL_CTX_set_default_verify_paths(tm_ctx))) {
! 349: /*
! 350: * BIO_printf(bio_err,"error setting default verify
! 351: * locations\n");
! 352: */
! 353: ERR_print_errors(bio_err);
! 354: /* goto end; */
! 355: }
! 356: if (tm_cipher == NULL)
! 357: tm_cipher = getenv("SSL_CIPHER");
! 358:
! 359: if (tm_cipher == NULL) {
! 360: fprintf(stderr, "No CIPHER specified\n");
! 361: }
! 362: if (!(perform & 1))
! 363: goto next;
! 364: printf("Collecting connection statistics for %d seconds\n", maxTime);
! 365:
! 366: /* Loop and time how long it takes to make connections */
! 367:
! 368: bytes_read = 0;
! 369: finishtime = (long) time(NULL) + maxTime;
! 370: tm_Time_F(START);
! 371: for (;;) {
! 372: if (finishtime < (long) time(NULL))
! 373: break;
! 374: if ((scon = doConnection(NULL)) == NULL)
! 375: goto end;
! 376:
! 377: if (s_www_path != NULL) {
! 378: int ret = snprintf(buf, sizeof buf,
! 379: "GET %s HTTP/1.0\r\n\r\n", s_www_path);
! 380: if (ret == -1 || ret >= sizeof buf) {
! 381: fprintf(stderr, "URL too long\n");
! 382: goto end;
! 383: }
! 384: SSL_write(scon, buf, strlen(buf));
! 385: while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
! 386: bytes_read += i;
! 387: }
! 388: #ifdef NO_SHUTDOWN
! 389: SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
! 390: #else
! 391: SSL_shutdown(scon);
! 392: #endif
! 393: shutdown(SSL_get_fd(scon), SHUT_RDWR);
! 394: close(SSL_get_fd(scon));
! 395:
! 396: nConn += 1;
! 397: if (SSL_session_reused(scon))
! 398: ver = 'r';
! 399: else {
! 400: ver = SSL_version(scon);
! 401: if (ver == TLS1_VERSION)
! 402: ver = 't';
! 403: else if (ver == SSL3_VERSION)
! 404: ver = '3';
! 405: else if (ver == SSL2_VERSION)
! 406: ver = '2';
! 407: else
! 408: ver = '*';
! 409: }
! 410: fputc(ver, stdout);
! 411: fflush(stdout);
! 412:
! 413: SSL_free(scon);
! 414: scon = NULL;
! 415: }
! 416: totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
! 417:
! 418: i = (int) ((long) time(NULL) - finishtime + maxTime);
! 419: printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double) nConn / totalTime), bytes_read);
! 420: printf("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long) time(NULL) - finishtime + maxTime, bytes_read / nConn);
! 421:
! 422: /*
! 423: * Now loop and time connections using the same session id over and
! 424: * over
! 425: */
! 426:
! 427: next:
! 428: if (!(perform & 2))
! 429: goto end;
! 430: printf("\n\nNow timing with session id reuse.\n");
! 431:
! 432: /* Get an SSL object so we can reuse the session id */
! 433: if ((scon = doConnection(NULL)) == NULL) {
! 434: fprintf(stderr, "Unable to get connection\n");
! 435: goto end;
! 436: }
! 437: if (s_www_path != NULL) {
! 438: int ret = snprintf(buf, sizeof buf,
! 439: "GET %s HTTP/1.0\r\n\r\n", s_www_path);
! 440: if (ret == -1 || ret >= sizeof buf) {
! 441: fprintf(stderr, "URL too long\n");
! 442: goto end;
! 443: }
! 444: SSL_write(scon, buf, strlen(buf));
! 445: while (SSL_read(scon, buf, sizeof(buf)) > 0);
! 446: }
! 447: #ifdef NO_SHUTDOWN
! 448: SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
! 449: #else
! 450: SSL_shutdown(scon);
! 451: #endif
! 452: shutdown(SSL_get_fd(scon), SHUT_RDWR);
! 453: close(SSL_get_fd(scon));
! 454:
! 455: nConn = 0;
! 456: totalTime = 0.0;
! 457:
! 458: finishtime = (long) time(NULL) + maxTime;
! 459:
! 460: printf("starting\n");
! 461: bytes_read = 0;
! 462: tm_Time_F(START);
! 463:
! 464: for (;;) {
! 465: if (finishtime < (long) time(NULL))
! 466: break;
! 467: if ((doConnection(scon)) == NULL)
! 468: goto end;
! 469:
! 470: if (s_www_path) {
! 471: int ret = snprintf(buf, sizeof buf,
! 472: "GET %s HTTP/1.0\r\n\r\n", s_www_path);
! 473: if (ret == -1 || ret >= sizeof buf) {
! 474: fprintf(stderr, "URL too long\n");
! 475: goto end;
! 476: }
! 477: SSL_write(scon, buf, strlen(buf));
! 478: while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
! 479: bytes_read += i;
! 480: }
! 481: #ifdef NO_SHUTDOWN
! 482: SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
! 483: #else
! 484: SSL_shutdown(scon);
! 485: #endif
! 486: shutdown(SSL_get_fd(scon), SHUT_RDWR);
! 487: close(SSL_get_fd(scon));
! 488:
! 489: nConn += 1;
! 490: if (SSL_session_reused(scon))
! 491: ver = 'r';
! 492: else {
! 493: ver = SSL_version(scon);
! 494: if (ver == TLS1_VERSION)
! 495: ver = 't';
! 496: else if (ver == SSL3_VERSION)
! 497: ver = '3';
! 498: else if (ver == SSL2_VERSION)
! 499: ver = '2';
! 500: else
! 501: ver = '*';
! 502: }
! 503: fputc(ver, stdout);
! 504: fflush(stdout);
! 505: }
! 506: totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
! 507:
! 508:
! 509: printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double) nConn / totalTime), bytes_read);
! 510: printf("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long) time(NULL) - finishtime + maxTime, bytes_read / nConn);
! 511:
! 512: ret = 0;
! 513: end:
! 514: if (scon != NULL)
! 515: SSL_free(scon);
! 516:
! 517: if (tm_ctx != NULL) {
! 518: SSL_CTX_free(tm_ctx);
! 519: tm_ctx = NULL;
! 520: }
! 521:
! 522: return (ret);
! 523: }
! 524:
! 525: /***********************************************************************
! 526: * doConnection - make a connection
! 527: * Args:
! 528: * scon = earlier ssl connection for session id, or NULL
! 529: * Returns:
! 530: * SSL * = the connection pointer.
! 531: */
! 532: static SSL *
! 533: doConnection(SSL * scon)
! 534: {
! 535: BIO *conn;
! 536: SSL *serverCon;
! 537: int width, i;
! 538: fd_set readfds;
! 539:
! 540: if ((conn = BIO_new(BIO_s_connect())) == NULL)
! 541: return (NULL);
! 542:
! 543: /* BIO_set_conn_port(conn,port);*/
! 544: BIO_set_conn_hostname(conn, host);
! 545:
! 546: if (scon == NULL)
! 547: serverCon = SSL_new(tm_ctx);
! 548: else {
! 549: serverCon = scon;
! 550: SSL_set_connect_state(serverCon);
! 551: }
! 552:
! 553: SSL_set_bio(serverCon, conn, conn);
! 554:
! 555: #if 0
! 556: if (scon != NULL)
! 557: SSL_set_session(serverCon, SSL_get_session(scon));
! 558: #endif
! 559:
! 560: /* ok, lets connect */
! 561: for (;;) {
! 562: i = SSL_connect(serverCon);
! 563: if (BIO_sock_should_retry(i)) {
! 564: BIO_printf(bio_err, "DELAY\n");
! 565:
! 566: i = SSL_get_fd(serverCon);
! 567: width = i + 1;
! 568: FD_ZERO(&readfds);
! 569: FD_SET(i, &readfds);
! 570: select(width, &readfds, NULL, NULL, NULL);
! 571: continue;
! 572: }
! 573: break;
! 574: }
! 575: if (i <= 0) {
! 576: BIO_printf(bio_err, "ERROR\n");
! 577: if (verify_error != X509_V_OK)
! 578: BIO_printf(bio_err, "verify error:%s\n",
! 579: X509_verify_cert_error_string(verify_error));
! 580: else
! 581: ERR_print_errors(bio_err);
! 582: if (scon == NULL)
! 583: SSL_free(serverCon);
! 584: return NULL;
! 585: }
! 586: return serverCon;
! 587: }