+int s_server_main(int argc, char *argv[])
+{
+ ENGINE *e = NULL;
+ EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+ SSL_CONF_CTX *cctx = NULL;
+ const SSL_METHOD *meth = SSLv23_server_method();
+ SSL_EXCERT *exc = NULL;
+ STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
+ STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL;
+ 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;
+ char *dhfile = NULL, *dpassarg = NULL, *dpass = NULL, *inrand = NULL;
+ char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+ char *crl_file = NULL, *prog, *p;
+ const char *unix_path = NULL;
+#ifndef NO_SYS_UN_H
+ int unlink_unix_path = 0;
+#endif
+ int (*server_cb) (char *hostname, int s, int stype,
+ unsigned char *context);
+ int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0;
+ int no_tmp_rsa = 0, no_dhe = 0, no_ecdhe = 0, nocert = 0, ret = 1;
+ int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
+ int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
+ int rev = 0, naccept = -1, sdebug = 0, socket_type = SOCK_STREAM;
+ int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
+ unsigned short port = PORT;
+ unsigned char *context = NULL;
+ OPTION_CHOICE o;
+#ifndef OPENSSL_NO_TLSEXT
+ EVP_PKEY *s_key2 = NULL;
+ X509 *s_cert2 = NULL;
+ tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING };
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ const char *next_proto_neg_in = NULL;
+ tlsextnextprotoctx next_proto = { NULL, 0 };
+# endif
+ const char *alpn_in = NULL;
+ tlsextalpnctx alpn_ctx = { NULL, 0 };
+#endif
+#ifndef OPENSSL_NO_PSK
+ /* by default do not send a PSK identity hint */
+ static char *psk_identity_hint = NULL;
+#endif
+#ifndef OPENSSL_NO_SRP
+ char *srpuserseed = NULL;
+ char *srp_verifier_file = NULL;
+#endif
+
+ local_argc = argc;
+ local_argv = argv;
+
+ s_server_init();
+ 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);
+
+ prog = opt_init(argc, argv, s_server_options);
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ case OPT_EOF:
+ case OPT_ERR:
+ opthelp:
+ BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+ goto end;
+ case OPT_HELP:
+ opt_help(s_server_options);
+ ret = 0;
+ goto end;
+
+ case OPT_PORT:
+ if (!extract_port(opt_arg(), &port))
+ goto end;
+ break;
+ case OPT_UNIX:
+#ifdef NO_SYS_UN_H
+ BIO_printf(bio_err, "unix domain sockets unsupported\n");
+ goto end;
+#else
+ unix_path = opt_arg();
+#endif
+ break;
+ case OPT_UNLINK:
+#ifdef NO_SYS_UN_H
+ BIO_printf(bio_err, "unix domain sockets unsupported\n");
+ goto end;
+#else
+ unlink_unix_path = 1;
+#endif
+ break;
+ case OPT_NACCEPT:
+ naccept = atol(opt_arg());
+ break;
+ case OPT_VERIFY:
+ s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+ verify_depth = atoi(opt_arg());
+ if (!s_quiet)
+ BIO_printf(bio_err, "verify depth is %d\n", verify_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());
+ if (!s_quiet)
+ BIO_printf(bio_err,
+ "verify depth is %d, must return a certificate\n",
+ verify_depth);
+ break;
+ case OPT_CONTEXT:
+ context = (unsigned char *)opt_arg();
+ break;
+ case OPT_CERT:
+ s_cert_file = opt_arg();
+ break;
+ case OPT_CRL:
+ crl_file = opt_arg();
+ break;
+ case OPT_CRL_DOWNLOAD:
+ crl_download = 1;
+ break;
+#ifndef OPENSSL_NO_TLSEXT
+ case OPT_SERVERINFO:
+ s_serverinfo_file = opt_arg();
+ break;
+#endif
+ case OPT_CERTFORM:
+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format))
+ goto opthelp;
+ break;
+ case OPT_KEY:
+ s_key_file = opt_arg();
+ break;
+ case OPT_KEYFORM:
+ if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format))
+ goto opthelp;
+ break;
+ case OPT_PASS:
+ passarg = opt_arg();
+ break;
+ case OPT_CERT_CHAIN:
+ s_chain_file = opt_arg();
+ break;
+ case OPT_DHPARAM:
+ dhfile = opt_arg();
+ break;
+ case OPT_DCERTFORM:
+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format))
+ goto opthelp;
+ break;
+ case OPT_DCERT:
+ s_dcert_file = opt_arg();
+ break;
+ case OPT_DKEYFORM:
+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format))
+ goto opthelp;
+ break;
+ case OPT_DPASS:
+ dpassarg = opt_arg();
+ break;
+ case OPT_DKEY:
+ s_dkey_file = opt_arg();
+ break;
+ case OPT_DCERT_CHAIN:
+ s_dchain_file = opt_arg();
+ break;
+ case OPT_NOCERT:
+ nocert = 1;
+ break;
+ case OPT_CAPATH:
+ CApath = opt_arg();
+ break;
+ case OPT_CHAINCAPATH:
+ chCApath = opt_arg();
+ break;
+ case OPT_VERIFYCAPATH:
+ vfyCApath = opt_arg();
+ break;
+ case OPT_NO_CACHE:
+ no_cache = 1;
+ break;
+ case OPT_EXT_CACHE:
+ ext_cache = 1;
+ break;
+ case OPT_CRLFORM:
+ if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format))
+ goto opthelp;
+ break;
+ case OPT_S_CASES:
+ if (ssl_args == NULL)
+ ssl_args = sk_OPENSSL_STRING_new_null();
+ if (ssl_args == NULL
+ || !sk_OPENSSL_STRING_push(ssl_args, opt_flag())
+ || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) {
+ BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
+ goto end;
+ }
+ break;
+ case OPT_V_CASES:
+ if (!opt_verify(o, vpm))
+ goto end;
+ vpmtouched++;
+ break;
+ case OPT_X_CASES:
+ if (!args_excert(o, &exc))
+ goto end;
+ break;
+ case OPT_VERIFY_RET_ERROR:
+ verify_return_error = 1;
+ break;
+ case OPT_VERIFY_QUIET:
+ verify_quiet = 1;
+ break;
+ case OPT_BUILD_CHAIN:
+ build_chain = 1;
+ break;
+ case OPT_CAFILE:
+ CAfile = opt_arg();
+ break;
+ case OPT_CHAINCAFILE:
+ chCAfile = opt_arg();
+ break;
+ case OPT_VERIFYCAFILE:
+ vfyCAfile = opt_arg();
+ break;
+ case OPT_NBIO:
+ s_nbio = 1;
+ break;
+ case OPT_NBIO_TEST:
+ s_nbio = s_nbio_test = 1;
+ break;
+ case OPT_IGN_EOF:
+ s_ign_eof = 1;
+ break;
+ case OPT_NO_IGN_EOF:
+ s_ign_eof = 0;
+ break;
+ case OPT_DEBUG:
+ s_debug = 1;
+ break;
+#ifndef OPENSSL_NO_TLSEXT
+ case OPT_TLSEXTDEBUG:
+ s_tlsextdebug = 1;
+ break;
+ case OPT_STATUS:
+ s_tlsextstatus = 1;
+ break;
+ case OPT_STATUS_VERBOSE:
+ s_tlsextstatus = tlscstatp.verbose = 1;
+ break;
+ case OPT_STATUS_TIMEOUT:
+ s_tlsextstatus = 1;
+ tlscstatp.timeout = atoi(opt_arg());
+ break;
+ case OPT_STATUS_URL:
+ s_tlsextstatus = 1;
+ if (!OCSP_parse_url(opt_arg(),
+ &tlscstatp.host,
+ &tlscstatp.port,
+ &tlscstatp.path, &tlscstatp.use_ssl)) {
+ BIO_printf(bio_err, "Error parsing URL\n");
+ goto end;
+ }
+ break;
+#endif
+ case OPT_MSG:
+ s_msg = 1;
+ break;
+ case OPT_MSGFILE:
+ bio_s_msg = BIO_new_file(opt_arg(), "w");
+ break;
+#ifndef OPENSSL_NO_SSL_TRACE
+ case OPT_TRACE:
+ s_msg = 2;
+ break;
+#else
+ case OPT_TRACE:
+ goto opthelp;
+#endif
+ case OPT_SECURITY_DEBUG:
+ sdebug = 1;
+ break;
+ case OPT_SECURITY_DEBUG_VERBOSE:
+ sdebug = 2;
+ break;
+ case OPT_STATE:
+ state = 1;
+ break;
+ case OPT_CRLF:
+ s_crlf = 1;
+ break;
+ case OPT_QUIET:
+ s_quiet = 1;
+ break;
+ case OPT_BRIEF:
+ s_quiet = s_brief = verify_quiet = 1;
+ break;
+ case OPT_NO_TMP_RSA:
+ no_tmp_rsa = 1;
+ break;
+ case OPT_NO_DHE:
+ no_dhe = 1;
+ break;
+ case OPT_NO_ECDHE:
+ no_ecdhe = 1;
+ break;
+ case OPT_NO_RESUME_EPHEMERAL:
+ no_resume_ephemeral = 1;
+ break;
+#ifndef OPENSSL_NO_PSK
+ case OPT_PSK_HINT:
+ psk_identity_hint = opt_arg();
+ break;
+ case OPT_PSK:
+ for (p = psk_key = opt_arg(); *p; p++) {
+ if (isxdigit(*p))
+ continue;
+ BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
+ goto end;
+ }
+ break;
+#endif
+#ifndef OPENSSL_NO_SRP
+ case OPT_SRPVFILE:
+ srp_verifier_file = opt_arg();
+ meth = TLSv1_server_method();
+ break;
+ case OPT_SRPUSERSEED:
+ srpuserseed = opt_arg();
+ meth = TLSv1_server_method();
+ break;
+#endif
+ case OPT_REV:
+ rev = 1;
+ break;
+ case OPT_WWW:
+ www = 1;
+ break;
+ case OPT_UPPER_WWW:
+ www = 2;
+ break;
+ case OPT_HTTP:
+ www = 3;
+ break;
+#ifndef OPENSSL_NO_SSL3
+ case OPT_SSL3:
+ meth = SSLv3_client_method();
+ break;
+#endif
+ case OPT_TLS1_2:
+ meth = TLSv1_2_client_method();
+ break;
+ case OPT_TLS1_1:
+ meth = TLSv1_1_client_method();
+ break;
+ case OPT_TLS1:
+ meth = TLSv1_client_method();
+ break;
+#ifndef OPENSSL_NO_DTLS1
+ case OPT_DTLS:
+ meth = DTLS_client_method();
+ socket_type = SOCK_DGRAM;
+ break;
+ case OPT_DTLS1:
+ meth = DTLSv1_client_method();
+ socket_type = SOCK_DGRAM;
+ break;
+ case OPT_DTLS1_2:
+ meth = DTLSv1_2_client_method();
+ socket_type = SOCK_DGRAM;
+ break;
+ case OPT_TIMEOUT:
+ enable_timeouts = 1;
+ break;
+ case OPT_MTU:
+ socket_mtu = atol(opt_arg());
+ break;
+ case OPT_CHAIN:
+ cert_chain = 1;
+ break;
+#endif
+ case OPT_ID_PREFIX:
+ session_id_prefix = opt_arg();
+ break;
+ case OPT_ENGINE:
+ e = setup_engine(opt_arg(), 1);
+ break;
+ case OPT_RAND:
+ inrand = opt_arg();
+ break;
+#ifndef OPENSSL_NO_TLSEXT
+ case OPT_SERVERNAME:
+ tlsextcbp.servername = opt_arg();
+ break;
+ case OPT_SERVERNAME_FATAL:
+ tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL;
+ break;
+ case OPT_CERT2:
+ s_cert_file2 = opt_arg();
+ break;
+ case OPT_KEY2:
+ s_key_file2 = opt_arg();
+ break;
+# ifndef OPENSSL_NO_NEXTPROTONEG
+ case OPT_NEXTPROTONEG:
+ next_proto_neg_in = opt_arg();
+ break;
+# endif
+ case OPT_ALPN:
+ alpn_in = opt_arg();
+ break;
+#endif
+#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
+ case OPT_JPAKE:
+ jpake_secret = opt_arg();
+ break;
+#else
+ case OPT_JPAKE:
+ goto opthelp;
+#endif
+ case OPT_KRB5SVC:
+ krb5svc = opt_arg();
+ break;
+ case OPT_KRBTAB:
+ krb5tab = opt_arg();
+ break;
+ case OPT_SRTP_PROFILES:
+ srtp_profiles = opt_arg();
+ break;
+ case OPT_KEYMATEXPORT:
+ keymatexportlabel = opt_arg();
+ break;
+ case OPT_KEYMATEXPORTLEN:
+ keymatexportlen = atoi(opt_arg());
+ break;
+ }
+ }
+ argc = opt_num_rest();
+ argv = opt_rest();