* https://www.openssl.org/source/license.html
*/
+/* We need to use some engine deprecated APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include "e_os.h"
#include <ctype.h>
#include <stdio.h>
# endif
#endif
-DEFINE_STACK_OF(X509)
-DEFINE_STACK_OF(X509_CRL)
-DEFINE_STACK_OF(X509_NAME)
DEFINE_STACK_OF(SCT)
DEFINE_STACK_OF_STRING()
OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE,
OPT_V_ENUM,
OPT_X_ENUM,
- OPT_S_ENUM,
+ OPT_S_ENUM, OPT_IGNORE_UNEXPECTED_EOF,
OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS,
OPT_DANE_TLSA_DOMAIN,
#ifndef OPENSSL_NO_CT
{"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 :" PORT ")"},
+ "TCP/IP where to connect; default: " PORT ")"},
{"bind", OPT_BIND, 's', "bind local address for connection"},
{"proxy", OPT_PROXY, 's',
"Connect to via specified proxy to the real server"},
{"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"},
+ {"key", OPT_KEY, 's', "Private key file to use; default: -cert file"},
{"keyform", OPT_KEYFORM, 'E', "Key format (ENGINE, other values ignored)"},
- {"pass", OPT_PASS, 's', "Private key file pass phrase source"},
+ {"pass", OPT_PASS, 's', "Private key and cert 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"},
{"keymatexport", OPT_KEYMATEXPORT, 's',
"Export keying material using label"},
{"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
- "Export len bytes of keying material (default 20)"},
+ "Export len bytes of keying material; default 20"},
{"security_debug", OPT_SECURITY_DEBUG, '-',
"Enable security debug messages"},
{"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-',
"Do not send the server name (SNI) extension in the ClientHello"},
{"tlsextdebug", OPT_TLSEXTDEBUG, '-',
"Hex dump of all TLS extensions received"},
+ {"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-',
+ "Do not treat lack of close_notify from a peer as an error"},
#ifndef OPENSSL_NO_OCSP
{"status", OPT_STATUS, '-', "Request certificate status from server"},
#endif
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"},
+ {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER); default PEM"},
{"verify_return_error", OPT_VERIFY_RET_ERROR, '-',
"Close connection on verification error"},
{"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"},
char *connectstr = NULL, *bindstr = NULL;
char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL;
+ char *thost = NULL, *tport = NULL;
char *port = OPENSSL_strdup(PORT);
char *bindhost = NULL, *bindport = NULL;
char *passarg = NULL, *pass = NULL;
#ifndef OPENSSL_NO_SCTP
int sctp_label_bug = 0;
#endif
+ int ignore_unexpected_eof = 0;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
if (!args_excert(o, &exc))
goto end;
break;
+ case OPT_IGNORE_UNEXPECTED_EOF:
+ ignore_unexpected_eof = 1;
+ break;
case OPT_PREXIT:
prexit = 1;
break;
case OPT_SSL3:
min_version = SSL3_VERSION;
max_version = SSL3_VERSION;
+ socket_type = SOCK_STREAM;
+#ifndef OPENSSL_NO_DTLS
+ isdtls = 0;
+#endif
break;
case OPT_TLS1_3:
min_version = TLS1_3_VERSION;
max_version = TLS1_3_VERSION;
+ socket_type = SOCK_STREAM;
+#ifndef OPENSSL_NO_DTLS
+ isdtls = 0;
+#endif
break;
case OPT_TLS1_2:
min_version = TLS1_2_VERSION;
max_version = TLS1_2_VERSION;
+ socket_type = SOCK_STREAM;
+#ifndef OPENSSL_NO_DTLS
+ isdtls = 0;
+#endif
break;
case OPT_TLS1_1:
min_version = TLS1_1_VERSION;
max_version = TLS1_1_VERSION;
+ socket_type = SOCK_STREAM;
+#ifndef OPENSSL_NO_DTLS
+ isdtls = 0;
+#endif
break;
case OPT_TLS1:
min_version = TLS1_VERSION;
max_version = TLS1_VERSION;
+ socket_type = SOCK_STREAM;
+#ifndef OPENSSL_NO_DTLS
+ isdtls = 0;
+#endif
break;
case OPT_DTLS:
#ifndef OPENSSL_NO_DTLS
goto opthelp;
}
#endif
- if (proxystr != NULL) {
+
+ if (connectstr != NULL) {
int res;
char *tmp_host = host, *tmp_port = port;
- if (connectstr == NULL) {
- BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog);
- goto opthelp;
- }
- res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST);
+
+ res = BIO_parse_hostserv(connectstr, &host, &port, BIO_PARSE_PRIO_HOST);
if (tmp_host != host)
OPENSSL_free(tmp_host);
if (tmp_port != port)
OPENSSL_free(tmp_port);
if (!res) {
BIO_printf(bio_err,
- "%s: -proxy argument malformed or ambiguous\n", prog);
+ "%s: -connect argument or target parameter malformed or ambiguous\n",
+ prog);
goto end;
}
- } else {
- int res = 1;
+ }
+
+ if (proxystr != NULL) {
+ int res;
char *tmp_host = host, *tmp_port = port;
- if (connectstr != NULL)
- res = BIO_parse_hostserv(connectstr, &host, &port,
- BIO_PARSE_PRIO_HOST);
+
+ if (host == NULL || port == NULL) {
+ BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog);
+ goto opthelp;
+ }
+
+ /* Retain the original target host:port for use in the HTTP proxy connect string */
+ thost = OPENSSL_strdup(host);
+ tport = OPENSSL_strdup(port);
+ if (thost == NULL || tport == NULL) {
+ BIO_printf(bio_err, "%s: out of memory\n", prog);
+ goto end;
+ }
+
+ res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST);
if (tmp_host != host)
OPENSSL_free(tmp_host);
if (tmp_port != port)
OPENSSL_free(tmp_port);
if (!res) {
BIO_printf(bio_err,
- "%s: -connect argument or target parameter malformed or ambiguous\n",
- prog);
+ "%s: -proxy argument malformed or ambiguous\n", prog);
goto end;
}
}
}
if (cert_file != NULL) {
- cert = load_cert(cert_file, cert_format, "client certificate file");
+ cert = load_cert_pass(cert_file, cert_format, pass, "client certificate file");
if (cert == NULL)
goto end;
}
if (chain_file != NULL) {
- if (!load_certs(chain_file, &chain, FORMAT_PEM, NULL,
- "client certificate chain"))
+ if (!load_certs(chain_file, &chain, pass, "client certificate chain"))
goto end;
}
&& SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
goto end;
+ if (ignore_unexpected_eof)
+ SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
+
if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
BIO_printf(bio_err, "Error setting verify params\n");
ERR_print_errors(bio_err);
}
break;
case PROTO_CONNECT:
- if (!OSSL_HTTP_proxy_connect(sbio, host, port, proxyuser, proxypass,
+ /* Here we must use the connect string target host & port */
+ if (!OSSL_HTTP_proxy_connect(sbio, thost, tport, proxyuser, proxypass,
0 /* no timeout */, bio_err, prog))
goto shut;
break;
OPENSSL_free(bindstr);
OPENSSL_free(host);
OPENSSL_free(port);
+ OPENSSL_free(thost);
+ OPENSSL_free(tport);
X509_VERIFY_PARAM_free(vpm);
ssl_excert_free(exc);
sk_OPENSSL_STRING_free(ssl_args);
}
BIO_printf(bio, "---\n");
- peer = SSL_get_peer_certificate(s);
+ peer = SSL_get0_peer_certificate(s);
if (peer != NULL) {
BIO_printf(bio, "Server certificate\n");
OPENSSL_free(exportedkeymat);
}
BIO_printf(bio, "---\n");
- X509_free(peer);
/* flush, or debugging output gets mixed with http response */
(void)BIO_flush(bio);
}