int MAIN(int argc, char *argv[])
	{
	X509_VERIFY_PARAM *vpm = NULL;
	int badarg = 0;
	short port=PORT;
	char *CApath=NULL,*CAfile=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;
	const SSL_METHOD *meth=NULL;
	int socket_type=SOCK_STREAM;
	ENGINE *e=NULL;
	char *inrand=NULL;
	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
	char *passarg = NULL, *pass = NULL;
	char *dpassarg = NULL, *dpass = NULL;
	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;
	int no_cache = 0, ext_cache = 0;
#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};
# ifndef OPENSSL_NO_NPN
	const char *next_proto_neg_in = NULL;
	tlsextnextprotoctx next_proto;
# endif
#endif
#ifndef OPENSSL_NO_PSK
	static char *psk_identity_hint=NULL;
#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
	meth=SSLv23_server_method();
#elif !defined(OPENSSL_NO_SSL3)
	meth=SSLv3_server_method();
#elif !defined(OPENSSL_NO_SSL2)
	meth=SSLv2_server_method();
#endif
	local_argc=argc;
	local_argv=argv;
	apps_startup();
#ifdef MONOLITH
	s_server_init();
#endif
	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	if (!load_config(bio_err, NULL))
		goto end;
	verify_depth=0;
#ifdef FIONBIO
	s_nbio=0;
#endif
	s_nbio_test=0;
	argc--;
	argv++;
	while (argc >= 1)
		{
		if	((strcmp(*argv,"-port") == 0) ||
			 (strcmp(*argv,"-accept") == 0))
			{
			if (--argc < 1) goto bad;
			if (!extract_port(*(++argv),&port))
				goto bad;
			}
		else if	(strcmp(*argv,"-verify") == 0)
			{
			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
			if (--argc < 1) goto bad;
			verify_depth=atoi(*(++argv));
			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
			}
		else if	(strcmp(*argv,"-Verify") == 0)
			{
			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
				SSL_VERIFY_CLIENT_ONCE;
			if (--argc < 1) goto bad;
			verify_depth=atoi(*(++argv));
			BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
			}
		else if	(strcmp(*argv,"-context") == 0)
			{
			if (--argc < 1) goto bad;
			context= (unsigned char *)*(++argv);
			}
		else if	(strcmp(*argv,"-cert") == 0)
			{
			if (--argc < 1) goto bad;
			s_cert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-certform") == 0)
			{
			if (--argc < 1) goto bad;
			s_cert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-key") == 0)
			{
			if (--argc < 1) goto bad;
			s_key_file= *(++argv);
			}
		else if	(strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			s_key_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg = *(++argv);
			}
		else if	(strcmp(*argv,"-dhparam") == 0)
			{
			if (--argc < 1) goto bad;
			dhfile = *(++argv);
			}
#ifndef OPENSSL_NO_ECDH
		else if	(strcmp(*argv,"-named_curve") == 0)
			{
			if (--argc < 1) goto bad;
			named_curve = *(++argv);
			}
#endif
		else if	(strcmp(*argv,"-dcertform") == 0)
			{
			if (--argc < 1) goto bad;
			s_dcert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-dcert") == 0)
			{
			if (--argc < 1) goto bad;
			s_dcert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-dkeyform") == 0)
			{
			if (--argc < 1) goto bad;
			s_dkey_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-dpass") == 0)
			{
			if (--argc < 1) goto bad;
			dpassarg = *(++argv);
			}
		else if	(strcmp(*argv,"-dkey") == 0)
			{
			if (--argc < 1) goto bad;
			s_dkey_file= *(++argv);
			}
		else if (strcmp(*argv,"-nocert") == 0)
			{
			nocert=1;
			}
		else if	(strcmp(*argv,"-CApath") == 0)
			{
			if (--argc < 1) goto bad;
			CApath= *(++argv);
			}
		else if (strcmp(*argv,"-no_cache") == 0)
			no_cache = 1;
		else if (strcmp(*argv,"-ext_cache") == 0)
			ext_cache = 1;
		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
			{
			if (badarg)
				goto bad;
			continue;
			}
		else if (strcmp(*argv,"-verify_return_error") == 0)
			verify_return_error = 1;
		else if	(strcmp(*argv,"-serverpref") == 0)
			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
		else if	(strcmp(*argv,"-cipher") == 0)
			{
			if (--argc < 1) goto bad;
			cipher= *(++argv);
			}
		else if	(strcmp(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			}
#ifdef FIONBIO
		else if	(strcmp(*argv,"-nbio") == 0)
			{ s_nbio=1; }
#endif
		else if	(strcmp(*argv,"-nbio_test") == 0)
			{
#ifdef FIONBIO
			s_nbio=1;
#endif
			s_nbio_test=1;
			}
		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)
			{ hack=1; }
		else if	(strcmp(*argv,"-state") == 0)
			{ state=1; }
		else if	(strcmp(*argv,"-crlf") == 0)
			{ s_crlf=1; }
		else if	(strcmp(*argv,"-quiet") == 0)
			{ s_quiet=1; }
		else if	(strcmp(*argv,"-bugs") == 0)
			{ bugs=1; }
		else if	(strcmp(*argv,"-no_tmp_rsa") == 0)
			{ no_tmp_rsa=1; }
		else if	(strcmp(*argv,"-no_dhe") == 0)
			{ no_dhe=1; }
		else if	(strcmp(*argv,"-no_ecdhe") == 0)
			{ no_ecdhe=1; }
#ifndef OPENSSL_NO_PSK
                else if (strcmp(*argv,"-psk_hint") == 0)
			{
                        if (--argc < 1) goto bad;
                        psk_identity_hint= *(++argv);
                        }
                else if (strcmp(*argv,"-psk") == 0)
			{
			size_t i;
			if (--argc < 1) goto bad;
			psk_key=*(++argv);
			for (i=0; i<strlen(psk_key); i++)
				{
				if (isxdigit((int)psk_key[i]))
					continue;
				BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
				goto bad;
				}
			}
#endif
		else if	(strcmp(*argv,"-www") == 0)
			{ www=1; }
		else if	(strcmp(*argv,"-WWW") == 0)
			{ www=2; }
		else if	(strcmp(*argv,"-HTTP") == 0)
			{ www=3; }
		else if	(strcmp(*argv,"-no_ssl2") == 0)
			{ off|=SSL_OP_NO_SSLv2; }
		else if	(strcmp(*argv,"-no_ssl3") == 0)
			{ off|=SSL_OP_NO_SSLv3; }
		else if	(strcmp(*argv,"-no_tls1_1") == 0)
			{ off|=SSL_OP_NO_TLSv1_1; }
		else if	(strcmp(*argv,"-no_tls1") == 0)
			{ off|=SSL_OP_NO_TLSv1; }
		else if	(strcmp(*argv,"-no_comp") == 0)
			{ off|=SSL_OP_NO_COMPRESSION; }
#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(); }
#endif
#ifndef OPENSSL_NO_SSL3
		else if	(strcmp(*argv,"-ssl3") == 0)
			{ meth=SSLv3_server_method(); }
#endif
#ifndef OPENSSL_NO_TLS1
		else if	(strcmp(*argv,"-tls1_1") == 0)
			{ meth=TLSv1_1_server_method(); }
		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;
			socket_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;
			session_id_prefix = *(++argv);
			}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine_id= *(++argv);
			}
#endif
		else if (strcmp(*argv,"-rand") == 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);
			}
# ifndef OPENSSL_NO_NPN
		else if	(strcmp(*argv,"-nextprotoneg") == 0)
			{
			if (--argc < 1) goto bad;
			next_proto_neg_in = *(++argv);
			}
# endif
#endif
#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
		else if (strcmp(*argv,"-jpake") == 0)
			{
			if (--argc < 1) goto bad;
			jpake_secret = *(++argv);
			}
#endif
		else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badop=1;
			break;
			}
		argc--;
		argv++;
		}
	if (badop)
		{
bad:
		sv_usage();
		goto end;
		}
#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
	if (jpake_secret)
		{
		if (psk_key)
			{
			BIO_printf(bio_err,
				   "Can't use JPAKE and PSK together\n");
			goto end;
			}
		psk_identity = "JPAKE";
		if (cipher)
			{
			BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
			goto end;
			}
		cipher = "PSK";
		}
#endif
	SSL_load_error_strings();
	OpenSSL_add_ssl_algorithms();
#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine_id, 1);
#endif
	if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}
	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
	if (nocert == 0)
		{
		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,
			NULL, e, "server certificate file");
		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;
				}
			}
