/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <openssl/rand.h>
#include <openssl/ocsp.h>
#include <openssl/bn.h>
+#include <openssl/trace.h>
#include <openssl/async.h>
#ifndef OPENSSL_NO_SRP
# include <openssl/srp.h>
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;
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();
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) &&
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,
OPT_V_ENUM,
OPT_X_ENUM,
OPT_S_ENUM,
- OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_DANE_TLSA_DOMAIN,
+ OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS,
+ OPT_DANE_TLSA_DOMAIN,
#ifndef OPENSSL_NO_CT
OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
#endif
OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
- OPT_FORCE_PHA,
+ OPT_ENABLE_PHA,
+ OPT_SCTP_LABEL_BUG,
OPT_R_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 configuration file"},
+#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',
{"bind", OPT_BIND, 's', "bind local address for connection"},
{"proxy", OPT_PROXY, 's',
"Connect to via specified proxy to the real server"},
+ {"proxy_user", OPT_PROXY_USER, 's', "UserID for proxy authentication"},
+ {"proxy_pass", OPT_PROXY_PASS, 's', "Proxy authentication password source"},
#ifdef AF_UNIX
{"unix", OPT_UNIX, 's', "Connect over the specified Unix-domain socket"},
#endif
#ifdef AF_INET6
{"6", OPT_6, '-', "Use IPv6 only"},
#endif
+ {"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"),
{"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"},
{"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"},
{"certform", OPT_CERTFORM, 'F',
{"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"},
+ {"CAstore", OPT_CAFILE, ':', "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_NOCAPATH, '-',
+ "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"},
"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)"},
"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)"},
{"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
#endif
#ifndef OPENSSL_NO_SCTP
{"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'"},
"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"},
- {"force_pha", OPT_FORCE_PHA, '-', "Force-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"},
+ {"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"},
+ {"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"},
+ {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"},
+ {"chainCAfile", OPT_CHAINCAFILE, '<',
+ "CA file for certificate chain (PEM format)"},
+ OPT_X_OPTIONS,
+
+ OPT_PARAMETERS(),
+ {"host:port", 0, 0, "Where to connect; same as -connect option"},
+ {NULL}
};
typedef enum PROTOCOL_choice {
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;
- char *cbuf = NULL, *sbuf = NULL;
- char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL, *bindstr = 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 isdtls = 0;
#endif
char *psksessf = NULL;
- int force_pha = 0;
+ int enable_pha = 0;
+#ifndef OPENSSL_NO_SCTP
+ int sctp_label_bug = 0;
+#endif
FD_ZERO(&readfds);
FD_ZERO(&writefds);
proxystr = opt_arg();
starttls_proto = PROTO_CONNECT;
break;
+ case OPT_PROXY_USER:
+ proxyuser = opt_arg();
+ break;
+ case OPT_PROXY_PASS:
+ proxypassarg = opt_arg();
+ break;
#ifdef AF_UNIX
case OPT_UNIX:
connect_type = use_unix;
goto opthelp;
break;
case OPT_VERIFY_RET_ERROR:
+ verify = SSL_VERIFY_PEER;
verify_args.return_error = 1;
break;
case OPT_VERIFY_QUIET:
case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
protocol = IPPROTO_SCTP;
+#endif
+ break;
+ case OPT_SCTP_LABEL_BUG:
+#ifndef OPENSSL_NO_SCTP
+ sctp_label_bug = 1;
#endif
break;
case OPT_TIMEOUT:
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;
case OPT_EARLY_DATA:
early_data_file = opt_arg();
break;
- case OPT_FORCE_PHA:
- force_pha = 1;
+ case OPT_ENABLE_PHA:
+ enable_pha = 1;
break;
}
}
+
if (count4or6 >= 2) {
BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog);
goto opthelp;
#endif
if (!app_passwd(passarg, NULL, &pass, NULL)) {
- BIO_printf(bio_err, "Error getting password\n");
+ BIO_printf(bio_err, "Error getting private key password\n");
+ goto end;
+ }
+
+ if (!app_passwd(proxypassarg, NULL, &proxypass, NULL)) {
+ BIO_printf(bio_err, "Error getting proxy password\n");
+ goto end;
+ }
+
+ if (proxypass != NULL && proxyuser == NULL) {
+ BIO_printf(bio_err, "Error: Must specify proxy_user with proxy_pass\n");
goto end;
}
}
}
+#ifndef OPENSSL_NO_SCTP
+ if (protocol == IPPROTO_SCTP && sctp_label_bug == 1)
+ SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
+#endif
+
if (min_version != 0
&& SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;
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);
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;
}
if (con == NULL)
goto end;
- if (force_pha)
- SSL_force_post_handshake_auth(con);
+ if (enable_pha)
+ SSL_set_post_handshake_auth(con, 1);
if (sess_in != NULL) {
SSL_SESSION *sess;
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
- if (servername == NULL)
- servername = (host == NULL) ? "localhost" : host;
- if (!SSL_set_tlsext_host_name(con, servername)) {
+ if (servername == NULL) {
+ if(host == NULL || is_dNS_name(host))
+ servername = (host == NULL) ? "localhost" : host;
+ }
+ if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) {
BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
ERR_print_errors(bio_err);
goto end;
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);
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
- BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n\r\n", connectstr);
+ 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:
+ * it's formatted exactly like this:
*
* HTTP/d.d ddd Reason text\r\n
*/
/* STARTTLS command requires CAPABILITIES... */
BIO_printf(fbio, "CAPABILITIES\r\n");
(void)BIO_flush(fbio);
- /* wait for multi-line CAPABILITIES response */
- do {
- mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
- if (strstr(mbuf, "STARTTLS"))
- foundit = 1;
- } while (mbuf_len > 1 && mbuf[0] != '.');
+ BIO_gets(fbio, mbuf, BUFSIZZ);
+ /* no point in trying to parse the CAPABILITIES response if there is none */
+ if (strstr(mbuf, "101") != NULL) {
+ /* wait for multi-line CAPABILITIES response */
+ do {
+ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+ if (strstr(mbuf, "STARTTLS"))
+ foundit = 1;
+ } while (mbuf_len > 1 && mbuf[0] != '.');
+ }
(void)BIO_flush(fbio);
BIO_pop(fbio);
BIO_free(fbio);
BIO_printf(bio_err, "RENEGOTIATING\n");
SSL_renegotiate(con);
cbuf_len = 0;
- }
-
- 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,
cbuf[0] == 'K' ? SSL_KEY_UPDATE_REQUESTED
: SSL_KEY_UPDATE_NOT_REQUESTED);
cbuf_len = 0;
- }
-#ifndef OPENSSL_NO_HEARTBEATS
- else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) {
- BIO_printf(bio_err, "HEARTBEATING\n");
- SSL_heartbeat(con);
- cbuf_len = 0;
- }
-#endif
- else {
+ } else {
cbuf_len = i;
cbuf_off = 0;
#ifdef CHARSET_EBCDIC
OPENSSL_clear_free(cbuf, BUFSIZZ);
OPENSSL_clear_free(sbuf, BUFSIZZ);
OPENSSL_clear_free(mbuf, BUFSIZZ);
+ if (proxypass != NULL)
+ OPENSSL_clear_free(proxypass, strlen(proxypass));
release_engine(e);
BIO_free(bio_c_out);
bio_c_out = NULL;
BIO_printf(bio, "Expansion: %s\n",
expansion ? SSL_COMP_get_name(expansion) : "NONE");
#endif
+#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
-#ifdef SSL_DEBUG
- {
+ if (OSSL_TRACE_ENABLED(TLS)) {
/* Print out local port of connection: useful for debugging */
int sock;
union BIO_sock_info_u info;
}
BIO_ADDR_free(info.addr);
}
-#endif
#if !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.status != -1) {
return ret;
}
+/*
+ * 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
+ * before setting it as SNI
+ */
+static int is_dNS_name(const char *host)
+{
+ const size_t MAX_LABEL_LENGTH = 63;
+ size_t i;
+ int isdnsname = 0;
+ size_t length = strlen(host);
+ size_t label_length = 0;
+ int all_numeric = 1;
+
+ /*
+ * Deviation from strict DNS name syntax, also check names with '_'
+ * Check DNS name syntax, any '-' or '.' must be internal,
+ * and on either side of each '.' we can't have a '-' or '.'.
+ *
+ * If the name has just one label, we don't consider it a DNS name.
+ */
+ for (i = 0; i < length && label_length < MAX_LABEL_LENGTH; ++i) {
+ char c = host[i];
+
+ if ((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '_') {
+ label_length += 1;
+ all_numeric = 0;
+ continue;
+ }
+
+ if (c >= '0' && c <= '9') {
+ label_length += 1;
+ continue;
+ }
+
+ /* Dot and hyphen cannot be first or last. */
+ if (i > 0 && i < length - 1) {
+ if (c == '-') {
+ label_length += 1;
+ continue;
+ }
+ /*
+ * Next to a dot the preceding and following characters must not be
+ * another dot or a hyphen. Otherwise, record that the name is
+ * plausible, since it has two or more labels.
+ */
+ if (c == '.'
+ && host[i + 1] != '.'
+ && host[i - 1] != '-'
+ && host[i + 1] != '-') {
+ label_length = 0;
+ isdnsname = 1;
+ continue;
+ }
+ }
+ isdnsname = 0;
+ break;
+ }
+
+ /* dNS name must not be all numeric and labels must be shorter than 64 characters. */
+ isdnsname &= !all_numeric && !(label_length == MAX_LABEL_LENGTH);
+
+ return isdnsname;
+}
#endif /* OPENSSL_NO_SOCK */