xref: /freebsd/crypto/openssl/apps/s_client.c (revision 3ff369fed2a08f32dda232c10470b949bef9489f)
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