s_client.c revision 76866
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
73typedef 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
107extern int verify_depth;
108extern int verify_error;
109
110#ifdef FIONBIO
111static int c_nbio=0;
112#endif
113static int c_Pause=0;
114static int c_debug=0;
115static int c_showcerts=0;
116
117static void sc_usage(void);
118static void print_stuff(BIO *berr,SSL *con,int full);
119static BIO *bio_c_out=NULL;
120static int c_quiet=0;
121static int c_ign_eof=0;
122
123static 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
160int MAIN(int, char **);
161
162int 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		{
338bad:
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
407re_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];
663printf("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		}
762shut:
763	SSL_shutdown(con);
764	SHUTDOWN(SSL_get_fd(con));
765	ret=0;
766end:
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
782static 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	}
900
901