#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
#include "s_apps.h"
+#include "timeouts.h"
#ifdef OPENSSL_SYS_WINCE
/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
static int generate_session_id(const SSL *ssl, unsigned char *id,
unsigned int *id_len);
#ifndef OPENSSL_NO_DH
-static DH *load_dh_param(char *dhfile);
+static DH *load_dh_param(const char *dhfile);
static DH *get_dh512(void);
#endif
static int accept_socket= -1;
#define TEST_CERT "server.pem"
+#ifndef OPENSSL_NO_TLSEXT
+#define TEST_CERT2 "server2.pem"
+#endif
#undef PROG
#define PROG s_server_main
static char *cipher=NULL;
static int s_server_verify=SSL_VERIFY_NONE;
static int s_server_session_id_context = 1; /* anything will do */
-static char *s_cert_file=TEST_CERT,*s_key_file=NULL;
+static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL;
+#endif
static char *s_dcert_file=NULL,*s_dkey_file=NULL;
#ifdef FIONBIO
static int s_nbio=0;
static int s_nbio_test=0;
int s_crlf=0;
static SSL_CTX *ctx=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+static SSL_CTX *ctx2=NULL;
+#endif
static int www=0;
static BIO *bio_s_out=NULL;
static int s_debug=0;
+#ifndef OPENSSL_NO_TLSEXT
+static int s_tlsextdebug=0;
+static int s_tlsextstatus=0;
+static int cert_status_cb(SSL *s, void *arg);
+#endif
static int s_msg=0;
static int s_quiet=0;
#endif
static const char *session_id_prefix=NULL;
+static int enable_timeouts = 0;
+#ifdef mtu
+#undef mtu
+#endif
+static long mtu;
+static int cert_chain = 0;
+
+
#ifdef MONOLITH
static void s_server_init(void)
{
s_dkey_file=NULL;
s_cert_file=TEST_CERT;
s_key_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ s_cert_file2=TEST_CERT2;
+ s_key_file2=NULL;
+ ctx2=NULL;
+#endif
#ifdef FIONBIO
s_nbio=0;
#endif
BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
+ BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n");
+ BIO_printf(bio_err," -timeout - Enable timeouts\n");
+ BIO_printf(bio_err," -mtu - Set MTU\n");
+ BIO_printf(bio_err," -chain - Read a certificate chain\n");
BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n");
BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
#endif
BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+#ifndef OPENSSL_NO_TLSEXT
+ BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
+ BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
+ BIO_printf(bio_err," -cert2 arg - certificate file to use for servername\n");
+ BIO_printf(bio_err," (default is %s)\n",TEST_CERT2);
+ BIO_printf(bio_err," -key2 arg - Private Key file to use for servername, in cert file if\n");
+ BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT2);
+ BIO_printf(bio_err," -tlsextdebug - hex dump of all TLS extensions received\n");
+ BIO_printf(bio_err," -no_ticket - disable use of RFC4507bis session tickets\n");
+#endif
}
static int local_argc=0;
}
#endif
+#ifndef OPENSSL_NO_TLSEXT
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+ char * servername;
+ BIO * biodebug;
+ int extension_error;
+} tlsextctx;
+
+
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+ {
+ tlsextctx * p = (tlsextctx *) arg;
+ const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+ if (servername && p->biodebug)
+ BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
+
+ if (!p->servername)
+ return SSL_TLSEXT_ERR_NOACK;
+
+ if (servername)
+ {
+ if (strcmp(servername,p->servername))
+ return p->extension_error;
+ if (ctx2)
+ {
+ BIO_printf(p->biodebug,"Swiching server context.\n");
+ SSL_set_SSL_CTX(s,ctx2);
+ }
+ }
+ return SSL_TLSEXT_ERR_OK;
+}
+
+/* Structure passed to cert status callback */
+
+typedef struct tlsextstatusctx_st {
+ /* Default responder to use */
+ char *host, *path, *port;
+ int use_ssl;
+ int timeout;
+ BIO *err;
+ int verbose;
+} tlsextstatusctx;
+
+static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0};
+
+/* Certificate Status callback. This is called when a client includes a
+ * certificate status request extension.
+ *
+ * This is a simplified version. It examines certificates each time and
+ * makes one OCSP responder query for each request.
+ *
+ * A full version would store details such as the OCSP certificate IDs and
+ * minimise the number of OCSP responses by caching them until they were
+ * considered "expired".
+ */
+
+static int cert_status_cb(SSL *s, void *arg)
+ {
+ tlsextstatusctx *srctx = arg;
+ BIO *err = srctx->err;
+ char *host, *port, *path;
+ int use_ssl;
+ unsigned char *rspder = NULL;
+ int rspderlen;
+ STACK *aia = NULL;
+ X509 *x = NULL;
+ X509_STORE_CTX inctx;
+ X509_OBJECT obj;
+ OCSP_REQUEST *req = NULL;
+ OCSP_RESPONSE *resp = NULL;
+ OCSP_CERTID *id = NULL;
+ STACK_OF(X509_EXTENSION) *exts;
+ int ret = SSL_TLSEXT_ERR_NOACK;
+ int i;
+#if 0
+STACK_OF(OCSP_RESPID) *ids;
+SSL_get_tlsext_status_ids(s, &ids);
+BIO_printf(err, "cert_status: received %d ids\n", sk_OCSP_RESPID_num(ids));
+#endif
+ if (srctx->verbose)
+ BIO_puts(err, "cert_status: callback called\n");
+ /* Build up OCSP query from server certificate */
+ x = SSL_get_certificate(s);
+ aia = X509_get1_ocsp(x);
+ if (aia)
+ {
+ if (!OCSP_parse_url(sk_value(aia, 0),
+ &host, &port, &path, &use_ssl))
+ {
+ BIO_puts(err, "cert_status: can't parse AIA URL\n");
+ goto err;
+ }
+ if (srctx->verbose)
+ BIO_printf(err, "cert_status: AIA URL: %s\n",
+ sk_value(aia, 0));
+ }
+ else
+ {
+ if (!srctx->host)
+ {
+ BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
+ goto done;
+ }
+ host = srctx->host;
+ path = srctx->path;
+ port = srctx->port;
+ use_ssl = srctx->use_ssl;
+ }
+
+ if (!X509_STORE_CTX_init(&inctx,
+ SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
+ NULL, NULL))
+ goto err;
+ if (X509_STORE_get_by_subject(&inctx,X509_LU_X509,
+ X509_get_issuer_name(x),&obj) <= 0)
+ {
+ BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
+ X509_STORE_CTX_cleanup(&inctx);
+ goto done;
+ }
+ req = OCSP_REQUEST_new();
+ if (!req)
+ goto err;
+ id = OCSP_cert_to_id(NULL, x, obj.data.x509);
+ X509_free(obj.data.x509);
+ X509_STORE_CTX_cleanup(&inctx);
+ if (!id)
+ goto err;
+ if (!OCSP_request_add0_id(req, id))
+ goto err;
+ id = NULL;
+ /* Add any extensions to the request */
+ SSL_get_tlsext_status_exts(s, &exts);
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++)
+ {
+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+ if (!OCSP_REQUEST_add_ext(req, ext, -1))
+ goto err;
+ }
+ resp = process_responder(err, req, host, path, port, use_ssl,
+ srctx->timeout);
+ if (!resp)
+ {
+ BIO_puts(err, "cert_status: error querying responder\n");
+ goto done;
+ }
+ rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
+ if (rspderlen <= 0)
+ goto err;
+ SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
+ if (srctx->verbose)
+ {
+ BIO_puts(err, "cert_status: ocsp response sent:\n");
+ OCSP_RESPONSE_print(err, resp, 2);
+ }
+ ret = SSL_TLSEXT_ERR_OK;
+ done:
+ if (ret != SSL_TLSEXT_ERR_OK)
+ ERR_print_errors(err);
+ if (aia)
+ {
+ OPENSSL_free(host);
+ OPENSSL_free(path);
+ OPENSSL_free(port);
+ X509_email_free(aia);
+ }
+ if (id)
+ OCSP_CERTID_free(id);
+ if (req)
+ OCSP_REQUEST_free(req);
+ if (resp)
+ OCSP_RESPONSE_free(resp);
+ return ret;
+ err:
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ goto done;
+ }
+#endif
int MAIN(int, char **);
int MAIN(int argc, char *argv[])
int vflags = 0;
short port=PORT;
char *CApath=NULL,*CAfile=NULL;
- char *context = NULL;
+ unsigned char *context = NULL;
char *dhfile = NULL;
+#ifndef OPENSSL_NO_ECDH
char *named_curve = NULL;
+#endif
int badop=0,bugs=0;
int ret=1;
int off=0;
int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
int state=0;
SSL_METHOD *meth=NULL;
+ int socket_type=SOCK_STREAM;
#ifndef OPENSSL_NO_ENGINE
ENGINE *e=NULL;
#endif
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
X509 *s_cert = NULL, *s_dcert = NULL;
EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ EVP_PKEY *s_key2 = NULL;
+ X509 *s_cert2 = NULL;
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+ tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
+#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_server_method();
else if (strcmp(*argv,"-context") == 0)
{
if (--argc < 1) goto bad;
- context= *(++argv);
+ context= (unsigned char *)*(++argv);
}
else if (strcmp(*argv,"-cert") == 0)
{
}
else if (strcmp(*argv,"-debug") == 0)
{ s_debug=1; }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-tlsextdebug") == 0)
+ s_tlsextdebug=1;
+ else if (strcmp(*argv,"-status") == 0)
+ s_tlsextstatus=1;
+ else if (strcmp(*argv,"-status_verbose") == 0)
+ {
+ s_tlsextstatus=1;
+ tlscstatp.verbose = 1;
+ }
+ else if (!strcmp(*argv, "-status_timeout"))
+ {
+ s_tlsextstatus=1;
+ if (--argc < 1) goto bad;
+ tlscstatp.timeout = atoi(*(++argv));
+ }
+ else if (!strcmp(*argv, "-status_url"))
+ {
+ s_tlsextstatus=1;
+ if (--argc < 1) goto bad;
+ if (!OCSP_parse_url(*(++argv),
+ &tlscstatp.host,
+ &tlscstatp.port,
+ &tlscstatp.path,
+ &tlscstatp.use_ssl))
+ {
+ BIO_printf(bio_err, "Error parsing URL\n");
+ goto bad;
+ }
+ }
+#endif
else if (strcmp(*argv,"-msg") == 0)
{ s_msg=1; }
else if (strcmp(*argv,"-hack") == 0)
{ off|=SSL_OP_NO_SSLv3; }
else if (strcmp(*argv,"-no_tls1") == 0)
{ off|=SSL_OP_NO_TLSv1; }
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-no_ticket") == 0)
+ { off|=SSL_OP_NO_TICKET; }
+#endif
#ifndef OPENSSL_NO_SSL2
else if (strcmp(*argv,"-ssl2") == 0)
{ meth=SSLv2_server_method(); }
#ifndef OPENSSL_NO_TLS1
else if (strcmp(*argv,"-tls1") == 0)
{ meth=TLSv1_server_method(); }
+#endif
+#ifndef OPENSSL_NO_DTLS1
+ else if (strcmp(*argv,"-dtls1") == 0)
+ {
+ meth=DTLSv1_server_method();
+ socket_type = SOCK_DGRAM;
+ }
+ else if (strcmp(*argv,"-timeout") == 0)
+ enable_timeouts = 1;
+ else if (strcmp(*argv,"-mtu") == 0)
+ {
+ if (--argc < 1) goto bad;
+ mtu = atol(*(++argv));
+ }
+ else if (strcmp(*argv, "-chain") == 0)
+ cert_chain = 1;
#endif
else if (strcmp(*argv, "-id_prefix") == 0)
{
if (--argc < 1) goto bad;
inrand= *(++argv);
}
+#ifndef OPENSSL_NO_TLSEXT
+ else if (strcmp(*argv,"-servername") == 0)
+ {
+ if (--argc < 1) goto bad;
+ tlsextcbp.servername= *(++argv);
+ }
+ else if (strcmp(*argv,"-servername_fatal") == 0)
+ { tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }
+ else if (strcmp(*argv,"-cert2") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_cert_file2= *(++argv);
+ }
+ else if (strcmp(*argv,"-key2") == 0)
+ {
+ if (--argc < 1) goto bad;
+ s_key_file2= *(++argv);
+ }
+#endif
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
if (s_key_file == NULL)
s_key_file = s_cert_file;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_key_file2 == NULL)
+ s_key_file2 = s_cert_file2;
+#endif
- s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
- "server certificate private key file");
- if (!s_key)
+ if (nocert == 0)
{
- ERR_print_errors(bio_err);
- goto end;
- }
+ s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
+ "server certificate private key file");
+ if (!s_key)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
- s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
+ s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
NULL, e, "server certificate file");
- if (!s_cert)
- {
- ERR_print_errors(bio_err);
- goto end;
- }
+ if (!s_cert)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#ifndef OPENSSL_NO_TLSEXT
+ if (tlsextcbp.servername)
+ {
+ s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
+ "second server certificate private key file");
+ if (!s_key2)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+
+ s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,
+ NULL, e, "second server certificate file");
+
+ if (!s_cert2)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+#endif
+ }
if (s_dcert_file)
{
s_key_file=NULL;
s_dcert_file=NULL;
s_dkey_file=NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ s_cert_file2=NULL;
+ s_key_file2=NULL;
+#endif
}
ctx=SSL_CTX_new(meth);
if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
SSL_CTX_set_options(ctx,off);
+ /* DTLS: partial reads end up discarding unread UDP bytes :-(
+ * Setting read ahead solves this problem.
+ */
+ if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
}
store = SSL_CTX_get_cert_store(ctx);
X509_STORE_set_flags(store, vflags);
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_cert2)
+ {
+ ctx2=SSL_CTX_new(meth);
+ if (ctx2 == NULL)
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+
+ if (ctx2)
+ {
+ BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
+
+ if (session_id_prefix)
+ {
+ if(strlen(session_id_prefix) >= 32)
+ BIO_printf(bio_err,
+ "warning: id_prefix is too long, only one new session will be possible\n");
+ else if(strlen(session_id_prefix) >= 16)
+ BIO_printf(bio_err,
+ "warning: id_prefix is too long if you use SSLv2\n");
+ if(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id))
+ {
+ BIO_printf(bio_err,"error setting 'id_prefix'\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+ }
+ SSL_CTX_set_quiet_shutdown(ctx2,1);
+ if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
+ if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+ SSL_CTX_set_options(ctx2,off);
+
+ /* DTLS: partial reads end up discarding unread UDP bytes :-(
+ * Setting read ahead solves this problem.
+ */
+ if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
+
+
+ if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
+
+ SSL_CTX_sess_set_cache_size(ctx2,128);
+
+ if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
+ (!SSL_CTX_set_default_verify_paths(ctx2)))
+ {
+ ERR_print_errors(bio_err);
+ }
+ store = SSL_CTX_get_cert_store(ctx2);
+ X509_STORE_set_flags(store, vflags);
+ }
+#endif
+
#ifndef OPENSSL_NO_DH
if (!no_dhe)
(void)BIO_flush(bio_s_out);
SSL_CTX_set_tmp_dh(ctx,dh);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ {
+ if (!dhfile)
+ {
+ DH *dh2=load_dh_param(s_cert_file2);
+ if (dh2 != NULL)
+ {
+ BIO_printf(bio_s_out,"Setting temp DH parameters\n");
+ (void)BIO_flush(bio_s_out);
+
+ DH_free(dh);
+ dh = dh2;
+ }
+ }
+ SSL_CTX_set_tmp_dh(ctx2,dh);
+ }
+#endif
DH_free(dh);
}
#endif
{
EC_KEY *ecdh=NULL;
- ecdh = EC_KEY_new();
- if (ecdh == NULL)
- {
- BIO_printf(bio_err,"Could not create ECDH struct.\n");
- goto end;
- }
-
if (named_curve)
{
int nid = OBJ_sn2nid(named_curve);
named_curve);
goto end;
}
-
- ecdh->group = EC_GROUP_new_by_nid(nid);
- if (ecdh->group == NULL)
+ ecdh = EC_KEY_new_by_curve_name(nid);
+ if (ecdh == NULL)
{
BIO_printf(bio_err, "unable to create curve (%s)\n",
named_curve);
}
}
- if (ecdh->group != NULL)
+ if (ecdh != NULL)
{
BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
}
else
{
BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
- ecdh->group=EC_GROUP_new_by_nid(NID_sect163r2);
- if (ecdh->group == NULL)
+ ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);
+ if (ecdh == NULL)
{
BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
goto end;
(void)BIO_flush(bio_s_out);
SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ SSL_CTX_set_tmp_ecdh(ctx2,ecdh);
+#endif
EC_KEY_free(ecdh);
}
#endif
if (!set_cert_key_stuff(ctx,s_cert,s_key))
goto end;
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2))
+ goto end;
+#endif
if (s_dcert != NULL)
{
if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
#ifndef OPENSSL_NO_RSA
#if 1
if (!no_tmp_rsa)
+ {
SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
+#endif
+ }
#else
if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
{
ERR_print_errors(bio_err);
goto end;
}
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ {
+ if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
+ {
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ }
+#endif
RSA_free(rsa);
BIO_printf(bio_s_out,"\n");
}
BIO_printf(bio_err,"error setting cipher list\n");
ERR_print_errors(bio_err);
goto end;
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
+ {
+ BIO_printf(bio_err,"error setting cipher list\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+#endif
}
SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
sizeof s_server_session_id_context);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ {
+ SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);
+ SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,
+ sizeof s_server_session_id_context);
+
+ tlsextcbp.biodebug = bio_s_out;
+ SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
+ SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+ }
+#endif
if (CAfile != NULL)
- SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
-
+ {
+ SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2)
+ SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
+#endif
+ }
BIO_printf(bio_s_out,"ACCEPT\n");
if (www)
- do_server(port,&accept_socket,www_body, context);
+ do_server(port,socket_type,&accept_socket,www_body, context);
else
- do_server(port,&accept_socket,sv_body, context);
+ do_server(port,socket_type,&accept_socket,sv_body, context);
print_stats(bio_s_out,ctx);
ret=0;
end:
OPENSSL_free(pass);
if (dpass)
OPENSSL_free(dpass);
+#ifndef OPENSSL_NO_TLSEXT
+ if (ctx2 != NULL) SSL_CTX_free(ctx2);
+ if (s_cert2)
+ X509_free(s_cert2);
+ if (s_key2)
+ EVP_PKEY_free(s_key2);
+#endif
if (bio_s_out != NULL)
{
- BIO_free(bio_s_out);
+ BIO_free(bio_s_out);
bio_s_out=NULL;
}
apps_shutdown();
if (con == NULL) {
con=SSL_new(ctx);
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_s_out);
+ }
+ if (s_tlsextstatus)
+ {
+ SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
+ tlscstatp.err = bio_err;
+ SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
+ }
+#endif
#ifndef OPENSSL_NO_KRB5
if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
{
}
SSL_clear(con);
- sbio=BIO_new_socket(s,BIO_NOCLOSE);
+ if (SSL_version(con) == DTLS1_VERSION)
+ {
+ struct timeval timeout;
+
+ sbio=BIO_new_dgram(s,BIO_NOCLOSE);
+
+ if ( enable_timeouts)
+ {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = DGRAM_SND_TIMEOUT;
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+ }
+
+
+ if ( mtu > 0)
+ {
+ SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+ SSL_set_mtu(con, mtu);
+ }
+ else
+ /* want to do MTU discovery */
+ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+
+ /* turn on cookie exchange */
+ SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
+ }
+ else
+ sbio=BIO_new_socket(s,BIO_NOCLOSE);
+
if (s_nbio_test)
{
BIO *test;
{
con->debug=1;
BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
- BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
+ BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
}
if (s_msg)
{
SSL_set_msg_callback(con, msg_cb);
SSL_set_msg_callback_arg(con, bio_s_out);
}
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_s_out);
+ }
+#endif
width=s+1;
for (;;)
if ((i <= 0) || (buf[0] == 'q'))
{
BIO_printf(bio_s_out,"DONE\n");
- SHUTDOWN(s);
+ if (SSL_version(con) != DTLS1_VERSION)
+ SHUTDOWN(s);
/* close_accept_socket();
ret= -11;*/
goto err;
}
if (buf[0] == 'P')
{
- static char *str="Lets print some clear text\n";
+ static const char *str="Lets print some clear text\n";
BIO_write(SSL_get_wbio(con),str,strlen(str));
}
if (buf[0] == 'S')
}
#ifndef OPENSSL_NO_DH
-static DH *load_dh_param(char *dhfile)
+static DH *load_dh_param(const char *dhfile)
{
DH *ret=NULL;
BIO *bio;
if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
if ((con=SSL_new(ctx)) == NULL) goto err;
+#ifndef OPENSSL_NO_TLSEXT
+ if (s_tlsextdebug)
+ {
+ SSL_set_tlsext_debug_callback(con, tlsext_cb);
+ SSL_set_tlsext_debug_arg(con, bio_s_out);
+ }
+#endif
#ifndef OPENSSL_NO_KRB5
if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
{
{
con->debug=1;
BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
- BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
+ BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out);
}
if (s_msg)
{
char *p;
X509 *peer;
STACK_OF(SSL_CIPHER) *sk;
- static char *space=" ";
+ static const char *space=" ";
BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
{
BIO *file;
char *p,*e;
- static char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
+ static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
/* skip the '/' */
p= &(buf[5]);