# ifndef OPENSSL_NO_NPN
		if (next_proto_neg_in)
			{
			unsigned short len;
			next_proto.data = next_protos_parse(&len,
				next_proto_neg_in);
			if (next_proto.data == NULL)
				goto end;
			next_proto.len = len;
			}
		else
			{
			next_proto.data = NULL;
			}
# endif
#endif
		}
	if (s_dcert_file)
		{
		if (s_dkey_file == NULL)
			s_dkey_file = s_dcert_file;
		s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
				0, dpass, e,
			       "second certificate private key file");
		if (!s_dkey)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
				NULL, e, "second server certificate file");
		if (!s_dcert)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
		&& !RAND_status())
		{
		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
		}
	if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));
	if (bio_s_out == NULL)
		{
		if (s_quiet && !s_debug && !s_msg)
			{
			bio_s_out=BIO_new(BIO_s_null());
			}
		else
			{
			if (bio_s_out == NULL)
				bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
			}
		}
#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
	if (nocert)
#endif
		{
		s_cert_file=NULL;
		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 (ctx == NULL)
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	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(ctx, 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(ctx,1);
	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);
	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
	if (no_cache)
		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
	else if (ext_cache)
		init_session_cache_ctx(ctx);
	else
		SSL_CTX_sess_set_cache_size(ctx,128);
#if 0
	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
#endif
#if 0
	if (s_cert_file == NULL)
		{
		BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
		goto end;
		}
#endif
	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(ctx)))
		{
		ERR_print_errors(bio_err);
		}
	if (vpm)
		SSL_CTX_set1_param(ctx, vpm);
#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);
		if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
		if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
		if (no_cache)
			SSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF);
		else if (ext_cache)
			init_session_cache_ctx(ctx2);
		else
			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);
			}
		if (vpm)
			SSL_CTX_set1_param(ctx2, vpm);
		}
