s_client.c revision 290207
155714Skris/* apps/s_client.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280297Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280297Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280297Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280297Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280297Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
58109998Smarkm/* ====================================================================
59238405Sjkim * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60109998Smarkm *
61109998Smarkm * Redistribution and use in source and binary forms, with or without
62109998Smarkm * modification, are permitted provided that the following conditions
63109998Smarkm * are met:
64109998Smarkm *
65109998Smarkm * 1. Redistributions of source code must retain the above copyright
66280297Sjkim *    notice, this list of conditions and the following disclaimer.
67109998Smarkm *
68109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
69109998Smarkm *    notice, this list of conditions and the following disclaimer in
70109998Smarkm *    the documentation and/or other materials provided with the
71109998Smarkm *    distribution.
72109998Smarkm *
73109998Smarkm * 3. All advertising materials mentioning features or use of this
74109998Smarkm *    software must display the following acknowledgment:
75109998Smarkm *    "This product includes software developed by the OpenSSL Project
76109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77109998Smarkm *
78109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79109998Smarkm *    endorse or promote products derived from this software without
80109998Smarkm *    prior written permission. For written permission, please contact
81109998Smarkm *    openssl-core@openssl.org.
82109998Smarkm *
83109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
84109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
85109998Smarkm *    permission of the OpenSSL Project.
86109998Smarkm *
87109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
88109998Smarkm *    acknowledgment:
89109998Smarkm *    "This product includes software developed by the OpenSSL Project
90109998Smarkm *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91109998Smarkm *
92109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
104109998Smarkm * ====================================================================
105109998Smarkm *
106109998Smarkm * This product includes cryptographic software written by Eric Young
107109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
108109998Smarkm * Hudson (tjh@cryptsoft.com).
109109998Smarkm *
110109998Smarkm */
111238405Sjkim/* ====================================================================
112238405Sjkim * Copyright 2005 Nokia. All rights reserved.
113238405Sjkim *
114238405Sjkim * The portions of the attached software ("Contribution") is developed by
115238405Sjkim * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116238405Sjkim * license.
117238405Sjkim *
118238405Sjkim * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119238405Sjkim * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120238405Sjkim * support (see RFC 4279) to OpenSSL.
121238405Sjkim *
122238405Sjkim * No patent licenses or other rights except those expressly stated in
123238405Sjkim * the OpenSSL open source license shall be deemed granted or received
124238405Sjkim * expressly, by implication, estoppel, or otherwise.
125238405Sjkim *
126238405Sjkim * No assurances are provided by Nokia that the Contribution does not
127238405Sjkim * infringe the patent or other intellectual property rights of any third
128238405Sjkim * party or that the license provides you with all the necessary rights
129238405Sjkim * to make use of the Contribution.
130238405Sjkim *
131238405Sjkim * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132238405Sjkim * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133238405Sjkim * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134238405Sjkim * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135238405Sjkim * OTHERWISE.
136238405Sjkim */
13755714Skris
13859191Skris#include <assert.h>
139238405Sjkim#include <ctype.h>
14055714Skris#include <stdio.h>
14155714Skris#include <stdlib.h>
14255714Skris#include <string.h>
143109998Smarkm#include <openssl/e_os2.h>
144109998Smarkm#ifdef OPENSSL_NO_STDIO
145280297Sjkim# define APPS_WIN16
14655714Skris#endif
14755714Skris
148280297Sjkim/*
149280297Sjkim * With IPv6, it looks like Digital has mixed up the proper order of
150280297Sjkim * recursive header file inclusion, resulting in the compiler complaining
151280297Sjkim * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
152280297Sjkim * needed to have fileno() declared correctly...  So let's define u_int
153280297Sjkim */
154109998Smarkm#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
155280297Sjkim# define __U_INT
15655714Skristypedef unsigned int u_int;
15755714Skris#endif
15855714Skris
15955714Skris#define USE_SOCKETS
16055714Skris#include "apps.h"
16155714Skris#include <openssl/x509.h>
16255714Skris#include <openssl/ssl.h>
16355714Skris#include <openssl/err.h>
16455714Skris#include <openssl/pem.h>
16576866Skris#include <openssl/rand.h>
166194206Ssimon#include <openssl/ocsp.h>
167238405Sjkim#include <openssl/bn.h>
168238405Sjkim#ifndef OPENSSL_NO_SRP
169280297Sjkim# include <openssl/srp.h>
170238405Sjkim#endif
17155714Skris#include "s_apps.h"
172160814Ssimon#include "timeouts.h"
17355714Skris
174109998Smarkm#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
17555714Skris/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
176280297Sjkim# undef FIONBIO
17755714Skris#endif
17855714Skris
179238405Sjkim#if defined(OPENSSL_SYS_BEOS_R5)
180280297Sjkim# include <fcntl.h>
181238405Sjkim#endif
182238405Sjkim
18355714Skris#undef PROG
184280297Sjkim#define PROG    s_client_main
18555714Skris
186280297Sjkim/*
187280297Sjkim * #define SSL_HOST_NAME "www.netscape.com"
188280297Sjkim */
189280297Sjkim/*
190280297Sjkim * #define SSL_HOST_NAME "193.118.187.102"
191280297Sjkim */
192280297Sjkim#define SSL_HOST_NAME   "localhost"
19355714Skris
194280297Sjkim/* no default cert. */
195280297Sjkim/*
196280297Sjkim * #define TEST_CERT "client.pem"
197280297Sjkim */
19855714Skris
19955714Skris#undef BUFSIZZ
20055714Skris#define BUFSIZZ 1024*8
20155714Skris
20255714Skrisextern int verify_depth;
20355714Skrisextern int verify_error;
204238405Sjkimextern int verify_return_error;
205290207Sjkimextern int verify_quiet;
20655714Skris
20755714Skris#ifdef FIONBIO
208280297Sjkimstatic int c_nbio = 0;
20955714Skris#endif
210280297Sjkimstatic int c_Pause = 0;
211280297Sjkimstatic int c_debug = 0;
212194206Ssimon#ifndef OPENSSL_NO_TLSEXT
213280297Sjkimstatic int c_tlsextdebug = 0;
214280297Sjkimstatic int c_status_req = 0;
215194206Ssimon#endif
216280297Sjkimstatic int c_msg = 0;
217280297Sjkimstatic int c_showcerts = 0;
21855714Skris
219280297Sjkimstatic char *keymatexportlabel = NULL;
220280297Sjkimstatic int keymatexportlen = 20;
221238405Sjkim
22255714Skrisstatic void sc_usage(void);
223280297Sjkimstatic void print_stuff(BIO *berr, SSL *con, int full);
224194206Ssimon#ifndef OPENSSL_NO_TLSEXT
225194206Ssimonstatic int ocsp_resp_cb(SSL *s, void *arg);
226194206Ssimon#endif
227280297Sjkimstatic BIO *bio_c_out = NULL;
228290207Sjkimstatic BIO *bio_c_msg = NULL;
229280297Sjkimstatic int c_quiet = 0;
230280297Sjkimstatic int c_ign_eof = 0;
231290207Sjkimstatic int c_brief = 0;
23255714Skris
233238405Sjkim#ifndef OPENSSL_NO_PSK
234238405Sjkim/* Default PSK identity and key */
235280297Sjkimstatic char *psk_identity = "Client_identity";
236280297Sjkim/*
237280297Sjkim * char *psk_key=NULL; by default PSK is not used
238280297Sjkim */
239238405Sjkim
240238405Sjkimstatic unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
241280297Sjkim                                  unsigned int max_identity_len,
242280297Sjkim                                  unsigned char *psk,
243280297Sjkim                                  unsigned int max_psk_len)
244280297Sjkim{
245280297Sjkim    unsigned int psk_len = 0;
246280297Sjkim    int ret;
247280297Sjkim    BIGNUM *bn = NULL;
248238405Sjkim
249280297Sjkim    if (c_debug)
250280297Sjkim        BIO_printf(bio_c_out, "psk_client_cb\n");
251280297Sjkim    if (!hint) {
252280297Sjkim        /* no ServerKeyExchange message */
253280297Sjkim        if (c_debug)
254280297Sjkim            BIO_printf(bio_c_out,
255280297Sjkim                       "NULL received PSK identity hint, continuing anyway\n");
256280297Sjkim    } else if (c_debug)
257280297Sjkim        BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
258238405Sjkim
259280297Sjkim    /*
260280297Sjkim     * lookup PSK identity and PSK key based on the given identity hint here
261280297Sjkim     */
262280297Sjkim    ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
263280297Sjkim    if (ret < 0 || (unsigned int)ret > max_identity_len)
264280297Sjkim        goto out_err;
265280297Sjkim    if (c_debug)
266280297Sjkim        BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity,
267280297Sjkim                   ret);
268280297Sjkim    ret = BN_hex2bn(&bn, psk_key);
269280297Sjkim    if (!ret) {
270280297Sjkim        BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n",
271280297Sjkim                   psk_key);
272280297Sjkim        if (bn)
273280297Sjkim            BN_free(bn);
274280297Sjkim        return 0;
275280297Sjkim    }
276238405Sjkim
277280297Sjkim    if ((unsigned int)BN_num_bytes(bn) > max_psk_len) {
278280297Sjkim        BIO_printf(bio_err,
279280297Sjkim                   "psk buffer of callback is too small (%d) for key (%d)\n",
280280297Sjkim                   max_psk_len, BN_num_bytes(bn));
281238405Sjkim        BN_free(bn);
282280297Sjkim        return 0;
283280297Sjkim    }
284238405Sjkim
285280297Sjkim    psk_len = BN_bn2bin(bn, psk);
286280297Sjkim    BN_free(bn);
287280297Sjkim    if (psk_len == 0)
288280297Sjkim        goto out_err;
289238405Sjkim
290280297Sjkim    if (c_debug)
291280297Sjkim        BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
292280297Sjkim
293280297Sjkim    return psk_len;
294238405Sjkim out_err:
295280297Sjkim    if (c_debug)
296280297Sjkim        BIO_printf(bio_err, "Error in PSK client callback\n");
297280297Sjkim    return 0;
298280297Sjkim}
299238405Sjkim#endif
300238405Sjkim
30155714Skrisstatic void sc_usage(void)
302280297Sjkim{
303280297Sjkim    BIO_printf(bio_err, "usage: s_client args\n");
304280297Sjkim    BIO_printf(bio_err, "\n");
305280297Sjkim    BIO_printf(bio_err, " -host host     - use -connect instead\n");
306280297Sjkim    BIO_printf(bio_err, " -port port     - use -connect instead\n");
307280297Sjkim    BIO_printf(bio_err,
308280297Sjkim               " -connect host:port - who to connect to (default is %s:%s)\n",
309280297Sjkim               SSL_HOST_NAME, PORT_STR);
310290207Sjkim    BIO_printf(bio_err,
311290207Sjkim               " -verify_host host - check peer certificate matches \"host\"\n");
312290207Sjkim    BIO_printf(bio_err,
313290207Sjkim               " -verify_email email - check peer certificate matches \"email\"\n");
314290207Sjkim    BIO_printf(bio_err,
315290207Sjkim               " -verify_ip ipaddr - check peer certificate matches \"ipaddr\"\n");
31655714Skris
317280297Sjkim    BIO_printf(bio_err,
318280297Sjkim               " -verify arg   - turn on peer certificate verification\n");
319280297Sjkim    BIO_printf(bio_err,
320280297Sjkim               " -verify_return_error - return verification errors\n");
321280297Sjkim    BIO_printf(bio_err,
322280297Sjkim               " -cert arg     - certificate file to use, PEM format assumed\n");
323280297Sjkim    BIO_printf(bio_err,
324280297Sjkim               " -certform arg - certificate format (PEM or DER) PEM default\n");
325280297Sjkim    BIO_printf(bio_err,
326280297Sjkim               " -key arg      - Private key file to use, in cert file if\n");
327280297Sjkim    BIO_printf(bio_err, "                 not specified but cert file is.\n");
328280297Sjkim    BIO_printf(bio_err,
329280297Sjkim               " -keyform arg  - key format (PEM or DER) PEM default\n");
330280297Sjkim    BIO_printf(bio_err,
331280297Sjkim               " -pass arg     - private key file pass phrase source\n");
332280297Sjkim    BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
333280297Sjkim    BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
334280297Sjkim    BIO_printf(bio_err,
335284283Sjkim               " -no_alt_chains - only ever use the first certificate chain found\n");
336284283Sjkim    BIO_printf(bio_err,
337280297Sjkim               " -reconnect    - Drop and re-make the connection with the same Session-ID\n");
338280297Sjkim    BIO_printf(bio_err,
339280297Sjkim               " -pause        - sleep(1) after each read(2) and write(2) system call\n");
340280297Sjkim    BIO_printf(bio_err,
341280297Sjkim               " -prexit       - print session information even on connection failure\n");
342280297Sjkim    BIO_printf(bio_err,
343280297Sjkim               " -showcerts    - show all certificates in the chain\n");
344280297Sjkim    BIO_printf(bio_err, " -debug        - extra output\n");
345160814Ssimon#ifdef WATT32
346280297Sjkim    BIO_printf(bio_err, " -wdebug       - WATT-32 tcp debugging\n");
347160814Ssimon#endif
348280297Sjkim    BIO_printf(bio_err, " -msg          - Show protocol messages\n");
349280297Sjkim    BIO_printf(bio_err, " -nbio_test    - more ssl protocol testing\n");
350280297Sjkim    BIO_printf(bio_err, " -state        - print the 'ssl' states\n");
35155714Skris#ifdef FIONBIO
352280297Sjkim    BIO_printf(bio_err, " -nbio         - Run with non-blocking IO\n");
35355714Skris#endif
354280297Sjkim    BIO_printf(bio_err,
355280297Sjkim               " -crlf         - convert LF from terminal into CRLF\n");
356280297Sjkim    BIO_printf(bio_err, " -quiet        - no s_client output\n");
357280297Sjkim    BIO_printf(bio_err,
358280297Sjkim               " -ign_eof      - ignore input eof (default when -quiet)\n");
359280297Sjkim    BIO_printf(bio_err, " -no_ign_eof   - don't ignore input eof\n");
360238405Sjkim#ifndef OPENSSL_NO_PSK
361280297Sjkim    BIO_printf(bio_err, " -psk_identity arg - PSK identity\n");
362280297Sjkim    BIO_printf(bio_err, " -psk arg      - PSK in hex (without 0x)\n");
363238405Sjkim# ifndef OPENSSL_NO_JPAKE
364280297Sjkim    BIO_printf(bio_err, " -jpake arg    - JPAKE secret to use\n");
365238405Sjkim# endif
366238405Sjkim#endif
367238405Sjkim#ifndef OPENSSL_NO_SRP
368280297Sjkim    BIO_printf(bio_err,
369280297Sjkim               " -srpuser user     - SRP authentification for 'user'\n");
370280297Sjkim    BIO_printf(bio_err, " -srppass arg      - password for 'user'\n");
371280297Sjkim    BIO_printf(bio_err,
372280297Sjkim               " -srp_lateuser     - SRP username into second ClientHello message\n");
373280297Sjkim    BIO_printf(bio_err,
374280297Sjkim               " -srp_moregroups   - Tolerate other than the known g N values.\n");
375280297Sjkim    BIO_printf(bio_err,
376280297Sjkim               " -srp_strength int - minimal length in bits for N (default %d).\n",
377280297Sjkim               SRP_MINIMAL_N);
378238405Sjkim#endif
379280297Sjkim    BIO_printf(bio_err, " -ssl2         - just use SSLv2\n");
380276861Sjkim#ifndef OPENSSL_NO_SSL3_METHOD
381280297Sjkim    BIO_printf(bio_err, " -ssl3         - just use SSLv3\n");
382276861Sjkim#endif
383280297Sjkim    BIO_printf(bio_err, " -tls1_2       - just use TLSv1.2\n");
384280297Sjkim    BIO_printf(bio_err, " -tls1_1       - just use TLSv1.1\n");
385280297Sjkim    BIO_printf(bio_err, " -tls1         - just use TLSv1\n");
386280297Sjkim    BIO_printf(bio_err, " -dtls1        - just use DTLSv1\n");
387280297Sjkim    BIO_printf(bio_err, " -fallback_scsv - send TLS_FALLBACK_SCSV\n");
388280297Sjkim    BIO_printf(bio_err, " -mtu          - set the link layer MTU\n");
389280297Sjkim    BIO_printf(bio_err,
390280297Sjkim               " -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
391280297Sjkim    BIO_printf(bio_err,
392280297Sjkim               " -bugs         - Switch on all SSL implementation bug workarounds\n");
393280297Sjkim    BIO_printf(bio_err,
394280297Sjkim               " -serverpref   - Use server's cipher preferences (only SSLv2)\n");
395280297Sjkim    BIO_printf(bio_err,
396280297Sjkim               " -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
397280297Sjkim    BIO_printf(bio_err,
398280297Sjkim               "                 command to see what is available\n");
399280297Sjkim    BIO_printf(bio_err,
400280297Sjkim               " -starttls prot - use the STARTTLS command before starting TLS\n");
401280297Sjkim    BIO_printf(bio_err,
402280297Sjkim               "                 for those protocols that support it, where\n");
403280297Sjkim    BIO_printf(bio_err,
404280297Sjkim               "                 'prot' defines which one to assume.  Currently,\n");
405280297Sjkim    BIO_printf(bio_err,
406280297Sjkim               "                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
407280297Sjkim    BIO_printf(bio_err, "                 are supported.\n");
408111147Snectar#ifndef OPENSSL_NO_ENGINE
409280297Sjkim    BIO_printf(bio_err,
410280297Sjkim               " -engine id    - Initialise and use the specified engine\n");
411111147Snectar#endif
412280297Sjkim    BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
413280297Sjkim               LIST_SEPARATOR_CHAR);
414280297Sjkim    BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n");
415280297Sjkim    BIO_printf(bio_err, " -sess_in arg  - file to read SSL session from\n");
416194206Ssimon#ifndef OPENSSL_NO_TLSEXT
417280297Sjkim    BIO_printf(bio_err,
418280297Sjkim               " -servername host  - Set TLS extension servername in ClientHello\n");
419280297Sjkim    BIO_printf(bio_err,
420280297Sjkim               " -tlsextdebug      - hex dump of all TLS extensions received\n");
421280297Sjkim    BIO_printf(bio_err,
422280297Sjkim               " -status           - request certificate status from server\n");
423280297Sjkim    BIO_printf(bio_err,
424280297Sjkim               " -no_ticket        - disable use of RFC4507bis session tickets\n");
425280297Sjkim    BIO_printf(bio_err,
426290207Sjkim               " -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
427290207Sjkim#endif
428290207Sjkim#ifndef OPENSSL_NO_NEXTPROTONEG
429290207Sjkim    BIO_printf(bio_err,
430280297Sjkim               " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
431194206Ssimon#endif
432280297Sjkim    BIO_printf(bio_err,
433290207Sjkim               " -alpn arg         - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
434290207Sjkim    BIO_printf(bio_err,
435280297Sjkim               " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
436246772Sjkim#ifndef OPENSSL_NO_SRTP
437280297Sjkim    BIO_printf(bio_err,
438280297Sjkim               " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
439246772Sjkim#endif
440280297Sjkim    BIO_printf(bio_err,
441280297Sjkim               " -keymatexport label   - Export keying material using label\n");
442280297Sjkim    BIO_printf(bio_err,
443280297Sjkim               " -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
444280297Sjkim}
44555714Skris
446194206Ssimon#ifndef OPENSSL_NO_TLSEXT
447194206Ssimon
448194206Ssimon/* This is a context that we pass to callbacks */
449194206Ssimontypedef struct tlsextctx_st {
450280297Sjkim    BIO *biodebug;
451280297Sjkim    int ack;
452194206Ssimon} tlsextctx;
453194206Ssimon
454194206Ssimonstatic int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
455280297Sjkim{
456280297Sjkim    tlsextctx *p = (tlsextctx *) arg;
457280297Sjkim    const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
458280297Sjkim    if (SSL_get_servername_type(s) != -1)
459280297Sjkim        p->ack = !SSL_session_reused(s) && hn != NULL;
460280297Sjkim    else
461280297Sjkim        BIO_printf(bio_err, "Can't use SSL_get_servername\n");
462238405Sjkim
463280297Sjkim    return SSL_TLSEXT_ERR_OK;
464280297Sjkim}
465238405Sjkim
466280297Sjkim# ifndef OPENSSL_NO_SRP
467280297Sjkim
468238405Sjkim/* This is a context that we pass to all callbacks */
469280297Sjkimtypedef struct srp_arg_st {
470280297Sjkim    char *srppassin;
471280297Sjkim    char *srplogin;
472280297Sjkim    int msg;                    /* copy from c_msg */
473280297Sjkim    int debug;                  /* copy from c_debug */
474280297Sjkim    int amp;                    /* allow more groups */
475280297Sjkim    int strength /* minimal size for N */ ;
476280297Sjkim} SRP_ARG;
477238405Sjkim
478280297Sjkim#  define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
479238405Sjkim
480238405Sjkimstatic int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
481280297Sjkim{
482280297Sjkim    BN_CTX *bn_ctx = BN_CTX_new();
483280297Sjkim    BIGNUM *p = BN_new();
484280297Sjkim    BIGNUM *r = BN_new();
485280297Sjkim    int ret =
486280297Sjkim        g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
487280297Sjkim        BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
488280297Sjkim        p != NULL && BN_rshift1(p, N) &&
489280297Sjkim        /* p = (N-1)/2 */
490280297Sjkim        BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
491280297Sjkim        r != NULL &&
492280297Sjkim        /* verify g^((N-1)/2) == -1 (mod N) */
493280297Sjkim        BN_mod_exp(r, g, p, N, bn_ctx) &&
494280297Sjkim        BN_add_word(r, 1) && BN_cmp(r, N) == 0;
495238405Sjkim
496280297Sjkim    if (r)
497280297Sjkim        BN_free(r);
498280297Sjkim    if (p)
499280297Sjkim        BN_free(p);
500280297Sjkim    if (bn_ctx)
501280297Sjkim        BN_CTX_free(bn_ctx);
502280297Sjkim    return ret;
503280297Sjkim}
504238405Sjkim
505280297Sjkim/*-
506280297Sjkim * This callback is used here for two purposes:
507280297Sjkim * - extended debugging
508280297Sjkim * - making some primality tests for unknown groups
509280297Sjkim * The callback is only called for a non default group.
510280297Sjkim *
511280297Sjkim * An application does not need the call back at all if
512280297Sjkim * only the stanard groups are used.  In real life situations,
513280297Sjkim * client and server already share well known groups,
514280297Sjkim * thus there is no need to verify them.
515280297Sjkim * Furthermore, in case that a server actually proposes a group that
516280297Sjkim * is not one of those defined in RFC 5054, it is more appropriate
517280297Sjkim * to add the group to a static list and then compare since
518280297Sjkim * primality tests are rather cpu consuming.
519280297Sjkim */
520238405Sjkim
521280297Sjkimstatic int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
522280297Sjkim{
523280297Sjkim    SRP_ARG *srp_arg = (SRP_ARG *)arg;
524280297Sjkim    BIGNUM *N = NULL, *g = NULL;
525280297Sjkim    if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
526280297Sjkim        return 0;
527280297Sjkim    if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {
528280297Sjkim        BIO_printf(bio_err, "SRP parameters:\n");
529280297Sjkim        BIO_printf(bio_err, "\tN=");
530280297Sjkim        BN_print(bio_err, N);
531280297Sjkim        BIO_printf(bio_err, "\n\tg=");
532280297Sjkim        BN_print(bio_err, g);
533280297Sjkim        BIO_printf(bio_err, "\n");
534280297Sjkim    }
535238405Sjkim
536280297Sjkim    if (SRP_check_known_gN_param(g, N))
537280297Sjkim        return 1;
538238405Sjkim
539280297Sjkim    if (srp_arg->amp == 1) {
540280297Sjkim        if (srp_arg->debug)
541280297Sjkim            BIO_printf(bio_err,
542280297Sjkim                       "SRP param N and g are not known params, going to check deeper.\n");
543238405Sjkim
544280297Sjkim        /*
545280297Sjkim         * The srp_moregroups is a real debugging feature. Implementors
546280297Sjkim         * should rather add the value to the known ones. The minimal size
547280297Sjkim         * has already been tested.
548280297Sjkim         */
549280297Sjkim        if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
550280297Sjkim            return 1;
551280297Sjkim    }
552280297Sjkim    BIO_printf(bio_err, "SRP param N and g rejected.\n");
553280297Sjkim    return 0;
554280297Sjkim}
555238405Sjkim
556280297Sjkim#  define PWD_STRLEN 1024
557238405Sjkim
558280297Sjkimstatic char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
559280297Sjkim{
560280297Sjkim    SRP_ARG *srp_arg = (SRP_ARG *)arg;
561280297Sjkim    char *pass = (char *)OPENSSL_malloc(PWD_STRLEN + 1);
562280297Sjkim    PW_CB_DATA cb_tmp;
563280297Sjkim    int l;
564238405Sjkim
565284283Sjkim    if (!pass) {
566280297Sjkim        BIO_printf(bio_err, "Malloc failure\n");
567280297Sjkim        return NULL;
568280297Sjkim    }
569238405Sjkim
570280297Sjkim    cb_tmp.password = (char *)srp_arg->srppassin;
571280297Sjkim    cb_tmp.prompt_info = "SRP user";
572280297Sjkim    if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) {
573280297Sjkim        BIO_printf(bio_err, "Can't read Password\n");
574280297Sjkim        OPENSSL_free(pass);
575280297Sjkim        return NULL;
576280297Sjkim    }
577280297Sjkim    *(pass + l) = '\0';
578238405Sjkim
579280297Sjkim    return pass;
580280297Sjkim}
581238405Sjkim
582280297Sjkim# endif
583280297Sjkim# ifndef OPENSSL_NO_SRTP
584280297Sjkimchar *srtp_profiles = NULL;
585280297Sjkim# endif
586238405Sjkim
587238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
588238405Sjkim/* This the context that we pass to next_proto_cb */
589238405Sjkimtypedef struct tlsextnextprotoctx_st {
590280297Sjkim    unsigned char *data;
591280297Sjkim    unsigned short len;
592280297Sjkim    int status;
593238405Sjkim} tlsextnextprotoctx;
594238405Sjkim
595238405Sjkimstatic tlsextnextprotoctx next_proto;
596238405Sjkim
597280297Sjkimstatic int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen,
598280297Sjkim                         const unsigned char *in, unsigned int inlen,
599280297Sjkim                         void *arg)
600280297Sjkim{
601280297Sjkim    tlsextnextprotoctx *ctx = arg;
602238405Sjkim
603280297Sjkim    if (!c_quiet) {
604280297Sjkim        /* We can assume that |in| is syntactically valid. */
605280297Sjkim        unsigned i;
606280297Sjkim        BIO_printf(bio_c_out, "Protocols advertised by server: ");
607280297Sjkim        for (i = 0; i < inlen;) {
608280297Sjkim            if (i)
609280297Sjkim                BIO_write(bio_c_out, ", ", 2);
610280297Sjkim            BIO_write(bio_c_out, &in[i + 1], in[i]);
611280297Sjkim            i += in[i] + 1;
612280297Sjkim        }
613280297Sjkim        BIO_write(bio_c_out, "\n", 1);
614280297Sjkim    }
615238405Sjkim
616280297Sjkim    ctx->status =
617280297Sjkim        SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
618280297Sjkim    return SSL_TLSEXT_ERR_OK;
619280297Sjkim}
620280297Sjkim# endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
621290207Sjkim
622290207Sjkimstatic int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type,
623290207Sjkim                                   const unsigned char *in, size_t inlen,
624290207Sjkim                                   int *al, void *arg)
625290207Sjkim{
626290207Sjkim    char pem_name[100];
627290207Sjkim    unsigned char ext_buf[4 + 65536];
628290207Sjkim
629290207Sjkim    /* Reconstruct the type/len fields prior to extension data */
630290207Sjkim    ext_buf[0] = ext_type >> 8;
631290207Sjkim    ext_buf[1] = ext_type & 0xFF;
632290207Sjkim    ext_buf[2] = inlen >> 8;
633290207Sjkim    ext_buf[3] = inlen & 0xFF;
634290207Sjkim    memcpy(ext_buf + 4, in, inlen);
635290207Sjkim
636290207Sjkim    BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d",
637290207Sjkim                 ext_type);
638290207Sjkim    PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
639290207Sjkim    return 1;
640290207Sjkim}
641290207Sjkim
642238405Sjkim#endif
643238405Sjkim
644280297Sjkimenum {
645280297Sjkim    PROTO_OFF = 0,
646280297Sjkim    PROTO_SMTP,
647280297Sjkim    PROTO_POP3,
648280297Sjkim    PROTO_IMAP,
649280297Sjkim    PROTO_FTP,
650280297Sjkim    PROTO_XMPP
651167612Ssimon};
652167612Ssimon
65359191Skrisint MAIN(int, char **);
65459191Skris
65555714Skrisint MAIN(int argc, char **argv)
656280297Sjkim{
657290207Sjkim    int build_chain = 0;
658280297Sjkim    SSL *con = NULL;
659238405Sjkim#ifndef OPENSSL_NO_KRB5
660280297Sjkim    KSSL_CTX *kctx;
661238405Sjkim#endif
662280297Sjkim    int s, k, width, state = 0;
663280297Sjkim    char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL;
664280297Sjkim    int cbuf_len, cbuf_off;
665280297Sjkim    int sbuf_len, sbuf_off;
666280297Sjkim    fd_set readfds, writefds;
667280297Sjkim    short port = PORT;
668280297Sjkim    int full_log = 1;
669280297Sjkim    char *host = SSL_HOST_NAME;
670290207Sjkim    char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
671280297Sjkim    int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
672280297Sjkim    char *passarg = NULL, *pass = NULL;
673280297Sjkim    X509 *cert = NULL;
674280297Sjkim    EVP_PKEY *key = NULL;
675290207Sjkim    STACK_OF(X509) *chain = NULL;
676290207Sjkim    char *CApath = NULL, *CAfile = NULL;
677290207Sjkim    char *chCApath = NULL, *chCAfile = NULL;
678290207Sjkim    char *vfyCApath = NULL, *vfyCAfile = NULL;
679290207Sjkim    int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE;
680280297Sjkim    int crlf = 0;
681280297Sjkim    int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
682280297Sjkim    SSL_CTX *ctx = NULL;
683280297Sjkim    int ret = 1, in_init = 1, i, nbio_test = 0;
684280297Sjkim    int starttls_proto = PROTO_OFF;
685280297Sjkim    int prexit = 0;
686280297Sjkim    X509_VERIFY_PARAM *vpm = NULL;
687280297Sjkim    int badarg = 0;
688280297Sjkim    const SSL_METHOD *meth = NULL;
689280297Sjkim    int socket_type = SOCK_STREAM;
690280297Sjkim    BIO *sbio;
691280297Sjkim    char *inrand = NULL;
692280297Sjkim    int mbuf_len = 0;
693280297Sjkim    struct timeval timeout, *timeoutp;
694111147Snectar#ifndef OPENSSL_NO_ENGINE
695280297Sjkim    char *engine_id = NULL;
696280297Sjkim    char *ssl_client_engine_id = NULL;
697280297Sjkim    ENGINE *ssl_client_engine = NULL;
698194206Ssimon#endif
699280297Sjkim    ENGINE *e = NULL;
700238405Sjkim#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
701280297Sjkim    struct timeval tv;
702280297Sjkim# if defined(OPENSSL_SYS_BEOS_R5)
703280297Sjkim    int stdin_set = 0;
704280297Sjkim# endif
70559191Skris#endif
706194206Ssimon#ifndef OPENSSL_NO_TLSEXT
707280297Sjkim    char *servername = NULL;
708280297Sjkim    tlsextctx tlsextcbp = { NULL, 0 };
709238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
710280297Sjkim    const char *next_proto_neg_in = NULL;
711238405Sjkim# endif
712290207Sjkim    const char *alpn_in = NULL;
713290207Sjkim# define MAX_SI_TYPES 100
714290207Sjkim    unsigned short serverinfo_types[MAX_SI_TYPES];
715290207Sjkim    int serverinfo_types_count = 0;
716194206Ssimon#endif
717280297Sjkim    char *sess_in = NULL;
718280297Sjkim    char *sess_out = NULL;
719280297Sjkim    struct sockaddr peer;
720280297Sjkim    int peerlen = sizeof(peer);
721280297Sjkim    int fallback_scsv = 0;
722280297Sjkim    int enable_timeouts = 0;
723280297Sjkim    long socket_mtu = 0;
724194206Ssimon#ifndef OPENSSL_NO_JPAKE
725290207Sjkim    static char *jpake_secret = NULL;
726290207Sjkim# define no_jpake !jpake_secret
727290207Sjkim#else
728290207Sjkim# define no_jpake 1
729194206Ssimon#endif
730238405Sjkim#ifndef OPENSSL_NO_SRP
731280297Sjkim    char *srppass = NULL;
732280297Sjkim    int srp_lateuser = 0;
733280297Sjkim    SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 };
734238405Sjkim#endif
735290207Sjkim    SSL_EXCERT *exc = NULL;
736160814Ssimon
737290207Sjkim    SSL_CONF_CTX *cctx = NULL;
738290207Sjkim    STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
739290207Sjkim
740290207Sjkim    char *crl_file = NULL;
741290207Sjkim    int crl_format = FORMAT_PEM;
742290207Sjkim    int crl_download = 0;
743290207Sjkim    STACK_OF(X509_CRL) *crls = NULL;
744290207Sjkim
745280297Sjkim    meth = SSLv23_client_method();
74655714Skris
747280297Sjkim    apps_startup();
748280297Sjkim    c_Pause = 0;
749280297Sjkim    c_quiet = 0;
750280297Sjkim    c_ign_eof = 0;
751280297Sjkim    c_debug = 0;
752280297Sjkim    c_msg = 0;
753280297Sjkim    c_showcerts = 0;
75455714Skris
755280297Sjkim    if (bio_err == NULL)
756280297Sjkim        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
75755714Skris
758280297Sjkim    if (!load_config(bio_err, NULL))
759280297Sjkim        goto end;
760109998Smarkm
761290207Sjkim    cctx = SSL_CONF_CTX_new();
762290207Sjkim    if (!cctx)
763290207Sjkim        goto end;
764290207Sjkim    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
765290207Sjkim    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);
766290207Sjkim
767280297Sjkim    if (((cbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) ||
768280297Sjkim        ((sbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) ||
769280297Sjkim        ((mbuf = OPENSSL_malloc(BUFSIZZ)) == NULL)) {
770280297Sjkim        BIO_printf(bio_err, "out of memory\n");
771280297Sjkim        goto end;
772280297Sjkim    }
77355714Skris
774280297Sjkim    verify_depth = 0;
775280297Sjkim    verify_error = X509_V_OK;
77655714Skris#ifdef FIONBIO
777280297Sjkim    c_nbio = 0;
77855714Skris#endif
77955714Skris
780280297Sjkim    argc--;
781280297Sjkim    argv++;
782280297Sjkim    while (argc >= 1) {
783280297Sjkim        if (strcmp(*argv, "-host") == 0) {
784280297Sjkim            if (--argc < 1)
785280297Sjkim                goto bad;
786280297Sjkim            host = *(++argv);
787280297Sjkim        } else if (strcmp(*argv, "-port") == 0) {
788280297Sjkim            if (--argc < 1)
789280297Sjkim                goto bad;
790280297Sjkim            port = atoi(*(++argv));
791280297Sjkim            if (port == 0)
792280297Sjkim                goto bad;
793280297Sjkim        } else if (strcmp(*argv, "-connect") == 0) {
794280297Sjkim            if (--argc < 1)
795280297Sjkim                goto bad;
796280297Sjkim            if (!extract_host_port(*(++argv), &host, NULL, &port))
797280297Sjkim                goto bad;
798280297Sjkim        } else if (strcmp(*argv, "-verify") == 0) {
799280297Sjkim            verify = SSL_VERIFY_PEER;
800280297Sjkim            if (--argc < 1)
801280297Sjkim                goto bad;
802280297Sjkim            verify_depth = atoi(*(++argv));
803290207Sjkim            if (!c_quiet)
804290207Sjkim                BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
805280297Sjkim        } else if (strcmp(*argv, "-cert") == 0) {
806280297Sjkim            if (--argc < 1)
807280297Sjkim                goto bad;
808280297Sjkim            cert_file = *(++argv);
809290207Sjkim        } else if (strcmp(*argv, "-CRL") == 0) {
810280297Sjkim            if (--argc < 1)
811280297Sjkim                goto bad;
812290207Sjkim            crl_file = *(++argv);
813290207Sjkim        } else if (strcmp(*argv, "-crl_download") == 0)
814290207Sjkim            crl_download = 1;
815290207Sjkim        else if (strcmp(*argv, "-sess_out") == 0) {
816290207Sjkim            if (--argc < 1)
817290207Sjkim                goto bad;
818280297Sjkim            sess_out = *(++argv);
819280297Sjkim        } else if (strcmp(*argv, "-sess_in") == 0) {
820280297Sjkim            if (--argc < 1)
821280297Sjkim                goto bad;
822280297Sjkim            sess_in = *(++argv);
823280297Sjkim        } else if (strcmp(*argv, "-certform") == 0) {
824280297Sjkim            if (--argc < 1)
825280297Sjkim                goto bad;
826280297Sjkim            cert_format = str2fmt(*(++argv));
827290207Sjkim        } else if (strcmp(*argv, "-CRLform") == 0) {
828290207Sjkim            if (--argc < 1)
829290207Sjkim                goto bad;
830290207Sjkim            crl_format = str2fmt(*(++argv));
831280297Sjkim        } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) {
832280297Sjkim            if (badarg)
833280297Sjkim                goto bad;
834280297Sjkim            continue;
835280297Sjkim        } else if (strcmp(*argv, "-verify_return_error") == 0)
836280297Sjkim            verify_return_error = 1;
837290207Sjkim        else if (strcmp(*argv, "-verify_quiet") == 0)
838290207Sjkim            verify_quiet = 1;
839290207Sjkim        else if (strcmp(*argv, "-brief") == 0) {
840290207Sjkim            c_brief = 1;
841290207Sjkim            verify_quiet = 1;
842290207Sjkim            c_quiet = 1;
843290207Sjkim        } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) {
844290207Sjkim            if (badarg)
845290207Sjkim                goto bad;
846290207Sjkim            continue;
847290207Sjkim        } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) {
848290207Sjkim            if (badarg)
849290207Sjkim                goto bad;
850290207Sjkim            continue;
851290207Sjkim        } else if (strcmp(*argv, "-prexit") == 0)
852280297Sjkim            prexit = 1;
853280297Sjkim        else if (strcmp(*argv, "-crlf") == 0)
854280297Sjkim            crlf = 1;
855280297Sjkim        else if (strcmp(*argv, "-quiet") == 0) {
856280297Sjkim            c_quiet = 1;
857280297Sjkim            c_ign_eof = 1;
858280297Sjkim        } else if (strcmp(*argv, "-ign_eof") == 0)
859280297Sjkim            c_ign_eof = 1;
860280297Sjkim        else if (strcmp(*argv, "-no_ign_eof") == 0)
861280297Sjkim            c_ign_eof = 0;
862280297Sjkim        else if (strcmp(*argv, "-pause") == 0)
863280297Sjkim            c_Pause = 1;
864280297Sjkim        else if (strcmp(*argv, "-debug") == 0)
865280297Sjkim            c_debug = 1;
866194206Ssimon#ifndef OPENSSL_NO_TLSEXT
867280297Sjkim        else if (strcmp(*argv, "-tlsextdebug") == 0)
868280297Sjkim            c_tlsextdebug = 1;
869280297Sjkim        else if (strcmp(*argv, "-status") == 0)
870280297Sjkim            c_status_req = 1;
871194206Ssimon#endif
872160814Ssimon#ifdef WATT32
873280297Sjkim        else if (strcmp(*argv, "-wdebug") == 0)
874280297Sjkim            dbug_init();
875160814Ssimon#endif
876280297Sjkim        else if (strcmp(*argv, "-msg") == 0)
877280297Sjkim            c_msg = 1;
878290207Sjkim        else if (strcmp(*argv, "-msgfile") == 0) {
879290207Sjkim            if (--argc < 1)
880290207Sjkim                goto bad;
881290207Sjkim            bio_c_msg = BIO_new_file(*(++argv), "w");
882290207Sjkim        }
883290207Sjkim#ifndef OPENSSL_NO_SSL_TRACE
884290207Sjkim        else if (strcmp(*argv, "-trace") == 0)
885290207Sjkim            c_msg = 2;
886290207Sjkim#endif
887280297Sjkim        else if (strcmp(*argv, "-showcerts") == 0)
888280297Sjkim            c_showcerts = 1;
889280297Sjkim        else if (strcmp(*argv, "-nbio_test") == 0)
890280297Sjkim            nbio_test = 1;
891280297Sjkim        else if (strcmp(*argv, "-state") == 0)
892280297Sjkim            state = 1;
893238405Sjkim#ifndef OPENSSL_NO_PSK
894280297Sjkim        else if (strcmp(*argv, "-psk_identity") == 0) {
895280297Sjkim            if (--argc < 1)
896280297Sjkim                goto bad;
897280297Sjkim            psk_identity = *(++argv);
898280297Sjkim        } else if (strcmp(*argv, "-psk") == 0) {
899280297Sjkim            size_t j;
900238405Sjkim
901280297Sjkim            if (--argc < 1)
902280297Sjkim                goto bad;
903280297Sjkim            psk_key = *(++argv);
904280297Sjkim            for (j = 0; j < strlen(psk_key); j++) {
905280297Sjkim                if (isxdigit((unsigned char)psk_key[j]))
906280297Sjkim                    continue;
907280297Sjkim                BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
908280297Sjkim                goto bad;
909280297Sjkim            }
910280297Sjkim        }
911238405Sjkim#endif
912238405Sjkim#ifndef OPENSSL_NO_SRP
913280297Sjkim        else if (strcmp(*argv, "-srpuser") == 0) {
914280297Sjkim            if (--argc < 1)
915280297Sjkim                goto bad;
916280297Sjkim            srp_arg.srplogin = *(++argv);
917280297Sjkim            meth = TLSv1_client_method();
918280297Sjkim        } else if (strcmp(*argv, "-srppass") == 0) {
919280297Sjkim            if (--argc < 1)
920280297Sjkim                goto bad;
921280297Sjkim            srppass = *(++argv);
922280297Sjkim            meth = TLSv1_client_method();
923280297Sjkim        } else if (strcmp(*argv, "-srp_strength") == 0) {
924280297Sjkim            if (--argc < 1)
925280297Sjkim                goto bad;
926280297Sjkim            srp_arg.strength = atoi(*(++argv));
927280297Sjkim            BIO_printf(bio_err, "SRP minimal length for N is %d\n",
928280297Sjkim                       srp_arg.strength);
929280297Sjkim            meth = TLSv1_client_method();
930280297Sjkim        } else if (strcmp(*argv, "-srp_lateuser") == 0) {
931280297Sjkim            srp_lateuser = 1;
932280297Sjkim            meth = TLSv1_client_method();
933280297Sjkim        } else if (strcmp(*argv, "-srp_moregroups") == 0) {
934280297Sjkim            srp_arg.amp = 1;
935280297Sjkim            meth = TLSv1_client_method();
936280297Sjkim        }
937238405Sjkim#endif
938109998Smarkm#ifndef OPENSSL_NO_SSL2
939280297Sjkim        else if (strcmp(*argv, "-ssl2") == 0)
940280297Sjkim            meth = SSLv2_client_method();
94155714Skris#endif
942276861Sjkim#ifndef OPENSSL_NO_SSL3_METHOD
943280297Sjkim        else if (strcmp(*argv, "-ssl3") == 0)
944280297Sjkim            meth = SSLv3_client_method();
94555714Skris#endif
946109998Smarkm#ifndef OPENSSL_NO_TLS1
947280297Sjkim        else if (strcmp(*argv, "-tls1_2") == 0)
948280297Sjkim            meth = TLSv1_2_client_method();
949280297Sjkim        else if (strcmp(*argv, "-tls1_1") == 0)
950280297Sjkim            meth = TLSv1_1_client_method();
951280297Sjkim        else if (strcmp(*argv, "-tls1") == 0)
952280297Sjkim            meth = TLSv1_client_method();
95355714Skris#endif
954160814Ssimon#ifndef OPENSSL_NO_DTLS1
955290207Sjkim        else if (strcmp(*argv, "-dtls") == 0) {
956290207Sjkim            meth = DTLS_client_method();
957290207Sjkim            socket_type = SOCK_DGRAM;
958290207Sjkim        } else if (strcmp(*argv, "-dtls1") == 0) {
959280297Sjkim            meth = DTLSv1_client_method();
960280297Sjkim            socket_type = SOCK_DGRAM;
961290207Sjkim        } else if (strcmp(*argv, "-dtls1_2") == 0) {
962290207Sjkim            meth = DTLSv1_2_client_method();
963290207Sjkim            socket_type = SOCK_DGRAM;
964280297Sjkim        } else if (strcmp(*argv, "-timeout") == 0)
965280297Sjkim            enable_timeouts = 1;
966280297Sjkim        else if (strcmp(*argv, "-mtu") == 0) {
967280297Sjkim            if (--argc < 1)
968280297Sjkim                goto bad;
969280297Sjkim            socket_mtu = atol(*(++argv));
970280297Sjkim        }
971160814Ssimon#endif
972290207Sjkim        else if (strcmp(*argv, "-fallback_scsv") == 0) {
973290207Sjkim            fallback_scsv = 1;
974290207Sjkim        } else if (strcmp(*argv, "-keyform") == 0) {
975280297Sjkim            if (--argc < 1)
976280297Sjkim                goto bad;
977280297Sjkim            key_format = str2fmt(*(++argv));
978280297Sjkim        } else if (strcmp(*argv, "-pass") == 0) {
979280297Sjkim            if (--argc < 1)
980280297Sjkim                goto bad;
981280297Sjkim            passarg = *(++argv);
982290207Sjkim        } else if (strcmp(*argv, "-cert_chain") == 0) {
983290207Sjkim            if (--argc < 1)
984290207Sjkim                goto bad;
985290207Sjkim            chain_file = *(++argv);
986280297Sjkim        } else if (strcmp(*argv, "-key") == 0) {
987280297Sjkim            if (--argc < 1)
988280297Sjkim                goto bad;
989280297Sjkim            key_file = *(++argv);
990280297Sjkim        } else if (strcmp(*argv, "-reconnect") == 0) {
991280297Sjkim            reconnect = 5;
992280297Sjkim        } else if (strcmp(*argv, "-CApath") == 0) {
993280297Sjkim            if (--argc < 1)
994280297Sjkim                goto bad;
995280297Sjkim            CApath = *(++argv);
996290207Sjkim        } else if (strcmp(*argv, "-chainCApath") == 0) {
997280297Sjkim            if (--argc < 1)
998280297Sjkim                goto bad;
999290207Sjkim            chCApath = *(++argv);
1000290207Sjkim        } else if (strcmp(*argv, "-verifyCApath") == 0) {
1001290207Sjkim            if (--argc < 1)
1002290207Sjkim                goto bad;
1003290207Sjkim            vfyCApath = *(++argv);
1004290207Sjkim        } else if (strcmp(*argv, "-build_chain") == 0)
1005290207Sjkim            build_chain = 1;
1006290207Sjkim        else if (strcmp(*argv, "-CAfile") == 0) {
1007290207Sjkim            if (--argc < 1)
1008290207Sjkim                goto bad;
1009280297Sjkim            CAfile = *(++argv);
1010290207Sjkim        } else if (strcmp(*argv, "-chainCAfile") == 0) {
1011290207Sjkim            if (--argc < 1)
1012290207Sjkim                goto bad;
1013290207Sjkim            chCAfile = *(++argv);
1014290207Sjkim        } else if (strcmp(*argv, "-verifyCAfile") == 0) {
1015290207Sjkim            if (--argc < 1)
1016290207Sjkim                goto bad;
1017290207Sjkim            vfyCAfile = *(++argv);
1018280297Sjkim        }
1019194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1020238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
1021280297Sjkim        else if (strcmp(*argv, "-nextprotoneg") == 0) {
1022280297Sjkim            if (--argc < 1)
1023280297Sjkim                goto bad;
1024280297Sjkim            next_proto_neg_in = *(++argv);
1025280297Sjkim        }
1026238405Sjkim# endif
1027290207Sjkim        else if (strcmp(*argv, "-alpn") == 0) {
1028280297Sjkim            if (--argc < 1)
1029280297Sjkim                goto bad;
1030290207Sjkim            alpn_in = *(++argv);
1031290207Sjkim        } else if (strcmp(*argv, "-serverinfo") == 0) {
1032290207Sjkim            char *c;
1033290207Sjkim            int start = 0;
1034290207Sjkim            int len;
1035290207Sjkim
1036290207Sjkim            if (--argc < 1)
1037290207Sjkim                goto bad;
1038290207Sjkim            c = *(++argv);
1039290207Sjkim            serverinfo_types_count = 0;
1040290207Sjkim            len = strlen(c);
1041290207Sjkim            for (i = 0; i <= len; ++i) {
1042290207Sjkim                if (i == len || c[i] == ',') {
1043290207Sjkim                    serverinfo_types[serverinfo_types_count]
1044290207Sjkim                        = atoi(c + start);
1045290207Sjkim                    serverinfo_types_count++;
1046290207Sjkim                    start = i + 1;
1047290207Sjkim                }
1048290207Sjkim                if (serverinfo_types_count == MAX_SI_TYPES)
1049290207Sjkim                    break;
1050290207Sjkim            }
1051280297Sjkim        }
1052290207Sjkim#endif
105355714Skris#ifdef FIONBIO
1054280297Sjkim        else if (strcmp(*argv, "-nbio") == 0) {
1055280297Sjkim            c_nbio = 1;
1056280297Sjkim        }
105755714Skris#endif
1058280297Sjkim        else if (strcmp(*argv, "-starttls") == 0) {
1059280297Sjkim            if (--argc < 1)
1060280297Sjkim                goto bad;
1061280297Sjkim            ++argv;
1062280297Sjkim            if (strcmp(*argv, "smtp") == 0)
1063280297Sjkim                starttls_proto = PROTO_SMTP;
1064280297Sjkim            else if (strcmp(*argv, "pop3") == 0)
1065280297Sjkim                starttls_proto = PROTO_POP3;
1066280297Sjkim            else if (strcmp(*argv, "imap") == 0)
1067280297Sjkim                starttls_proto = PROTO_IMAP;
1068280297Sjkim            else if (strcmp(*argv, "ftp") == 0)
1069280297Sjkim                starttls_proto = PROTO_FTP;
1070280297Sjkim            else if (strcmp(*argv, "xmpp") == 0)
1071280297Sjkim                starttls_proto = PROTO_XMPP;
1072280297Sjkim            else
1073280297Sjkim                goto bad;
1074280297Sjkim        }
1075111147Snectar#ifndef OPENSSL_NO_ENGINE
1076280297Sjkim        else if (strcmp(*argv, "-engine") == 0) {
1077280297Sjkim            if (--argc < 1)
1078280297Sjkim                goto bad;
1079280297Sjkim            engine_id = *(++argv);
1080280297Sjkim        } else if (strcmp(*argv, "-ssl_client_engine") == 0) {
1081280297Sjkim            if (--argc < 1)
1082280297Sjkim                goto bad;
1083280297Sjkim            ssl_client_engine_id = *(++argv);
1084280297Sjkim        }
1085111147Snectar#endif
1086280297Sjkim        else if (strcmp(*argv, "-rand") == 0) {
1087280297Sjkim            if (--argc < 1)
1088280297Sjkim                goto bad;
1089280297Sjkim            inrand = *(++argv);
1090280297Sjkim        }
1091194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1092280297Sjkim        else if (strcmp(*argv, "-servername") == 0) {
1093280297Sjkim            if (--argc < 1)
1094280297Sjkim                goto bad;
1095280297Sjkim            servername = *(++argv);
1096280297Sjkim            /* meth=TLSv1_client_method(); */
1097280297Sjkim        }
1098194206Ssimon#endif
1099194206Ssimon#ifndef OPENSSL_NO_JPAKE
1100280297Sjkim        else if (strcmp(*argv, "-jpake") == 0) {
1101280297Sjkim            if (--argc < 1)
1102280297Sjkim                goto bad;
1103280297Sjkim            jpake_secret = *++argv;
1104280297Sjkim        }
1105194206Ssimon#endif
1106246772Sjkim#ifndef OPENSSL_NO_SRTP
1107280297Sjkim        else if (strcmp(*argv, "-use_srtp") == 0) {
1108280297Sjkim            if (--argc < 1)
1109280297Sjkim                goto bad;
1110280297Sjkim            srtp_profiles = *(++argv);
1111280297Sjkim        }
1112246772Sjkim#endif
1113280297Sjkim        else if (strcmp(*argv, "-keymatexport") == 0) {
1114280297Sjkim            if (--argc < 1)
1115280297Sjkim                goto bad;
1116280297Sjkim            keymatexportlabel = *(++argv);
1117280297Sjkim        } else if (strcmp(*argv, "-keymatexportlen") == 0) {
1118280297Sjkim            if (--argc < 1)
1119280297Sjkim                goto bad;
1120280297Sjkim            keymatexportlen = atoi(*(++argv));
1121280297Sjkim            if (keymatexportlen == 0)
1122280297Sjkim                goto bad;
1123280297Sjkim        } else {
1124280297Sjkim            BIO_printf(bio_err, "unknown option %s\n", *argv);
1125280297Sjkim            badop = 1;
1126280297Sjkim            break;
1127280297Sjkim        }
1128280297Sjkim        argc--;
1129280297Sjkim        argv++;
1130280297Sjkim    }
1131280297Sjkim    if (badop) {
1132280297Sjkim bad:
1133280297Sjkim        sc_usage();
1134280297Sjkim        goto end;
1135280297Sjkim    }
1136238405Sjkim#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
1137280297Sjkim    if (jpake_secret) {
1138280297Sjkim        if (psk_key) {
1139280297Sjkim            BIO_printf(bio_err, "Can't use JPAKE and PSK together\n");
1140280297Sjkim            goto end;
1141280297Sjkim        }
1142280297Sjkim        psk_identity = "JPAKE";
1143280297Sjkim    }
1144238405Sjkim#endif
1145238405Sjkim
1146280297Sjkim    OpenSSL_add_ssl_algorithms();
1147280297Sjkim    SSL_load_error_strings();
1148109998Smarkm
1149238405Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
1150280297Sjkim    next_proto.status = -1;
1151280297Sjkim    if (next_proto_neg_in) {
1152280297Sjkim        next_proto.data =
1153280297Sjkim            next_protos_parse(&next_proto.len, next_proto_neg_in);
1154280297Sjkim        if (next_proto.data == NULL) {
1155280297Sjkim            BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
1156280297Sjkim            goto end;
1157280297Sjkim        }
1158280297Sjkim    } else
1159280297Sjkim        next_proto.data = NULL;
1160238405Sjkim#endif
1161238405Sjkim
1162111147Snectar#ifndef OPENSSL_NO_ENGINE
1163280297Sjkim    e = setup_engine(bio_err, engine_id, 1);
1164280297Sjkim    if (ssl_client_engine_id) {
1165280297Sjkim        ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
1166280297Sjkim        if (!ssl_client_engine) {
1167280297Sjkim            BIO_printf(bio_err, "Error getting client auth engine\n");
1168280297Sjkim            goto end;
1169280297Sjkim        }
1170280297Sjkim    }
1171111147Snectar#endif
1172280297Sjkim    if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
1173280297Sjkim        BIO_printf(bio_err, "Error getting password\n");
1174280297Sjkim        goto end;
1175280297Sjkim    }
1176109998Smarkm
1177280297Sjkim    if (key_file == NULL)
1178280297Sjkim        key_file = cert_file;
1179160814Ssimon
1180280297Sjkim    if (key_file) {
1181160814Ssimon
1182280297Sjkim        key = load_key(bio_err, key_file, key_format, 0, pass, e,
1183280297Sjkim                       "client certificate private key file");
1184280297Sjkim        if (!key) {
1185280297Sjkim            ERR_print_errors(bio_err);
1186280297Sjkim            goto end;
1187280297Sjkim        }
1188160814Ssimon
1189280297Sjkim    }
1190160814Ssimon
1191280297Sjkim    if (cert_file) {
1192280297Sjkim        cert = load_cert(bio_err, cert_file, cert_format,
1193280297Sjkim                         NULL, e, "client certificate file");
1194160814Ssimon
1195280297Sjkim        if (!cert) {
1196280297Sjkim            ERR_print_errors(bio_err);
1197280297Sjkim            goto end;
1198280297Sjkim        }
1199280297Sjkim    }
1200160814Ssimon
1201290207Sjkim    if (chain_file) {
1202290207Sjkim        chain = load_certs(bio_err, chain_file, FORMAT_PEM,
1203290207Sjkim                           NULL, e, "client certificate chain");
1204290207Sjkim        if (!chain)
1205290207Sjkim            goto end;
1206290207Sjkim    }
1207290207Sjkim
1208290207Sjkim    if (crl_file) {
1209290207Sjkim        X509_CRL *crl;
1210290207Sjkim        crl = load_crl(crl_file, crl_format);
1211290207Sjkim        if (!crl) {
1212290207Sjkim            BIO_puts(bio_err, "Error loading CRL\n");
1213290207Sjkim            ERR_print_errors(bio_err);
1214290207Sjkim            goto end;
1215290207Sjkim        }
1216290207Sjkim        crls = sk_X509_CRL_new_null();
1217290207Sjkim        if (!crls || !sk_X509_CRL_push(crls, crl)) {
1218290207Sjkim            BIO_puts(bio_err, "Error adding CRL\n");
1219290207Sjkim            ERR_print_errors(bio_err);
1220290207Sjkim            X509_CRL_free(crl);
1221290207Sjkim            goto end;
1222290207Sjkim        }
1223290207Sjkim    }
1224290207Sjkim
1225290207Sjkim    if (!load_excert(&exc, bio_err))
1226290207Sjkim        goto end;
1227290207Sjkim
1228280297Sjkim    if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
1229280297Sjkim        && !RAND_status()) {
1230280297Sjkim        BIO_printf(bio_err,
1231280297Sjkim                   "warning, not much extra random data, consider using the -rand option\n");
1232280297Sjkim    }
1233280297Sjkim    if (inrand != NULL)
1234280297Sjkim        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
1235280297Sjkim                   app_RAND_load_files(inrand));
1236160814Ssimon
1237280297Sjkim    if (bio_c_out == NULL) {
1238290207Sjkim        if (c_quiet && !c_debug) {
1239280297Sjkim            bio_c_out = BIO_new(BIO_s_null());
1240290207Sjkim            if (c_msg && !bio_c_msg)
1241290207Sjkim                bio_c_msg = BIO_new_fp(stdout, BIO_NOCLOSE);
1242280297Sjkim        } else {
1243280297Sjkim            if (bio_c_out == NULL)
1244280297Sjkim                bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE);
1245280297Sjkim        }
1246280297Sjkim    }
1247238405Sjkim#ifndef OPENSSL_NO_SRP
1248280297Sjkim    if (!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL)) {
1249280297Sjkim        BIO_printf(bio_err, "Error getting password\n");
1250280297Sjkim        goto end;
1251280297Sjkim    }
1252238405Sjkim#endif
1253238405Sjkim
1254280297Sjkim    ctx = SSL_CTX_new(meth);
1255280297Sjkim    if (ctx == NULL) {
1256280297Sjkim        ERR_print_errors(bio_err);
1257280297Sjkim        goto end;
1258280297Sjkim    }
125955714Skris
1260280297Sjkim    if (vpm)
1261280297Sjkim        SSL_CTX_set1_param(ctx, vpm);
1262238405Sjkim
1263290207Sjkim    if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake)) {
1264290207Sjkim        ERR_print_errors(bio_err);
1265290207Sjkim        goto end;
1266290207Sjkim    }
1267290207Sjkim
1268290207Sjkim    if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
1269290207Sjkim                         crls, crl_download)) {
1270290207Sjkim        BIO_printf(bio_err, "Error loading store locations\n");
1271290207Sjkim        ERR_print_errors(bio_err);
1272290207Sjkim        goto end;
1273290207Sjkim    }
1274194206Ssimon#ifndef OPENSSL_NO_ENGINE
1275280297Sjkim    if (ssl_client_engine) {
1276280297Sjkim        if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
1277280297Sjkim            BIO_puts(bio_err, "Error setting client auth engine\n");
1278280297Sjkim            ERR_print_errors(bio_err);
1279280297Sjkim            ENGINE_free(ssl_client_engine);
1280280297Sjkim            goto end;
1281280297Sjkim        }
1282280297Sjkim        ENGINE_free(ssl_client_engine);
1283280297Sjkim    }
1284194206Ssimon#endif
1285194206Ssimon
1286238405Sjkim#ifndef OPENSSL_NO_PSK
1287280297Sjkim# ifdef OPENSSL_NO_JPAKE
1288280297Sjkim    if (psk_key != NULL)
1289280297Sjkim# else
1290280297Sjkim    if (psk_key != NULL || jpake_secret)
1291280297Sjkim# endif
1292280297Sjkim    {
1293280297Sjkim        if (c_debug)
1294280297Sjkim            BIO_printf(bio_c_out,
1295280297Sjkim                       "PSK key given or JPAKE in use, setting client callback\n");
1296280297Sjkim        SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
1297280297Sjkim    }
1298238405Sjkim#endif
1299246772Sjkim#ifndef OPENSSL_NO_SRTP
1300280297Sjkim    if (srtp_profiles != NULL)
1301280297Sjkim        SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
1302238405Sjkim#endif
1303290207Sjkim    if (exc)
1304290207Sjkim        ssl_ctx_set_excert(ctx, exc);
1305205128Ssimon
1306290207Sjkim#if !defined(OPENSSL_NO_TLSEXT)
1307290207Sjkim# if !defined(OPENSSL_NO_NEXTPROTONEG)
1308280297Sjkim    if (next_proto.data)
1309280297Sjkim        SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
1310290207Sjkim# endif
1311290207Sjkim    if (alpn_in) {
1312290207Sjkim        unsigned short alpn_len;
1313290207Sjkim        unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
1314290207Sjkim
1315290207Sjkim        if (alpn == NULL) {
1316290207Sjkim            BIO_printf(bio_err, "Error parsing -alpn argument\n");
1317290207Sjkim            goto end;
1318290207Sjkim        }
1319290207Sjkim        SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
1320290207Sjkim        OPENSSL_free(alpn);
1321290207Sjkim    }
1322238405Sjkim#endif
1323290207Sjkim#ifndef OPENSSL_NO_TLSEXT
1324290207Sjkim    for (i = 0; i < serverinfo_types_count; i++) {
1325290207Sjkim        SSL_CTX_add_client_custom_ext(ctx,
1326290207Sjkim                                      serverinfo_types[i],
1327290207Sjkim                                      NULL, NULL, NULL,
1328290207Sjkim                                      serverinfo_cli_parse_cb, NULL);
1329290207Sjkim    }
1330290207Sjkim#endif
1331238405Sjkim
1332280297Sjkim    if (state)
1333280297Sjkim        SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
133455714Skris#if 0
1335290207Sjkim    else
1336290207Sjkim        SSL_CTX_set_cipher_list(ctx, getenv("SSL_CIPHER"));
133755714Skris#endif
133855714Skris
1339280297Sjkim    SSL_CTX_set_verify(ctx, verify, verify_callback);
134055714Skris
1341284283Sjkim    if ((CAfile || CApath)
1342284283Sjkim        && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
1343280297Sjkim        ERR_print_errors(bio_err);
1344280297Sjkim    }
1345284283Sjkim    if (!SSL_CTX_set_default_verify_paths(ctx)) {
1346284283Sjkim        ERR_print_errors(bio_err);
1347284283Sjkim    }
1348290207Sjkim
1349290207Sjkim    ssl_ctx_add_crls(ctx, crls, crl_download);
1350290207Sjkim    if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain))
1351290207Sjkim        goto end;
1352290207Sjkim
1353194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1354280297Sjkim    if (servername != NULL) {
1355280297Sjkim        tlsextcbp.biodebug = bio_err;
1356280297Sjkim        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1357280297Sjkim        SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
1358280297Sjkim    }
1359280297Sjkim# ifndef OPENSSL_NO_SRP
1360280297Sjkim    if (srp_arg.srplogin) {
1361280297Sjkim        if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) {
1362280297Sjkim            BIO_printf(bio_err, "Unable to set SRP username\n");
1363280297Sjkim            goto end;
1364280297Sjkim        }
1365280297Sjkim        srp_arg.msg = c_msg;
1366280297Sjkim        srp_arg.debug = c_debug;
1367280297Sjkim        SSL_CTX_set_srp_cb_arg(ctx, &srp_arg);
1368280297Sjkim        SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
1369280297Sjkim        SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
1370280297Sjkim        if (c_msg || c_debug || srp_arg.amp == 0)
1371280297Sjkim            SSL_CTX_set_srp_verify_param_callback(ctx,
1372280297Sjkim                                                  ssl_srp_verify_param_cb);
1373280297Sjkim    }
1374280297Sjkim# endif
1375194206Ssimon#endif
137655714Skris
1377280297Sjkim    con = SSL_new(ctx);
1378280297Sjkim    if (sess_in) {
1379280297Sjkim        SSL_SESSION *sess;
1380280297Sjkim        BIO *stmp = BIO_new_file(sess_in, "r");
1381280297Sjkim        if (!stmp) {
1382280297Sjkim            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
1383280297Sjkim            ERR_print_errors(bio_err);
1384280297Sjkim            goto end;
1385280297Sjkim        }
1386280297Sjkim        sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
1387280297Sjkim        BIO_free(stmp);
1388280297Sjkim        if (!sess) {
1389280297Sjkim            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
1390280297Sjkim            ERR_print_errors(bio_err);
1391280297Sjkim            goto end;
1392280297Sjkim        }
1393280297Sjkim        SSL_set_session(con, sess);
1394280297Sjkim        SSL_SESSION_free(sess);
1395280297Sjkim    }
1396273144Sjkim
1397280297Sjkim    if (fallback_scsv)
1398280297Sjkim        SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
1399273144Sjkim
1400194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1401280297Sjkim    if (servername != NULL) {
1402280297Sjkim        if (!SSL_set_tlsext_host_name(con, servername)) {
1403280297Sjkim            BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
1404280297Sjkim            ERR_print_errors(bio_err);
1405280297Sjkim            goto end;
1406280297Sjkim        }
1407280297Sjkim    }
1408194206Ssimon#endif
1409109998Smarkm#ifndef OPENSSL_NO_KRB5
1410280297Sjkim    if (con && (kctx = kssl_ctx_new()) != NULL) {
1411280297Sjkim        SSL_set0_kssl_ctx(con, kctx);
1412280297Sjkim        kssl_ctx_setstring(kctx, KSSL_SERVER, host);
1413280297Sjkim    }
1414280297Sjkim#endif                          /* OPENSSL_NO_KRB5 */
1415280297Sjkim/*      SSL_set_cipher_list(con,"RC4-MD5"); */
1416238405Sjkim#if 0
1417280297Sjkim# ifdef TLSEXT_TYPE_opaque_prf_input
1418280297Sjkim    SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
1419280297Sjkim# endif
1420238405Sjkim#endif
142155714Skris
1422280297Sjkim re_start:
142355714Skris
1424280297Sjkim    if (init_client(&s, host, port, socket_type) == 0) {
1425280297Sjkim        BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
1426280297Sjkim        SHUTDOWN(s);
1427280297Sjkim        goto end;
1428280297Sjkim    }
1429280297Sjkim    BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
143055714Skris
143155714Skris#ifdef FIONBIO
1432280297Sjkim    if (c_nbio) {
1433280297Sjkim        unsigned long l = 1;
1434280297Sjkim        BIO_printf(bio_c_out, "turning on non blocking io\n");
1435280297Sjkim        if (BIO_socket_ioctl(s, FIONBIO, &l) < 0) {
1436280297Sjkim            ERR_print_errors(bio_err);
1437280297Sjkim            goto end;
1438280297Sjkim        }
1439280297Sjkim    }
1440280297Sjkim#endif
1441280297Sjkim    if (c_Pause & 0x01)
1442280297Sjkim        SSL_set_debug(con, 1);
144355714Skris
1444290207Sjkim    if (socket_type == SOCK_DGRAM) {
1445160814Ssimon
1446280297Sjkim        sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1447280297Sjkim        if (getsockname(s, &peer, (void *)&peerlen) < 0) {
1448280297Sjkim            BIO_printf(bio_err, "getsockname:errno=%d\n",
1449280297Sjkim                       get_last_socket_error());
1450280297Sjkim            SHUTDOWN(s);
1451280297Sjkim            goto end;
1452280297Sjkim        }
1453160814Ssimon
1454280297Sjkim        (void)BIO_ctrl_set_connected(sbio, 1, &peer);
1455160814Ssimon
1456280297Sjkim        if (enable_timeouts) {
1457280297Sjkim            timeout.tv_sec = 0;
1458280297Sjkim            timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1459280297Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
1460160814Ssimon
1461280297Sjkim            timeout.tv_sec = 0;
1462280297Sjkim            timeout.tv_usec = DGRAM_SND_TIMEOUT;
1463280297Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
1464280297Sjkim        }
1465160814Ssimon
1466280297Sjkim        if (socket_mtu) {
1467280297Sjkim            if (socket_mtu < DTLS_get_link_min_mtu(con)) {
1468280297Sjkim                BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
1469280297Sjkim                           DTLS_get_link_min_mtu(con));
1470280297Sjkim                BIO_free(sbio);
1471280297Sjkim                goto shut;
1472280297Sjkim            }
1473280297Sjkim            SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1474280297Sjkim            if (!DTLS_set_link_mtu(con, socket_mtu)) {
1475280297Sjkim                BIO_printf(bio_err, "Failed to set MTU\n");
1476280297Sjkim                BIO_free(sbio);
1477280297Sjkim                goto shut;
1478280297Sjkim            }
1479280297Sjkim        } else
1480280297Sjkim            /* want to do MTU discovery */
1481280297Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1482280297Sjkim    } else
1483280297Sjkim        sbio = BIO_new_socket(s, BIO_NOCLOSE);
148455714Skris
1485280297Sjkim    if (nbio_test) {
1486280297Sjkim        BIO *test;
148755714Skris
1488280297Sjkim        test = BIO_new(BIO_f_nbio_test());
1489280297Sjkim        sbio = BIO_push(test, sbio);
1490280297Sjkim    }
1491280297Sjkim
1492280297Sjkim    if (c_debug) {
1493280297Sjkim        SSL_set_debug(con, 1);
1494280297Sjkim        BIO_set_callback(sbio, bio_dump_callback);
1495280297Sjkim        BIO_set_callback_arg(sbio, (char *)bio_c_out);
1496280297Sjkim    }
1497280297Sjkim    if (c_msg) {
1498290207Sjkim#ifndef OPENSSL_NO_SSL_TRACE
1499290207Sjkim        if (c_msg == 2)
1500290207Sjkim            SSL_set_msg_callback(con, SSL_trace);
1501290207Sjkim        else
1502290207Sjkim#endif
1503290207Sjkim            SSL_set_msg_callback(con, msg_cb);
1504290207Sjkim        SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);
1505280297Sjkim    }
1506194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1507280297Sjkim    if (c_tlsextdebug) {
1508280297Sjkim        SSL_set_tlsext_debug_callback(con, tlsext_cb);
1509280297Sjkim        SSL_set_tlsext_debug_arg(con, bio_c_out);
1510280297Sjkim    }
1511280297Sjkim    if (c_status_req) {
1512280297Sjkim        SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
1513280297Sjkim        SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
1514280297Sjkim        SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
1515280297Sjkim# if 0
1516280297Sjkim        {
1517280297Sjkim            STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
1518280297Sjkim            OCSP_RESPID *id = OCSP_RESPID_new();
1519280297Sjkim            id->value.byKey = ASN1_OCTET_STRING_new();
1520280297Sjkim            id->type = V_OCSP_RESPID_KEY;
1521280297Sjkim            ASN1_STRING_set(id->value.byKey, "Hello World", -1);
1522280297Sjkim            sk_OCSP_RESPID_push(ids, id);
1523280297Sjkim            SSL_set_tlsext_status_ids(con, ids);
1524280297Sjkim        }
1525280297Sjkim# endif
1526280297Sjkim    }
1527194206Ssimon#endif
1528194206Ssimon#ifndef OPENSSL_NO_JPAKE
1529280297Sjkim    if (jpake_secret)
1530280297Sjkim        jpake_client_auth(bio_c_out, sbio, jpake_secret);
1531194206Ssimon#endif
153255714Skris
1533280297Sjkim    SSL_set_bio(con, sbio, sbio);
1534280297Sjkim    SSL_set_connect_state(con);
153555714Skris
1536280297Sjkim    /* ok, lets connect */
1537280297Sjkim    width = SSL_get_fd(con) + 1;
153855714Skris
1539280297Sjkim    read_tty = 1;
1540280297Sjkim    write_tty = 0;
1541280297Sjkim    tty_on = 0;
1542280297Sjkim    read_ssl = 1;
1543280297Sjkim    write_ssl = 1;
154455714Skris
1545280297Sjkim    cbuf_len = 0;
1546280297Sjkim    cbuf_off = 0;
1547280297Sjkim    sbuf_len = 0;
1548280297Sjkim    sbuf_off = 0;
1549109998Smarkm
1550280297Sjkim    /* This is an ugly hack that does a lot of assumptions */
1551280297Sjkim    /*
1552280297Sjkim     * We do have to handle multi-line responses which may come in a single
1553280297Sjkim     * packet or not. We therefore have to use BIO_gets() which does need a
1554280297Sjkim     * buffering BIO. So during the initial chitchat we do push a buffering
1555280297Sjkim     * BIO into the chain that is removed again later on to not disturb the
1556280297Sjkim     * rest of the s_client operation.
1557280297Sjkim     */
1558280297Sjkim    if (starttls_proto == PROTO_SMTP) {
1559280297Sjkim        int foundit = 0;
1560280297Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1561280297Sjkim        BIO_push(fbio, sbio);
1562280297Sjkim        /* wait for multi-line response to end from SMTP */
1563280297Sjkim        do {
1564280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1565280297Sjkim        }
1566280297Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1567280297Sjkim        /* STARTTLS command requires EHLO... */
1568280297Sjkim        BIO_printf(fbio, "EHLO openssl.client.net\r\n");
1569280297Sjkim        (void)BIO_flush(fbio);
1570280297Sjkim        /* wait for multi-line response to end EHLO SMTP response */
1571280297Sjkim        do {
1572280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1573280297Sjkim            if (strstr(mbuf, "STARTTLS"))
1574280297Sjkim                foundit = 1;
1575280297Sjkim        }
1576280297Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1577280297Sjkim        (void)BIO_flush(fbio);
1578280297Sjkim        BIO_pop(fbio);
1579280297Sjkim        BIO_free(fbio);
1580280297Sjkim        if (!foundit)
1581280297Sjkim            BIO_printf(bio_err,
1582280297Sjkim                       "didn't found starttls in server response,"
1583280297Sjkim                       " try anyway...\n");
1584280297Sjkim        BIO_printf(sbio, "STARTTLS\r\n");
1585280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1586280297Sjkim    } else if (starttls_proto == PROTO_POP3) {
1587280297Sjkim        BIO_read(sbio, mbuf, BUFSIZZ);
1588280297Sjkim        BIO_printf(sbio, "STLS\r\n");
1589280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1590280297Sjkim    } else if (starttls_proto == PROTO_IMAP) {
1591280297Sjkim        int foundit = 0;
1592280297Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1593280297Sjkim        BIO_push(fbio, sbio);
1594280297Sjkim        BIO_gets(fbio, mbuf, BUFSIZZ);
1595280297Sjkim        /* STARTTLS command requires CAPABILITY... */
1596280297Sjkim        BIO_printf(fbio, ". CAPABILITY\r\n");
1597280297Sjkim        (void)BIO_flush(fbio);
1598280297Sjkim        /* wait for multi-line CAPABILITY response */
1599280297Sjkim        do {
1600280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1601280297Sjkim            if (strstr(mbuf, "STARTTLS"))
1602280297Sjkim                foundit = 1;
1603280297Sjkim        }
1604280297Sjkim        while (mbuf_len > 3 && mbuf[0] != '.');
1605280297Sjkim        (void)BIO_flush(fbio);
1606280297Sjkim        BIO_pop(fbio);
1607280297Sjkim        BIO_free(fbio);
1608280297Sjkim        if (!foundit)
1609280297Sjkim            BIO_printf(bio_err,
1610280297Sjkim                       "didn't found STARTTLS in server response,"
1611280297Sjkim                       " try anyway...\n");
1612280297Sjkim        BIO_printf(sbio, ". STARTTLS\r\n");
1613280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1614280297Sjkim    } else if (starttls_proto == PROTO_FTP) {
1615280297Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1616280297Sjkim        BIO_push(fbio, sbio);
1617280297Sjkim        /* wait for multi-line response to end from FTP */
1618280297Sjkim        do {
1619280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1620280297Sjkim        }
1621280297Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1622280297Sjkim        (void)BIO_flush(fbio);
1623280297Sjkim        BIO_pop(fbio);
1624280297Sjkim        BIO_free(fbio);
1625280297Sjkim        BIO_printf(sbio, "AUTH TLS\r\n");
1626280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1627280297Sjkim    }
1628280297Sjkim    if (starttls_proto == PROTO_XMPP) {
1629280297Sjkim        int seen = 0;
1630280297Sjkim        BIO_printf(sbio, "<stream:stream "
1631280297Sjkim                   "xmlns:stream='http://etherx.jabber.org/streams' "
1632280297Sjkim                   "xmlns='jabber:client' to='%s' version='1.0'>", host);
1633280297Sjkim        seen = BIO_read(sbio, mbuf, BUFSIZZ);
1634280297Sjkim        mbuf[seen] = 0;
1635280297Sjkim        while (!strstr
1636280297Sjkim               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) {
1637280297Sjkim            if (strstr(mbuf, "/stream:features>"))
1638280297Sjkim                goto shut;
1639280297Sjkim            seen = BIO_read(sbio, mbuf, BUFSIZZ);
1640280297Sjkim            mbuf[seen] = 0;
1641280297Sjkim        }
1642280297Sjkim        BIO_printf(sbio,
1643280297Sjkim                   "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1644280297Sjkim        seen = BIO_read(sbio, sbuf, BUFSIZZ);
1645280297Sjkim        sbuf[seen] = 0;
1646280297Sjkim        if (!strstr(sbuf, "<proceed"))
1647280297Sjkim            goto shut;
1648280297Sjkim        mbuf[0] = 0;
1649280297Sjkim    }
165055714Skris
1651280297Sjkim    for (;;) {
1652280297Sjkim        FD_ZERO(&readfds);
1653280297Sjkim        FD_ZERO(&writefds);
1654205128Ssimon
1655280297Sjkim        if ((SSL_version(con) == DTLS1_VERSION) &&
1656280297Sjkim            DTLSv1_get_timeout(con, &timeout))
1657280297Sjkim            timeoutp = &timeout;
1658280297Sjkim        else
1659280297Sjkim            timeoutp = NULL;
1660280297Sjkim
1661280297Sjkim        if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
1662280297Sjkim            in_init = 1;
1663280297Sjkim            tty_on = 0;
1664280297Sjkim        } else {
1665280297Sjkim            tty_on = 1;
1666280297Sjkim            if (in_init) {
1667280297Sjkim                in_init = 0;
1668280297Sjkim#if 0                           /* This test doesn't really work as intended
1669280297Sjkim                                 * (needs to be fixed) */
1670280297Sjkim# ifndef OPENSSL_NO_TLSEXT
1671280297Sjkim                if (servername != NULL && !SSL_session_reused(con)) {
1672280297Sjkim                    BIO_printf(bio_c_out,
1673280297Sjkim                               "Server did %sacknowledge servername extension.\n",
1674280297Sjkim                               tlsextcbp.ack ? "" : "not ");
1675280297Sjkim                }
1676280297Sjkim# endif
1677238405Sjkim#endif
1678280297Sjkim                if (sess_out) {
1679280297Sjkim                    BIO *stmp = BIO_new_file(sess_out, "w");
1680280297Sjkim                    if (stmp) {
1681280297Sjkim                        PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
1682280297Sjkim                        BIO_free(stmp);
1683280297Sjkim                    } else
1684280297Sjkim                        BIO_printf(bio_err, "Error writing session file %s\n",
1685280297Sjkim                                   sess_out);
1686280297Sjkim                }
1687290207Sjkim                if (c_brief) {
1688290207Sjkim                    BIO_puts(bio_err, "CONNECTION ESTABLISHED\n");
1689290207Sjkim                    print_ssl_summary(bio_err, con);
1690290207Sjkim                }
1691290207Sjkim
1692280297Sjkim                print_stuff(bio_c_out, con, full_log);
1693280297Sjkim                if (full_log > 0)
1694280297Sjkim                    full_log--;
169555714Skris
1696280297Sjkim                if (starttls_proto) {
1697280297Sjkim                    BIO_printf(bio_err, "%s", mbuf);
1698280297Sjkim                    /* We don't need to know any more */
1699280297Sjkim                    starttls_proto = PROTO_OFF;
1700280297Sjkim                }
1701109998Smarkm
1702280297Sjkim                if (reconnect) {
1703280297Sjkim                    reconnect--;
1704280297Sjkim                    BIO_printf(bio_c_out,
1705280297Sjkim                               "drop connection and then reconnect\n");
1706280297Sjkim                    SSL_shutdown(con);
1707280297Sjkim                    SSL_set_connect_state(con);
1708280297Sjkim                    SHUTDOWN(SSL_get_fd(con));
1709280297Sjkim                    goto re_start;
1710280297Sjkim                }
1711280297Sjkim            }
1712280297Sjkim        }
171355714Skris
1714280297Sjkim        ssl_pending = read_ssl && SSL_pending(con);
171555714Skris
1716280297Sjkim        if (!ssl_pending) {
1717238405Sjkim#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
1718280297Sjkim            if (tty_on) {
1719280297Sjkim                if (read_tty)
1720280297Sjkim                    openssl_fdset(fileno(stdin), &readfds);
1721280297Sjkim                if (write_tty)
1722280297Sjkim                    openssl_fdset(fileno(stdout), &writefds);
1723280297Sjkim            }
1724280297Sjkim            if (read_ssl)
1725280297Sjkim                openssl_fdset(SSL_get_fd(con), &readfds);
1726280297Sjkim            if (write_ssl)
1727280297Sjkim                openssl_fdset(SSL_get_fd(con), &writefds);
172859191Skris#else
1729280297Sjkim            if (!tty_on || !write_tty) {
1730280297Sjkim                if (read_ssl)
1731280297Sjkim                    openssl_fdset(SSL_get_fd(con), &readfds);
1732280297Sjkim                if (write_ssl)
1733280297Sjkim                    openssl_fdset(SSL_get_fd(con), &writefds);
1734280297Sjkim            }
173559191Skris#endif
1736280297Sjkim/*-         printf("mode tty(%d %d%d) ssl(%d%d)\n",
1737280297Sjkim                    tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
173855714Skris
1739280297Sjkim            /*
1740280297Sjkim             * Note: under VMS with SOCKETSHR the second parameter is
1741280297Sjkim             * currently of type (int *) whereas under other systems it is
1742280297Sjkim             * (void *) if you don't have a cast it will choke the compiler:
1743280297Sjkim             * if you do have a cast then you can either go for (int *) or
1744280297Sjkim             * (void *).
1745280297Sjkim             */
1746120631Snectar#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
1747280297Sjkim            /*
1748280297Sjkim             * Under Windows/DOS we make the assumption that we can always
1749280297Sjkim             * write to the tty: therefore if we need to write to the tty we
1750280297Sjkim             * just fall through. Otherwise we timeout the select every
1751280297Sjkim             * second and see if there are any keypresses. Note: this is a
1752280297Sjkim             * hack, in a proper Windows application we wouldn't do this.
1753280297Sjkim             */
1754280297Sjkim            i = 0;
1755280297Sjkim            if (!write_tty) {
1756280297Sjkim                if (read_tty) {
1757280297Sjkim                    tv.tv_sec = 1;
1758280297Sjkim                    tv.tv_usec = 0;
1759280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1760280297Sjkim                               NULL, &tv);
1761280297Sjkim# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
1762280297Sjkim                    if (!i && (!_kbhit() || !read_tty))
1763280297Sjkim                        continue;
1764280297Sjkim# else
1765280297Sjkim                    if (!i && (!((_kbhit())
1766280297Sjkim                                 || (WAIT_OBJECT_0 ==
1767280297Sjkim                                     WaitForSingleObject(GetStdHandle
1768280297Sjkim                                                         (STD_INPUT_HANDLE),
1769280297Sjkim                                                         0)))
1770280297Sjkim                               || !read_tty))
1771280297Sjkim                        continue;
1772280297Sjkim# endif
1773280297Sjkim                } else
1774280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1775280297Sjkim                               NULL, timeoutp);
1776280297Sjkim            }
1777160814Ssimon#elif defined(OPENSSL_SYS_NETWARE)
1778280297Sjkim            if (!write_tty) {
1779280297Sjkim                if (read_tty) {
1780280297Sjkim                    tv.tv_sec = 1;
1781280297Sjkim                    tv.tv_usec = 0;
1782280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1783280297Sjkim                               NULL, &tv);
1784280297Sjkim                } else
1785280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1786280297Sjkim                               NULL, timeoutp);
1787280297Sjkim            }
1788238405Sjkim#elif defined(OPENSSL_SYS_BEOS_R5)
1789280297Sjkim            /* Under BeOS-R5 the situation is similar to DOS */
1790280297Sjkim            i = 0;
1791280297Sjkim            stdin_set = 0;
1792280297Sjkim            (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
1793280297Sjkim            if (!write_tty) {
1794280297Sjkim                if (read_tty) {
1795280297Sjkim                    tv.tv_sec = 1;
1796280297Sjkim                    tv.tv_usec = 0;
1797280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1798280297Sjkim                               NULL, &tv);
1799280297Sjkim                    if (read(fileno(stdin), sbuf, 0) >= 0)
1800280297Sjkim                        stdin_set = 1;
1801280297Sjkim                    if (!i && (stdin_set != 1 || !read_tty))
1802280297Sjkim                        continue;
1803280297Sjkim                } else
1804280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1805280297Sjkim                               NULL, timeoutp);
1806280297Sjkim            }
1807280297Sjkim            (void)fcntl(fileno(stdin), F_SETFL, 0);
180859191Skris#else
1809280297Sjkim            i = select(width, (void *)&readfds, (void *)&writefds,
1810280297Sjkim                       NULL, timeoutp);
181159191Skris#endif
1812280297Sjkim            if (i < 0) {
1813280297Sjkim                BIO_printf(bio_err, "bad select %d\n",
1814280297Sjkim                           get_last_socket_error());
1815280297Sjkim                goto shut;
1816280297Sjkim                /* goto end; */
1817280297Sjkim            }
1818280297Sjkim        }
181955714Skris
1820280297Sjkim        if ((SSL_version(con) == DTLS1_VERSION)
1821280297Sjkim            && DTLSv1_handle_timeout(con) > 0) {
1822280297Sjkim            BIO_printf(bio_err, "TIMEOUT occured\n");
1823280297Sjkim        }
1824205128Ssimon
1825280297Sjkim        if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
1826280297Sjkim            k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len);
1827280297Sjkim            switch (SSL_get_error(con, k)) {
1828280297Sjkim            case SSL_ERROR_NONE:
1829280297Sjkim                cbuf_off += k;
1830280297Sjkim                cbuf_len -= k;
1831280297Sjkim                if (k <= 0)
1832280297Sjkim                    goto end;
1833280297Sjkim                /* we have done a  write(con,NULL,0); */
1834280297Sjkim                if (cbuf_len <= 0) {
1835280297Sjkim                    read_tty = 1;
1836280297Sjkim                    write_ssl = 0;
1837280297Sjkim                } else {        /* if (cbuf_len > 0) */
1838280297Sjkim
1839280297Sjkim                    read_tty = 0;
1840280297Sjkim                    write_ssl = 1;
1841280297Sjkim                }
1842280297Sjkim                break;
1843280297Sjkim            case SSL_ERROR_WANT_WRITE:
1844280297Sjkim                BIO_printf(bio_c_out, "write W BLOCK\n");
1845280297Sjkim                write_ssl = 1;
1846280297Sjkim                read_tty = 0;
1847280297Sjkim                break;
1848280297Sjkim            case SSL_ERROR_WANT_READ:
1849280297Sjkim                BIO_printf(bio_c_out, "write R BLOCK\n");
1850280297Sjkim                write_tty = 0;
1851280297Sjkim                read_ssl = 1;
1852280297Sjkim                write_ssl = 0;
1853280297Sjkim                break;
1854280297Sjkim            case SSL_ERROR_WANT_X509_LOOKUP:
1855280297Sjkim                BIO_printf(bio_c_out, "write X BLOCK\n");
1856280297Sjkim                break;
1857280297Sjkim            case SSL_ERROR_ZERO_RETURN:
1858280297Sjkim                if (cbuf_len != 0) {
1859280297Sjkim                    BIO_printf(bio_c_out, "shutdown\n");
1860280297Sjkim                    ret = 0;
1861280297Sjkim                    goto shut;
1862280297Sjkim                } else {
1863280297Sjkim                    read_tty = 1;
1864280297Sjkim                    write_ssl = 0;
1865280297Sjkim                    break;
1866280297Sjkim                }
1867280297Sjkim
1868280297Sjkim            case SSL_ERROR_SYSCALL:
1869280297Sjkim                if ((k != 0) || (cbuf_len != 0)) {
1870280297Sjkim                    BIO_printf(bio_err, "write:errno=%d\n",
1871280297Sjkim                               get_last_socket_error());
1872280297Sjkim                    goto shut;
1873280297Sjkim                } else {
1874280297Sjkim                    read_tty = 1;
1875280297Sjkim                    write_ssl = 0;
1876280297Sjkim                }
1877280297Sjkim                break;
1878280297Sjkim            case SSL_ERROR_SSL:
1879280297Sjkim                ERR_print_errors(bio_err);
1880280297Sjkim                goto shut;
1881280297Sjkim            }
1882280297Sjkim        }
1883238405Sjkim#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
1884280297Sjkim        /* Assume Windows/DOS/BeOS can always write */
1885280297Sjkim        else if (!ssl_pending && write_tty)
188659191Skris#else
1887280297Sjkim        else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds))
188859191Skris#endif
1889280297Sjkim        {
189055714Skris#ifdef CHARSET_EBCDIC
1891280297Sjkim            ascii2ebcdic(&(sbuf[sbuf_off]), &(sbuf[sbuf_off]), sbuf_len);
189255714Skris#endif
1893280297Sjkim            i = raw_write_stdout(&(sbuf[sbuf_off]), sbuf_len);
189455714Skris
1895280297Sjkim            if (i <= 0) {
1896280297Sjkim                BIO_printf(bio_c_out, "DONE\n");
1897280297Sjkim                ret = 0;
1898280297Sjkim                goto shut;
1899280297Sjkim                /* goto end; */
1900280297Sjkim            }
190155714Skris
1902280297Sjkim            sbuf_len -= i;;
1903280297Sjkim            sbuf_off += i;
1904280297Sjkim            if (sbuf_len <= 0) {
1905280297Sjkim                read_ssl = 1;
1906280297Sjkim                write_tty = 0;
1907280297Sjkim            }
1908280297Sjkim        } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) {
190955714Skris#ifdef RENEG
1910280297Sjkim            {
1911280297Sjkim                static int iiii;
1912280297Sjkim                if (++iiii == 52) {
1913280297Sjkim                    SSL_renegotiate(con);
1914280297Sjkim                    iiii = 0;
1915280297Sjkim                }
1916280297Sjkim            }
191755714Skris#endif
191855714Skris#if 1
1919280297Sjkim            k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ );
192055714Skris#else
192155714Skris/* Demo for pending and peek :-) */
1922280297Sjkim            k = SSL_read(con, sbuf, 16);
1923280297Sjkim            {
1924280297Sjkim                char zbuf[10240];
1925280297Sjkim                printf("read=%d pending=%d peek=%d\n", k, SSL_pending(con),
1926280297Sjkim                       SSL_peek(con, zbuf, 10240));
1927280297Sjkim            }
192855714Skris#endif
192955714Skris
1930280297Sjkim            switch (SSL_get_error(con, k)) {
1931280297Sjkim            case SSL_ERROR_NONE:
1932280297Sjkim                if (k <= 0)
1933280297Sjkim                    goto end;
1934280297Sjkim                sbuf_off = 0;
1935280297Sjkim                sbuf_len = k;
193655714Skris
1937280297Sjkim                read_ssl = 0;
1938280297Sjkim                write_tty = 1;
1939280297Sjkim                break;
1940280297Sjkim            case SSL_ERROR_WANT_WRITE:
1941280297Sjkim                BIO_printf(bio_c_out, "read W BLOCK\n");
1942280297Sjkim                write_ssl = 1;
1943280297Sjkim                read_tty = 0;
1944280297Sjkim                break;
1945280297Sjkim            case SSL_ERROR_WANT_READ:
1946280297Sjkim                BIO_printf(bio_c_out, "read R BLOCK\n");
1947280297Sjkim                write_tty = 0;
1948280297Sjkim                read_ssl = 1;
1949280297Sjkim                if ((read_tty == 0) && (write_ssl == 0))
1950280297Sjkim                    write_ssl = 1;
1951280297Sjkim                break;
1952280297Sjkim            case SSL_ERROR_WANT_X509_LOOKUP:
1953280297Sjkim                BIO_printf(bio_c_out, "read X BLOCK\n");
1954280297Sjkim                break;
1955280297Sjkim            case SSL_ERROR_SYSCALL:
1956280297Sjkim                ret = get_last_socket_error();
1957290207Sjkim                if (c_brief)
1958290207Sjkim                    BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n");
1959290207Sjkim                else
1960290207Sjkim                    BIO_printf(bio_err, "read:errno=%d\n", ret);
1961280297Sjkim                goto shut;
1962280297Sjkim            case SSL_ERROR_ZERO_RETURN:
1963280297Sjkim                BIO_printf(bio_c_out, "closed\n");
1964280297Sjkim                ret = 0;
1965280297Sjkim                goto shut;
1966280297Sjkim            case SSL_ERROR_SSL:
1967280297Sjkim                ERR_print_errors(bio_err);
1968280297Sjkim                goto shut;
1969280297Sjkim                /* break; */
1970280297Sjkim            }
1971280297Sjkim        }
1972120631Snectar#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
1973280297Sjkim# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
1974280297Sjkim        else if (_kbhit())
1975280297Sjkim# else
1976280297Sjkim        else if ((_kbhit())
1977280297Sjkim                 || (WAIT_OBJECT_0 ==
1978280297Sjkim                     WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
1979280297Sjkim# endif
1980160814Ssimon#elif defined (OPENSSL_SYS_NETWARE)
1981280297Sjkim        else if (_kbhit())
1982238405Sjkim#elif defined(OPENSSL_SYS_BEOS_R5)
1983280297Sjkim        else if (stdin_set)
198459191Skris#else
1985280297Sjkim        else if (FD_ISSET(fileno(stdin), &readfds))
198659191Skris#endif
1987280297Sjkim        {
1988280297Sjkim            if (crlf) {
1989280297Sjkim                int j, lf_num;
199055714Skris
1991280297Sjkim                i = raw_read_stdin(cbuf, BUFSIZZ / 2);
1992280297Sjkim                lf_num = 0;
1993280297Sjkim                /* both loops are skipped when i <= 0 */
1994280297Sjkim                for (j = 0; j < i; j++)
1995280297Sjkim                    if (cbuf[j] == '\n')
1996280297Sjkim                        lf_num++;
1997280297Sjkim                for (j = i - 1; j >= 0; j--) {
1998280297Sjkim                    cbuf[j + lf_num] = cbuf[j];
1999280297Sjkim                    if (cbuf[j] == '\n') {
2000280297Sjkim                        lf_num--;
2001280297Sjkim                        i++;
2002280297Sjkim                        cbuf[j + lf_num] = '\r';
2003280297Sjkim                    }
2004280297Sjkim                }
2005280297Sjkim                assert(lf_num == 0);
2006280297Sjkim            } else
2007280297Sjkim                i = raw_read_stdin(cbuf, BUFSIZZ);
200855714Skris
2009280297Sjkim            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) {
2010280297Sjkim                BIO_printf(bio_err, "DONE\n");
2011280297Sjkim                ret = 0;
2012280297Sjkim                goto shut;
2013280297Sjkim            }
201455714Skris
2015280297Sjkim            if ((!c_ign_eof) && (cbuf[0] == 'R')) {
2016280297Sjkim                BIO_printf(bio_err, "RENEGOTIATING\n");
2017280297Sjkim                SSL_renegotiate(con);
2018280297Sjkim                cbuf_len = 0;
2019280297Sjkim            }
2020238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS
2021280297Sjkim            else if ((!c_ign_eof) && (cbuf[0] == 'B')) {
2022280297Sjkim                BIO_printf(bio_err, "HEARTBEATING\n");
2023280297Sjkim                SSL_heartbeat(con);
2024280297Sjkim                cbuf_len = 0;
2025280297Sjkim            }
2026238405Sjkim#endif
2027280297Sjkim            else {
2028280297Sjkim                cbuf_len = i;
2029280297Sjkim                cbuf_off = 0;
203055714Skris#ifdef CHARSET_EBCDIC
2031280297Sjkim                ebcdic2ascii(cbuf, cbuf, i);
203255714Skris#endif
2033280297Sjkim            }
203455714Skris
2035280297Sjkim            write_ssl = 1;
2036280297Sjkim            read_tty = 0;
2037280297Sjkim        }
2038280297Sjkim    }
2039238405Sjkim
2040280297Sjkim    ret = 0;
2041280297Sjkim shut:
2042280297Sjkim    if (in_init)
2043280297Sjkim        print_stuff(bio_c_out, con, full_log);
2044280297Sjkim    SSL_shutdown(con);
2045280297Sjkim    SHUTDOWN(SSL_get_fd(con));
2046280297Sjkim end:
2047280297Sjkim    if (con != NULL) {
2048280297Sjkim        if (prexit != 0)
2049280297Sjkim            print_stuff(bio_c_out, con, 1);
2050280297Sjkim        SSL_free(con);
2051280297Sjkim    }
2052246772Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
2053280297Sjkim    if (next_proto.data)
2054280297Sjkim        OPENSSL_free(next_proto.data);
2055246772Sjkim#endif
2056280297Sjkim    if (ctx != NULL)
2057280297Sjkim        SSL_CTX_free(ctx);
2058280297Sjkim    if (cert)
2059280297Sjkim        X509_free(cert);
2060290207Sjkim    if (crls)
2061290207Sjkim        sk_X509_CRL_pop_free(crls, X509_CRL_free);
2062280297Sjkim    if (key)
2063280297Sjkim        EVP_PKEY_free(key);
2064290207Sjkim    if (chain)
2065290207Sjkim        sk_X509_pop_free(chain, X509_free);
2066280297Sjkim    if (pass)
2067280297Sjkim        OPENSSL_free(pass);
2068280297Sjkim    if (vpm)
2069280297Sjkim        X509_VERIFY_PARAM_free(vpm);
2070290207Sjkim    ssl_excert_free(exc);
2071290207Sjkim    if (ssl_args)
2072290207Sjkim        sk_OPENSSL_STRING_free(ssl_args);
2073290207Sjkim    if (cctx)
2074290207Sjkim        SSL_CONF_CTX_free(cctx);
2075290207Sjkim#ifndef OPENSSL_NO_JPAKE
2076290207Sjkim    if (jpake_secret && psk_key)
2077290207Sjkim        OPENSSL_free(psk_key);
2078290207Sjkim#endif
2079280297Sjkim    if (cbuf != NULL) {
2080280297Sjkim        OPENSSL_cleanse(cbuf, BUFSIZZ);
2081280297Sjkim        OPENSSL_free(cbuf);
2082280297Sjkim    }
2083280297Sjkim    if (sbuf != NULL) {
2084280297Sjkim        OPENSSL_cleanse(sbuf, BUFSIZZ);
2085280297Sjkim        OPENSSL_free(sbuf);
2086280297Sjkim    }
2087280297Sjkim    if (mbuf != NULL) {
2088280297Sjkim        OPENSSL_cleanse(mbuf, BUFSIZZ);
2089280297Sjkim        OPENSSL_free(mbuf);
2090280297Sjkim    }
2091280297Sjkim    if (bio_c_out != NULL) {
2092280297Sjkim        BIO_free(bio_c_out);
2093280297Sjkim        bio_c_out = NULL;
2094280297Sjkim    }
2095290207Sjkim    if (bio_c_msg != NULL) {
2096290207Sjkim        BIO_free(bio_c_msg);
2097290207Sjkim        bio_c_msg = NULL;
2098290207Sjkim    }
2099280297Sjkim    apps_shutdown();
2100280297Sjkim    OPENSSL_EXIT(ret);
2101280297Sjkim}
210255714Skris
210355714Skrisstatic void print_stuff(BIO *bio, SSL *s, int full)
2104280297Sjkim{
2105280297Sjkim    X509 *peer = NULL;
2106280297Sjkim    char *p;
2107280297Sjkim    static const char *space = "                ";
2108280297Sjkim    char buf[BUFSIZ];
2109280297Sjkim    STACK_OF(X509) *sk;
2110280297Sjkim    STACK_OF(X509_NAME) *sk2;
2111280297Sjkim    const SSL_CIPHER *c;
2112280297Sjkim    X509_NAME *xn;
2113280297Sjkim    int j, i;
2114160814Ssimon#ifndef OPENSSL_NO_COMP
2115280297Sjkim    const COMP_METHOD *comp, *expansion;
2116160814Ssimon#endif
2117280297Sjkim    unsigned char *exportedkeymat;
211855714Skris
2119280297Sjkim    if (full) {
2120280297Sjkim        int got_a_chain = 0;
212155714Skris
2122280297Sjkim        sk = SSL_get_peer_cert_chain(s);
2123280297Sjkim        if (sk != NULL) {
2124280297Sjkim            got_a_chain = 1;    /* we don't have it for SSL2 (yet) */
212555714Skris
2126280297Sjkim            BIO_printf(bio, "---\nCertificate chain\n");
2127280297Sjkim            for (i = 0; i < sk_X509_num(sk); i++) {
2128280297Sjkim                X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)),
2129280297Sjkim                                  buf, sizeof buf);
2130280297Sjkim                BIO_printf(bio, "%2d s:%s\n", i, buf);
2131280297Sjkim                X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)),
2132280297Sjkim                                  buf, sizeof buf);
2133280297Sjkim                BIO_printf(bio, "   i:%s\n", buf);
2134280297Sjkim                if (c_showcerts)
2135280297Sjkim                    PEM_write_bio_X509(bio, sk_X509_value(sk, i));
2136280297Sjkim            }
2137280297Sjkim        }
213855714Skris
2139280297Sjkim        BIO_printf(bio, "---\n");
2140280297Sjkim        peer = SSL_get_peer_certificate(s);
2141280297Sjkim        if (peer != NULL) {
2142280297Sjkim            BIO_printf(bio, "Server certificate\n");
214355714Skris
2144280297Sjkim            /* Redundant if we showed the whole chain */
2145280297Sjkim            if (!(c_showcerts && got_a_chain))
2146280297Sjkim                PEM_write_bio_X509(bio, peer);
2147280297Sjkim            X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
2148280297Sjkim            BIO_printf(bio, "subject=%s\n", buf);
2149280297Sjkim            X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
2150280297Sjkim            BIO_printf(bio, "issuer=%s\n", buf);
2151280297Sjkim        } else
2152280297Sjkim            BIO_printf(bio, "no peer certificate available\n");
215355714Skris
2154280297Sjkim        sk2 = SSL_get_client_CA_list(s);
2155280297Sjkim        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
2156280297Sjkim            BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
2157280297Sjkim            for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
2158280297Sjkim                xn = sk_X509_NAME_value(sk2, i);
2159280297Sjkim                X509_NAME_oneline(xn, buf, sizeof(buf));
2160280297Sjkim                BIO_write(bio, buf, strlen(buf));
2161280297Sjkim                BIO_write(bio, "\n", 1);
2162280297Sjkim            }
2163280297Sjkim        } else {
2164280297Sjkim            BIO_printf(bio, "---\nNo client certificate CA names sent\n");
2165280297Sjkim        }
2166280297Sjkim        p = SSL_get_shared_ciphers(s, buf, sizeof buf);
2167280297Sjkim        if (p != NULL) {
2168280297Sjkim            /*
2169280297Sjkim             * This works only for SSL 2.  In later protocol versions, the
2170280297Sjkim             * client does not know what other ciphers (in addition to the
2171280297Sjkim             * one to be used in the current connection) the server supports.
2172280297Sjkim             */
217355714Skris
2174280297Sjkim            BIO_printf(bio,
2175280297Sjkim                       "---\nCiphers common between both SSL endpoints:\n");
2176280297Sjkim            j = i = 0;
2177280297Sjkim            while (*p) {
2178280297Sjkim                if (*p == ':') {
2179280297Sjkim                    BIO_write(bio, space, 15 - j % 25);
2180280297Sjkim                    i++;
2181280297Sjkim                    j = 0;
2182280297Sjkim                    BIO_write(bio, ((i % 3) ? " " : "\n"), 1);
2183280297Sjkim                } else {
2184280297Sjkim                    BIO_write(bio, p, 1);
2185280297Sjkim                    j++;
2186280297Sjkim                }
2187280297Sjkim                p++;
2188280297Sjkim            }
2189280297Sjkim            BIO_write(bio, "\n", 1);
2190280297Sjkim        }
2191280297Sjkim
2192290207Sjkim        ssl_print_sigalgs(bio, s);
2193290207Sjkim        ssl_print_tmp_key(bio, s);
2194290207Sjkim
2195280297Sjkim        BIO_printf(bio,
2196280297Sjkim                   "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
2197280297Sjkim                   BIO_number_read(SSL_get_rbio(s)),
2198280297Sjkim                   BIO_number_written(SSL_get_wbio(s)));
2199280297Sjkim    }
2200280297Sjkim    BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
2201280297Sjkim    c = SSL_get_current_cipher(s);
2202280297Sjkim    BIO_printf(bio, "%s, Cipher is %s\n",
2203280297Sjkim               SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
2204280297Sjkim    if (peer != NULL) {
2205280297Sjkim        EVP_PKEY *pktmp;
2206280297Sjkim        pktmp = X509_get_pubkey(peer);
2207280297Sjkim        BIO_printf(bio, "Server public key is %d bit\n",
2208280297Sjkim                   EVP_PKEY_bits(pktmp));
2209280297Sjkim        EVP_PKEY_free(pktmp);
2210280297Sjkim    }
2211280297Sjkim    BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
2212280297Sjkim               SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
2213160814Ssimon#ifndef OPENSSL_NO_COMP
2214280297Sjkim    comp = SSL_get_current_compression(s);
2215280297Sjkim    expansion = SSL_get_current_expansion(s);
2216280297Sjkim    BIO_printf(bio, "Compression: %s\n",
2217280297Sjkim               comp ? SSL_COMP_get_name(comp) : "NONE");
2218280297Sjkim    BIO_printf(bio, "Expansion: %s\n",
2219280297Sjkim               expansion ? SSL_COMP_get_name(expansion) : "NONE");
2220160814Ssimon#endif
2221280297Sjkim
2222238405Sjkim#ifdef SSL_DEBUG
2223280297Sjkim    {
2224280297Sjkim        /* Print out local port of connection: useful for debugging */
2225280297Sjkim        int sock;
2226280297Sjkim        struct sockaddr_in ladd;
2227280297Sjkim        socklen_t ladd_size = sizeof(ladd);
2228280297Sjkim        sock = SSL_get_fd(s);
2229280297Sjkim        getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
2230280297Sjkim        BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
2231280297Sjkim    }
2232238405Sjkim#endif
2233238405Sjkim
2234290207Sjkim#if !defined(OPENSSL_NO_TLSEXT)
2235290207Sjkim# if !defined(OPENSSL_NO_NEXTPROTONEG)
2236280297Sjkim    if (next_proto.status != -1) {
2237280297Sjkim        const unsigned char *proto;
2238280297Sjkim        unsigned int proto_len;
2239280297Sjkim        SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
2240280297Sjkim        BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
2241280297Sjkim        BIO_write(bio, proto, proto_len);
2242280297Sjkim        BIO_write(bio, "\n", 1);
2243280297Sjkim    }
2244290207Sjkim# endif
2245290207Sjkim    {
2246290207Sjkim        const unsigned char *proto;
2247290207Sjkim        unsigned int proto_len;
2248290207Sjkim        SSL_get0_alpn_selected(s, &proto, &proto_len);
2249290207Sjkim        if (proto_len > 0) {
2250290207Sjkim            BIO_printf(bio, "ALPN protocol: ");
2251290207Sjkim            BIO_write(bio, proto, proto_len);
2252290207Sjkim            BIO_write(bio, "\n", 1);
2253290207Sjkim        } else
2254290207Sjkim            BIO_printf(bio, "No ALPN negotiated\n");
2255290207Sjkim    }
2256238405Sjkim#endif
2257238405Sjkim
2258246772Sjkim#ifndef OPENSSL_NO_SRTP
2259280297Sjkim    {
2260280297Sjkim        SRTP_PROTECTION_PROFILE *srtp_profile =
2261280297Sjkim            SSL_get_selected_srtp_profile(s);
2262280297Sjkim
2263280297Sjkim        if (srtp_profile)
2264280297Sjkim            BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n",
2265280297Sjkim                       srtp_profile->name);
2266280297Sjkim    }
2267246772Sjkim#endif
226855714Skris
2269280297Sjkim    SSL_SESSION_print(bio, SSL_get_session(s));
2270280297Sjkim    if (keymatexportlabel != NULL) {
2271280297Sjkim        BIO_printf(bio, "Keying material exporter:\n");
2272280297Sjkim        BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
2273280297Sjkim        BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
2274280297Sjkim        exportedkeymat = OPENSSL_malloc(keymatexportlen);
2275280297Sjkim        if (exportedkeymat != NULL) {
2276280297Sjkim            if (!SSL_export_keying_material(s, exportedkeymat,
2277280297Sjkim                                            keymatexportlen,
2278280297Sjkim                                            keymatexportlabel,
2279280297Sjkim                                            strlen(keymatexportlabel),
2280280297Sjkim                                            NULL, 0, 0)) {
2281280297Sjkim                BIO_printf(bio, "    Error\n");
2282280297Sjkim            } else {
2283280297Sjkim                BIO_printf(bio, "    Keying material: ");
2284280297Sjkim                for (i = 0; i < keymatexportlen; i++)
2285280297Sjkim                    BIO_printf(bio, "%02X", exportedkeymat[i]);
2286280297Sjkim                BIO_printf(bio, "\n");
2287280297Sjkim            }
2288280297Sjkim            OPENSSL_free(exportedkeymat);
2289280297Sjkim        }
2290280297Sjkim    }
2291280297Sjkim    BIO_printf(bio, "---\n");
2292280297Sjkim    if (peer != NULL)
2293280297Sjkim        X509_free(peer);
2294280297Sjkim    /* flush, or debugging output gets mixed with http response */
2295280297Sjkim    (void)BIO_flush(bio);
2296280297Sjkim}
2297280297Sjkim
2298194206Ssimon#ifndef OPENSSL_NO_TLSEXT
2299194206Ssimon
2300194206Ssimonstatic int ocsp_resp_cb(SSL *s, void *arg)
2301280297Sjkim{
2302280297Sjkim    const unsigned char *p;
2303280297Sjkim    int len;
2304280297Sjkim    OCSP_RESPONSE *rsp;
2305280297Sjkim    len = SSL_get_tlsext_status_ocsp_resp(s, &p);
2306280297Sjkim    BIO_puts(arg, "OCSP response: ");
2307280297Sjkim    if (!p) {
2308280297Sjkim        BIO_puts(arg, "no response sent\n");
2309280297Sjkim        return 1;
2310280297Sjkim    }
2311280297Sjkim    rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
2312280297Sjkim    if (!rsp) {
2313280297Sjkim        BIO_puts(arg, "response parse error\n");
2314280297Sjkim        BIO_dump_indent(arg, (char *)p, len, 4);
2315280297Sjkim        return 0;
2316280297Sjkim    }
2317280297Sjkim    BIO_puts(arg, "\n======================================\n");
2318280297Sjkim    OCSP_RESPONSE_print(arg, rsp, 0);
2319280297Sjkim    BIO_puts(arg, "======================================\n");
2320280297Sjkim    OCSP_RESPONSE_free(rsp);
2321280297Sjkim    return 1;
2322280297Sjkim}
2323238405Sjkim
2324238405Sjkim#endif
2325