1 /* apps/s_client.c */ 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 #include <assert.h> 60 #include <stdio.h> 61 #include <stdlib.h> 62 #include <string.h> 63 #ifdef NO_STDIO 64 #define APPS_WIN16 65 #endif 66 67 /* With IPv6, it looks like Digital has mixed up the proper order of 68 recursive header file inclusion, resulting in the compiler complaining 69 that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which 70 is needed to have fileno() declared correctly... So let's define u_int */ 71 #if defined(VMS) && defined(__DECC) && !defined(__U_INT) 72 #define __U_INT 73 typedef unsigned int u_int; 74 #endif 75 76 #define USE_SOCKETS 77 #include "apps.h" 78 #include <openssl/x509.h> 79 #include <openssl/ssl.h> 80 #include <openssl/err.h> 81 #include <openssl/pem.h> 82 #include <openssl/rand.h> 83 #include "s_apps.h" 84 85 #ifdef WINDOWS 86 #include <conio.h> 87 #endif 88 89 90 #if (defined(VMS) && __VMS_VER < 70000000) 91 /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ 92 #undef FIONBIO 93 #endif 94 95 #undef PROG 96 #define PROG s_client_main 97 98 /*#define SSL_HOST_NAME "www.netscape.com" */ 99 /*#define SSL_HOST_NAME "193.118.187.102" */ 100 #define SSL_HOST_NAME "localhost" 101 102 /*#define TEST_CERT "client.pem" */ /* no default cert. */ 103 104 #undef BUFSIZZ 105 #define BUFSIZZ 1024*8 106 107 extern int verify_depth; 108 extern int verify_error; 109 110 #ifdef FIONBIO 111 static int c_nbio=0; 112 #endif 113 static int c_Pause=0; 114 static int c_debug=0; 115 static int c_showcerts=0; 116 117 static void sc_usage(void); 118 static void print_stuff(BIO *berr,SSL *con,int full); 119 static BIO *bio_c_out=NULL; 120 static int c_quiet=0; 121 static int c_ign_eof=0; 122 123 static void sc_usage(void) 124 { 125 BIO_printf(bio_err,"usage: s_client args\n"); 126 BIO_printf(bio_err,"\n"); 127 BIO_printf(bio_err," -host host - use -connect instead\n"); 128 BIO_printf(bio_err," -port port - use -connect instead\n"); 129 BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); 130 131 BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); 132 BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); 133 BIO_printf(bio_err," -key arg - Private key file to use, PEM format assumed, in cert file if\n"); 134 BIO_printf(bio_err," not specified but cert file is.\n"); 135 BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n"); 136 BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n"); 137 BIO_printf(bio_err," -reconnect - Drop and re-make the connection with the same Session-ID\n"); 138 BIO_printf(bio_err," -pause - sleep(1) after each read(2) and write(2) system call\n"); 139 BIO_printf(bio_err," -showcerts - show all certificates in the chain\n"); 140 BIO_printf(bio_err," -debug - extra output\n"); 141 BIO_printf(bio_err," -nbio_test - more ssl protocol testing\n"); 142 BIO_printf(bio_err," -state - print the 'ssl' states\n"); 143 #ifdef FIONBIO 144 BIO_printf(bio_err," -nbio - Run with non-blocking IO\n"); 145 #endif 146 BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n"); 147 BIO_printf(bio_err," -quiet - no s_client output\n"); 148 BIO_printf(bio_err," -ign_eof - ignore input eof (default when -quiet)\n"); 149 BIO_printf(bio_err," -ssl2 - just use SSLv2\n"); 150 BIO_printf(bio_err," -ssl3 - just use SSLv3\n"); 151 BIO_printf(bio_err," -tls1 - just use TLSv1\n"); 152 BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); 153 BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n"); 154 BIO_printf(bio_err," -cipher - preferred cipher to use, use the 'openssl ciphers'\n"); 155 BIO_printf(bio_err," command to see what is available\n"); 156 BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 157 158 } 159 160 int MAIN(int, char **); 161 162 int MAIN(int argc, char **argv) 163 { 164 int off=0; 165 SSL *con=NULL,*con2=NULL; 166 int s,k,width,state=0; 167 char *cbuf=NULL,*sbuf=NULL; 168 int cbuf_len,cbuf_off; 169 int sbuf_len,sbuf_off; 170 fd_set readfds,writefds; 171 short port=PORT; 172 int full_log=1; 173 char *host=SSL_HOST_NAME; 174 char *cert_file=NULL,*key_file=NULL; 175 char *CApath=NULL,*CAfile=NULL,*cipher=NULL; 176 int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0; 177 int crlf=0; 178 int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending; 179 SSL_CTX *ctx=NULL; 180 int ret=1,in_init=1,i,nbio_test=0; 181 int prexit = 0; 182 SSL_METHOD *meth=NULL; 183 BIO *sbio; 184 char *inrand=NULL; 185 #ifdef WINDOWS 186 struct timeval tv; 187 #endif 188 189 #if !defined(NO_SSL2) && !defined(NO_SSL3) 190 meth=SSLv23_client_method(); 191 #elif !defined(NO_SSL3) 192 meth=SSLv3_client_method(); 193 #elif !defined(NO_SSL2) 194 meth=SSLv2_client_method(); 195 #endif 196 197 apps_startup(); 198 c_Pause=0; 199 c_quiet=0; 200 c_ign_eof=0; 201 c_debug=0; 202 c_showcerts=0; 203 204 if (bio_err == NULL) 205 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 206 207 if ( ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || 208 ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL)) 209 { 210 BIO_printf(bio_err,"out of memory\n"); 211 goto end; 212 } 213 214 verify_depth=0; 215 verify_error=X509_V_OK; 216 #ifdef FIONBIO 217 c_nbio=0; 218 #endif 219 220 argc--; 221 argv++; 222 while (argc >= 1) 223 { 224 if (strcmp(*argv,"-host") == 0) 225 { 226 if (--argc < 1) goto bad; 227 host= *(++argv); 228 } 229 else if (strcmp(*argv,"-port") == 0) 230 { 231 if (--argc < 1) goto bad; 232 port=atoi(*(++argv)); 233 if (port == 0) goto bad; 234 } 235 else if (strcmp(*argv,"-connect") == 0) 236 { 237 if (--argc < 1) goto bad; 238 if (!extract_host_port(*(++argv),&host,NULL,&port)) 239 goto bad; 240 } 241 else if (strcmp(*argv,"-verify") == 0) 242 { 243 verify=SSL_VERIFY_PEER; 244 if (--argc < 1) goto bad; 245 verify_depth=atoi(*(++argv)); 246 BIO_printf(bio_err,"verify depth is %d\n",verify_depth); 247 } 248 else if (strcmp(*argv,"-cert") == 0) 249 { 250 if (--argc < 1) goto bad; 251 cert_file= *(++argv); 252 } 253 else if (strcmp(*argv,"-prexit") == 0) 254 prexit=1; 255 else if (strcmp(*argv,"-crlf") == 0) 256 crlf=1; 257 else if (strcmp(*argv,"-quiet") == 0) 258 { 259 c_quiet=1; 260 c_ign_eof=1; 261 } 262 else if (strcmp(*argv,"-ign_eof") == 0) 263 c_ign_eof=1; 264 else if (strcmp(*argv,"-pause") == 0) 265 c_Pause=1; 266 else if (strcmp(*argv,"-debug") == 0) 267 c_debug=1; 268 else if (strcmp(*argv,"-showcerts") == 0) 269 c_showcerts=1; 270 else if (strcmp(*argv,"-nbio_test") == 0) 271 nbio_test=1; 272 else if (strcmp(*argv,"-state") == 0) 273 state=1; 274 #ifndef NO_SSL2 275 else if (strcmp(*argv,"-ssl2") == 0) 276 meth=SSLv2_client_method(); 277 #endif 278 #ifndef NO_SSL3 279 else if (strcmp(*argv,"-ssl3") == 0) 280 meth=SSLv3_client_method(); 281 #endif 282 #ifndef NO_TLS1 283 else if (strcmp(*argv,"-tls1") == 0) 284 meth=TLSv1_client_method(); 285 #endif 286 else if (strcmp(*argv,"-bugs") == 0) 287 bugs=1; 288 else if (strcmp(*argv,"-key") == 0) 289 { 290 if (--argc < 1) goto bad; 291 key_file= *(++argv); 292 } 293 else if (strcmp(*argv,"-reconnect") == 0) 294 { 295 reconnect=5; 296 } 297 else if (strcmp(*argv,"-CApath") == 0) 298 { 299 if (--argc < 1) goto bad; 300 CApath= *(++argv); 301 } 302 else if (strcmp(*argv,"-CAfile") == 0) 303 { 304 if (--argc < 1) goto bad; 305 CAfile= *(++argv); 306 } 307 else if (strcmp(*argv,"-no_tls1") == 0) 308 off|=SSL_OP_NO_TLSv1; 309 else if (strcmp(*argv,"-no_ssl3") == 0) 310 off|=SSL_OP_NO_SSLv3; 311 else if (strcmp(*argv,"-no_ssl2") == 0) 312 off|=SSL_OP_NO_SSLv2; 313 else if (strcmp(*argv,"-cipher") == 0) 314 { 315 if (--argc < 1) goto bad; 316 cipher= *(++argv); 317 } 318 #ifdef FIONBIO 319 else if (strcmp(*argv,"-nbio") == 0) 320 { c_nbio=1; } 321 #endif 322 else if (strcmp(*argv,"-rand") == 0) 323 { 324 if (--argc < 1) goto bad; 325 inrand= *(++argv); 326 } 327 else 328 { 329 BIO_printf(bio_err,"unknown option %s\n",*argv); 330 badop=1; 331 break; 332 } 333 argc--; 334 argv++; 335 } 336 if (badop) 337 { 338 bad: 339 sc_usage(); 340 goto end; 341 } 342 343 if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL 344 && !RAND_status()) 345 { 346 BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); 347 } 348 if (inrand != NULL) 349 BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 350 app_RAND_load_files(inrand)); 351 352 if (bio_c_out == NULL) 353 { 354 if (c_quiet) 355 { 356 bio_c_out=BIO_new(BIO_s_null()); 357 } 358 else 359 { 360 if (bio_c_out == NULL) 361 bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE); 362 } 363 } 364 365 OpenSSL_add_ssl_algorithms(); 366 SSL_load_error_strings(); 367 ctx=SSL_CTX_new(meth); 368 if (ctx == NULL) 369 { 370 ERR_print_errors(bio_err); 371 goto end; 372 } 373 374 if (bugs) 375 SSL_CTX_set_options(ctx,SSL_OP_ALL|off); 376 else 377 SSL_CTX_set_options(ctx,off); 378 379 if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); 380 if (cipher != NULL) 381 if(!SSL_CTX_set_cipher_list(ctx,cipher)) { 382 BIO_printf(bio_err,"error setting cipher list\n"); 383 ERR_print_errors(bio_err); 384 goto end; 385 } 386 #if 0 387 else 388 SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER")); 389 #endif 390 391 SSL_CTX_set_verify(ctx,verify,verify_callback); 392 if (!set_cert_stuff(ctx,cert_file,key_file)) 393 goto end; 394 395 if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || 396 (!SSL_CTX_set_default_verify_paths(ctx))) 397 { 398 /* BIO_printf(bio_err,"error setting default verify locations\n"); */ 399 ERR_print_errors(bio_err); 400 /* goto end; */ 401 } 402 403 404 con=SSL_new(ctx); 405 /* SSL_set_cipher_list(con,"RC4-MD5"); */ 406 407 re_start: 408 409 if (init_client(&s,host,port) == 0) 410 { 411 BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); 412 SHUTDOWN(s); 413 goto end; 414 } 415 BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s); 416 417 #ifdef FIONBIO 418 if (c_nbio) 419 { 420 unsigned long l=1; 421 BIO_printf(bio_c_out,"turning on non blocking io\n"); 422 if (BIO_socket_ioctl(s,FIONBIO,&l) < 0) 423 { 424 ERR_print_errors(bio_err); 425 goto end; 426 } 427 } 428 #endif 429 if (c_Pause & 0x01) con->debug=1; 430 sbio=BIO_new_socket(s,BIO_NOCLOSE); 431 432 if (nbio_test) 433 { 434 BIO *test; 435 436 test=BIO_new(BIO_f_nbio_test()); 437 sbio=BIO_push(test,sbio); 438 } 439 440 if (c_debug) 441 { 442 con->debug=1; 443 BIO_set_callback(sbio,bio_dump_cb); 444 BIO_set_callback_arg(sbio,bio_c_out); 445 } 446 447 SSL_set_bio(con,sbio,sbio); 448 SSL_set_connect_state(con); 449 450 /* ok, lets connect */ 451 width=SSL_get_fd(con)+1; 452 453 read_tty=1; 454 write_tty=0; 455 tty_on=0; 456 read_ssl=1; 457 write_ssl=1; 458 459 cbuf_len=0; 460 cbuf_off=0; 461 sbuf_len=0; 462 sbuf_off=0; 463 464 for (;;) 465 { 466 FD_ZERO(&readfds); 467 FD_ZERO(&writefds); 468 469 if (SSL_in_init(con) && !SSL_total_renegotiations(con)) 470 { 471 in_init=1; 472 tty_on=0; 473 } 474 else 475 { 476 tty_on=1; 477 if (in_init) 478 { 479 in_init=0; 480 print_stuff(bio_c_out,con,full_log); 481 if (full_log > 0) full_log--; 482 483 if (reconnect) 484 { 485 reconnect--; 486 BIO_printf(bio_c_out,"drop connection and then reconnect\n"); 487 SSL_shutdown(con); 488 SSL_set_connect_state(con); 489 SHUTDOWN(SSL_get_fd(con)); 490 goto re_start; 491 } 492 } 493 } 494 495 ssl_pending = read_ssl && SSL_pending(con); 496 497 if (!ssl_pending) 498 { 499 #ifndef WINDOWS 500 if (tty_on) 501 { 502 if (read_tty) FD_SET(fileno(stdin),&readfds); 503 if (write_tty) FD_SET(fileno(stdout),&writefds); 504 } 505 if (read_ssl) 506 FD_SET(SSL_get_fd(con),&readfds); 507 if (write_ssl) 508 FD_SET(SSL_get_fd(con),&writefds); 509 #else 510 if(!tty_on || !write_tty) { 511 if (read_ssl) 512 FD_SET(SSL_get_fd(con),&readfds); 513 if (write_ssl) 514 FD_SET(SSL_get_fd(con),&writefds); 515 } 516 #endif 517 /* printf("mode tty(%d %d%d) ssl(%d%d)\n", 518 tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ 519 520 /* Note: under VMS with SOCKETSHR the second parameter 521 * is currently of type (int *) whereas under other 522 * systems it is (void *) if you don't have a cast it 523 * will choke the compiler: if you do have a cast then 524 * you can either go for (int *) or (void *). 525 */ 526 #ifdef WINDOWS 527 /* Under Windows we make the assumption that we can 528 * always write to the tty: therefore if we need to 529 * write to the tty we just fall through. Otherwise 530 * we timeout the select every second and see if there 531 * are any keypresses. Note: this is a hack, in a proper 532 * Windows application we wouldn't do this. 533 */ 534 i=0; 535 if(!write_tty) { 536 if(read_tty) { 537 tv.tv_sec = 1; 538 tv.tv_usec = 0; 539 i=select(width,(void *)&readfds,(void *)&writefds, 540 NULL,&tv); 541 if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue; 542 } else i=select(width,(void *)&readfds,(void *)&writefds, 543 NULL,NULL); 544 } 545 #else 546 i=select(width,(void *)&readfds,(void *)&writefds, 547 NULL,NULL); 548 #endif 549 if ( i < 0) 550 { 551 BIO_printf(bio_err,"bad select %d\n", 552 get_last_socket_error()); 553 goto shut; 554 /* goto end; */ 555 } 556 } 557 558 if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds)) 559 { 560 k=SSL_write(con,&(cbuf[cbuf_off]), 561 (unsigned int)cbuf_len); 562 switch (SSL_get_error(con,k)) 563 { 564 case SSL_ERROR_NONE: 565 cbuf_off+=k; 566 cbuf_len-=k; 567 if (k <= 0) goto end; 568 /* we have done a write(con,NULL,0); */ 569 if (cbuf_len <= 0) 570 { 571 read_tty=1; 572 write_ssl=0; 573 } 574 else /* if (cbuf_len > 0) */ 575 { 576 read_tty=0; 577 write_ssl=1; 578 } 579 break; 580 case SSL_ERROR_WANT_WRITE: 581 BIO_printf(bio_c_out,"write W BLOCK\n"); 582 write_ssl=1; 583 read_tty=0; 584 break; 585 case SSL_ERROR_WANT_READ: 586 BIO_printf(bio_c_out,"write R BLOCK\n"); 587 write_tty=0; 588 read_ssl=1; 589 write_ssl=0; 590 break; 591 case SSL_ERROR_WANT_X509_LOOKUP: 592 BIO_printf(bio_c_out,"write X BLOCK\n"); 593 break; 594 case SSL_ERROR_ZERO_RETURN: 595 if (cbuf_len != 0) 596 { 597 BIO_printf(bio_c_out,"shutdown\n"); 598 goto shut; 599 } 600 else 601 { 602 read_tty=1; 603 write_ssl=0; 604 break; 605 } 606 607 case SSL_ERROR_SYSCALL: 608 if ((k != 0) || (cbuf_len != 0)) 609 { 610 BIO_printf(bio_err,"write:errno=%d\n", 611 get_last_socket_error()); 612 goto shut; 613 } 614 else 615 { 616 read_tty=1; 617 write_ssl=0; 618 } 619 break; 620 case SSL_ERROR_SSL: 621 ERR_print_errors(bio_err); 622 goto shut; 623 } 624 } 625 #ifdef WINDOWS 626 /* Assume Windows can always write */ 627 else if (!ssl_pending && write_tty) 628 #else 629 else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds)) 630 #endif 631 { 632 #ifdef CHARSET_EBCDIC 633 ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len); 634 #endif 635 i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len); 636 637 if (i <= 0) 638 { 639 BIO_printf(bio_c_out,"DONE\n"); 640 goto shut; 641 /* goto end; */ 642 } 643 644 sbuf_len-=i;; 645 sbuf_off+=i; 646 if (sbuf_len <= 0) 647 { 648 read_ssl=1; 649 write_tty=0; 650 } 651 } 652 else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds)) 653 { 654 #ifdef RENEG 655 { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } } 656 #endif 657 #if 1 658 k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ ); 659 #else 660 /* Demo for pending and peek :-) */ 661 k=SSL_read(con,sbuf,16); 662 { char zbuf[10240]; 663 printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240)); 664 } 665 #endif 666 667 switch (SSL_get_error(con,k)) 668 { 669 case SSL_ERROR_NONE: 670 if (k <= 0) 671 goto end; 672 sbuf_off=0; 673 sbuf_len=k; 674 675 read_ssl=0; 676 write_tty=1; 677 break; 678 case SSL_ERROR_WANT_WRITE: 679 BIO_printf(bio_c_out,"read W BLOCK\n"); 680 write_ssl=1; 681 read_tty=0; 682 break; 683 case SSL_ERROR_WANT_READ: 684 BIO_printf(bio_c_out,"read R BLOCK\n"); 685 write_tty=0; 686 read_ssl=1; 687 if ((read_tty == 0) && (write_ssl == 0)) 688 write_ssl=1; 689 break; 690 case SSL_ERROR_WANT_X509_LOOKUP: 691 BIO_printf(bio_c_out,"read X BLOCK\n"); 692 break; 693 case SSL_ERROR_SYSCALL: 694 BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error()); 695 goto shut; 696 case SSL_ERROR_ZERO_RETURN: 697 BIO_printf(bio_c_out,"closed\n"); 698 goto shut; 699 case SSL_ERROR_SSL: 700 ERR_print_errors(bio_err); 701 goto shut; 702 /* break; */ 703 } 704 } 705 706 #ifdef WINDOWS 707 else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) 708 #else 709 else if (FD_ISSET(fileno(stdin),&readfds)) 710 #endif 711 { 712 if (crlf) 713 { 714 int j, lf_num; 715 716 i=read(fileno(stdin),cbuf,BUFSIZZ/2); 717 lf_num = 0; 718 /* both loops are skipped when i <= 0 */ 719 for (j = 0; j < i; j++) 720 if (cbuf[j] == '\n') 721 lf_num++; 722 for (j = i-1; j >= 0; j--) 723 { 724 cbuf[j+lf_num] = cbuf[j]; 725 if (cbuf[j] == '\n') 726 { 727 lf_num--; 728 i++; 729 cbuf[j+lf_num] = '\r'; 730 } 731 } 732 assert(lf_num == 0); 733 } 734 else 735 i=read(fileno(stdin),cbuf,BUFSIZZ); 736 737 if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) 738 { 739 BIO_printf(bio_err,"DONE\n"); 740 goto shut; 741 } 742 743 if ((!c_ign_eof) && (cbuf[0] == 'R')) 744 { 745 BIO_printf(bio_err,"RENEGOTIATING\n"); 746 SSL_renegotiate(con); 747 cbuf_len=0; 748 } 749 else 750 { 751 cbuf_len=i; 752 cbuf_off=0; 753 #ifdef CHARSET_EBCDIC 754 ebcdic2ascii(cbuf, cbuf, i); 755 #endif 756 } 757 758 write_ssl=1; 759 read_tty=0; 760 } 761 } 762 shut: 763 SSL_shutdown(con); 764 SHUTDOWN(SSL_get_fd(con)); 765 ret=0; 766 end: 767 if(prexit) print_stuff(bio_c_out,con,1); 768 if (con != NULL) SSL_free(con); 769 if (con2 != NULL) SSL_free(con2); 770 if (ctx != NULL) SSL_CTX_free(ctx); 771 if (cbuf != NULL) { memset(cbuf,0,BUFSIZZ); OPENSSL_free(cbuf); } 772 if (sbuf != NULL) { memset(sbuf,0,BUFSIZZ); OPENSSL_free(sbuf); } 773 if (bio_c_out != NULL) 774 { 775 BIO_free(bio_c_out); 776 bio_c_out=NULL; 777 } 778 EXIT(ret); 779 } 780 781 782 static void print_stuff(BIO *bio, SSL *s, int full) 783 { 784 X509 *peer=NULL; 785 char *p; 786 static char *space=" "; 787 char buf[BUFSIZ]; 788 STACK_OF(X509) *sk; 789 STACK_OF(X509_NAME) *sk2; 790 SSL_CIPHER *c; 791 X509_NAME *xn; 792 int j,i; 793 794 if (full) 795 { 796 int got_a_chain = 0; 797 798 sk=SSL_get_peer_cert_chain(s); 799 if (sk != NULL) 800 { 801 got_a_chain = 1; /* we don't have it for SSL2 (yet) */ 802 803 BIO_printf(bio,"---\nCertificate chain\n"); 804 for (i=0; i<sk_X509_num(sk); i++) 805 { 806 X509_NAME_oneline(X509_get_subject_name( 807 sk_X509_value(sk,i)),buf,BUFSIZ); 808 BIO_printf(bio,"%2d s:%s\n",i,buf); 809 X509_NAME_oneline(X509_get_issuer_name( 810 sk_X509_value(sk,i)),buf,BUFSIZ); 811 BIO_printf(bio," i:%s\n",buf); 812 if (c_showcerts) 813 PEM_write_bio_X509(bio,sk_X509_value(sk,i)); 814 } 815 } 816 817 BIO_printf(bio,"---\n"); 818 peer=SSL_get_peer_certificate(s); 819 if (peer != NULL) 820 { 821 BIO_printf(bio,"Server certificate\n"); 822 if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */ 823 PEM_write_bio_X509(bio,peer); 824 X509_NAME_oneline(X509_get_subject_name(peer), 825 buf,BUFSIZ); 826 BIO_printf(bio,"subject=%s\n",buf); 827 X509_NAME_oneline(X509_get_issuer_name(peer), 828 buf,BUFSIZ); 829 BIO_printf(bio,"issuer=%s\n",buf); 830 } 831 else 832 BIO_printf(bio,"no peer certificate available\n"); 833 834 sk2=SSL_get_client_CA_list(s); 835 if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) 836 { 837 BIO_printf(bio,"---\nAcceptable client certificate CA names\n"); 838 for (i=0; i<sk_X509_NAME_num(sk2); i++) 839 { 840 xn=sk_X509_NAME_value(sk2,i); 841 X509_NAME_oneline(xn,buf,sizeof(buf)); 842 BIO_write(bio,buf,strlen(buf)); 843 BIO_write(bio,"\n",1); 844 } 845 } 846 else 847 { 848 BIO_printf(bio,"---\nNo client certificate CA names sent\n"); 849 } 850 p=SSL_get_shared_ciphers(s,buf,BUFSIZ); 851 if (p != NULL) 852 { 853 /* This works only for SSL 2. In later protocol 854 * versions, the client does not know what other 855 * ciphers (in addition to the one to be used 856 * in the current connection) the server supports. */ 857 858 BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n"); 859 j=i=0; 860 while (*p) 861 { 862 if (*p == ':') 863 { 864 BIO_write(bio,space,15-j%25); 865 i++; 866 j=0; 867 BIO_write(bio,((i%3)?" ":"\n"),1); 868 } 869 else 870 { 871 BIO_write(bio,p,1); 872 j++; 873 } 874 p++; 875 } 876 BIO_write(bio,"\n",1); 877 } 878 879 BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n", 880 BIO_number_read(SSL_get_rbio(s)), 881 BIO_number_written(SSL_get_wbio(s))); 882 } 883 BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, ")); 884 c=SSL_get_current_cipher(s); 885 BIO_printf(bio,"%s, Cipher is %s\n", 886 SSL_CIPHER_get_version(c), 887 SSL_CIPHER_get_name(c)); 888 if (peer != NULL) { 889 EVP_PKEY *pktmp; 890 pktmp = X509_get_pubkey(peer); 891 BIO_printf(bio,"Server public key is %d bit\n", 892 EVP_PKEY_bits(pktmp)); 893 EVP_PKEY_free(pktmp); 894 } 895 SSL_SESSION_print(bio,SSL_get_session(s)); 896 BIO_printf(bio,"---\n"); 897 if (peer != NULL) 898 X509_free(peer); 899 /* flush, or debugging output gets mixed with http response */ 900 BIO_flush(bio); 901 } 902 903