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