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/* ====================================================================
59337982Sjkim * Copyright (c) 1998-2018 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    int ret;
246306195Sjkim    long key_len;
247306195Sjkim    unsigned char *key;
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);
268306195Sjkim
269306195Sjkim    /* convert the PSK key to binary */
270306195Sjkim    key = string_to_hex(psk_key, &key_len);
271306195Sjkim    if (key == NULL) {
272306195Sjkim        BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n",
273280297Sjkim                   psk_key);
274280297Sjkim        return 0;
275280297Sjkim    }
276306195Sjkim    if ((unsigned long)key_len > (unsigned long)max_psk_len) {
277280297Sjkim        BIO_printf(bio_err,
278306195Sjkim                   "psk buffer of callback is too small (%d) for key (%ld)\n",
279306195Sjkim                   max_psk_len, key_len);
280306195Sjkim        OPENSSL_free(key);
281280297Sjkim        return 0;
282280297Sjkim    }
283238405Sjkim
284306195Sjkim    memcpy(psk, key, key_len);
285306195Sjkim    OPENSSL_free(key);
286238405Sjkim
287280297Sjkim    if (c_debug)
288306195Sjkim        BIO_printf(bio_c_out, "created PSK len=%ld\n", key_len);
289280297Sjkim
290306195Sjkim    return key_len;
291238405Sjkim out_err:
292280297Sjkim    if (c_debug)
293280297Sjkim        BIO_printf(bio_err, "Error in PSK client callback\n");
294280297Sjkim    return 0;
295280297Sjkim}
296238405Sjkim#endif
297238405Sjkim
29855714Skrisstatic void sc_usage(void)
299280297Sjkim{
300280297Sjkim    BIO_printf(bio_err, "usage: s_client args\n");
301280297Sjkim    BIO_printf(bio_err, "\n");
302280297Sjkim    BIO_printf(bio_err, " -host host     - use -connect instead\n");
303280297Sjkim    BIO_printf(bio_err, " -port port     - use -connect instead\n");
304280297Sjkim    BIO_printf(bio_err,
305280297Sjkim               " -connect host:port - who to connect to (default is %s:%s)\n",
306280297Sjkim               SSL_HOST_NAME, PORT_STR);
307290207Sjkim    BIO_printf(bio_err,
308295009Sjkim               " -verify_hostname host - check peer certificate matches \"host\"\n");
309290207Sjkim    BIO_printf(bio_err,
310290207Sjkim               " -verify_email email - check peer certificate matches \"email\"\n");
311290207Sjkim    BIO_printf(bio_err,
312290207Sjkim               " -verify_ip ipaddr - check peer certificate matches \"ipaddr\"\n");
31355714Skris
314280297Sjkim    BIO_printf(bio_err,
315280297Sjkim               " -verify arg   - turn on peer certificate verification\n");
316280297Sjkim    BIO_printf(bio_err,
317280297Sjkim               " -verify_return_error - return verification errors\n");
318280297Sjkim    BIO_printf(bio_err,
319280297Sjkim               " -cert arg     - certificate file to use, PEM format assumed\n");
320280297Sjkim    BIO_printf(bio_err,
321280297Sjkim               " -certform arg - certificate format (PEM or DER) PEM default\n");
322280297Sjkim    BIO_printf(bio_err,
323280297Sjkim               " -key arg      - Private key file to use, in cert file if\n");
324280297Sjkim    BIO_printf(bio_err, "                 not specified but cert file is.\n");
325280297Sjkim    BIO_printf(bio_err,
326280297Sjkim               " -keyform arg  - key format (PEM or DER) PEM default\n");
327280297Sjkim    BIO_printf(bio_err,
328280297Sjkim               " -pass arg     - private key file pass phrase source\n");
329280297Sjkim    BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
330280297Sjkim    BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
331280297Sjkim    BIO_printf(bio_err,
332284283Sjkim               " -no_alt_chains - only ever use the first certificate chain found\n");
333284283Sjkim    BIO_printf(bio_err,
334280297Sjkim               " -reconnect    - Drop and re-make the connection with the same Session-ID\n");
335280297Sjkim    BIO_printf(bio_err,
336280297Sjkim               " -pause        - sleep(1) after each read(2) and write(2) system call\n");
337280297Sjkim    BIO_printf(bio_err,
338280297Sjkim               " -prexit       - print session information even on connection failure\n");
339280297Sjkim    BIO_printf(bio_err,
340337982Sjkim               " -showcerts    - Show all certificates sent by the server\n");
341280297Sjkim    BIO_printf(bio_err, " -debug        - extra output\n");
342160814Ssimon#ifdef WATT32
343280297Sjkim    BIO_printf(bio_err, " -wdebug       - WATT-32 tcp debugging\n");
344160814Ssimon#endif
345280297Sjkim    BIO_printf(bio_err, " -msg          - Show protocol messages\n");
346280297Sjkim    BIO_printf(bio_err, " -nbio_test    - more ssl protocol testing\n");
347280297Sjkim    BIO_printf(bio_err, " -state        - print the 'ssl' states\n");
34855714Skris#ifdef FIONBIO
349280297Sjkim    BIO_printf(bio_err, " -nbio         - Run with non-blocking IO\n");
35055714Skris#endif
351280297Sjkim    BIO_printf(bio_err,
352280297Sjkim               " -crlf         - convert LF from terminal into CRLF\n");
353280297Sjkim    BIO_printf(bio_err, " -quiet        - no s_client output\n");
354280297Sjkim    BIO_printf(bio_err,
355280297Sjkim               " -ign_eof      - ignore input eof (default when -quiet)\n");
356280297Sjkim    BIO_printf(bio_err, " -no_ign_eof   - don't ignore input eof\n");
357238405Sjkim#ifndef OPENSSL_NO_PSK
358280297Sjkim    BIO_printf(bio_err, " -psk_identity arg - PSK identity\n");
359280297Sjkim    BIO_printf(bio_err, " -psk arg      - PSK in hex (without 0x)\n");
360238405Sjkim# ifndef OPENSSL_NO_JPAKE
361280297Sjkim    BIO_printf(bio_err, " -jpake arg    - JPAKE secret to use\n");
362238405Sjkim# endif
363238405Sjkim#endif
364238405Sjkim#ifndef OPENSSL_NO_SRP
365280297Sjkim    BIO_printf(bio_err,
366280297Sjkim               " -srpuser user     - SRP authentification for 'user'\n");
367280297Sjkim    BIO_printf(bio_err, " -srppass arg      - password for 'user'\n");
368280297Sjkim    BIO_printf(bio_err,
369280297Sjkim               " -srp_lateuser     - SRP username into second ClientHello message\n");
370280297Sjkim    BIO_printf(bio_err,
371280297Sjkim               " -srp_moregroups   - Tolerate other than the known g N values.\n");
372280297Sjkim    BIO_printf(bio_err,
373280297Sjkim               " -srp_strength int - minimal length in bits for N (default %d).\n",
374280297Sjkim               SRP_MINIMAL_N);
375238405Sjkim#endif
376280297Sjkim    BIO_printf(bio_err, " -ssl2         - just use SSLv2\n");
377276861Sjkim#ifndef OPENSSL_NO_SSL3_METHOD
378280297Sjkim    BIO_printf(bio_err, " -ssl3         - just use SSLv3\n");
379276861Sjkim#endif
380280297Sjkim    BIO_printf(bio_err, " -tls1_2       - just use TLSv1.2\n");
381280297Sjkim    BIO_printf(bio_err, " -tls1_1       - just use TLSv1.1\n");
382280297Sjkim    BIO_printf(bio_err, " -tls1         - just use TLSv1\n");
383280297Sjkim    BIO_printf(bio_err, " -dtls1        - just use DTLSv1\n");
384280297Sjkim    BIO_printf(bio_err, " -fallback_scsv - send TLS_FALLBACK_SCSV\n");
385280297Sjkim    BIO_printf(bio_err, " -mtu          - set the link layer MTU\n");
386280297Sjkim    BIO_printf(bio_err,
387280297Sjkim               " -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
388280297Sjkim    BIO_printf(bio_err,
389280297Sjkim               " -bugs         - Switch on all SSL implementation bug workarounds\n");
390280297Sjkim    BIO_printf(bio_err,
391280297Sjkim               " -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
392280297Sjkim    BIO_printf(bio_err,
393280297Sjkim               "                 command to see what is available\n");
394280297Sjkim    BIO_printf(bio_err,
395280297Sjkim               " -starttls prot - use the STARTTLS command before starting TLS\n");
396280297Sjkim    BIO_printf(bio_err,
397280297Sjkim               "                 for those protocols that support it, where\n");
398280297Sjkim    BIO_printf(bio_err,
399280297Sjkim               "                 'prot' defines which one to assume.  Currently,\n");
400280297Sjkim    BIO_printf(bio_err,
401280297Sjkim               "                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
402280297Sjkim    BIO_printf(bio_err, "                 are supported.\n");
403111147Snectar#ifndef OPENSSL_NO_ENGINE
404280297Sjkim    BIO_printf(bio_err,
405280297Sjkim               " -engine id    - Initialise and use the specified engine\n");
406111147Snectar#endif
407280297Sjkim    BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
408280297Sjkim               LIST_SEPARATOR_CHAR);
409280297Sjkim    BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n");
410280297Sjkim    BIO_printf(bio_err, " -sess_in arg  - file to read SSL session from\n");
411194206Ssimon#ifndef OPENSSL_NO_TLSEXT
412280297Sjkim    BIO_printf(bio_err,
413280297Sjkim               " -servername host  - Set TLS extension servername in ClientHello\n");
414280297Sjkim    BIO_printf(bio_err,
415280297Sjkim               " -tlsextdebug      - hex dump of all TLS extensions received\n");
416280297Sjkim    BIO_printf(bio_err,
417280297Sjkim               " -status           - request certificate status from server\n");
418280297Sjkim    BIO_printf(bio_err,
419280297Sjkim               " -no_ticket        - disable use of RFC4507bis session tickets\n");
420280297Sjkim    BIO_printf(bio_err,
421290207Sjkim               " -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
422291719Sjkim    BIO_printf(bio_err,
423291719Sjkim               " -curves arg       - Elliptic curves to advertise (colon-separated list)\n");
424291719Sjkim    BIO_printf(bio_err,
425291719Sjkim               " -sigalgs arg      - Signature algorithms to support (colon-separated list)\n");
426291719Sjkim    BIO_printf(bio_err,
427291719Sjkim               " -client_sigalgs arg - Signature algorithms to support for client\n");
428291719Sjkim    BIO_printf(bio_err,
429291719Sjkim               "                       certificate authentication (colon-separated list)\n");
430290207Sjkim#endif
431290207Sjkim#ifndef OPENSSL_NO_NEXTPROTONEG
432290207Sjkim    BIO_printf(bio_err,
433280297Sjkim               " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
434194206Ssimon#endif
435280297Sjkim    BIO_printf(bio_err,
436290207Sjkim               " -alpn arg         - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
437290207Sjkim    BIO_printf(bio_err,
438280297Sjkim               " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
439246772Sjkim#ifndef OPENSSL_NO_SRTP
440280297Sjkim    BIO_printf(bio_err,
441280297Sjkim               " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
442246772Sjkim#endif
443280297Sjkim    BIO_printf(bio_err,
444280297Sjkim               " -keymatexport label   - Export keying material using label\n");
445280297Sjkim    BIO_printf(bio_err,
446280297Sjkim               " -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
447280297Sjkim}
44855714Skris
449194206Ssimon#ifndef OPENSSL_NO_TLSEXT
450194206Ssimon
451194206Ssimon/* This is a context that we pass to callbacks */
452194206Ssimontypedef struct tlsextctx_st {
453280297Sjkim    BIO *biodebug;
454280297Sjkim    int ack;
455194206Ssimon} tlsextctx;
456194206Ssimon
457194206Ssimonstatic int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
458280297Sjkim{
459280297Sjkim    tlsextctx *p = (tlsextctx *) arg;
460280297Sjkim    const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
461280297Sjkim    if (SSL_get_servername_type(s) != -1)
462280297Sjkim        p->ack = !SSL_session_reused(s) && hn != NULL;
463280297Sjkim    else
464280297Sjkim        BIO_printf(bio_err, "Can't use SSL_get_servername\n");
465238405Sjkim
466280297Sjkim    return SSL_TLSEXT_ERR_OK;
467280297Sjkim}
468238405Sjkim
469280297Sjkim# ifndef OPENSSL_NO_SRP
470280297Sjkim
471238405Sjkim/* This is a context that we pass to all callbacks */
472280297Sjkimtypedef struct srp_arg_st {
473280297Sjkim    char *srppassin;
474280297Sjkim    char *srplogin;
475280297Sjkim    int msg;                    /* copy from c_msg */
476280297Sjkim    int debug;                  /* copy from c_debug */
477280297Sjkim    int amp;                    /* allow more groups */
478280297Sjkim    int strength /* minimal size for N */ ;
479280297Sjkim} SRP_ARG;
480238405Sjkim
481280297Sjkim#  define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
482238405Sjkim
483238405Sjkimstatic int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
484280297Sjkim{
485280297Sjkim    BN_CTX *bn_ctx = BN_CTX_new();
486280297Sjkim    BIGNUM *p = BN_new();
487280297Sjkim    BIGNUM *r = BN_new();
488280297Sjkim    int ret =
489280297Sjkim        g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
490280297Sjkim        BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
491280297Sjkim        p != NULL && BN_rshift1(p, N) &&
492280297Sjkim        /* p = (N-1)/2 */
493280297Sjkim        BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
494280297Sjkim        r != NULL &&
495280297Sjkim        /* verify g^((N-1)/2) == -1 (mod N) */
496280297Sjkim        BN_mod_exp(r, g, p, N, bn_ctx) &&
497280297Sjkim        BN_add_word(r, 1) && BN_cmp(r, N) == 0;
498238405Sjkim
499280297Sjkim    if (r)
500280297Sjkim        BN_free(r);
501280297Sjkim    if (p)
502280297Sjkim        BN_free(p);
503280297Sjkim    if (bn_ctx)
504280297Sjkim        BN_CTX_free(bn_ctx);
505280297Sjkim    return ret;
506280297Sjkim}
507238405Sjkim
508280297Sjkim/*-
509280297Sjkim * This callback is used here for two purposes:
510280297Sjkim * - extended debugging
511280297Sjkim * - making some primality tests for unknown groups
512280297Sjkim * The callback is only called for a non default group.
513280297Sjkim *
514280297Sjkim * An application does not need the call back at all if
515280297Sjkim * only the stanard groups are used.  In real life situations,
516280297Sjkim * client and server already share well known groups,
517280297Sjkim * thus there is no need to verify them.
518280297Sjkim * Furthermore, in case that a server actually proposes a group that
519280297Sjkim * is not one of those defined in RFC 5054, it is more appropriate
520280297Sjkim * to add the group to a static list and then compare since
521280297Sjkim * primality tests are rather cpu consuming.
522280297Sjkim */
523238405Sjkim
524280297Sjkimstatic int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
525280297Sjkim{
526280297Sjkim    SRP_ARG *srp_arg = (SRP_ARG *)arg;
527280297Sjkim    BIGNUM *N = NULL, *g = NULL;
528280297Sjkim    if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
529280297Sjkim        return 0;
530280297Sjkim    if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {
531280297Sjkim        BIO_printf(bio_err, "SRP parameters:\n");
532280297Sjkim        BIO_printf(bio_err, "\tN=");
533280297Sjkim        BN_print(bio_err, N);
534280297Sjkim        BIO_printf(bio_err, "\n\tg=");
535280297Sjkim        BN_print(bio_err, g);
536280297Sjkim        BIO_printf(bio_err, "\n");
537280297Sjkim    }
538238405Sjkim
539280297Sjkim    if (SRP_check_known_gN_param(g, N))
540280297Sjkim        return 1;
541238405Sjkim
542280297Sjkim    if (srp_arg->amp == 1) {
543280297Sjkim        if (srp_arg->debug)
544280297Sjkim            BIO_printf(bio_err,
545280297Sjkim                       "SRP param N and g are not known params, going to check deeper.\n");
546238405Sjkim
547280297Sjkim        /*
548280297Sjkim         * The srp_moregroups is a real debugging feature. Implementors
549280297Sjkim         * should rather add the value to the known ones. The minimal size
550280297Sjkim         * has already been tested.
551280297Sjkim         */
552280297Sjkim        if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
553280297Sjkim            return 1;
554280297Sjkim    }
555280297Sjkim    BIO_printf(bio_err, "SRP param N and g rejected.\n");
556280297Sjkim    return 0;
557280297Sjkim}
558238405Sjkim
559280297Sjkim#  define PWD_STRLEN 1024
560238405Sjkim
561280297Sjkimstatic char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
562280297Sjkim{
563280297Sjkim    SRP_ARG *srp_arg = (SRP_ARG *)arg;
564280297Sjkim    char *pass = (char *)OPENSSL_malloc(PWD_STRLEN + 1);
565280297Sjkim    PW_CB_DATA cb_tmp;
566280297Sjkim    int l;
567238405Sjkim
568284283Sjkim    if (!pass) {
569280297Sjkim        BIO_printf(bio_err, "Malloc failure\n");
570280297Sjkim        return NULL;
571280297Sjkim    }
572238405Sjkim
573280297Sjkim    cb_tmp.password = (char *)srp_arg->srppassin;
574280297Sjkim    cb_tmp.prompt_info = "SRP user";
575280297Sjkim    if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) {
576280297Sjkim        BIO_printf(bio_err, "Can't read Password\n");
577280297Sjkim        OPENSSL_free(pass);
578280297Sjkim        return NULL;
579280297Sjkim    }
580280297Sjkim    *(pass + l) = '\0';
581238405Sjkim
582280297Sjkim    return pass;
583280297Sjkim}
584238405Sjkim
585280297Sjkim# endif
586280297Sjkim# ifndef OPENSSL_NO_SRTP
587280297Sjkimchar *srtp_profiles = NULL;
588280297Sjkim# endif
589238405Sjkim
590238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
591238405Sjkim/* This the context that we pass to next_proto_cb */
592238405Sjkimtypedef struct tlsextnextprotoctx_st {
593280297Sjkim    unsigned char *data;
594280297Sjkim    unsigned short len;
595280297Sjkim    int status;
596238405Sjkim} tlsextnextprotoctx;
597238405Sjkim
598238405Sjkimstatic tlsextnextprotoctx next_proto;
599238405Sjkim
600280297Sjkimstatic int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen,
601280297Sjkim                         const unsigned char *in, unsigned int inlen,
602280297Sjkim                         void *arg)
603280297Sjkim{
604280297Sjkim    tlsextnextprotoctx *ctx = arg;
605238405Sjkim
606280297Sjkim    if (!c_quiet) {
607280297Sjkim        /* We can assume that |in| is syntactically valid. */
608280297Sjkim        unsigned i;
609280297Sjkim        BIO_printf(bio_c_out, "Protocols advertised by server: ");
610280297Sjkim        for (i = 0; i < inlen;) {
611280297Sjkim            if (i)
612280297Sjkim                BIO_write(bio_c_out, ", ", 2);
613280297Sjkim            BIO_write(bio_c_out, &in[i + 1], in[i]);
614280297Sjkim            i += in[i] + 1;
615280297Sjkim        }
616280297Sjkim        BIO_write(bio_c_out, "\n", 1);
617280297Sjkim    }
618238405Sjkim
619280297Sjkim    ctx->status =
620280297Sjkim        SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
621280297Sjkim    return SSL_TLSEXT_ERR_OK;
622280297Sjkim}
623280297Sjkim# endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
624290207Sjkim
625290207Sjkimstatic int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type,
626290207Sjkim                                   const unsigned char *in, size_t inlen,
627290207Sjkim                                   int *al, void *arg)
628290207Sjkim{
629290207Sjkim    char pem_name[100];
630290207Sjkim    unsigned char ext_buf[4 + 65536];
631290207Sjkim
632290207Sjkim    /* Reconstruct the type/len fields prior to extension data */
633326663Sjkim    inlen &= 0xffff; /* for formal memcpy correctness */
634326663Sjkim    ext_buf[0] = (unsigned char)(ext_type >> 8);
635326663Sjkim    ext_buf[1] = (unsigned char)(ext_type);
636326663Sjkim    ext_buf[2] = (unsigned char)(inlen >> 8);
637326663Sjkim    ext_buf[3] = (unsigned char)(inlen);
638290207Sjkim    memcpy(ext_buf + 4, in, inlen);
639290207Sjkim
640290207Sjkim    BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d",
641290207Sjkim                 ext_type);
642290207Sjkim    PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
643290207Sjkim    return 1;
644290207Sjkim}
645290207Sjkim
646238405Sjkim#endif
647238405Sjkim
648280297Sjkimenum {
649280297Sjkim    PROTO_OFF = 0,
650280297Sjkim    PROTO_SMTP,
651280297Sjkim    PROTO_POP3,
652280297Sjkim    PROTO_IMAP,
653280297Sjkim    PROTO_FTP,
654280297Sjkim    PROTO_XMPP
655167612Ssimon};
656167612Ssimon
65759191Skrisint MAIN(int, char **);
65859191Skris
65955714Skrisint MAIN(int argc, char **argv)
660280297Sjkim{
661290207Sjkim    int build_chain = 0;
662280297Sjkim    SSL *con = NULL;
663238405Sjkim#ifndef OPENSSL_NO_KRB5
664280297Sjkim    KSSL_CTX *kctx;
665238405Sjkim#endif
666280297Sjkim    int s, k, width, state = 0;
667280297Sjkim    char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL;
668280297Sjkim    int cbuf_len, cbuf_off;
669280297Sjkim    int sbuf_len, sbuf_off;
670280297Sjkim    fd_set readfds, writefds;
671280297Sjkim    short port = PORT;
672280297Sjkim    int full_log = 1;
673280297Sjkim    char *host = SSL_HOST_NAME;
674290207Sjkim    char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
675280297Sjkim    int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
676280297Sjkim    char *passarg = NULL, *pass = NULL;
677280297Sjkim    X509 *cert = NULL;
678280297Sjkim    EVP_PKEY *key = NULL;
679290207Sjkim    STACK_OF(X509) *chain = NULL;
680290207Sjkim    char *CApath = NULL, *CAfile = NULL;
681290207Sjkim    char *chCApath = NULL, *chCAfile = NULL;
682290207Sjkim    char *vfyCApath = NULL, *vfyCAfile = NULL;
683290207Sjkim    int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE;
684280297Sjkim    int crlf = 0;
685280297Sjkim    int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
686280297Sjkim    SSL_CTX *ctx = NULL;
687280297Sjkim    int ret = 1, in_init = 1, i, nbio_test = 0;
688280297Sjkim    int starttls_proto = PROTO_OFF;
689280297Sjkim    int prexit = 0;
690280297Sjkim    X509_VERIFY_PARAM *vpm = NULL;
691280297Sjkim    int badarg = 0;
692280297Sjkim    const SSL_METHOD *meth = NULL;
693280297Sjkim    int socket_type = SOCK_STREAM;
694280297Sjkim    BIO *sbio;
695280297Sjkim    char *inrand = NULL;
696280297Sjkim    int mbuf_len = 0;
697280297Sjkim    struct timeval timeout, *timeoutp;
698312826Sjkim    char *engine_id = NULL;
699312826Sjkim    ENGINE *e = NULL;
700111147Snectar#ifndef OPENSSL_NO_ENGINE
701280297Sjkim    char *ssl_client_engine_id = NULL;
702280297Sjkim    ENGINE *ssl_client_engine = NULL;
703194206Ssimon#endif
704238405Sjkim#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
705280297Sjkim    struct timeval tv;
706280297Sjkim# if defined(OPENSSL_SYS_BEOS_R5)
707280297Sjkim    int stdin_set = 0;
708280297Sjkim# endif
70959191Skris#endif
710194206Ssimon#ifndef OPENSSL_NO_TLSEXT
711280297Sjkim    char *servername = NULL;
712280297Sjkim    tlsextctx tlsextcbp = { NULL, 0 };
713238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
714280297Sjkim    const char *next_proto_neg_in = NULL;
715238405Sjkim# endif
716290207Sjkim    const char *alpn_in = NULL;
717290207Sjkim# define MAX_SI_TYPES 100
718290207Sjkim    unsigned short serverinfo_types[MAX_SI_TYPES];
719290207Sjkim    int serverinfo_types_count = 0;
720194206Ssimon#endif
721280297Sjkim    char *sess_in = NULL;
722280297Sjkim    char *sess_out = NULL;
723280297Sjkim    struct sockaddr peer;
724280297Sjkim    int peerlen = sizeof(peer);
725280297Sjkim    int fallback_scsv = 0;
726280297Sjkim    int enable_timeouts = 0;
727280297Sjkim    long socket_mtu = 0;
728194206Ssimon#ifndef OPENSSL_NO_JPAKE
729290207Sjkim    static char *jpake_secret = NULL;
730290207Sjkim# define no_jpake !jpake_secret
731290207Sjkim#else
732290207Sjkim# define no_jpake 1
733194206Ssimon#endif
734238405Sjkim#ifndef OPENSSL_NO_SRP
735280297Sjkim    char *srppass = NULL;
736280297Sjkim    int srp_lateuser = 0;
737280297Sjkim    SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 };
738238405Sjkim#endif
739290207Sjkim    SSL_EXCERT *exc = NULL;
740160814Ssimon
741290207Sjkim    SSL_CONF_CTX *cctx = NULL;
742290207Sjkim    STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
743290207Sjkim
744290207Sjkim    char *crl_file = NULL;
745290207Sjkim    int crl_format = FORMAT_PEM;
746290207Sjkim    int crl_download = 0;
747290207Sjkim    STACK_OF(X509_CRL) *crls = NULL;
748306195Sjkim    int prot_opt = 0, no_prot_opt = 0;
749290207Sjkim
750280297Sjkim    meth = SSLv23_client_method();
75155714Skris
752280297Sjkim    apps_startup();
753280297Sjkim    c_Pause = 0;
754280297Sjkim    c_quiet = 0;
755280297Sjkim    c_ign_eof = 0;
756280297Sjkim    c_debug = 0;
757280297Sjkim    c_msg = 0;
758280297Sjkim    c_showcerts = 0;
75955714Skris
760280297Sjkim    if (bio_err == NULL)
761280297Sjkim        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
76255714Skris
763280297Sjkim    if (!load_config(bio_err, NULL))
764280297Sjkim        goto end;
765109998Smarkm
766290207Sjkim    cctx = SSL_CONF_CTX_new();
767290207Sjkim    if (!cctx)
768290207Sjkim        goto end;
769290207Sjkim    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
770290207Sjkim    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);
771290207Sjkim
772280297Sjkim    if (((cbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) ||
773280297Sjkim        ((sbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) ||
774280297Sjkim        ((mbuf = OPENSSL_malloc(BUFSIZZ)) == NULL)) {
775280297Sjkim        BIO_printf(bio_err, "out of memory\n");
776280297Sjkim        goto end;
777280297Sjkim    }
77855714Skris
779280297Sjkim    verify_depth = 0;
780280297Sjkim    verify_error = X509_V_OK;
78155714Skris#ifdef FIONBIO
782280297Sjkim    c_nbio = 0;
78355714Skris#endif
78455714Skris
785280297Sjkim    argc--;
786280297Sjkim    argv++;
787280297Sjkim    while (argc >= 1) {
788280297Sjkim        if (strcmp(*argv, "-host") == 0) {
789280297Sjkim            if (--argc < 1)
790280297Sjkim                goto bad;
791280297Sjkim            host = *(++argv);
792280297Sjkim        } else if (strcmp(*argv, "-port") == 0) {
793280297Sjkim            if (--argc < 1)
794280297Sjkim                goto bad;
795280297Sjkim            port = atoi(*(++argv));
796280297Sjkim            if (port == 0)
797280297Sjkim                goto bad;
798280297Sjkim        } else if (strcmp(*argv, "-connect") == 0) {
799280297Sjkim            if (--argc < 1)
800280297Sjkim                goto bad;
801280297Sjkim            if (!extract_host_port(*(++argv), &host, NULL, &port))
802280297Sjkim                goto bad;
803280297Sjkim        } else if (strcmp(*argv, "-verify") == 0) {
804280297Sjkim            verify = SSL_VERIFY_PEER;
805280297Sjkim            if (--argc < 1)
806280297Sjkim                goto bad;
807280297Sjkim            verify_depth = atoi(*(++argv));
808290207Sjkim            if (!c_quiet)
809290207Sjkim                BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
810280297Sjkim        } else if (strcmp(*argv, "-cert") == 0) {
811280297Sjkim            if (--argc < 1)
812280297Sjkim                goto bad;
813280297Sjkim            cert_file = *(++argv);
814290207Sjkim        } else if (strcmp(*argv, "-CRL") == 0) {
815280297Sjkim            if (--argc < 1)
816280297Sjkim                goto bad;
817290207Sjkim            crl_file = *(++argv);
818290207Sjkim        } else if (strcmp(*argv, "-crl_download") == 0)
819290207Sjkim            crl_download = 1;
820290207Sjkim        else if (strcmp(*argv, "-sess_out") == 0) {
821290207Sjkim            if (--argc < 1)
822290207Sjkim                goto bad;
823280297Sjkim            sess_out = *(++argv);
824280297Sjkim        } else if (strcmp(*argv, "-sess_in") == 0) {
825280297Sjkim            if (--argc < 1)
826280297Sjkim                goto bad;
827280297Sjkim            sess_in = *(++argv);
828280297Sjkim        } else if (strcmp(*argv, "-certform") == 0) {
829280297Sjkim            if (--argc < 1)
830280297Sjkim                goto bad;
831280297Sjkim            cert_format = str2fmt(*(++argv));
832290207Sjkim        } else if (strcmp(*argv, "-CRLform") == 0) {
833290207Sjkim            if (--argc < 1)
834290207Sjkim                goto bad;
835290207Sjkim            crl_format = str2fmt(*(++argv));
836280297Sjkim        } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) {
837280297Sjkim            if (badarg)
838280297Sjkim                goto bad;
839280297Sjkim            continue;
840280297Sjkim        } else if (strcmp(*argv, "-verify_return_error") == 0)
841280297Sjkim            verify_return_error = 1;
842290207Sjkim        else if (strcmp(*argv, "-verify_quiet") == 0)
843290207Sjkim            verify_quiet = 1;
844290207Sjkim        else if (strcmp(*argv, "-brief") == 0) {
845290207Sjkim            c_brief = 1;
846290207Sjkim            verify_quiet = 1;
847290207Sjkim            c_quiet = 1;
848290207Sjkim        } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) {
849290207Sjkim            if (badarg)
850290207Sjkim                goto bad;
851290207Sjkim            continue;
852306195Sjkim        } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args,
853306195Sjkim                            &no_prot_opt)) {
854290207Sjkim            if (badarg)
855290207Sjkim                goto bad;
856290207Sjkim            continue;
857290207Sjkim        } else if (strcmp(*argv, "-prexit") == 0)
858280297Sjkim            prexit = 1;
859280297Sjkim        else if (strcmp(*argv, "-crlf") == 0)
860280297Sjkim            crlf = 1;
861280297Sjkim        else if (strcmp(*argv, "-quiet") == 0) {
862280297Sjkim            c_quiet = 1;
863280297Sjkim            c_ign_eof = 1;
864280297Sjkim        } else if (strcmp(*argv, "-ign_eof") == 0)
865280297Sjkim            c_ign_eof = 1;
866280297Sjkim        else if (strcmp(*argv, "-no_ign_eof") == 0)
867280297Sjkim            c_ign_eof = 0;
868280297Sjkim        else if (strcmp(*argv, "-pause") == 0)
869280297Sjkim            c_Pause = 1;
870280297Sjkim        else if (strcmp(*argv, "-debug") == 0)
871280297Sjkim            c_debug = 1;
872194206Ssimon#ifndef OPENSSL_NO_TLSEXT
873280297Sjkim        else if (strcmp(*argv, "-tlsextdebug") == 0)
874280297Sjkim            c_tlsextdebug = 1;
875280297Sjkim        else if (strcmp(*argv, "-status") == 0)
876280297Sjkim            c_status_req = 1;
877194206Ssimon#endif
878160814Ssimon#ifdef WATT32
879280297Sjkim        else if (strcmp(*argv, "-wdebug") == 0)
880280297Sjkim            dbug_init();
881160814Ssimon#endif
882280297Sjkim        else if (strcmp(*argv, "-msg") == 0)
883280297Sjkim            c_msg = 1;
884290207Sjkim        else if (strcmp(*argv, "-msgfile") == 0) {
885290207Sjkim            if (--argc < 1)
886290207Sjkim                goto bad;
887290207Sjkim            bio_c_msg = BIO_new_file(*(++argv), "w");
888290207Sjkim        }
889290207Sjkim#ifndef OPENSSL_NO_SSL_TRACE
890290207Sjkim        else if (strcmp(*argv, "-trace") == 0)
891290207Sjkim            c_msg = 2;
892290207Sjkim#endif
893280297Sjkim        else if (strcmp(*argv, "-showcerts") == 0)
894280297Sjkim            c_showcerts = 1;
895280297Sjkim        else if (strcmp(*argv, "-nbio_test") == 0)
896280297Sjkim            nbio_test = 1;
897280297Sjkim        else if (strcmp(*argv, "-state") == 0)
898280297Sjkim            state = 1;
899238405Sjkim#ifndef OPENSSL_NO_PSK
900280297Sjkim        else if (strcmp(*argv, "-psk_identity") == 0) {
901280297Sjkim            if (--argc < 1)
902280297Sjkim                goto bad;
903280297Sjkim            psk_identity = *(++argv);
904280297Sjkim        } else if (strcmp(*argv, "-psk") == 0) {
905280297Sjkim            size_t j;
906238405Sjkim
907280297Sjkim            if (--argc < 1)
908280297Sjkim                goto bad;
909280297Sjkim            psk_key = *(++argv);
910280297Sjkim            for (j = 0; j < strlen(psk_key); j++) {
911280297Sjkim                if (isxdigit((unsigned char)psk_key[j]))
912280297Sjkim                    continue;
913280297Sjkim                BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
914280297Sjkim                goto bad;
915280297Sjkim            }
916280297Sjkim        }
917238405Sjkim#endif
918238405Sjkim#ifndef OPENSSL_NO_SRP
919280297Sjkim        else if (strcmp(*argv, "-srpuser") == 0) {
920280297Sjkim            if (--argc < 1)
921280297Sjkim                goto bad;
922280297Sjkim            srp_arg.srplogin = *(++argv);
923280297Sjkim            meth = TLSv1_client_method();
924280297Sjkim        } else if (strcmp(*argv, "-srppass") == 0) {
925280297Sjkim            if (--argc < 1)
926280297Sjkim                goto bad;
927280297Sjkim            srppass = *(++argv);
928280297Sjkim            meth = TLSv1_client_method();
929280297Sjkim        } else if (strcmp(*argv, "-srp_strength") == 0) {
930280297Sjkim            if (--argc < 1)
931280297Sjkim                goto bad;
932280297Sjkim            srp_arg.strength = atoi(*(++argv));
933280297Sjkim            BIO_printf(bio_err, "SRP minimal length for N is %d\n",
934280297Sjkim                       srp_arg.strength);
935280297Sjkim            meth = TLSv1_client_method();
936280297Sjkim        } else if (strcmp(*argv, "-srp_lateuser") == 0) {
937280297Sjkim            srp_lateuser = 1;
938280297Sjkim            meth = TLSv1_client_method();
939280297Sjkim        } else if (strcmp(*argv, "-srp_moregroups") == 0) {
940280297Sjkim            srp_arg.amp = 1;
941280297Sjkim            meth = TLSv1_client_method();
942280297Sjkim        }
943238405Sjkim#endif
944109998Smarkm#ifndef OPENSSL_NO_SSL2
945306195Sjkim        else if (strcmp(*argv, "-ssl2") == 0) {
946280297Sjkim            meth = SSLv2_client_method();
947306195Sjkim            prot_opt++;
948306195Sjkim        }
94955714Skris#endif
950276861Sjkim#ifndef OPENSSL_NO_SSL3_METHOD
951306195Sjkim        else if (strcmp(*argv, "-ssl3") == 0) {
952280297Sjkim            meth = SSLv3_client_method();
953306195Sjkim            prot_opt++;
954306195Sjkim        }
95555714Skris#endif
956109998Smarkm#ifndef OPENSSL_NO_TLS1
957306195Sjkim        else if (strcmp(*argv, "-tls1_2") == 0) {
958280297Sjkim            meth = TLSv1_2_client_method();
959306195Sjkim            prot_opt++;
960306195Sjkim        } else if (strcmp(*argv, "-tls1_1") == 0) {
961280297Sjkim            meth = TLSv1_1_client_method();
962306195Sjkim            prot_opt++;
963306195Sjkim        } else if (strcmp(*argv, "-tls1") == 0) {
964280297Sjkim            meth = TLSv1_client_method();
965306195Sjkim            prot_opt++;
966306195Sjkim        }
96755714Skris#endif
968160814Ssimon#ifndef OPENSSL_NO_DTLS1
969290207Sjkim        else if (strcmp(*argv, "-dtls") == 0) {
970290207Sjkim            meth = DTLS_client_method();
971290207Sjkim            socket_type = SOCK_DGRAM;
972306195Sjkim            prot_opt++;
973290207Sjkim        } else if (strcmp(*argv, "-dtls1") == 0) {
974280297Sjkim            meth = DTLSv1_client_method();
975280297Sjkim            socket_type = SOCK_DGRAM;
976306195Sjkim            prot_opt++;
977290207Sjkim        } else if (strcmp(*argv, "-dtls1_2") == 0) {
978290207Sjkim            meth = DTLSv1_2_client_method();
979290207Sjkim            socket_type = SOCK_DGRAM;
980306195Sjkim            prot_opt++;
981280297Sjkim        } else if (strcmp(*argv, "-timeout") == 0)
982280297Sjkim            enable_timeouts = 1;
983280297Sjkim        else if (strcmp(*argv, "-mtu") == 0) {
984280297Sjkim            if (--argc < 1)
985280297Sjkim                goto bad;
986280297Sjkim            socket_mtu = atol(*(++argv));
987280297Sjkim        }
988160814Ssimon#endif
989290207Sjkim        else if (strcmp(*argv, "-fallback_scsv") == 0) {
990290207Sjkim            fallback_scsv = 1;
991290207Sjkim        } else if (strcmp(*argv, "-keyform") == 0) {
992280297Sjkim            if (--argc < 1)
993280297Sjkim                goto bad;
994280297Sjkim            key_format = str2fmt(*(++argv));
995280297Sjkim        } else if (strcmp(*argv, "-pass") == 0) {
996280297Sjkim            if (--argc < 1)
997280297Sjkim                goto bad;
998280297Sjkim            passarg = *(++argv);
999290207Sjkim        } else if (strcmp(*argv, "-cert_chain") == 0) {
1000290207Sjkim            if (--argc < 1)
1001290207Sjkim                goto bad;
1002290207Sjkim            chain_file = *(++argv);
1003280297Sjkim        } else if (strcmp(*argv, "-key") == 0) {
1004280297Sjkim            if (--argc < 1)
1005280297Sjkim                goto bad;
1006280297Sjkim            key_file = *(++argv);
1007280297Sjkim        } else if (strcmp(*argv, "-reconnect") == 0) {
1008280297Sjkim            reconnect = 5;
1009280297Sjkim        } else if (strcmp(*argv, "-CApath") == 0) {
1010280297Sjkim            if (--argc < 1)
1011280297Sjkim                goto bad;
1012280297Sjkim            CApath = *(++argv);
1013290207Sjkim        } else if (strcmp(*argv, "-chainCApath") == 0) {
1014280297Sjkim            if (--argc < 1)
1015280297Sjkim                goto bad;
1016290207Sjkim            chCApath = *(++argv);
1017290207Sjkim        } else if (strcmp(*argv, "-verifyCApath") == 0) {
1018290207Sjkim            if (--argc < 1)
1019290207Sjkim                goto bad;
1020290207Sjkim            vfyCApath = *(++argv);
1021290207Sjkim        } else if (strcmp(*argv, "-build_chain") == 0)
1022290207Sjkim            build_chain = 1;
1023290207Sjkim        else if (strcmp(*argv, "-CAfile") == 0) {
1024290207Sjkim            if (--argc < 1)
1025290207Sjkim                goto bad;
1026280297Sjkim            CAfile = *(++argv);
1027290207Sjkim        } else if (strcmp(*argv, "-chainCAfile") == 0) {
1028290207Sjkim            if (--argc < 1)
1029290207Sjkim                goto bad;
1030290207Sjkim            chCAfile = *(++argv);
1031290207Sjkim        } else if (strcmp(*argv, "-verifyCAfile") == 0) {
1032290207Sjkim            if (--argc < 1)
1033290207Sjkim                goto bad;
1034290207Sjkim            vfyCAfile = *(++argv);
1035280297Sjkim        }
1036194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1037238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
1038280297Sjkim        else if (strcmp(*argv, "-nextprotoneg") == 0) {
1039280297Sjkim            if (--argc < 1)
1040280297Sjkim                goto bad;
1041280297Sjkim            next_proto_neg_in = *(++argv);
1042280297Sjkim        }
1043238405Sjkim# endif
1044290207Sjkim        else if (strcmp(*argv, "-alpn") == 0) {
1045280297Sjkim            if (--argc < 1)
1046280297Sjkim                goto bad;
1047290207Sjkim            alpn_in = *(++argv);
1048290207Sjkim        } else if (strcmp(*argv, "-serverinfo") == 0) {
1049290207Sjkim            char *c;
1050290207Sjkim            int start = 0;
1051290207Sjkim            int len;
1052290207Sjkim
1053290207Sjkim            if (--argc < 1)
1054290207Sjkim                goto bad;
1055290207Sjkim            c = *(++argv);
1056290207Sjkim            serverinfo_types_count = 0;
1057290207Sjkim            len = strlen(c);
1058290207Sjkim            for (i = 0; i <= len; ++i) {
1059290207Sjkim                if (i == len || c[i] == ',') {
1060290207Sjkim                    serverinfo_types[serverinfo_types_count]
1061290207Sjkim                        = atoi(c + start);
1062290207Sjkim                    serverinfo_types_count++;
1063290207Sjkim                    start = i + 1;
1064290207Sjkim                }
1065290207Sjkim                if (serverinfo_types_count == MAX_SI_TYPES)
1066290207Sjkim                    break;
1067290207Sjkim            }
1068280297Sjkim        }
1069290207Sjkim#endif
107055714Skris#ifdef FIONBIO
1071280297Sjkim        else if (strcmp(*argv, "-nbio") == 0) {
1072280297Sjkim            c_nbio = 1;
1073280297Sjkim        }
107455714Skris#endif
1075280297Sjkim        else if (strcmp(*argv, "-starttls") == 0) {
1076280297Sjkim            if (--argc < 1)
1077280297Sjkim                goto bad;
1078280297Sjkim            ++argv;
1079280297Sjkim            if (strcmp(*argv, "smtp") == 0)
1080280297Sjkim                starttls_proto = PROTO_SMTP;
1081280297Sjkim            else if (strcmp(*argv, "pop3") == 0)
1082280297Sjkim                starttls_proto = PROTO_POP3;
1083280297Sjkim            else if (strcmp(*argv, "imap") == 0)
1084280297Sjkim                starttls_proto = PROTO_IMAP;
1085280297Sjkim            else if (strcmp(*argv, "ftp") == 0)
1086280297Sjkim                starttls_proto = PROTO_FTP;
1087280297Sjkim            else if (strcmp(*argv, "xmpp") == 0)
1088280297Sjkim                starttls_proto = PROTO_XMPP;
1089280297Sjkim            else
1090280297Sjkim                goto bad;
1091280297Sjkim        }
1092111147Snectar#ifndef OPENSSL_NO_ENGINE
1093280297Sjkim        else if (strcmp(*argv, "-engine") == 0) {
1094280297Sjkim            if (--argc < 1)
1095280297Sjkim                goto bad;
1096280297Sjkim            engine_id = *(++argv);
1097280297Sjkim        } else if (strcmp(*argv, "-ssl_client_engine") == 0) {
1098280297Sjkim            if (--argc < 1)
1099280297Sjkim                goto bad;
1100280297Sjkim            ssl_client_engine_id = *(++argv);
1101280297Sjkim        }
1102111147Snectar#endif
1103280297Sjkim        else if (strcmp(*argv, "-rand") == 0) {
1104280297Sjkim            if (--argc < 1)
1105280297Sjkim                goto bad;
1106280297Sjkim            inrand = *(++argv);
1107280297Sjkim        }
1108194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1109280297Sjkim        else if (strcmp(*argv, "-servername") == 0) {
1110280297Sjkim            if (--argc < 1)
1111280297Sjkim                goto bad;
1112280297Sjkim            servername = *(++argv);
1113280297Sjkim            /* meth=TLSv1_client_method(); */
1114280297Sjkim        }
1115194206Ssimon#endif
1116194206Ssimon#ifndef OPENSSL_NO_JPAKE
1117280297Sjkim        else if (strcmp(*argv, "-jpake") == 0) {
1118280297Sjkim            if (--argc < 1)
1119280297Sjkim                goto bad;
1120280297Sjkim            jpake_secret = *++argv;
1121280297Sjkim        }
1122194206Ssimon#endif
1123246772Sjkim#ifndef OPENSSL_NO_SRTP
1124280297Sjkim        else if (strcmp(*argv, "-use_srtp") == 0) {
1125280297Sjkim            if (--argc < 1)
1126280297Sjkim                goto bad;
1127280297Sjkim            srtp_profiles = *(++argv);
1128280297Sjkim        }
1129246772Sjkim#endif
1130280297Sjkim        else if (strcmp(*argv, "-keymatexport") == 0) {
1131280297Sjkim            if (--argc < 1)
1132280297Sjkim                goto bad;
1133280297Sjkim            keymatexportlabel = *(++argv);
1134280297Sjkim        } else if (strcmp(*argv, "-keymatexportlen") == 0) {
1135280297Sjkim            if (--argc < 1)
1136280297Sjkim                goto bad;
1137280297Sjkim            keymatexportlen = atoi(*(++argv));
1138280297Sjkim            if (keymatexportlen == 0)
1139280297Sjkim                goto bad;
1140280297Sjkim        } else {
1141280297Sjkim            BIO_printf(bio_err, "unknown option %s\n", *argv);
1142280297Sjkim            badop = 1;
1143280297Sjkim            break;
1144280297Sjkim        }
1145280297Sjkim        argc--;
1146280297Sjkim        argv++;
1147280297Sjkim    }
1148280297Sjkim    if (badop) {
1149280297Sjkim bad:
1150280297Sjkim        sc_usage();
1151280297Sjkim        goto end;
1152280297Sjkim    }
1153238405Sjkim#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
1154280297Sjkim    if (jpake_secret) {
1155280297Sjkim        if (psk_key) {
1156280297Sjkim            BIO_printf(bio_err, "Can't use JPAKE and PSK together\n");
1157280297Sjkim            goto end;
1158280297Sjkim        }
1159280297Sjkim        psk_identity = "JPAKE";
1160280297Sjkim    }
1161238405Sjkim#endif
1162238405Sjkim
1163306195Sjkim    if (prot_opt > 1) {
1164306195Sjkim        BIO_printf(bio_err, "Cannot supply multiple protocol flags\n");
1165306195Sjkim        goto end;
1166306195Sjkim    }
1167306195Sjkim
1168306195Sjkim    if (prot_opt == 1 && no_prot_opt) {
1169306195Sjkim        BIO_printf(bio_err, "Cannot supply both a protocol flag and "
1170306195Sjkim                            "\"-no_<prot>\"\n");
1171306195Sjkim        goto end;
1172306195Sjkim    }
1173306195Sjkim
1174280297Sjkim    OpenSSL_add_ssl_algorithms();
1175280297Sjkim    SSL_load_error_strings();
1176109998Smarkm
1177238405Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
1178280297Sjkim    next_proto.status = -1;
1179280297Sjkim    if (next_proto_neg_in) {
1180280297Sjkim        next_proto.data =
1181280297Sjkim            next_protos_parse(&next_proto.len, next_proto_neg_in);
1182280297Sjkim        if (next_proto.data == NULL) {
1183280297Sjkim            BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
1184280297Sjkim            goto end;
1185280297Sjkim        }
1186280297Sjkim    } else
1187280297Sjkim        next_proto.data = NULL;
1188238405Sjkim#endif
1189238405Sjkim
1190312826Sjkim    e = setup_engine(bio_err, engine_id, 1);
1191111147Snectar#ifndef OPENSSL_NO_ENGINE
1192280297Sjkim    if (ssl_client_engine_id) {
1193280297Sjkim        ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
1194280297Sjkim        if (!ssl_client_engine) {
1195280297Sjkim            BIO_printf(bio_err, "Error getting client auth engine\n");
1196280297Sjkim            goto end;
1197280297Sjkim        }
1198280297Sjkim    }
1199111147Snectar#endif
1200280297Sjkim    if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
1201280297Sjkim        BIO_printf(bio_err, "Error getting password\n");
1202280297Sjkim        goto end;
1203280297Sjkim    }
1204109998Smarkm
1205280297Sjkim    if (key_file == NULL)
1206280297Sjkim        key_file = cert_file;
1207160814Ssimon
1208280297Sjkim    if (key_file) {
1209160814Ssimon
1210280297Sjkim        key = load_key(bio_err, key_file, key_format, 0, pass, e,
1211280297Sjkim                       "client certificate private key file");
1212280297Sjkim        if (!key) {
1213280297Sjkim            ERR_print_errors(bio_err);
1214280297Sjkim            goto end;
1215280297Sjkim        }
1216160814Ssimon
1217280297Sjkim    }
1218160814Ssimon
1219280297Sjkim    if (cert_file) {
1220280297Sjkim        cert = load_cert(bio_err, cert_file, cert_format,
1221280297Sjkim                         NULL, e, "client certificate file");
1222160814Ssimon
1223280297Sjkim        if (!cert) {
1224280297Sjkim            ERR_print_errors(bio_err);
1225280297Sjkim            goto end;
1226280297Sjkim        }
1227280297Sjkim    }
1228160814Ssimon
1229290207Sjkim    if (chain_file) {
1230290207Sjkim        chain = load_certs(bio_err, chain_file, FORMAT_PEM,
1231290207Sjkim                           NULL, e, "client certificate chain");
1232290207Sjkim        if (!chain)
1233290207Sjkim            goto end;
1234290207Sjkim    }
1235290207Sjkim
1236290207Sjkim    if (crl_file) {
1237290207Sjkim        X509_CRL *crl;
1238290207Sjkim        crl = load_crl(crl_file, crl_format);
1239290207Sjkim        if (!crl) {
1240290207Sjkim            BIO_puts(bio_err, "Error loading CRL\n");
1241290207Sjkim            ERR_print_errors(bio_err);
1242290207Sjkim            goto end;
1243290207Sjkim        }
1244290207Sjkim        crls = sk_X509_CRL_new_null();
1245290207Sjkim        if (!crls || !sk_X509_CRL_push(crls, crl)) {
1246290207Sjkim            BIO_puts(bio_err, "Error adding CRL\n");
1247290207Sjkim            ERR_print_errors(bio_err);
1248290207Sjkim            X509_CRL_free(crl);
1249290207Sjkim            goto end;
1250290207Sjkim        }
1251290207Sjkim    }
1252290207Sjkim
1253290207Sjkim    if (!load_excert(&exc, bio_err))
1254290207Sjkim        goto end;
1255290207Sjkim
1256280297Sjkim    if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
1257280297Sjkim        && !RAND_status()) {
1258280297Sjkim        BIO_printf(bio_err,
1259280297Sjkim                   "warning, not much extra random data, consider using the -rand option\n");
1260280297Sjkim    }
1261280297Sjkim    if (inrand != NULL)
1262280297Sjkim        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
1263280297Sjkim                   app_RAND_load_files(inrand));
1264160814Ssimon
1265280297Sjkim    if (bio_c_out == NULL) {
1266290207Sjkim        if (c_quiet && !c_debug) {
1267280297Sjkim            bio_c_out = BIO_new(BIO_s_null());
1268290207Sjkim            if (c_msg && !bio_c_msg)
1269290207Sjkim                bio_c_msg = BIO_new_fp(stdout, BIO_NOCLOSE);
1270280297Sjkim        } else {
1271280297Sjkim            if (bio_c_out == NULL)
1272280297Sjkim                bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE);
1273280297Sjkim        }
1274280297Sjkim    }
1275238405Sjkim#ifndef OPENSSL_NO_SRP
1276280297Sjkim    if (!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL)) {
1277280297Sjkim        BIO_printf(bio_err, "Error getting password\n");
1278280297Sjkim        goto end;
1279280297Sjkim    }
1280238405Sjkim#endif
1281238405Sjkim
1282280297Sjkim    ctx = SSL_CTX_new(meth);
1283280297Sjkim    if (ctx == NULL) {
1284280297Sjkim        ERR_print_errors(bio_err);
1285280297Sjkim        goto end;
1286280297Sjkim    }
128755714Skris
1288280297Sjkim    if (vpm)
1289280297Sjkim        SSL_CTX_set1_param(ctx, vpm);
1290238405Sjkim
1291290207Sjkim    if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake)) {
1292290207Sjkim        ERR_print_errors(bio_err);
1293290207Sjkim        goto end;
1294290207Sjkim    }
1295290207Sjkim
1296290207Sjkim    if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
1297290207Sjkim                         crls, crl_download)) {
1298290207Sjkim        BIO_printf(bio_err, "Error loading store locations\n");
1299290207Sjkim        ERR_print_errors(bio_err);
1300290207Sjkim        goto end;
1301290207Sjkim    }
1302194206Ssimon#ifndef OPENSSL_NO_ENGINE
1303280297Sjkim    if (ssl_client_engine) {
1304280297Sjkim        if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
1305280297Sjkim            BIO_puts(bio_err, "Error setting client auth engine\n");
1306280297Sjkim            ERR_print_errors(bio_err);
1307280297Sjkim            ENGINE_free(ssl_client_engine);
1308280297Sjkim            goto end;
1309280297Sjkim        }
1310280297Sjkim        ENGINE_free(ssl_client_engine);
1311280297Sjkim    }
1312194206Ssimon#endif
1313194206Ssimon
1314238405Sjkim#ifndef OPENSSL_NO_PSK
1315280297Sjkim# ifdef OPENSSL_NO_JPAKE
1316280297Sjkim    if (psk_key != NULL)
1317280297Sjkim# else
1318280297Sjkim    if (psk_key != NULL || jpake_secret)
1319280297Sjkim# endif
1320280297Sjkim    {
1321280297Sjkim        if (c_debug)
1322280297Sjkim            BIO_printf(bio_c_out,
1323280297Sjkim                       "PSK key given or JPAKE in use, setting client callback\n");
1324280297Sjkim        SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
1325280297Sjkim    }
1326238405Sjkim#endif
1327246772Sjkim#ifndef OPENSSL_NO_SRTP
1328280297Sjkim    if (srtp_profiles != NULL)
1329280297Sjkim        SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
1330238405Sjkim#endif
1331290207Sjkim    if (exc)
1332290207Sjkim        ssl_ctx_set_excert(ctx, exc);
1333205128Ssimon
1334290207Sjkim#if !defined(OPENSSL_NO_TLSEXT)
1335290207Sjkim# if !defined(OPENSSL_NO_NEXTPROTONEG)
1336280297Sjkim    if (next_proto.data)
1337280297Sjkim        SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
1338290207Sjkim# endif
1339290207Sjkim    if (alpn_in) {
1340290207Sjkim        unsigned short alpn_len;
1341290207Sjkim        unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
1342290207Sjkim
1343290207Sjkim        if (alpn == NULL) {
1344290207Sjkim            BIO_printf(bio_err, "Error parsing -alpn argument\n");
1345290207Sjkim            goto end;
1346290207Sjkim        }
1347290207Sjkim        SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
1348290207Sjkim        OPENSSL_free(alpn);
1349290207Sjkim    }
1350238405Sjkim#endif
1351290207Sjkim#ifndef OPENSSL_NO_TLSEXT
1352290207Sjkim    for (i = 0; i < serverinfo_types_count; i++) {
1353290207Sjkim        SSL_CTX_add_client_custom_ext(ctx,
1354290207Sjkim                                      serverinfo_types[i],
1355290207Sjkim                                      NULL, NULL, NULL,
1356290207Sjkim                                      serverinfo_cli_parse_cb, NULL);
1357290207Sjkim    }
1358290207Sjkim#endif
1359238405Sjkim
1360280297Sjkim    if (state)
1361280297Sjkim        SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
136255714Skris#if 0
1363290207Sjkim    else
1364290207Sjkim        SSL_CTX_set_cipher_list(ctx, getenv("SSL_CIPHER"));
136555714Skris#endif
136655714Skris
1367280297Sjkim    SSL_CTX_set_verify(ctx, verify, verify_callback);
136855714Skris
1369284283Sjkim    if ((CAfile || CApath)
1370284283Sjkim        && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
1371280297Sjkim        ERR_print_errors(bio_err);
1372280297Sjkim    }
1373284283Sjkim    if (!SSL_CTX_set_default_verify_paths(ctx)) {
1374284283Sjkim        ERR_print_errors(bio_err);
1375284283Sjkim    }
1376290207Sjkim
1377290207Sjkim    ssl_ctx_add_crls(ctx, crls, crl_download);
1378290207Sjkim    if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain))
1379290207Sjkim        goto end;
1380290207Sjkim
1381194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1382280297Sjkim    if (servername != NULL) {
1383280297Sjkim        tlsextcbp.biodebug = bio_err;
1384280297Sjkim        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1385280297Sjkim        SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
1386280297Sjkim    }
1387280297Sjkim# ifndef OPENSSL_NO_SRP
1388280297Sjkim    if (srp_arg.srplogin) {
1389280297Sjkim        if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) {
1390280297Sjkim            BIO_printf(bio_err, "Unable to set SRP username\n");
1391280297Sjkim            goto end;
1392280297Sjkim        }
1393280297Sjkim        srp_arg.msg = c_msg;
1394280297Sjkim        srp_arg.debug = c_debug;
1395280297Sjkim        SSL_CTX_set_srp_cb_arg(ctx, &srp_arg);
1396280297Sjkim        SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
1397280297Sjkim        SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
1398280297Sjkim        if (c_msg || c_debug || srp_arg.amp == 0)
1399280297Sjkim            SSL_CTX_set_srp_verify_param_callback(ctx,
1400280297Sjkim                                                  ssl_srp_verify_param_cb);
1401280297Sjkim    }
1402280297Sjkim# endif
1403194206Ssimon#endif
140455714Skris
1405280297Sjkim    con = SSL_new(ctx);
1406280297Sjkim    if (sess_in) {
1407280297Sjkim        SSL_SESSION *sess;
1408280297Sjkim        BIO *stmp = BIO_new_file(sess_in, "r");
1409280297Sjkim        if (!stmp) {
1410280297Sjkim            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
1411280297Sjkim            ERR_print_errors(bio_err);
1412280297Sjkim            goto end;
1413280297Sjkim        }
1414280297Sjkim        sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
1415280297Sjkim        BIO_free(stmp);
1416280297Sjkim        if (!sess) {
1417280297Sjkim            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
1418280297Sjkim            ERR_print_errors(bio_err);
1419280297Sjkim            goto end;
1420280297Sjkim        }
1421280297Sjkim        SSL_set_session(con, sess);
1422280297Sjkim        SSL_SESSION_free(sess);
1423280297Sjkim    }
1424273144Sjkim
1425280297Sjkim    if (fallback_scsv)
1426280297Sjkim        SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
1427273144Sjkim
1428194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1429280297Sjkim    if (servername != NULL) {
1430280297Sjkim        if (!SSL_set_tlsext_host_name(con, servername)) {
1431280297Sjkim            BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
1432280297Sjkim            ERR_print_errors(bio_err);
1433280297Sjkim            goto end;
1434280297Sjkim        }
1435280297Sjkim    }
1436194206Ssimon#endif
1437109998Smarkm#ifndef OPENSSL_NO_KRB5
1438280297Sjkim    if (con && (kctx = kssl_ctx_new()) != NULL) {
1439280297Sjkim        SSL_set0_kssl_ctx(con, kctx);
1440280297Sjkim        kssl_ctx_setstring(kctx, KSSL_SERVER, host);
1441280297Sjkim    }
1442280297Sjkim#endif                          /* OPENSSL_NO_KRB5 */
1443280297Sjkim/*      SSL_set_cipher_list(con,"RC4-MD5"); */
1444238405Sjkim#if 0
1445280297Sjkim# ifdef TLSEXT_TYPE_opaque_prf_input
1446280297Sjkim    SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
1447280297Sjkim# endif
1448238405Sjkim#endif
144955714Skris
1450280297Sjkim re_start:
145155714Skris
1452280297Sjkim    if (init_client(&s, host, port, socket_type) == 0) {
1453280297Sjkim        BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
1454280297Sjkim        SHUTDOWN(s);
1455280297Sjkim        goto end;
1456280297Sjkim    }
1457280297Sjkim    BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
145855714Skris
145955714Skris#ifdef FIONBIO
1460280297Sjkim    if (c_nbio) {
1461280297Sjkim        unsigned long l = 1;
1462280297Sjkim        BIO_printf(bio_c_out, "turning on non blocking io\n");
1463280297Sjkim        if (BIO_socket_ioctl(s, FIONBIO, &l) < 0) {
1464280297Sjkim            ERR_print_errors(bio_err);
1465280297Sjkim            goto end;
1466280297Sjkim        }
1467280297Sjkim    }
1468280297Sjkim#endif
1469280297Sjkim    if (c_Pause & 0x01)
1470280297Sjkim        SSL_set_debug(con, 1);
147155714Skris
1472290207Sjkim    if (socket_type == SOCK_DGRAM) {
1473160814Ssimon
1474280297Sjkim        sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1475280297Sjkim        if (getsockname(s, &peer, (void *)&peerlen) < 0) {
1476280297Sjkim            BIO_printf(bio_err, "getsockname:errno=%d\n",
1477280297Sjkim                       get_last_socket_error());
1478280297Sjkim            SHUTDOWN(s);
1479280297Sjkim            goto end;
1480280297Sjkim        }
1481160814Ssimon
1482280297Sjkim        (void)BIO_ctrl_set_connected(sbio, 1, &peer);
1483160814Ssimon
1484280297Sjkim        if (enable_timeouts) {
1485280297Sjkim            timeout.tv_sec = 0;
1486280297Sjkim            timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1487280297Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
1488160814Ssimon
1489280297Sjkim            timeout.tv_sec = 0;
1490280297Sjkim            timeout.tv_usec = DGRAM_SND_TIMEOUT;
1491280297Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
1492280297Sjkim        }
1493160814Ssimon
1494280297Sjkim        if (socket_mtu) {
1495280297Sjkim            if (socket_mtu < DTLS_get_link_min_mtu(con)) {
1496280297Sjkim                BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
1497280297Sjkim                           DTLS_get_link_min_mtu(con));
1498280297Sjkim                BIO_free(sbio);
1499280297Sjkim                goto shut;
1500280297Sjkim            }
1501280297Sjkim            SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1502280297Sjkim            if (!DTLS_set_link_mtu(con, socket_mtu)) {
1503280297Sjkim                BIO_printf(bio_err, "Failed to set MTU\n");
1504280297Sjkim                BIO_free(sbio);
1505280297Sjkim                goto shut;
1506280297Sjkim            }
1507280297Sjkim        } else
1508280297Sjkim            /* want to do MTU discovery */
1509280297Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1510280297Sjkim    } else
1511280297Sjkim        sbio = BIO_new_socket(s, BIO_NOCLOSE);
151255714Skris
1513280297Sjkim    if (nbio_test) {
1514280297Sjkim        BIO *test;
151555714Skris
1516280297Sjkim        test = BIO_new(BIO_f_nbio_test());
1517280297Sjkim        sbio = BIO_push(test, sbio);
1518280297Sjkim    }
1519280297Sjkim
1520280297Sjkim    if (c_debug) {
1521280297Sjkim        SSL_set_debug(con, 1);
1522280297Sjkim        BIO_set_callback(sbio, bio_dump_callback);
1523280297Sjkim        BIO_set_callback_arg(sbio, (char *)bio_c_out);
1524280297Sjkim    }
1525280297Sjkim    if (c_msg) {
1526290207Sjkim#ifndef OPENSSL_NO_SSL_TRACE
1527290207Sjkim        if (c_msg == 2)
1528290207Sjkim            SSL_set_msg_callback(con, SSL_trace);
1529290207Sjkim        else
1530290207Sjkim#endif
1531290207Sjkim            SSL_set_msg_callback(con, msg_cb);
1532290207Sjkim        SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);
1533280297Sjkim    }
1534194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1535280297Sjkim    if (c_tlsextdebug) {
1536280297Sjkim        SSL_set_tlsext_debug_callback(con, tlsext_cb);
1537280297Sjkim        SSL_set_tlsext_debug_arg(con, bio_c_out);
1538280297Sjkim    }
1539280297Sjkim    if (c_status_req) {
1540280297Sjkim        SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
1541280297Sjkim        SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
1542280297Sjkim        SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
1543280297Sjkim# if 0
1544280297Sjkim        {
1545280297Sjkim            STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
1546280297Sjkim            OCSP_RESPID *id = OCSP_RESPID_new();
1547280297Sjkim            id->value.byKey = ASN1_OCTET_STRING_new();
1548280297Sjkim            id->type = V_OCSP_RESPID_KEY;
1549280297Sjkim            ASN1_STRING_set(id->value.byKey, "Hello World", -1);
1550280297Sjkim            sk_OCSP_RESPID_push(ids, id);
1551280297Sjkim            SSL_set_tlsext_status_ids(con, ids);
1552280297Sjkim        }
1553280297Sjkim# endif
1554280297Sjkim    }
1555194206Ssimon#endif
1556194206Ssimon#ifndef OPENSSL_NO_JPAKE
1557280297Sjkim    if (jpake_secret)
1558280297Sjkim        jpake_client_auth(bio_c_out, sbio, jpake_secret);
1559194206Ssimon#endif
156055714Skris
1561280297Sjkim    SSL_set_bio(con, sbio, sbio);
1562280297Sjkim    SSL_set_connect_state(con);
156355714Skris
1564280297Sjkim    /* ok, lets connect */
1565306195Sjkim    if (fileno_stdin() > SSL_get_fd(con))
1566306195Sjkim        width = fileno_stdin() + 1;
1567306195Sjkim    else
1568306195Sjkim        width = SSL_get_fd(con) + 1;
156955714Skris
1570280297Sjkim    read_tty = 1;
1571280297Sjkim    write_tty = 0;
1572280297Sjkim    tty_on = 0;
1573280297Sjkim    read_ssl = 1;
1574280297Sjkim    write_ssl = 1;
157555714Skris
1576280297Sjkim    cbuf_len = 0;
1577280297Sjkim    cbuf_off = 0;
1578280297Sjkim    sbuf_len = 0;
1579280297Sjkim    sbuf_off = 0;
1580109998Smarkm
1581280297Sjkim    /* This is an ugly hack that does a lot of assumptions */
1582280297Sjkim    /*
1583280297Sjkim     * We do have to handle multi-line responses which may come in a single
1584280297Sjkim     * packet or not. We therefore have to use BIO_gets() which does need a
1585280297Sjkim     * buffering BIO. So during the initial chitchat we do push a buffering
1586280297Sjkim     * BIO into the chain that is removed again later on to not disturb the
1587280297Sjkim     * rest of the s_client operation.
1588280297Sjkim     */
1589280297Sjkim    if (starttls_proto == PROTO_SMTP) {
1590280297Sjkim        int foundit = 0;
1591280297Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1592280297Sjkim        BIO_push(fbio, sbio);
1593280297Sjkim        /* wait for multi-line response to end from SMTP */
1594280297Sjkim        do {
1595280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1596280297Sjkim        }
1597280297Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1598280297Sjkim        /* STARTTLS command requires EHLO... */
1599280297Sjkim        BIO_printf(fbio, "EHLO openssl.client.net\r\n");
1600280297Sjkim        (void)BIO_flush(fbio);
1601280297Sjkim        /* wait for multi-line response to end EHLO SMTP response */
1602280297Sjkim        do {
1603280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1604280297Sjkim            if (strstr(mbuf, "STARTTLS"))
1605280297Sjkim                foundit = 1;
1606280297Sjkim        }
1607280297Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1608280297Sjkim        (void)BIO_flush(fbio);
1609280297Sjkim        BIO_pop(fbio);
1610280297Sjkim        BIO_free(fbio);
1611280297Sjkim        if (!foundit)
1612280297Sjkim            BIO_printf(bio_err,
1613280297Sjkim                       "didn't found starttls in server response,"
1614280297Sjkim                       " try anyway...\n");
1615280297Sjkim        BIO_printf(sbio, "STARTTLS\r\n");
1616280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1617280297Sjkim    } else if (starttls_proto == PROTO_POP3) {
1618280297Sjkim        BIO_read(sbio, mbuf, BUFSIZZ);
1619280297Sjkim        BIO_printf(sbio, "STLS\r\n");
1620280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1621280297Sjkim    } else if (starttls_proto == PROTO_IMAP) {
1622280297Sjkim        int foundit = 0;
1623280297Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1624280297Sjkim        BIO_push(fbio, sbio);
1625280297Sjkim        BIO_gets(fbio, mbuf, BUFSIZZ);
1626280297Sjkim        /* STARTTLS command requires CAPABILITY... */
1627280297Sjkim        BIO_printf(fbio, ". CAPABILITY\r\n");
1628280297Sjkim        (void)BIO_flush(fbio);
1629280297Sjkim        /* wait for multi-line CAPABILITY response */
1630280297Sjkim        do {
1631280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1632280297Sjkim            if (strstr(mbuf, "STARTTLS"))
1633280297Sjkim                foundit = 1;
1634280297Sjkim        }
1635280297Sjkim        while (mbuf_len > 3 && mbuf[0] != '.');
1636280297Sjkim        (void)BIO_flush(fbio);
1637280297Sjkim        BIO_pop(fbio);
1638280297Sjkim        BIO_free(fbio);
1639280297Sjkim        if (!foundit)
1640280297Sjkim            BIO_printf(bio_err,
1641280297Sjkim                       "didn't found STARTTLS in server response,"
1642280297Sjkim                       " try anyway...\n");
1643280297Sjkim        BIO_printf(sbio, ". STARTTLS\r\n");
1644280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1645280297Sjkim    } else if (starttls_proto == PROTO_FTP) {
1646280297Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1647280297Sjkim        BIO_push(fbio, sbio);
1648280297Sjkim        /* wait for multi-line response to end from FTP */
1649280297Sjkim        do {
1650280297Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1651280297Sjkim        }
1652280297Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1653280297Sjkim        (void)BIO_flush(fbio);
1654280297Sjkim        BIO_pop(fbio);
1655280297Sjkim        BIO_free(fbio);
1656280297Sjkim        BIO_printf(sbio, "AUTH TLS\r\n");
1657280297Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1658280297Sjkim    }
1659280297Sjkim    if (starttls_proto == PROTO_XMPP) {
1660280297Sjkim        int seen = 0;
1661280297Sjkim        BIO_printf(sbio, "<stream:stream "
1662280297Sjkim                   "xmlns:stream='http://etherx.jabber.org/streams' "
1663280297Sjkim                   "xmlns='jabber:client' to='%s' version='1.0'>", host);
1664280297Sjkim        seen = BIO_read(sbio, mbuf, BUFSIZZ);
1665280297Sjkim        mbuf[seen] = 0;
1666280297Sjkim        while (!strstr
1667280297Sjkim               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) {
1668280297Sjkim            if (strstr(mbuf, "/stream:features>"))
1669280297Sjkim                goto shut;
1670280297Sjkim            seen = BIO_read(sbio, mbuf, BUFSIZZ);
1671325337Sjkim            if (seen <= 0)
1672325337Sjkim                goto shut;
1673280297Sjkim            mbuf[seen] = 0;
1674280297Sjkim        }
1675280297Sjkim        BIO_printf(sbio,
1676280297Sjkim                   "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1677280297Sjkim        seen = BIO_read(sbio, sbuf, BUFSIZZ);
1678280297Sjkim        sbuf[seen] = 0;
1679280297Sjkim        if (!strstr(sbuf, "<proceed"))
1680280297Sjkim            goto shut;
1681280297Sjkim        mbuf[0] = 0;
1682280297Sjkim    }
168355714Skris
1684280297Sjkim    for (;;) {
1685280297Sjkim        FD_ZERO(&readfds);
1686280297Sjkim        FD_ZERO(&writefds);
1687205128Ssimon
1688280297Sjkim        if ((SSL_version(con) == DTLS1_VERSION) &&
1689280297Sjkim            DTLSv1_get_timeout(con, &timeout))
1690280297Sjkim            timeoutp = &timeout;
1691280297Sjkim        else
1692280297Sjkim            timeoutp = NULL;
1693280297Sjkim
1694280297Sjkim        if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
1695280297Sjkim            in_init = 1;
1696280297Sjkim            tty_on = 0;
1697280297Sjkim        } else {
1698280297Sjkim            tty_on = 1;
1699280297Sjkim            if (in_init) {
1700280297Sjkim                in_init = 0;
1701280297Sjkim#if 0                           /* This test doesn't really work as intended
1702280297Sjkim                                 * (needs to be fixed) */
1703280297Sjkim# ifndef OPENSSL_NO_TLSEXT
1704280297Sjkim                if (servername != NULL && !SSL_session_reused(con)) {
1705280297Sjkim                    BIO_printf(bio_c_out,
1706280297Sjkim                               "Server did %sacknowledge servername extension.\n",
1707280297Sjkim                               tlsextcbp.ack ? "" : "not ");
1708280297Sjkim                }
1709280297Sjkim# endif
1710238405Sjkim#endif
1711280297Sjkim                if (sess_out) {
1712280297Sjkim                    BIO *stmp = BIO_new_file(sess_out, "w");
1713280297Sjkim                    if (stmp) {
1714280297Sjkim                        PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
1715280297Sjkim                        BIO_free(stmp);
1716280297Sjkim                    } else
1717280297Sjkim                        BIO_printf(bio_err, "Error writing session file %s\n",
1718280297Sjkim                                   sess_out);
1719280297Sjkim                }
1720290207Sjkim                if (c_brief) {
1721290207Sjkim                    BIO_puts(bio_err, "CONNECTION ESTABLISHED\n");
1722290207Sjkim                    print_ssl_summary(bio_err, con);
1723290207Sjkim                }
1724290207Sjkim
1725280297Sjkim                print_stuff(bio_c_out, con, full_log);
1726280297Sjkim                if (full_log > 0)
1727280297Sjkim                    full_log--;
172855714Skris
1729280297Sjkim                if (starttls_proto) {
1730280297Sjkim                    BIO_printf(bio_err, "%s", mbuf);
1731280297Sjkim                    /* We don't need to know any more */
1732280297Sjkim                    starttls_proto = PROTO_OFF;
1733280297Sjkim                }
1734109998Smarkm
1735280297Sjkim                if (reconnect) {
1736280297Sjkim                    reconnect--;
1737280297Sjkim                    BIO_printf(bio_c_out,
1738280297Sjkim                               "drop connection and then reconnect\n");
1739280297Sjkim                    SSL_shutdown(con);
1740280297Sjkim                    SSL_set_connect_state(con);
1741280297Sjkim                    SHUTDOWN(SSL_get_fd(con));
1742280297Sjkim                    goto re_start;
1743280297Sjkim                }
1744280297Sjkim            }
1745280297Sjkim        }
174655714Skris
1747280297Sjkim        ssl_pending = read_ssl && SSL_pending(con);
174855714Skris
1749280297Sjkim        if (!ssl_pending) {
1750238405Sjkim#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
1751280297Sjkim            if (tty_on) {
1752280297Sjkim                if (read_tty)
1753306195Sjkim                    openssl_fdset(fileno_stdin(), &readfds);
1754306195Sjkim#if !defined(OPENSSL_SYS_VMS)
1755280297Sjkim                if (write_tty)
1756306195Sjkim                    openssl_fdset(fileno_stdout(), &writefds);
1757306195Sjkim#endif
1758280297Sjkim            }
1759280297Sjkim            if (read_ssl)
1760280297Sjkim                openssl_fdset(SSL_get_fd(con), &readfds);
1761280297Sjkim            if (write_ssl)
1762280297Sjkim                openssl_fdset(SSL_get_fd(con), &writefds);
176359191Skris#else
1764280297Sjkim            if (!tty_on || !write_tty) {
1765280297Sjkim                if (read_ssl)
1766280297Sjkim                    openssl_fdset(SSL_get_fd(con), &readfds);
1767280297Sjkim                if (write_ssl)
1768280297Sjkim                    openssl_fdset(SSL_get_fd(con), &writefds);
1769280297Sjkim            }
177059191Skris#endif
1771280297Sjkim/*-         printf("mode tty(%d %d%d) ssl(%d%d)\n",
1772280297Sjkim                    tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
177355714Skris
1774280297Sjkim            /*
1775280297Sjkim             * Note: under VMS with SOCKETSHR the second parameter is
1776280297Sjkim             * currently of type (int *) whereas under other systems it is
1777280297Sjkim             * (void *) if you don't have a cast it will choke the compiler:
1778280297Sjkim             * if you do have a cast then you can either go for (int *) or
1779280297Sjkim             * (void *).
1780280297Sjkim             */
1781120631Snectar#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
1782280297Sjkim            /*
1783280297Sjkim             * Under Windows/DOS we make the assumption that we can always
1784280297Sjkim             * write to the tty: therefore if we need to write to the tty we
1785280297Sjkim             * just fall through. Otherwise we timeout the select every
1786280297Sjkim             * second and see if there are any keypresses. Note: this is a
1787280297Sjkim             * hack, in a proper Windows application we wouldn't do this.
1788280297Sjkim             */
1789280297Sjkim            i = 0;
1790280297Sjkim            if (!write_tty) {
1791280297Sjkim                if (read_tty) {
1792280297Sjkim                    tv.tv_sec = 1;
1793280297Sjkim                    tv.tv_usec = 0;
1794280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1795280297Sjkim                               NULL, &tv);
1796280297Sjkim# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
1797280297Sjkim                    if (!i && (!_kbhit() || !read_tty))
1798280297Sjkim                        continue;
1799280297Sjkim# else
1800280297Sjkim                    if (!i && (!((_kbhit())
1801280297Sjkim                                 || (WAIT_OBJECT_0 ==
1802280297Sjkim                                     WaitForSingleObject(GetStdHandle
1803280297Sjkim                                                         (STD_INPUT_HANDLE),
1804280297Sjkim                                                         0)))
1805280297Sjkim                               || !read_tty))
1806280297Sjkim                        continue;
1807280297Sjkim# endif
1808280297Sjkim                } else
1809280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1810280297Sjkim                               NULL, timeoutp);
1811280297Sjkim            }
1812160814Ssimon#elif defined(OPENSSL_SYS_NETWARE)
1813280297Sjkim            if (!write_tty) {
1814280297Sjkim                if (read_tty) {
1815280297Sjkim                    tv.tv_sec = 1;
1816280297Sjkim                    tv.tv_usec = 0;
1817280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1818280297Sjkim                               NULL, &tv);
1819280297Sjkim                } else
1820280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1821280297Sjkim                               NULL, timeoutp);
1822280297Sjkim            }
1823238405Sjkim#elif defined(OPENSSL_SYS_BEOS_R5)
1824280297Sjkim            /* Under BeOS-R5 the situation is similar to DOS */
1825280297Sjkim            i = 0;
1826280297Sjkim            stdin_set = 0;
1827306195Sjkim            (void)fcntl(fileno_stdin(), F_SETFL, O_NONBLOCK);
1828280297Sjkim            if (!write_tty) {
1829280297Sjkim                if (read_tty) {
1830280297Sjkim                    tv.tv_sec = 1;
1831280297Sjkim                    tv.tv_usec = 0;
1832280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1833280297Sjkim                               NULL, &tv);
1834306195Sjkim                    if (read(fileno_stdin(), sbuf, 0) >= 0)
1835280297Sjkim                        stdin_set = 1;
1836280297Sjkim                    if (!i && (stdin_set != 1 || !read_tty))
1837280297Sjkim                        continue;
1838280297Sjkim                } else
1839280297Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1840280297Sjkim                               NULL, timeoutp);
1841280297Sjkim            }
1842306195Sjkim            (void)fcntl(fileno_stdin(), F_SETFL, 0);
184359191Skris#else
1844280297Sjkim            i = select(width, (void *)&readfds, (void *)&writefds,
1845280297Sjkim                       NULL, timeoutp);
184659191Skris#endif
1847280297Sjkim            if (i < 0) {
1848280297Sjkim                BIO_printf(bio_err, "bad select %d\n",
1849280297Sjkim                           get_last_socket_error());
1850280297Sjkim                goto shut;
1851280297Sjkim                /* goto end; */
1852280297Sjkim            }
1853280297Sjkim        }
185455714Skris
1855280297Sjkim        if ((SSL_version(con) == DTLS1_VERSION)
1856280297Sjkim            && DTLSv1_handle_timeout(con) > 0) {
1857280297Sjkim            BIO_printf(bio_err, "TIMEOUT occured\n");
1858280297Sjkim        }
1859205128Ssimon
1860280297Sjkim        if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
1861280297Sjkim            k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len);
1862280297Sjkim            switch (SSL_get_error(con, k)) {
1863280297Sjkim            case SSL_ERROR_NONE:
1864280297Sjkim                cbuf_off += k;
1865280297Sjkim                cbuf_len -= k;
1866280297Sjkim                if (k <= 0)
1867280297Sjkim                    goto end;
1868280297Sjkim                /* we have done a  write(con,NULL,0); */
1869280297Sjkim                if (cbuf_len <= 0) {
1870280297Sjkim                    read_tty = 1;
1871280297Sjkim                    write_ssl = 0;
1872280297Sjkim                } else {        /* if (cbuf_len > 0) */
1873280297Sjkim
1874280297Sjkim                    read_tty = 0;
1875280297Sjkim                    write_ssl = 1;
1876280297Sjkim                }
1877280297Sjkim                break;
1878280297Sjkim            case SSL_ERROR_WANT_WRITE:
1879280297Sjkim                BIO_printf(bio_c_out, "write W BLOCK\n");
1880280297Sjkim                write_ssl = 1;
1881280297Sjkim                read_tty = 0;
1882280297Sjkim                break;
1883280297Sjkim            case SSL_ERROR_WANT_READ:
1884280297Sjkim                BIO_printf(bio_c_out, "write R BLOCK\n");
1885280297Sjkim                write_tty = 0;
1886280297Sjkim                read_ssl = 1;
1887280297Sjkim                write_ssl = 0;
1888280297Sjkim                break;
1889280297Sjkim            case SSL_ERROR_WANT_X509_LOOKUP:
1890280297Sjkim                BIO_printf(bio_c_out, "write X BLOCK\n");
1891280297Sjkim                break;
1892280297Sjkim            case SSL_ERROR_ZERO_RETURN:
1893280297Sjkim                if (cbuf_len != 0) {
1894280297Sjkim                    BIO_printf(bio_c_out, "shutdown\n");
1895280297Sjkim                    ret = 0;
1896280297Sjkim                    goto shut;
1897280297Sjkim                } else {
1898280297Sjkim                    read_tty = 1;
1899280297Sjkim                    write_ssl = 0;
1900280297Sjkim                    break;
1901280297Sjkim                }
1902280297Sjkim
1903280297Sjkim            case SSL_ERROR_SYSCALL:
1904280297Sjkim                if ((k != 0) || (cbuf_len != 0)) {
1905280297Sjkim                    BIO_printf(bio_err, "write:errno=%d\n",
1906280297Sjkim                               get_last_socket_error());
1907280297Sjkim                    goto shut;
1908280297Sjkim                } else {
1909280297Sjkim                    read_tty = 1;
1910280297Sjkim                    write_ssl = 0;
1911280297Sjkim                }
1912280297Sjkim                break;
1913280297Sjkim            case SSL_ERROR_SSL:
1914280297Sjkim                ERR_print_errors(bio_err);
1915280297Sjkim                goto shut;
1916280297Sjkim            }
1917280297Sjkim        }
1918306195Sjkim#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5) || defined(OPENSSL_SYS_VMS)
1919280297Sjkim        /* Assume Windows/DOS/BeOS can always write */
1920280297Sjkim        else if (!ssl_pending && write_tty)
192159191Skris#else
1922306195Sjkim        else if (!ssl_pending && FD_ISSET(fileno_stdout(), &writefds))
192359191Skris#endif
1924280297Sjkim        {
192555714Skris#ifdef CHARSET_EBCDIC
1926280297Sjkim            ascii2ebcdic(&(sbuf[sbuf_off]), &(sbuf[sbuf_off]), sbuf_len);
192755714Skris#endif
1928280297Sjkim            i = raw_write_stdout(&(sbuf[sbuf_off]), sbuf_len);
192955714Skris
1930280297Sjkim            if (i <= 0) {
1931280297Sjkim                BIO_printf(bio_c_out, "DONE\n");
1932280297Sjkim                ret = 0;
1933280297Sjkim                goto shut;
1934280297Sjkim                /* goto end; */
1935280297Sjkim            }
193655714Skris
1937280297Sjkim            sbuf_len -= i;;
1938280297Sjkim            sbuf_off += i;
1939280297Sjkim            if (sbuf_len <= 0) {
1940280297Sjkim                read_ssl = 1;
1941280297Sjkim                write_tty = 0;
1942280297Sjkim            }
1943280297Sjkim        } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) {
194455714Skris#ifdef RENEG
1945280297Sjkim            {
1946280297Sjkim                static int iiii;
1947280297Sjkim                if (++iiii == 52) {
1948280297Sjkim                    SSL_renegotiate(con);
1949280297Sjkim                    iiii = 0;
1950280297Sjkim                }
1951280297Sjkim            }
195255714Skris#endif
195355714Skris#if 1
1954280297Sjkim            k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ );
195555714Skris#else
195655714Skris/* Demo for pending and peek :-) */
1957280297Sjkim            k = SSL_read(con, sbuf, 16);
1958280297Sjkim            {
1959280297Sjkim                char zbuf[10240];
1960280297Sjkim                printf("read=%d pending=%d peek=%d\n", k, SSL_pending(con),
1961280297Sjkim                       SSL_peek(con, zbuf, 10240));
1962280297Sjkim            }
196355714Skris#endif
196455714Skris
1965280297Sjkim            switch (SSL_get_error(con, k)) {
1966280297Sjkim            case SSL_ERROR_NONE:
1967280297Sjkim                if (k <= 0)
1968280297Sjkim                    goto end;
1969280297Sjkim                sbuf_off = 0;
1970280297Sjkim                sbuf_len = k;
197155714Skris
1972280297Sjkim                read_ssl = 0;
1973280297Sjkim                write_tty = 1;
1974280297Sjkim                break;
1975280297Sjkim            case SSL_ERROR_WANT_WRITE:
1976280297Sjkim                BIO_printf(bio_c_out, "read W BLOCK\n");
1977280297Sjkim                write_ssl = 1;
1978280297Sjkim                read_tty = 0;
1979280297Sjkim                break;
1980280297Sjkim            case SSL_ERROR_WANT_READ:
1981280297Sjkim                BIO_printf(bio_c_out, "read R BLOCK\n");
1982280297Sjkim                write_tty = 0;
1983280297Sjkim                read_ssl = 1;
1984280297Sjkim                if ((read_tty == 0) && (write_ssl == 0))
1985280297Sjkim                    write_ssl = 1;
1986280297Sjkim                break;
1987280297Sjkim            case SSL_ERROR_WANT_X509_LOOKUP:
1988280297Sjkim                BIO_printf(bio_c_out, "read X BLOCK\n");
1989280297Sjkim                break;
1990280297Sjkim            case SSL_ERROR_SYSCALL:
1991280297Sjkim                ret = get_last_socket_error();
1992290207Sjkim                if (c_brief)
1993290207Sjkim                    BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n");
1994290207Sjkim                else
1995290207Sjkim                    BIO_printf(bio_err, "read:errno=%d\n", ret);
1996280297Sjkim                goto shut;
1997280297Sjkim            case SSL_ERROR_ZERO_RETURN:
1998280297Sjkim                BIO_printf(bio_c_out, "closed\n");
1999280297Sjkim                ret = 0;
2000280297Sjkim                goto shut;
2001280297Sjkim            case SSL_ERROR_SSL:
2002280297Sjkim                ERR_print_errors(bio_err);
2003280297Sjkim                goto shut;
2004280297Sjkim                /* break; */
2005280297Sjkim            }
2006280297Sjkim        }
2007120631Snectar#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
2008280297Sjkim# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
2009280297Sjkim        else if (_kbhit())
2010280297Sjkim# else
2011280297Sjkim        else if ((_kbhit())
2012280297Sjkim                 || (WAIT_OBJECT_0 ==
2013280297Sjkim                     WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
2014280297Sjkim# endif
2015160814Ssimon#elif defined (OPENSSL_SYS_NETWARE)
2016280297Sjkim        else if (_kbhit())
2017238405Sjkim#elif defined(OPENSSL_SYS_BEOS_R5)
2018280297Sjkim        else if (stdin_set)
201959191Skris#else
2020306195Sjkim        else if (FD_ISSET(fileno_stdin(), &readfds))
202159191Skris#endif
2022280297Sjkim        {
2023280297Sjkim            if (crlf) {
2024280297Sjkim                int j, lf_num;
202555714Skris
2026280297Sjkim                i = raw_read_stdin(cbuf, BUFSIZZ / 2);
2027280297Sjkim                lf_num = 0;
2028280297Sjkim                /* both loops are skipped when i <= 0 */
2029280297Sjkim                for (j = 0; j < i; j++)
2030280297Sjkim                    if (cbuf[j] == '\n')
2031280297Sjkim                        lf_num++;
2032280297Sjkim                for (j = i - 1; j >= 0; j--) {
2033280297Sjkim                    cbuf[j + lf_num] = cbuf[j];
2034280297Sjkim                    if (cbuf[j] == '\n') {
2035280297Sjkim                        lf_num--;
2036280297Sjkim                        i++;
2037280297Sjkim                        cbuf[j + lf_num] = '\r';
2038280297Sjkim                    }
2039280297Sjkim                }
2040280297Sjkim                assert(lf_num == 0);
2041280297Sjkim            } else
2042280297Sjkim                i = raw_read_stdin(cbuf, BUFSIZZ);
204355714Skris
2044280297Sjkim            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) {
2045280297Sjkim                BIO_printf(bio_err, "DONE\n");
2046280297Sjkim                ret = 0;
2047280297Sjkim                goto shut;
2048280297Sjkim            }
204955714Skris
2050280297Sjkim            if ((!c_ign_eof) && (cbuf[0] == 'R')) {
2051280297Sjkim                BIO_printf(bio_err, "RENEGOTIATING\n");
2052280297Sjkim                SSL_renegotiate(con);
2053280297Sjkim                cbuf_len = 0;
2054280297Sjkim            }
2055238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS
2056280297Sjkim            else if ((!c_ign_eof) && (cbuf[0] == 'B')) {
2057280297Sjkim                BIO_printf(bio_err, "HEARTBEATING\n");
2058280297Sjkim                SSL_heartbeat(con);
2059280297Sjkim                cbuf_len = 0;
2060280297Sjkim            }
2061238405Sjkim#endif
2062280297Sjkim            else {
2063280297Sjkim                cbuf_len = i;
2064280297Sjkim                cbuf_off = 0;
206555714Skris#ifdef CHARSET_EBCDIC
2066280297Sjkim                ebcdic2ascii(cbuf, cbuf, i);
206755714Skris#endif
2068280297Sjkim            }
206955714Skris
2070280297Sjkim            write_ssl = 1;
2071280297Sjkim            read_tty = 0;
2072280297Sjkim        }
2073280297Sjkim    }
2074238405Sjkim
2075280297Sjkim    ret = 0;
2076280297Sjkim shut:
2077280297Sjkim    if (in_init)
2078280297Sjkim        print_stuff(bio_c_out, con, full_log);
2079280297Sjkim    SSL_shutdown(con);
2080280297Sjkim    SHUTDOWN(SSL_get_fd(con));
2081280297Sjkim end:
2082280297Sjkim    if (con != NULL) {
2083280297Sjkim        if (prexit != 0)
2084280297Sjkim            print_stuff(bio_c_out, con, 1);
2085280297Sjkim        SSL_free(con);
2086280297Sjkim    }
2087246772Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
2088280297Sjkim    if (next_proto.data)
2089280297Sjkim        OPENSSL_free(next_proto.data);
2090246772Sjkim#endif
2091280297Sjkim    if (ctx != NULL)
2092280297Sjkim        SSL_CTX_free(ctx);
2093280297Sjkim    if (cert)
2094280297Sjkim        X509_free(cert);
2095290207Sjkim    if (crls)
2096290207Sjkim        sk_X509_CRL_pop_free(crls, X509_CRL_free);
2097280297Sjkim    if (key)
2098280297Sjkim        EVP_PKEY_free(key);
2099290207Sjkim    if (chain)
2100290207Sjkim        sk_X509_pop_free(chain, X509_free);
2101280297Sjkim    if (pass)
2102280297Sjkim        OPENSSL_free(pass);
2103291719Sjkim#ifndef OPENSSL_NO_SRP
2104291719Sjkim    OPENSSL_free(srp_arg.srppassin);
2105291719Sjkim#endif
2106280297Sjkim    if (vpm)
2107280297Sjkim        X509_VERIFY_PARAM_free(vpm);
2108290207Sjkim    ssl_excert_free(exc);
2109290207Sjkim    if (ssl_args)
2110290207Sjkim        sk_OPENSSL_STRING_free(ssl_args);
2111290207Sjkim    if (cctx)
2112290207Sjkim        SSL_CONF_CTX_free(cctx);
2113290207Sjkim#ifndef OPENSSL_NO_JPAKE
2114290207Sjkim    if (jpake_secret && psk_key)
2115290207Sjkim        OPENSSL_free(psk_key);
2116290207Sjkim#endif
2117280297Sjkim    if (cbuf != NULL) {
2118280297Sjkim        OPENSSL_cleanse(cbuf, BUFSIZZ);
2119280297Sjkim        OPENSSL_free(cbuf);
2120280297Sjkim    }
2121280297Sjkim    if (sbuf != NULL) {
2122280297Sjkim        OPENSSL_cleanse(sbuf, BUFSIZZ);
2123280297Sjkim        OPENSSL_free(sbuf);
2124280297Sjkim    }
2125280297Sjkim    if (mbuf != NULL) {
2126280297Sjkim        OPENSSL_cleanse(mbuf, BUFSIZZ);
2127280297Sjkim        OPENSSL_free(mbuf);
2128280297Sjkim    }
2129312826Sjkim    release_engine(e);
2130280297Sjkim    if (bio_c_out != NULL) {
2131280297Sjkim        BIO_free(bio_c_out);
2132280297Sjkim        bio_c_out = NULL;
2133280297Sjkim    }
2134290207Sjkim    if (bio_c_msg != NULL) {
2135290207Sjkim        BIO_free(bio_c_msg);
2136290207Sjkim        bio_c_msg = NULL;
2137290207Sjkim    }
2138325335Sjkim    SSL_COMP_free_compression_methods();
2139280297Sjkim    apps_shutdown();
2140280297Sjkim    OPENSSL_EXIT(ret);
2141280297Sjkim}
214255714Skris
214355714Skrisstatic void print_stuff(BIO *bio, SSL *s, int full)
2144280297Sjkim{
2145280297Sjkim    X509 *peer = NULL;
2146280297Sjkim    char *p;
2147280297Sjkim    static const char *space = "                ";
2148280297Sjkim    char buf[BUFSIZ];
2149280297Sjkim    STACK_OF(X509) *sk;
2150280297Sjkim    STACK_OF(X509_NAME) *sk2;
2151280297Sjkim    const SSL_CIPHER *c;
2152280297Sjkim    X509_NAME *xn;
2153280297Sjkim    int j, i;
2154160814Ssimon#ifndef OPENSSL_NO_COMP
2155280297Sjkim    const COMP_METHOD *comp, *expansion;
2156160814Ssimon#endif
2157280297Sjkim    unsigned char *exportedkeymat;
215855714Skris
2159280297Sjkim    if (full) {
2160280297Sjkim        int got_a_chain = 0;
216155714Skris
2162280297Sjkim        sk = SSL_get_peer_cert_chain(s);
2163280297Sjkim        if (sk != NULL) {
2164280297Sjkim            got_a_chain = 1;    /* we don't have it for SSL2 (yet) */
216555714Skris
2166280297Sjkim            BIO_printf(bio, "---\nCertificate chain\n");
2167280297Sjkim            for (i = 0; i < sk_X509_num(sk); i++) {
2168280297Sjkim                X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)),
2169331638Sjkim                                  buf, sizeof(buf));
2170280297Sjkim                BIO_printf(bio, "%2d s:%s\n", i, buf);
2171280297Sjkim                X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)),
2172331638Sjkim                                  buf, sizeof(buf));
2173280297Sjkim                BIO_printf(bio, "   i:%s\n", buf);
2174280297Sjkim                if (c_showcerts)
2175280297Sjkim                    PEM_write_bio_X509(bio, sk_X509_value(sk, i));
2176280297Sjkim            }
2177280297Sjkim        }
217855714Skris
2179280297Sjkim        BIO_printf(bio, "---\n");
2180280297Sjkim        peer = SSL_get_peer_certificate(s);
2181280297Sjkim        if (peer != NULL) {
2182280297Sjkim            BIO_printf(bio, "Server certificate\n");
218355714Skris
2184280297Sjkim            /* Redundant if we showed the whole chain */
2185280297Sjkim            if (!(c_showcerts && got_a_chain))
2186280297Sjkim                PEM_write_bio_X509(bio, peer);
2187331638Sjkim            X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf));
2188280297Sjkim            BIO_printf(bio, "subject=%s\n", buf);
2189331638Sjkim            X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf));
2190280297Sjkim            BIO_printf(bio, "issuer=%s\n", buf);
2191280297Sjkim        } else
2192280297Sjkim            BIO_printf(bio, "no peer certificate available\n");
219355714Skris
2194280297Sjkim        sk2 = SSL_get_client_CA_list(s);
2195280297Sjkim        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
2196280297Sjkim            BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
2197280297Sjkim            for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
2198280297Sjkim                xn = sk_X509_NAME_value(sk2, i);
2199280297Sjkim                X509_NAME_oneline(xn, buf, sizeof(buf));
2200280297Sjkim                BIO_write(bio, buf, strlen(buf));
2201280297Sjkim                BIO_write(bio, "\n", 1);
2202280297Sjkim            }
2203280297Sjkim        } else {
2204280297Sjkim            BIO_printf(bio, "---\nNo client certificate CA names sent\n");
2205280297Sjkim        }
2206331638Sjkim        p = SSL_get_shared_ciphers(s, buf, sizeof(buf));
2207280297Sjkim        if (p != NULL) {
2208280297Sjkim            /*
2209280297Sjkim             * This works only for SSL 2.  In later protocol versions, the
2210280297Sjkim             * client does not know what other ciphers (in addition to the
2211280297Sjkim             * one to be used in the current connection) the server supports.
2212280297Sjkim             */
221355714Skris
2214280297Sjkim            BIO_printf(bio,
2215280297Sjkim                       "---\nCiphers common between both SSL endpoints:\n");
2216280297Sjkim            j = i = 0;
2217280297Sjkim            while (*p) {
2218280297Sjkim                if (*p == ':') {
2219280297Sjkim                    BIO_write(bio, space, 15 - j % 25);
2220280297Sjkim                    i++;
2221280297Sjkim                    j = 0;
2222280297Sjkim                    BIO_write(bio, ((i % 3) ? " " : "\n"), 1);
2223280297Sjkim                } else {
2224280297Sjkim                    BIO_write(bio, p, 1);
2225280297Sjkim                    j++;
2226280297Sjkim                }
2227280297Sjkim                p++;
2228280297Sjkim            }
2229280297Sjkim            BIO_write(bio, "\n", 1);
2230280297Sjkim        }
2231280297Sjkim
2232290207Sjkim        ssl_print_sigalgs(bio, s);
2233290207Sjkim        ssl_print_tmp_key(bio, s);
2234290207Sjkim
2235280297Sjkim        BIO_printf(bio,
2236280297Sjkim                   "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
2237280297Sjkim                   BIO_number_read(SSL_get_rbio(s)),
2238280297Sjkim                   BIO_number_written(SSL_get_wbio(s)));
2239280297Sjkim    }
2240280297Sjkim    BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
2241280297Sjkim    c = SSL_get_current_cipher(s);
2242280297Sjkim    BIO_printf(bio, "%s, Cipher is %s\n",
2243280297Sjkim               SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
2244280297Sjkim    if (peer != NULL) {
2245280297Sjkim        EVP_PKEY *pktmp;
2246280297Sjkim        pktmp = X509_get_pubkey(peer);
2247280297Sjkim        BIO_printf(bio, "Server public key is %d bit\n",
2248280297Sjkim                   EVP_PKEY_bits(pktmp));
2249280297Sjkim        EVP_PKEY_free(pktmp);
2250280297Sjkim    }
2251280297Sjkim    BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
2252280297Sjkim               SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
2253160814Ssimon#ifndef OPENSSL_NO_COMP
2254280297Sjkim    comp = SSL_get_current_compression(s);
2255280297Sjkim    expansion = SSL_get_current_expansion(s);
2256280297Sjkim    BIO_printf(bio, "Compression: %s\n",
2257280297Sjkim               comp ? SSL_COMP_get_name(comp) : "NONE");
2258280297Sjkim    BIO_printf(bio, "Expansion: %s\n",
2259280297Sjkim               expansion ? SSL_COMP_get_name(expansion) : "NONE");
2260160814Ssimon#endif
2261280297Sjkim
2262238405Sjkim#ifdef SSL_DEBUG
2263280297Sjkim    {
2264280297Sjkim        /* Print out local port of connection: useful for debugging */
2265280297Sjkim        int sock;
2266280297Sjkim        struct sockaddr_in ladd;
2267280297Sjkim        socklen_t ladd_size = sizeof(ladd);
2268280297Sjkim        sock = SSL_get_fd(s);
2269280297Sjkim        getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
2270280297Sjkim        BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
2271280297Sjkim    }
2272238405Sjkim#endif
2273238405Sjkim
2274290207Sjkim#if !defined(OPENSSL_NO_TLSEXT)
2275290207Sjkim# if !defined(OPENSSL_NO_NEXTPROTONEG)
2276280297Sjkim    if (next_proto.status != -1) {
2277280297Sjkim        const unsigned char *proto;
2278280297Sjkim        unsigned int proto_len;
2279280297Sjkim        SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
2280280297Sjkim        BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
2281280297Sjkim        BIO_write(bio, proto, proto_len);
2282280297Sjkim        BIO_write(bio, "\n", 1);
2283280297Sjkim    }
2284290207Sjkim# endif
2285290207Sjkim    {
2286290207Sjkim        const unsigned char *proto;
2287290207Sjkim        unsigned int proto_len;
2288290207Sjkim        SSL_get0_alpn_selected(s, &proto, &proto_len);
2289290207Sjkim        if (proto_len > 0) {
2290290207Sjkim            BIO_printf(bio, "ALPN protocol: ");
2291290207Sjkim            BIO_write(bio, proto, proto_len);
2292290207Sjkim            BIO_write(bio, "\n", 1);
2293290207Sjkim        } else
2294290207Sjkim            BIO_printf(bio, "No ALPN negotiated\n");
2295290207Sjkim    }
2296238405Sjkim#endif
2297238405Sjkim
2298246772Sjkim#ifndef OPENSSL_NO_SRTP
2299280297Sjkim    {
2300280297Sjkim        SRTP_PROTECTION_PROFILE *srtp_profile =
2301280297Sjkim            SSL_get_selected_srtp_profile(s);
2302280297Sjkim
2303280297Sjkim        if (srtp_profile)
2304280297Sjkim            BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n",
2305280297Sjkim                       srtp_profile->name);
2306280297Sjkim    }
2307246772Sjkim#endif
230855714Skris
2309280297Sjkim    SSL_SESSION_print(bio, SSL_get_session(s));
2310280297Sjkim    if (keymatexportlabel != NULL) {
2311280297Sjkim        BIO_printf(bio, "Keying material exporter:\n");
2312280297Sjkim        BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
2313280297Sjkim        BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
2314280297Sjkim        exportedkeymat = OPENSSL_malloc(keymatexportlen);
2315280297Sjkim        if (exportedkeymat != NULL) {
2316280297Sjkim            if (!SSL_export_keying_material(s, exportedkeymat,
2317280297Sjkim                                            keymatexportlen,
2318280297Sjkim                                            keymatexportlabel,
2319280297Sjkim                                            strlen(keymatexportlabel),
2320280297Sjkim                                            NULL, 0, 0)) {
2321280297Sjkim                BIO_printf(bio, "    Error\n");
2322280297Sjkim            } else {
2323280297Sjkim                BIO_printf(bio, "    Keying material: ");
2324280297Sjkim                for (i = 0; i < keymatexportlen; i++)
2325280297Sjkim                    BIO_printf(bio, "%02X", exportedkeymat[i]);
2326280297Sjkim                BIO_printf(bio, "\n");
2327280297Sjkim            }
2328280297Sjkim            OPENSSL_free(exportedkeymat);
2329280297Sjkim        }
2330280297Sjkim    }
2331280297Sjkim    BIO_printf(bio, "---\n");
2332280297Sjkim    if (peer != NULL)
2333280297Sjkim        X509_free(peer);
2334280297Sjkim    /* flush, or debugging output gets mixed with http response */
2335280297Sjkim    (void)BIO_flush(bio);
2336280297Sjkim}
2337280297Sjkim
2338194206Ssimon#ifndef OPENSSL_NO_TLSEXT
2339194206Ssimon
2340194206Ssimonstatic int ocsp_resp_cb(SSL *s, void *arg)
2341280297Sjkim{
2342280297Sjkim    const unsigned char *p;
2343280297Sjkim    int len;
2344280297Sjkim    OCSP_RESPONSE *rsp;
2345280297Sjkim    len = SSL_get_tlsext_status_ocsp_resp(s, &p);
2346280297Sjkim    BIO_puts(arg, "OCSP response: ");
2347280297Sjkim    if (!p) {
2348280297Sjkim        BIO_puts(arg, "no response sent\n");
2349280297Sjkim        return 1;
2350280297Sjkim    }
2351280297Sjkim    rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
2352280297Sjkim    if (!rsp) {
2353280297Sjkim        BIO_puts(arg, "response parse error\n");
2354280297Sjkim        BIO_dump_indent(arg, (char *)p, len, 4);
2355280297Sjkim        return 0;
2356280297Sjkim    }
2357280297Sjkim    BIO_puts(arg, "\n======================================\n");
2358280297Sjkim    OCSP_RESPONSE_print(arg, rsp, 0);
2359280297Sjkim    BIO_puts(arg, "======================================\n");
2360280297Sjkim    OCSP_RESPONSE_free(rsp);
2361280297Sjkim    return 1;
2362280297Sjkim}
2363238405Sjkim
2364238405Sjkim#endif
2365