10Sstevel@tonic-gate /* apps/s_client.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate /* ====================================================================
590Sstevel@tonic-gate * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
600Sstevel@tonic-gate *
610Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
620Sstevel@tonic-gate * modification, are permitted provided that the following conditions
630Sstevel@tonic-gate * are met:
640Sstevel@tonic-gate *
650Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
660Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
670Sstevel@tonic-gate *
680Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
690Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
700Sstevel@tonic-gate * the documentation and/or other materials provided with the
710Sstevel@tonic-gate * distribution.
720Sstevel@tonic-gate *
730Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
740Sstevel@tonic-gate * software must display the following acknowledgment:
750Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
760Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
770Sstevel@tonic-gate *
780Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
790Sstevel@tonic-gate * endorse or promote products derived from this software without
800Sstevel@tonic-gate * prior written permission. For written permission, please contact
810Sstevel@tonic-gate * openssl-core@openssl.org.
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
840Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
850Sstevel@tonic-gate * permission of the OpenSSL Project.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
880Sstevel@tonic-gate * acknowledgment:
890Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
900Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
910Sstevel@tonic-gate *
920Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
930Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
940Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
950Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
960Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
970Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
980Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
990Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1000Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1010Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1020Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1030Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
1040Sstevel@tonic-gate * ====================================================================
1050Sstevel@tonic-gate *
1060Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
1070Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
1080Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
1090Sstevel@tonic-gate *
1100Sstevel@tonic-gate */
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate #include <assert.h>
1130Sstevel@tonic-gate #include <stdio.h>
1140Sstevel@tonic-gate #include <stdlib.h>
1150Sstevel@tonic-gate #include <string.h>
1160Sstevel@tonic-gate #include <openssl/e_os2.h>
1170Sstevel@tonic-gate #ifdef OPENSSL_NO_STDIO
1180Sstevel@tonic-gate #define APPS_WIN16
1190Sstevel@tonic-gate #endif
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate /* With IPv6, it looks like Digital has mixed up the proper order of
1220Sstevel@tonic-gate recursive header file inclusion, resulting in the compiler complaining
1230Sstevel@tonic-gate that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
1240Sstevel@tonic-gate is needed to have fileno() declared correctly... So let's define u_int */
1250Sstevel@tonic-gate #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
1260Sstevel@tonic-gate #define __U_INT
1270Sstevel@tonic-gate typedef unsigned int u_int;
1280Sstevel@tonic-gate #endif
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate #define USE_SOCKETS
1310Sstevel@tonic-gate #include "apps.h"
1320Sstevel@tonic-gate #include <openssl/x509.h>
1330Sstevel@tonic-gate #include <openssl/ssl.h>
1340Sstevel@tonic-gate #include <openssl/err.h>
1350Sstevel@tonic-gate #include <openssl/pem.h>
1360Sstevel@tonic-gate #include <openssl/rand.h>
1370Sstevel@tonic-gate #include "s_apps.h"
138*2139Sjp161948 #include "timeouts.h"
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINCE
1410Sstevel@tonic-gate /* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
1420Sstevel@tonic-gate #ifdef fileno
1430Sstevel@tonic-gate #undef fileno
1440Sstevel@tonic-gate #endif
1450Sstevel@tonic-gate #define fileno(a) (int)_fileno(a)
1460Sstevel@tonic-gate #endif
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate
1490Sstevel@tonic-gate #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
1500Sstevel@tonic-gate /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
1510Sstevel@tonic-gate #undef FIONBIO
1520Sstevel@tonic-gate #endif
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate #undef PROG
1550Sstevel@tonic-gate #define PROG s_client_main
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate /*#define SSL_HOST_NAME "www.netscape.com" */
1580Sstevel@tonic-gate /*#define SSL_HOST_NAME "193.118.187.102" */
1590Sstevel@tonic-gate #define SSL_HOST_NAME "localhost"
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate /*#define TEST_CERT "client.pem" */ /* no default cert. */
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate #undef BUFSIZZ
1640Sstevel@tonic-gate #define BUFSIZZ 1024*8
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate extern int verify_depth;
1670Sstevel@tonic-gate extern int verify_error;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate #ifdef FIONBIO
1700Sstevel@tonic-gate static int c_nbio=0;
1710Sstevel@tonic-gate #endif
1720Sstevel@tonic-gate static int c_Pause=0;
1730Sstevel@tonic-gate static int c_debug=0;
1740Sstevel@tonic-gate static int c_msg=0;
1750Sstevel@tonic-gate static int c_showcerts=0;
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate static void sc_usage(void);
1780Sstevel@tonic-gate static void print_stuff(BIO *berr,SSL *con,int full);
1790Sstevel@tonic-gate static BIO *bio_c_out=NULL;
1800Sstevel@tonic-gate static int c_quiet=0;
1810Sstevel@tonic-gate static int c_ign_eof=0;
1820Sstevel@tonic-gate
sc_usage(void)1830Sstevel@tonic-gate static void sc_usage(void)
1840Sstevel@tonic-gate {
1850Sstevel@tonic-gate BIO_printf(bio_err,"usage: s_client args\n");
1860Sstevel@tonic-gate BIO_printf(bio_err,"\n");
1870Sstevel@tonic-gate BIO_printf(bio_err," -host host - use -connect instead\n");
1880Sstevel@tonic-gate BIO_printf(bio_err," -port port - use -connect instead\n");
1890Sstevel@tonic-gate BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n");
1920Sstevel@tonic-gate BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n");
193*2139Sjp161948 BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
194*2139Sjp161948 BIO_printf(bio_err," -key arg - Private key file to use, in cert file if\n");
1950Sstevel@tonic-gate BIO_printf(bio_err," not specified but cert file is.\n");
196*2139Sjp161948 BIO_printf(bio_err," -keyform arg - key format (PEM or DER) PEM default\n");
197*2139Sjp161948 BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
1980Sstevel@tonic-gate BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
1990Sstevel@tonic-gate BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
2000Sstevel@tonic-gate BIO_printf(bio_err," -reconnect - Drop and re-make the connection with the same Session-ID\n");
2010Sstevel@tonic-gate BIO_printf(bio_err," -pause - sleep(1) after each read(2) and write(2) system call\n");
2020Sstevel@tonic-gate BIO_printf(bio_err," -showcerts - show all certificates in the chain\n");
2030Sstevel@tonic-gate BIO_printf(bio_err," -debug - extra output\n");
204*2139Sjp161948 #ifdef WATT32
205*2139Sjp161948 BIO_printf(bio_err," -wdebug - WATT-32 tcp debugging\n");
206*2139Sjp161948 #endif
2070Sstevel@tonic-gate BIO_printf(bio_err," -msg - Show protocol messages\n");
2080Sstevel@tonic-gate BIO_printf(bio_err," -nbio_test - more ssl protocol testing\n");
2090Sstevel@tonic-gate BIO_printf(bio_err," -state - print the 'ssl' states\n");
2100Sstevel@tonic-gate #ifdef FIONBIO
2110Sstevel@tonic-gate BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
2120Sstevel@tonic-gate #endif
2130Sstevel@tonic-gate BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
2140Sstevel@tonic-gate BIO_printf(bio_err," -quiet - no s_client output\n");
2150Sstevel@tonic-gate BIO_printf(bio_err," -ign_eof - ignore input eof (default when -quiet)\n");
2160Sstevel@tonic-gate BIO_printf(bio_err," -ssl2 - just use SSLv2\n");
2170Sstevel@tonic-gate BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
2180Sstevel@tonic-gate BIO_printf(bio_err," -tls1 - just use TLSv1\n");
219*2139Sjp161948 BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
220*2139Sjp161948 BIO_printf(bio_err," -mtu - set the MTU\n");
2210Sstevel@tonic-gate BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
2220Sstevel@tonic-gate BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
2230Sstevel@tonic-gate BIO_printf(bio_err," -serverpref - Use server's cipher preferences (only SSLv2)\n");
2240Sstevel@tonic-gate BIO_printf(bio_err," -cipher - preferred cipher to use, use the 'openssl ciphers'\n");
2250Sstevel@tonic-gate BIO_printf(bio_err," command to see what is available\n");
2260Sstevel@tonic-gate BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
2270Sstevel@tonic-gate BIO_printf(bio_err," for those protocols that support it, where\n");
2280Sstevel@tonic-gate BIO_printf(bio_err," 'prot' defines which one to assume. Currently,\n");
2290Sstevel@tonic-gate BIO_printf(bio_err," only \"smtp\" and \"pop3\" are supported.\n");
2300Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2310Sstevel@tonic-gate BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
2320Sstevel@tonic-gate #endif
2330Sstevel@tonic-gate BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate int MAIN(int, char **);
2380Sstevel@tonic-gate
MAIN(int argc,char ** argv)2390Sstevel@tonic-gate int MAIN(int argc, char **argv)
2400Sstevel@tonic-gate {
2410Sstevel@tonic-gate int off=0;
2420Sstevel@tonic-gate SSL *con=NULL,*con2=NULL;
2430Sstevel@tonic-gate X509_STORE *store = NULL;
2440Sstevel@tonic-gate int s,k,width,state=0;
2450Sstevel@tonic-gate char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
2460Sstevel@tonic-gate int cbuf_len,cbuf_off;
2470Sstevel@tonic-gate int sbuf_len,sbuf_off;
2480Sstevel@tonic-gate fd_set readfds,writefds;
2490Sstevel@tonic-gate short port=PORT;
2500Sstevel@tonic-gate int full_log=1;
2510Sstevel@tonic-gate char *host=SSL_HOST_NAME;
2520Sstevel@tonic-gate char *cert_file=NULL,*key_file=NULL;
253*2139Sjp161948 int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
254*2139Sjp161948 char *passarg = NULL, *pass = NULL;
255*2139Sjp161948 X509 *cert = NULL;
256*2139Sjp161948 EVP_PKEY *key = NULL;
2570Sstevel@tonic-gate char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
2580Sstevel@tonic-gate int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
2590Sstevel@tonic-gate int crlf=0;
2600Sstevel@tonic-gate int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
2610Sstevel@tonic-gate SSL_CTX *ctx=NULL;
2620Sstevel@tonic-gate int ret=1,in_init=1,i,nbio_test=0;
2630Sstevel@tonic-gate int starttls_proto = 0;
2640Sstevel@tonic-gate int prexit = 0, vflags = 0;
2650Sstevel@tonic-gate SSL_METHOD *meth=NULL;
266*2139Sjp161948 #ifdef sock_type
267*2139Sjp161948 #undef sock_type
268*2139Sjp161948 #endif
269*2139Sjp161948 int sock_type=SOCK_STREAM;
2700Sstevel@tonic-gate BIO *sbio;
2710Sstevel@tonic-gate char *inrand=NULL;
2720Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2730Sstevel@tonic-gate char *engine_id=NULL;
2740Sstevel@tonic-gate ENGINE *e=NULL;
2750Sstevel@tonic-gate #endif
276*2139Sjp161948 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
2770Sstevel@tonic-gate struct timeval tv;
2780Sstevel@tonic-gate #endif
2790Sstevel@tonic-gate
280*2139Sjp161948 struct sockaddr peer;
281*2139Sjp161948 int peerlen = sizeof(peer);
282*2139Sjp161948 int enable_timeouts = 0 ;
283*2139Sjp161948 long mtu = 0;
284*2139Sjp161948
2850Sstevel@tonic-gate #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
2860Sstevel@tonic-gate meth=SSLv23_client_method();
2870Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL3)
2880Sstevel@tonic-gate meth=SSLv3_client_method();
2890Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL2)
2900Sstevel@tonic-gate meth=SSLv2_client_method();
2910Sstevel@tonic-gate #endif
2920Sstevel@tonic-gate
2930Sstevel@tonic-gate apps_startup();
2940Sstevel@tonic-gate c_Pause=0;
2950Sstevel@tonic-gate c_quiet=0;
2960Sstevel@tonic-gate c_ign_eof=0;
2970Sstevel@tonic-gate c_debug=0;
2980Sstevel@tonic-gate c_msg=0;
2990Sstevel@tonic-gate c_showcerts=0;
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate if (bio_err == NULL)
3020Sstevel@tonic-gate bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
3030Sstevel@tonic-gate
3040Sstevel@tonic-gate if (!load_config(bio_err, NULL))
3050Sstevel@tonic-gate goto end;
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate if ( ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
3080Sstevel@tonic-gate ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
3090Sstevel@tonic-gate ((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
3100Sstevel@tonic-gate {
3110Sstevel@tonic-gate BIO_printf(bio_err,"out of memory\n");
3120Sstevel@tonic-gate goto end;
3130Sstevel@tonic-gate }
3140Sstevel@tonic-gate
3150Sstevel@tonic-gate verify_depth=0;
3160Sstevel@tonic-gate verify_error=X509_V_OK;
3170Sstevel@tonic-gate #ifdef FIONBIO
3180Sstevel@tonic-gate c_nbio=0;
3190Sstevel@tonic-gate #endif
3200Sstevel@tonic-gate
3210Sstevel@tonic-gate argc--;
3220Sstevel@tonic-gate argv++;
3230Sstevel@tonic-gate while (argc >= 1)
3240Sstevel@tonic-gate {
3250Sstevel@tonic-gate if (strcmp(*argv,"-host") == 0)
3260Sstevel@tonic-gate {
3270Sstevel@tonic-gate if (--argc < 1) goto bad;
3280Sstevel@tonic-gate host= *(++argv);
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate else if (strcmp(*argv,"-port") == 0)
3310Sstevel@tonic-gate {
3320Sstevel@tonic-gate if (--argc < 1) goto bad;
3330Sstevel@tonic-gate port=atoi(*(++argv));
3340Sstevel@tonic-gate if (port == 0) goto bad;
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate else if (strcmp(*argv,"-connect") == 0)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate if (--argc < 1) goto bad;
3390Sstevel@tonic-gate if (!extract_host_port(*(++argv),&host,NULL,&port))
3400Sstevel@tonic-gate goto bad;
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate else if (strcmp(*argv,"-verify") == 0)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate verify=SSL_VERIFY_PEER;
3450Sstevel@tonic-gate if (--argc < 1) goto bad;
3460Sstevel@tonic-gate verify_depth=atoi(*(++argv));
3470Sstevel@tonic-gate BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate else if (strcmp(*argv,"-cert") == 0)
3500Sstevel@tonic-gate {
3510Sstevel@tonic-gate if (--argc < 1) goto bad;
3520Sstevel@tonic-gate cert_file= *(++argv);
3530Sstevel@tonic-gate }
354*2139Sjp161948 else if (strcmp(*argv,"-certform") == 0)
355*2139Sjp161948 {
356*2139Sjp161948 if (--argc < 1) goto bad;
357*2139Sjp161948 cert_format = str2fmt(*(++argv));
358*2139Sjp161948 }
3590Sstevel@tonic-gate else if (strcmp(*argv,"-crl_check") == 0)
3600Sstevel@tonic-gate vflags |= X509_V_FLAG_CRL_CHECK;
3610Sstevel@tonic-gate else if (strcmp(*argv,"-crl_check_all") == 0)
3620Sstevel@tonic-gate vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
3630Sstevel@tonic-gate else if (strcmp(*argv,"-prexit") == 0)
3640Sstevel@tonic-gate prexit=1;
3650Sstevel@tonic-gate else if (strcmp(*argv,"-crlf") == 0)
3660Sstevel@tonic-gate crlf=1;
3670Sstevel@tonic-gate else if (strcmp(*argv,"-quiet") == 0)
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate c_quiet=1;
3700Sstevel@tonic-gate c_ign_eof=1;
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate else if (strcmp(*argv,"-ign_eof") == 0)
3730Sstevel@tonic-gate c_ign_eof=1;
3740Sstevel@tonic-gate else if (strcmp(*argv,"-pause") == 0)
3750Sstevel@tonic-gate c_Pause=1;
3760Sstevel@tonic-gate else if (strcmp(*argv,"-debug") == 0)
3770Sstevel@tonic-gate c_debug=1;
378*2139Sjp161948 #ifdef WATT32
379*2139Sjp161948 else if (strcmp(*argv,"-wdebug") == 0)
380*2139Sjp161948 dbug_init();
381*2139Sjp161948 #endif
3820Sstevel@tonic-gate else if (strcmp(*argv,"-msg") == 0)
3830Sstevel@tonic-gate c_msg=1;
3840Sstevel@tonic-gate else if (strcmp(*argv,"-showcerts") == 0)
3850Sstevel@tonic-gate c_showcerts=1;
3860Sstevel@tonic-gate else if (strcmp(*argv,"-nbio_test") == 0)
3870Sstevel@tonic-gate nbio_test=1;
3880Sstevel@tonic-gate else if (strcmp(*argv,"-state") == 0)
3890Sstevel@tonic-gate state=1;
3900Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL2
3910Sstevel@tonic-gate else if (strcmp(*argv,"-ssl2") == 0)
3920Sstevel@tonic-gate meth=SSLv2_client_method();
3930Sstevel@tonic-gate #endif
3940Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL3
3950Sstevel@tonic-gate else if (strcmp(*argv,"-ssl3") == 0)
3960Sstevel@tonic-gate meth=SSLv3_client_method();
3970Sstevel@tonic-gate #endif
3980Sstevel@tonic-gate #ifndef OPENSSL_NO_TLS1
3990Sstevel@tonic-gate else if (strcmp(*argv,"-tls1") == 0)
4000Sstevel@tonic-gate meth=TLSv1_client_method();
4010Sstevel@tonic-gate #endif
402*2139Sjp161948 #ifndef OPENSSL_NO_DTLS1
403*2139Sjp161948 else if (strcmp(*argv,"-dtls1") == 0)
404*2139Sjp161948 {
405*2139Sjp161948 meth=DTLSv1_client_method();
406*2139Sjp161948 sock_type=SOCK_DGRAM;
407*2139Sjp161948 }
408*2139Sjp161948 else if (strcmp(*argv,"-timeout") == 0)
409*2139Sjp161948 enable_timeouts=1;
410*2139Sjp161948 else if (strcmp(*argv,"-mtu") == 0)
411*2139Sjp161948 {
412*2139Sjp161948 if (--argc < 1) goto bad;
413*2139Sjp161948 mtu = atol(*(++argv));
414*2139Sjp161948 }
415*2139Sjp161948 #endif
4160Sstevel@tonic-gate else if (strcmp(*argv,"-bugs") == 0)
4170Sstevel@tonic-gate bugs=1;
418*2139Sjp161948 else if (strcmp(*argv,"-keyform") == 0)
419*2139Sjp161948 {
420*2139Sjp161948 if (--argc < 1) goto bad;
421*2139Sjp161948 key_format = str2fmt(*(++argv));
422*2139Sjp161948 }
423*2139Sjp161948 else if (strcmp(*argv,"-pass") == 0)
424*2139Sjp161948 {
425*2139Sjp161948 if (--argc < 1) goto bad;
426*2139Sjp161948 passarg = *(++argv);
427*2139Sjp161948 }
4280Sstevel@tonic-gate else if (strcmp(*argv,"-key") == 0)
4290Sstevel@tonic-gate {
4300Sstevel@tonic-gate if (--argc < 1) goto bad;
4310Sstevel@tonic-gate key_file= *(++argv);
4320Sstevel@tonic-gate }
4330Sstevel@tonic-gate else if (strcmp(*argv,"-reconnect") == 0)
4340Sstevel@tonic-gate {
4350Sstevel@tonic-gate reconnect=5;
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate else if (strcmp(*argv,"-CApath") == 0)
4380Sstevel@tonic-gate {
4390Sstevel@tonic-gate if (--argc < 1) goto bad;
4400Sstevel@tonic-gate CApath= *(++argv);
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate else if (strcmp(*argv,"-CAfile") == 0)
4430Sstevel@tonic-gate {
4440Sstevel@tonic-gate if (--argc < 1) goto bad;
4450Sstevel@tonic-gate CAfile= *(++argv);
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate else if (strcmp(*argv,"-no_tls1") == 0)
4480Sstevel@tonic-gate off|=SSL_OP_NO_TLSv1;
4490Sstevel@tonic-gate else if (strcmp(*argv,"-no_ssl3") == 0)
4500Sstevel@tonic-gate off|=SSL_OP_NO_SSLv3;
4510Sstevel@tonic-gate else if (strcmp(*argv,"-no_ssl2") == 0)
4520Sstevel@tonic-gate off|=SSL_OP_NO_SSLv2;
4530Sstevel@tonic-gate else if (strcmp(*argv,"-serverpref") == 0)
4540Sstevel@tonic-gate off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
4550Sstevel@tonic-gate else if (strcmp(*argv,"-cipher") == 0)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate if (--argc < 1) goto bad;
4580Sstevel@tonic-gate cipher= *(++argv);
4590Sstevel@tonic-gate }
4600Sstevel@tonic-gate #ifdef FIONBIO
4610Sstevel@tonic-gate else if (strcmp(*argv,"-nbio") == 0)
4620Sstevel@tonic-gate { c_nbio=1; }
4630Sstevel@tonic-gate #endif
4640Sstevel@tonic-gate else if (strcmp(*argv,"-starttls") == 0)
4650Sstevel@tonic-gate {
4660Sstevel@tonic-gate if (--argc < 1) goto bad;
4670Sstevel@tonic-gate ++argv;
4680Sstevel@tonic-gate if (strcmp(*argv,"smtp") == 0)
4690Sstevel@tonic-gate starttls_proto = 1;
4700Sstevel@tonic-gate else if (strcmp(*argv,"pop3") == 0)
4710Sstevel@tonic-gate starttls_proto = 2;
4720Sstevel@tonic-gate else
4730Sstevel@tonic-gate goto bad;
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
4760Sstevel@tonic-gate else if (strcmp(*argv,"-engine") == 0)
4770Sstevel@tonic-gate {
4780Sstevel@tonic-gate if (--argc < 1) goto bad;
4790Sstevel@tonic-gate engine_id = *(++argv);
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate #endif
4820Sstevel@tonic-gate else if (strcmp(*argv,"-rand") == 0)
4830Sstevel@tonic-gate {
4840Sstevel@tonic-gate if (--argc < 1) goto bad;
4850Sstevel@tonic-gate inrand= *(++argv);
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate else
4880Sstevel@tonic-gate {
4890Sstevel@tonic-gate BIO_printf(bio_err,"unknown option %s\n",*argv);
4900Sstevel@tonic-gate badop=1;
4910Sstevel@tonic-gate break;
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate argc--;
4940Sstevel@tonic-gate argv++;
4950Sstevel@tonic-gate }
4960Sstevel@tonic-gate if (badop)
4970Sstevel@tonic-gate {
4980Sstevel@tonic-gate bad:
4990Sstevel@tonic-gate sc_usage();
5000Sstevel@tonic-gate goto end;
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate OpenSSL_add_ssl_algorithms();
5040Sstevel@tonic-gate SSL_load_error_strings();
5050Sstevel@tonic-gate
5060Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
5070Sstevel@tonic-gate e = setup_engine(bio_err, engine_id, 1);
5080Sstevel@tonic-gate #endif
509*2139Sjp161948 if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
510*2139Sjp161948 {
511*2139Sjp161948 BIO_printf(bio_err, "Error getting password\n");
512*2139Sjp161948 goto end;
513*2139Sjp161948 }
514*2139Sjp161948
515*2139Sjp161948 if (key_file == NULL)
516*2139Sjp161948 key_file = cert_file;
517*2139Sjp161948
518*2139Sjp161948
519*2139Sjp161948 if (key_file)
520*2139Sjp161948
521*2139Sjp161948 {
522*2139Sjp161948
523*2139Sjp161948 key = load_key(bio_err, key_file, key_format, 0, pass, e,
524*2139Sjp161948 "client certificate private key file");
525*2139Sjp161948 if (!key)
526*2139Sjp161948 {
527*2139Sjp161948 ERR_print_errors(bio_err);
528*2139Sjp161948 goto end;
529*2139Sjp161948 }
530*2139Sjp161948
531*2139Sjp161948 }
532*2139Sjp161948
533*2139Sjp161948 if (cert_file)
534*2139Sjp161948
535*2139Sjp161948 {
536*2139Sjp161948 cert = load_cert(bio_err,cert_file,cert_format,
537*2139Sjp161948 NULL, e, "client certificate file");
538*2139Sjp161948
539*2139Sjp161948 if (!cert)
540*2139Sjp161948 {
541*2139Sjp161948 ERR_print_errors(bio_err);
542*2139Sjp161948 goto end;
543*2139Sjp161948 }
544*2139Sjp161948 }
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
5470Sstevel@tonic-gate && !RAND_status())
5480Sstevel@tonic-gate {
5490Sstevel@tonic-gate BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate if (inrand != NULL)
5520Sstevel@tonic-gate BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
5530Sstevel@tonic-gate app_RAND_load_files(inrand));
5540Sstevel@tonic-gate
5550Sstevel@tonic-gate if (bio_c_out == NULL)
5560Sstevel@tonic-gate {
5570Sstevel@tonic-gate if (c_quiet && !c_debug && !c_msg)
5580Sstevel@tonic-gate {
5590Sstevel@tonic-gate bio_c_out=BIO_new(BIO_s_null());
5600Sstevel@tonic-gate }
5610Sstevel@tonic-gate else
5620Sstevel@tonic-gate {
5630Sstevel@tonic-gate if (bio_c_out == NULL)
5640Sstevel@tonic-gate bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate }
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate ctx=SSL_CTX_new(meth);
5690Sstevel@tonic-gate if (ctx == NULL)
5700Sstevel@tonic-gate {
5710Sstevel@tonic-gate ERR_print_errors(bio_err);
5720Sstevel@tonic-gate goto end;
5730Sstevel@tonic-gate }
5740Sstevel@tonic-gate
5750Sstevel@tonic-gate if (bugs)
5760Sstevel@tonic-gate SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
5770Sstevel@tonic-gate else
5780Sstevel@tonic-gate SSL_CTX_set_options(ctx,off);
579*2139Sjp161948 /* DTLS: partial reads end up discarding unread UDP bytes :-(
580*2139Sjp161948 * Setting read ahead solves this problem.
581*2139Sjp161948 */
582*2139Sjp161948 if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
5830Sstevel@tonic-gate
5840Sstevel@tonic-gate if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
5850Sstevel@tonic-gate if (cipher != NULL)
5860Sstevel@tonic-gate if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
5870Sstevel@tonic-gate BIO_printf(bio_err,"error setting cipher list\n");
5880Sstevel@tonic-gate ERR_print_errors(bio_err);
5890Sstevel@tonic-gate goto end;
5900Sstevel@tonic-gate }
5910Sstevel@tonic-gate #if 0
5920Sstevel@tonic-gate else
5930Sstevel@tonic-gate SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
5940Sstevel@tonic-gate #endif
5950Sstevel@tonic-gate
5960Sstevel@tonic-gate SSL_CTX_set_verify(ctx,verify,verify_callback);
597*2139Sjp161948 if (!set_cert_key_stuff(ctx,cert,key))
5980Sstevel@tonic-gate goto end;
5990Sstevel@tonic-gate
6000Sstevel@tonic-gate if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
6010Sstevel@tonic-gate (!SSL_CTX_set_default_verify_paths(ctx)))
6020Sstevel@tonic-gate {
6030Sstevel@tonic-gate /* BIO_printf(bio_err,"error setting default verify locations\n"); */
6040Sstevel@tonic-gate ERR_print_errors(bio_err);
6050Sstevel@tonic-gate /* goto end; */
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate
6080Sstevel@tonic-gate store = SSL_CTX_get_cert_store(ctx);
6090Sstevel@tonic-gate X509_STORE_set_flags(store, vflags);
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate con=SSL_new(ctx);
6120Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
6130Sstevel@tonic-gate if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL)
6140Sstevel@tonic-gate {
6150Sstevel@tonic-gate kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
6180Sstevel@tonic-gate /* SSL_set_cipher_list(con,"RC4-MD5"); */
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate re_start:
6210Sstevel@tonic-gate
622*2139Sjp161948 if (init_client(&s,host,port,sock_type) == 0)
6230Sstevel@tonic-gate {
6240Sstevel@tonic-gate BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
6250Sstevel@tonic-gate SHUTDOWN(s);
6260Sstevel@tonic-gate goto end;
6270Sstevel@tonic-gate }
6280Sstevel@tonic-gate BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate #ifdef FIONBIO
6310Sstevel@tonic-gate if (c_nbio)
6320Sstevel@tonic-gate {
6330Sstevel@tonic-gate unsigned long l=1;
6340Sstevel@tonic-gate BIO_printf(bio_c_out,"turning on non blocking io\n");
6350Sstevel@tonic-gate if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
6360Sstevel@tonic-gate {
6370Sstevel@tonic-gate ERR_print_errors(bio_err);
6380Sstevel@tonic-gate goto end;
6390Sstevel@tonic-gate }
6400Sstevel@tonic-gate }
6410Sstevel@tonic-gate #endif
6420Sstevel@tonic-gate if (c_Pause & 0x01) con->debug=1;
643*2139Sjp161948
644*2139Sjp161948 if ( SSL_version(con) == DTLS1_VERSION)
645*2139Sjp161948 {
646*2139Sjp161948 struct timeval timeout;
647*2139Sjp161948
648*2139Sjp161948 sbio=BIO_new_dgram(s,BIO_NOCLOSE);
649*2139Sjp161948 if (getsockname(s, &peer, (void *)&peerlen) < 0)
650*2139Sjp161948 {
651*2139Sjp161948 BIO_printf(bio_err, "getsockname:errno=%d\n",
652*2139Sjp161948 get_last_socket_error());
653*2139Sjp161948 SHUTDOWN(s);
654*2139Sjp161948 goto end;
655*2139Sjp161948 }
656*2139Sjp161948
657*2139Sjp161948 BIO_ctrl_set_connected(sbio, 1, &peer);
658*2139Sjp161948
659*2139Sjp161948 if ( enable_timeouts)
660*2139Sjp161948 {
661*2139Sjp161948 timeout.tv_sec = 0;
662*2139Sjp161948 timeout.tv_usec = DGRAM_RCV_TIMEOUT;
663*2139Sjp161948 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
664*2139Sjp161948
665*2139Sjp161948 timeout.tv_sec = 0;
666*2139Sjp161948 timeout.tv_usec = DGRAM_SND_TIMEOUT;
667*2139Sjp161948 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
668*2139Sjp161948 }
669*2139Sjp161948
670*2139Sjp161948 if ( mtu > 0)
671*2139Sjp161948 {
672*2139Sjp161948 SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
673*2139Sjp161948 SSL_set_mtu(con, mtu);
674*2139Sjp161948 }
675*2139Sjp161948 else
676*2139Sjp161948 /* want to do MTU discovery */
677*2139Sjp161948 BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
678*2139Sjp161948 }
679*2139Sjp161948 else
680*2139Sjp161948 sbio=BIO_new_socket(s,BIO_NOCLOSE);
681*2139Sjp161948
682*2139Sjp161948
6830Sstevel@tonic-gate
6840Sstevel@tonic-gate if (nbio_test)
6850Sstevel@tonic-gate {
6860Sstevel@tonic-gate BIO *test;
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate test=BIO_new(BIO_f_nbio_test());
6890Sstevel@tonic-gate sbio=BIO_push(test,sbio);
6900Sstevel@tonic-gate }
6910Sstevel@tonic-gate
6920Sstevel@tonic-gate if (c_debug)
6930Sstevel@tonic-gate {
6940Sstevel@tonic-gate con->debug=1;
695*2139Sjp161948 BIO_set_callback(sbio,bio_dump_callback);
6960Sstevel@tonic-gate BIO_set_callback_arg(sbio,bio_c_out);
6970Sstevel@tonic-gate }
6980Sstevel@tonic-gate if (c_msg)
6990Sstevel@tonic-gate {
7000Sstevel@tonic-gate SSL_set_msg_callback(con, msg_cb);
7010Sstevel@tonic-gate SSL_set_msg_callback_arg(con, bio_c_out);
7020Sstevel@tonic-gate }
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate SSL_set_bio(con,sbio,sbio);
7050Sstevel@tonic-gate SSL_set_connect_state(con);
7060Sstevel@tonic-gate
7070Sstevel@tonic-gate /* ok, lets connect */
7080Sstevel@tonic-gate width=SSL_get_fd(con)+1;
7090Sstevel@tonic-gate
7100Sstevel@tonic-gate read_tty=1;
7110Sstevel@tonic-gate write_tty=0;
7120Sstevel@tonic-gate tty_on=0;
7130Sstevel@tonic-gate read_ssl=1;
7140Sstevel@tonic-gate write_ssl=1;
7150Sstevel@tonic-gate
7160Sstevel@tonic-gate cbuf_len=0;
7170Sstevel@tonic-gate cbuf_off=0;
7180Sstevel@tonic-gate sbuf_len=0;
7190Sstevel@tonic-gate sbuf_off=0;
7200Sstevel@tonic-gate
7210Sstevel@tonic-gate /* This is an ugly hack that does a lot of assumptions */
7220Sstevel@tonic-gate if (starttls_proto == 1)
7230Sstevel@tonic-gate {
7240Sstevel@tonic-gate BIO_read(sbio,mbuf,BUFSIZZ);
7250Sstevel@tonic-gate BIO_printf(sbio,"STARTTLS\r\n");
7260Sstevel@tonic-gate BIO_read(sbio,sbuf,BUFSIZZ);
7270Sstevel@tonic-gate }
7280Sstevel@tonic-gate if (starttls_proto == 2)
7290Sstevel@tonic-gate {
7300Sstevel@tonic-gate BIO_read(sbio,mbuf,BUFSIZZ);
7310Sstevel@tonic-gate BIO_printf(sbio,"STLS\r\n");
7320Sstevel@tonic-gate BIO_read(sbio,sbuf,BUFSIZZ);
7330Sstevel@tonic-gate }
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate for (;;)
7360Sstevel@tonic-gate {
7370Sstevel@tonic-gate FD_ZERO(&readfds);
7380Sstevel@tonic-gate FD_ZERO(&writefds);
7390Sstevel@tonic-gate
7400Sstevel@tonic-gate if (SSL_in_init(con) && !SSL_total_renegotiations(con))
7410Sstevel@tonic-gate {
7420Sstevel@tonic-gate in_init=1;
7430Sstevel@tonic-gate tty_on=0;
7440Sstevel@tonic-gate }
7450Sstevel@tonic-gate else
7460Sstevel@tonic-gate {
7470Sstevel@tonic-gate tty_on=1;
7480Sstevel@tonic-gate if (in_init)
7490Sstevel@tonic-gate {
7500Sstevel@tonic-gate in_init=0;
7510Sstevel@tonic-gate print_stuff(bio_c_out,con,full_log);
7520Sstevel@tonic-gate if (full_log > 0) full_log--;
7530Sstevel@tonic-gate
7540Sstevel@tonic-gate if (starttls_proto)
7550Sstevel@tonic-gate {
7560Sstevel@tonic-gate BIO_printf(bio_err,"%s",mbuf);
7570Sstevel@tonic-gate /* We don't need to know any more */
7580Sstevel@tonic-gate starttls_proto = 0;
7590Sstevel@tonic-gate }
7600Sstevel@tonic-gate
7610Sstevel@tonic-gate if (reconnect)
7620Sstevel@tonic-gate {
7630Sstevel@tonic-gate reconnect--;
7640Sstevel@tonic-gate BIO_printf(bio_c_out,"drop connection and then reconnect\n");
7650Sstevel@tonic-gate SSL_shutdown(con);
7660Sstevel@tonic-gate SSL_set_connect_state(con);
7670Sstevel@tonic-gate SHUTDOWN(SSL_get_fd(con));
7680Sstevel@tonic-gate goto re_start;
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate }
7710Sstevel@tonic-gate }
7720Sstevel@tonic-gate
7730Sstevel@tonic-gate ssl_pending = read_ssl && SSL_pending(con);
7740Sstevel@tonic-gate
7750Sstevel@tonic-gate if (!ssl_pending)
7760Sstevel@tonic-gate {
777*2139Sjp161948 #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
7780Sstevel@tonic-gate if (tty_on)
7790Sstevel@tonic-gate {
7800Sstevel@tonic-gate if (read_tty) FD_SET(fileno(stdin),&readfds);
7810Sstevel@tonic-gate if (write_tty) FD_SET(fileno(stdout),&writefds);
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate if (read_ssl)
7840Sstevel@tonic-gate FD_SET(SSL_get_fd(con),&readfds);
7850Sstevel@tonic-gate if (write_ssl)
7860Sstevel@tonic-gate FD_SET(SSL_get_fd(con),&writefds);
7870Sstevel@tonic-gate #else
7880Sstevel@tonic-gate if(!tty_on || !write_tty) {
7890Sstevel@tonic-gate if (read_ssl)
7900Sstevel@tonic-gate FD_SET(SSL_get_fd(con),&readfds);
7910Sstevel@tonic-gate if (write_ssl)
7920Sstevel@tonic-gate FD_SET(SSL_get_fd(con),&writefds);
7930Sstevel@tonic-gate }
7940Sstevel@tonic-gate #endif
7950Sstevel@tonic-gate /* printf("mode tty(%d %d%d) ssl(%d%d)\n",
7960Sstevel@tonic-gate tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
7970Sstevel@tonic-gate
7980Sstevel@tonic-gate /* Note: under VMS with SOCKETSHR the second parameter
7990Sstevel@tonic-gate * is currently of type (int *) whereas under other
8000Sstevel@tonic-gate * systems it is (void *) if you don't have a cast it
8010Sstevel@tonic-gate * will choke the compiler: if you do have a cast then
8020Sstevel@tonic-gate * you can either go for (int *) or (void *).
8030Sstevel@tonic-gate */
8040Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
8050Sstevel@tonic-gate /* Under Windows/DOS we make the assumption that we can
8060Sstevel@tonic-gate * always write to the tty: therefore if we need to
8070Sstevel@tonic-gate * write to the tty we just fall through. Otherwise
8080Sstevel@tonic-gate * we timeout the select every second and see if there
8090Sstevel@tonic-gate * are any keypresses. Note: this is a hack, in a proper
8100Sstevel@tonic-gate * Windows application we wouldn't do this.
8110Sstevel@tonic-gate */
8120Sstevel@tonic-gate i=0;
8130Sstevel@tonic-gate if(!write_tty) {
8140Sstevel@tonic-gate if(read_tty) {
8150Sstevel@tonic-gate tv.tv_sec = 1;
8160Sstevel@tonic-gate tv.tv_usec = 0;
8170Sstevel@tonic-gate i=select(width,(void *)&readfds,(void *)&writefds,
8180Sstevel@tonic-gate NULL,&tv);
8190Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
8200Sstevel@tonic-gate if(!i && (!_kbhit() || !read_tty) ) continue;
8210Sstevel@tonic-gate #else
8220Sstevel@tonic-gate if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
8230Sstevel@tonic-gate #endif
8240Sstevel@tonic-gate } else i=select(width,(void *)&readfds,(void *)&writefds,
8250Sstevel@tonic-gate NULL,NULL);
8260Sstevel@tonic-gate }
827*2139Sjp161948 #elif defined(OPENSSL_SYS_NETWARE)
828*2139Sjp161948 if(!write_tty) {
829*2139Sjp161948 if(read_tty) {
830*2139Sjp161948 tv.tv_sec = 1;
831*2139Sjp161948 tv.tv_usec = 0;
832*2139Sjp161948 i=select(width,(void *)&readfds,(void *)&writefds,
833*2139Sjp161948 NULL,&tv);
834*2139Sjp161948 } else i=select(width,(void *)&readfds,(void *)&writefds,
835*2139Sjp161948 NULL,NULL);
836*2139Sjp161948 }
8370Sstevel@tonic-gate #else
8380Sstevel@tonic-gate i=select(width,(void *)&readfds,(void *)&writefds,
8390Sstevel@tonic-gate NULL,NULL);
8400Sstevel@tonic-gate #endif
8410Sstevel@tonic-gate if ( i < 0)
8420Sstevel@tonic-gate {
8430Sstevel@tonic-gate BIO_printf(bio_err,"bad select %d\n",
8440Sstevel@tonic-gate get_last_socket_error());
8450Sstevel@tonic-gate goto shut;
8460Sstevel@tonic-gate /* goto end; */
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate }
8490Sstevel@tonic-gate
8500Sstevel@tonic-gate if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
8510Sstevel@tonic-gate {
8520Sstevel@tonic-gate k=SSL_write(con,&(cbuf[cbuf_off]),
8530Sstevel@tonic-gate (unsigned int)cbuf_len);
8540Sstevel@tonic-gate switch (SSL_get_error(con,k))
8550Sstevel@tonic-gate {
8560Sstevel@tonic-gate case SSL_ERROR_NONE:
8570Sstevel@tonic-gate cbuf_off+=k;
8580Sstevel@tonic-gate cbuf_len-=k;
8590Sstevel@tonic-gate if (k <= 0) goto end;
8600Sstevel@tonic-gate /* we have done a write(con,NULL,0); */
8610Sstevel@tonic-gate if (cbuf_len <= 0)
8620Sstevel@tonic-gate {
8630Sstevel@tonic-gate read_tty=1;
8640Sstevel@tonic-gate write_ssl=0;
8650Sstevel@tonic-gate }
8660Sstevel@tonic-gate else /* if (cbuf_len > 0) */
8670Sstevel@tonic-gate {
8680Sstevel@tonic-gate read_tty=0;
8690Sstevel@tonic-gate write_ssl=1;
8700Sstevel@tonic-gate }
8710Sstevel@tonic-gate break;
8720Sstevel@tonic-gate case SSL_ERROR_WANT_WRITE:
8730Sstevel@tonic-gate BIO_printf(bio_c_out,"write W BLOCK\n");
8740Sstevel@tonic-gate write_ssl=1;
8750Sstevel@tonic-gate read_tty=0;
8760Sstevel@tonic-gate break;
8770Sstevel@tonic-gate case SSL_ERROR_WANT_READ:
8780Sstevel@tonic-gate BIO_printf(bio_c_out,"write R BLOCK\n");
8790Sstevel@tonic-gate write_tty=0;
8800Sstevel@tonic-gate read_ssl=1;
8810Sstevel@tonic-gate write_ssl=0;
8820Sstevel@tonic-gate break;
8830Sstevel@tonic-gate case SSL_ERROR_WANT_X509_LOOKUP:
8840Sstevel@tonic-gate BIO_printf(bio_c_out,"write X BLOCK\n");
8850Sstevel@tonic-gate break;
8860Sstevel@tonic-gate case SSL_ERROR_ZERO_RETURN:
8870Sstevel@tonic-gate if (cbuf_len != 0)
8880Sstevel@tonic-gate {
8890Sstevel@tonic-gate BIO_printf(bio_c_out,"shutdown\n");
8900Sstevel@tonic-gate goto shut;
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate else
8930Sstevel@tonic-gate {
8940Sstevel@tonic-gate read_tty=1;
8950Sstevel@tonic-gate write_ssl=0;
8960Sstevel@tonic-gate break;
8970Sstevel@tonic-gate }
8980Sstevel@tonic-gate
8990Sstevel@tonic-gate case SSL_ERROR_SYSCALL:
9000Sstevel@tonic-gate if ((k != 0) || (cbuf_len != 0))
9010Sstevel@tonic-gate {
9020Sstevel@tonic-gate BIO_printf(bio_err,"write:errno=%d\n",
9030Sstevel@tonic-gate get_last_socket_error());
9040Sstevel@tonic-gate goto shut;
9050Sstevel@tonic-gate }
9060Sstevel@tonic-gate else
9070Sstevel@tonic-gate {
9080Sstevel@tonic-gate read_tty=1;
9090Sstevel@tonic-gate write_ssl=0;
9100Sstevel@tonic-gate }
9110Sstevel@tonic-gate break;
9120Sstevel@tonic-gate case SSL_ERROR_SSL:
9130Sstevel@tonic-gate ERR_print_errors(bio_err);
9140Sstevel@tonic-gate goto shut;
9150Sstevel@tonic-gate }
9160Sstevel@tonic-gate }
917*2139Sjp161948 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
9180Sstevel@tonic-gate /* Assume Windows/DOS can always write */
9190Sstevel@tonic-gate else if (!ssl_pending && write_tty)
9200Sstevel@tonic-gate #else
9210Sstevel@tonic-gate else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
9220Sstevel@tonic-gate #endif
9230Sstevel@tonic-gate {
9240Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
9250Sstevel@tonic-gate ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
9260Sstevel@tonic-gate #endif
9270Sstevel@tonic-gate i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
9280Sstevel@tonic-gate
9290Sstevel@tonic-gate if (i <= 0)
9300Sstevel@tonic-gate {
9310Sstevel@tonic-gate BIO_printf(bio_c_out,"DONE\n");
9320Sstevel@tonic-gate goto shut;
9330Sstevel@tonic-gate /* goto end; */
9340Sstevel@tonic-gate }
9350Sstevel@tonic-gate
9360Sstevel@tonic-gate sbuf_len-=i;;
9370Sstevel@tonic-gate sbuf_off+=i;
9380Sstevel@tonic-gate if (sbuf_len <= 0)
9390Sstevel@tonic-gate {
9400Sstevel@tonic-gate read_ssl=1;
9410Sstevel@tonic-gate write_tty=0;
9420Sstevel@tonic-gate }
9430Sstevel@tonic-gate }
9440Sstevel@tonic-gate else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
9450Sstevel@tonic-gate {
9460Sstevel@tonic-gate #ifdef RENEG
9470Sstevel@tonic-gate { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
9480Sstevel@tonic-gate #endif
9490Sstevel@tonic-gate #if 1
9500Sstevel@tonic-gate k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
9510Sstevel@tonic-gate #else
9520Sstevel@tonic-gate /* Demo for pending and peek :-) */
9530Sstevel@tonic-gate k=SSL_read(con,sbuf,16);
9540Sstevel@tonic-gate { char zbuf[10240];
9550Sstevel@tonic-gate printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
9560Sstevel@tonic-gate }
9570Sstevel@tonic-gate #endif
9580Sstevel@tonic-gate
9590Sstevel@tonic-gate switch (SSL_get_error(con,k))
9600Sstevel@tonic-gate {
9610Sstevel@tonic-gate case SSL_ERROR_NONE:
9620Sstevel@tonic-gate if (k <= 0)
9630Sstevel@tonic-gate goto end;
9640Sstevel@tonic-gate sbuf_off=0;
9650Sstevel@tonic-gate sbuf_len=k;
9660Sstevel@tonic-gate
9670Sstevel@tonic-gate read_ssl=0;
9680Sstevel@tonic-gate write_tty=1;
9690Sstevel@tonic-gate break;
9700Sstevel@tonic-gate case SSL_ERROR_WANT_WRITE:
9710Sstevel@tonic-gate BIO_printf(bio_c_out,"read W BLOCK\n");
9720Sstevel@tonic-gate write_ssl=1;
9730Sstevel@tonic-gate read_tty=0;
9740Sstevel@tonic-gate break;
9750Sstevel@tonic-gate case SSL_ERROR_WANT_READ:
9760Sstevel@tonic-gate BIO_printf(bio_c_out,"read R BLOCK\n");
9770Sstevel@tonic-gate write_tty=0;
9780Sstevel@tonic-gate read_ssl=1;
9790Sstevel@tonic-gate if ((read_tty == 0) && (write_ssl == 0))
9800Sstevel@tonic-gate write_ssl=1;
9810Sstevel@tonic-gate break;
9820Sstevel@tonic-gate case SSL_ERROR_WANT_X509_LOOKUP:
9830Sstevel@tonic-gate BIO_printf(bio_c_out,"read X BLOCK\n");
9840Sstevel@tonic-gate break;
9850Sstevel@tonic-gate case SSL_ERROR_SYSCALL:
9860Sstevel@tonic-gate BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
9870Sstevel@tonic-gate goto shut;
9880Sstevel@tonic-gate case SSL_ERROR_ZERO_RETURN:
9890Sstevel@tonic-gate BIO_printf(bio_c_out,"closed\n");
9900Sstevel@tonic-gate goto shut;
9910Sstevel@tonic-gate case SSL_ERROR_SSL:
9920Sstevel@tonic-gate ERR_print_errors(bio_err);
9930Sstevel@tonic-gate goto shut;
9940Sstevel@tonic-gate /* break; */
9950Sstevel@tonic-gate }
9960Sstevel@tonic-gate }
9970Sstevel@tonic-gate
9980Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
9990Sstevel@tonic-gate #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
10000Sstevel@tonic-gate else if (_kbhit())
10010Sstevel@tonic-gate #else
10020Sstevel@tonic-gate else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
10030Sstevel@tonic-gate #endif
1004*2139Sjp161948 #elif defined (OPENSSL_SYS_NETWARE)
1005*2139Sjp161948 else if (_kbhit())
10060Sstevel@tonic-gate #else
10070Sstevel@tonic-gate else if (FD_ISSET(fileno(stdin),&readfds))
10080Sstevel@tonic-gate #endif
10090Sstevel@tonic-gate {
10100Sstevel@tonic-gate if (crlf)
10110Sstevel@tonic-gate {
10120Sstevel@tonic-gate int j, lf_num;
10130Sstevel@tonic-gate
10140Sstevel@tonic-gate i=read(fileno(stdin),cbuf,BUFSIZZ/2);
10150Sstevel@tonic-gate lf_num = 0;
10160Sstevel@tonic-gate /* both loops are skipped when i <= 0 */
10170Sstevel@tonic-gate for (j = 0; j < i; j++)
10180Sstevel@tonic-gate if (cbuf[j] == '\n')
10190Sstevel@tonic-gate lf_num++;
10200Sstevel@tonic-gate for (j = i-1; j >= 0; j--)
10210Sstevel@tonic-gate {
10220Sstevel@tonic-gate cbuf[j+lf_num] = cbuf[j];
10230Sstevel@tonic-gate if (cbuf[j] == '\n')
10240Sstevel@tonic-gate {
10250Sstevel@tonic-gate lf_num--;
10260Sstevel@tonic-gate i++;
10270Sstevel@tonic-gate cbuf[j+lf_num] = '\r';
10280Sstevel@tonic-gate }
10290Sstevel@tonic-gate }
10300Sstevel@tonic-gate assert(lf_num == 0);
10310Sstevel@tonic-gate }
10320Sstevel@tonic-gate else
10330Sstevel@tonic-gate i=read(fileno(stdin),cbuf,BUFSIZZ);
10340Sstevel@tonic-gate
10350Sstevel@tonic-gate if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
10360Sstevel@tonic-gate {
10370Sstevel@tonic-gate BIO_printf(bio_err,"DONE\n");
10380Sstevel@tonic-gate goto shut;
10390Sstevel@tonic-gate }
10400Sstevel@tonic-gate
10410Sstevel@tonic-gate if ((!c_ign_eof) && (cbuf[0] == 'R'))
10420Sstevel@tonic-gate {
10430Sstevel@tonic-gate BIO_printf(bio_err,"RENEGOTIATING\n");
10440Sstevel@tonic-gate SSL_renegotiate(con);
10450Sstevel@tonic-gate cbuf_len=0;
10460Sstevel@tonic-gate }
10470Sstevel@tonic-gate else
10480Sstevel@tonic-gate {
10490Sstevel@tonic-gate cbuf_len=i;
10500Sstevel@tonic-gate cbuf_off=0;
10510Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
10520Sstevel@tonic-gate ebcdic2ascii(cbuf, cbuf, i);
10530Sstevel@tonic-gate #endif
10540Sstevel@tonic-gate }
10550Sstevel@tonic-gate
10560Sstevel@tonic-gate write_ssl=1;
10570Sstevel@tonic-gate read_tty=0;
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate }
10600Sstevel@tonic-gate shut:
10610Sstevel@tonic-gate SSL_shutdown(con);
10620Sstevel@tonic-gate SHUTDOWN(SSL_get_fd(con));
10630Sstevel@tonic-gate ret=0;
10640Sstevel@tonic-gate end:
10650Sstevel@tonic-gate if(prexit) print_stuff(bio_c_out,con,1);
10660Sstevel@tonic-gate if (con != NULL) SSL_free(con);
10670Sstevel@tonic-gate if (con2 != NULL) SSL_free(con2);
10680Sstevel@tonic-gate if (ctx != NULL) SSL_CTX_free(ctx);
1069*2139Sjp161948 if (cert)
1070*2139Sjp161948 X509_free(cert);
1071*2139Sjp161948 if (key)
1072*2139Sjp161948 EVP_PKEY_free(key);
1073*2139Sjp161948 if (pass)
1074*2139Sjp161948 OPENSSL_free(pass);
10750Sstevel@tonic-gate if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
10760Sstevel@tonic-gate if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
10770Sstevel@tonic-gate if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
10780Sstevel@tonic-gate if (bio_c_out != NULL)
10790Sstevel@tonic-gate {
10800Sstevel@tonic-gate BIO_free(bio_c_out);
10810Sstevel@tonic-gate bio_c_out=NULL;
10820Sstevel@tonic-gate }
10830Sstevel@tonic-gate apps_shutdown();
10840Sstevel@tonic-gate OPENSSL_EXIT(ret);
10850Sstevel@tonic-gate }
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate
print_stuff(BIO * bio,SSL * s,int full)10880Sstevel@tonic-gate static void print_stuff(BIO *bio, SSL *s, int full)
10890Sstevel@tonic-gate {
10900Sstevel@tonic-gate X509 *peer=NULL;
10910Sstevel@tonic-gate char *p;
1092*2139Sjp161948 static const char *space=" ";
10930Sstevel@tonic-gate char buf[BUFSIZ];
10940Sstevel@tonic-gate STACK_OF(X509) *sk;
10950Sstevel@tonic-gate STACK_OF(X509_NAME) *sk2;
10960Sstevel@tonic-gate SSL_CIPHER *c;
10970Sstevel@tonic-gate X509_NAME *xn;
10980Sstevel@tonic-gate int j,i;
1099*2139Sjp161948 #ifndef OPENSSL_NO_COMP
1100*2139Sjp161948 const COMP_METHOD *comp, *expansion;
1101*2139Sjp161948 #endif
11020Sstevel@tonic-gate
11030Sstevel@tonic-gate if (full)
11040Sstevel@tonic-gate {
11050Sstevel@tonic-gate int got_a_chain = 0;
11060Sstevel@tonic-gate
11070Sstevel@tonic-gate sk=SSL_get_peer_cert_chain(s);
11080Sstevel@tonic-gate if (sk != NULL)
11090Sstevel@tonic-gate {
11100Sstevel@tonic-gate got_a_chain = 1; /* we don't have it for SSL2 (yet) */
11110Sstevel@tonic-gate
11120Sstevel@tonic-gate BIO_printf(bio,"---\nCertificate chain\n");
11130Sstevel@tonic-gate for (i=0; i<sk_X509_num(sk); i++)
11140Sstevel@tonic-gate {
11150Sstevel@tonic-gate X509_NAME_oneline(X509_get_subject_name(
11160Sstevel@tonic-gate sk_X509_value(sk,i)),buf,sizeof buf);
11170Sstevel@tonic-gate BIO_printf(bio,"%2d s:%s\n",i,buf);
11180Sstevel@tonic-gate X509_NAME_oneline(X509_get_issuer_name(
11190Sstevel@tonic-gate sk_X509_value(sk,i)),buf,sizeof buf);
11200Sstevel@tonic-gate BIO_printf(bio," i:%s\n",buf);
11210Sstevel@tonic-gate if (c_showcerts)
11220Sstevel@tonic-gate PEM_write_bio_X509(bio,sk_X509_value(sk,i));
11230Sstevel@tonic-gate }
11240Sstevel@tonic-gate }
11250Sstevel@tonic-gate
11260Sstevel@tonic-gate BIO_printf(bio,"---\n");
11270Sstevel@tonic-gate peer=SSL_get_peer_certificate(s);
11280Sstevel@tonic-gate if (peer != NULL)
11290Sstevel@tonic-gate {
11300Sstevel@tonic-gate BIO_printf(bio,"Server certificate\n");
11310Sstevel@tonic-gate if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
11320Sstevel@tonic-gate PEM_write_bio_X509(bio,peer);
11330Sstevel@tonic-gate X509_NAME_oneline(X509_get_subject_name(peer),
11340Sstevel@tonic-gate buf,sizeof buf);
11350Sstevel@tonic-gate BIO_printf(bio,"subject=%s\n",buf);
11360Sstevel@tonic-gate X509_NAME_oneline(X509_get_issuer_name(peer),
11370Sstevel@tonic-gate buf,sizeof buf);
11380Sstevel@tonic-gate BIO_printf(bio,"issuer=%s\n",buf);
11390Sstevel@tonic-gate }
11400Sstevel@tonic-gate else
11410Sstevel@tonic-gate BIO_printf(bio,"no peer certificate available\n");
11420Sstevel@tonic-gate
11430Sstevel@tonic-gate sk2=SSL_get_client_CA_list(s);
11440Sstevel@tonic-gate if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
11450Sstevel@tonic-gate {
11460Sstevel@tonic-gate BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
11470Sstevel@tonic-gate for (i=0; i<sk_X509_NAME_num(sk2); i++)
11480Sstevel@tonic-gate {
11490Sstevel@tonic-gate xn=sk_X509_NAME_value(sk2,i);
11500Sstevel@tonic-gate X509_NAME_oneline(xn,buf,sizeof(buf));
11510Sstevel@tonic-gate BIO_write(bio,buf,strlen(buf));
11520Sstevel@tonic-gate BIO_write(bio,"\n",1);
11530Sstevel@tonic-gate }
11540Sstevel@tonic-gate }
11550Sstevel@tonic-gate else
11560Sstevel@tonic-gate {
11570Sstevel@tonic-gate BIO_printf(bio,"---\nNo client certificate CA names sent\n");
11580Sstevel@tonic-gate }
11590Sstevel@tonic-gate p=SSL_get_shared_ciphers(s,buf,sizeof buf);
11600Sstevel@tonic-gate if (p != NULL)
11610Sstevel@tonic-gate {
11620Sstevel@tonic-gate /* This works only for SSL 2. In later protocol
11630Sstevel@tonic-gate * versions, the client does not know what other
11640Sstevel@tonic-gate * ciphers (in addition to the one to be used
11650Sstevel@tonic-gate * in the current connection) the server supports. */
11660Sstevel@tonic-gate
11670Sstevel@tonic-gate BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
11680Sstevel@tonic-gate j=i=0;
11690Sstevel@tonic-gate while (*p)
11700Sstevel@tonic-gate {
11710Sstevel@tonic-gate if (*p == ':')
11720Sstevel@tonic-gate {
11730Sstevel@tonic-gate BIO_write(bio,space,15-j%25);
11740Sstevel@tonic-gate i++;
11750Sstevel@tonic-gate j=0;
11760Sstevel@tonic-gate BIO_write(bio,((i%3)?" ":"\n"),1);
11770Sstevel@tonic-gate }
11780Sstevel@tonic-gate else
11790Sstevel@tonic-gate {
11800Sstevel@tonic-gate BIO_write(bio,p,1);
11810Sstevel@tonic-gate j++;
11820Sstevel@tonic-gate }
11830Sstevel@tonic-gate p++;
11840Sstevel@tonic-gate }
11850Sstevel@tonic-gate BIO_write(bio,"\n",1);
11860Sstevel@tonic-gate }
11870Sstevel@tonic-gate
11880Sstevel@tonic-gate BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
11890Sstevel@tonic-gate BIO_number_read(SSL_get_rbio(s)),
11900Sstevel@tonic-gate BIO_number_written(SSL_get_wbio(s)));
11910Sstevel@tonic-gate }
11920Sstevel@tonic-gate BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
11930Sstevel@tonic-gate c=SSL_get_current_cipher(s);
11940Sstevel@tonic-gate BIO_printf(bio,"%s, Cipher is %s\n",
11950Sstevel@tonic-gate SSL_CIPHER_get_version(c),
11960Sstevel@tonic-gate SSL_CIPHER_get_name(c));
11970Sstevel@tonic-gate if (peer != NULL) {
11980Sstevel@tonic-gate EVP_PKEY *pktmp;
11990Sstevel@tonic-gate pktmp = X509_get_pubkey(peer);
12000Sstevel@tonic-gate BIO_printf(bio,"Server public key is %d bit\n",
12010Sstevel@tonic-gate EVP_PKEY_bits(pktmp));
12020Sstevel@tonic-gate EVP_PKEY_free(pktmp);
12030Sstevel@tonic-gate }
1204*2139Sjp161948 #ifndef OPENSSL_NO_COMP
1205*2139Sjp161948 comp=SSL_get_current_compression(s);
1206*2139Sjp161948 expansion=SSL_get_current_expansion(s);
1207*2139Sjp161948 BIO_printf(bio,"Compression: %s\n",
1208*2139Sjp161948 comp ? SSL_COMP_get_name(comp) : "NONE");
1209*2139Sjp161948 BIO_printf(bio,"Expansion: %s\n",
1210*2139Sjp161948 expansion ? SSL_COMP_get_name(expansion) : "NONE");
1211*2139Sjp161948 #endif
12120Sstevel@tonic-gate SSL_SESSION_print(bio,SSL_get_session(s));
12130Sstevel@tonic-gate BIO_printf(bio,"---\n");
12140Sstevel@tonic-gate if (peer != NULL)
12150Sstevel@tonic-gate X509_free(peer);
12160Sstevel@tonic-gate /* flush, or debugging output gets mixed with http response */
12170Sstevel@tonic-gate BIO_flush(bio);
12180Sstevel@tonic-gate }
12190Sstevel@tonic-gate
1220