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