#endif
OPT_SSL3, OPT_SSL_CONFIG,
OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
- OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
+ 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_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME,
+ OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_NOSERVERNAME,
OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST,
OPT_ASYNC, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
- OPT_KEYLOG_FILE, OPT_EARLY_DATA,
+ OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE,
OPT_V_ENUM,
OPT_X_ENUM,
OPT_S_ENUM,
"Do not load the default certificates file"},
{"no-CApath", OPT_NOCAPATH, '-',
"Do not load certificates from the default certificates directory"},
+ {"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", OPT_DANE_TLSA_RRDATA, 's',
"DANE TLSA rrdata presentation form"},
{"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"},
{"servername", OPT_SERVERNAME, 's',
"Set TLS extension servername in ClientHello"},
+ {"noservername", OPT_NOSERVERNAME, '-',
+ "Do not send the server name (SNI) extension in the ClientHello"},
{"tlsextdebug", OPT_TLSEXTDEBUG, '-',
"Hex dump of all TLS extensions received"},
#ifndef OPENSSL_NO_OCSP
#ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"},
#endif
+#ifndef OPENSSL_NO_SCTP
+ {"sctp", OPT_SCTP, '-', "Use SCTP"},
+#endif
#ifndef OPENSSL_NO_SSL_TRACE
{"trace", OPT_TRACE, '-', "Show trace output of protocol messages"},
#endif
char *port = OPENSSL_strdup(PORT);
char *inrand = NULL;
char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+ char *ReqCAfile = NULL;
char *sess_in = NULL, *crl_file = NULL, *p;
char *xmpphost = NULL;
const char *ehlo = "mail.example.com";
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 sbuf_len, sbuf_off, cmdletters = 1;
- int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
+ int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
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;
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
struct timeval tv;
#endif
char *servername = NULL;
+ int noservername = 0;
const char *alpn_in = NULL;
tlsextctx tlsextcbp = { NULL, 0 };
const char *ssl_config = NULL;
#endif
BIO *bio_c_msg = NULL;
const char *keylog_file = NULL, *early_data_file = NULL;
+#ifndef OPENSSL_NO_DTLS
+ int isdtls = 0;
+#endif
FD_ZERO(&readfds);
FD_ZERO(&writefds);
#ifndef OPENSSL_NO_DTLS
meth = DTLS_client_method();
socket_type = SOCK_DGRAM;
+ isdtls = 1;
#endif
break;
case OPT_DTLS1:
min_version = DTLS1_VERSION;
max_version = DTLS1_VERSION;
socket_type = SOCK_DGRAM;
+ isdtls = 1;
#endif
break;
case OPT_DTLS1_2:
min_version = DTLS1_2_VERSION;
max_version = DTLS1_2_VERSION;
socket_type = SOCK_DGRAM;
+ isdtls = 1;
+#endif
+ break;
+ case OPT_SCTP:
+#ifndef OPENSSL_NO_SCTP
+ protocol = IPPROTO_SCTP;
#endif
break;
case OPT_TIMEOUT:
case OPT_BUILD_CHAIN:
build_chain = 1;
break;
+ case OPT_REQCAFILE:
+ ReqCAfile = opt_arg();
+ break;
case OPT_CAFILE:
CAfile = opt_arg();
break;
case OPT_SERVERNAME:
servername = opt_arg();
break;
+ case OPT_NOSERVERNAME:
+ noservername = 1;
+ break;
case OPT_USE_SRTP:
srtp_profiles = opt_arg();
break;
BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog);
goto opthelp;
}
+ if (noservername) {
+ if (servername != NULL) {
+ BIO_printf(bio_err,
+ "%s: Can't use -servername and -noservername together\n",
+ prog);
+ goto opthelp;
+ }
+ if (dane_tlsa_domain != NULL) {
+ BIO_printf(bio_err,
+ "%s: Can't use -dane_tlsa_domain and -noservername together\n",
+ prog);
+ goto opthelp;
+ }
+ }
argc = opt_num_rest();
if (argc != 0)
goto opthelp;
goto end;
}
+#ifndef OPENSSL_NO_SCTP
+ if (protocol == IPPROTO_SCTP) {
+ if (socket_type != SOCK_DGRAM) {
+ BIO_printf(bio_err, "Can't use -sctp without DTLS\n");
+ goto end;
+ }
+ /* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */
+ socket_type = SOCK_STREAM;
+ }
+#endif
+
if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
BIO_printf(bio_err, "Bad split send fragment size\n");
goto end;
ERR_print_errors(bio_err);
goto end;
}
+ if (ReqCAfile != NULL) {
+ STACK_OF(X509_NAME) *nm = sk_X509_NAME_new_null();
+
+ if (nm == NULL || !SSL_add_file_cert_subjects_to_stack(nm, ReqCAfile)) {
+ sk_X509_NAME_pop_free(nm, X509_NAME_free);
+ BIO_printf(bio_err, "Error loading CA names\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ SSL_CTX_set0_CA_list(ctx, nm);
+ }
#ifndef OPENSSL_NO_ENGINE
if (ssl_client_engine) {
if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain))
goto end;
- if (servername != NULL) {
+ if (!noservername) {
tlsextcbp.biodebug = bio_err;
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
if (fallback_scsv)
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
- if (servername != NULL) {
+ if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
+ if (servername == NULL)
+ servername = (host == NULL) ? "localhost" : host;
if (!SSL_set_tlsext_host_name(con, servername)) {
BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
ERR_print_errors(bio_err);
}
re_start:
- if (init_client(&s, host, port, socket_family, socket_type) == 0) {
+ if (init_client(&s, host, port, socket_family, socket_type, protocol)
+ == 0) {
BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
BIO_closesocket(s);
goto end;
BIO_printf(bio_c_out, "Turned on non blocking io\n");
}
#ifndef OPENSSL_NO_DTLS
- if (socket_type == SOCK_DGRAM) {
+ if (isdtls) {
union BIO_sock_info_u peer_info;
- sbio = BIO_new_dgram(s, BIO_NOCLOSE);
+#ifndef OPENSSL_NO_SCTP
+ if (protocol == IPPROTO_SCTP)
+ sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
+ else
+#endif
+ sbio = BIO_new_dgram(s, BIO_NOCLOSE);
+
if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
BIO_printf(bio_err, "memory allocation failure\n");
BIO_closesocket(s);
else
timeoutp = NULL;
- if (SSL_in_init(con) && !SSL_total_renegotiations(con)
+ if (!SSL_is_init_finished(con) && SSL_total_renegotiations(con) == 0
&& SSL_get_key_update_type(con) == SSL_KEY_UPDATE_NONE) {
in_init = 1;
tty_on = 0;
if (in_init) {
in_init = 0;
- if (servername != NULL && !SSL_session_reused(con)) {
- BIO_printf(bio_c_out,
- "Server did %sacknowledge servername extension.\n",
- tlsextcbp.ack ? "" : "not ");
- }
-
if (c_brief) {
BIO_puts(bio_err, "CONNECTION ESTABLISHED\n");
print_ssl_summary(con);
static void print_stuff(BIO *bio, SSL *s, int full)
{
X509 *peer = NULL;
- char buf[BUFSIZ];
STACK_OF(X509) *sk;
- STACK_OF(X509_NAME) *sk2;
const SSL_CIPHER *c;
- X509_NAME *xn;
int i;
#ifndef OPENSSL_NO_COMP
const COMP_METHOD *comp, *expansion;
BIO_printf(bio, "---\nCertificate chain\n");
for (i = 0; i < sk_X509_num(sk); i++) {
- X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)),
- buf, sizeof buf);
- BIO_printf(bio, "%2d s:%s\n", i, buf);
- X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)),
- buf, sizeof buf);
- BIO_printf(bio, " i:%s\n", buf);
+ BIO_printf(bio, "%2d s:", i);
+ X509_NAME_print_ex(bio, X509_get_subject_name(sk_X509_value(sk, i)), 0, get_nameopt());
+ BIO_puts(bio, "\n");
+ BIO_printf(bio, " i:");
+ X509_NAME_print_ex(bio, X509_get_issuer_name(sk_X509_value(sk, i)), 0, get_nameopt());
+ BIO_puts(bio, "\n");
if (c_showcerts)
PEM_write_bio_X509(bio, sk_X509_value(sk, i));
}
/* Redundant if we showed the whole chain */
if (!(c_showcerts && got_a_chain))
PEM_write_bio_X509(bio, peer);
- X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
- BIO_printf(bio, "subject=%s\n", buf);
- X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
- BIO_printf(bio, "issuer=%s\n", buf);
- } else
- BIO_printf(bio, "no peer certificate available\n");
-
- sk2 = SSL_get_client_CA_list(s);
- if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
- BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
- for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
- xn = sk_X509_NAME_value(sk2, i);
- X509_NAME_oneline(xn, buf, sizeof(buf));
- BIO_write(bio, buf, strlen(buf));
- BIO_write(bio, "\n", 1);
- }
+ dump_cert_text(bio, peer);
} else {
- BIO_printf(bio, "---\nNo client certificate CA names sent\n");
+ BIO_printf(bio, "no peer certificate available\n");
}
+ print_ca_names(bio, s);
ssl_print_sigalgs(bio, s);
ssl_print_tmp_key(bio, s);
#endif
BIO_printf(bio,
- "---\nSSL handshake has read %" PRIu64
- " bytes and written %" PRIu64 " bytes\n",
+ "---\nSSL handshake has read %ju bytes "
+ "and written %ju bytes\n",
BIO_number_read(SSL_get_rbio(s)),
BIO_number_written(SSL_get_wbio(s)));
}