1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59: #define NO_SHUTDOWN
60:
61:
62:
63:
64:
65:
66: #include <stdio.h>
67: #include <stdlib.h>
68: #include <string.h>
69:
70: #define USE_SOCKETS
71: #include "apps.h"
72: #ifdef OPENSSL_NO_STDIO
73: #define APPS_WIN16
74: #endif
75: #include <openssl/x509.h>
76: #include <openssl/ssl.h>
77: #include <openssl/pem.h>
78: #include "s_apps.h"
79: #include <openssl/err.h>
80: #ifdef WIN32_STUFF
81: #include "winmain.h"
82: #include "wintext.h"
83: #endif
84: #if !defined(OPENSSL_SYS_MSDOS)
85: #include OPENSSL_UNISTD
86: #endif
87:
88: #if !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC))
89: #define TIMES
90: #endif
91:
92: #ifndef _IRIX
93: #include <time.h>
94: #endif
95: #ifdef TIMES
96: #include <sys/types.h>
97: #include <sys/times.h>
98: #endif
99:
100:
101:
102:
103:
104: #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
105: #undef TIMES
106: #endif
107:
108: #if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE)
109: #include <sys/timeb.h>
110: #endif
111:
112: #if defined(sun) || defined(__ultrix)
113: #define _POSIX_SOURCE
114: #include <limits.h>
115: #include <sys/param.h>
116: #endif
117:
118:
119:
120: #ifndef HZ
121: # ifdef _SC_CLK_TCK
122: # define HZ ((double)sysconf(_SC_CLK_TCK))
123: # else
124: # ifndef CLK_TCK
125: # ifndef _BSD_CLK_TCK_
126: # define HZ 100.0
127: # else
128: # define HZ ((double)_BSD_CLK_TCK_)
129: # endif
130: # else
131: # define HZ ((double)CLK_TCK)
132: # endif
133: # endif
134: #endif
135:
136: #undef PROG
137: #define PROG s_time_main
138:
139: #undef ioctl
140: #define ioctl ioctlsocket
141:
142: #define SSL_CONNECT_NAME "localhost:4433"
143:
144:
145:
146: #undef BUFSIZZ
147: #define BUFSIZZ 1024*10
148:
149: #define MYBUFSIZ 1024*8
150:
151: #undef min
152: #undef max
153: #define min(a,b) (((a) < (b)) ? (a) : (b))
154: #define max(a,b) (((a) > (b)) ? (a) : (b))
155:
156: #undef SECONDS
157: #define SECONDS 30
158: extern int verify_depth;
159: extern int verify_error;
160:
161: static void s_time_usage(void);
162: static int parseArgs( int argc, char **argv );
163: static SSL *doConnection( SSL *scon );
164: static void s_time_init(void);
165:
166:
167:
168:
169:
170:
171: static char *host=SSL_CONNECT_NAME;
172: static char *t_cert_file=NULL;
173: static char *t_key_file=NULL;
174: static char *CApath=NULL;
175: static char *CAfile=NULL;
176: static char *tm_cipher=NULL;
177: static int tm_verify = SSL_VERIFY_NONE;
178: static int maxTime = SECONDS;
179: static SSL_CTX *tm_ctx=NULL;
180: static SSL_METHOD *s_time_meth=NULL;
181: static char *s_www_path=NULL;
182: static long bytes_read=0;
183: static int st_bugs=0;
184: static int perform=0;
185: #ifdef FIONBIO
186: static int t_nbio=0;
187: #endif
188: #ifdef OPENSSL_SYS_WIN32
189: static int exitNow = 0;
190: #endif
191:
192: static void s_time_init(void)
193: {
194: host=SSL_CONNECT_NAME;
195: t_cert_file=NULL;
196: t_key_file=NULL;
197: CApath=NULL;
198: CAfile=NULL;
199: tm_cipher=NULL;
200: tm_verify = SSL_VERIFY_NONE;
201: maxTime = SECONDS;
202: tm_ctx=NULL;
203: s_time_meth=NULL;
204: s_www_path=NULL;
205: bytes_read=0;
206: st_bugs=0;
207: perform=0;
208:
209: #ifdef FIONBIO
210: t_nbio=0;
211: #endif
212: #ifdef OPENSSL_SYS_WIN32
213: exitNow = 0;
214: #endif
215: }
216:
217:
218:
219:
220: static void s_time_usage(void)
221: {
222: static char umsg[] = "\
223: -time arg - max number of seconds to collect data, default %d\n\
224: -verify arg - turn on peer certificate verification, arg == depth\n\
225: -cert arg - certificate file to use, PEM format assumed\n\
226: -key arg - RSA file to use, PEM format assumed, key is in cert file\n\
227: file if not specified by this option\n\
228: -CApath arg - PEM format directory of CA's\n\
229: -CAfile arg - PEM format file of CA's\n\
230: -cipher - preferred cipher to use, play with 'openssl ciphers'\n\n";
231:
232: printf( "usage: s_time <args>\n\n" );
233:
234: printf("-connect host:port - host:port to connect to (default is %s)\n",SSL_CONNECT_NAME);
235: #ifdef FIONBIO
236: printf("-nbio - Run with non-blocking IO\n");
237: printf("-ssl2 - Just use SSLv2\n");
238: printf("-ssl3 - Just use SSLv3\n");
239: printf("-bugs - Turn on SSL bug compatibility\n");
240: printf("-new - Just time new connections\n");
241: printf("-reuse - Just time connection reuse\n");
242: printf("-www page - Retrieve 'page' from the site\n");
243: #endif
244: printf( umsg,SECONDS );
245: }
246:
247:
248:
249:
250:
251:
252: static int parseArgs(int argc, char **argv)
253: {
254: int badop = 0;
255:
256: verify_depth=0;
257: verify_error=X509_V_OK;
258:
259: argc--;
260: argv++;
261:
262: while (argc >= 1) {
263: if (strcmp(*argv,"-connect") == 0)
264: {
265: if (--argc < 1) goto bad;
266: host= *(++argv);
267: }
268: #if 0
269: else if( strcmp(*argv,"-host") == 0)
270: {
271: if (--argc < 1) goto bad;
272: host= *(++argv);
273: }
274: else if( strcmp(*argv,"-port") == 0)
275: {
276: if (--argc < 1) goto bad;
277: port= *(++argv);
278: }
279: #endif
280: else if (strcmp(*argv,"-reuse") == 0)
281: perform=2;
282: else if (strcmp(*argv,"-new") == 0)
283: perform=1;
284: else if( strcmp(*argv,"-verify") == 0) {
285:
286: tm_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
287: if (--argc < 1) goto bad;
288: verify_depth=atoi(*(++argv));
289: BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
290:
291: } else if( strcmp(*argv,"-cert") == 0) {
292:
293: if (--argc < 1) goto bad;
294: t_cert_file= *(++argv);
295:
296: } else if( strcmp(*argv,"-key") == 0) {
297:
298: if (--argc < 1) goto bad;
299: t_key_file= *(++argv);
300:
301: } else if( strcmp(*argv,"-CApath") == 0) {
302:
303: if (--argc < 1) goto bad;
304: CApath= *(++argv);
305:
306: } else if( strcmp(*argv,"-CAfile") == 0) {
307:
308: if (--argc < 1) goto bad;
309: CAfile= *(++argv);
310:
311: } else if( strcmp(*argv,"-cipher") == 0) {
312:
313: if (--argc < 1) goto bad;
314: tm_cipher= *(++argv);
315: }
316: #ifdef FIONBIO
317: else if(strcmp(*argv,"-nbio") == 0) {
318: t_nbio=1;
319: }
320: #endif
321: else if(strcmp(*argv,"-www") == 0)
322: {
323: if (--argc < 1) goto bad;
324: s_www_path= *(++argv);
325: if(strlen(s_www_path) > MYBUFSIZ-100)
326: {
327: BIO_printf(bio_err,"-www option too long\n");
328: badop=1;
329: }
330: }
331: else if(strcmp(*argv,"-bugs") == 0)
332: st_bugs=1;
333: #ifndef OPENSSL_NO_SSL2
334: else if(strcmp(*argv,"-ssl2") == 0)
335: s_time_meth=SSLv2_client_method();
336: #endif
337: #ifndef OPENSSL_NO_SSL3
338: else if(strcmp(*argv,"-ssl3") == 0)
339: s_time_meth=SSLv3_client_method();
340: #endif
341: else if( strcmp(*argv,"-time") == 0) {
342:
343: if (--argc < 1) goto bad;
344: maxTime= atoi(*(++argv));
345: }
346: else {
347: BIO_printf(bio_err,"unknown option %s\n",*argv);
348: badop=1;
349: break;
350: }
351:
352: argc--;
353: argv++;
354: }
355:
356: if (perform == 0) perform=3;
357:
358: if(badop) {
359: bad:
360: s_time_usage();
361: return -1;
362: }
363:
364: return 0;
365: }
366:
367:
368:
369:
370: #define START 0
371: #define STOP 1
372:
373: static double tm_Time_F(int s)
374: {
375: static double ret;
376: #ifdef TIMES
377: static struct tms tstart,tend;
378:
379: if(s == START) {
380: times(&tstart);
381: return(0);
382: } else {
383: times(&tend);
384: ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
385: return((ret == 0.0)?1e-6:ret);
386: }
387: #elif defined(OPENSSL_SYS_NETWARE)
388: static clock_t tstart,tend;
389:
390: if (s == START)
391: {
392: tstart=clock();
393: return(0);
394: }
395: else
396: {
397: tend=clock();
398: ret=(double)((double)(tend)-(double)(tstart));
399: return((ret < 0.001)?0.001:ret);
400: }
401: #elif defined(OPENSSL_SYS_VXWORKS)
402: {
403: static unsigned long tick_start, tick_end;
404:
405: if( s == START )
406: {
407: tick_start = tickGet();
408: return 0;
409: }
410: else
411: {
412: tick_end = tickGet();
413: ret = (double)(tick_end - tick_start) / (double)sysClkRateGet();
414: return((ret == 0.0)?1e-6:ret);
415: }
416: }
417: #else
418: static struct timeb tstart,tend;
419: long i;
420:
421: if(s == START) {
422: ftime(&tstart);
423: return(0);
424: } else {
425: ftime(&tend);
426: i=(long)tend.millitm-(long)tstart.millitm;
427: ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
428: return((ret == 0.0)?1e-6:ret);
429: }
430: #endif
431: }
432:
433:
434:
435:
436:
437: int MAIN(int, char **);
438:
439: int MAIN(int argc, char **argv)
440: {
441: double totalTime = 0.0;
442: int nConn = 0;
443: SSL *scon=NULL;
444: long finishtime=0;
445: int ret=1,i;
446: MS_STATIC char buf[1024*8];
447: int ver;
448:
449: apps_startup();
450: s_time_init();
451:
452: if (bio_err == NULL)
453: bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
454:
455: #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
456: s_time_meth=SSLv23_client_method();
457: #elif !defined(OPENSSL_NO_SSL3)
458: s_time_meth=SSLv3_client_method();
459: #elif !defined(OPENSSL_NO_SSL2)
460: s_time_meth=SSLv2_client_method();
461: #endif
462:
463:
464: if( parseArgs( argc, argv ) < 0 )
465: goto end;
466:
467: OpenSSL_add_ssl_algorithms();
468: if ((tm_ctx=SSL_CTX_new(s_time_meth)) == NULL) return(1);
469:
470: SSL_CTX_set_quiet_shutdown(tm_ctx,1);
471:
472: if (st_bugs) SSL_CTX_set_options(tm_ctx,SSL_OP_ALL);
473: SSL_CTX_set_cipher_list(tm_ctx,tm_cipher);
474: if(!set_cert_stuff(tm_ctx,t_cert_file,t_key_file))
475: goto end;
476:
477: SSL_load_error_strings();
478:
479: if ((!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) ||
480: (!SSL_CTX_set_default_verify_paths(tm_ctx)))
481: {
482:
483: ERR_print_errors(bio_err);
484:
485: }
486:
487: if (tm_cipher == NULL)
488: tm_cipher = getenv("SSL_CIPHER");
489:
490: if (tm_cipher == NULL ) {
491: fprintf( stderr, "No CIPHER specified\n" );
492: }
493:
494: if (!(perform & 1)) goto next;
495: printf( "Collecting connection statistics for %d seconds\n", maxTime );
496:
497:
498:
499: bytes_read=0;
500: finishtime=(long)time(NULL)+maxTime;
501: tm_Time_F(START);
502: for (;;)
503: {
504: if (finishtime < (long)time(NULL)) break;
505: #ifdef WIN32_STUFF
506:
507: if( flushWinMsgs(0) == -1 )
508: goto end;
509:
510: if( waitingToDie || exitNow )
511: goto end;
512: #endif
513:
514: if( (scon = doConnection( NULL )) == NULL )
515: goto end;
516:
517: if (s_www_path != NULL)
518: {
519: BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
520: SSL_write(scon,buf,strlen(buf));
521: while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
522: bytes_read+=i;
523: }
524:
525: #ifdef NO_SHUTDOWN
526: SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
527: #else
528: SSL_shutdown(scon);
529: #endif
530: SHUTDOWN2(SSL_get_fd(scon));
531:
532: nConn += 1;
533: if (SSL_session_reused(scon))
534: ver='r';
535: else
536: {
537: ver=SSL_version(scon);
538: if (ver == TLS1_VERSION)
539: ver='t';
540: else if (ver == SSL3_VERSION)
541: ver='3';
542: else if (ver == SSL2_VERSION)
543: ver='2';
544: else
545: ver='*';
546: }
547: fputc(ver,stdout);
548: fflush(stdout);
549:
550: SSL_free( scon );
551: scon=NULL;
552: }
553: totalTime += tm_Time_F(STOP);
554:
555: i=(int)((long)time