e6da658f06342eede973613ac138ac2a4cf0b52e
[openssl.git] / apps / sc.c
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 <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #define USE_SOCKETS
63 #ifdef NO_STDIO
64 #define APPS_WIN16
65 #endif
66 #include "apps.h"
67 #include <openssl/x509.h>
68 #include <openssl/ssl.h>
69 #include <openssl/err.h>
70 #include <openssl/pem.h>
71 #include "s_apps.h"
72
73 #ifdef WINDOWS
74 /* Most of the #if(n)def WINDOWS put in by Gerrit van Niekerk 
75    <gerritvn@osi.co.za> to support the keyboard under Windows.
76    Tested using Win95, *should* work with NT and Win3.x
77 */
78 #include <conio.h>
79 #endif
80
81 #undef PROG
82 #define PROG    s_client_main
83
84 /*#define SSL_HOST_NAME "www.netscape.com" */
85 /*#define SSL_HOST_NAME "193.118.187.102" */
86 #define SSL_HOST_NAME   "localhost"
87
88 /*#define TEST_CERT "client.pem" */ /* no default cert. */
89
90 #undef BUFSIZZ
91 #define BUFSIZZ 1024*8
92
93 extern int verify_depth;
94 extern int verify_error;
95
96 #ifdef FIONBIO
97 static int c_nbio=0;
98 #endif
99 static int c_Pause=0;
100 static int c_debug=0;
101
102 #ifndef NOPROTO
103 static void sc_usage(void);
104 static void print_stuff(BIO *berr,SSL *con,int full);
105 #else
106 static void sc_usage();
107 static void print_stuff();
108 #endif
109
110 static BIO *bio_c_out=NULL;
111 static int c_quiet=0;
112
113 static void sc_usage(void)
114         {
115         BIO_printf(bio_err,"usage: client args\n");
116         BIO_printf(bio_err,"\n");
117         BIO_printf(bio_err," -host host     - use -connect instead\n");
118         BIO_printf(bio_err," -port port     - use -connect instead\n");
119         BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
120
121         BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
122         BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
123         BIO_printf(bio_err," -key arg      - Private key file to use, PEM format assumed, in cert file if\n");
124         BIO_printf(bio_err,"                 not specified but cert file is.\n");
125         BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
126         BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
127         BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
128         BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
129         BIO_printf(bio_err," -debug        - extra output\n");
130         BIO_printf(bio_err," -nbio_test    - more ssl protocol testing\n");
131         BIO_printf(bio_err," -state        - print the 'ssl' states\n");
132 #ifdef FIONBIO
133         BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
134 #endif
135         BIO_printf(bio_err," -quiet        - no s_client output\n");
136         BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
137         BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
138         BIO_printf(bio_err," -tls1         - just use TLSv1\n");
139         BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
140         BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
141         BIO_printf(bio_err," -cipher       - prefered cipher to use, use the 'openssl ciphers'\n");
142         BIO_printf(bio_err,"                 command to see what is available\n");
143
144         }
145
146 int MAIN(int argc, char **argv)
147         {
148         int off=0;
149         SSL *con=NULL,*con2=NULL;
150         int s,k,width,state=0;
151         char *cbuf=NULL,*sbuf=NULL;
152         int cbuf_len,cbuf_off;
153         int sbuf_len,sbuf_off;
154         fd_set readfds,writefds;
155         short port=PORT;
156         int full_log=1;
157         char *host=SSL_HOST_NAME;
158         char *cert_file=NULL,*key_file=NULL;
159         char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
160         int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
161         int write_tty,read_tty,write_ssl,read_ssl,tty_on;
162         SSL_CTX *ctx=NULL;
163         int ret=1,in_init=1,i,nbio_test=0;
164         SSL_METHOD *meth=NULL;
165         BIO *sbio;
166         /*static struct timeval timeout={10,0};*/
167
168 #if !defined(NO_SSL2) && !defined(NO_SSL3)
169         meth=SSLv23_client_method();
170 #elif !defined(NO_SSL3)
171         meth=SSLv3_client_method();
172 #elif !defined(NO_SSL2)
173         meth=SSLv2_client_method();
174 #endif
175
176         apps_startup();
177         c_Pause=0;
178         c_quiet=0;
179         c_debug=0;
180
181         if (bio_err == NULL)
182                 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
183
184         if (    ((cbuf=Malloc(BUFSIZZ)) == NULL) ||
185                 ((sbuf=Malloc(BUFSIZZ)) == NULL))
186                 {
187                 BIO_printf(bio_err,"out of memory\n");
188                 goto end;
189                 }
190
191         verify_depth=0;
192         verify_error=X509_V_OK;
193 #ifdef FIONBIO
194         c_nbio=0;
195 #endif
196 #ifdef WINDOWS
197         c_nbio = 1;
198 #endif
199
200         argc--;
201         argv++;
202         while (argc >= 1)
203                 {
204                 if      (strcmp(*argv,"-host") == 0)
205                         {
206                         if (--argc < 1) goto bad;
207                         host= *(++argv);
208                         }
209                 else if (strcmp(*argv,"-port") == 0)
210                         {
211                         if (--argc < 1) goto bad;
212                         port=atoi(*(++argv));
213                         if (port == 0) goto bad;
214                         }
215                 else if (strcmp(*argv,"-connect") == 0)
216                         {
217                         if (--argc < 1) goto bad;
218                         if (!extract_host_port(*(++argv),&host,NULL,&port))
219                                 goto bad;
220                         }
221                 else if (strcmp(*argv,"-verify") == 0)
222                         {
223                         verify=SSL_VERIFY_PEER;
224                         if (--argc < 1) goto bad;
225                         verify_depth=atoi(*(++argv));
226                         BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
227                         }
228                 else if (strcmp(*argv,"-cert") == 0)
229                         {
230                         if (--argc < 1) goto bad;
231                         cert_file= *(++argv);
232                         }
233                 else if (strcmp(*argv,"-quiet") == 0)
234                         c_quiet=1;
235                 else if (strcmp(*argv,"-pause") == 0)
236                         c_Pause=1;
237                 else if (strcmp(*argv,"-debug") == 0)
238                         c_debug=1;
239                 else if (strcmp(*argv,"-nbio_test") == 0)
240                         nbio_test=1;
241                 else if (strcmp(*argv,"-state") == 0)
242                         state=1;
243 #ifndef NO_SSL2
244                 else if (strcmp(*argv,"-ssl2") == 0)
245                         meth=SSLv2_client_method();
246 #endif
247 #ifndef NO_SSL3
248                 else if (strcmp(*argv,"-ssl3") == 0)
249                         meth=SSLv3_client_method();
250 #endif
251 #ifndef NO_TLS1
252                 else if (strcmp(*argv,"-tls1") == 0)
253                         meth=TLSv1_client_method();
254 #endif
255                 else if (strcmp(*argv,"-bugs") == 0)
256                         bugs=1;
257                 else if (strcmp(*argv,"-key") == 0)
258                         {
259                         if (--argc < 1) goto bad;
260                         key_file= *(++argv);
261                         }
262                 else if (strcmp(*argv,"-reconnect") == 0)
263                         {
264                         reconnect=5;
265                         }
266                 else if (strcmp(*argv,"-CApath") == 0)
267                         {
268                         if (--argc < 1) goto bad;
269                         CApath= *(++argv);
270                         }
271                 else if (strcmp(*argv,"-CAfile") == 0)
272                         {
273                         if (--argc < 1) goto bad;
274                         CAfile= *(++argv);
275                         }
276                 else if (strcmp(*argv,"-no_tls1") == 0)
277                         off|=SSL_OP_NO_TLSv1;
278                 else if (strcmp(*argv,"-no_ssl3") == 0)
279                         off|=SSL_OP_NO_SSLv3;
280                 else if (strcmp(*argv,"-no_ssl2") == 0)
281                         off|=SSL_OP_NO_SSLv2;
282                 else if (strcmp(*argv,"-cipher") == 0)
283                         {
284                         if (--argc < 1) goto bad;
285                         cipher= *(++argv);
286                         }
287 #ifdef FIONBIO
288                 else if (strcmp(*argv,"-nbio") == 0)
289                         { c_nbio=1; }
290 #endif
291                 else
292                         {
293                         BIO_printf(bio_err,"unknown option %s\n",*argv);
294                         badop=1;
295                         break;
296                         }
297                 argc--;
298                 argv++;
299                 }
300         if (badop)
301                 {
302 bad:
303                 sc_usage();
304                 goto end;
305                 }
306
307         if (bio_c_out == NULL)
308                 {
309                 if (c_quiet)
310                         {
311                         bio_c_out=BIO_new(BIO_s_null());
312                         }
313                 else
314                         {
315                         if (bio_c_out == NULL)
316                                 bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
317                         }
318                 }
319
320         SSLeay_add_ssl_algorithms();
321         ctx=SSL_CTX_new(meth);
322         if (ctx == NULL)
323                 {
324                 ERR_print_errors(bio_err);
325                 goto end;
326                 }
327
328         if (bugs)
329                 SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
330         else
331                 SSL_CTX_set_options(ctx,off);
332
333         if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
334         if (cipher != NULL)
335                 SSL_CTX_set_cipher_list(ctx,cipher);
336 #if 0
337         else
338                 SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
339 #endif
340
341         SSL_CTX_set_verify(ctx,verify,verify_callback);
342         if (!set_cert_stuff(ctx,cert_file,key_file))
343                 goto end;
344
345         if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
346                 (!SSL_CTX_set_default_verify_paths(ctx)))
347                 {
348                 /* BIO_printf(bio_err,"error seting default verify locations\n"); */
349                 ERR_print_errors(bio_err);
350                 /* goto end; */
351                 }
352
353         SSL_load_error_strings();
354
355         con=(SSL *)SSL_new(ctx);
356 /*      SSL_set_cipher_list(con,"RC4-MD5"); */
357
358 re_start:
359
360         if (init_client(&s,host,port) == 0)
361                 {
362                 BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
363                 SHUTDOWN(s);
364                 goto end;
365                 }
366         BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
367
368 #ifdef FIONBIO
369         if (c_nbio)
370                 {
371                 unsigned long l=1;
372                 BIO_printf(bio_c_out,"turning on non blocking io\n");
373                 if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
374                         {
375                         ERR_print_errors(bio_err);
376                         goto end;
377                         }
378                 }
379 #endif                                              
380         if (c_Pause & 0x01) con->debug=1;
381         sbio=BIO_new_socket(s,BIO_NOCLOSE);
382
383         if (nbio_test)
384                 {
385                 BIO *test;
386
387                 test=BIO_new(BIO_f_nbio_test());
388                 sbio=BIO_push(test,sbio);
389                 }
390
391         if (c_debug)
392                 {
393                 con->debug=1;
394                 BIO_set_callback(sbio,bio_dump_cb);
395                 BIO_set_callback_arg(sbio,bio_c_out);
396                 }
397
398         SSL_set_bio(con,sbio,sbio);
399         SSL_set_connect_state(con);
400
401         /* ok, lets connect */
402         width=SSL_get_fd(con)+1;
403
404         read_tty=1;
405         write_tty=0;
406         tty_on=0;
407         read_ssl=1;
408         write_ssl=1;
409         
410         cbuf_len=0;
411         cbuf_off=0;
412         sbuf_len=0;
413         sbuf_off=0;
414
415         for (;;)
416                 {
417                 FD_ZERO(&readfds);
418                 FD_ZERO(&writefds);
419
420                 if (SSL_in_init(con) && !SSL_total_renegotiations(con))
421                         {
422                         in_init=1;
423                         tty_on=0;
424                         }
425                 else
426                         {
427                         tty_on=1;
428                         if (in_init)
429                                 {
430                                 in_init=0;
431                                 print_stuff(bio_c_out,con,full_log);
432                                 if (full_log > 0) full_log--;
433
434                                 if (reconnect)
435                                         {
436                                         reconnect--;
437                                         BIO_printf(bio_c_out,"drop connection and then reconnect\n");
438                                         SSL_shutdown(con);
439                                         SSL_set_connect_state(con);
440                                         SHUTDOWN(SSL_get_fd(con));
441                                         goto re_start;
442                                         }
443                                 }
444                         }
445
446 #ifndef WINDOWS
447                 if (tty_on)
448                         {
449                         if (read_tty)  FD_SET(fileno(stdin),&readfds);
450                         if (write_tty) FD_SET(fileno(stdout),&writefds);
451                         }
452 #endif
453                 if (read_ssl)
454                         FD_SET(SSL_get_fd(con),&readfds);
455                 if (write_ssl)
456                         FD_SET(SSL_get_fd(con),&writefds);
457
458 /*              printf("mode tty(%d %d%d) ssl(%d%d)\n",
459                         tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
460
461 #ifndef WINDOWS
462                 i=select(width,&readfds,&writefds,NULL,NULL);
463                 if ( i < 0)
464                         {
465                         BIO_printf(bio_err,"bad select %d\n",
466                                 get_last_socket_error());
467                         goto shut;
468                         /* goto end; */
469                         }
470
471                 if (FD_ISSET(SSL_get_fd(con),&writefds))
472 #else
473                 if (write_ssl)
474 #endif
475                         {
476                         k=SSL_write(con,&(cbuf[cbuf_off]),
477                                 (unsigned int)cbuf_len);
478                         switch (SSL_get_error(con,k))
479                                 {
480                         case SSL_ERROR_NONE:
481                                 cbuf_off+=k;
482                                 cbuf_len-=k;
483                                 if (k <= 0) goto end;
484                                 /* we have done a  write(con,NULL,0); */
485                                 if (cbuf_len <= 0)
486                                         {
487                                         read_tty=1;
488                                         write_ssl=0;
489                                         }
490                                 else /* if (cbuf_len > 0) */
491                                         {
492                                         read_tty=0;
493                                         write_ssl=1;
494                                         }
495                                 break;
496                         case SSL_ERROR_WANT_WRITE:
497 #ifndef WINDOWS
498                                 BIO_printf(bio_c_out,"write W BLOCK\n");
499 #endif
500                                 write_ssl=1;
501                                 read_tty=0;
502                                 break;
503                         case SSL_ERROR_WANT_READ:
504 #ifndef WINDOWS
505                                 BIO_printf(bio_c_out,"write R BLOCK\n");
506 #endif
507                                 write_tty=0;
508                                 read_ssl=1;
509                                 write_ssl=0;
510                                 break;
511                         case SSL_ERROR_WANT_X509_LOOKUP:
512                                 BIO_printf(bio_c_out,"write X BLOCK\n");
513                                 break;
514                         case SSL_ERROR_ZERO_RETURN:
515                                 if (cbuf_len != 0)
516                                         {
517                                         BIO_printf(bio_c_out,"shutdown\n");
518                                         goto shut;
519                                         }
520                                 else
521                                         {
522                                         read_tty=1;
523                                         write_ssl=0;
524                                         break;
525                                         }
526                                 
527                         case SSL_ERROR_SYSCALL:
528                                 if ((k != 0) || (cbuf_len != 0))
529                                         {
530                                         BIO_printf(bio_err,"write:errno=%d\n",
531                                                 get_last_socket_error());
532                                         goto shut;
533                                         }
534                                 else
535                                         {
536                                         read_tty=1;
537                                         write_ssl=0;
538                                         }
539                                 break;
540                         case SSL_ERROR_SSL:
541                                 ERR_print_errors(bio_err);
542                                 goto shut;
543                                 }
544                         }
545 #ifndef WINDOWS
546                 else if (FD_ISSET(fileno(stdout),&writefds))
547 #else
548                 else if (tty_on && write_tty)
549 #endif
550                         {
551                         i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
552
553                         if (i <= 0)
554                                 {
555                                 BIO_printf(bio_c_out,"DONE\n");
556                                 goto shut;
557                                 /* goto end; */
558                                 }
559
560                         sbuf_len-=i;;
561                         sbuf_off+=i;
562                         if (sbuf_len <= 0)
563                                 {
564                                 read_ssl=1;
565                                 write_tty=0;
566                                 }
567                         }
568 #ifndef WINDOWS
569                 else if (FD_ISSET(SSL_get_fd(con),&readfds))
570 #else
571                 if (read_ssl)
572 #endif
573                         {
574 #ifdef RENEG
575 { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
576 #endif
577                         k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
578
579                         switch (SSL_get_error(con,k))
580                                 {
581                         case SSL_ERROR_NONE:
582                                 if (k <= 0)
583                                         goto end;
584                                 sbuf_off=0;
585                                 sbuf_len=k;
586
587                                 read_ssl=0;
588                                 write_tty=1;
589                                 break;
590                         case SSL_ERROR_WANT_WRITE:
591 #ifndef WINDOWS
592                                 BIO_printf(bio_c_out,"read W BLOCK\n");
593 #endif
594                                 write_ssl=1;
595                                 read_tty=0;
596                                 break;
597                         case SSL_ERROR_WANT_READ:
598 #ifndef WINDOWS
599                                 BIO_printf(bio_c_out,"read R BLOCK\n");
600 #endif
601                                 write_tty=0;
602                                 read_ssl=1;
603                                 if ((read_tty == 0) && (write_ssl == 0))
604                                         write_ssl=1;
605                                 break;
606                         case SSL_ERROR_WANT_X509_LOOKUP:
607                                 BIO_printf(bio_c_out,"read X BLOCK\n");
608                                 break;
609                         case SSL_ERROR_SYSCALL:
610                                 BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
611                                 goto shut;
612                         case SSL_ERROR_ZERO_RETURN:
613                                 BIO_printf(bio_c_out,"closed\n");
614                                 goto shut;
615                         case SSL_ERROR_SSL:
616                                 ERR_print_errors(bio_err);
617                                 goto shut;
618                                 break;
619                                 }
620                         }
621
622 #ifndef WINDOWS
623                 else if (FD_ISSET(fileno(stdin),&readfds))
624                         {
625                         i=read(fileno(stdin),cbuf,BUFSIZZ);
626 #else
627                 if (tty_on && read_tty && _kbhit())
628                         {
629                         i = 1;
630                         cbuf[0] = _getch();
631 #endif
632
633                         if ((!c_quiet) && ((i <= 0) || (cbuf[0] == 'Q')))
634                                 {
635                                 BIO_printf(bio_err,"DONE\n");
636                                 goto shut;
637                                 }
638
639                         if ((!c_quiet) && (cbuf[0] == 'R'))
640                                 {
641                                 SSL_renegotiate(con);
642                                 read_tty=0;
643                                 write_ssl=1;
644                                 }
645                         else
646                                 {
647                                 cbuf_len=i;
648                                 cbuf_off=0;
649                                 }
650
651                         read_tty=0;
652                         write_ssl=1;
653                         }
654                 }
655 shut:
656         SSL_shutdown(con);
657         SHUTDOWN(SSL_get_fd(con));
658         ret=0;
659 end:
660         if (con != NULL) SSL_free(con);
661         if (con2 != NULL) SSL_free(con2);
662         if (ctx != NULL) SSL_CTX_free(ctx);
663         if (cbuf != NULL) { memset(cbuf,0,BUFSIZZ); Free(cbuf); }
664         if (sbuf != NULL) { memset(sbuf,0,BUFSIZZ); Free(sbuf); }
665         if (bio_c_out != NULL)
666                 {
667                 BIO_free(bio_c_out);
668                 bio_c_out=NULL;
669                 }
670         EXIT(ret);
671         }
672
673
674 static void print_stuff(bio,s,full)
675 BIO *bio;
676 SSL *s;
677 int full;
678         {
679         X509 *peer=NULL;
680         char *p;
681         static char *space="                ";
682         char buf[BUFSIZ];
683         STACK *sk;
684         SSL_CIPHER *c;
685         X509_NAME *xn;
686         int j,i;
687
688         if (full)
689                 {
690                 sk=SSL_get_peer_cert_chain(s);
691                 if (sk != NULL)
692                         {
693                         BIO_printf(bio,"---\nCertificate chain\n");
694                         for (i=0; i<sk_num(sk); i++)
695                                 {
696                                 X509_NAME_oneline(X509_get_subject_name((X509 *)
697                                         sk_value(sk,i)),buf,BUFSIZ);
698                                 BIO_printf(bio,"%2d s:%s\n",i,buf);
699                                 X509_NAME_oneline(X509_get_issuer_name((X509 *)
700                                         sk_value(sk,i)),buf,BUFSIZ);
701                                 BIO_printf(bio,"   i:%s\n",buf);
702                                 }
703                         }
704
705                 BIO_printf(bio,"---\n");
706                 peer=SSL_get_peer_certificate(s);
707                 if (peer != NULL)
708                         {
709                         BIO_printf(bio,"Server certificate\n");
710                         PEM_write_bio_X509(bio,peer);
711                         X509_NAME_oneline(X509_get_subject_name(peer),
712                                 buf,BUFSIZ);
713                         BIO_printf(bio,"subject=%s\n",buf);
714                         X509_NAME_oneline(X509_get_issuer_name(peer),
715                                 buf,BUFSIZ);
716                         BIO_printf(bio,"issuer=%s\n",buf);
717                         }
718                 else
719                         BIO_printf(bio,"no peer certificate available\n");
720
721                 sk=SSL_get_client_CA_list(s);
722                 if ((sk != NULL) && (sk_num(sk) > 0))
723                         {
724                         BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
725                         for (i=0; i<sk_num(sk); i++)
726                                 {
727                                 xn=(X509_NAME *)sk_value(sk,i);
728                                 X509_NAME_oneline(xn,buf,sizeof(buf));
729                                 BIO_write(bio,buf,strlen(buf));
730                                 BIO_write(bio,"\n",1);
731                                 }
732                         }
733                 else
734                         {
735                         BIO_printf(bio,"---\nNo client certificate CA names sent\n");
736                         }
737                 p=SSL_get_shared_ciphers(s,buf,BUFSIZ);
738                 if (p != NULL)
739                         {
740                         BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
741                         j=i=0;
742                         while (*p)
743                                 {
744                                 if (*p == ':')
745                                         {
746                                         BIO_write(bio,space,15-j%25);
747                                         i++;
748                                         j=0;
749                                         BIO_write(bio,((i%3)?" ":"\n"),1);
750                                         }
751                                 else
752                                         {
753                                         BIO_write(bio,p,1);
754                                         j++;
755                                         }
756                                 p++;
757                                 }
758                         BIO_write(bio,"\n",1);
759                         }
760
761                 BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
762                         BIO_number_read(SSL_get_rbio(s)),
763                         BIO_number_written(SSL_get_wbio(s)));
764                 }
765         BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
766         c=SSL_get_current_cipher(s);
767         BIO_printf(bio,"%s, Cipher is %s\n",
768                 SSL_CIPHER_get_version(c),
769                 SSL_CIPHER_get_name(c));
770         if (peer != NULL)
771         {
772                 EVP_PKEY *pktmp;
773                 BIO_printf(bio,"Server public key is %d bit\n",
774                                                         EVP_PKEY_bits(pktmp));
775                 EVP_PKEY_free(pktmp);
776         }
777         SSL_SESSION_print(bio,SSL_get_session(s));
778         BIO_printf(bio,"---\n");
779         if (peer != NULL)
780                 X509_free(peer);
781         }
782