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