/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <openssl/async.h>
+#if defined(_WIN32)
+/* Included before async.h to avoid some warnings */
+# include <windows.h>
+#endif
#include <openssl/e_os2.h>
+#include <openssl/async.h>
+#include <openssl/ssl.h>
#ifndef OPENSSL_NO_SOCK
static DH *load_dh_param(const char *dhfile);
#endif
-static void s_server_init(void);
-
-/* static int load_CA(SSL_CTX *ctx, char *file);*/
-
-#undef BUFSIZZ
-#define BUFSIZZ 16*1024
-static int bufsize = BUFSIZZ;
+static const int bufsize = 16 * 1024;
static int accept_socket = -1;
#define TEST_CERT "server.pem"
#define TEST_CERT2 "server2.pem"
-extern int verify_depth, verify_return_error, verify_quiet;
-
-static int s_server_verify = SSL_VERIFY_NONE;
-static int s_server_session_id_context = 1; /* anything will do */
-static const char *s_cert_file = TEST_CERT, *s_key_file =
- NULL, *s_chain_file = NULL;
-
-static const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL;
-static char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL;
static int s_nbio = 0;
static int s_nbio_test = 0;
static int s_crlf = 0;
static BIO *bio_s_msg = NULL;
static int s_debug = 0;
static int s_tlsextdebug = 0;
-static int s_tlsextstatus = 0;
-static int no_resume_ephemeral = 0;
static int s_msg = 0;
static int s_quiet = 0;
static int s_ign_eof = 0;
static int keymatexportlen = 20;
static int async = 0;
-static unsigned int split_send_fragment = 0;
-static unsigned int max_pipelines = 0;
static const char *session_id_prefix = NULL;
#ifndef OPENSSL_NO_DTLS
static int enable_timeouts = 0;
static long socket_mtu;
-
#endif
-static int dtlslisten = 0;
-static const char *s_serverinfo_file = NULL;
+/*
+ * We define this but make it always be 0 in no-dtls builds to simplify the
+ * code.
+ */
+static int dtlslisten = 0;
#ifndef OPENSSL_NO_PSK
-static char *psk_identity = "Client_identity";
+static const char psk_identity[] = "Client_identity";
char *psk_key = NULL; /* by default PSK is not used */
static unsigned int psk_server_cb(SSL *ssl, const char *identity,
p->login, p->user->info);
ret = SSL_ERROR_NONE;
-err:
+ err:
SRP_user_pwd_free(p->user);
p->user = NULL;
p->login = NULL;
#endif
-static void s_server_init(void)
-{
- accept_socket = -1;
- verify_depth = 0;
- s_server_verify = SSL_VERIFY_NONE;
- s_dcert_file = NULL;
- s_dkey_file = NULL;
- s_dchain_file = NULL;
- s_cert_file = TEST_CERT;
- s_key_file = NULL;
- s_chain_file = NULL;
- s_cert_file2 = TEST_CERT2;
- s_key_file2 = NULL;
- ctx2 = NULL;
- s_nbio = 0;
- s_nbio_test = 0;
- ctx = NULL;
- www = 0;
- bio_s_out = NULL;
- s_debug = 0;
- s_msg = 0;
- s_quiet = 0;
- s_brief = 0;
- async = 0;
- split_send_fragment = 0;
- max_pipelines = 0;
-}
-
static int local_argc = 0;
static char **local_argv;
{
if (methods_ebcdic == NULL) {
methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER,
- "EBCDIC/ASCII filter");
- if ( methods_ebcdic == NULL
+ "EBCDIC/ASCII filter");
+ if (methods_ebcdic == NULL
|| !BIO_meth_set_write(methods_ebcdic, ebcdic_write)
|| !BIO_meth_set_read(methods_ebcdic, ebcdic_read)
|| !BIO_meth_set_puts(methods_ebcdic, ebcdic_puts)
}
/* Structure passed to cert status callback */
-
typedef struct tlsextstatusctx_st {
/* Default responder to use */
char *host, *path, *port;
/* This is the context that we pass to next_proto_cb */
typedef struct tlsextnextprotoctx_st {
unsigned char *data;
- unsigned int len;
+ size_t len;
} tlsextnextprotoctx;
static int next_proto_cb(SSL *s, const unsigned char **data,
{"port", OPT_PORT, 'p',
"TCP/IP port to listen on for connections (default is " PORT ")"},
{"accept", OPT_ACCEPT, 's',
- "TCP/IP optional host and port to accept on (default is " PORT ")"},
+ "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"},
#ifdef AF_UNIX
{"unix", OPT_UNIX, 's', "Unix domain socket to accept on"},
#endif
"PEM serverinfo file for certificate"},
{"certform", OPT_CERTFORM, 'F',
"Certificate format (PEM or DER) PEM default"},
- {"key", OPT_KEY, '<',
+ {"key", OPT_KEY, 's',
"Private Key if not in -cert; default is " TEST_CERT},
{"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"},
{"dcertform", OPT_DCERTFORM, 'F',
"Second certificate format (PEM or DER) PEM default"},
{"dkey", OPT_DKEY, '<',
{"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" },
+ {"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, '-',
"Print output from SSL/TLS security framework"},
{"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-',
"Print more output from SSL/TLS security framework"},
- {"brief", OPT_BRIEF, '-', \
+ {"brief", OPT_BRIEF, '-',
"Restrict output to brief summary of connection parameters"},
{"rev", OPT_REV, '-',
"act as a simple test server which just sends back with the received text reversed"},
{"async", OPT_ASYNC, '-', "Operate in asynchronous mode"},
- {"ssl_config", OPT_SSL_CONFIG, 's', \
+ {"ssl_config", OPT_SSL_CONFIG, 's',
"Configure SSL_CTX using the configuration 'val'"},
{"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n',
"Size used to split data for encrypt pipelines"},
STACK_OF(X509_CRL) *crls = NULL;
X509 *s_cert = NULL, *s_dcert = NULL;
X509_VERIFY_PARAM *vpm = NULL;
- char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL;
-#ifndef OPENSSL_NO_DH
- char *dhfile = NULL;
-#endif
+ const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL;
char *dpassarg = NULL, *dpass = NULL, *inrand = NULL;
char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
char *crl_file = NULL, *prog;
-#ifndef OPENSSL_NO_PSK
- char *p;
-#endif
#ifdef AF_UNIX
int unlink_unix_path = 0;
#endif
do_server_cb server_cb;
int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0;
#ifndef OPENSSL_NO_DH
+ char *dhfile = NULL;
int no_dhe = 0;
#endif
int nocert = 0, ret = 1;
tlsextalpnctx alpn_ctx = { NULL, 0 };
#ifndef OPENSSL_NO_PSK
/* by default do not send a PSK identity hint */
- static char *psk_identity_hint = NULL;
+ char *psk_identity_hint = NULL;
+ char *p;
#endif
#ifndef OPENSSL_NO_SRP
char *srpuserseed = NULL;
char *srp_verifier_file = NULL;
#endif
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
+ int s_server_verify = SSL_VERIFY_NONE;
+ int s_server_session_id_context = 1; /* anything will do */
+ const char *s_cert_file = TEST_CERT, *s_key_file = NULL, *s_chain_file = NULL;
+ const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL;
+ char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL;
+#ifndef OPENSSL_NO_OCSP
+ int s_tlsextstatus = 0;
+#endif
+ int no_resume_ephemeral = 0;
+ unsigned int split_send_fragment = 0, max_pipelines = 0;
+ const char *s_serverinfo_file = NULL;
+ /* Init of few remaining global variables */
local_argc = argc;
local_argv = argv;
- s_server_init();
+ ctx = ctx2 = NULL;
+ s_nbio = s_nbio_test = 0;
+ www = 0;
+ bio_s_out = NULL;
+ s_debug = 0;
+ s_msg = 0;
+ s_quiet = 0;
+ s_brief = 0;
+ async = 0;
+
cctx = SSL_CONF_CTX_new();
vpm = X509_VERIFY_PARAM_new();
if (cctx == NULL || vpm == NULL)
goto end;
- SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE);
+ SSL_CONF_CTX_set_flags(cctx,
+ SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE);
prog = opt_init(argc, argv, s_server_options);
while ((o = opt_next()) != OPT_EOF) {
if (IS_NO_PROT_FLAG(o))
no_prot_opt++;
if (prot_opt == 1 && no_prot_opt) {
- BIO_printf(bio_err, "Cannot supply both a protocol flag and "
- "\"-no_<prot>\"\n");
+ BIO_printf(bio_err,
+ "Cannot supply both a protocol flag and '-no_<prot>'\n");
goto end;
}
switch (o) {
break;
case OPT_VERIFY:
s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
- verify_depth = atoi(opt_arg());
+ verify_args.depth = atoi(opt_arg());
if (!s_quiet)
- BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
+ BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth);
break;
case OPT_UPPER_V_VERIFY:
s_server_verify =
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
SSL_VERIFY_CLIENT_ONCE;
- verify_depth = atoi(opt_arg());
+ verify_args.depth = atoi(opt_arg());
if (!s_quiet)
BIO_printf(bio_err,
"verify depth is %d, must return a certificate\n",
- verify_depth);
+ verify_args.depth);
break;
case OPT_CONTEXT:
context = (unsigned char *)opt_arg();
goto end;
break;
case OPT_VERIFY_RET_ERROR:
- verify_return_error = 1;
+ verify_args.return_error = 1;
break;
case OPT_VERIFY_QUIET:
- verify_quiet = 1;
+ verify_args.quiet = 1;
break;
case OPT_BUILD_CHAIN:
build_chain = 1;
s_tlsextdebug = 1;
break;
case OPT_STATUS:
+#ifndef OPENSSL_NO_OCSP
s_tlsextstatus = 1;
+#endif
break;
case OPT_STATUS_VERBOSE:
+#ifndef OPENSSL_NO_OCSP
s_tlsextstatus = tlscstatp.verbose = 1;
+#endif
break;
case OPT_STATUS_TIMEOUT:
+#ifndef OPENSSL_NO_OCSP
s_tlsextstatus = 1;
tlscstatp.timeout = atoi(opt_arg());
+#endif
break;
case OPT_STATUS_URL:
#ifndef OPENSSL_NO_OCSP
s_quiet = 1;
break;
case OPT_BRIEF:
- s_quiet = s_brief = verify_quiet = 1;
+ s_quiet = s_brief = verify_args.quiet = 1;
break;
case OPT_NO_DHE:
#ifndef OPENSSL_NO_DH
}
#if !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto_neg_in) {
- size_t len;
- next_proto.data = next_protos_parse(&len, next_proto_neg_in);
+ next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
if (next_proto.data == NULL)
goto end;
- next_proto.len = len;
- } else {
- next_proto.data = NULL;
}
#endif
alpn_ctx.data = NULL;
if (alpn_in) {
- size_t len;
- alpn_ctx.data = next_protos_parse(&len, alpn_in);
+ alpn_ctx.data = next_protos_parse(&alpn_ctx.len, alpn_in);
if (alpn_ctx.data == NULL)
goto end;
- alpn_ctx.len = len;
}
if (crl_file) {
}
if (sdebug)
ssl_ctx_security_debug(ctx, sdebug);
+
+ if (!config_ctx(cctx, ssl_args, ctx))
+ goto end;
+
if (ssl_config) {
if (SSL_CTX_config(ctx, ssl_config) == 0) {
BIO_printf(bio_err, "Error using configuration \"%s\"\n",
ssl_config);
- ERR_print_errors(bio_err);
- goto end;
+ ERR_print_errors(bio_err);
+ goto end;
}
}
- if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+ if (min_version != 0
+ && SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;
- if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+ if (max_version != 0
+ && SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
goto end;
if (session_id_prefix) {
if (read_buf_len > 0) {
SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len);
}
-
#ifndef OPENSSL_NO_SRTP
if (srtp_profiles != NULL) {
/* Returns 0 on success! */
}
ssl_ctx_add_crls(ctx, crls, 0);
- if (!config_ctx(cctx, ssl_args, ctx))
- goto end;
if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
crls, crl_download)) {
#ifndef OPENSSL_NO_PSK
if (psk_key != NULL) {
if (s_debug)
- BIO_printf(bio_s_out,
- "PSK key given, setting server callback\n");
+ BIO_printf(bio_s_out, "PSK key given, setting server callback\n");
SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
}
SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
if (!SSL_CTX_set_session_id_context(ctx,
- (void *)&s_server_session_id_context,
- sizeof s_server_session_id_context)) {
+ (void *)&s_server_session_id_context,
+ sizeof(s_server_session_id_context))) {
BIO_printf(bio_err, "error setting session id context\n");
ERR_print_errors(bio_err);
goto end;
SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
if (!SSL_CTX_set_session_id_context(ctx2,
(void *)&s_server_session_id_context,
- sizeof s_server_session_id_context)) {
+ sizeof(s_server_session_id_context))) {
BIO_printf(bio_err, "error setting session id context\n");
ERR_print_errors(bio_err);
goto end;
ssl_excert_free(exc);
sk_OPENSSL_STRING_free(ssl_args);
SSL_CONF_CTX_free(cctx);
+ release_engine(engine);
BIO_free(bio_s_out);
bio_s_out = NULL;
BIO_free(bio_s_msg);
SSL *con = NULL;
BIO *sbio;
struct timeval timeout;
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
- struct timeval tv;
-#else
+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS))
struct timeval *timeoutp;
#endif
}
if (context
- && !SSL_set_session_id_context(con,
- context, strlen((char *)context))) {
+ && !SSL_set_session_id_context(con,
+ context, strlen((char *)context))) {
BIO_printf(bio_err, "Error setting session id context\n");
ret = -1;
goto err;
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
- width = s + 1;
+ if (fileno_stdin() > s)
+ width = fileno_stdin() + 1;
+ else
+ width = s + 1;
for (;;) {
int read_from_terminal;
int read_from_sslcon;
if (!read_from_sslcon) {
FD_ZERO(&readfds);
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
- openssl_fdset(fileno(stdin), &readfds);
+ openssl_fdset(fileno_stdin(), &readfds);
#endif
openssl_fdset(s, &readfds);
/*
* second and check for any keypress. In a proper Windows
* application we wouldn't do this because it is inefficient.
*/
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- i = select(width, (void *)&readfds, NULL, NULL, &tv);
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ i = select(width, (void *)&readfds, NULL, NULL, &timeout);
if (has_stdin_waiting())
read_from_terminal = 1;
if ((i < 0) || (!i && !read_from_terminal))
continue;
#else
- if ((SSL_version(con) == DTLS1_VERSION) &&
- DTLSv1_get_timeout(con, &timeout))
+ if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout))
timeoutp = &timeout;
else
timeoutp = NULL;
i = select(width, (void *)&readfds, NULL, NULL, timeoutp);
- if ((SSL_version(con) == DTLS1_VERSION)
- && DTLSv1_handle_timeout(con) > 0) {
+ if ((SSL_is_dtls(con)) && DTLSv1_handle_timeout(con) > 0)
BIO_printf(bio_err, "TIMEOUT occurred\n");
- }
if (i <= 0)
continue;
- if (FD_ISSET(fileno(stdin), &readfds))
+ if (FD_ISSET(fileno_stdin(), &readfds))
read_from_terminal = 1;
#endif
if (FD_ISSET(s, &readfds))
assert(lf_num == 0);
} else
i = raw_read_stdin(buf, bufsize);
+
if (!s_quiet && !s_brief) {
if ((i <= 0) || (buf[0] == 'Q')) {
BIO_printf(bio_s_out, "DONE\n");
for (;;) {
/* should do a select for the write */
#ifdef RENEG
- {
- static count = 0;
- if (++count == 100) {
- count = 0;
- SSL_renegotiate(con);
- }
+ static count = 0;
+ if (++count == 100) {
+ count = 0;
+ SSL_renegotiate(con);
}
#endif
k = SSL_write(con, &(buf[l]), (unsigned int)i);
retry = BIO_sock_should_retry(i);
#ifdef CERT_CB_TEST_RETRY
{
- while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
+ while (i <= 0
+ && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
&& SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
BIO_printf(bio_err,
- "LOOKUP from certificate callback during accept\n");
+ "LOOKUP from certificate callback during accept\n");
i = SSL_accept(con);
if (i <= 0)
retry = BIO_sock_should_retry(i);
#endif
#ifndef OPENSSL_NO_SRP
- while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
+ while (i <= 0
+ && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
srp_callback_parm.login);
SRP_user_pwd_free(srp_callback_parm.user);
if (peer != NULL) {
BIO_printf(bio_s_out, "Client certificate\n");
PEM_write_bio_X509(bio_s_out, peer);
- X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
+ X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf));
BIO_printf(bio_s_out, "subject=%s\n", buf);
- X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
+ X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf));
BIO_printf(bio_s_out, "issuer=%s\n", buf);
X509_free(peer);
peer = NULL;
}
- if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
+ if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL)
BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
ssl_print_sigalgs(bio_s_out, con);
BIO_printf(bio_s_out, "Reused session-id\n");
BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
+ if ((SSL_get_options(con) & SSL_OP_NO_RENEGOTIATION))
+ BIO_printf(bio_s_out, "Renegotiation is DISABLED\n");
+
if (keymatexportlabel != NULL) {
BIO_printf(bio_s_out, "Keying material exporter:\n");
BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel);
OPENSSL_free(exportedkeymat);
}
- (void)BIO_flush(bio_s_out);
+ (void)BIO_flush(bio_s_out);
return (1);
}
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
- if (context && !SSL_set_session_id_context(con, context,
- strlen((char *)context)))
+ if (context
+ && !SSL_set_session_id_context(con, context,
+ strlen((char *)context))) {
+ SSL_free(con);
goto err;
+ }
sbio = BIO_new_socket(s, BIO_NOCLOSE);
if (s_nbio_test) {
SSL_set_bio(con, sbio, sbio);
SSL_set_accept_state(con);
- /* SSL_set_fd(con,s); */
+ /* No need to free |con| after this. Done by BIO_free(ssl_bio) */
BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
BIO_push(io, ssl_bio);
#ifdef CHARSET_EBCDIC
openssl_fdset(s, &readfds);
i = select(width, (void *)&readfds, NULL, NULL, NULL);
if (i <= 0 || !FD_ISSET(s, &readfds)) {
- BIO_printf(bio_s_out, "Error waiting for client response\n");
+ BIO_printf(bio_s_out,
+ "Error waiting for client response\n");
ERR_print_errors(bio_err);
goto err;
}
PEM_write_bio_X509(io, peer);
X509_free(peer);
peer = NULL;
- } else
+ } else {
BIO_puts(io, "no client certificate available\n");
- BIO_puts(io, "</BODY></HTML>\r\n\r\n");
+ }
+ BIO_puts(io, "</pre></BODY></HTML>\r\n\r\n");
break;
} else if ((www == 2 || www == 3)
&& (strncmp("GET /", buf, 5) == 0)) {
for (j = 0; j < i;) {
#ifdef RENEG
- {
- static count = 0;
- if (++count == 13) {
- SSL_renegotiate(con);
- }
+ 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))
+ if (!BIO_should_retry(io)
+ && !SSL_waiting_for_async(con))
goto write_error;
else {
BIO_printf(bio_s_out, "rwrite W BLOCK\n");
SSL_set_tlsext_debug_callback(con, tlsext_cb);
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
- if (context && !SSL_set_session_id_context(con, context,
- strlen((char *)context))) {
+ if (context
+ && !SSL_set_session_id_context(con, context,
+ strlen((char *)context))) {
+ SSL_free(con);
ERR_print_errors(bio_err);
goto err;
}
SSL_set_bio(con, sbio, sbio);
SSL_set_accept_state(con);
+ /* No need to free |con| after this. Done by BIO_free(ssl_bio) */
BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
BIO_push(io, ssl_bio);
#ifdef CHARSET_EBCDIC
first = NULL;
}
-#endif /* OPENSSL_NO_SOCK */
+#endif /* OPENSSL_NO_SOCK */