/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
#endif
#include "internal/sockets.h"
+DEFINE_STACK_OF(X509_EXTENSION)
+DEFINE_STACK_OF(X509_CRL)
+DEFINE_STACK_OF(X509)
+DEFINE_STACK_OF(SSL_CIPHER)
+DEFINE_STACK_OF_STRING()
+
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
static int sv_body(int s, int stype, int prot, unsigned char *context);
static int www_body(int s, int stype, int prot, unsigned char *context);
static int async = 0;
+static int use_sendfile = 0;
+
static const char *session_id_prefix = NULL;
#ifndef OPENSSL_NO_DTLS
if (SSL_select_next_proto
((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in,
inlen) != OPENSSL_NPN_NEGOTIATED) {
- return SSL_TLSEXT_ERR_NOACK;
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
}
if (!s_quiet) {
OPT_SSL3, 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_LISTEN, OPT_STATELESS,
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
- OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
+ OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_SENDFILE,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
- OPT_HTTP_SERVER_BINMODE,
+ OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES,
OPT_R_ENUM,
OPT_S_ENUM,
OPT_V_ENUM,
- OPT_X_ENUM
+ OPT_X_ENUM,
+ OPT_PROV_ENUM
} OPTION_CHOICE;
const OPTIONS s_server_options[] = {
{"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"},
{"Verify", OPT_UPPER_V_VERIFY, 'n',
"Turn on peer certificate verification, must have a cert"},
- {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT},
+ {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"},
+ {"cert", OPT_CERT, '<', "Server certificate file to use; default is " TEST_CERT},
{"cert2", OPT_CERT2, '<',
"Certificate file to use for servername; default is" TEST_CERT2},
- {"key2", OPT_KEY2, '<',
- "-Private Key file to use for servername if not in -cert2"},
- {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
+ {"certform", OPT_CERTFORM, 'F',
+ "Server certificate file format (PEM or DER) PEM default"},
+ {"cert_chain", OPT_CERT_CHAIN, '<',
+ "Server certificate chain file in PEM format"},
+ {"build_chain", OPT_BUILD_CHAIN, '-', "Build server certificate chain"},
{"serverinfo", OPT_SERVERINFO, 's',
"PEM serverinfo file for certificate"},
- {"certform", OPT_CERTFORM, 'F',
- "Certificate format (PEM or DER) PEM default"},
{"key", OPT_KEY, 's',
- "Private Key if not in -cert; default is " TEST_CERT},
+ "Private key file to use; default is -cert file or else" TEST_CERT},
+ {"key2", OPT_KEY2, '<',
+ "-Private Key file to use for servername if not in -cert2"},
{"keyform", OPT_KEYFORM, 'f',
"Key format (PEM, DER or ENGINE) PEM default"},
{"pass", OPT_PASS, 's', "Private key file pass phrase source"},
{"dcert", OPT_DCERT, '<',
- "Second certificate file to use (usually for DSA)"},
- {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"},
+ "Second server certificate file to use (usually for DSA)"},
{"dcertform", OPT_DCERTFORM, 'F',
- "Second certificate format (PEM or DER) PEM default"},
+ "Second server certificate file format (PEM or DER) PEM default"},
+ {"dcert_chain", OPT_DCERT_CHAIN, '<',
+ "second server certificate chain file in PEM format"},
{"dkey", OPT_DKEY, '<',
"Second private key file to use (usually for DSA)"},
{"dkeyform", OPT_DKEYFORM, 'F',
- "Second key format (PEM, DER or ENGINE) PEM default"},
+ "Second key file format (PEM, DER or ENGINE) PEM default"},
{"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"},
+ {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"},
{"servername", OPT_SERVERNAME, 's',
"Servername for HostName TLS extension"},
{"servername_fatal", OPT_SERVERNAME_FATAL, '-',
{"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
"Export len bytes of keying material (default 20)"},
{"CRL", OPT_CRL, '<', "CRL file to use"},
+ {"CRLform", OPT_CRLFORM, 'F', "CRL file format (PEM or DER); default PEM"},
{"crl_download", OPT_CRL_DOWNLOAD, '-',
- "Download CRL from distribution points"},
+ "Download CRLs from distribution points in certificate CDP entries"},
+ {"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, ':',
"use URI as certificate store to build CA 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, ':',
{"no_cache", OPT_NO_CACHE, '-', "Disable session cache"},
{"ext_cache", OPT_EXT_CACHE, '-',
"Disable internal cache, setup and use external cache"},
- {"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, '-',
"No verify output except verify errors"},
- {"verifyCAfile", OPT_VERIFYCAFILE, '<',
- "CA file for certificate verification (PEM format)"},
{"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"},
{"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"},
{"anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)"},
{"no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection"},
{"http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)"},
+ {"no_ca_names", OPT_NOCANAMES, '-',
+ "Disable TLS Extension CA Names"},
{"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"},
#ifndef OPENSSL_NO_SSL3
{"ssl3", OPT_SSL3, '-', "Just talk SSLv3"},
#endif
{"alpn", OPT_ALPN, 's',
"Set the advertised protocols for the ALPN extension (comma-separated list)"},
+#ifndef OPENSSL_NO_KTLS
+ {"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"},
+#endif
OPT_R_OPTIONS,
OPT_S_OPTIONS,
OPT_V_OPTIONS,
- {"cert_chain", OPT_CERT_CHAIN, '<',
- "certificate chain file in PEM format"},
- {"dcert_chain", OPT_DCERT_CHAIN, '<',
- "second certificate chain file in PEM format"},
- {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"},
- {"chainCAfile", OPT_CHAINCAFILE, '<',
- "CA file for certificate chain (PEM format)"},
OPT_X_OPTIONS,
+ OPT_PROV_OPTIONS,
{NULL}
};
const char *keylog_file = NULL;
int max_early_data = -1, recv_max_early_data = -1;
char *psksessf = NULL;
+ int no_ca_names = 0;
#ifndef OPENSSL_NO_SCTP
int sctp_label_bug = 0;
#endif
s_quiet = 0;
s_brief = 0;
async = 0;
+ use_sendfile = 0;
cctx = SSL_CONF_CTX_new();
vpm = X509_VERIFY_PARAM_new();
s_key_file = opt_arg();
break;
case OPT_KEYFORM:
- if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format))
+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &s_key_format))
goto opthelp;
break;
case OPT_PASS:
s_dcert_file = opt_arg();
break;
case OPT_DKEYFORM:
- if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format))
+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &s_dkey_format))
goto opthelp;
break;
case OPT_DPASS:
if (!opt_rand(o))
goto end;
break;
+ case OPT_PROV_CASES:
+ if (!opt_provider(o))
+ goto end;
+ break;
case OPT_SERVERNAME:
tlsextcbp.servername = opt_arg();
break;
case OPT_HTTP_SERVER_BINMODE:
http_server_binmode = 1;
break;
+ case OPT_NOCANAMES:
+ no_ca_names = 1;
+ break;
+ case OPT_SENDFILE:
+#ifndef OPENSSL_NO_KTLS
+ use_sendfile = 1;
+#endif
+ break;
}
}
argc = opt_num_rest();
}
#endif
+#ifndef OPENSSL_NO_KTLS
+ if (use_sendfile && www <= 1) {
+ BIO_printf(bio_err, "Can't use -sendfile without -WWW or -HTTP\n");
+ goto end;
+ }
+#endif
+
if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
if (nocert == 0) {
s_key = load_key(s_key_file, s_key_format, 0, pass, engine,
"server certificate private key file");
- if (s_key == NULL) {
- ERR_print_errors(bio_err);
+ if (s_key == NULL)
goto end;
- }
s_cert = load_cert(s_cert_file, s_cert_format,
"server certificate file");
- if (s_cert == NULL) {
- ERR_print_errors(bio_err);
+ if (s_cert == NULL)
goto end;
- }
if (s_chain_file != NULL) {
if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL,
"server certificate chain"))
if (tlsextcbp.servername != NULL) {
s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine,
"second server certificate private key file");
- if (s_key2 == NULL) {
- ERR_print_errors(bio_err);
+ if (s_key2 == NULL)
goto end;
- }
s_cert2 = load_cert(s_cert_file2, s_cert_format,
"second server certificate file");
- if (s_cert2 == NULL) {
- ERR_print_errors(bio_err);
+ if (s_cert2 == NULL)
goto end;
- }
}
}
#if !defined(OPENSSL_NO_NEXTPROTONEG)
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");
s_dkey = load_key(s_dkey_file, s_dkey_format,
0, dpass, engine, "second certificate private key file");
- if (s_dkey == NULL) {
- ERR_print_errors(bio_err);
+ if (s_dkey == NULL)
goto end;
- }
s_dcert = load_cert(s_dcert_file, s_dcert_format,
"second server certificate file");
}
BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
}
- SSL_CTX_set_quiet_shutdown(ctx, 1);
if (exc != NULL)
ssl_ctx_set_excert(ctx, exc);
SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC);
}
+ if (no_ca_names) {
+ SSL_CTX_set_options(ctx, SSL_OP_DISABLE_TLSEXT_CA_NAMES);
+ }
+
if (max_send_fragment > 0
&& !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) {
BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n",
BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
if (sdebug)
- ssl_ctx_security_debug(ctx, sdebug);
+ ssl_ctx_security_debug(ctx2, sdebug);
if (session_id_prefix) {
if (strlen(session_id_prefix) >= 32)
}
BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
}
- SSL_CTX_set_quiet_shutdown(ctx2, 1);
if (exc != NULL)
ssl_ctx_set_excert(ctx2, exc);
SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
}
- if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
- BIO_printf(bio_err, "error setting PSK identity hint to context\n");
- ERR_print_errors(bio_err);
- goto end;
+ if (psk_identity_hint != NULL) {
+ if (min_version == TLS1_3_VERSION) {
+ BIO_printf(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n");
+ } else {
+ if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
+ BIO_printf(bio_err, "error setting PSK identity hint to context\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
}
#endif
if (psksessf != NULL) {
err:
if (con != NULL) {
BIO_printf(bio_s_out, "shutting down SSL\n");
- SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+ do_ssl_shutdown(con);
SSL_free(con);
}
BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
}
/* send the file */
- for (;;) {
- i = BIO_read(file, buf, bufsize);
- if (i <= 0)
- break;
+#ifndef OPENSSL_NO_KTLS
+ if (use_sendfile) {
+ FILE *fp = NULL;
+ int fd;
+ struct stat st;
+ off_t offset = 0;
+ size_t filesize;
+
+ BIO_get_fp(file, &fp);
+ fd = fileno(fp);
+ if (fstat(fd, &st) < 0) {
+ BIO_printf(io, "Error fstat '%s'\r\n", p);
+ ERR_print_errors(io);
+ goto write_error;
+ }
-#ifdef RENEG
- total_bytes += i;
- BIO_printf(bio_err, "%d\n", i);
- if (total_bytes > 3 * 1024) {
- total_bytes = 0;
- BIO_printf(bio_err, "RENEGOTIATE\n");
- SSL_renegotiate(con);
+ filesize = st.st_size;
+ if (((int)BIO_flush(io)) < 0)
+ goto write_error;
+
+ for (;;) {
+ i = SSL_sendfile(con, fd, offset, filesize, 0);
+ if (i < 0) {
+ BIO_printf(io, "Error SSL_sendfile '%s'\r\n", p);
+ ERR_print_errors(io);
+ break;
+ } else {
+ offset += i;
+ filesize -= i;
+ }
+
+ if (filesize <= 0) {
+ if (!s_quiet)
+ BIO_printf(bio_err, "KTLS SENDFILE '%s' OK\n", p);
+
+ break;
+ }
}
+ } else
#endif
+ {
+ for (;;) {
+ i = BIO_read(file, buf, bufsize);
+ if (i <= 0)
+ break;
- for (j = 0; j < i;) {
#ifdef RENEG
- static count = 0;
- if (++count == 13) {
+ total_bytes += i;
+ BIO_printf(bio_err, "%d\n", i);
+ if (total_bytes > 3 * 1024) {
+ total_bytes = 0;
+ BIO_printf(bio_err, "RENEGOTIATE\n");
SSL_renegotiate(con);
}
#endif
- k = BIO_write(io, &(buf[j]), i - j);
- if (k <= 0) {
- if (!BIO_should_retry(io)
- && !SSL_waiting_for_async(con))
- goto write_error;
- else {
- BIO_printf(bio_s_out, "rwrite W BLOCK\n");
+
+ for (j = 0; j < i;) {
+#ifdef RENEG
+ static count = 0;
+ if (++count == 13)
+ SSL_renegotiate(con);
+#endif
+ k = BIO_write(io, &(buf[j]), i - j);
+ if (k <= 0) {
+ if (!BIO_should_retry(io)
+ && !SSL_waiting_for_async(con)) {
+ goto write_error;
+ } else {
+ BIO_printf(bio_s_out, "rwrite W BLOCK\n");
+ }
+ } else {
+ j += k;
}
- } else {
- j += k;
}
}
}
}
end:
/* make sure we re-use sessions */
- SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+ do_ssl_shutdown(con);
err:
OPENSSL_free(buf);
}
end:
/* make sure we re-use sessions */
- SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+ do_ssl_shutdown(con);
err: