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.
8280304Sjkim *
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).
15280304Sjkim *
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.
22280304Sjkim *
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 :-).
37280304Sjkim * 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)"
40280304Sjkim *
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.
52280304Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
58109998Smarkm/* ====================================================================
59238405Sjkim * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60109998Smarkm *
61109998Smarkm * Redistribution and use in source and binary forms, with or without
62109998Smarkm * modification, are permitted provided that the following conditions
63109998Smarkm * are met:
64109998Smarkm *
65109998Smarkm * 1. Redistributions of source code must retain the above copyright
66280304Sjkim *    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
145280304Sjkim# define APPS_WIN16
14655714Skris#endif
14755714Skris
148280304Sjkim/*
149280304Sjkim * With IPv6, it looks like Digital has mixed up the proper order of
150280304Sjkim * recursive header file inclusion, resulting in the compiler complaining
151280304Sjkim * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
152280304Sjkim * needed to have fileno() declared correctly...  So let's define u_int
153280304Sjkim */
154109998Smarkm#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
155280304Sjkim# 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
169280304Sjkim# 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 */
176280304Sjkim# undef FIONBIO
17755714Skris#endif
17855714Skris
179238405Sjkim#if defined(OPENSSL_SYS_BEOS_R5)
180280304Sjkim# include <fcntl.h>
181238405Sjkim#endif
182238405Sjkim
18355714Skris#undef PROG
184280304Sjkim#define PROG    s_client_main
18555714Skris
186280304Sjkim/*
187280304Sjkim * #define SSL_HOST_NAME "www.netscape.com"
188280304Sjkim */
189280304Sjkim/*
190280304Sjkim * #define SSL_HOST_NAME "193.118.187.102"
191280304Sjkim */
192280304Sjkim#define SSL_HOST_NAME   "localhost"
19355714Skris
194280304Sjkim/* no default cert. */
195280304Sjkim/*
196280304Sjkim * #define TEST_CERT "client.pem"
197280304Sjkim */
19855714Skris
19955714Skris#undef BUFSIZZ
20055714Skris#define BUFSIZZ 1024*8
20155714Skris
20255714Skrisextern int verify_depth;
20355714Skrisextern int verify_error;
204238405Sjkimextern int verify_return_error;
20555714Skris
20655714Skris#ifdef FIONBIO
207280304Sjkimstatic int c_nbio = 0;
20855714Skris#endif
209280304Sjkimstatic int c_Pause = 0;
210280304Sjkimstatic int c_debug = 0;
211194206Ssimon#ifndef OPENSSL_NO_TLSEXT
212280304Sjkimstatic int c_tlsextdebug = 0;
213280304Sjkimstatic int c_status_req = 0;
214194206Ssimon#endif
215280304Sjkimstatic int c_msg = 0;
216280304Sjkimstatic int c_showcerts = 0;
21755714Skris
218280304Sjkimstatic char *keymatexportlabel = NULL;
219280304Sjkimstatic int keymatexportlen = 20;
220238405Sjkim
22155714Skrisstatic void sc_usage(void);
222280304Sjkimstatic void print_stuff(BIO *berr, SSL *con, int full);
223194206Ssimon#ifndef OPENSSL_NO_TLSEXT
224194206Ssimonstatic int ocsp_resp_cb(SSL *s, void *arg);
225194206Ssimon#endif
226280304Sjkimstatic BIO *bio_c_out = NULL;
227280304Sjkimstatic int c_quiet = 0;
228280304Sjkimstatic int c_ign_eof = 0;
22955714Skris
230238405Sjkim#ifndef OPENSSL_NO_PSK
231238405Sjkim/* Default PSK identity and key */
232280304Sjkimstatic char *psk_identity = "Client_identity";
233280304Sjkim/*
234280304Sjkim * char *psk_key=NULL; by default PSK is not used
235280304Sjkim */
236238405Sjkim
237238405Sjkimstatic unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
238280304Sjkim                                  unsigned int max_identity_len,
239280304Sjkim                                  unsigned char *psk,
240280304Sjkim                                  unsigned int max_psk_len)
241280304Sjkim{
242280304Sjkim    unsigned int psk_len = 0;
243280304Sjkim    int ret;
244280304Sjkim    BIGNUM *bn = NULL;
245238405Sjkim
246280304Sjkim    if (c_debug)
247280304Sjkim        BIO_printf(bio_c_out, "psk_client_cb\n");
248280304Sjkim    if (!hint) {
249280304Sjkim        /* no ServerKeyExchange message */
250280304Sjkim        if (c_debug)
251280304Sjkim            BIO_printf(bio_c_out,
252280304Sjkim                       "NULL received PSK identity hint, continuing anyway\n");
253280304Sjkim    } else if (c_debug)
254280304Sjkim        BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
255238405Sjkim
256280304Sjkim    /*
257280304Sjkim     * lookup PSK identity and PSK key based on the given identity hint here
258280304Sjkim     */
259280304Sjkim    ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
260280304Sjkim    if (ret < 0 || (unsigned int)ret > max_identity_len)
261280304Sjkim        goto out_err;
262280304Sjkim    if (c_debug)
263280304Sjkim        BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity,
264280304Sjkim                   ret);
265280304Sjkim    ret = BN_hex2bn(&bn, psk_key);
266280304Sjkim    if (!ret) {
267280304Sjkim        BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n",
268280304Sjkim                   psk_key);
269280304Sjkim        if (bn)
270280304Sjkim            BN_free(bn);
271280304Sjkim        return 0;
272280304Sjkim    }
273238405Sjkim
274280304Sjkim    if ((unsigned int)BN_num_bytes(bn) > max_psk_len) {
275280304Sjkim        BIO_printf(bio_err,
276280304Sjkim                   "psk buffer of callback is too small (%d) for key (%d)\n",
277280304Sjkim                   max_psk_len, BN_num_bytes(bn));
278238405Sjkim        BN_free(bn);
279280304Sjkim        return 0;
280280304Sjkim    }
281238405Sjkim
282280304Sjkim    psk_len = BN_bn2bin(bn, psk);
283280304Sjkim    BN_free(bn);
284280304Sjkim    if (psk_len == 0)
285280304Sjkim        goto out_err;
286238405Sjkim
287280304Sjkim    if (c_debug)
288280304Sjkim        BIO_printf(bio_c_out, "created PSK len=%d\n", psk_len);
289280304Sjkim
290280304Sjkim    return psk_len;
291238405Sjkim out_err:
292280304Sjkim    if (c_debug)
293280304Sjkim        BIO_printf(bio_err, "Error in PSK client callback\n");
294280304Sjkim    return 0;
295280304Sjkim}
296238405Sjkim#endif
297238405Sjkim
29855714Skrisstatic void sc_usage(void)
299280304Sjkim{
300280304Sjkim    BIO_printf(bio_err, "usage: s_client args\n");
301280304Sjkim    BIO_printf(bio_err, "\n");
302280304Sjkim    BIO_printf(bio_err, " -host host     - use -connect instead\n");
303280304Sjkim    BIO_printf(bio_err, " -port port     - use -connect instead\n");
304280304Sjkim    BIO_printf(bio_err,
305280304Sjkim               " -connect host:port - who to connect to (default is %s:%s)\n",
306280304Sjkim               SSL_HOST_NAME, PORT_STR);
30755714Skris
308280304Sjkim    BIO_printf(bio_err,
309280304Sjkim               " -verify arg   - turn on peer certificate verification\n");
310280304Sjkim    BIO_printf(bio_err,
311280304Sjkim               " -verify_return_error - return verification errors\n");
312280304Sjkim    BIO_printf(bio_err,
313280304Sjkim               " -cert arg     - certificate file to use, PEM format assumed\n");
314280304Sjkim    BIO_printf(bio_err,
315280304Sjkim               " -certform arg - certificate format (PEM or DER) PEM default\n");
316280304Sjkim    BIO_printf(bio_err,
317280304Sjkim               " -key arg      - Private key file to use, in cert file if\n");
318280304Sjkim    BIO_printf(bio_err, "                 not specified but cert file is.\n");
319280304Sjkim    BIO_printf(bio_err,
320280304Sjkim               " -keyform arg  - key format (PEM or DER) PEM default\n");
321280304Sjkim    BIO_printf(bio_err,
322280304Sjkim               " -pass arg     - private key file pass phrase source\n");
323280304Sjkim    BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
324280304Sjkim    BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
325280304Sjkim    BIO_printf(bio_err,
326284285Sjkim               " -no_alt_chains - only ever use the first certificate chain found\n");
327284285Sjkim    BIO_printf(bio_err,
328280304Sjkim               " -reconnect    - Drop and re-make the connection with the same Session-ID\n");
329280304Sjkim    BIO_printf(bio_err,
330280304Sjkim               " -pause        - sleep(1) after each read(2) and write(2) system call\n");
331280304Sjkim    BIO_printf(bio_err,
332280304Sjkim               " -prexit       - print session information even on connection failure\n");
333280304Sjkim    BIO_printf(bio_err,
334280304Sjkim               " -showcerts    - show all certificates in the chain\n");
335280304Sjkim    BIO_printf(bio_err, " -debug        - extra output\n");
336160814Ssimon#ifdef WATT32
337280304Sjkim    BIO_printf(bio_err, " -wdebug       - WATT-32 tcp debugging\n");
338160814Ssimon#endif
339280304Sjkim    BIO_printf(bio_err, " -msg          - Show protocol messages\n");
340280304Sjkim    BIO_printf(bio_err, " -nbio_test    - more ssl protocol testing\n");
341280304Sjkim    BIO_printf(bio_err, " -state        - print the 'ssl' states\n");
34255714Skris#ifdef FIONBIO
343280304Sjkim    BIO_printf(bio_err, " -nbio         - Run with non-blocking IO\n");
34455714Skris#endif
345280304Sjkim    BIO_printf(bio_err,
346280304Sjkim               " -crlf         - convert LF from terminal into CRLF\n");
347280304Sjkim    BIO_printf(bio_err, " -quiet        - no s_client output\n");
348280304Sjkim    BIO_printf(bio_err,
349280304Sjkim               " -ign_eof      - ignore input eof (default when -quiet)\n");
350280304Sjkim    BIO_printf(bio_err, " -no_ign_eof   - don't ignore input eof\n");
351238405Sjkim#ifndef OPENSSL_NO_PSK
352280304Sjkim    BIO_printf(bio_err, " -psk_identity arg - PSK identity\n");
353280304Sjkim    BIO_printf(bio_err, " -psk arg      - PSK in hex (without 0x)\n");
354238405Sjkim# ifndef OPENSSL_NO_JPAKE
355280304Sjkim    BIO_printf(bio_err, " -jpake arg    - JPAKE secret to use\n");
356238405Sjkim# endif
357238405Sjkim#endif
358238405Sjkim#ifndef OPENSSL_NO_SRP
359280304Sjkim    BIO_printf(bio_err,
360280304Sjkim               " -srpuser user     - SRP authentification for 'user'\n");
361280304Sjkim    BIO_printf(bio_err, " -srppass arg      - password for 'user'\n");
362280304Sjkim    BIO_printf(bio_err,
363280304Sjkim               " -srp_lateuser     - SRP username into second ClientHello message\n");
364280304Sjkim    BIO_printf(bio_err,
365280304Sjkim               " -srp_moregroups   - Tolerate other than the known g N values.\n");
366280304Sjkim    BIO_printf(bio_err,
367280304Sjkim               " -srp_strength int - minimal length in bits for N (default %d).\n",
368280304Sjkim               SRP_MINIMAL_N);
369238405Sjkim#endif
370280304Sjkim    BIO_printf(bio_err, " -ssl2         - just use SSLv2\n");
371276864Sjkim#ifndef OPENSSL_NO_SSL3_METHOD
372280304Sjkim    BIO_printf(bio_err, " -ssl3         - just use SSLv3\n");
373276864Sjkim#endif
374280304Sjkim    BIO_printf(bio_err, " -tls1_2       - just use TLSv1.2\n");
375280304Sjkim    BIO_printf(bio_err, " -tls1_1       - just use TLSv1.1\n");
376280304Sjkim    BIO_printf(bio_err, " -tls1         - just use TLSv1\n");
377280304Sjkim    BIO_printf(bio_err, " -dtls1        - just use DTLSv1\n");
378280304Sjkim    BIO_printf(bio_err, " -fallback_scsv - send TLS_FALLBACK_SCSV\n");
379280304Sjkim    BIO_printf(bio_err, " -mtu          - set the link layer MTU\n");
380280304Sjkim    BIO_printf(bio_err,
381280304Sjkim               " -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
382280304Sjkim    BIO_printf(bio_err,
383280304Sjkim               " -bugs         - Switch on all SSL implementation bug workarounds\n");
384280304Sjkim    BIO_printf(bio_err,
385280304Sjkim               " -serverpref   - Use server's cipher preferences (only SSLv2)\n");
386280304Sjkim    BIO_printf(bio_err,
387280304Sjkim               " -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
388280304Sjkim    BIO_printf(bio_err,
389280304Sjkim               "                 command to see what is available\n");
390280304Sjkim    BIO_printf(bio_err,
391280304Sjkim               " -starttls prot - use the STARTTLS command before starting TLS\n");
392280304Sjkim    BIO_printf(bio_err,
393280304Sjkim               "                 for those protocols that support it, where\n");
394280304Sjkim    BIO_printf(bio_err,
395280304Sjkim               "                 'prot' defines which one to assume.  Currently,\n");
396280304Sjkim    BIO_printf(bio_err,
397280304Sjkim               "                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
398280304Sjkim    BIO_printf(bio_err, "                 are supported.\n");
399111147Snectar#ifndef OPENSSL_NO_ENGINE
400280304Sjkim    BIO_printf(bio_err,
401280304Sjkim               " -engine id    - Initialise and use the specified engine\n");
402111147Snectar#endif
403280304Sjkim    BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
404280304Sjkim               LIST_SEPARATOR_CHAR);
405280304Sjkim    BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n");
406280304Sjkim    BIO_printf(bio_err, " -sess_in arg  - file to read SSL session from\n");
407194206Ssimon#ifndef OPENSSL_NO_TLSEXT
408280304Sjkim    BIO_printf(bio_err,
409280304Sjkim               " -servername host  - Set TLS extension servername in ClientHello\n");
410280304Sjkim    BIO_printf(bio_err,
411280304Sjkim               " -tlsextdebug      - hex dump of all TLS extensions received\n");
412280304Sjkim    BIO_printf(bio_err,
413280304Sjkim               " -status           - request certificate status from server\n");
414280304Sjkim    BIO_printf(bio_err,
415280304Sjkim               " -no_ticket        - disable use of RFC4507bis session tickets\n");
416246772Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
417280304Sjkim    BIO_printf(bio_err,
418280304Sjkim               " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
419238405Sjkim# endif
420194206Ssimon#endif
421280304Sjkim    BIO_printf(bio_err,
422280304Sjkim               " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
423246772Sjkim#ifndef OPENSSL_NO_SRTP
424280304Sjkim    BIO_printf(bio_err,
425280304Sjkim               " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
426246772Sjkim#endif
427280304Sjkim    BIO_printf(bio_err,
428280304Sjkim               " -keymatexport label   - Export keying material using label\n");
429280304Sjkim    BIO_printf(bio_err,
430280304Sjkim               " -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
431280304Sjkim}
43255714Skris
433194206Ssimon#ifndef OPENSSL_NO_TLSEXT
434194206Ssimon
435194206Ssimon/* This is a context that we pass to callbacks */
436194206Ssimontypedef struct tlsextctx_st {
437280304Sjkim    BIO *biodebug;
438280304Sjkim    int ack;
439194206Ssimon} tlsextctx;
440194206Ssimon
441194206Ssimonstatic int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
442280304Sjkim{
443280304Sjkim    tlsextctx *p = (tlsextctx *) arg;
444280304Sjkim    const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
445280304Sjkim    if (SSL_get_servername_type(s) != -1)
446280304Sjkim        p->ack = !SSL_session_reused(s) && hn != NULL;
447280304Sjkim    else
448280304Sjkim        BIO_printf(bio_err, "Can't use SSL_get_servername\n");
449238405Sjkim
450280304Sjkim    return SSL_TLSEXT_ERR_OK;
451280304Sjkim}
452238405Sjkim
453280304Sjkim# ifndef OPENSSL_NO_SRP
454280304Sjkim
455238405Sjkim/* This is a context that we pass to all callbacks */
456280304Sjkimtypedef struct srp_arg_st {
457280304Sjkim    char *srppassin;
458280304Sjkim    char *srplogin;
459280304Sjkim    int msg;                    /* copy from c_msg */
460280304Sjkim    int debug;                  /* copy from c_debug */
461280304Sjkim    int amp;                    /* allow more groups */
462280304Sjkim    int strength /* minimal size for N */ ;
463280304Sjkim} SRP_ARG;
464238405Sjkim
465280304Sjkim#  define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
466238405Sjkim
467238405Sjkimstatic int srp_Verify_N_and_g(BIGNUM *N, BIGNUM *g)
468280304Sjkim{
469280304Sjkim    BN_CTX *bn_ctx = BN_CTX_new();
470280304Sjkim    BIGNUM *p = BN_new();
471280304Sjkim    BIGNUM *r = BN_new();
472280304Sjkim    int ret =
473280304Sjkim        g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
474280304Sjkim        BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
475280304Sjkim        p != NULL && BN_rshift1(p, N) &&
476280304Sjkim        /* p = (N-1)/2 */
477280304Sjkim        BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
478280304Sjkim        r != NULL &&
479280304Sjkim        /* verify g^((N-1)/2) == -1 (mod N) */
480280304Sjkim        BN_mod_exp(r, g, p, N, bn_ctx) &&
481280304Sjkim        BN_add_word(r, 1) && BN_cmp(r, N) == 0;
482238405Sjkim
483280304Sjkim    if (r)
484280304Sjkim        BN_free(r);
485280304Sjkim    if (p)
486280304Sjkim        BN_free(p);
487280304Sjkim    if (bn_ctx)
488280304Sjkim        BN_CTX_free(bn_ctx);
489280304Sjkim    return ret;
490280304Sjkim}
491238405Sjkim
492280304Sjkim/*-
493280304Sjkim * This callback is used here for two purposes:
494280304Sjkim * - extended debugging
495280304Sjkim * - making some primality tests for unknown groups
496280304Sjkim * The callback is only called for a non default group.
497280304Sjkim *
498280304Sjkim * An application does not need the call back at all if
499280304Sjkim * only the stanard groups are used.  In real life situations,
500280304Sjkim * client and server already share well known groups,
501280304Sjkim * thus there is no need to verify them.
502280304Sjkim * Furthermore, in case that a server actually proposes a group that
503280304Sjkim * is not one of those defined in RFC 5054, it is more appropriate
504280304Sjkim * to add the group to a static list and then compare since
505280304Sjkim * primality tests are rather cpu consuming.
506280304Sjkim */
507238405Sjkim
508280304Sjkimstatic int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
509280304Sjkim{
510280304Sjkim    SRP_ARG *srp_arg = (SRP_ARG *)arg;
511280304Sjkim    BIGNUM *N = NULL, *g = NULL;
512280304Sjkim    if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
513280304Sjkim        return 0;
514280304Sjkim    if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {
515280304Sjkim        BIO_printf(bio_err, "SRP parameters:\n");
516280304Sjkim        BIO_printf(bio_err, "\tN=");
517280304Sjkim        BN_print(bio_err, N);
518280304Sjkim        BIO_printf(bio_err, "\n\tg=");
519280304Sjkim        BN_print(bio_err, g);
520280304Sjkim        BIO_printf(bio_err, "\n");
521280304Sjkim    }
522238405Sjkim
523280304Sjkim    if (SRP_check_known_gN_param(g, N))
524280304Sjkim        return 1;
525238405Sjkim
526280304Sjkim    if (srp_arg->amp == 1) {
527280304Sjkim        if (srp_arg->debug)
528280304Sjkim            BIO_printf(bio_err,
529280304Sjkim                       "SRP param N and g are not known params, going to check deeper.\n");
530238405Sjkim
531280304Sjkim        /*
532280304Sjkim         * The srp_moregroups is a real debugging feature. Implementors
533280304Sjkim         * should rather add the value to the known ones. The minimal size
534280304Sjkim         * has already been tested.
535280304Sjkim         */
536280304Sjkim        if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
537280304Sjkim            return 1;
538280304Sjkim    }
539280304Sjkim    BIO_printf(bio_err, "SRP param N and g rejected.\n");
540280304Sjkim    return 0;
541280304Sjkim}
542238405Sjkim
543280304Sjkim#  define PWD_STRLEN 1024
544238405Sjkim
545280304Sjkimstatic char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
546280304Sjkim{
547280304Sjkim    SRP_ARG *srp_arg = (SRP_ARG *)arg;
548280304Sjkim    char *pass = (char *)OPENSSL_malloc(PWD_STRLEN + 1);
549280304Sjkim    PW_CB_DATA cb_tmp;
550280304Sjkim    int l;
551238405Sjkim
552284285Sjkim    if (!pass) {
553280304Sjkim        BIO_printf(bio_err, "Malloc failure\n");
554280304Sjkim        return NULL;
555280304Sjkim    }
556238405Sjkim
557280304Sjkim    cb_tmp.password = (char *)srp_arg->srppassin;
558280304Sjkim    cb_tmp.prompt_info = "SRP user";
559280304Sjkim    if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) {
560280304Sjkim        BIO_printf(bio_err, "Can't read Password\n");
561280304Sjkim        OPENSSL_free(pass);
562280304Sjkim        return NULL;
563280304Sjkim    }
564280304Sjkim    *(pass + l) = '\0';
565238405Sjkim
566280304Sjkim    return pass;
567280304Sjkim}
568238405Sjkim
569280304Sjkim# endif
570280304Sjkim# ifndef OPENSSL_NO_SRTP
571280304Sjkimchar *srtp_profiles = NULL;
572280304Sjkim# endif
573238405Sjkim
574238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
575238405Sjkim/* This the context that we pass to next_proto_cb */
576238405Sjkimtypedef struct tlsextnextprotoctx_st {
577280304Sjkim    unsigned char *data;
578280304Sjkim    unsigned short len;
579280304Sjkim    int status;
580238405Sjkim} tlsextnextprotoctx;
581238405Sjkim
582238405Sjkimstatic tlsextnextprotoctx next_proto;
583238405Sjkim
584280304Sjkimstatic int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen,
585280304Sjkim                         const unsigned char *in, unsigned int inlen,
586280304Sjkim                         void *arg)
587280304Sjkim{
588280304Sjkim    tlsextnextprotoctx *ctx = arg;
589238405Sjkim
590280304Sjkim    if (!c_quiet) {
591280304Sjkim        /* We can assume that |in| is syntactically valid. */
592280304Sjkim        unsigned i;
593280304Sjkim        BIO_printf(bio_c_out, "Protocols advertised by server: ");
594280304Sjkim        for (i = 0; i < inlen;) {
595280304Sjkim            if (i)
596280304Sjkim                BIO_write(bio_c_out, ", ", 2);
597280304Sjkim            BIO_write(bio_c_out, &in[i + 1], in[i]);
598280304Sjkim            i += in[i] + 1;
599280304Sjkim        }
600280304Sjkim        BIO_write(bio_c_out, "\n", 1);
601280304Sjkim    }
602238405Sjkim
603280304Sjkim    ctx->status =
604280304Sjkim        SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
605280304Sjkim    return SSL_TLSEXT_ERR_OK;
606280304Sjkim}
607280304Sjkim# endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
608238405Sjkim#endif
609238405Sjkim
610280304Sjkimenum {
611280304Sjkim    PROTO_OFF = 0,
612280304Sjkim    PROTO_SMTP,
613280304Sjkim    PROTO_POP3,
614280304Sjkim    PROTO_IMAP,
615280304Sjkim    PROTO_FTP,
616280304Sjkim    PROTO_XMPP
617167612Ssimon};
618167612Ssimon
61959191Skrisint MAIN(int, char **);
62059191Skris
62155714Skrisint MAIN(int argc, char **argv)
622280304Sjkim{
623280304Sjkim    unsigned int off = 0, clr = 0;
624280304Sjkim    SSL *con = NULL;
625238405Sjkim#ifndef OPENSSL_NO_KRB5
626280304Sjkim    KSSL_CTX *kctx;
627238405Sjkim#endif
628280304Sjkim    int s, k, width, state = 0;
629280304Sjkim    char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL;
630280304Sjkim    int cbuf_len, cbuf_off;
631280304Sjkim    int sbuf_len, sbuf_off;
632280304Sjkim    fd_set readfds, writefds;
633280304Sjkim    short port = PORT;
634280304Sjkim    int full_log = 1;
635280304Sjkim    char *host = SSL_HOST_NAME;
636280304Sjkim    char *cert_file = NULL, *key_file = NULL;
637280304Sjkim    int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
638280304Sjkim    char *passarg = NULL, *pass = NULL;
639280304Sjkim    X509 *cert = NULL;
640280304Sjkim    EVP_PKEY *key = NULL;
641280304Sjkim    char *CApath = NULL, *CAfile = NULL, *cipher = NULL;
642280304Sjkim    int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE, bugs = 0;
643280304Sjkim    int crlf = 0;
644280304Sjkim    int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
645280304Sjkim    SSL_CTX *ctx = NULL;
646280304Sjkim    int ret = 1, in_init = 1, i, nbio_test = 0;
647280304Sjkim    int starttls_proto = PROTO_OFF;
648280304Sjkim    int prexit = 0;
649280304Sjkim    X509_VERIFY_PARAM *vpm = NULL;
650280304Sjkim    int badarg = 0;
651280304Sjkim    const SSL_METHOD *meth = NULL;
652280304Sjkim    int socket_type = SOCK_STREAM;
653280304Sjkim    BIO *sbio;
654280304Sjkim    char *inrand = NULL;
655280304Sjkim    int mbuf_len = 0;
656280304Sjkim    struct timeval timeout, *timeoutp;
657111147Snectar#ifndef OPENSSL_NO_ENGINE
658280304Sjkim    char *engine_id = NULL;
659280304Sjkim    char *ssl_client_engine_id = NULL;
660280304Sjkim    ENGINE *ssl_client_engine = NULL;
661194206Ssimon#endif
662280304Sjkim    ENGINE *e = NULL;
663238405Sjkim#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
664280304Sjkim    struct timeval tv;
665280304Sjkim# if defined(OPENSSL_SYS_BEOS_R5)
666280304Sjkim    int stdin_set = 0;
667280304Sjkim# endif
66859191Skris#endif
669194206Ssimon#ifndef OPENSSL_NO_TLSEXT
670280304Sjkim    char *servername = NULL;
671280304Sjkim    tlsextctx tlsextcbp = { NULL, 0 };
672238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
673280304Sjkim    const char *next_proto_neg_in = NULL;
674238405Sjkim# endif
675194206Ssimon#endif
676280304Sjkim    char *sess_in = NULL;
677280304Sjkim    char *sess_out = NULL;
678280304Sjkim    struct sockaddr peer;
679280304Sjkim    int peerlen = sizeof(peer);
680280304Sjkim    int fallback_scsv = 0;
681280304Sjkim    int enable_timeouts = 0;
682280304Sjkim    long socket_mtu = 0;
683194206Ssimon#ifndef OPENSSL_NO_JPAKE
684280304Sjkim    char *jpake_secret = NULL;
685194206Ssimon#endif
686238405Sjkim#ifndef OPENSSL_NO_SRP
687280304Sjkim    char *srppass = NULL;
688280304Sjkim    int srp_lateuser = 0;
689280304Sjkim    SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 };
690238405Sjkim#endif
691160814Ssimon
692280304Sjkim    meth = SSLv23_client_method();
69355714Skris
694280304Sjkim    apps_startup();
695280304Sjkim    c_Pause = 0;
696280304Sjkim    c_quiet = 0;
697280304Sjkim    c_ign_eof = 0;
698280304Sjkim    c_debug = 0;
699280304Sjkim    c_msg = 0;
700280304Sjkim    c_showcerts = 0;
70155714Skris
702280304Sjkim    if (bio_err == NULL)
703280304Sjkim        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
70455714Skris
705280304Sjkim    if (!load_config(bio_err, NULL))
706280304Sjkim        goto end;
707109998Smarkm
708280304Sjkim    if (((cbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) ||
709280304Sjkim        ((sbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) ||
710280304Sjkim        ((mbuf = OPENSSL_malloc(BUFSIZZ)) == NULL)) {
711280304Sjkim        BIO_printf(bio_err, "out of memory\n");
712280304Sjkim        goto end;
713280304Sjkim    }
71455714Skris
715280304Sjkim    verify_depth = 0;
716280304Sjkim    verify_error = X509_V_OK;
71755714Skris#ifdef FIONBIO
718280304Sjkim    c_nbio = 0;
71955714Skris#endif
72055714Skris
721280304Sjkim    argc--;
722280304Sjkim    argv++;
723280304Sjkim    while (argc >= 1) {
724280304Sjkim        if (strcmp(*argv, "-host") == 0) {
725280304Sjkim            if (--argc < 1)
726280304Sjkim                goto bad;
727280304Sjkim            host = *(++argv);
728280304Sjkim        } else if (strcmp(*argv, "-port") == 0) {
729280304Sjkim            if (--argc < 1)
730280304Sjkim                goto bad;
731280304Sjkim            port = atoi(*(++argv));
732280304Sjkim            if (port == 0)
733280304Sjkim                goto bad;
734280304Sjkim        } else if (strcmp(*argv, "-connect") == 0) {
735280304Sjkim            if (--argc < 1)
736280304Sjkim                goto bad;
737280304Sjkim            if (!extract_host_port(*(++argv), &host, NULL, &port))
738280304Sjkim                goto bad;
739280304Sjkim        } else if (strcmp(*argv, "-verify") == 0) {
740280304Sjkim            verify = SSL_VERIFY_PEER;
741280304Sjkim            if (--argc < 1)
742280304Sjkim                goto bad;
743280304Sjkim            verify_depth = atoi(*(++argv));
744280304Sjkim            BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
745280304Sjkim        } else if (strcmp(*argv, "-cert") == 0) {
746280304Sjkim            if (--argc < 1)
747280304Sjkim                goto bad;
748280304Sjkim            cert_file = *(++argv);
749280304Sjkim        } else if (strcmp(*argv, "-sess_out") == 0) {
750280304Sjkim            if (--argc < 1)
751280304Sjkim                goto bad;
752280304Sjkim            sess_out = *(++argv);
753280304Sjkim        } else if (strcmp(*argv, "-sess_in") == 0) {
754280304Sjkim            if (--argc < 1)
755280304Sjkim                goto bad;
756280304Sjkim            sess_in = *(++argv);
757280304Sjkim        } else if (strcmp(*argv, "-certform") == 0) {
758280304Sjkim            if (--argc < 1)
759280304Sjkim                goto bad;
760280304Sjkim            cert_format = str2fmt(*(++argv));
761280304Sjkim        } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) {
762280304Sjkim            if (badarg)
763280304Sjkim                goto bad;
764280304Sjkim            continue;
765280304Sjkim        } else if (strcmp(*argv, "-verify_return_error") == 0)
766280304Sjkim            verify_return_error = 1;
767280304Sjkim        else if (strcmp(*argv, "-prexit") == 0)
768280304Sjkim            prexit = 1;
769280304Sjkim        else if (strcmp(*argv, "-crlf") == 0)
770280304Sjkim            crlf = 1;
771280304Sjkim        else if (strcmp(*argv, "-quiet") == 0) {
772280304Sjkim            c_quiet = 1;
773280304Sjkim            c_ign_eof = 1;
774280304Sjkim        } else if (strcmp(*argv, "-ign_eof") == 0)
775280304Sjkim            c_ign_eof = 1;
776280304Sjkim        else if (strcmp(*argv, "-no_ign_eof") == 0)
777280304Sjkim            c_ign_eof = 0;
778280304Sjkim        else if (strcmp(*argv, "-pause") == 0)
779280304Sjkim            c_Pause = 1;
780280304Sjkim        else if (strcmp(*argv, "-debug") == 0)
781280304Sjkim            c_debug = 1;
782194206Ssimon#ifndef OPENSSL_NO_TLSEXT
783280304Sjkim        else if (strcmp(*argv, "-tlsextdebug") == 0)
784280304Sjkim            c_tlsextdebug = 1;
785280304Sjkim        else if (strcmp(*argv, "-status") == 0)
786280304Sjkim            c_status_req = 1;
787194206Ssimon#endif
788160814Ssimon#ifdef WATT32
789280304Sjkim        else if (strcmp(*argv, "-wdebug") == 0)
790280304Sjkim            dbug_init();
791160814Ssimon#endif
792280304Sjkim        else if (strcmp(*argv, "-msg") == 0)
793280304Sjkim            c_msg = 1;
794280304Sjkim        else if (strcmp(*argv, "-showcerts") == 0)
795280304Sjkim            c_showcerts = 1;
796280304Sjkim        else if (strcmp(*argv, "-nbio_test") == 0)
797280304Sjkim            nbio_test = 1;
798280304Sjkim        else if (strcmp(*argv, "-state") == 0)
799280304Sjkim            state = 1;
800238405Sjkim#ifndef OPENSSL_NO_PSK
801280304Sjkim        else if (strcmp(*argv, "-psk_identity") == 0) {
802280304Sjkim            if (--argc < 1)
803280304Sjkim                goto bad;
804280304Sjkim            psk_identity = *(++argv);
805280304Sjkim        } else if (strcmp(*argv, "-psk") == 0) {
806280304Sjkim            size_t j;
807238405Sjkim
808280304Sjkim            if (--argc < 1)
809280304Sjkim                goto bad;
810280304Sjkim            psk_key = *(++argv);
811280304Sjkim            for (j = 0; j < strlen(psk_key); j++) {
812280304Sjkim                if (isxdigit((unsigned char)psk_key[j]))
813280304Sjkim                    continue;
814280304Sjkim                BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
815280304Sjkim                goto bad;
816280304Sjkim            }
817280304Sjkim        }
818238405Sjkim#endif
819238405Sjkim#ifndef OPENSSL_NO_SRP
820280304Sjkim        else if (strcmp(*argv, "-srpuser") == 0) {
821280304Sjkim            if (--argc < 1)
822280304Sjkim                goto bad;
823280304Sjkim            srp_arg.srplogin = *(++argv);
824280304Sjkim            meth = TLSv1_client_method();
825280304Sjkim        } else if (strcmp(*argv, "-srppass") == 0) {
826280304Sjkim            if (--argc < 1)
827280304Sjkim                goto bad;
828280304Sjkim            srppass = *(++argv);
829280304Sjkim            meth = TLSv1_client_method();
830280304Sjkim        } else if (strcmp(*argv, "-srp_strength") == 0) {
831280304Sjkim            if (--argc < 1)
832280304Sjkim                goto bad;
833280304Sjkim            srp_arg.strength = atoi(*(++argv));
834280304Sjkim            BIO_printf(bio_err, "SRP minimal length for N is %d\n",
835280304Sjkim                       srp_arg.strength);
836280304Sjkim            meth = TLSv1_client_method();
837280304Sjkim        } else if (strcmp(*argv, "-srp_lateuser") == 0) {
838280304Sjkim            srp_lateuser = 1;
839280304Sjkim            meth = TLSv1_client_method();
840280304Sjkim        } else if (strcmp(*argv, "-srp_moregroups") == 0) {
841280304Sjkim            srp_arg.amp = 1;
842280304Sjkim            meth = TLSv1_client_method();
843280304Sjkim        }
844238405Sjkim#endif
845109998Smarkm#ifndef OPENSSL_NO_SSL2
846280304Sjkim        else if (strcmp(*argv, "-ssl2") == 0)
847280304Sjkim            meth = SSLv2_client_method();
84855714Skris#endif
849276864Sjkim#ifndef OPENSSL_NO_SSL3_METHOD
850280304Sjkim        else if (strcmp(*argv, "-ssl3") == 0)
851280304Sjkim            meth = SSLv3_client_method();
85255714Skris#endif
853109998Smarkm#ifndef OPENSSL_NO_TLS1
854280304Sjkim        else if (strcmp(*argv, "-tls1_2") == 0)
855280304Sjkim            meth = TLSv1_2_client_method();
856280304Sjkim        else if (strcmp(*argv, "-tls1_1") == 0)
857280304Sjkim            meth = TLSv1_1_client_method();
858280304Sjkim        else if (strcmp(*argv, "-tls1") == 0)
859280304Sjkim            meth = TLSv1_client_method();
86055714Skris#endif
861160814Ssimon#ifndef OPENSSL_NO_DTLS1
862280304Sjkim        else if (strcmp(*argv, "-dtls1") == 0) {
863280304Sjkim            meth = DTLSv1_client_method();
864280304Sjkim            socket_type = SOCK_DGRAM;
865280304Sjkim        } else if (strcmp(*argv, "-fallback_scsv") == 0) {
866280304Sjkim            fallback_scsv = 1;
867280304Sjkim        } else if (strcmp(*argv, "-timeout") == 0)
868280304Sjkim            enable_timeouts = 1;
869280304Sjkim        else if (strcmp(*argv, "-mtu") == 0) {
870280304Sjkim            if (--argc < 1)
871280304Sjkim                goto bad;
872280304Sjkim            socket_mtu = atol(*(++argv));
873280304Sjkim        }
874160814Ssimon#endif
875280304Sjkim        else if (strcmp(*argv, "-bugs") == 0)
876280304Sjkim            bugs = 1;
877280304Sjkim        else if (strcmp(*argv, "-keyform") == 0) {
878280304Sjkim            if (--argc < 1)
879280304Sjkim                goto bad;
880280304Sjkim            key_format = str2fmt(*(++argv));
881280304Sjkim        } else if (strcmp(*argv, "-pass") == 0) {
882280304Sjkim            if (--argc < 1)
883280304Sjkim                goto bad;
884280304Sjkim            passarg = *(++argv);
885280304Sjkim        } else if (strcmp(*argv, "-key") == 0) {
886280304Sjkim            if (--argc < 1)
887280304Sjkim                goto bad;
888280304Sjkim            key_file = *(++argv);
889280304Sjkim        } else if (strcmp(*argv, "-reconnect") == 0) {
890280304Sjkim            reconnect = 5;
891280304Sjkim        } else if (strcmp(*argv, "-CApath") == 0) {
892280304Sjkim            if (--argc < 1)
893280304Sjkim                goto bad;
894280304Sjkim            CApath = *(++argv);
895280304Sjkim        } else if (strcmp(*argv, "-CAfile") == 0) {
896280304Sjkim            if (--argc < 1)
897280304Sjkim                goto bad;
898280304Sjkim            CAfile = *(++argv);
899280304Sjkim        } else if (strcmp(*argv, "-no_tls1_2") == 0)
900280304Sjkim            off |= SSL_OP_NO_TLSv1_2;
901280304Sjkim        else if (strcmp(*argv, "-no_tls1_1") == 0)
902280304Sjkim            off |= SSL_OP_NO_TLSv1_1;
903280304Sjkim        else if (strcmp(*argv, "-no_tls1") == 0)
904280304Sjkim            off |= SSL_OP_NO_TLSv1;
905280304Sjkim        else if (strcmp(*argv, "-no_ssl3") == 0)
906280304Sjkim            off |= SSL_OP_NO_SSLv3;
907280304Sjkim        else if (strcmp(*argv, "-no_ssl2") == 0)
908280304Sjkim            off |= SSL_OP_NO_SSLv2;
909280304Sjkim        else if (strcmp(*argv, "-no_comp") == 0) {
910280304Sjkim            off |= SSL_OP_NO_COMPRESSION;
911280304Sjkim        }
912194206Ssimon#ifndef OPENSSL_NO_TLSEXT
913280304Sjkim        else if (strcmp(*argv, "-no_ticket") == 0) {
914280304Sjkim            off |= SSL_OP_NO_TICKET;
915280304Sjkim        }
916238405Sjkim# ifndef OPENSSL_NO_NEXTPROTONEG
917280304Sjkim        else if (strcmp(*argv, "-nextprotoneg") == 0) {
918280304Sjkim            if (--argc < 1)
919280304Sjkim                goto bad;
920280304Sjkim            next_proto_neg_in = *(++argv);
921280304Sjkim        }
922238405Sjkim# endif
923194206Ssimon#endif
924280304Sjkim        else if (strcmp(*argv, "-serverpref") == 0)
925280304Sjkim            off |= SSL_OP_CIPHER_SERVER_PREFERENCE;
926280304Sjkim        else if (strcmp(*argv, "-legacy_renegotiation") == 0)
927280304Sjkim            off |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
928280304Sjkim        else if (strcmp(*argv, "-legacy_server_connect") == 0) {
929280304Sjkim            off |= SSL_OP_LEGACY_SERVER_CONNECT;
930280304Sjkim        } else if (strcmp(*argv, "-no_legacy_server_connect") == 0) {
931280304Sjkim            clr |= SSL_OP_LEGACY_SERVER_CONNECT;
932280304Sjkim        } else if (strcmp(*argv, "-cipher") == 0) {
933280304Sjkim            if (--argc < 1)
934280304Sjkim                goto bad;
935280304Sjkim            cipher = *(++argv);
936280304Sjkim        }
93755714Skris#ifdef FIONBIO
938280304Sjkim        else if (strcmp(*argv, "-nbio") == 0) {
939280304Sjkim            c_nbio = 1;
940280304Sjkim        }
94155714Skris#endif
942280304Sjkim        else if (strcmp(*argv, "-starttls") == 0) {
943280304Sjkim            if (--argc < 1)
944280304Sjkim                goto bad;
945280304Sjkim            ++argv;
946280304Sjkim            if (strcmp(*argv, "smtp") == 0)
947280304Sjkim                starttls_proto = PROTO_SMTP;
948280304Sjkim            else if (strcmp(*argv, "pop3") == 0)
949280304Sjkim                starttls_proto = PROTO_POP3;
950280304Sjkim            else if (strcmp(*argv, "imap") == 0)
951280304Sjkim                starttls_proto = PROTO_IMAP;
952280304Sjkim            else if (strcmp(*argv, "ftp") == 0)
953280304Sjkim                starttls_proto = PROTO_FTP;
954280304Sjkim            else if (strcmp(*argv, "xmpp") == 0)
955280304Sjkim                starttls_proto = PROTO_XMPP;
956280304Sjkim            else
957280304Sjkim                goto bad;
958280304Sjkim        }
959111147Snectar#ifndef OPENSSL_NO_ENGINE
960280304Sjkim        else if (strcmp(*argv, "-engine") == 0) {
961280304Sjkim            if (--argc < 1)
962280304Sjkim                goto bad;
963280304Sjkim            engine_id = *(++argv);
964280304Sjkim        } else if (strcmp(*argv, "-ssl_client_engine") == 0) {
965280304Sjkim            if (--argc < 1)
966280304Sjkim                goto bad;
967280304Sjkim            ssl_client_engine_id = *(++argv);
968280304Sjkim        }
969111147Snectar#endif
970280304Sjkim        else if (strcmp(*argv, "-rand") == 0) {
971280304Sjkim            if (--argc < 1)
972280304Sjkim                goto bad;
973280304Sjkim            inrand = *(++argv);
974280304Sjkim        }
975194206Ssimon#ifndef OPENSSL_NO_TLSEXT
976280304Sjkim        else if (strcmp(*argv, "-servername") == 0) {
977280304Sjkim            if (--argc < 1)
978280304Sjkim                goto bad;
979280304Sjkim            servername = *(++argv);
980280304Sjkim            /* meth=TLSv1_client_method(); */
981280304Sjkim        }
982194206Ssimon#endif
983194206Ssimon#ifndef OPENSSL_NO_JPAKE
984280304Sjkim        else if (strcmp(*argv, "-jpake") == 0) {
985280304Sjkim            if (--argc < 1)
986280304Sjkim                goto bad;
987280304Sjkim            jpake_secret = *++argv;
988280304Sjkim        }
989194206Ssimon#endif
990246772Sjkim#ifndef OPENSSL_NO_SRTP
991280304Sjkim        else if (strcmp(*argv, "-use_srtp") == 0) {
992280304Sjkim            if (--argc < 1)
993280304Sjkim                goto bad;
994280304Sjkim            srtp_profiles = *(++argv);
995280304Sjkim        }
996246772Sjkim#endif
997280304Sjkim        else if (strcmp(*argv, "-keymatexport") == 0) {
998280304Sjkim            if (--argc < 1)
999280304Sjkim                goto bad;
1000280304Sjkim            keymatexportlabel = *(++argv);
1001280304Sjkim        } else if (strcmp(*argv, "-keymatexportlen") == 0) {
1002280304Sjkim            if (--argc < 1)
1003280304Sjkim                goto bad;
1004280304Sjkim            keymatexportlen = atoi(*(++argv));
1005280304Sjkim            if (keymatexportlen == 0)
1006280304Sjkim                goto bad;
1007280304Sjkim        } else {
1008280304Sjkim            BIO_printf(bio_err, "unknown option %s\n", *argv);
1009280304Sjkim            badop = 1;
1010280304Sjkim            break;
1011280304Sjkim        }
1012280304Sjkim        argc--;
1013280304Sjkim        argv++;
1014280304Sjkim    }
1015280304Sjkim    if (badop) {
1016280304Sjkim bad:
1017280304Sjkim        sc_usage();
1018280304Sjkim        goto end;
1019280304Sjkim    }
1020238405Sjkim#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
1021280304Sjkim    if (jpake_secret) {
1022280304Sjkim        if (psk_key) {
1023280304Sjkim            BIO_printf(bio_err, "Can't use JPAKE and PSK together\n");
1024280304Sjkim            goto end;
1025280304Sjkim        }
1026280304Sjkim        psk_identity = "JPAKE";
1027280304Sjkim        if (cipher) {
1028280304Sjkim            BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
1029280304Sjkim            goto end;
1030280304Sjkim        }
1031280304Sjkim        cipher = "PSK";
1032280304Sjkim    }
1033238405Sjkim#endif
1034238405Sjkim
1035280304Sjkim    OpenSSL_add_ssl_algorithms();
1036280304Sjkim    SSL_load_error_strings();
1037109998Smarkm
1038238405Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
1039280304Sjkim    next_proto.status = -1;
1040280304Sjkim    if (next_proto_neg_in) {
1041280304Sjkim        next_proto.data =
1042280304Sjkim            next_protos_parse(&next_proto.len, next_proto_neg_in);
1043280304Sjkim        if (next_proto.data == NULL) {
1044280304Sjkim            BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
1045280304Sjkim            goto end;
1046280304Sjkim        }
1047280304Sjkim    } else
1048280304Sjkim        next_proto.data = NULL;
1049238405Sjkim#endif
1050238405Sjkim
1051111147Snectar#ifndef OPENSSL_NO_ENGINE
1052280304Sjkim    e = setup_engine(bio_err, engine_id, 1);
1053280304Sjkim    if (ssl_client_engine_id) {
1054280304Sjkim        ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
1055280304Sjkim        if (!ssl_client_engine) {
1056280304Sjkim            BIO_printf(bio_err, "Error getting client auth engine\n");
1057280304Sjkim            goto end;
1058280304Sjkim        }
1059280304Sjkim    }
1060111147Snectar#endif
1061280304Sjkim    if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
1062280304Sjkim        BIO_printf(bio_err, "Error getting password\n");
1063280304Sjkim        goto end;
1064280304Sjkim    }
1065109998Smarkm
1066280304Sjkim    if (key_file == NULL)
1067280304Sjkim        key_file = cert_file;
1068160814Ssimon
1069280304Sjkim    if (key_file) {
1070160814Ssimon
1071280304Sjkim        key = load_key(bio_err, key_file, key_format, 0, pass, e,
1072280304Sjkim                       "client certificate private key file");
1073280304Sjkim        if (!key) {
1074280304Sjkim            ERR_print_errors(bio_err);
1075280304Sjkim            goto end;
1076280304Sjkim        }
1077160814Ssimon
1078280304Sjkim    }
1079160814Ssimon
1080280304Sjkim    if (cert_file) {
1081280304Sjkim        cert = load_cert(bio_err, cert_file, cert_format,
1082280304Sjkim                         NULL, e, "client certificate file");
1083160814Ssimon
1084280304Sjkim        if (!cert) {
1085280304Sjkim            ERR_print_errors(bio_err);
1086280304Sjkim            goto end;
1087280304Sjkim        }
1088280304Sjkim    }
1089160814Ssimon
1090280304Sjkim    if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
1091280304Sjkim        && !RAND_status()) {
1092280304Sjkim        BIO_printf(bio_err,
1093280304Sjkim                   "warning, not much extra random data, consider using the -rand option\n");
1094280304Sjkim    }
1095280304Sjkim    if (inrand != NULL)
1096280304Sjkim        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
1097280304Sjkim                   app_RAND_load_files(inrand));
1098160814Ssimon
1099280304Sjkim    if (bio_c_out == NULL) {
1100280304Sjkim        if (c_quiet && !c_debug && !c_msg) {
1101280304Sjkim            bio_c_out = BIO_new(BIO_s_null());
1102280304Sjkim        } else {
1103280304Sjkim            if (bio_c_out == NULL)
1104280304Sjkim                bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE);
1105280304Sjkim        }
1106280304Sjkim    }
1107238405Sjkim#ifndef OPENSSL_NO_SRP
1108280304Sjkim    if (!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL)) {
1109280304Sjkim        BIO_printf(bio_err, "Error getting password\n");
1110280304Sjkim        goto end;
1111280304Sjkim    }
1112238405Sjkim#endif
1113238405Sjkim
1114280304Sjkim    ctx = SSL_CTX_new(meth);
1115280304Sjkim    if (ctx == NULL) {
1116280304Sjkim        ERR_print_errors(bio_err);
1117280304Sjkim        goto end;
1118280304Sjkim    }
111955714Skris
1120280304Sjkim    if (vpm)
1121280304Sjkim        SSL_CTX_set1_param(ctx, vpm);
1122238405Sjkim
1123194206Ssimon#ifndef OPENSSL_NO_ENGINE
1124280304Sjkim    if (ssl_client_engine) {
1125280304Sjkim        if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
1126280304Sjkim            BIO_puts(bio_err, "Error setting client auth engine\n");
1127280304Sjkim            ERR_print_errors(bio_err);
1128280304Sjkim            ENGINE_free(ssl_client_engine);
1129280304Sjkim            goto end;
1130280304Sjkim        }
1131280304Sjkim        ENGINE_free(ssl_client_engine);
1132280304Sjkim    }
1133194206Ssimon#endif
1134194206Ssimon
1135238405Sjkim#ifndef OPENSSL_NO_PSK
1136280304Sjkim# ifdef OPENSSL_NO_JPAKE
1137280304Sjkim    if (psk_key != NULL)
1138280304Sjkim# else
1139280304Sjkim    if (psk_key != NULL || jpake_secret)
1140280304Sjkim# endif
1141280304Sjkim    {
1142280304Sjkim        if (c_debug)
1143280304Sjkim            BIO_printf(bio_c_out,
1144280304Sjkim                       "PSK key given or JPAKE in use, setting client callback\n");
1145280304Sjkim        SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
1146280304Sjkim    }
1147238405Sjkim#endif
1148246772Sjkim#ifndef OPENSSL_NO_SRTP
1149280304Sjkim    if (srtp_profiles != NULL)
1150280304Sjkim        SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
1151238405Sjkim#endif
1152280304Sjkim    if (bugs)
1153280304Sjkim        SSL_CTX_set_options(ctx, SSL_OP_ALL | off);
1154280304Sjkim    else
1155280304Sjkim        SSL_CTX_set_options(ctx, off);
1156205128Ssimon
1157280304Sjkim    if (clr)
1158280304Sjkim        SSL_CTX_clear_options(ctx, clr);
115955714Skris
1160238405Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
1161280304Sjkim    if (next_proto.data)
1162280304Sjkim        SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
1163238405Sjkim#endif
1164238405Sjkim
1165280304Sjkim    if (state)
1166280304Sjkim        SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
1167280304Sjkim    if (cipher != NULL)
1168280304Sjkim        if (!SSL_CTX_set_cipher_list(ctx, cipher)) {
1169280304Sjkim            BIO_printf(bio_err, "error setting cipher list\n");
1170280304Sjkim            ERR_print_errors(bio_err);
1171280304Sjkim            goto end;
1172280304Sjkim        }
117355714Skris#if 0
1174280304Sjkim        else
1175280304Sjkim            SSL_CTX_set_cipher_list(ctx, getenv("SSL_CIPHER"));
117655714Skris#endif
117755714Skris
1178280304Sjkim    SSL_CTX_set_verify(ctx, verify, verify_callback);
1179280304Sjkim    if (!set_cert_key_stuff(ctx, cert, key))
1180280304Sjkim        goto end;
118155714Skris
1182284285Sjkim    if ((CAfile || CApath)
1183284285Sjkim        && !SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
1184280304Sjkim        ERR_print_errors(bio_err);
1185280304Sjkim    }
1186284285Sjkim    if (!SSL_CTX_set_default_verify_paths(ctx)) {
1187284285Sjkim        ERR_print_errors(bio_err);
1188284285Sjkim    }
1189194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1190280304Sjkim    if (servername != NULL) {
1191280304Sjkim        tlsextcbp.biodebug = bio_err;
1192280304Sjkim        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1193280304Sjkim        SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
1194280304Sjkim    }
1195280304Sjkim# ifndef OPENSSL_NO_SRP
1196280304Sjkim    if (srp_arg.srplogin) {
1197280304Sjkim        if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) {
1198280304Sjkim            BIO_printf(bio_err, "Unable to set SRP username\n");
1199280304Sjkim            goto end;
1200280304Sjkim        }
1201280304Sjkim        srp_arg.msg = c_msg;
1202280304Sjkim        srp_arg.debug = c_debug;
1203280304Sjkim        SSL_CTX_set_srp_cb_arg(ctx, &srp_arg);
1204280304Sjkim        SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
1205280304Sjkim        SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
1206280304Sjkim        if (c_msg || c_debug || srp_arg.amp == 0)
1207280304Sjkim            SSL_CTX_set_srp_verify_param_callback(ctx,
1208280304Sjkim                                                  ssl_srp_verify_param_cb);
1209280304Sjkim    }
1210280304Sjkim# endif
1211194206Ssimon#endif
121255714Skris
1213280304Sjkim    con = SSL_new(ctx);
1214280304Sjkim    if (sess_in) {
1215280304Sjkim        SSL_SESSION *sess;
1216280304Sjkim        BIO *stmp = BIO_new_file(sess_in, "r");
1217280304Sjkim        if (!stmp) {
1218280304Sjkim            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
1219280304Sjkim            ERR_print_errors(bio_err);
1220280304Sjkim            goto end;
1221280304Sjkim        }
1222280304Sjkim        sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
1223280304Sjkim        BIO_free(stmp);
1224280304Sjkim        if (!sess) {
1225280304Sjkim            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
1226280304Sjkim            ERR_print_errors(bio_err);
1227280304Sjkim            goto end;
1228280304Sjkim        }
1229280304Sjkim        SSL_set_session(con, sess);
1230280304Sjkim        SSL_SESSION_free(sess);
1231280304Sjkim    }
1232273149Sjkim
1233280304Sjkim    if (fallback_scsv)
1234280304Sjkim        SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
1235273149Sjkim
1236194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1237280304Sjkim    if (servername != NULL) {
1238280304Sjkim        if (!SSL_set_tlsext_host_name(con, servername)) {
1239280304Sjkim            BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
1240280304Sjkim            ERR_print_errors(bio_err);
1241280304Sjkim            goto end;
1242280304Sjkim        }
1243280304Sjkim    }
1244194206Ssimon#endif
1245109998Smarkm#ifndef OPENSSL_NO_KRB5
1246280304Sjkim    if (con && (kctx = kssl_ctx_new()) != NULL) {
1247280304Sjkim        SSL_set0_kssl_ctx(con, kctx);
1248280304Sjkim        kssl_ctx_setstring(kctx, KSSL_SERVER, host);
1249280304Sjkim    }
1250280304Sjkim#endif                          /* OPENSSL_NO_KRB5 */
1251280304Sjkim/*      SSL_set_cipher_list(con,"RC4-MD5"); */
1252238405Sjkim#if 0
1253280304Sjkim# ifdef TLSEXT_TYPE_opaque_prf_input
1254280304Sjkim    SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
1255280304Sjkim# endif
1256238405Sjkim#endif
125755714Skris
1258280304Sjkim re_start:
125955714Skris
1260280304Sjkim    if (init_client(&s, host, port, socket_type) == 0) {
1261280304Sjkim        BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
1262280304Sjkim        SHUTDOWN(s);
1263280304Sjkim        goto end;
1264280304Sjkim    }
1265280304Sjkim    BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
126655714Skris
126755714Skris#ifdef FIONBIO
1268280304Sjkim    if (c_nbio) {
1269280304Sjkim        unsigned long l = 1;
1270280304Sjkim        BIO_printf(bio_c_out, "turning on non blocking io\n");
1271280304Sjkim        if (BIO_socket_ioctl(s, FIONBIO, &l) < 0) {
1272280304Sjkim            ERR_print_errors(bio_err);
1273280304Sjkim            goto end;
1274280304Sjkim        }
1275280304Sjkim    }
1276280304Sjkim#endif
1277280304Sjkim    if (c_Pause & 0x01)
1278280304Sjkim        SSL_set_debug(con, 1);
127955714Skris
1280280304Sjkim    if (SSL_version(con) == DTLS1_VERSION) {
1281160814Ssimon
1282280304Sjkim        sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1283280304Sjkim        if (getsockname(s, &peer, (void *)&peerlen) < 0) {
1284280304Sjkim            BIO_printf(bio_err, "getsockname:errno=%d\n",
1285280304Sjkim                       get_last_socket_error());
1286280304Sjkim            SHUTDOWN(s);
1287280304Sjkim            goto end;
1288280304Sjkim        }
1289160814Ssimon
1290280304Sjkim        (void)BIO_ctrl_set_connected(sbio, 1, &peer);
1291160814Ssimon
1292280304Sjkim        if (enable_timeouts) {
1293280304Sjkim            timeout.tv_sec = 0;
1294280304Sjkim            timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1295280304Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
1296160814Ssimon
1297280304Sjkim            timeout.tv_sec = 0;
1298280304Sjkim            timeout.tv_usec = DGRAM_SND_TIMEOUT;
1299280304Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
1300280304Sjkim        }
1301160814Ssimon
1302280304Sjkim        if (socket_mtu) {
1303280304Sjkim            if (socket_mtu < DTLS_get_link_min_mtu(con)) {
1304280304Sjkim                BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
1305280304Sjkim                           DTLS_get_link_min_mtu(con));
1306280304Sjkim                BIO_free(sbio);
1307280304Sjkim                goto shut;
1308280304Sjkim            }
1309280304Sjkim            SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1310280304Sjkim            if (!DTLS_set_link_mtu(con, socket_mtu)) {
1311280304Sjkim                BIO_printf(bio_err, "Failed to set MTU\n");
1312280304Sjkim                BIO_free(sbio);
1313280304Sjkim                goto shut;
1314280304Sjkim            }
1315280304Sjkim        } else
1316280304Sjkim            /* want to do MTU discovery */
1317280304Sjkim            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1318280304Sjkim    } else
1319280304Sjkim        sbio = BIO_new_socket(s, BIO_NOCLOSE);
132055714Skris
1321280304Sjkim    if (nbio_test) {
1322280304Sjkim        BIO *test;
132355714Skris
1324280304Sjkim        test = BIO_new(BIO_f_nbio_test());
1325280304Sjkim        sbio = BIO_push(test, sbio);
1326280304Sjkim    }
1327280304Sjkim
1328280304Sjkim    if (c_debug) {
1329280304Sjkim        SSL_set_debug(con, 1);
1330280304Sjkim        BIO_set_callback(sbio, bio_dump_callback);
1331280304Sjkim        BIO_set_callback_arg(sbio, (char *)bio_c_out);
1332280304Sjkim    }
1333280304Sjkim    if (c_msg) {
1334280304Sjkim        SSL_set_msg_callback(con, msg_cb);
1335280304Sjkim        SSL_set_msg_callback_arg(con, bio_c_out);
1336280304Sjkim    }
1337194206Ssimon#ifndef OPENSSL_NO_TLSEXT
1338280304Sjkim    if (c_tlsextdebug) {
1339280304Sjkim        SSL_set_tlsext_debug_callback(con, tlsext_cb);
1340280304Sjkim        SSL_set_tlsext_debug_arg(con, bio_c_out);
1341280304Sjkim    }
1342280304Sjkim    if (c_status_req) {
1343280304Sjkim        SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
1344280304Sjkim        SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
1345280304Sjkim        SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
1346280304Sjkim# if 0
1347280304Sjkim        {
1348280304Sjkim            STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
1349280304Sjkim            OCSP_RESPID *id = OCSP_RESPID_new();
1350280304Sjkim            id->value.byKey = ASN1_OCTET_STRING_new();
1351280304Sjkim            id->type = V_OCSP_RESPID_KEY;
1352280304Sjkim            ASN1_STRING_set(id->value.byKey, "Hello World", -1);
1353280304Sjkim            sk_OCSP_RESPID_push(ids, id);
1354280304Sjkim            SSL_set_tlsext_status_ids(con, ids);
1355280304Sjkim        }
1356280304Sjkim# endif
1357280304Sjkim    }
1358194206Ssimon#endif
1359194206Ssimon#ifndef OPENSSL_NO_JPAKE
1360280304Sjkim    if (jpake_secret)
1361280304Sjkim        jpake_client_auth(bio_c_out, sbio, jpake_secret);
1362194206Ssimon#endif
136355714Skris
1364280304Sjkim    SSL_set_bio(con, sbio, sbio);
1365280304Sjkim    SSL_set_connect_state(con);
136655714Skris
1367280304Sjkim    /* ok, lets connect */
1368280304Sjkim    width = SSL_get_fd(con) + 1;
136955714Skris
1370280304Sjkim    read_tty = 1;
1371280304Sjkim    write_tty = 0;
1372280304Sjkim    tty_on = 0;
1373280304Sjkim    read_ssl = 1;
1374280304Sjkim    write_ssl = 1;
137555714Skris
1376280304Sjkim    cbuf_len = 0;
1377280304Sjkim    cbuf_off = 0;
1378280304Sjkim    sbuf_len = 0;
1379280304Sjkim    sbuf_off = 0;
1380109998Smarkm
1381280304Sjkim    /* This is an ugly hack that does a lot of assumptions */
1382280304Sjkim    /*
1383280304Sjkim     * We do have to handle multi-line responses which may come in a single
1384280304Sjkim     * packet or not. We therefore have to use BIO_gets() which does need a
1385280304Sjkim     * buffering BIO. So during the initial chitchat we do push a buffering
1386280304Sjkim     * BIO into the chain that is removed again later on to not disturb the
1387280304Sjkim     * rest of the s_client operation.
1388280304Sjkim     */
1389280304Sjkim    if (starttls_proto == PROTO_SMTP) {
1390280304Sjkim        int foundit = 0;
1391280304Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1392280304Sjkim        BIO_push(fbio, sbio);
1393280304Sjkim        /* wait for multi-line response to end from SMTP */
1394280304Sjkim        do {
1395280304Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1396280304Sjkim        }
1397280304Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1398280304Sjkim        /* STARTTLS command requires EHLO... */
1399280304Sjkim        BIO_printf(fbio, "EHLO openssl.client.net\r\n");
1400280304Sjkim        (void)BIO_flush(fbio);
1401280304Sjkim        /* wait for multi-line response to end EHLO SMTP response */
1402280304Sjkim        do {
1403280304Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1404280304Sjkim            if (strstr(mbuf, "STARTTLS"))
1405280304Sjkim                foundit = 1;
1406280304Sjkim        }
1407280304Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1408280304Sjkim        (void)BIO_flush(fbio);
1409280304Sjkim        BIO_pop(fbio);
1410280304Sjkim        BIO_free(fbio);
1411280304Sjkim        if (!foundit)
1412280304Sjkim            BIO_printf(bio_err,
1413280304Sjkim                       "didn't found starttls in server response,"
1414280304Sjkim                       " try anyway...\n");
1415280304Sjkim        BIO_printf(sbio, "STARTTLS\r\n");
1416280304Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1417280304Sjkim    } else if (starttls_proto == PROTO_POP3) {
1418280304Sjkim        BIO_read(sbio, mbuf, BUFSIZZ);
1419280304Sjkim        BIO_printf(sbio, "STLS\r\n");
1420280304Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1421280304Sjkim    } else if (starttls_proto == PROTO_IMAP) {
1422280304Sjkim        int foundit = 0;
1423280304Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1424280304Sjkim        BIO_push(fbio, sbio);
1425280304Sjkim        BIO_gets(fbio, mbuf, BUFSIZZ);
1426280304Sjkim        /* STARTTLS command requires CAPABILITY... */
1427280304Sjkim        BIO_printf(fbio, ". CAPABILITY\r\n");
1428280304Sjkim        (void)BIO_flush(fbio);
1429280304Sjkim        /* wait for multi-line CAPABILITY response */
1430280304Sjkim        do {
1431280304Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1432280304Sjkim            if (strstr(mbuf, "STARTTLS"))
1433280304Sjkim                foundit = 1;
1434280304Sjkim        }
1435280304Sjkim        while (mbuf_len > 3 && mbuf[0] != '.');
1436280304Sjkim        (void)BIO_flush(fbio);
1437280304Sjkim        BIO_pop(fbio);
1438280304Sjkim        BIO_free(fbio);
1439280304Sjkim        if (!foundit)
1440280304Sjkim            BIO_printf(bio_err,
1441280304Sjkim                       "didn't found STARTTLS in server response,"
1442280304Sjkim                       " try anyway...\n");
1443280304Sjkim        BIO_printf(sbio, ". STARTTLS\r\n");
1444280304Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1445280304Sjkim    } else if (starttls_proto == PROTO_FTP) {
1446280304Sjkim        BIO *fbio = BIO_new(BIO_f_buffer());
1447280304Sjkim        BIO_push(fbio, sbio);
1448280304Sjkim        /* wait for multi-line response to end from FTP */
1449280304Sjkim        do {
1450280304Sjkim            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1451280304Sjkim        }
1452280304Sjkim        while (mbuf_len > 3 && mbuf[3] == '-');
1453280304Sjkim        (void)BIO_flush(fbio);
1454280304Sjkim        BIO_pop(fbio);
1455280304Sjkim        BIO_free(fbio);
1456280304Sjkim        BIO_printf(sbio, "AUTH TLS\r\n");
1457280304Sjkim        BIO_read(sbio, sbuf, BUFSIZZ);
1458280304Sjkim    }
1459280304Sjkim    if (starttls_proto == PROTO_XMPP) {
1460280304Sjkim        int seen = 0;
1461280304Sjkim        BIO_printf(sbio, "<stream:stream "
1462280304Sjkim                   "xmlns:stream='http://etherx.jabber.org/streams' "
1463280304Sjkim                   "xmlns='jabber:client' to='%s' version='1.0'>", host);
1464280304Sjkim        seen = BIO_read(sbio, mbuf, BUFSIZZ);
1465280304Sjkim        mbuf[seen] = 0;
1466280304Sjkim        while (!strstr
1467280304Sjkim               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) {
1468280304Sjkim            if (strstr(mbuf, "/stream:features>"))
1469280304Sjkim                goto shut;
1470280304Sjkim            seen = BIO_read(sbio, mbuf, BUFSIZZ);
1471280304Sjkim            mbuf[seen] = 0;
1472280304Sjkim        }
1473280304Sjkim        BIO_printf(sbio,
1474280304Sjkim                   "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1475280304Sjkim        seen = BIO_read(sbio, sbuf, BUFSIZZ);
1476280304Sjkim        sbuf[seen] = 0;
1477280304Sjkim        if (!strstr(sbuf, "<proceed"))
1478280304Sjkim            goto shut;
1479280304Sjkim        mbuf[0] = 0;
1480280304Sjkim    }
148155714Skris
1482280304Sjkim    for (;;) {
1483280304Sjkim        FD_ZERO(&readfds);
1484280304Sjkim        FD_ZERO(&writefds);
1485205128Ssimon
1486280304Sjkim        if ((SSL_version(con) == DTLS1_VERSION) &&
1487280304Sjkim            DTLSv1_get_timeout(con, &timeout))
1488280304Sjkim            timeoutp = &timeout;
1489280304Sjkim        else
1490280304Sjkim            timeoutp = NULL;
1491280304Sjkim
1492280304Sjkim        if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
1493280304Sjkim            in_init = 1;
1494280304Sjkim            tty_on = 0;
1495280304Sjkim        } else {
1496280304Sjkim            tty_on = 1;
1497280304Sjkim            if (in_init) {
1498280304Sjkim                in_init = 0;
1499280304Sjkim#if 0                           /* This test doesn't really work as intended
1500280304Sjkim                                 * (needs to be fixed) */
1501280304Sjkim# ifndef OPENSSL_NO_TLSEXT
1502280304Sjkim                if (servername != NULL && !SSL_session_reused(con)) {
1503280304Sjkim                    BIO_printf(bio_c_out,
1504280304Sjkim                               "Server did %sacknowledge servername extension.\n",
1505280304Sjkim                               tlsextcbp.ack ? "" : "not ");
1506280304Sjkim                }
1507280304Sjkim# endif
1508238405Sjkim#endif
1509280304Sjkim                if (sess_out) {
1510280304Sjkim                    BIO *stmp = BIO_new_file(sess_out, "w");
1511280304Sjkim                    if (stmp) {
1512280304Sjkim                        PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
1513280304Sjkim                        BIO_free(stmp);
1514280304Sjkim                    } else
1515280304Sjkim                        BIO_printf(bio_err, "Error writing session file %s\n",
1516280304Sjkim                                   sess_out);
1517280304Sjkim                }
1518280304Sjkim                print_stuff(bio_c_out, con, full_log);
1519280304Sjkim                if (full_log > 0)
1520280304Sjkim                    full_log--;
152155714Skris
1522280304Sjkim                if (starttls_proto) {
1523280304Sjkim                    BIO_printf(bio_err, "%s", mbuf);
1524280304Sjkim                    /* We don't need to know any more */
1525280304Sjkim                    starttls_proto = PROTO_OFF;
1526280304Sjkim                }
1527109998Smarkm
1528280304Sjkim                if (reconnect) {
1529280304Sjkim                    reconnect--;
1530280304Sjkim                    BIO_printf(bio_c_out,
1531280304Sjkim                               "drop connection and then reconnect\n");
1532280304Sjkim                    SSL_shutdown(con);
1533280304Sjkim                    SSL_set_connect_state(con);
1534280304Sjkim                    SHUTDOWN(SSL_get_fd(con));
1535280304Sjkim                    goto re_start;
1536280304Sjkim                }
1537280304Sjkim            }
1538280304Sjkim        }
153955714Skris
1540280304Sjkim        ssl_pending = read_ssl && SSL_pending(con);
154155714Skris
1542280304Sjkim        if (!ssl_pending) {
1543238405Sjkim#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
1544280304Sjkim            if (tty_on) {
1545280304Sjkim                if (read_tty)
1546280304Sjkim                    openssl_fdset(fileno(stdin), &readfds);
1547280304Sjkim                if (write_tty)
1548280304Sjkim                    openssl_fdset(fileno(stdout), &writefds);
1549280304Sjkim            }
1550280304Sjkim            if (read_ssl)
1551280304Sjkim                openssl_fdset(SSL_get_fd(con), &readfds);
1552280304Sjkim            if (write_ssl)
1553280304Sjkim                openssl_fdset(SSL_get_fd(con), &writefds);
155459191Skris#else
1555280304Sjkim            if (!tty_on || !write_tty) {
1556280304Sjkim                if (read_ssl)
1557280304Sjkim                    openssl_fdset(SSL_get_fd(con), &readfds);
1558280304Sjkim                if (write_ssl)
1559280304Sjkim                    openssl_fdset(SSL_get_fd(con), &writefds);
1560280304Sjkim            }
156159191Skris#endif
1562280304Sjkim/*-         printf("mode tty(%d %d%d) ssl(%d%d)\n",
1563280304Sjkim                    tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
156455714Skris
1565280304Sjkim            /*
1566280304Sjkim             * Note: under VMS with SOCKETSHR the second parameter is
1567280304Sjkim             * currently of type (int *) whereas under other systems it is
1568280304Sjkim             * (void *) if you don't have a cast it will choke the compiler:
1569280304Sjkim             * if you do have a cast then you can either go for (int *) or
1570280304Sjkim             * (void *).
1571280304Sjkim             */
1572120631Snectar#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
1573280304Sjkim            /*
1574280304Sjkim             * Under Windows/DOS we make the assumption that we can always
1575280304Sjkim             * write to the tty: therefore if we need to write to the tty we
1576280304Sjkim             * just fall through. Otherwise we timeout the select every
1577280304Sjkim             * second and see if there are any keypresses. Note: this is a
1578280304Sjkim             * hack, in a proper Windows application we wouldn't do this.
1579280304Sjkim             */
1580280304Sjkim            i = 0;
1581280304Sjkim            if (!write_tty) {
1582280304Sjkim                if (read_tty) {
1583280304Sjkim                    tv.tv_sec = 1;
1584280304Sjkim                    tv.tv_usec = 0;
1585280304Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1586280304Sjkim                               NULL, &tv);
1587280304Sjkim# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
1588280304Sjkim                    if (!i && (!_kbhit() || !read_tty))
1589280304Sjkim                        continue;
1590280304Sjkim# else
1591280304Sjkim                    if (!i && (!((_kbhit())
1592280304Sjkim                                 || (WAIT_OBJECT_0 ==
1593280304Sjkim                                     WaitForSingleObject(GetStdHandle
1594280304Sjkim                                                         (STD_INPUT_HANDLE),
1595280304Sjkim                                                         0)))
1596280304Sjkim                               || !read_tty))
1597280304Sjkim                        continue;
1598280304Sjkim# endif
1599280304Sjkim                } else
1600280304Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1601280304Sjkim                               NULL, timeoutp);
1602280304Sjkim            }
1603160814Ssimon#elif defined(OPENSSL_SYS_NETWARE)
1604280304Sjkim            if (!write_tty) {
1605280304Sjkim                if (read_tty) {
1606280304Sjkim                    tv.tv_sec = 1;
1607280304Sjkim                    tv.tv_usec = 0;
1608280304Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1609280304Sjkim                               NULL, &tv);
1610280304Sjkim                } else
1611280304Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1612280304Sjkim                               NULL, timeoutp);
1613280304Sjkim            }
1614238405Sjkim#elif defined(OPENSSL_SYS_BEOS_R5)
1615280304Sjkim            /* Under BeOS-R5 the situation is similar to DOS */
1616280304Sjkim            i = 0;
1617280304Sjkim            stdin_set = 0;
1618280304Sjkim            (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
1619280304Sjkim            if (!write_tty) {
1620280304Sjkim                if (read_tty) {
1621280304Sjkim                    tv.tv_sec = 1;
1622280304Sjkim                    tv.tv_usec = 0;
1623280304Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1624280304Sjkim                               NULL, &tv);
1625280304Sjkim                    if (read(fileno(stdin), sbuf, 0) >= 0)
1626280304Sjkim                        stdin_set = 1;
1627280304Sjkim                    if (!i && (stdin_set != 1 || !read_tty))
1628280304Sjkim                        continue;
1629280304Sjkim                } else
1630280304Sjkim                    i = select(width, (void *)&readfds, (void *)&writefds,
1631280304Sjkim                               NULL, timeoutp);
1632280304Sjkim            }
1633280304Sjkim            (void)fcntl(fileno(stdin), F_SETFL, 0);
163459191Skris#else
1635280304Sjkim            i = select(width, (void *)&readfds, (void *)&writefds,
1636280304Sjkim                       NULL, timeoutp);
163759191Skris#endif
1638280304Sjkim            if (i < 0) {
1639280304Sjkim                BIO_printf(bio_err, "bad select %d\n",
1640280304Sjkim                           get_last_socket_error());
1641280304Sjkim                goto shut;
1642280304Sjkim                /* goto end; */
1643280304Sjkim            }
1644280304Sjkim        }
164555714Skris
1646280304Sjkim        if ((SSL_version(con) == DTLS1_VERSION)
1647280304Sjkim            && DTLSv1_handle_timeout(con) > 0) {
1648280304Sjkim            BIO_printf(bio_err, "TIMEOUT occured\n");
1649280304Sjkim        }
1650205128Ssimon
1651280304Sjkim        if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
1652280304Sjkim            k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len);
1653280304Sjkim            switch (SSL_get_error(con, k)) {
1654280304Sjkim            case SSL_ERROR_NONE:
1655280304Sjkim                cbuf_off += k;
1656280304Sjkim                cbuf_len -= k;
1657280304Sjkim                if (k <= 0)
1658280304Sjkim                    goto end;
1659280304Sjkim                /* we have done a  write(con,NULL,0); */
1660280304Sjkim                if (cbuf_len <= 0) {
1661280304Sjkim                    read_tty = 1;
1662280304Sjkim                    write_ssl = 0;
1663280304Sjkim                } else {        /* if (cbuf_len > 0) */
1664280304Sjkim
1665280304Sjkim                    read_tty = 0;
1666280304Sjkim                    write_ssl = 1;
1667280304Sjkim                }
1668280304Sjkim                break;
1669280304Sjkim            case SSL_ERROR_WANT_WRITE:
1670280304Sjkim                BIO_printf(bio_c_out, "write W BLOCK\n");
1671280304Sjkim                write_ssl = 1;
1672280304Sjkim                read_tty = 0;
1673280304Sjkim                break;
1674280304Sjkim            case SSL_ERROR_WANT_READ:
1675280304Sjkim                BIO_printf(bio_c_out, "write R BLOCK\n");
1676280304Sjkim                write_tty = 0;
1677280304Sjkim                read_ssl = 1;
1678280304Sjkim                write_ssl = 0;
1679280304Sjkim                break;
1680280304Sjkim            case SSL_ERROR_WANT_X509_LOOKUP:
1681280304Sjkim                BIO_printf(bio_c_out, "write X BLOCK\n");
1682280304Sjkim                break;
1683280304Sjkim            case SSL_ERROR_ZERO_RETURN:
1684280304Sjkim                if (cbuf_len != 0) {
1685280304Sjkim                    BIO_printf(bio_c_out, "shutdown\n");
1686280304Sjkim                    ret = 0;
1687280304Sjkim                    goto shut;
1688280304Sjkim                } else {
1689280304Sjkim                    read_tty = 1;
1690280304Sjkim                    write_ssl = 0;
1691280304Sjkim                    break;
1692280304Sjkim                }
1693280304Sjkim
1694280304Sjkim            case SSL_ERROR_SYSCALL:
1695280304Sjkim                if ((k != 0) || (cbuf_len != 0)) {
1696280304Sjkim                    BIO_printf(bio_err, "write:errno=%d\n",
1697280304Sjkim                               get_last_socket_error());
1698280304Sjkim                    goto shut;
1699280304Sjkim                } else {
1700280304Sjkim                    read_tty = 1;
1701280304Sjkim                    write_ssl = 0;
1702280304Sjkim                }
1703280304Sjkim                break;
1704280304Sjkim            case SSL_ERROR_SSL:
1705280304Sjkim                ERR_print_errors(bio_err);
1706280304Sjkim                goto shut;
1707280304Sjkim            }
1708280304Sjkim        }
1709238405Sjkim#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
1710280304Sjkim        /* Assume Windows/DOS/BeOS can always write */
1711280304Sjkim        else if (!ssl_pending && write_tty)
171259191Skris#else
1713280304Sjkim        else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds))
171459191Skris#endif
1715280304Sjkim        {
171655714Skris#ifdef CHARSET_EBCDIC
1717280304Sjkim            ascii2ebcdic(&(sbuf[sbuf_off]), &(sbuf[sbuf_off]), sbuf_len);
171855714Skris#endif
1719280304Sjkim            i = raw_write_stdout(&(sbuf[sbuf_off]), sbuf_len);
172055714Skris
1721280304Sjkim            if (i <= 0) {
1722280304Sjkim                BIO_printf(bio_c_out, "DONE\n");
1723280304Sjkim                ret = 0;
1724280304Sjkim                goto shut;
1725280304Sjkim                /* goto end; */
1726280304Sjkim            }
172755714Skris
1728280304Sjkim            sbuf_len -= i;;
1729280304Sjkim            sbuf_off += i;
1730280304Sjkim            if (sbuf_len <= 0) {
1731280304Sjkim                read_ssl = 1;
1732280304Sjkim                write_tty = 0;
1733280304Sjkim            }
1734280304Sjkim        } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) {
173555714Skris#ifdef RENEG
1736280304Sjkim            {
1737280304Sjkim                static int iiii;
1738280304Sjkim                if (++iiii == 52) {
1739280304Sjkim                    SSL_renegotiate(con);
1740280304Sjkim                    iiii = 0;
1741280304Sjkim                }
1742280304Sjkim            }
174355714Skris#endif
174455714Skris#if 1
1745280304Sjkim            k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ );
174655714Skris#else
174755714Skris/* Demo for pending and peek :-) */
1748280304Sjkim            k = SSL_read(con, sbuf, 16);
1749280304Sjkim            {
1750280304Sjkim                char zbuf[10240];
1751280304Sjkim                printf("read=%d pending=%d peek=%d\n", k, SSL_pending(con),
1752280304Sjkim                       SSL_peek(con, zbuf, 10240));
1753280304Sjkim            }
175455714Skris#endif
175555714Skris
1756280304Sjkim            switch (SSL_get_error(con, k)) {
1757280304Sjkim            case SSL_ERROR_NONE:
1758280304Sjkim                if (k <= 0)
1759280304Sjkim                    goto end;
1760280304Sjkim                sbuf_off = 0;
1761280304Sjkim                sbuf_len = k;
176255714Skris
1763280304Sjkim                read_ssl = 0;
1764280304Sjkim                write_tty = 1;
1765280304Sjkim                break;
1766280304Sjkim            case SSL_ERROR_WANT_WRITE:
1767280304Sjkim                BIO_printf(bio_c_out, "read W BLOCK\n");
1768280304Sjkim                write_ssl = 1;
1769280304Sjkim                read_tty = 0;
1770280304Sjkim                break;
1771280304Sjkim            case SSL_ERROR_WANT_READ:
1772280304Sjkim                BIO_printf(bio_c_out, "read R BLOCK\n");
1773280304Sjkim                write_tty = 0;
1774280304Sjkim                read_ssl = 1;
1775280304Sjkim                if ((read_tty == 0) && (write_ssl == 0))
1776280304Sjkim                    write_ssl = 1;
1777280304Sjkim                break;
1778280304Sjkim            case SSL_ERROR_WANT_X509_LOOKUP:
1779280304Sjkim                BIO_printf(bio_c_out, "read X BLOCK\n");
1780280304Sjkim                break;
1781280304Sjkim            case SSL_ERROR_SYSCALL:
1782280304Sjkim                ret = get_last_socket_error();
1783280304Sjkim                BIO_printf(bio_err, "read:errno=%d\n", ret);
1784280304Sjkim                goto shut;
1785280304Sjkim            case SSL_ERROR_ZERO_RETURN:
1786280304Sjkim                BIO_printf(bio_c_out, "closed\n");
1787280304Sjkim                ret = 0;
1788280304Sjkim                goto shut;
1789280304Sjkim            case SSL_ERROR_SSL:
1790280304Sjkim                ERR_print_errors(bio_err);
1791280304Sjkim                goto shut;
1792280304Sjkim                /* break; */
1793280304Sjkim            }
1794280304Sjkim        }
1795120631Snectar#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
1796280304Sjkim# if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
1797280304Sjkim        else if (_kbhit())
1798280304Sjkim# else
1799280304Sjkim        else if ((_kbhit())
1800280304Sjkim                 || (WAIT_OBJECT_0 ==
1801280304Sjkim                     WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
1802280304Sjkim# endif
1803160814Ssimon#elif defined (OPENSSL_SYS_NETWARE)
1804280304Sjkim        else if (_kbhit())
1805238405Sjkim#elif defined(OPENSSL_SYS_BEOS_R5)
1806280304Sjkim        else if (stdin_set)
180759191Skris#else
1808280304Sjkim        else if (FD_ISSET(fileno(stdin), &readfds))
180959191Skris#endif
1810280304Sjkim        {
1811280304Sjkim            if (crlf) {
1812280304Sjkim                int j, lf_num;
181355714Skris
1814280304Sjkim                i = raw_read_stdin(cbuf, BUFSIZZ / 2);
1815280304Sjkim                lf_num = 0;
1816280304Sjkim                /* both loops are skipped when i <= 0 */
1817280304Sjkim                for (j = 0; j < i; j++)
1818280304Sjkim                    if (cbuf[j] == '\n')
1819280304Sjkim                        lf_num++;
1820280304Sjkim                for (j = i - 1; j >= 0; j--) {
1821280304Sjkim                    cbuf[j + lf_num] = cbuf[j];
1822280304Sjkim                    if (cbuf[j] == '\n') {
1823280304Sjkim                        lf_num--;
1824280304Sjkim                        i++;
1825280304Sjkim                        cbuf[j + lf_num] = '\r';
1826280304Sjkim                    }
1827280304Sjkim                }
1828280304Sjkim                assert(lf_num == 0);
1829280304Sjkim            } else
1830280304Sjkim                i = raw_read_stdin(cbuf, BUFSIZZ);
183155714Skris
1832280304Sjkim            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) {
1833280304Sjkim                BIO_printf(bio_err, "DONE\n");
1834280304Sjkim                ret = 0;
1835280304Sjkim                goto shut;
1836280304Sjkim            }
183755714Skris
1838280304Sjkim            if ((!c_ign_eof) && (cbuf[0] == 'R')) {
1839280304Sjkim                BIO_printf(bio_err, "RENEGOTIATING\n");
1840280304Sjkim                SSL_renegotiate(con);
1841280304Sjkim                cbuf_len = 0;
1842280304Sjkim            }
1843238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS
1844280304Sjkim            else if ((!c_ign_eof) && (cbuf[0] == 'B')) {
1845280304Sjkim                BIO_printf(bio_err, "HEARTBEATING\n");
1846280304Sjkim                SSL_heartbeat(con);
1847280304Sjkim                cbuf_len = 0;
1848280304Sjkim            }
1849238405Sjkim#endif
1850280304Sjkim            else {
1851280304Sjkim                cbuf_len = i;
1852280304Sjkim                cbuf_off = 0;
185355714Skris#ifdef CHARSET_EBCDIC
1854280304Sjkim                ebcdic2ascii(cbuf, cbuf, i);
185555714Skris#endif
1856280304Sjkim            }
185755714Skris
1858280304Sjkim            write_ssl = 1;
1859280304Sjkim            read_tty = 0;
1860280304Sjkim        }
1861280304Sjkim    }
1862238405Sjkim
1863280304Sjkim    ret = 0;
1864280304Sjkim shut:
1865280304Sjkim    if (in_init)
1866280304Sjkim        print_stuff(bio_c_out, con, full_log);
1867280304Sjkim    SSL_shutdown(con);
1868280304Sjkim    SHUTDOWN(SSL_get_fd(con));
1869280304Sjkim end:
1870280304Sjkim    if (con != NULL) {
1871280304Sjkim        if (prexit != 0)
1872280304Sjkim            print_stuff(bio_c_out, con, 1);
1873280304Sjkim        SSL_free(con);
1874280304Sjkim    }
1875246772Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
1876280304Sjkim    if (next_proto.data)
1877280304Sjkim        OPENSSL_free(next_proto.data);
1878246772Sjkim#endif
1879280304Sjkim    if (ctx != NULL)
1880280304Sjkim        SSL_CTX_free(ctx);
1881280304Sjkim    if (cert)
1882280304Sjkim        X509_free(cert);
1883280304Sjkim    if (key)
1884280304Sjkim        EVP_PKEY_free(key);
1885280304Sjkim    if (pass)
1886280304Sjkim        OPENSSL_free(pass);
1887291721Sjkim#ifndef OPENSSL_NO_SRP
1888291721Sjkim    OPENSSL_free(srp_arg.srppassin);
1889291721Sjkim#endif
1890280304Sjkim    if (vpm)
1891280304Sjkim        X509_VERIFY_PARAM_free(vpm);
1892280304Sjkim    if (cbuf != NULL) {
1893280304Sjkim        OPENSSL_cleanse(cbuf, BUFSIZZ);
1894280304Sjkim        OPENSSL_free(cbuf);
1895280304Sjkim    }
1896280304Sjkim    if (sbuf != NULL) {
1897280304Sjkim        OPENSSL_cleanse(sbuf, BUFSIZZ);
1898280304Sjkim        OPENSSL_free(sbuf);
1899280304Sjkim    }
1900280304Sjkim    if (mbuf != NULL) {
1901280304Sjkim        OPENSSL_cleanse(mbuf, BUFSIZZ);
1902280304Sjkim        OPENSSL_free(mbuf);
1903280304Sjkim    }
1904280304Sjkim    if (bio_c_out != NULL) {
1905280304Sjkim        BIO_free(bio_c_out);
1906280304Sjkim        bio_c_out = NULL;
1907280304Sjkim    }
1908280304Sjkim    apps_shutdown();
1909280304Sjkim    OPENSSL_EXIT(ret);
1910280304Sjkim}
191155714Skris
191255714Skrisstatic void print_stuff(BIO *bio, SSL *s, int full)
1913280304Sjkim{
1914280304Sjkim    X509 *peer = NULL;
1915280304Sjkim    char *p;
1916280304Sjkim    static const char *space = "                ";
1917280304Sjkim    char buf[BUFSIZ];
1918280304Sjkim    STACK_OF(X509) *sk;
1919280304Sjkim    STACK_OF(X509_NAME) *sk2;
1920280304Sjkim    const SSL_CIPHER *c;
1921280304Sjkim    X509_NAME *xn;
1922280304Sjkim    int j, i;
1923160814Ssimon#ifndef OPENSSL_NO_COMP
1924280304Sjkim    const COMP_METHOD *comp, *expansion;
1925160814Ssimon#endif
1926280304Sjkim    unsigned char *exportedkeymat;
192755714Skris
1928280304Sjkim    if (full) {
1929280304Sjkim        int got_a_chain = 0;
193055714Skris
1931280304Sjkim        sk = SSL_get_peer_cert_chain(s);
1932280304Sjkim        if (sk != NULL) {
1933280304Sjkim            got_a_chain = 1;    /* we don't have it for SSL2 (yet) */
193455714Skris
1935280304Sjkim            BIO_printf(bio, "---\nCertificate chain\n");
1936280304Sjkim            for (i = 0; i < sk_X509_num(sk); i++) {
1937280304Sjkim                X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)),
1938280304Sjkim                                  buf, sizeof buf);
1939280304Sjkim                BIO_printf(bio, "%2d s:%s\n", i, buf);
1940280304Sjkim                X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)),
1941280304Sjkim                                  buf, sizeof buf);
1942280304Sjkim                BIO_printf(bio, "   i:%s\n", buf);
1943280304Sjkim                if (c_showcerts)
1944280304Sjkim                    PEM_write_bio_X509(bio, sk_X509_value(sk, i));
1945280304Sjkim            }
1946280304Sjkim        }
194755714Skris
1948280304Sjkim        BIO_printf(bio, "---\n");
1949280304Sjkim        peer = SSL_get_peer_certificate(s);
1950280304Sjkim        if (peer != NULL) {
1951280304Sjkim            BIO_printf(bio, "Server certificate\n");
195255714Skris
1953280304Sjkim            /* Redundant if we showed the whole chain */
1954280304Sjkim            if (!(c_showcerts && got_a_chain))
1955280304Sjkim                PEM_write_bio_X509(bio, peer);
1956280304Sjkim            X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
1957280304Sjkim            BIO_printf(bio, "subject=%s\n", buf);
1958280304Sjkim            X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
1959280304Sjkim            BIO_printf(bio, "issuer=%s\n", buf);
1960280304Sjkim        } else
1961280304Sjkim            BIO_printf(bio, "no peer certificate available\n");
196255714Skris
1963280304Sjkim        sk2 = SSL_get_client_CA_list(s);
1964280304Sjkim        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
1965280304Sjkim            BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
1966280304Sjkim            for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
1967280304Sjkim                xn = sk_X509_NAME_value(sk2, i);
1968280304Sjkim                X509_NAME_oneline(xn, buf, sizeof(buf));
1969280304Sjkim                BIO_write(bio, buf, strlen(buf));
1970280304Sjkim                BIO_write(bio, "\n", 1);
1971280304Sjkim            }
1972280304Sjkim        } else {
1973280304Sjkim            BIO_printf(bio, "---\nNo client certificate CA names sent\n");
1974280304Sjkim        }
1975280304Sjkim        p = SSL_get_shared_ciphers(s, buf, sizeof buf);
1976280304Sjkim        if (p != NULL) {
1977280304Sjkim            /*
1978280304Sjkim             * This works only for SSL 2.  In later protocol versions, the
1979280304Sjkim             * client does not know what other ciphers (in addition to the
1980280304Sjkim             * one to be used in the current connection) the server supports.
1981280304Sjkim             */
198255714Skris
1983280304Sjkim            BIO_printf(bio,
1984280304Sjkim                       "---\nCiphers common between both SSL endpoints:\n");
1985280304Sjkim            j = i = 0;
1986280304Sjkim            while (*p) {
1987280304Sjkim                if (*p == ':') {
1988280304Sjkim                    BIO_write(bio, space, 15 - j % 25);
1989280304Sjkim                    i++;
1990280304Sjkim                    j = 0;
1991280304Sjkim                    BIO_write(bio, ((i % 3) ? " " : "\n"), 1);
1992280304Sjkim                } else {
1993280304Sjkim                    BIO_write(bio, p, 1);
1994280304Sjkim                    j++;
1995280304Sjkim                }
1996280304Sjkim                p++;
1997280304Sjkim            }
1998280304Sjkim            BIO_write(bio, "\n", 1);
1999280304Sjkim        }
2000280304Sjkim
2001280304Sjkim        BIO_printf(bio,
2002280304Sjkim                   "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
2003280304Sjkim                   BIO_number_read(SSL_get_rbio(s)),
2004280304Sjkim                   BIO_number_written(SSL_get_wbio(s)));
2005280304Sjkim    }
2006280304Sjkim    BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
2007280304Sjkim    c = SSL_get_current_cipher(s);
2008280304Sjkim    BIO_printf(bio, "%s, Cipher is %s\n",
2009280304Sjkim               SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
2010280304Sjkim    if (peer != NULL) {
2011280304Sjkim        EVP_PKEY *pktmp;
2012280304Sjkim        pktmp = X509_get_pubkey(peer);
2013280304Sjkim        BIO_printf(bio, "Server public key is %d bit\n",
2014280304Sjkim                   EVP_PKEY_bits(pktmp));
2015280304Sjkim        EVP_PKEY_free(pktmp);
2016280304Sjkim    }
2017280304Sjkim    BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
2018280304Sjkim               SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
2019160814Ssimon#ifndef OPENSSL_NO_COMP
2020280304Sjkim    comp = SSL_get_current_compression(s);
2021280304Sjkim    expansion = SSL_get_current_expansion(s);
2022280304Sjkim    BIO_printf(bio, "Compression: %s\n",
2023280304Sjkim               comp ? SSL_COMP_get_name(comp) : "NONE");
2024280304Sjkim    BIO_printf(bio, "Expansion: %s\n",
2025280304Sjkim               expansion ? SSL_COMP_get_name(expansion) : "NONE");
2026160814Ssimon#endif
2027280304Sjkim
2028238405Sjkim#ifdef SSL_DEBUG
2029280304Sjkim    {
2030280304Sjkim        /* Print out local port of connection: useful for debugging */
2031280304Sjkim        int sock;
2032280304Sjkim        struct sockaddr_in ladd;
2033280304Sjkim        socklen_t ladd_size = sizeof(ladd);
2034280304Sjkim        sock = SSL_get_fd(s);
2035280304Sjkim        getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
2036280304Sjkim        BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
2037280304Sjkim    }
2038238405Sjkim#endif
2039238405Sjkim
2040238405Sjkim#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
2041280304Sjkim    if (next_proto.status != -1) {
2042280304Sjkim        const unsigned char *proto;
2043280304Sjkim        unsigned int proto_len;
2044280304Sjkim        SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
2045280304Sjkim        BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
2046280304Sjkim        BIO_write(bio, proto, proto_len);
2047280304Sjkim        BIO_write(bio, "\n", 1);
2048280304Sjkim    }
2049238405Sjkim#endif
2050238405Sjkim
2051246772Sjkim#ifndef OPENSSL_NO_SRTP
2052280304Sjkim    {
2053280304Sjkim        SRTP_PROTECTION_PROFILE *srtp_profile =
2054280304Sjkim            SSL_get_selected_srtp_profile(s);
2055280304Sjkim
2056280304Sjkim        if (srtp_profile)
2057280304Sjkim            BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n",
2058280304Sjkim                       srtp_profile->name);
2059280304Sjkim    }
2060246772Sjkim#endif
206155714Skris
2062280304Sjkim    SSL_SESSION_print(bio, SSL_get_session(s));
2063280304Sjkim    if (keymatexportlabel != NULL) {
2064280304Sjkim        BIO_printf(bio, "Keying material exporter:\n");
2065280304Sjkim        BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
2066280304Sjkim        BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
2067280304Sjkim        exportedkeymat = OPENSSL_malloc(keymatexportlen);
2068280304Sjkim        if (exportedkeymat != NULL) {
2069280304Sjkim            if (!SSL_export_keying_material(s, exportedkeymat,
2070280304Sjkim                                            keymatexportlen,
2071280304Sjkim                                            keymatexportlabel,
2072280304Sjkim                                            strlen(keymatexportlabel),
2073280304Sjkim                                            NULL, 0, 0)) {
2074280304Sjkim                BIO_printf(bio, "    Error\n");
2075280304Sjkim            } else {
2076280304Sjkim                BIO_printf(bio, "    Keying material: ");
2077280304Sjkim                for (i = 0; i < keymatexportlen; i++)
2078280304Sjkim                    BIO_printf(bio, "%02X", exportedkeymat[i]);
2079280304Sjkim                BIO_printf(bio, "\n");
2080280304Sjkim            }
2081280304Sjkim            OPENSSL_free(exportedkeymat);
2082280304Sjkim        }
2083280304Sjkim    }
2084280304Sjkim    BIO_printf(bio, "---\n");
2085280304Sjkim    if (peer != NULL)
2086280304Sjkim        X509_free(peer);
2087280304Sjkim    /* flush, or debugging output gets mixed with http response */
2088280304Sjkim    (void)BIO_flush(bio);
2089280304Sjkim}
2090280304Sjkim
2091194206Ssimon#ifndef OPENSSL_NO_TLSEXT
2092194206Ssimon
2093194206Ssimonstatic int ocsp_resp_cb(SSL *s, void *arg)
2094280304Sjkim{
2095280304Sjkim    const unsigned char *p;
2096280304Sjkim    int len;
2097280304Sjkim    OCSP_RESPONSE *rsp;
2098280304Sjkim    len = SSL_get_tlsext_status_ocsp_resp(s, &p);
2099280304Sjkim    BIO_puts(arg, "OCSP response: ");
2100280304Sjkim    if (!p) {
2101280304Sjkim        BIO_puts(arg, "no response sent\n");
2102280304Sjkim        return 1;
2103280304Sjkim    }
2104280304Sjkim    rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
2105280304Sjkim    if (!rsp) {
2106280304Sjkim        BIO_puts(arg, "response parse error\n");
2107280304Sjkim        BIO_dump_indent(arg, (char *)p, len, 4);
2108280304Sjkim        return 0;
2109280304Sjkim    }
2110280304Sjkim    BIO_puts(arg, "\n======================================\n");
2111280304Sjkim    OCSP_RESPONSE_print(arg, rsp, 0);
2112280304Sjkim    BIO_puts(arg, "======================================\n");
2113280304Sjkim    OCSP_RESPONSE_free(rsp);
2114280304Sjkim    return 1;
2115280304Sjkim}
2116238405Sjkim
2117238405Sjkim#endif
2118