# ifndef OPENSSL_NO_NPN
	if (next_proto.data)
		SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
# endif
#endif
#ifndef OPENSSL_NO_DH
	if (!no_dhe)
		{
		DH *dh=NULL;
		if (dhfile)
			dh = load_dh_param(dhfile);
		else if (s_cert_file)
			dh = load_dh_param(s_cert_file);
		if (dh != NULL)
			{
			BIO_printf(bio_s_out,"Setting temp DH parameters\n");
			}
		else
			{
			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
			dh=get_dh512();
			}
		(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
#ifndef OPENSSL_NO_ECDH
	if (!no_ecdhe)
		{
		EC_KEY *ecdh=NULL;
		if (named_curve)
			{
			int nid = OBJ_sn2nid(named_curve);
			if (nid == 0)
				{
				BIO_printf(bio_err, "unknown curve name (%s)\n",
					named_curve);
				goto end;
				}
			ecdh = EC_KEY_new_by_curve_name(nid);
			if (ecdh == NULL)
				{
				BIO_printf(bio_err, "unable to create curve (%s)\n",
					named_curve);
				goto end;
				}
			}
		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 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
			if (ecdh == NULL)
				{
				BIO_printf(bio_err, "unable to create curve (nistp256)\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))
			goto end;
		}
#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))
		{
		RSA *rsa;
		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
		BIO_flush(bio_s_out);
		rsa=RSA_generate_key(512,RSA_F4,NULL);
		if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
			{
			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");
		}
#endif
#endif
#ifndef OPENSSL_NO_PSK
#ifdef OPENSSL_NO_JPAKE
	if (psk_key != NULL)
#else
	if (psk_key != NULL || jpake_secret)
#endif
		{
		if (s_debug)
			BIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\n");
		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;
		}
#endif
	if (cipher != NULL)
		{
		if(!SSL_CTX_set_cipher_list(ctx,cipher))
			{
			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);
	SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
	SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
#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));
#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");
	(void)BIO_flush(bio_s_out);
	if (www)
		do_server(port,socket_type,&accept_socket,www_body, context);
	else
		do_server(port,socket_type,&accept_socket,sv_body, context);
	print_stats(bio_s_out,ctx);
	ret=0;
end:
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (s_cert)
		X509_free(s_cert);
	if (s_dcert)
		X509_free(s_dcert);
	if (s_key)
		EVP_PKEY_free(s_key);
	if (s_dkey)
		EVP_PKEY_free(s_dkey);
	if (pass)
		OPENSSL_free(pass);
	if (dpass)
		OPENSSL_free(dpass);
	free_sessions();
#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_s_out=NULL;
		}
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
['int MAIN(int argc, char *argv[])\n\t{\n\tX509_VERIFY_PARAM *vpm = NULL;\n\tint badarg = 0;\n\tshort port=PORT;\n\tchar *CApath=NULL,*CAfile=NULL;\n\tunsigned char *context = NULL;\n\tchar *dhfile = NULL;\n#ifndef OPENSSL_NO_ECDH\n\tchar *named_curve = NULL;\n#endif\n\tint badop=0,bugs=0;\n\tint ret=1;\n\tint off=0;\n\tint no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;\n\tint state=0;\n\tconst SSL_METHOD *meth=NULL;\n\tint socket_type=SOCK_STREAM;\n\tENGINE *e=NULL;\n\tchar *inrand=NULL;\n\tint s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;\n\tchar *passarg = NULL, *pass = NULL;\n\tchar *dpassarg = NULL, *dpass = NULL;\n\tint s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;\n\tX509 *s_cert = NULL, *s_dcert = NULL;\n\tEVP_PKEY *s_key = NULL, *s_dkey = NULL;\n\tint no_cache = 0, ext_cache = 0;\n#ifndef OPENSSL_NO_TLSEXT\n\tEVP_PKEY *s_key2 = NULL;\n\tX509 *s_cert2 = NULL;\n#endif\n#ifndef OPENSSL_NO_TLSEXT\n        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};\n# ifndef OPENSSL_NO_NPN\n\tconst char *next_proto_neg_in = NULL;\n\ttlsextnextprotoctx next_proto;\n# endif\n#endif\n#ifndef OPENSSL_NO_PSK\n\tstatic char *psk_identity_hint=NULL;\n#endif\n#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)\n\tmeth=SSLv23_server_method();\n#elif !defined(OPENSSL_NO_SSL3)\n\tmeth=SSLv3_server_method();\n#elif !defined(OPENSSL_NO_SSL2)\n\tmeth=SSLv2_server_method();\n#endif\n\tlocal_argc=argc;\n\tlocal_argv=argv;\n\tapps_startup();\n#ifdef MONOLITH\n\ts_server_init();\n#endif\n\tif (bio_err == NULL)\n\t\tbio_err=BIO_new_fp(stderr,BIO_NOCLOSE);\n\tif (!load_config(bio_err, NULL))\n\t\tgoto end;\n\tverify_depth=0;\n#ifdef FIONBIO\n\ts_nbio=0;\n#endif\n\ts_nbio_test=0;\n\targc--;\n\targv++;\n\twhile (argc >= 1)\n\t\t{\n\t\tif\t((strcmp(*argv,"-port") == 0) ||\n\t\t\t (strcmp(*argv,"-accept") == 0))\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tif (!extract_port(*(++argv),&port))\n\t\t\t\tgoto bad;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-verify") == 0)\n\t\t\t{\n\t\t\ts_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tverify_depth=atoi(*(++argv));\n\t\t\tBIO_printf(bio_err,"verify depth is %d\\n",verify_depth);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-Verify") == 0)\n\t\t\t{\n\t\t\ts_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|\n\t\t\t\tSSL_VERIFY_CLIENT_ONCE;\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tverify_depth=atoi(*(++argv));\n\t\t\tBIO_printf(bio_err,"verify depth is %d, must return a certificate\\n",verify_depth);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-context") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tcontext= (unsigned char *)*(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-cert") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_cert_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-certform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_cert_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-key") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_key_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-keyform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_key_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-pass") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tpassarg = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dhparam") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tdhfile = *(++argv);\n\t\t\t}\n#ifndef OPENSSL_NO_ECDH\n\t\telse if\t(strcmp(*argv,"-named_curve") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tnamed_curve = *(++argv);\n\t\t\t}\n#endif\n\t\telse if\t(strcmp(*argv,"-dcertform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_dcert_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dcert") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_dcert_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dkeyform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_dkey_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dpass") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tdpassarg = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dkey") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_dkey_file= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-nocert") == 0)\n\t\t\t{\n\t\t\tnocert=1;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-CApath") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tCApath= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-no_cache") == 0)\n\t\t\tno_cache = 1;\n\t\telse if (strcmp(*argv,"-ext_cache") == 0)\n\t\t\text_cache = 1;\n\t\telse if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))\n\t\t\t{\n\t\t\tif (badarg)\n\t\t\t\tgoto bad;\n\t\t\tcontinue;\n\t\t\t}\n\t\telse if (strcmp(*argv,"-verify_return_error") == 0)\n\t\t\tverify_return_error = 1;\n\t\telse if\t(strcmp(*argv,"-serverpref") == 0)\n\t\t\t{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }\n\t\telse if (strcmp(*argv,"-legacy_renegotiation") == 0)\n\t\t\toff|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;\n\t\telse if\t(strcmp(*argv,"-cipher") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tcipher= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-CAfile") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tCAfile= *(++argv);\n\t\t\t}\n#ifdef FIONBIO\n\t\telse if\t(strcmp(*argv,"-nbio") == 0)\n\t\t\t{ s_nbio=1; }\n#endif\n\t\telse if\t(strcmp(*argv,"-nbio_test") == 0)\n\t\t\t{\n#ifdef FIONBIO\n\t\t\ts_nbio=1;\n#endif\n\t\t\ts_nbio_test=1;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-debug") == 0)\n\t\t\t{ s_debug=1; }\n#ifndef OPENSSL_NO_TLSEXT\n\t\telse if\t(strcmp(*argv,"-tlsextdebug") == 0)\n\t\t\ts_tlsextdebug=1;\n\t\telse if\t(strcmp(*argv,"-status") == 0)\n\t\t\ts_tlsextstatus=1;\n\t\telse if\t(strcmp(*argv,"-status_verbose") == 0)\n\t\t\t{\n\t\t\ts_tlsextstatus=1;\n\t\t\ttlscstatp.verbose = 1;\n\t\t\t}\n\t\telse if (!strcmp(*argv, "-status_timeout"))\n\t\t\t{\n\t\t\ts_tlsextstatus=1;\n                        if (--argc < 1) goto bad;\n\t\t\ttlscstatp.timeout = atoi(*(++argv));\n\t\t\t}\n\t\telse if (!strcmp(*argv, "-status_url"))\n\t\t\t{\n\t\t\ts_tlsextstatus=1;\n                        if (--argc < 1) goto bad;\n\t\t\tif (!OCSP_parse_url(*(++argv),\n\t\t\t\t\t&tlscstatp.host,\n\t\t\t\t\t&tlscstatp.port,\n\t\t\t\t\t&tlscstatp.path,\n\t\t\t\t\t&tlscstatp.use_ssl))\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err, "Error parsing URL\\n");\n\t\t\t\tgoto bad;\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\telse if\t(strcmp(*argv,"-msg") == 0)\n\t\t\t{ s_msg=1; }\n\t\telse if\t(strcmp(*argv,"-hack") == 0)\n\t\t\t{ hack=1; }\n\t\telse if\t(strcmp(*argv,"-state") == 0)\n\t\t\t{ state=1; }\n\t\telse if\t(strcmp(*argv,"-crlf") == 0)\n\t\t\t{ s_crlf=1; }\n\t\telse if\t(strcmp(*argv,"-quiet") == 0)\n\t\t\t{ s_quiet=1; }\n\t\telse if\t(strcmp(*argv,"-bugs") == 0)\n\t\t\t{ bugs=1; }\n\t\telse if\t(strcmp(*argv,"-no_tmp_rsa") == 0)\n\t\t\t{ no_tmp_rsa=1; }\n\t\telse if\t(strcmp(*argv,"-no_dhe") == 0)\n\t\t\t{ no_dhe=1; }\n\t\telse if\t(strcmp(*argv,"-no_ecdhe") == 0)\n\t\t\t{ no_ecdhe=1; }\n#ifndef OPENSSL_NO_PSK\n                else if (strcmp(*argv,"-psk_hint") == 0)\n\t\t\t{\n                        if (--argc < 1) goto bad;\n                        psk_identity_hint= *(++argv);\n                        }\n                else if (strcmp(*argv,"-psk") == 0)\n\t\t\t{\n\t\t\tsize_t i;\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tpsk_key=*(++argv);\n\t\t\tfor (i=0; i<strlen(psk_key); i++)\n\t\t\t\t{\n\t\t\t\tif (isxdigit((int)psk_key[i]))\n\t\t\t\t\tcontinue;\n\t\t\t\tBIO_printf(bio_err,"Not a hex number \'%s\'\\n",*argv);\n\t\t\t\tgoto bad;\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\telse if\t(strcmp(*argv,"-www") == 0)\n\t\t\t{ www=1; }\n\t\telse if\t(strcmp(*argv,"-WWW") == 0)\n\t\t\t{ www=2; }\n\t\telse if\t(strcmp(*argv,"-HTTP") == 0)\n\t\t\t{ www=3; }\n\t\telse if\t(strcmp(*argv,"-no_ssl2") == 0)\n\t\t\t{ off|=SSL_OP_NO_SSLv2; }\n\t\telse if\t(strcmp(*argv,"-no_ssl3") == 0)\n\t\t\t{ off|=SSL_OP_NO_SSLv3; }\n\t\telse if\t(strcmp(*argv,"-no_tls1_1") == 0)\n\t\t\t{ off|=SSL_OP_NO_TLSv1_1; }\n\t\telse if\t(strcmp(*argv,"-no_tls1") == 0)\n\t\t\t{ off|=SSL_OP_NO_TLSv1; }\n\t\telse if\t(strcmp(*argv,"-no_comp") == 0)\n\t\t\t{ off|=SSL_OP_NO_COMPRESSION; }\n#ifndef OPENSSL_NO_TLSEXT\n\t\telse if\t(strcmp(*argv,"-no_ticket") == 0)\n\t\t\t{ off|=SSL_OP_NO_TICKET; }\n#endif\n#ifndef OPENSSL_NO_SSL2\n\t\telse if\t(strcmp(*argv,"-ssl2") == 0)\n\t\t\t{ meth=SSLv2_server_method(); }\n#endif\n#ifndef OPENSSL_NO_SSL3\n\t\telse if\t(strcmp(*argv,"-ssl3") == 0)\n\t\t\t{ meth=SSLv3_server_method(); }\n#endif\n#ifndef OPENSSL_NO_TLS1\n\t\telse if\t(strcmp(*argv,"-tls1_1") == 0)\n\t\t\t{ meth=TLSv1_1_server_method(); }\n\t\telse if\t(strcmp(*argv,"-tls1") == 0)\n\t\t\t{ meth=TLSv1_server_method(); }\n#endif\n#ifndef OPENSSL_NO_DTLS1\n\t\telse if\t(strcmp(*argv,"-dtls1") == 0)\n\t\t\t{\n\t\t\tmeth=DTLSv1_server_method();\n\t\t\tsocket_type = SOCK_DGRAM;\n\t\t\t}\n\t\telse if (strcmp(*argv,"-timeout") == 0)\n\t\t\tenable_timeouts = 1;\n\t\telse if (strcmp(*argv,"-mtu") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsocket_mtu = atol(*(++argv));\n\t\t\t}\n\t\telse if (strcmp(*argv, "-chain") == 0)\n\t\t\tcert_chain = 1;\n#endif\n\t\telse if (strcmp(*argv, "-id_prefix") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsession_id_prefix = *(++argv);\n\t\t\t}\n#ifndef OPENSSL_NO_ENGINE\n\t\telse if (strcmp(*argv,"-engine") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tengine_id= *(++argv);\n\t\t\t}\n#endif\n\t\telse if (strcmp(*argv,"-rand") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tinrand= *(++argv);\n\t\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\t\telse if (strcmp(*argv,"-servername") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ttlsextcbp.servername= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-servername_fatal") == 0)\n\t\t\t{ tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }\n\t\telse if\t(strcmp(*argv,"-cert2") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_cert_file2= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-key2") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\ts_key_file2= *(++argv);\n\t\t\t}\n# ifndef OPENSSL_NO_NPN\n\t\telse if\t(strcmp(*argv,"-nextprotoneg") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tnext_proto_neg_in = *(++argv);\n\t\t\t}\n# endif\n#endif\n#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)\n\t\telse if (strcmp(*argv,"-jpake") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tjpake_secret = *(++argv);\n\t\t\t}\n#endif\n\t\telse\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"unknown option %s\\n",*argv);\n\t\t\tbadop=1;\n\t\t\tbreak;\n\t\t\t}\n\t\targc--;\n\t\targv++;\n\t\t}\n\tif (badop)\n\t\t{\nbad:\n\t\tsv_usage();\n\t\tgoto end;\n\t\t}\n#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)\n\tif (jpake_secret)\n\t\t{\n\t\tif (psk_key)\n\t\t\t{\n\t\t\tBIO_printf(bio_err,\n\t\t\t\t   "Can\'t use JPAKE and PSK together\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tpsk_identity = "JPAKE";\n\t\tif (cipher)\n\t\t\t{\n\t\t\tBIO_printf(bio_err, "JPAKE sets cipher to PSK\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tcipher = "PSK";\n\t\t}\n#endif\n\tSSL_load_error_strings();\n\tOpenSSL_add_ssl_algorithms();\n#ifndef OPENSSL_NO_ENGINE\n        e = setup_engine(bio_err, engine_id, 1);\n#endif\n\tif (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))\n\t\t{\n\t\tBIO_printf(bio_err, "Error getting password\\n");\n\t\tgoto end;\n\t\t}\n\tif (s_key_file == NULL)\n\t\ts_key_file = s_cert_file;\n#ifndef OPENSSL_NO_TLSEXT\n\tif (s_key_file2 == NULL)\n\t\ts_key_file2 = s_cert_file2;\n#endif\n\tif (nocert == 0)\n\t\t{\n\t\ts_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,\n\t\t       "server certificate private key file");\n\t\tif (!s_key)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\ts_cert = load_cert(bio_err,s_cert_file,s_cert_format,\n\t\t\tNULL, e, "server certificate file");\n\t\tif (!s_cert)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\t\tif (tlsextcbp.servername)\n\t\t\t{\n\t\t\ts_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,\n\t\t\t\t"second server certificate private key file");\n\t\t\tif (!s_key2)\n\t\t\t\t{\n\t\t\t\tERR_print_errors(bio_err);\n\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\ts_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,\n\t\t\t\tNULL, e, "second server certificate file");\n\t\t\tif (!s_cert2)\n\t\t\t\t{\n\t\t\t\tERR_print_errors(bio_err);\n\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\t}\n# ifndef OPENSSL_NO_NPN\n\t\tif (next_proto_neg_in)\n\t\t\t{\n\t\t\tunsigned short len;\n\t\t\tnext_proto.data = next_protos_parse(&len,\n\t\t\t\tnext_proto_neg_in);\n\t\t\tif (next_proto.data == NULL)\n\t\t\t\tgoto end;\n\t\t\tnext_proto.len = len;\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tnext_proto.data = NULL;\n\t\t\t}\n# endif\n#endif\n\t\t}\n\tif (s_dcert_file)\n\t\t{\n\t\tif (s_dkey_file == NULL)\n\t\t\ts_dkey_file = s_dcert_file;\n\t\ts_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,\n\t\t\t\t0, dpass, e,\n\t\t\t       "second certificate private key file");\n\t\tif (!s_dkey)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\ts_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,\n\t\t\t\tNULL, e, "second server certificate file");\n\t\tif (!s_dcert)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL\n\t\t&& !RAND_status())\n\t\t{\n\t\tBIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\\n");\n\t\t}\n\tif (inrand != NULL)\n\t\tBIO_printf(bio_err,"%ld semi-random bytes loaded\\n",\n\t\t\tapp_RAND_load_files(inrand));\n\tif (bio_s_out == NULL)\n\t\t{\n\t\tif (s_quiet && !s_debug && !s_msg)\n\t\t\t{\n\t\t\tbio_s_out=BIO_new(BIO_s_null());\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tif (bio_s_out == NULL)\n\t\t\t\tbio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);\n\t\t\t}\n\t\t}\n#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)\n\tif (nocert)\n#endif\n\t\t{\n\t\ts_cert_file=NULL;\n\t\ts_key_file=NULL;\n\t\ts_dcert_file=NULL;\n\t\ts_dkey_file=NULL;\n#ifndef OPENSSL_NO_TLSEXT\n\t\ts_cert_file2=NULL;\n\t\ts_key_file2=NULL;\n#endif\n\t\t}\n\tctx=SSL_CTX_new(meth);\n\tif (ctx == NULL)\n\t\t{\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n\tif (session_id_prefix)\n\t\t{\n\t\tif(strlen(session_id_prefix) >= 32)\n\t\t\tBIO_printf(bio_err,\n"warning: id_prefix is too long, only one new session will be possible\\n");\n\t\telse if(strlen(session_id_prefix) >= 16)\n\t\t\tBIO_printf(bio_err,\n"warning: id_prefix is too long if you use SSLv2\\n");\n\t\tif(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"error setting \'id_prefix\'\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\tBIO_printf(bio_err,"id_prefix \'%s\' set.\\n", session_id_prefix);\n\t\t}\n\tSSL_CTX_set_quiet_shutdown(ctx,1);\n\tif (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);\n\tif (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);\n\tSSL_CTX_set_options(ctx,off);\n\tif (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);\n\tif (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);\n\tif (no_cache)\n\t\tSSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);\n\telse if (ext_cache)\n\t\tinit_session_cache_ctx(ctx);\n\telse\n\t\tSSL_CTX_sess_set_cache_size(ctx,128);\n#if 0\n\tif (cipher == NULL) cipher=getenv("SSL_CIPHER");\n#endif\n#if 0\n\tif (s_cert_file == NULL)\n\t\t{\n\t\tBIO_printf(bio_err,"You must specify a certificate file for the server to use\\n");\n\t\tgoto end;\n\t\t}\n#endif\n\tif ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||\n\t\t(!SSL_CTX_set_default_verify_paths(ctx)))\n\t\t{\n\t\tERR_print_errors(bio_err);\n\t\t}\n\tif (vpm)\n\t\tSSL_CTX_set1_param(ctx, vpm);\n#ifndef OPENSSL_NO_TLSEXT\n\tif (s_cert2)\n\t\t{\n\t\tctx2=SSL_CTX_new(meth);\n\t\tif (ctx2 == NULL)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (ctx2)\n\t\t{\n\t\tBIO_printf(bio_s_out,"Setting secondary ctx parameters\\n");\n\t\tif (session_id_prefix)\n\t\t\t{\n\t\t\tif(strlen(session_id_prefix) >= 32)\n\t\t\t\tBIO_printf(bio_err,\n\t\t\t\t\t"warning: id_prefix is too long, only one new session will be possible\\n");\n\t\t\telse if(strlen(session_id_prefix) >= 16)\n\t\t\t\tBIO_printf(bio_err,\n\t\t\t\t\t"warning: id_prefix is too long if you use SSLv2\\n");\n\t\t\tif(!SSL_CTX_set_generate_session_id(ctx2, generate_session_id))\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err,"error setting \'id_prefix\'\\n");\n\t\t\t\tERR_print_errors(bio_err);\n\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\tBIO_printf(bio_err,"id_prefix \'%s\' set.\\n", session_id_prefix);\n\t\t\t}\n\t\tSSL_CTX_set_quiet_shutdown(ctx2,1);\n\t\tif (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);\n\t\tif (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);\n\t\tSSL_CTX_set_options(ctx2,off);\n\t\tif (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);\n\t\tif (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);\n\t\tif (no_cache)\n\t\t\tSSL_CTX_set_session_cache_mode(ctx2,SSL_SESS_CACHE_OFF);\n\t\telse if (ext_cache)\n\t\t\tinit_session_cache_ctx(ctx2);\n\t\telse\n\t\t\tSSL_CTX_sess_set_cache_size(ctx2,128);\n\t\tif ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||\n\t\t\t(!SSL_CTX_set_default_verify_paths(ctx2)))\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\t}\n\t\tif (vpm)\n\t\t\tSSL_CTX_set1_param(ctx2, vpm);\n\t\t}\n# ifndef OPENSSL_NO_NPN\n\tif (next_proto.data)\n\t\tSSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);\n# endif\n#endif\n#ifndef OPENSSL_NO_DH\n\tif (!no_dhe)\n\t\t{\n\t\tDH *dh=NULL;\n\t\tif (dhfile)\n\t\t\tdh = load_dh_param(dhfile);\n\t\telse if (s_cert_file)\n\t\t\tdh = load_dh_param(s_cert_file);\n\t\tif (dh != NULL)\n\t\t\t{\n\t\t\tBIO_printf(bio_s_out,"Setting temp DH parameters\\n");\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tBIO_printf(bio_s_out,"Using default temp DH parameters\\n");\n\t\t\tdh=get_dh512();\n\t\t\t}\n\t\t(void)BIO_flush(bio_s_out);\n\t\tSSL_CTX_set_tmp_dh(ctx,dh);\n#ifndef OPENSSL_NO_TLSEXT\n\t\tif (ctx2)\n\t\t\t{\n\t\t\tif (!dhfile)\n\t\t\t\t{\n\t\t\t\tDH *dh2=load_dh_param(s_cert_file2);\n\t\t\t\tif (dh2 != NULL)\n\t\t\t\t\t{\n\t\t\t\t\tBIO_printf(bio_s_out,"Setting temp DH parameters\\n");\n\t\t\t\t\t(void)BIO_flush(bio_s_out);\n\t\t\t\t\tDH_free(dh);\n\t\t\t\t\tdh = dh2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tSSL_CTX_set_tmp_dh(ctx2,dh);\n\t\t\t}\n#endif\n\t\tDH_free(dh);\n\t\t}\n#endif\n#ifndef OPENSSL_NO_ECDH\n\tif (!no_ecdhe)\n\t\t{\n\t\tEC_KEY *ecdh=NULL;\n\t\tif (named_curve)\n\t\t\t{\n\t\t\tint nid = OBJ_sn2nid(named_curve);\n\t\t\tif (nid == 0)\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err, "unknown curve name (%s)\\n",\n\t\t\t\t\tnamed_curve);\n\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\tecdh = EC_KEY_new_by_curve_name(nid);\n\t\t\tif (ecdh == NULL)\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err, "unable to create curve (%s)\\n",\n\t\t\t\t\tnamed_curve);\n\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\t}\n\t\tif (ecdh != NULL)\n\t\t\t{\n\t\t\tBIO_printf(bio_s_out,"Setting temp ECDH parameters\\n");\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tBIO_printf(bio_s_out,"Using default temp ECDH parameters\\n");\n\t\t\tecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);\n\t\t\tif (ecdh == NULL)\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err, "unable to create curve (nistp256)\\n");\n\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\t}\n\t\t(void)BIO_flush(bio_s_out);\n\t\tSSL_CTX_set_tmp_ecdh(ctx,ecdh);\n#ifndef OPENSSL_NO_TLSEXT\n\t\tif (ctx2)\n\t\t\tSSL_CTX_set_tmp_ecdh(ctx2,ecdh);\n#endif\n\t\tEC_KEY_free(ecdh);\n\t\t}\n#endif\n\tif (!set_cert_key_stuff(ctx,s_cert,s_key))\n\t\tgoto end;\n#ifndef OPENSSL_NO_TLSEXT\n\tif (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2))\n\t\tgoto end;\n#endif\n\tif (s_dcert != NULL)\n\t\t{\n\t\tif (!set_cert_key_stuff(ctx,s_dcert,s_dkey))\n\t\t\tgoto end;\n\t\t}\n#ifndef OPENSSL_NO_RSA\n#if 1\n\tif (!no_tmp_rsa)\n\t\t{\n\t\tSSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);\n#ifndef OPENSSL_NO_TLSEXT\n\t\tif (ctx2)\n\t\t\tSSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);\n#endif\n\t\t}\n#else\n\tif (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))\n\t\t{\n\t\tRSA *rsa;\n\t\tBIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");\n\t\tBIO_flush(bio_s_out);\n\t\trsa=RSA_generate_key(512,RSA_F4,NULL);\n\t\tif (!SSL_CTX_set_tmp_rsa(ctx,rsa))\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\t\t\tif (ctx2)\n\t\t\t\t{\n\t\t\t\tif (!SSL_CTX_set_tmp_rsa(ctx2,rsa))\n\t\t\t\t\t{\n\t\t\t\t\tERR_print_errors(bio_err);\n\t\t\t\t\tgoto end;\n\t\t\t\t\t}\n\t\t\t\t}\n#endif\n\t\tRSA_free(rsa);\n\t\tBIO_printf(bio_s_out,"\\n");\n\t\t}\n#endif\n#endif\n#ifndef OPENSSL_NO_PSK\n#ifdef OPENSSL_NO_JPAKE\n\tif (psk_key != NULL)\n#else\n\tif (psk_key != NULL || jpake_secret)\n#endif\n\t\t{\n\t\tif (s_debug)\n\t\t\tBIO_printf(bio_s_out, "PSK key given or JPAKE in use, setting server callback\\n");\n\t\tSSL_CTX_set_psk_server_callback(ctx, psk_server_cb);\n\t\t}\n\tif (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint))\n\t\t{\n\t\tBIO_printf(bio_err,"error setting PSK identity hint to context\\n");\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n#endif\n\tif (cipher != NULL)\n\t\t{\n\t\tif(!SSL_CTX_set_cipher_list(ctx,cipher))\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"error setting cipher list\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\t\tif (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"error setting cipher list\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n#endif\n\t\t}\n\tSSL_CTX_set_verify(ctx,s_server_verify,verify_callback);\n\tSSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,\n\t\tsizeof s_server_session_id_context);\n\tSSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);\n\tSSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);\n#ifndef OPENSSL_NO_TLSEXT\n\tif (ctx2)\n\t\t{\n\t\tSSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);\n\t\tSSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,\n\t\t\tsizeof s_server_session_id_context);\n\t\ttlsextcbp.biodebug = bio_s_out;\n\t\tSSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);\n\t\tSSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);\n\t\tSSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);\n\t\tSSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);\n\t\t}\n#endif\n\tif (CAfile != NULL)\n\t\t{\n\t\tSSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));\n#ifndef OPENSSL_NO_TLSEXT\n\t\tif (ctx2)\n\t\t\tSSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));\n#endif\n\t\t}\n\tBIO_printf(bio_s_out,"ACCEPT\\n");\n\t(void)BIO_flush(bio_s_out);\n\tif (www)\n\t\tdo_server(port,socket_type,&accept_socket,www_body, context);\n\telse\n\t\tdo_server(port,socket_type,&accept_socket,sv_body, context);\n\tprint_stats(bio_s_out,ctx);\n\tret=0;\nend:\n\tif (ctx != NULL) SSL_CTX_free(ctx);\n\tif (s_cert)\n\t\tX509_free(s_cert);\n\tif (s_dcert)\n\t\tX509_free(s_dcert);\n\tif (s_key)\n\t\tEVP_PKEY_free(s_key);\n\tif (s_dkey)\n\t\tEVP_PKEY_free(s_dkey);\n\tif (pass)\n\t\tOPENSSL_free(pass);\n\tif (dpass)\n\t\tOPENSSL_free(dpass);\n\tfree_sessions();\n#ifndef OPENSSL_NO_TLSEXT\n\tif (ctx2 != NULL) SSL_CTX_free(ctx2);\n\tif (s_cert2)\n\t\tX509_free(s_cert2);\n\tif (s_key2)\n\t\tEVP_PKEY_free(s_key2);\n#endif\n\tif (bio_s_out != NULL)\n\t\t{\n        BIO_free(bio_s_out);\n\t\tbio_s_out=NULL;\n\t\t}\n\tapps_shutdown();\n\tOPENSSL_EXIT(ret);\n\t}']