X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_client.c;h=559cf706a7af351fffca1a0101409147c554d874;hp=0c4e6bdbd97dde22fc012e5075a57d6c1f0922dc;hb=13cbe5e711528da65753ad526ad69de406250402;hpb=f4002412518703d07fee321d4c88ee0bbe1694fe diff --git a/apps/s_client.c b/apps/s_client.c index 0c4e6bdbd9..559cf706a7 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1,4 +1,3 @@ -/* apps/s_client.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -135,12 +134,12 @@ * OTHERWISE. */ -#include #include #include #include #include #include + /* * With IPv6, it looks like Digital has mixed up the proper order of * recursive header file inclusion, resulting in the compiler complaining @@ -172,22 +171,8 @@ typedef unsigned int u_int; # undef FIONBIO #endif -#undef PROG -#define PROG s_client_main - -/* - * #define SSL_HOST_NAME "www.netscape.com" - */ -/* - * #define SSL_HOST_NAME "193.118.187.102" - */ #define SSL_HOST_NAME "localhost" -/* no default cert. */ -/* - * #define TEST_CERT "client.pem" - */ - #undef BUFSIZZ #define BUFSIZZ 1024*8 @@ -196,32 +181,24 @@ extern int verify_error; extern int verify_return_error; extern int verify_quiet; -#ifdef FIONBIO static int c_nbio = 0; -#endif -static int c_Pause = 0; -static int c_debug = 0; -#ifndef OPENSSL_NO_TLSEXT static int c_tlsextdebug = 0; static int c_status_req = 0; -#endif +static int c_Pause = 0; +static int c_debug = 0; static int c_msg = 0; static int c_showcerts = 0; - static char *keymatexportlabel = NULL; static int keymatexportlen = 20; - -static void sc_usage(void); -static void print_stuff(BIO *berr, SSL *con, int full); -#ifndef OPENSSL_NO_TLSEXT -static int ocsp_resp_cb(SSL *s, void *arg); -#endif static BIO *bio_c_out = NULL; static BIO *bio_c_msg = NULL; static int c_quiet = 0; static int c_ign_eof = 0; static int c_brief = 0; +static void print_stuff(BIO *berr, SSL *con, int full); +static int ocsp_resp_cb(SSL *s, void *arg); + #ifndef OPENSSL_NO_PSK /* Default PSK identity and key */ static char *psk_identity = "Client_identity"; @@ -261,8 +238,7 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, if (!ret) { BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", psk_key); - if (bn) - BN_free(bn); + BN_free(bn); return 0; } @@ -290,147 +266,6 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, } #endif -static void sc_usage(void) -{ - BIO_printf(bio_err, "usage: s_client args\n"); - BIO_printf(bio_err, "\n"); - BIO_printf(bio_err, " -host host - use -connect instead\n"); - BIO_printf(bio_err, " -port port - use -connect instead\n"); - BIO_printf(bio_err, - " -connect host:port - connect over TCP/IP (default is %s:%s)\n", - SSL_HOST_NAME, PORT_STR); - BIO_printf(bio_err, - " -unix path - connect over unix domain sockets\n"); - BIO_printf(bio_err, - " -verify arg - turn on peer certificate verification\n"); - BIO_printf(bio_err, - " -verify_return_error - return verification errors\n"); - BIO_printf(bio_err, - " -cert arg - certificate file to use, PEM format assumed\n"); - BIO_printf(bio_err, - " -certform arg - certificate format (PEM or DER) PEM default\n"); - BIO_printf(bio_err, - " -key arg - Private key file to use, in cert file if\n"); - BIO_printf(bio_err, " not specified but cert file is.\n"); - BIO_printf(bio_err, - " -keyform arg - key format (PEM or DER) PEM default\n"); - BIO_printf(bio_err, - " -pass arg - private key file pass phrase source\n"); - BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); - BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); - BIO_printf(bio_err, - " -trusted_first - Use local CA's first when building trust chain\n"); - BIO_printf(bio_err, - " -reconnect - Drop and re-make the connection with the same Session-ID\n"); - BIO_printf(bio_err, - " -pause - sleep(1) after each read(2) and write(2) system call\n"); - BIO_printf(bio_err, - " -prexit - print session information even on connection failure\n"); - BIO_printf(bio_err, - " -showcerts - show all certificates in the chain\n"); - BIO_printf(bio_err, " -debug - extra output\n"); -#ifdef WATT32 - BIO_printf(bio_err, " -wdebug - WATT-32 tcp debugging\n"); -#endif - BIO_printf(bio_err, " -msg - Show protocol messages\n"); - BIO_printf(bio_err, " -nbio_test - more ssl protocol testing\n"); - BIO_printf(bio_err, " -state - print the 'ssl' states\n"); -#ifdef FIONBIO - BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); -#endif - BIO_printf(bio_err, - " -crlf - convert LF from terminal into CRLF\n"); - BIO_printf(bio_err, " -quiet - no s_client output\n"); - BIO_printf(bio_err, - " -ign_eof - ignore input eof (default when -quiet)\n"); - BIO_printf(bio_err, " -no_ign_eof - don't ignore input eof\n"); -#ifndef OPENSSL_NO_PSK - BIO_printf(bio_err, " -psk_identity arg - PSK identity\n"); - BIO_printf(bio_err, " -psk arg - PSK in hex (without 0x)\n"); -# ifndef OPENSSL_NO_JPAKE - BIO_printf(bio_err, " -jpake arg - JPAKE secret to use\n"); -# endif -#endif -#ifndef OPENSSL_NO_SRP - BIO_printf(bio_err, - " -srpuser user - SRP authentification for 'user'\n"); - BIO_printf(bio_err, " -srppass arg - password for 'user'\n"); - BIO_printf(bio_err, - " -srp_lateuser - SRP username into second ClientHello message\n"); - BIO_printf(bio_err, - " -srp_moregroups - Tolerate other than the known g N values.\n"); - BIO_printf(bio_err, - " -srp_strength int - minimal length in bits for N (default %d).\n", - SRP_MINIMAL_N); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - BIO_printf(bio_err, " -ssl3 - just use SSLv3\n"); -#endif - BIO_printf(bio_err, " -tls1_2 - just use TLSv1.2\n"); - BIO_printf(bio_err, " -tls1_1 - just use TLSv1.1\n"); - BIO_printf(bio_err, " -tls1 - just use TLSv1\n"); - BIO_printf(bio_err, " -dtls1 - just use DTLSv1\n"); - BIO_printf(bio_err, " -fallback_scsv - send TLS_FALLBACK_SCSV\n"); - BIO_printf(bio_err, " -mtu - set the link layer MTU\n"); - BIO_printf(bio_err, - " -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3 - turn off that protocol\n"); - BIO_printf(bio_err, - " -bugs - Switch on all SSL implementation bug workarounds\n"); - BIO_printf(bio_err, - " -cipher - preferred cipher to use, use the 'openssl ciphers'\n"); - BIO_printf(bio_err, - " command to see what is available\n"); - BIO_printf(bio_err, - " -starttls prot - use the STARTTLS command before starting TLS\n"); - BIO_printf(bio_err, - " for those protocols that support it, where\n"); - BIO_printf(bio_err, - " 'prot' defines which one to assume. Currently,\n"); - BIO_printf(bio_err, - " only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n"); - BIO_printf(bio_err, " are supported.\n"); - BIO_printf(bio_err, - " -xmpphost host - When used with \"-starttls xmpp\" specifies the virtual host.\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine id - Initialise and use the specified engine\n"); -#endif - BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, - LIST_SEPARATOR_CHAR); - BIO_printf(bio_err, " -sess_out arg - file to write SSL session to\n"); - BIO_printf(bio_err, " -sess_in arg - file to read SSL session from\n"); -#ifndef OPENSSL_NO_TLSEXT - BIO_printf(bio_err, - " -servername host - Set TLS extension servername in ClientHello\n"); - BIO_printf(bio_err, - " -tlsextdebug - hex dump of all TLS extensions received\n"); - BIO_printf(bio_err, - " -status - request certificate status from server\n"); - BIO_printf(bio_err, - " -no_ticket - disable use of RFC4507bis session tickets\n"); - BIO_printf(bio_err, - " -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n"); -# ifndef OPENSSL_NO_NEXTPROTONEG - BIO_printf(bio_err, - " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); -# endif - BIO_printf(bio_err, - " -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n"); -#endif - BIO_printf(bio_err, - " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); -#ifndef OPENSSL_NO_SRTP - BIO_printf(bio_err, - " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); -#endif - BIO_printf(bio_err, - " -keymatexport label - Export keying material using label\n"); - BIO_printf(bio_err, - " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); -} - -#ifndef OPENSSL_NO_TLSEXT - /* This is a context that we pass to callbacks */ typedef struct tlsextctx_st { BIO *biodebug; @@ -449,7 +284,7 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg) return SSL_TLSEXT_ERR_OK; } -# ifndef OPENSSL_NO_SRP +#ifndef OPENSSL_NO_SRP /* This is a context that we pass to all callbacks */ typedef struct srp_arg_st { @@ -461,7 +296,7 @@ typedef struct srp_arg_st { int strength /* minimal size for N */ ; } SRP_ARG; -# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64 +# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64 static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) { @@ -479,12 +314,9 @@ static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) BN_mod_exp(r, g, p, N, bn_ctx) && BN_add_word(r, 1) && BN_cmp(r, N) == 0; - if (r) - BN_free(r); - if (p) - BN_free(p); - if (bn_ctx) - BN_CTX_free(bn_ctx); + BN_free(r); + BN_free(p); + BN_CTX_free(bn_ctx); return ret; } @@ -508,7 +340,8 @@ static int ssl_srp_verify_param_cb(SSL *s, void *arg) { SRP_ARG *srp_arg = (SRP_ARG *)arg; BIGNUM *N = NULL, *g = NULL; - if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s))) + + if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL)) return 0; if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) { BIO_printf(bio_err, "SRP parameters:\n"); @@ -539,12 +372,12 @@ static int ssl_srp_verify_param_cb(SSL *s, void *arg) return 0; } -# define PWD_STRLEN 1024 +# define PWD_STRLEN 1024 static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) { SRP_ARG *srp_arg = (SRP_ARG *)arg; - char *pass = (char *)OPENSSL_malloc(PWD_STRLEN + 1); + char *pass = app_malloc(PWD_STRLEN + 1, "SRP password buffer"); PW_CB_DATA cb_tmp; int l; @@ -560,12 +393,11 @@ static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg) return pass; } -# endif -# ifndef OPENSSL_NO_SRTP +#endif + char *srtp_profiles = NULL; -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG /* This the context that we pass to next_proto_cb */ typedef struct tlsextnextprotoctx_st { unsigned char *data; @@ -598,7 +430,7 @@ static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen, SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len); return SSL_TLSEXT_ERR_OK; } -# endif /* ndef OPENSSL_NO_NEXTPROTONEG */ +#endif /* ndef OPENSSL_NO_NEXTPROTONEG */ static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, @@ -620,507 +452,617 @@ static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, return 1; } +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX, OPT_XMPPHOST, OPT_VERIFY, + OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN, + OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, + OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO, + OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF, + OPT_PAUSE, OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG, + OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG, + OPT_SECURITY_DEBUG_VERBOSE, OPT_SHOWCERTS, OPT_NBIO_TEST, OPT_STATE, + OPT_PSK_IDENTITY, OPT_PSK, OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, + OPT_SRP_LATEUSER, OPT_SRP_MOREGROUPS, OPT_SSL3, + OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, + OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, + OPT_CERT_CHAIN, OPT_CAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, + OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, + OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN, + OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_JPAKE, + OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST, + OPT_V_ENUM, + OPT_X_ENUM, + OPT_S_ENUM, + OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY +} OPTION_CHOICE; + +OPTIONS s_client_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"host", OPT_HOST, 's', "Use -connect instead"}, + {"port", OPT_PORT, 'p', "Use -connect instead"}, + {"connect", OPT_CONNECT, 's', + "TCP/IP where to connect (default is " SSL_HOST_NAME ":" PORT_STR ")"}, + {"proxy", OPT_PROXY, 's', + "Connect to via specified proxy to the real server"}, + {"unix", OPT_UNIX, 's', "Connect over unix domain sockets"}, + {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, + {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"}, + {"certform", OPT_CERTFORM, 'F', + "Certificate format (PEM or DER) PEM default"}, + {"key", OPT_KEY, '<', "Private key file to use, if not in -cert file"}, + {"keyform", OPT_KEYFORM, 'F', "Key format (PEM or DER) PEM default"}, + {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"reconnect", OPT_RECONNECT, '-', + "Drop and re-make the connection with the same Session-ID"}, + {"pause", OPT_PAUSE, '-', "Sleep after each read and write system call"}, + {"showcerts", OPT_SHOWCERTS, '-', "Show all certificates in the chain"}, + {"debug", OPT_DEBUG, '-', "Extra output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>'}, + {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, + {"state", OPT_STATE, '-', "Print the ssl states"}, + {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, + {"quiet", OPT_QUIET, '-', "No s_client output"}, + {"ign_eof", OPT_IGN_EOF, '-', "Ignore input eof (default when -quiet)"}, + {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Don't ignore input eof"}, + {"tls1_2", OPT_TLS1_2, '-', "Just use TLSv1.2"}, + {"tls1_1", OPT_TLS1_1, '-', "Just use TLSv1.1"}, + {"tls1", OPT_TLS1, '-', "Just use TLSv1"}, + {"starttls", OPT_STARTTLS, 's', + "Use the STARTTLS command before starting TLS"}, + {"xmpphost", OPT_XMPPHOST, 's', "Host to use with \"-starttls xmpp\""}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, + {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, + {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, + {"use_srtp", OPT_USE_SRTP, '<', + "Offer SRTP key management with a colon-separated profile list"}, + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material (default 20)"}, + {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, + {"name", OPT_SMTPHOST, 's', "Hostname to use for \"-starttls smtp\""}, + {"CRL", OPT_CRL, '<'}, + {"crl_download", OPT_CRL_DOWNLOAD, '-'}, + {"CRLform", OPT_CRLFORM, 'F'}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-'}, + {"verify_quiet", OPT_VERIFY_QUIET, '-'}, + {"brief", OPT_BRIEF, '-'}, + {"prexit", OPT_PREXIT, '-'}, + {"security_debug", OPT_SECURITY_DEBUG, '-'}, + {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-'}, + {"cert_chain", OPT_CERT_CHAIN, '<'}, + {"chainCApath", OPT_CHAINCAPATH, '/'}, + {"verifyCApath", OPT_VERIFYCAPATH, '/'}, + {"build_chain", OPT_BUILD_CHAIN, '-'}, + {"chainCAfile", OPT_CHAINCAFILE, '<'}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<'}, + {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"}, + {"servername", OPT_SERVERNAME, 's', + "Set TLS extension servername in ClientHello"}, + {"tlsextdebug", OPT_TLSEXTDEBUG, '-', + "Hex dump of all TLS extensions received"}, + {"status", OPT_STATUS, '-', "Request certificate status from server"}, + {"serverinfo", OPT_SERVERINFO, 's', + "types Send empty ClientHello extensions (comma-separated numbers)"}, + {"alpn", OPT_ALPN, 's', + "Enable ALPN extension, considering named protocols supported (comma-separated list)"}, + OPT_S_OPTIONS, + OPT_V_OPTIONS, + OPT_X_OPTIONS, +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, +#endif +#ifndef OPENSSL_NO_DTLS1 + {"dtls", OPT_DTLS, '-'}, + {"dtls1", OPT_DTLS1, '-', "Just use DTLSv1"}, + {"dtls1_2", OPT_DTLS1_2, '-'}, + {"timeout", OPT_TIMEOUT, '-'}, + {"mtu", OPT_MTU, 'p', "Set the link layer MTU"}, +#endif +#ifndef OPENSSL_NO_SSL_TRACE + {"trace", OPT_TRACE, '-'}, #endif +#ifdef WATT32 + {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, +#endif +#ifdef FIONBIO + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, +#endif +#ifndef OPENSSL_NO_PSK + {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, +# ifndef OPENSSL_NO_JPAKE + {"jpake", OPT_JPAKE, 's', "JPAKE secret to use"}, +# endif +#endif +#ifndef OPENSSL_NO_SRP + {"srpuser", OPT_SRPUSER, 's', "SRP authentification for 'user'"}, + {"srppass", OPT_SRPPASS, 's', "Password for 'user'"}, + {"srp_lateuser", OPT_SRP_LATEUSER, '-', + "SRP username into second ClientHello message"}, + {"srp_moregroups", OPT_SRP_MOREGROUPS, '-', + "Tolerate other than the known g N values."}, + {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal mength in bits for N"}, +#endif +#ifndef OPENSSL_NO_NEXTPROTONEG + {"nextprotoneg", OPT_NEXTPROTONEG, 's', + "Enable NPN extension, considering named protocols supported (comma-separated list)"}, +#endif +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's'}, +#endif + {NULL} +}; -enum { - PROTO_OFF = 0, +typedef enum PROTOCOL_choice { + PROTO_OFF, PROTO_SMTP, PROTO_POP3, PROTO_IMAP, PROTO_FTP, - PROTO_XMPP + PROTO_TELNET, + PROTO_XMPP, + PROTO_CONNECT +} PROTOCOL_CHOICE; + +static OPT_PAIR services[] = { + {"smtp", PROTO_SMTP}, + {"pop3", PROTO_POP3}, + {"imap", PROTO_IMAP}, + {"ftp", PROTO_FTP}, + {"xmpp", PROTO_XMPP}, + {"telnet", PROTO_TELNET}, + {NULL} }; -int MAIN(int, char **); - -int MAIN(int argc, char **argv) +int s_client_main(int argc, char **argv) { - int build_chain = 0; - SSL *con = NULL; -#ifndef OPENSSL_NO_KRB5 - KSSL_CTX *kctx; -#endif - int s, k, width, state = 0; - char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; - int cbuf_len, cbuf_off; - int sbuf_len, sbuf_off; - fd_set readfds, writefds; - short port = PORT; - int full_log = 1; - char *host = SSL_HOST_NAME; - const char *unix_path = NULL; - char *xmpphost = NULL; - char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; - int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; - char *passarg = NULL, *pass = NULL; - X509 *cert = NULL; + BIO *sbio; EVP_PKEY *key = NULL; - STACK_OF(X509) *chain = NULL; - char *CApath = NULL, *CAfile = NULL; - char *chCApath = NULL, *chCAfile = NULL; - char *vfyCApath = NULL, *vfyCAfile = NULL; - int reconnect = 0, badop = 0, verify = SSL_VERIFY_NONE; - int crlf = 0; - int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; + SSL *con = NULL; SSL_CTX *ctx = NULL; - int ret = 1, in_init = 1, i, nbio_test = 0; - int starttls_proto = PROTO_OFF; - int prexit = 0; + STACK_OF(X509) *chain = NULL; + X509 *cert = NULL; X509_VERIFY_PARAM *vpm = NULL; - int badarg = 0; - const SSL_METHOD *meth = NULL; - int socket_type = SOCK_STREAM; - BIO *sbio; + SSL_EXCERT *exc = NULL; + SSL_CONF_CTX *cctx = NULL; + STACK_OF(OPENSSL_STRING) *ssl_args = NULL; + STACK_OF(X509_CRL) *crls = NULL; + const SSL_METHOD *meth = TLS_client_method(); + char *CApath = NULL, *CAfile = NULL, *cbuf = NULL, *sbuf = NULL; + char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL; + char *cert_file = NULL, *key_file = NULL, *chain_file = NULL, *prog; + char *chCApath = NULL, *chCAfile = NULL, *host = SSL_HOST_NAME; char *inrand = NULL; - int mbuf_len = 0; + char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p; + char *jpake_secret = NULL, *xmpphost = NULL; + const char *unix_path = NULL; + const char *ehlo = "mail.example.com"; + struct sockaddr peer; struct timeval timeout, *timeoutp; + fd_set readfds, writefds; + int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM; + int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0; + int prexit = 0; + int enable_timeouts = 0, sdebug = 0, peerlen = sizeof peer; + int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; + int ret = 1, in_init = 1, i, nbio_test = 0, s, k, width, state = 0; + int sbuf_len, sbuf_off, socket_type = SOCK_STREAM, cmdletters = 1; + int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; + int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending; + int fallback_scsv = 0; + long socket_mtu = 0, randamt = 0; + unsigned short port = PORT; + OPTION_CHOICE o; #ifndef OPENSSL_NO_ENGINE - char *engine_id = NULL; - char *ssl_client_engine_id = NULL; ENGINE *ssl_client_engine = NULL; #endif ENGINE *e = NULL; #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) struct timeval tv; #endif -#ifndef OPENSSL_NO_TLSEXT char *servername = NULL; - tlsextctx tlsextcbp = { NULL, 0 }; -# ifndef OPENSSL_NO_NEXTPROTONEG - const char *next_proto_neg_in = NULL; -# endif const char *alpn_in = NULL; -# define MAX_SI_TYPES 100 + tlsextctx tlsextcbp = { NULL, 0 }; +#define MAX_SI_TYPES 100 unsigned short serverinfo_types[MAX_SI_TYPES]; - int serverinfo_types_count = 0; -#endif - char *sess_in = NULL; - char *sess_out = NULL; - struct sockaddr peer; - int peerlen = sizeof(peer); - int fallback_scsv = 0; - int enable_timeouts = 0; - long socket_mtu = 0; -#ifndef OPENSSL_NO_JPAKE - static char *jpake_secret = NULL; -# define no_jpake !jpake_secret -#else -# define no_jpake 1 + int serverinfo_count = 0, start = 0, len; +#ifndef OPENSSL_NO_NEXTPROTONEG + const char *next_proto_neg_in = NULL; #endif #ifndef OPENSSL_NO_SRP char *srppass = NULL; int srp_lateuser = 0; SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 }; #endif - SSL_EXCERT *exc = NULL; - - SSL_CONF_CTX *cctx = NULL; - STACK_OF(OPENSSL_STRING) *ssl_args = NULL; - char *crl_file = NULL; - int crl_format = FORMAT_PEM; - int crl_download = 0; - STACK_OF(X509_CRL) *crls = NULL; - int sdebug = 0; - - meth = SSLv23_client_method(); - - apps_startup(); + prog = opt_progname(argv[0]); c_Pause = 0; c_quiet = 0; c_ign_eof = 0; c_debug = 0; c_msg = 0; c_showcerts = 0; - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - if (!load_config(bio_err, NULL)) - goto end; + c_nbio = 0; + verify_depth = 0; + verify_error = X509_V_OK; + vpm = X509_VERIFY_PARAM_new(); + cbuf = app_malloc(BUFSIZZ, "cbuf"); + sbuf = app_malloc(BUFSIZZ, "sbuf"); + mbuf = app_malloc(BUFSIZZ, "mbuf"); cctx = SSL_CONF_CTX_new(); - if (!cctx) - goto end; - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE); - if (((cbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) || - ((sbuf = OPENSSL_malloc(BUFSIZZ)) == NULL) || - ((mbuf = OPENSSL_malloc(BUFSIZZ)) == NULL)) { - BIO_printf(bio_err, "out of memory\n"); + if (vpm == NULL || cctx == NULL) { + BIO_printf(bio_err, "%s: out of memory\n", prog); goto end; } - verify_depth = 0; - verify_error = X509_V_OK; -#ifdef FIONBIO - c_nbio = 0; -#endif + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT | SSL_CONF_FLAG_CMDLINE); - argc--; - argv++; - while (argc >= 1) { - if (strcmp(*argv, "-host") == 0) { - if (--argc < 1) - goto bad; - host = *(++argv); - } else if (strcmp(*argv, "-port") == 0) { - if (--argc < 1) - goto bad; - port = atoi(*(++argv)); - if (port == 0) - goto bad; - } else if (strcmp(*argv, "-connect") == 0) { - if (--argc < 1) - goto bad; - if (!extract_host_port(*(++argv), &host, NULL, &port)) - goto bad; - } else if (strcmp(*argv, "-unix") == 0) { - if (--argc < 1) - goto bad; - unix_path = *(++argv); - } else if (strcmp(*argv, "-xmpphost") == 0) { - if (--argc < 1) - goto bad; - xmpphost = *(++argv); - } else if (strcmp(*argv, "-verify") == 0) { + prog = opt_init(argc, argv, s_client_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(s_client_options); + ret = 0; + goto end; + case OPT_HOST: + host = opt_arg(); + break; + case OPT_PORT: + port = atoi(opt_arg()); + break; + case OPT_CONNECT: + connectstr = opt_arg(); + break; + case OPT_PROXY: + proxystr = opt_arg(); + starttls_proto = PROTO_CONNECT; + break; + case OPT_UNIX: + unix_path = opt_arg(); + break; + case OPT_XMPPHOST: + xmpphost = opt_arg(); + break; + case OPT_SMTPHOST: + ehlo = opt_arg(); + break; + case OPT_VERIFY: verify = SSL_VERIFY_PEER; - if (--argc < 1) - goto bad; - verify_depth = atoi(*(++argv)); + verify_depth = atoi(opt_arg()); if (!c_quiet) BIO_printf(bio_err, "verify depth is %d\n", verify_depth); - } else if (strcmp(*argv, "-cert") == 0) { - if (--argc < 1) - goto bad; - cert_file = *(++argv); - } else if (strcmp(*argv, "-CRL") == 0) { - if (--argc < 1) - goto bad; - crl_file = *(++argv); - } else if (strcmp(*argv, "-crl_download") == 0) + break; + case OPT_CERT: + cert_file = opt_arg(); + break; + case OPT_CRL: + crl_file = opt_arg(); + break; + case OPT_CRL_DOWNLOAD: crl_download = 1; - else if (strcmp(*argv, "-sess_out") == 0) { - if (--argc < 1) - goto bad; - sess_out = *(++argv); - } else if (strcmp(*argv, "-sess_in") == 0) { - if (--argc < 1) - goto bad; - sess_in = *(++argv); - } else if (strcmp(*argv, "-certform") == 0) { - if (--argc < 1) - goto bad; - cert_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-CRLform") == 0) { - if (--argc < 1) - goto bad; - crl_format = str2fmt(*(++argv)); - } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { - if (badarg) - goto bad; - continue; - } else if (strcmp(*argv, "-verify_return_error") == 0) + break; + case OPT_SESS_OUT: + sess_out = opt_arg(); + break; + case OPT_SESS_IN: + sess_in = opt_arg(); + break; + case OPT_CERTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &cert_format)) + goto opthelp; + break; + case OPT_CRLFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) + goto opthelp; + break; + case OPT_VERIFY_RET_ERROR: verify_return_error = 1; - else if (strcmp(*argv, "-verify_quiet") == 0) - verify_quiet = 1; - else if (strcmp(*argv, "-brief") == 0) { - c_brief = 1; + break; + case OPT_VERIFY_QUIET: verify_quiet = 1; - c_quiet = 1; - } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) { - if (badarg) - goto bad; - continue; - } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) { - if (badarg) - goto bad; - continue; - } else if (strcmp(*argv, "-prexit") == 0) + break; + case OPT_BRIEF: + c_brief = verify_quiet = c_quiet = 1; + break; + case OPT_S_CASES: + if (ssl_args == NULL) + ssl_args = sk_OPENSSL_STRING_new_null(); + if (ssl_args == NULL + || !sk_OPENSSL_STRING_push(ssl_args, opt_flag()) + || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) { + BIO_printf(bio_err, "%s: Memory allocation failure\n", prog); + goto end; + } + break; + case OPT_V_CASES: + if (!opt_verify(o, vpm)) + goto end; + vpmtouched++; + break; + case OPT_X_CASES: + if (!args_excert(o, &exc)) + goto end; + break; + case OPT_PREXIT: prexit = 1; - else if (strcmp(*argv, "-crlf") == 0) + break; + case OPT_CRLF: crlf = 1; - else if (strcmp(*argv, "-quiet") == 0) { - c_quiet = 1; - c_ign_eof = 1; - } else if (strcmp(*argv, "-ign_eof") == 0) + break; + case OPT_QUIET: + c_quiet = c_ign_eof = 1; + break; + case OPT_NBIO: + c_nbio = 1; + break; + case OPT_NOCMDS: + cmdletters = 0; + break; + case OPT_ENGINE: + e = setup_engine(opt_arg(), 1); + break; + case OPT_SSL_CLIENT_ENGINE: +#ifndef OPENSSL_NO_ENGINE + ssl_client_engine = ENGINE_by_id(opt_arg()); + if (ssl_client_engine == NULL) { + BIO_printf(bio_err, "Error getting client auth engine\n"); + goto opthelp; + } + break; +#endif + break; + case OPT_RAND: + inrand = opt_arg(); + break; + case OPT_IGN_EOF: c_ign_eof = 1; - else if (strcmp(*argv, "-no_ign_eof") == 0) + break; + case OPT_NO_IGN_EOF: c_ign_eof = 0; - else if (strcmp(*argv, "-pause") == 0) + break; + case OPT_PAUSE: c_Pause = 1; - else if (strcmp(*argv, "-debug") == 0) + break; + case OPT_DEBUG: c_debug = 1; -#ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-tlsextdebug") == 0) + break; + case OPT_TLSEXTDEBUG: c_tlsextdebug = 1; - else if (strcmp(*argv, "-status") == 0) + break; + case OPT_STATUS: c_status_req = 1; -#endif + break; + case OPT_WDEBUG: #ifdef WATT32 - else if (strcmp(*argv, "-wdebug") == 0) dbug_init(); #endif - else if (strcmp(*argv, "-msg") == 0) + break; + case OPT_MSG: c_msg = 1; - else if (strcmp(*argv, "-msgfile") == 0) { - if (--argc < 1) - goto bad; - bio_c_msg = BIO_new_file(*(++argv), "w"); - } + break; + case OPT_MSGFILE: + bio_c_msg = BIO_new_file(opt_arg(), "w"); + break; + case OPT_TRACE: #ifndef OPENSSL_NO_SSL_TRACE - else if (strcmp(*argv, "-trace") == 0) c_msg = 2; #endif - else if (strcmp(*argv, "-security_debug") == 0) { + break; + case OPT_SECURITY_DEBUG: sdebug = 1; - } else if (strcmp(*argv, "-security_debug_verbose") == 0) { + break; + case OPT_SECURITY_DEBUG_VERBOSE: sdebug = 2; - } else if (strcmp(*argv, "-showcerts") == 0) + break; + case OPT_SHOWCERTS: c_showcerts = 1; - else if (strcmp(*argv, "-nbio_test") == 0) + break; + case OPT_NBIO_TEST: nbio_test = 1; - else if (strcmp(*argv, "-state") == 0) + break; + case OPT_STATE: state = 1; + break; #ifndef OPENSSL_NO_PSK - else if (strcmp(*argv, "-psk_identity") == 0) { - if (--argc < 1) - goto bad; - psk_identity = *(++argv); - } else if (strcmp(*argv, "-psk") == 0) { - size_t j; - - if (--argc < 1) - goto bad; - psk_key = *(++argv); - for (j = 0; j < strlen(psk_key); j++) { - if (isxdigit((unsigned char)psk_key[j])) + case OPT_PSK_IDENTITY: + psk_identity = opt_arg(); + break; + case OPT_PSK: + for (p = psk_key = opt_arg(); *p; p++) { + if (isxdigit(*p)) continue; - BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); - goto bad; + BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key); + goto end; } - } + break; +#else + case OPT_PSK_IDENTITY: + case OPT_PSK: + break; #endif #ifndef OPENSSL_NO_SRP - else if (strcmp(*argv, "-srpuser") == 0) { - if (--argc < 1) - goto bad; - srp_arg.srplogin = *(++argv); + case OPT_SRPUSER: + srp_arg.srplogin = opt_arg(); meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srppass") == 0) { - if (--argc < 1) - goto bad; - srppass = *(++argv); + break; + case OPT_SRPPASS: + srppass = opt_arg(); meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srp_strength") == 0) { - if (--argc < 1) - goto bad; - srp_arg.strength = atoi(*(++argv)); + break; + case OPT_SRP_STRENGTH: + srp_arg.strength = atoi(opt_arg()); BIO_printf(bio_err, "SRP minimal length for N is %d\n", srp_arg.strength); meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srp_lateuser") == 0) { + break; + case OPT_SRP_LATEUSER: srp_lateuser = 1; meth = TLSv1_client_method(); - } else if (strcmp(*argv, "-srp_moregroups") == 0) { + break; + case OPT_SRP_MOREGROUPS: srp_arg.amp = 1; meth = TLSv1_client_method(); - } + break; +#else + case OPT_SRPUSER: + case OPT_SRPPASS: + case OPT_SRP_STRENGTH: + case OPT_SRP_LATEUSER: + case OPT_SRP_MOREGROUPS: + break; #endif -#ifndef OPENSSL_NO_SSL3_METHOD - else if (strcmp(*argv, "-ssl3") == 0) + case OPT_SSL3: +#ifndef OPENSSL_NO_SSL3 meth = SSLv3_client_method(); #endif -#ifndef OPENSSL_NO_TLS1 - else if (strcmp(*argv, "-tls1_2") == 0) + break; + case OPT_TLS1_2: meth = TLSv1_2_client_method(); - else if (strcmp(*argv, "-tls1_1") == 0) + break; + case OPT_TLS1_1: meth = TLSv1_1_client_method(); - else if (strcmp(*argv, "-tls1") == 0) + break; + case OPT_TLS1: meth = TLSv1_client_method(); -#endif + break; #ifndef OPENSSL_NO_DTLS1 - else if (strcmp(*argv, "-dtls") == 0) { + case OPT_DTLS: meth = DTLS_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-dtls1") == 0) { + break; + case OPT_DTLS1: meth = DTLSv1_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-dtls1_2") == 0) { + break; + case OPT_DTLS1_2: meth = DTLSv1_2_client_method(); socket_type = SOCK_DGRAM; - } else if (strcmp(*argv, "-timeout") == 0) + break; + case OPT_TIMEOUT: enable_timeouts = 1; - else if (strcmp(*argv, "-mtu") == 0) { - if (--argc < 1) - goto bad; - socket_mtu = atol(*(++argv)); - } + break; + case OPT_MTU: + socket_mtu = atol(opt_arg()); + break; +#else + case OPT_DTLS: + case OPT_DTLS1: + case OPT_DTLS1_2: + case OPT_TIMEOUT: + case OPT_MTU: + break; #endif - else if (strcmp(*argv, "-fallback_scsv") == 0) { + case OPT_FALLBACKSCSV: fallback_scsv = 1; - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - key_format = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-pass") == 0) { - if (--argc < 1) - goto bad; - passarg = *(++argv); - } else if (strcmp(*argv, "-cert_chain") == 0) { - if (--argc < 1) - goto bad; - chain_file = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - key_file = *(++argv); - } else if (strcmp(*argv, "-reconnect") == 0) { + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &key_format)) + goto opthelp; + break; + case OPT_PASS: + passarg = opt_arg(); + break; + case OPT_CERT_CHAIN: + chain_file = opt_arg(); + break; + case OPT_KEY: + key_file = opt_arg(); + break; + case OPT_RECONNECT: reconnect = 5; - } else if (strcmp(*argv, "-CApath") == 0) { - if (--argc < 1) - goto bad; - CApath = *(++argv); - } else if (strcmp(*argv, "-chainCApath") == 0) { - if (--argc < 1) - goto bad; - chCApath = *(++argv); - } else if (strcmp(*argv, "-verifyCApath") == 0) { - if (--argc < 1) - goto bad; - vfyCApath = *(++argv); - } else if (strcmp(*argv, "-build_chain") == 0) + break; + case OPT_CAPATH: + CApath = opt_arg(); + break; + case OPT_CHAINCAPATH: + chCApath = opt_arg(); + break; + case OPT_VERIFYCAPATH: + vfyCApath = opt_arg(); + break; + case OPT_BUILD_CHAIN: build_chain = 1; - else if (strcmp(*argv, "-CAfile") == 0) { - if (--argc < 1) - goto bad; - CAfile = *(++argv); - } else if (strcmp(*argv, "-chainCAfile") == 0) { - if (--argc < 1) - goto bad; - chCAfile = *(++argv); - } else if (strcmp(*argv, "-verifyCAfile") == 0) { - if (--argc < 1) - goto bad; - vfyCAfile = *(++argv); - } -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_NEXTPROTONEG - else if (strcmp(*argv, "-nextprotoneg") == 0) { - if (--argc < 1) - goto bad; - next_proto_neg_in = *(++argv); - } -# endif - else if (strcmp(*argv, "-alpn") == 0) { - if (--argc < 1) - goto bad; - alpn_in = *(++argv); - } else if (strcmp(*argv, "-serverinfo") == 0) { - char *c; - int start = 0; - int len; - - if (--argc < 1) - goto bad; - c = *(++argv); - serverinfo_types_count = 0; - len = strlen(c); - for (i = 0; i <= len; ++i) { - if (i == len || c[i] == ',') { - serverinfo_types[serverinfo_types_count] - = atoi(c + start); - serverinfo_types_count++; + break; + case OPT_CAFILE: + CAfile = opt_arg(); + break; + case OPT_CHAINCAFILE: + chCAfile = opt_arg(); + break; + case OPT_VERIFYCAFILE: + vfyCAfile = opt_arg(); + break; + case OPT_NEXTPROTONEG: + next_proto_neg_in = opt_arg(); + break; + case OPT_ALPN: + alpn_in = opt_arg(); + break; + case OPT_SERVERINFO: + p = opt_arg(); + len = strlen(p); + for (start = 0, i = 0; i <= len; ++i) { + if (i == len || p[i] == ',') { + serverinfo_types[serverinfo_count] = atoi(p + start); + if (++serverinfo_count == MAX_SI_TYPES) + break; start = i + 1; } - if (serverinfo_types_count == MAX_SI_TYPES) - break; } - } -#endif -#ifdef FIONBIO - else if (strcmp(*argv, "-nbio") == 0) { - c_nbio = 1; - } -#endif - else if (strcmp(*argv, "-starttls") == 0) { - if (--argc < 1) - goto bad; - ++argv; - if (strcmp(*argv, "smtp") == 0) - starttls_proto = PROTO_SMTP; - else if (strcmp(*argv, "pop3") == 0) - starttls_proto = PROTO_POP3; - else if (strcmp(*argv, "imap") == 0) - starttls_proto = PROTO_IMAP; - else if (strcmp(*argv, "ftp") == 0) - starttls_proto = PROTO_FTP; - else if (strcmp(*argv, "xmpp") == 0) - starttls_proto = PROTO_XMPP; - else - goto bad; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine_id = *(++argv); - } else if (strcmp(*argv, "-ssl_client_engine") == 0) { - if (--argc < 1) - goto bad; - ssl_client_engine_id = *(++argv); - } -#endif - else if (strcmp(*argv, "-rand") == 0) { - if (--argc < 1) - goto bad; - inrand = *(++argv); - } -#ifndef OPENSSL_NO_TLSEXT - else if (strcmp(*argv, "-servername") == 0) { - if (--argc < 1) - goto bad; - servername = *(++argv); - /* meth=TLSv1_client_method(); */ - } -#endif + break; + case OPT_STARTTLS: + if (!opt_pair(opt_arg(), services, &starttls_proto)) + goto end; + case OPT_SERVERNAME: + servername = opt_arg(); + break; + case OPT_JPAKE: #ifndef OPENSSL_NO_JPAKE - else if (strcmp(*argv, "-jpake") == 0) { - if (--argc < 1) - goto bad; - jpake_secret = *++argv; - } -#endif -#ifndef OPENSSL_NO_SRTP - else if (strcmp(*argv, "-use_srtp") == 0) { - if (--argc < 1) - goto bad; - srtp_profiles = *(++argv); - } + jpake_secret = opt_arg(); #endif - else if (strcmp(*argv, "-keymatexport") == 0) { - if (--argc < 1) - goto bad; - keymatexportlabel = *(++argv); - } else if (strcmp(*argv, "-keymatexportlen") == 0) { - if (--argc < 1) - goto bad; - keymatexportlen = atoi(*(++argv)); - if (keymatexportlen == 0) - goto bad; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badop = 1; + break; + case OPT_USE_SRTP: + srtp_profiles = opt_arg(); + break; + case OPT_KEYMATEXPORT: + keymatexportlabel = opt_arg(); + break; + case OPT_KEYMATEXPORTLEN: + keymatexportlen = atoi(opt_arg()); break; } - argc--; - argv++; } - if (badop) { - bad: - sc_usage(); + argc = opt_num_rest(); + argv = opt_rest(); + + if (!app_load_modules(NULL)) goto end; + + if (proxystr) { + if (connectstr == NULL) { + BIO_printf(bio_err, "%s: -proxy requires use of -connect\n", prog); + goto opthelp; + } + if (!extract_host_port(proxystr, &host, NULL, &port)) + goto end; } + else if (connectstr != NULL + && !extract_host_port(connectstr, &host, NULL, &port)) + goto end; if (unix_path && (socket_type != SOCK_STREAM)) { BIO_printf(bio_err, @@ -1137,10 +1079,7 @@ int MAIN(int argc, char **argv) } #endif - OpenSSL_add_ssl_algorithms(); - SSL_load_error_strings(); - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +#if !defined(OPENSSL_NO_NEXTPROTONEG) next_proto.status = -1; if (next_proto_neg_in) { next_proto.data = @@ -1153,17 +1092,7 @@ int MAIN(int argc, char **argv) next_proto.data = NULL; #endif -#ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine_id, 1); - if (ssl_client_engine_id) { - ssl_client_engine = ENGINE_by_id(ssl_client_engine_id); - if (!ssl_client_engine) { - BIO_printf(bio_err, "Error getting client auth engine\n"); - goto end; - } - } -#endif - if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { + if (!app_passwd(passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -1172,28 +1101,25 @@ int MAIN(int argc, char **argv) key_file = cert_file; if (key_file) { - - key = load_key(bio_err, key_file, key_format, 0, pass, e, + key = load_key(key_file, key_format, 0, pass, e, "client certificate private key file"); - if (!key) { + if (key == NULL) { ERR_print_errors(bio_err); goto end; } - } if (cert_file) { - cert = load_cert(bio_err, cert_file, cert_format, + cert = load_cert(cert_file, cert_format, NULL, e, "client certificate file"); - - if (!cert) { + if (cert == NULL) { ERR_print_errors(bio_err); goto end; } } if (chain_file) { - chain = load_certs(bio_err, chain_file, FORMAT_PEM, + chain = load_certs(chain_file, FORMAT_PEM, NULL, e, "client certificate chain"); if (!chain) goto end; @@ -1202,13 +1128,13 @@ int MAIN(int argc, char **argv) if (crl_file) { X509_CRL *crl; crl = load_crl(crl_file, crl_format); - if (!crl) { + if (crl == NULL) { BIO_puts(bio_err, "Error loading CRL\n"); ERR_print_errors(bio_err); goto end; } crls = sk_X509_CRL_new_null(); - if (!crls || !sk_X509_CRL_push(crls, crl)) { + if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { BIO_puts(bio_err, "Error adding CRL\n"); ERR_print_errors(bio_err); X509_CRL_free(crl); @@ -1216,30 +1142,29 @@ int MAIN(int argc, char **argv) } } - if (!load_excert(&exc, bio_err)) + if (!load_excert(&exc)) goto end; - if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL + if (!app_RAND_load_file(NULL, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } - if (inrand != NULL) - BIO_printf(bio_err, "%ld semi-random bytes loaded\n", - app_RAND_load_files(inrand)); + if (inrand != NULL) { + randamt = app_RAND_load_files(inrand); + BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt); + } if (bio_c_out == NULL) { if (c_quiet && !c_debug) { bio_c_out = BIO_new(BIO_s_null()); if (c_msg && !bio_c_msg) - bio_c_msg = BIO_new_fp(stdout, BIO_NOCLOSE); - } else { - if (bio_c_out == NULL) - bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE); - } + bio_c_msg = dup_bio_out(); + } else if (bio_c_out == NULL) + bio_c_out = dup_bio_out(); } #ifndef OPENSSL_NO_SRP - if (!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL)) { + if (!app_passwd(srppass, NULL, &srp_arg.srppassin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -1252,16 +1177,17 @@ int MAIN(int argc, char **argv) } if (sdebug) - ssl_ctx_security_debug(ctx, bio_err, sdebug); - - if (vpm) - SSL_CTX_set1_param(ctx, vpm); + ssl_ctx_security_debug(ctx, sdebug); - if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake)) { + if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { + BIO_printf(bio_err, "Error setting verify params\n"); ERR_print_errors(bio_err); goto end; } + if (!config_ctx(cctx, ssl_args, ctx, 1, jpake_secret == NULL)) + goto end; + if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); @@ -1281,12 +1207,7 @@ int MAIN(int argc, char **argv) #endif #ifndef OPENSSL_NO_PSK -# ifdef OPENSSL_NO_JPAKE - if (psk_key != NULL) -# else - if (psk_key != NULL || jpake_secret) -# endif - { + if (psk_key != NULL || jpake_secret) { if (c_debug) BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n"); @@ -1294,17 +1215,23 @@ int MAIN(int argc, char **argv) } #endif #ifndef OPENSSL_NO_SRTP - if (srtp_profiles != NULL) - SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles); + if (srtp_profiles != NULL) { + /* Returns 0 on success! */ + if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) { + BIO_printf(bio_err, "Error setting SRTP profile\n"); + ERR_print_errors(bio_err); + goto end; + } + } #endif + if (exc) ssl_ctx_set_excert(ctx, exc); -#if !defined(OPENSSL_NO_TLSEXT) -# if !defined(OPENSSL_NO_NEXTPROTONEG) +#if !defined(OPENSSL_NO_NEXTPROTONEG) if (next_proto.data) SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto); -# endif +#endif if (alpn_in) { unsigned short alpn_len; unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in); @@ -1313,35 +1240,33 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "Error parsing -alpn argument\n"); goto end; } - SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len); + /* Returns 0 on success! */ + if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len) != 0) { + BIO_printf(bio_err, "Error setting ALPN\n"); + goto end; + } OPENSSL_free(alpn); } -#endif -#ifndef OPENSSL_NO_TLSEXT - for (i = 0; i < serverinfo_types_count; i++) { - SSL_CTX_add_client_custom_ext(ctx, - serverinfo_types[i], - NULL, NULL, NULL, - serverinfo_cli_parse_cb, NULL); + + for (i = 0; i < serverinfo_count; i++) { + if (!SSL_CTX_add_client_custom_ext(ctx, + serverinfo_types[i], + NULL, NULL, NULL, + serverinfo_cli_parse_cb, NULL)) { + BIO_printf(bio_err, + "Warning: Unable to add custom extension %u, skipping\n", + serverinfo_types[i]); + } } -#endif if (state) SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); -#if 0 - else - SSL_CTX_set_cipher_list(ctx, getenv("SSL_CIPHER")); -#endif SSL_CTX_set_verify(ctx, verify, verify_callback); - if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) || - (!SSL_CTX_set_default_verify_paths(ctx))) { - /* - * BIO_printf(bio_err,"error setting default verify locations\n"); - */ + if (!ctx_set_verify_locations(ctx, CAfile, CApath)) { ERR_print_errors(bio_err); - /* goto end; */ + goto end; } ssl_ctx_add_crls(ctx, crls, crl_download); @@ -1349,7 +1274,6 @@ int MAIN(int argc, char **argv) if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain)) goto end; -#ifndef OPENSSL_NO_TLSEXT if (servername != NULL) { tlsextcbp.biodebug = bio_err; SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); @@ -1371,7 +1295,6 @@ int MAIN(int argc, char **argv) ssl_srp_verify_param_cb); } # endif -#endif con = SSL_new(ctx); if (sess_in) { @@ -1389,14 +1312,17 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - SSL_set_session(con, sess); + if (!SSL_set_session(con, sess)) { + BIO_printf(bio_err, "Can't set session\n"); + ERR_print_errors(bio_err); + goto end; + } SSL_SESSION_free(sess); } if (fallback_scsv) SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV); -#ifndef OPENSSL_NO_TLSEXT if (servername != NULL) { if (!SSL_set_tlsext_host_name(con, servername)) { BIO_printf(bio_err, "Unable to set TLS servername extension.\n"); @@ -1404,19 +1330,6 @@ int MAIN(int argc, char **argv) goto end; } } -#endif -#ifndef OPENSSL_NO_KRB5 - if (con && (kctx = kssl_ctx_new()) != NULL) { - SSL_set0_kssl_ctx(con, kctx); - kssl_ctx_setstring(kctx, KSSL_SERVER, host); - } -#endif /* OPENSSL_NO_KRB5 */ -/* SSL_set_cipher_list(con,"RC4-MD5"); */ -#if 0 -# ifdef TLSEXT_TYPE_opaque_prf_input - SSL_set_tlsext_opaque_prf_input(con, "Test client", 11); -# endif -#endif re_start: #ifdef NO_SYS_UN_H @@ -1507,7 +1420,7 @@ int MAIN(int argc, char **argv) SSL_set_msg_callback(con, msg_cb); SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out); } -#ifndef OPENSSL_NO_TLSEXT + if (c_tlsextdebug) { SSL_set_tlsext_debug_callback(con, tlsext_cb); SSL_set_tlsext_debug_arg(con, bio_c_out); @@ -1516,19 +1429,7 @@ int MAIN(int argc, char **argv) SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); -# if 0 - { - STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null(); - OCSP_RESPID *id = OCSP_RESPID_new(); - id->value.byKey = ASN1_OCTET_STRING_new(); - id->type = V_OCSP_RESPID_KEY; - ASN1_STRING_set(id->value.byKey, "Hello World", -1); - sk_OCSP_RESPID_push(ids, id); - SSL_set_tlsext_status_ids(con, ids); - } -# endif } -#endif #ifndef OPENSSL_NO_JPAKE if (jpake_secret) jpake_client_auth(bio_c_out, sbio, jpake_secret); @@ -1551,111 +1452,185 @@ int MAIN(int argc, char **argv) sbuf_len = 0; sbuf_off = 0; - /* This is an ugly hack that does a lot of assumptions */ - /* - * We do have to handle multi-line responses which may come in a single - * packet or not. We therefore have to use BIO_gets() which does need a - * buffering BIO. So during the initial chitchat we do push a buffering - * BIO into the chain that is removed again later on to not disturb the - * rest of the s_client operation. - */ - if (starttls_proto == PROTO_SMTP) { - int foundit = 0; - BIO *fbio = BIO_new(BIO_f_buffer()); - BIO_push(fbio, sbio); - /* wait for multi-line response to end from SMTP */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + switch ((PROTOCOL_CHOICE) starttls_proto) { + case PROTO_OFF: + break; + case PROTO_SMTP: + { + /* + * This is an ugly hack that does a lot of assumptions. We do + * have to handle multi-line responses which may come in a single + * packet or not. We therefore have to use BIO_gets() which does + * need a buffering BIO. So during the initial chitchat we do + * push a buffering BIO into the chain that is removed again + * later on to not disturb the rest of the s_client operation. + */ + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + /* wait for multi-line response to end from SMTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); + BIO_printf(fbio, "EHLO %s\r\n", ehlo); + (void)BIO_flush(fbio); + /* wait for multi-line response to end EHLO SMTP response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } + while (mbuf_len > 3 && mbuf[3] == '-'); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) + BIO_printf(bio_err, + "didn't found starttls in server response," + " try anyway...\n"); + BIO_printf(sbio, "STARTTLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[3] == '-'); - /* STARTTLS command requires EHLO... */ - BIO_printf(fbio, "EHLO openssl.client.net\r\n"); - (void)BIO_flush(fbio); - /* wait for multi-line response to end EHLO SMTP response */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (strstr(mbuf, "STARTTLS")) - foundit = 1; + break; + case PROTO_POP3: + { + BIO_read(sbio, mbuf, BUFSIZZ); + BIO_printf(sbio, "STLS\r\n"); + mbuf_len = BIO_read(sbio, sbuf, BUFSIZZ); + if (mbuf_len < 0) { + BIO_printf(bio_err, "BIO_read failed\n"); + goto end; + } } - while (mbuf_len > 3 && mbuf[3] == '-'); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - if (!foundit) - BIO_printf(bio_err, - "didn't found starttls in server response," - " try anyway...\n"); - BIO_printf(sbio, "STARTTLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } else if (starttls_proto == PROTO_POP3) { - BIO_read(sbio, mbuf, BUFSIZZ); - BIO_printf(sbio, "STLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } else if (starttls_proto == PROTO_IMAP) { - int foundit = 0; - BIO *fbio = BIO_new(BIO_f_buffer()); - BIO_push(fbio, sbio); - BIO_gets(fbio, mbuf, BUFSIZZ); - /* STARTTLS command requires CAPABILITY... */ - BIO_printf(fbio, ". CAPABILITY\r\n"); - (void)BIO_flush(fbio); - /* wait for multi-line CAPABILITY response */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (strstr(mbuf, "STARTTLS")) - foundit = 1; + break; + case PROTO_IMAP: + { + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + BIO_gets(fbio, mbuf, BUFSIZZ); + /* STARTTLS command requires CAPABILITY... */ + BIO_printf(fbio, ". CAPABILITY\r\n"); + (void)BIO_flush(fbio); + /* wait for multi-line CAPABILITY response */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) + foundit = 1; + } + while (mbuf_len > 3 && mbuf[0] != '.'); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) + BIO_printf(bio_err, + "didn't found STARTTLS in server response," + " try anyway...\n"); + BIO_printf(sbio, ". STARTTLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[0] != '.'); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - if (!foundit) - BIO_printf(bio_err, - "didn't found STARTTLS in server response," - " try anyway...\n"); - BIO_printf(sbio, ". STARTTLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } else if (starttls_proto == PROTO_FTP) { - BIO *fbio = BIO_new(BIO_f_buffer()); - BIO_push(fbio, sbio); - /* wait for multi-line response to end from FTP */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + break; + case PROTO_FTP: + { + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); + /* wait for multi-line response to end from FTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + BIO_printf(sbio, "AUTH TLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[3] == '-'); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - BIO_printf(sbio, "AUTH TLS\r\n"); - BIO_read(sbio, sbuf, BUFSIZZ); - } - if (starttls_proto == PROTO_XMPP) { - int seen = 0; - BIO_printf(sbio, "", xmpphost ? - xmpphost : host); - seen = BIO_read(sbio, mbuf, BUFSIZZ); - mbuf[seen] = 0; - while (!strstr - (mbuf, "", + xmpphost ? xmpphost : host); seen = BIO_read(sbio, mbuf, BUFSIZZ); + mbuf[seen] = 0; + while (!strstr + (mbuf, ""); + seen = BIO_read(sbio, sbuf, BUFSIZZ); + sbuf[seen] = 0; + if (!strstr(sbuf, ""); - seen = BIO_read(sbio, sbuf, BUFSIZZ); - sbuf[seen] = 0; - if (!strstr(sbuf, " 3 && foundit == 0); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (!foundit) { + BIO_printf(bio_err, "%s: HTTP CONNECT failed\n", prog); + goto shut; + } + } + break; } for (;;) { @@ -1675,16 +1650,13 @@ int MAIN(int argc, char **argv) tty_on = 1; if (in_init) { in_init = 0; -#if 0 /* This test doesn't really work as intended - * (needs to be fixed) */ -# ifndef OPENSSL_NO_TLSEXT + if (servername != NULL && !SSL_session_reused(con)) { BIO_printf(bio_c_out, "Server did %sacknowledge servername extension.\n", tlsextcbp.ack ? "" : "not "); } -# endif -#endif + if (sess_out) { BIO *stmp = BIO_new_file(sess_out, "w"); if (stmp) { @@ -1696,7 +1668,7 @@ int MAIN(int argc, char **argv) } if (c_brief) { BIO_puts(bio_err, "CONNECTION ESTABLISHED\n"); - print_ssl_summary(bio_err, con); + print_ssl_summary(con); } print_stuff(bio_c_out, con, full_log); @@ -1704,9 +1676,10 @@ int MAIN(int argc, char **argv) full_log--; if (starttls_proto) { - BIO_printf(bio_err, "%s", mbuf); + BIO_write(bio_err, mbuf, mbuf_len); /* We don't need to know any more */ - starttls_proto = PROTO_OFF; + if (!reconnect) + starttls_proto = PROTO_OFF; } if (reconnect) { @@ -1743,8 +1716,6 @@ int MAIN(int argc, char **argv) openssl_fdset(SSL_get_fd(con), &writefds); } #endif -/*- printf("mode tty(%d %d%d) ssl(%d%d)\n", - tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ /* * Note: under VMS with SOCKETSHR the second parameter is @@ -1905,17 +1876,7 @@ int MAIN(int argc, char **argv) } } #endif -#if 1 k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ ); -#else -/* Demo for pending and peek :-) */ - k = SSL_read(con, sbuf, 16); - { - char zbuf[10240]; - printf("read=%d pending=%d peek=%d\n", k, SSL_pending(con), - SSL_peek(con, zbuf, 10240)); - } -#endif switch (SSL_get_error(con, k)) { case SSL_ERROR_NONE: @@ -1994,19 +1955,19 @@ int MAIN(int argc, char **argv) } else i = raw_read_stdin(cbuf, BUFSIZZ); - if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { + if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) { BIO_printf(bio_err, "DONE\n"); ret = 0; goto shut; } - if ((!c_ign_eof) && (cbuf[0] == 'R')) { + if ((!c_ign_eof) && (cbuf[0] == 'R' && cmdletters)) { BIO_printf(bio_err, "RENEGOTIATING\n"); SSL_renegotiate(con); cbuf_len = 0; } #ifndef OPENSSL_NO_HEARTBEATS - else if ((!c_ign_eof) && (cbuf[0] == 'B')) { + else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) { BIO_printf(bio_err, "HEARTBEATING\n"); SSL_heartbeat(con); cbuf_len = 0; @@ -2037,55 +1998,27 @@ int MAIN(int argc, char **argv) print_stuff(bio_c_out, con, 1); SSL_free(con); } -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - if (next_proto.data) - OPENSSL_free(next_proto.data); -#endif - if (ctx != NULL) - SSL_CTX_free(ctx); - if (cert) - X509_free(cert); - if (crls) - sk_X509_CRL_pop_free(crls, X509_CRL_free); - if (key) - EVP_PKEY_free(key); - if (chain) - sk_X509_pop_free(chain, X509_free); - if (pass) - OPENSSL_free(pass); - if (vpm) - X509_VERIFY_PARAM_free(vpm); +#if !defined(OPENSSL_NO_NEXTPROTONEG) + OPENSSL_free(next_proto.data); +#endif + SSL_CTX_free(ctx); + X509_free(cert); + sk_X509_CRL_pop_free(crls, X509_CRL_free); + EVP_PKEY_free(key); + sk_X509_pop_free(chain, X509_free); + OPENSSL_free(pass); + X509_VERIFY_PARAM_free(vpm); ssl_excert_free(exc); - if (ssl_args) - sk_OPENSSL_STRING_free(ssl_args); - if (cctx) - SSL_CONF_CTX_free(cctx); -#ifndef OPENSSL_NO_JPAKE - if (jpake_secret && psk_key) - OPENSSL_free(psk_key); -#endif - if (cbuf != NULL) { - OPENSSL_cleanse(cbuf, BUFSIZZ); - OPENSSL_free(cbuf); - } - if (sbuf != NULL) { - OPENSSL_cleanse(sbuf, BUFSIZZ); - OPENSSL_free(sbuf); - } - if (mbuf != NULL) { - OPENSSL_cleanse(mbuf, BUFSIZZ); - OPENSSL_free(mbuf); - } - if (bio_c_out != NULL) { - BIO_free(bio_c_out); - bio_c_out = NULL; - } - if (bio_c_msg != NULL) { - BIO_free(bio_c_msg); - bio_c_msg = NULL; - } - apps_shutdown(); - OPENSSL_EXIT(ret); + sk_OPENSSL_STRING_free(ssl_args); + SSL_CONF_CTX_free(cctx); + OPENSSL_clear_free(cbuf, BUFSIZZ); + OPENSSL_clear_free(sbuf, BUFSIZZ); + OPENSSL_clear_free(mbuf, BUFSIZZ); + BIO_free(bio_c_out); + bio_c_out = NULL; + BIO_free(bio_c_msg); + bio_c_msg = NULL; + return (ret); } static void print_stuff(BIO *bio, SSL *s, int full) @@ -2107,7 +2040,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) sk = SSL_get_peer_cert_chain(s); if (sk != NULL) { - got_a_chain = 1; /* we don't have it for SSL2 (yet) */ + got_a_chain = 1; BIO_printf(bio, "---\nCertificate chain\n"); for (i = 0; i < sk_X509_num(sk); i++) { @@ -2192,8 +2125,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) } #endif -#if !defined(OPENSSL_NO_TLSEXT) -# if !defined(OPENSSL_NO_NEXTPROTONEG) +#if !defined(OPENSSL_NO_NEXTPROTONEG) if (next_proto.status != -1) { const unsigned char *proto; unsigned int proto_len; @@ -2202,7 +2134,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_write(bio, proto, proto_len); BIO_write(bio, "\n", 1); } -# endif +#endif { const unsigned char *proto; unsigned int proto_len; @@ -2214,7 +2146,6 @@ static void print_stuff(BIO *bio, SSL *s, int full) } else BIO_printf(bio, "No ALPN negotiated\n"); } -#endif #ifndef OPENSSL_NO_SRTP { @@ -2232,32 +2163,27 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_printf(bio, "Keying material exporter:\n"); BIO_printf(bio, " Label: '%s'\n", keymatexportlabel); BIO_printf(bio, " Length: %i bytes\n", keymatexportlen); - exportedkeymat = OPENSSL_malloc(keymatexportlen); - if (exportedkeymat != NULL) { - if (!SSL_export_keying_material(s, exportedkeymat, - keymatexportlen, - keymatexportlabel, - strlen(keymatexportlabel), - NULL, 0, 0)) { - BIO_printf(bio, " Error\n"); - } else { - BIO_printf(bio, " Keying material: "); - for (i = 0; i < keymatexportlen; i++) - BIO_printf(bio, "%02X", exportedkeymat[i]); - BIO_printf(bio, "\n"); - } - OPENSSL_free(exportedkeymat); + exportedkeymat = app_malloc(keymatexportlen, "export key"); + if (!SSL_export_keying_material(s, exportedkeymat, + keymatexportlen, + keymatexportlabel, + strlen(keymatexportlabel), + NULL, 0, 0)) { + BIO_printf(bio, " Error\n"); + } else { + BIO_printf(bio, " Keying material: "); + for (i = 0; i < keymatexportlen; i++) + BIO_printf(bio, "%02X", exportedkeymat[i]); + BIO_printf(bio, "\n"); } + OPENSSL_free(exportedkeymat); } BIO_printf(bio, "---\n"); - if (peer != NULL) - X509_free(peer); + X509_free(peer); /* flush, or debugging output gets mixed with http response */ (void)BIO_flush(bio); } -#ifndef OPENSSL_NO_TLSEXT - static int ocsp_resp_cb(SSL *s, void *arg) { const unsigned char *p; @@ -2281,5 +2207,3 @@ static int ocsp_resp_cb(SSL *s, void *arg) OCSP_RESPONSE_free(rsp); return 1; } - -#endif