X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=apps%2Fs_client.c;h=eb4dbdcaa26df518ee98397190a16cb1ae695af4;hb=a96e6c347bc1da9964ffe941608b11cf030320ef;hp=6d7a83f3a9b245ccf2a3ff14d42b564c68bb1a3c;hpb=558ea84743918f7a93bfbfc259f86ad1fa4c8de9;p=openssl.git diff --git a/apps/s_client.c b/apps/s_client.c index 6d7a83f3a9..eb4dbdcaa2 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -56,6 +56,12 @@ typedef unsigned int u_int; # endif #endif +DEFINE_STACK_OF(X509) +DEFINE_STACK_OF(X509_CRL) +DEFINE_STACK_OF(X509_NAME) +DEFINE_STACK_OF(SCT) +DEFINE_STACK_OF_STRING() + #undef BUFSIZZ #define BUFSIZZ 1024*8 #define S_CLIENT_IRC_READ_TIMEOUT 8 @@ -75,7 +81,6 @@ static void print_stuff(BIO *berr, SSL *con, int full); static int ocsp_resp_cb(SSL *s, void *arg); #endif static int ldap_ExtendedResponse_parse(const char *buf, long rem); -static char *base64encode (const void *buf, size_t len); static int is_dNS_name(const char *host); static int saved_errno; @@ -272,8 +277,6 @@ typedef struct srp_arg_st { int strength; /* minimal size for N */ } SRP_ARG; -# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64 - static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) { BN_CTX *bn_ctx = BN_CTX_new(); @@ -281,10 +284,10 @@ static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g) BIGNUM *r = BN_new(); int ret = g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) && - BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 && + BN_check_prime(N, bn_ctx, NULL) == 1 && p != NULL && BN_rshift1(p, N) && /* p = (N-1)/2 */ - BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 && + BN_check_prime(p, bn_ctx, NULL) == 1 && r != NULL && /* verify g^((N-1)/2) == -1 (mod N) */ BN_mod_exp(r, g, p, N, bn_ctx) && @@ -583,9 +586,11 @@ typedef enum OPTION_choice { OPT_SSL3, OPT_SSL_CONFIG, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS, - OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, - OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, - OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, + OPT_NEXTPROTONEG, OPT_ALPN, + OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, + OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, + OPT_CASTORE, OPT_NOCASTORE, OPT_CHAINCASTORE, OPT_VERIFYCASTORE, OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_NOSERVERNAME, OPT_ASYNC, OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST, OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, @@ -601,11 +606,27 @@ typedef enum OPTION_choice { OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME, OPT_ENABLE_PHA, OPT_SCTP_LABEL_BUG, - OPT_R_ENUM + OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; const OPTIONS s_client_options[] = { + {OPT_HELP_STR, 1, '-', "Usage: %s [options] [host:port]\n"}, + + OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, + {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's', + "Specify engine to be used for client certificate operations"}, +#endif + {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified section for SSL_CTX configuration"}, +#ifndef OPENSSL_NO_CT + {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, + {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, + {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, +#endif + + OPT_SECTION("Network"), {"host", OPT_HOST, 's', "Use -connect instead"}, {"port", OPT_PORT, 'p', "Use -connect instead"}, {"connect", OPT_CONNECT, 's', @@ -622,20 +643,38 @@ const OPTIONS s_client_options[] = { #ifdef AF_INET6 {"6", OPT_6, '-', "Use IPv6 only"}, #endif - {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, - {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"}, + {"maxfraglen", OPT_MAXFRAGLEN, 'p', + "Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"}, + {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, + {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', + "Size used to split data for encrypt pipelines"}, + {"max_pipelines", OPT_MAX_PIPELINES, 'p', + "Maximum number of encrypt/decrypt pipelines to be used"}, + {"read_buf", OPT_READ_BUF, 'p', + "Default read buffer size to be used for connections"}, + {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, + + OPT_SECTION("Identity"), + {"cert", OPT_CERT, '<', "Client certificate file to use"}, {"certform", OPT_CERTFORM, 'F', - "Certificate format (PEM or DER) PEM default"}, - {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, - {"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"}, + "Client certificate file format (PEM or DER) PEM default"}, + {"cert_chain", OPT_CERT_CHAIN, '<', + "Client certificate chain file (in PEM format)"}, + {"build_chain", OPT_BUILD_CHAIN, '-', "Build client certificate chain"}, + {"key", OPT_KEY, 's', "Private key file to use; default is: -cert file"}, {"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"}, {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, + {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, {"no-CAfile", OPT_NOCAFILE, '-', "Do not load the default certificates file"}, {"no-CApath", OPT_NOCAPATH, '-', "Do not load certificates from the default certificates directory"}, + {"no-CAstore", OPT_NOCASTORE, '-', + "Do not load certificates from the default certificates store"}, {"requestCAfile", OPT_REQCAFILE, '<', "PEM format file of CA names to send to the server"}, {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"}, @@ -643,16 +682,19 @@ const OPTIONS s_client_options[] = { "DANE TLSA rrdata presentation form"}, {"dane_ee_no_namechecks", OPT_DANE_EE_NO_NAME, '-', "Disable name checks when matching DANE-EE(3) TLSA records"}, + {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, + {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, + {"name", OPT_PROTOHOST, 's', + "Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""}, + + OPT_SECTION("Session"), {"reconnect", OPT_RECONNECT, '-', "Drop and re-make the connection with the same Session-ID"}, - {"showcerts", OPT_SHOWCERTS, '-', - "Show all certificates sent by the server"}, - {"debug", OPT_DEBUG, '-', "Extra output"}, - {"msg", OPT_MSG, '-', "Show protocol messages"}, - {"msgfile", OPT_MSGFILE, '>', - "File to send output of -msg or -trace, instead of stdout"}, - {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, - {"state", OPT_STATE, '-', "Print the ssl states"}, + {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, + {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, + + OPT_SECTION("Input/Output"), {"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)"}, @@ -661,47 +703,35 @@ const OPTIONS s_client_options[] = { "Use the appropriate STARTTLS command before starting TLS"}, {"xmpphost", OPT_XMPPHOST, 's', "Alias of -name option for \"-starttls xmpp[-server]\""}, - OPT_R_OPTIONS, - {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"}, - {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"}, -#ifndef OPENSSL_NO_SRTP - {"use_srtp", OPT_USE_SRTP, 's', - "Offer SRTP key management with a colon-separated profile list"}, -#endif - {"keymatexport", OPT_KEYMATEXPORT, 's', - "Export keying material using label"}, - {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', - "Export len bytes of keying material (default 20)"}, - {"maxfraglen", OPT_MAXFRAGLEN, 'p', - "Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"}, - {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"}, - {"name", OPT_PROTOHOST, 's', - "Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""}, - {"CRL", OPT_CRL, '<', "CRL file to use"}, - {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, - {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, - {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', - "Close connection on verification error"}, - {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, {"brief", OPT_BRIEF, '-', "Restrict output to brief summary of connection parameters"}, {"prexit", OPT_PREXIT, '-', "Print session information when the program exits"}, + + OPT_SECTION("Debug"), + {"showcerts", OPT_SHOWCERTS, '-', + "Show all certificates sent by the server"}, + {"debug", OPT_DEBUG, '-', "Extra output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>', + "File to send output of -msg or -trace, instead of stdout"}, + {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"}, + {"state", OPT_STATE, '-', "Print the ssl states"}, + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material (default 20)"}, {"security_debug", OPT_SECURITY_DEBUG, '-', "Enable security debug messages"}, {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', "Output more security debug output"}, - {"cert_chain", OPT_CERT_CHAIN, '<', - "Certificate chain file (in PEM format)"}, - {"chainCApath", OPT_CHAINCAPATH, '/', - "Use dir as certificate store path to build CA certificate chain"}, - {"verifyCApath", OPT_VERIFYCAPATH, '/', - "Use dir as certificate store path to verify CA certificate"}, - {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"}, - {"chainCAfile", OPT_CHAINCAFILE, '<', - "CA file for certificate chain (PEM format)"}, - {"verifyCAfile", OPT_VERIFYCAFILE, '<', - "CA file for certificate verification (PEM format)"}, +#ifndef OPENSSL_NO_SSL_TRACE + {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, +#endif +#ifdef WATT32 + {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, +#endif + {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"}, {"servername", OPT_SERVERNAME, 's', "Set TLS extension servername (SNI) in ClientHello (default)"}, @@ -717,17 +747,9 @@ const OPTIONS s_client_options[] = { {"alpn", OPT_ALPN, 's', "Enable ALPN extension, considering named protocols supported (comma-separated list)"}, {"async", OPT_ASYNC, '-', "Support asynchronous operation"}, - {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"}, - {"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "}, - {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p', - "Size used to split data for encrypt pipelines"}, - {"max_pipelines", OPT_MAX_PIPELINES, 'p', - "Maximum number of encrypt/decrypt pipelines to be used"}, - {"read_buf", OPT_READ_BUF, 'p', - "Default read buffer size to be used for connections"}, - OPT_S_OPTIONS, - OPT_V_OPTIONS, - OPT_X_OPTIONS, + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, + + OPT_SECTION("Protocol and version"), #ifndef OPENSSL_NO_SSL3 {"ssl3", OPT_SSL3, '-', "Just use SSLv3"}, #endif @@ -759,16 +781,16 @@ const OPTIONS s_client_options[] = { {"sctp", OPT_SCTP, '-', "Use SCTP"}, {"sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug"}, #endif -#ifndef OPENSSL_NO_SSL_TRACE - {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"}, +#ifndef OPENSSL_NO_NEXTPROTONEG + {"nextprotoneg", OPT_NEXTPROTONEG, 's', + "Enable NPN extension, considering named protocols supported (comma-separated list)"}, #endif -#ifdef WATT32 - {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"}, + {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"}, + {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"}, +#ifndef OPENSSL_NO_SRTP + {"use_srtp", OPT_USE_SRTP, 's', + "Offer SRTP key management with a colon-separated profile list"}, #endif - {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, - {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"}, - {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, - {"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"}, #ifndef OPENSSL_NO_SRP {"srpuser", OPT_SRPUSER, 's', "SRP authentication for 'user'"}, {"srppass", OPT_SRPPASS, 's', "Password for 'user'"}, @@ -778,24 +800,34 @@ const OPTIONS s_client_options[] = { "Tolerate other than the known g N values."}, {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal length 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', - "Specify engine to be used for client certificate operations"}, -#endif -#ifndef OPENSSL_NO_CT - {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"}, - {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"}, - {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"}, -#endif - {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"}, - {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"}, - {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"}, - {NULL, OPT_EOF, 0x00, NULL} + + OPT_R_OPTIONS, + OPT_S_OPTIONS, + OPT_V_OPTIONS, + {"CRL", OPT_CRL, '<', "CRL file to use"}, + {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, + {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', + "Close connection on verification error"}, + {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, + {"chainCAfile", OPT_CHAINCAFILE, '<', + "CA file for certificate chain (PEM format)"}, + {"chainCApath", OPT_CHAINCAPATH, '/', + "Use dir as certificate store path to build CA certificate chain"}, + {"chainCAstore", OPT_CHAINCASTORE, ':', + "CA store URI for certificate chain"}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<', + "CA file for certificate verification (PEM format)"}, + {"verifyCApath", OPT_VERIFYCAPATH, '/', + "Use dir as certificate store path to verify CA certificate"}, + {"verifyCAstore", OPT_VERIFYCASTORE, ':', + "CA store URI for certificate verification"}, + OPT_X_OPTIONS, + OPT_PROV_OPTIONS, + + OPT_PARAMETERS(), + {"host:port", 0, 0, "Where to connect; same as -connect option"}, + {NULL} }; typedef enum PROTOCOL_choice { @@ -901,28 +933,29 @@ int s_client_main(int argc, char **argv) int dane_ee_no_name = 0; STACK_OF(X509_CRL) *crls = NULL; const SSL_METHOD *meth = TLS_client_method(); - const char *CApath = NULL, *CAfile = NULL; + const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL; char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; char *proxystr = NULL, *proxyuser = NULL; char *proxypassarg = NULL, *proxypass = NULL; char *connectstr = NULL, *bindstr = NULL; char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; - char *chCApath = NULL, *chCAfile = NULL, *host = NULL; + char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL; char *port = OPENSSL_strdup(PORT); char *bindhost = NULL, *bindport = NULL; - char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; + char *passarg = NULL, *pass = NULL; + char *vfyCApath = NULL, *vfyCAfile = NULL, *vfyCAstore = NULL; char *ReqCAfile = NULL; char *sess_in = NULL, *crl_file = NULL, *p; const char *protohost = NULL; struct timeval timeout, *timeoutp; fd_set readfds, writefds; - int noCApath = 0, noCAfile = 0; + int noCApath = 0, noCAfile = 0, noCAstore = 0; 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 sdebug = 0; int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; - int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0; + int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0; int sbuf_len, sbuf_off, cmdletters = 1; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; @@ -1199,6 +1232,10 @@ int s_client_main(int argc, char **argv) if (!opt_rand(o)) goto end; break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; case OPT_IGN_EOF: c_ign_eof = 1; break; @@ -1418,6 +1455,18 @@ int s_client_main(int argc, char **argv) case OPT_VERIFYCAFILE: vfyCAfile = opt_arg(); break; + case OPT_CASTORE: + CAstore = opt_arg(); + break; + case OPT_NOCASTORE: + noCAstore = 1; + break; + case OPT_CHAINCASTORE: + chCAstore = opt_arg(); + break; + case OPT_VERIFYCASTORE: + vfyCAstore = opt_arg(); + break; case OPT_DANE_TLSA_DOMAIN: dane_tlsa_domain = opt_arg(); break; @@ -1665,18 +1714,14 @@ int s_client_main(int argc, char **argv) if (key_file != NULL) { key = load_key(key_file, key_format, 0, pass, e, "client certificate private key file"); - if (key == NULL) { - ERR_print_errors(bio_err); + if (key == NULL) goto end; - } } if (cert_file != NULL) { cert = load_cert(cert_file, cert_format, "client certificate file"); - if (cert == NULL) { - ERR_print_errors(bio_err); + if (cert == NULL) goto end; - } } if (chain_file != NULL) { @@ -1687,12 +1732,9 @@ int s_client_main(int argc, char **argv) if (crl_file != NULL) { X509_CRL *crl; - crl = load_crl(crl_file, crl_format); - if (crl == NULL) { - BIO_puts(bio_err, "Error loading CRL\n"); - ERR_print_errors(bio_err); + crl = load_crl(crl_file, crl_format, "CRL"); + if (crl == NULL) goto end; - } crls = sk_X509_CRL_new_null(); if (crls == NULL || !sk_X509_CRL_push(crls, crl)) { BIO_puts(bio_err, "Error adding CRL\n"); @@ -1798,7 +1840,9 @@ int s_client_main(int argc, char **argv) goto end; } - if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, + if (!ssl_load_stores(ctx, + vfyCApath, vfyCAfile, vfyCAstore, + chCApath, chCAfile, chCAstore, crls, crl_download)) { BIO_printf(bio_err, "Error loading store locations\n"); ERR_print_errors(bio_err); @@ -1927,7 +1971,8 @@ int s_client_main(int argc, char **argv) SSL_CTX_set_verify(ctx, verify, verify_callback); - if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { + if (!ctx_set_verify_locations(ctx, CAfile, noCAfile, CApath, noCApath, + CAstore, noCAstore)) { ERR_print_errors(bio_err); goto end; } @@ -2017,7 +2062,7 @@ int s_client_main(int argc, char **argv) if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) { if (servername == NULL) { - if(host == NULL || is_dNS_name(host)) + if(host == NULL || is_dNS_name(host)) servername = (host == NULL) ? "localhost" : host; } if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) { @@ -2053,16 +2098,16 @@ int s_client_main(int argc, char **argv) } re_start: - if (init_client(&s, host, port, bindhost, bindport, socket_family, + if (init_client(&sock, host, port, bindhost, bindport, socket_family, socket_type, protocol) == 0) { BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); - BIO_closesocket(s); + BIO_closesocket(sock); goto end; } - BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); + BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock); if (c_nbio) { - if (!BIO_socket_nbio(s, 1)) { + if (!BIO_socket_nbio(sock, 1)) { ERR_print_errors(bio_err); goto end; } @@ -2074,21 +2119,21 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_SCTP if (protocol == IPPROTO_SCTP) - sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE); + sbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE); else #endif - sbio = BIO_new_dgram(s, BIO_NOCLOSE); + sbio = BIO_new_dgram(sock, BIO_NOCLOSE); if ((peer_info.addr = BIO_ADDR_new()) == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); - BIO_closesocket(s); + BIO_closesocket(sock); goto end; } - if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) { + if (!BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &peer_info)) { BIO_printf(bio_err, "getsockname:errno=%d\n", get_last_socket_error()); BIO_ADDR_free(peer_info.addr); - BIO_closesocket(s); + BIO_closesocket(sock); goto end; } @@ -2125,7 +2170,7 @@ int s_client_main(int argc, char **argv) } } else #endif /* OPENSSL_NO_DTLS */ - sbio = BIO_new_socket(s, BIO_NOCLOSE); + sbio = BIO_new_socket(sock, BIO_NOCLOSE); if (nbio_test) { BIO *test; @@ -2277,7 +2322,7 @@ int s_client_main(int argc, char **argv) do { mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); } - while (mbuf_len > 3 && mbuf[3] == '-'); + while (mbuf_len > 3 && (!isdigit(mbuf[0]) || !isdigit(mbuf[1]) || !isdigit(mbuf[2]) || mbuf[3] != ' ')); (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); @@ -2356,83 +2401,9 @@ int s_client_main(int argc, char **argv) } break; case PROTO_CONNECT: - { - enum { - error_proto, /* Wrong protocol, not even HTTP */ - error_connect, /* CONNECT failed */ - success - } foundit = error_connect; - BIO *fbio = BIO_new(BIO_f_buffer()); - - BIO_push(fbio, sbio); - BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n", connectstr); - /* - * Workaround for broken proxies which would otherwise close - * the connection when entering tunnel mode (eg Squid 2.6) - */ - BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n"); - - /* Support for basic (base64) proxy authentication */ - if (proxyuser != NULL) { - size_t l; - char *proxyauth, *proxyauthenc; - - l = strlen(proxyuser); - if (proxypass != NULL) - l += strlen(proxypass); - proxyauth = app_malloc(l + 2, "Proxy auth string"); - BIO_snprintf(proxyauth, l + 2, "%s:%s", proxyuser, - (proxypass != NULL) ? proxypass : ""); - proxyauthenc = base64encode(proxyauth, strlen(proxyauth)); - BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", - proxyauthenc); - OPENSSL_clear_free(proxyauth, strlen(proxyauth)); - OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc)); - } - - /* Terminate the HTTP CONNECT request */ - BIO_printf(fbio, "\r\n"); - (void)BIO_flush(fbio); - /* - * The first line is the HTTP response. According to RFC 7230, - * it's formated exactly like this: - * - * HTTP/d.d ddd Reason text\r\n - */ - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - if (mbuf_len < (int)strlen("HTTP/1.0 200")) { - BIO_printf(bio_err, - "%s: HTTP CONNECT failed, insufficient response " - "from proxy (got %d octets)\n", prog, mbuf_len); - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - goto shut; - } - if (mbuf[8] != ' ') { - BIO_printf(bio_err, - "%s: HTTP CONNECT failed, incorrect response " - "from proxy\n", prog); - foundit = error_proto; - } else if (mbuf[9] != '2') { - BIO_printf(bio_err, "%s: HTTP CONNECT failed: %s ", prog, - &mbuf[9]); - } else { - foundit = success; - } - if (foundit != error_proto) { - /* Read past all following headers */ - do { - mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); - } while (mbuf_len > 2); - } - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - if (foundit != success) { - goto shut; - } - } + if (!OSSL_HTTP_proxy_connect(sbio, host, port, proxyuser, proxypass, + 0 /* no timeout */, bio_err, prog)) + goto shut; break; case PROTO_IRC: { @@ -3104,7 +3075,7 @@ int s_client_main(int argc, char **argv) BIO_printf(bio_err, "RENEGOTIATING\n"); SSL_renegotiate(con); cbuf_len = 0; - } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) + } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' ) && cmdletters) { BIO_printf(bio_err, "KEYUPDATE\n"); SSL_key_update(con, @@ -3150,8 +3121,8 @@ int s_client_main(int argc, char **argv) timeout.tv_usec = 500000; /* some extreme round-trip */ do { FD_ZERO(&readfds); - openssl_fdset(s, &readfds); - } while (select(s + 1, &readfds, NULL, NULL, &timeout) > 0 + openssl_fdset(sock, &readfds); + } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0 && BIO_read(sbio, sbuf, BUFSIZZ) > 0); BIO_closesocket(SSL_get_fd(con)); @@ -3313,6 +3284,8 @@ static void print_stuff(BIO *bio, SSL *s, int full) #ifndef OPENSSL_NO_KTLS if (BIO_get_ktls_send(SSL_get_wbio(s))) BIO_printf(bio_err, "Using Kernel TLS for sending\n"); + if (BIO_get_ktls_recv(SSL_get_rbio(s))) + BIO_printf(bio_err, "Using Kernel TLS for receiving\n"); #endif if (OSSL_TRACE_ENABLED(TLS)) { @@ -3527,30 +3500,7 @@ static int ldap_ExtendedResponse_parse(const char *buf, long rem) } /* - * BASE64 encoder: used only for encoding basic proxy authentication credentials - */ -static char *base64encode (const void *buf, size_t len) -{ - int i; - size_t outl; - char *out; - - /* Calculate size of encoded data */ - outl = (len / 3); - if (len % 3 > 0) - outl++; - outl <<= 2; - out = app_malloc(outl + 1, "base64 encode buffer"); - - i = EVP_EncodeBlock((unsigned char *)out, buf, len); - assert(i <= (int)outl); - if (i < 0) - *out = '\0'; - return out; -} - -/* - * Host dNS Name verifier: used for checking that the hostname is in dNS format + * Host dNS Name verifier: used for checking that the hostname is in dNS format * before setting it as SNI */ static int is_dNS_name(const char *host)