diff options
author | Rich Salz <rsalz@openssl.org> | 2015-04-24 15:26:15 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2015-04-24 15:26:15 -0400 |
commit | 7e1b7485706c2b11091b5fa897fe496a2faa56cc (patch) | |
tree | d008e38fda900d081a2496023625184c5c89a5ff /apps/s_server.c | |
parent | 53dd4ddf71ad79a64be934ca19445b1cf560adab (diff) |
Big apps cleanup (option-parsing, etc)
This is merges the old "rsalz-monolith" branch over to master. The biggest
change is that option parsing switch from cascasding 'else if strcmp("-foo")'
to a utility routine and somethin akin to getopt. Also, an error in the
command line no longer prints the full summary; use -help (or --help :)
for that. There have been many other changes and code-cleanup, see
bullet list below.
Special thanks to Matt for the long and detailed code review.
TEMPORARY:
For now, comment out CRYPTO_mem_leaks() at end of main
Tickets closed:
RT3515: Use 3DES in pkcs12 if built with no-rc2
RT1766: s_client -reconnect and -starttls broke
RT2932: Catch write errors
RT2604: port should be 'unsigned short'
RT2983: total_bytes undeclared #ifdef RENEG
RT1523: Add -nocert to fix output in x509 app
RT3508: Remove unused variable introduced by b09eb24
RT3511: doc fix; req default serial is random
RT1325,2973: Add more extensions to c_rehash
RT2119,3407: Updated to dgst.pod
RT2379: Additional typo fix
RT2693: Extra include of string.h
RT2880: HFS is case-insensitive filenames
RT3246: req command prints version number wrong
Other changes; incompatibilities marked with *:
Add SCSV support
Add -misalign to speed command
Make dhparam, dsaparam, ecparam, x509 output C in proper style
Make some internal ocsp.c functions void
Only display cert usages with -help in verify
Use global bio_err, remove "BIO*err" parameter from functions
For filenames, - always means stdin (or stdout as appropriate)
Add aliases for -des/aes "wrap" ciphers.
*Remove support for IISSGC (server gated crypto)
*The undocumented OCSP -header flag is now "-header name=value"
*Documented the OCSP -header flag
Reviewed-by: Matt Caswell <matt@openssl.org>
Diffstat (limited to 'apps/s_server.c')
-rw-r--r-- | apps/s_server.c | 1211 |
1 files changed, 567 insertions, 644 deletions
diff --git a/apps/s_server.c b/apps/s_server.c index 8e350c89d8..2aaa2cb7da 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1,4 +1,3 @@ -/* apps/s_server.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -199,7 +198,6 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context); static int www_body(char *hostname, int s, int stype, unsigned char *context); static int rev_body(char *hostname, int s, int stype, unsigned char *context); static void close_accept_socket(void); -static void sv_usage(void); static int init_ssl_connection(SSL *s); static void print_stats(BIO *bp, SSL_CTX *ctx); static int generate_session_id(const SSL *ssl, unsigned char *id, @@ -210,9 +208,7 @@ static void free_sessions(void); static DH *load_dh_param(const char *dhfile); #endif -#ifdef MONOLITH static void s_server_init(void); -#endif /* static int load_CA(SSL_CTX *ctx, char *file);*/ @@ -225,8 +221,6 @@ static int accept_socket = -1; #ifndef OPENSSL_NO_TLSEXT # define TEST_CERT2 "server2.pem" #endif -#undef PROG -#define PROG s_server_main extern int verify_depth, verify_return_error, verify_quiet; @@ -394,10 +388,10 @@ static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) #endif -#ifdef MONOLITH 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; @@ -405,208 +399,23 @@ static void s_server_init(void) s_cert_file = TEST_CERT; s_key_file = NULL; s_chain_file = NULL; -# ifndef OPENSSL_NO_TLSEXT +#ifndef OPENSSL_NO_TLSEXT s_cert_file2 = TEST_CERT2; s_key_file2 = NULL; ctx2 = NULL; -# endif -# ifdef FIONBIO +#endif s_nbio = 0; -# endif s_nbio_test = 0; ctx = NULL; www = 0; - bio_s_out = NULL; s_debug = 0; s_msg = 0; s_quiet = 0; s_brief = 0; -# ifndef OPENSSL_NO_ENGINE - engine_id = NULL; -# endif -} -#endif - -static void sv_usage(void) -{ - BIO_printf(bio_err, "usage: s_server [args ...]\n"); - BIO_printf(bio_err, "\n"); - BIO_printf(bio_err, - " -accept port - TCP/IP port to accept on (default is %d)\n", - PORT); - BIO_printf(bio_err, " -unix path - unix domain socket to accept on\n"); - BIO_printf(bio_err, - " -unlink - for -unix, unlink existing socket first\n"); - BIO_printf(bio_err, " -context arg - set session ID context\n"); - BIO_printf(bio_err, - " -verify arg - turn on peer certificate verification\n"); - BIO_printf(bio_err, - " -Verify arg - turn on peer certificate verification, must have a cert.\n"); - BIO_printf(bio_err, - " -verify_return_error - return verification errors\n"); - BIO_printf(bio_err, " -cert arg - certificate file to use\n"); - BIO_printf(bio_err, " (default is %s)\n", TEST_CERT); - BIO_printf(bio_err, - " -naccept arg - terminate after 'arg' connections\n"); -#ifndef OPENSSL_NO_TLSEXT - BIO_printf(bio_err, - " -serverinfo arg - PEM serverinfo file for certificate\n"); -#endif - BIO_printf(bio_err, - " -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n"); - BIO_printf(bio_err, - " -crl_check - check the peer certificate has not been revoked by its CA.\n" - " The CRL(s) are appended to the certificate file\n"); - BIO_printf(bio_err, - " -crl_check_all - check the peer certificate has not been revoked by its CA\n" - " or any other CRL in the CA chain. CRL(s) are appened to the\n" - " the certificate file.\n"); - BIO_printf(bio_err, - " -certform arg - certificate format (PEM or DER) PEM default\n"); - BIO_printf(bio_err, - " -key arg - Private Key file to use, in cert file if\n"); - BIO_printf(bio_err, " not specified (default is %s)\n", - TEST_CERT); - BIO_printf(bio_err, - " -keyform arg - key format (PEM, DER or ENGINE) PEM default\n"); - BIO_printf(bio_err, - " -pass arg - private key file pass phrase source\n"); - BIO_printf(bio_err, - " -dcert arg - second certificate file to use (usually for DSA)\n"); - BIO_printf(bio_err, - " -dcertform x - second certificate format (PEM or DER) PEM default\n"); - BIO_printf(bio_err, - " -dkey arg - second private key file to use (usually for DSA)\n"); - BIO_printf(bio_err, - " -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n"); - BIO_printf(bio_err, - " -dpass arg - second private key file pass phrase source\n"); - BIO_printf(bio_err, - " -dhparam arg - DH parameter file to use, in cert file if not specified\n"); - BIO_printf(bio_err, - " or a default set of parameters is used\n"); -#ifndef OPENSSL_NO_EC - BIO_printf(bio_err, - " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" - " Use \"openssl ecparam -list_curves\" for all names\n" - " (default is nistp256).\n"); -#endif -#ifdef FIONBIO - BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); -#endif - BIO_printf(bio_err, - " -nbio_test - test with the non-blocking test bio\n"); - BIO_printf(bio_err, - " -crlf - convert LF from terminal into CRLF\n"); - BIO_printf(bio_err, " -debug - Print more output\n"); - BIO_printf(bio_err, " -msg - Show protocol messages\n"); - BIO_printf(bio_err, " -state - Print the SSL states\n"); - BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); - BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); - BIO_printf(bio_err, - " -trusted_first - Use locally trusted CA's first when building trust chain\n"); - BIO_printf(bio_err, - " -no_alt_chains - only ever use the first certificate chain found\n"); - BIO_printf(bio_err, - " -nocert - Don't use any certificates (Anon-DH)\n"); - BIO_printf(bio_err, - " -cipher arg - play with 'openssl ciphers' to see what goes here\n"); - BIO_printf(bio_err, " -serverpref - Use server's cipher preferences\n"); - BIO_printf(bio_err, " -quiet - No server output\n"); - BIO_printf(bio_err, " -no_tmp_rsa - Do not generate a tmp RSA key\n"); -#ifndef OPENSSL_NO_PSK - BIO_printf(bio_err, " -psk_hint arg - PSK identity hint to use\n"); - BIO_printf(bio_err, " -psk arg - PSK in hex (without 0x)\n"); -# ifndef OPENSSL_NO_JPAKE - BIO_printf(bio_err, " -jpake arg - JPAKE secret to use\n"); -# endif -#endif -#ifndef OPENSSL_NO_SRP - BIO_printf(bio_err, " -srpvfile file - The verifier file for SRP\n"); - BIO_printf(bio_err, - " -srpuserseed string - A seed string for a default user salt.\n"); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - BIO_printf(bio_err, " -ssl3 - Just talk SSLv3\n"); -#endif - BIO_printf(bio_err, " -tls1_2 - Just talk TLSv1.2\n"); - BIO_printf(bio_err, " -tls1_1 - Just talk TLSv1.1\n"); - BIO_printf(bio_err, " -tls1 - Just talk TLSv1\n"); - BIO_printf(bio_err, " -dtls1 - Just talk DTLSv1\n"); - BIO_printf(bio_err, " -dtls1_2 - Just talk DTLSv1.2\n"); - BIO_printf(bio_err, " -timeout - Enable timeouts\n"); - BIO_printf(bio_err, " -mtu - Set link layer MTU\n"); - BIO_printf(bio_err, " -chain - Read a certificate chain\n"); - BIO_printf(bio_err, " -no_ssl3 - Just disable SSLv3\n"); - BIO_printf(bio_err, " -no_tls1 - Just disable TLSv1\n"); - BIO_printf(bio_err, " -no_tls1_1 - Just disable TLSv1.1\n"); - BIO_printf(bio_err, " -no_tls1_2 - Just disable TLSv1.2\n"); -#ifndef OPENSSL_NO_DH - BIO_printf(bio_err, " -no_dhe - Disable ephemeral DH\n"); -#endif -#ifndef OPENSSL_NO_EC - BIO_printf(bio_err, " -no_ecdhe - Disable ephemeral ECDH\n"); -#endif - BIO_printf(bio_err, - "-no_resume_ephemeral - Disable caching and tickets if ephemeral (EC)DH is used\n"); - BIO_printf(bio_err, " -bugs - Turn on SSL bug compatibility\n"); - BIO_printf(bio_err, - " -www - Respond to a 'GET /' with a status page\n"); - BIO_printf(bio_err, - " -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); - BIO_printf(bio_err, - " -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); - BIO_printf(bio_err, - " with the assumption it contains a complete HTTP response.\n"); #ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, - " -engine id - Initialise and use the specified engine\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"); - BIO_printf(bio_err, - " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); -# ifndef OPENSSL_NO_NEXTPROTONEG - BIO_printf(bio_err, - " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n"); -# endif -# ifndef OPENSSL_NO_SRTP - BIO_printf(bio_err, - " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); -# endif - BIO_printf(bio_err, - " -alpn arg - set the advertised protocols for the ALPN extension (comma-separated list)\n"); + engine_id = NULL; #endif - BIO_printf(bio_err, - " -keymatexport label - Export keying material using label\n"); - BIO_printf(bio_err, - " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); - BIO_printf(bio_err, - " -status - respond to certificate status requests\n"); - BIO_printf(bio_err, - " -status_verbose - enable status request verbose printout\n"); - BIO_printf(bio_err, - " -status_timeout n - status request responder timeout\n"); - BIO_printf(bio_err, " -status_url URL - status request fallback URL\n"); } static int local_argc = 0; @@ -705,8 +514,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl) num = num + num; /* double the size */ if (num < inl) num = inl; - wbuf = - (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); + wbuf = (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); if (!wbuf) return 0; OPENSSL_free(b->ptr); @@ -807,11 +615,10 @@ typedef struct tlsextstatusctx_st { char *host, *path, *port; int use_ssl; int timeout; - BIO *err; int verbose; } tlsextstatusctx; -static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 }; +static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, 0 }; /* * Certificate Status callback. This is called when a client includes a @@ -825,7 +632,6 @@ static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 }; 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; @@ -840,23 +646,24 @@ static int cert_status_cb(SSL *s, void *arg) STACK_OF(X509_EXTENSION) *exts; int ret = SSL_TLSEXT_ERR_NOACK; int i; + if (srctx->verbose) - BIO_puts(err, "cert_status: callback called\n"); + BIO_puts(bio_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_OPENSSL_STRING_value(aia, 0), &host, &port, &path, &use_ssl)) { - BIO_puts(err, "cert_status: can't parse AIA URL\n"); + BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); goto err; } if (srctx->verbose) - BIO_printf(err, "cert_status: AIA URL: %s\n", + BIO_printf(bio_err, "cert_status: AIA URL: %s\n", sk_OPENSSL_STRING_value(aia, 0)); } else { if (!srctx->host) { - BIO_puts(srctx->err, + BIO_puts(bio_err, "cert_status: no AIA and no default responder URL\n"); goto done; } @@ -872,7 +679,7 @@ static int cert_status_cb(SSL *s, void *arg) 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"); + BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n"); X509_STORE_CTX_cleanup(&inctx); goto done; } @@ -894,10 +701,10 @@ static int cert_status_cb(SSL *s, void *arg) if (!OCSP_REQUEST_add_ext(req, ext, -1)) goto err; } - resp = process_responder(err, req, host, path, port, use_ssl, NULL, + resp = process_responder(req, host, path, port, use_ssl, NULL, srctx->timeout); if (!resp) { - BIO_puts(err, "cert_status: error querying responder\n"); + BIO_puts(bio_err, "cert_status: error querying responder\n"); goto done; } rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); @@ -905,13 +712,13 @@ static int cert_status_cb(SSL *s, void *arg) 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); + BIO_puts(bio_err, "cert_status: ocsp response sent:\n"); + OCSP_RESPONSE_print(bio_err, resp, 2); } ret = SSL_TLSEXT_ERR_OK; done: if (ret != SSL_TLSEXT_ERR_OK) - ERR_print_errors(err); + ERR_print_errors(bio_err); if (aia) { OPENSSL_free(host); OPENSSL_free(path); @@ -995,14 +802,7 @@ static int not_resumable_sess_cb(SSL *s, int is_forward_secure) return is_forward_secure; } -int MAIN(int, char **); - -#ifndef OPENSSL_NO_JPAKE static char *jpake_secret = NULL; -# define no_jpake !jpake_secret -#else -# define no_jpake 1 -#endif #ifndef OPENSSL_NO_SRP static srpsrvparm srp_callback_parm; #endif @@ -1010,41 +810,214 @@ static srpsrvparm srp_callback_parm; static char *srtp_profiles = NULL; #endif -int MAIN(int argc, char *argv[]) +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_ENGINE, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT, + OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL, + OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM, + OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT, + OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT, + OPT_CAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE, + OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, + OPT_BUILD_CHAIN, OPT_CAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE, + OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_DEBUG, + OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE, OPT_STATUS_TIMEOUT, + OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE, OPT_SECURITY_DEBUG, + OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF, OPT_QUIET, + OPT_BRIEF, OPT_NO_TMP_RSA, OPT_NO_DHE, OPT_NO_ECDHE, + OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE, + OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, +#ifndef OPENSSL_NO_SSL3 + OPT_SSL3, +#endif + OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1, + OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_CHAIN, + OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL, + OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_JPAKE, + OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, + OPT_S_ENUM, + OPT_V_ENUM, + OPT_X_ENUM +} OPTION_CHOICE; + +OPTIONS s_server_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + + {"port", OPT_PORT, 'p'}, + {"accept", OPT_PORT, 'p', + "TCP/IP port to accept on (default is " PORT_STR ")"}, + {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"}, + {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"}, + {"context", OPT_CONTEXT, 's', "Set session ID context"}, + {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"}, + {"Verify", OPT_UPPER_V_VERIFY, 'n', + "Turn on peer certificate verification, must have a cert"}, + {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT}, + {"naccept", OPT_NACCEPT, 'p', "Terminate after pnum connections"}, +#ifndef OPENSSL_NO_TLSEXT + {"serverinfo", OPT_SERVERINFO, 's', + "PEM serverinfo file for certificate"}, +#endif + {"certform", OPT_CERTFORM, 'F', + "Certificate format (PEM or DER) PEM default"}, + {"key", OPT_KEY, '<', + "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)"}, + {"dcertform", OPT_DCERTFORM, 'F', + "Second certificate format (PEM or DER) PEM default"}, + {"dkey", OPT_DKEY, '<', + "Second private key file to use (usually for DSA)"}, + {"dkeyform", OPT_DKEYFORM, 'F', + "Second key format (PEM, DER or ENGINE) PEM default"}, + {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, +#ifdef FIONBIO + {"nbio", OPT_NBIO, '-', "Use non-blocking IO"}, +#endif + {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, + {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, + {"debug", OPT_DEBUG, '-', "Print more output"}, + {"msg", OPT_MSG, '-', "Show protocol messages"}, + {"msgfile", OPT_MSGFILE, '>'}, + {"state", OPT_STATE, '-', "Print the SSL states"}, + {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, + {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, + {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"}, + {"quiet", OPT_QUIET, '-', "No server output"}, + {"no_tmp_rsa", OPT_NO_TMP_RSA, '-', "Do not generate a tmp RSA key"}, +#ifndef OPENSSL_NO_PSK + {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"}, + {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"}, +# ifndef OPENSSL_NO_JPAKE + {"jpake", OPT_JPAKE, 's', "JPAKE secret to use"}, +# endif +#endif +#ifndef OPENSSL_NO_SRP + {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"}, + {"srpuserseed", OPT_SRPUSERSEED, 's', + "A seed string for a default user salt"}, +#endif +#ifndef OPENSSL_NO_SSL3 + {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"}, +#endif + {"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"}, + {"tls1_1", OPT_TLS1_1, '-', "Just talk TLSv1.1"}, + {"tls1", OPT_TLS1, '-', "Just talk TLSv1"}, +#ifndef OPENSSL_NO_DTLS1 + {"dtls", OPT_DTLS, '-'}, + {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"}, + {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"}, + {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"}, + {"mtu", OPT_MTU, 'p', "Set link layer MTU"}, + {"chain", OPT_CHAIN, '-', "Read a certificate chain"}, +#endif +#ifndef OPENSSL_NO_DH + {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"}, +#endif +#ifndef OPENSSL_NO_EC + {"no_ecdhe", OPT_NO_ECDHE, '-', "Disable ephemeral ECDH"}, +#endif + {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', + "Disable caching and tickets if ephemeral (EC)DH is used"}, + {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, + {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, + {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path incluedes HTTP headers"}, + {"id_prefix", OPT_ID_PREFIX, 's', + "Generate SSL/TLS session IDs prefixed by arg"}, + {"rand", OPT_RAND, 's', + "Load the file(s) into the random number generator"}, +#ifndef OPENSSL_NO_TLSEXT + {"servername", OPT_SERVERNAME, 's', + "Servername for HostName TLS extension"}, + {"servername_fatal", OPT_SERVERNAME_FATAL, '-', + "mismatch send fatal alert (default warning alert)"}, + {"cert2", OPT_CERT2, '<', + "Certificate file to use for servername; default is" TEST_CERT2}, + {"key2", OPT_KEY2, '<', + "-Private Key file to use for servername if not in -cert2"}, + {"tlsextdebug", OPT_TLSEXTDEBUG, '-', + "Hex dump of all TLS extensions received"}, +# ifndef OPENSSL_NO_NEXTPROTONEG + {"nextprotoneg", OPT_NEXTPROTONEG, 's', + "Set the advertised protocols for the NPN extension (comma-separated list)"}, +# endif + {"use_srtp", OPT_SRTP_PROFILES, '<', + "Offer SRTP key management with a colon-separated profile list"}, + {"alpn", OPT_ALPN, 's', + "Set the advertised protocols for the ALPN extension (comma-separated list)"}, +#endif + {"keymatexport", OPT_KEYMATEXPORT, 's', + "Export keying material using label"}, + {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', + "Export len bytes of keying material (default 20)"}, + {"CRL", OPT_CRL, '<'}, + {"crl_download", OPT_CRL_DOWNLOAD, '-'}, + {"cert_chain", OPT_CERT_CHAIN, '<'}, + {"dcert_chain", OPT_DCERT_CHAIN, '<'}, + {"chainCApath", OPT_CHAINCAPATH, '/'}, + {"verifyCApath", OPT_VERIFYCAPATH, '/'}, + {"no_cache", OPT_NO_CACHE, '-'}, + {"ext_cache", OPT_EXT_CACHE, '-'}, + {"CRLform", OPT_CRLFORM, 'F'}, + {"verify_return_error", OPT_VERIFY_RET_ERROR, '-'}, + {"verify_quiet", OPT_VERIFY_QUIET, '-'}, + {"build_chain", OPT_BUILD_CHAIN, '-'}, + {"chainCAfile", OPT_CHAINCAFILE, '<'}, + {"verifyCAfile", OPT_VERIFYCAFILE, '<'}, + {"ign_eof", OPT_IGN_EOF, '-'}, + {"no_ign_eof", OPT_NO_IGN_EOF, '-'}, + {"status", OPT_STATUS, '-'}, + {"status_verbose", OPT_STATUS_VERBOSE, '-'}, + {"status_timeout", OPT_STATUS_TIMEOUT, 'n'}, + {"status_url", OPT_STATUS_URL, 's'}, + {"trace", OPT_TRACE, '-'}, + {"security_debug", OPT_SECURITY_DEBUG, '-'}, + {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-'}, + {"brief", OPT_BRIEF, '-'}, + {"rev", OPT_REV, '-'}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's'}, +#endif + OPT_S_OPTIONS, + OPT_V_OPTIONS, + OPT_X_OPTIONS, + {NULL} +}; + +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; - int badarg = 0; - short port = PORT; + 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); - char *CApath = NULL, *CAfile = NULL; - char *chCApath = NULL, *chCAfile = NULL; - char *vfyCApath = NULL, *vfyCAfile = NULL; - unsigned char *context = NULL; - char *dhfile = NULL; - int badop = 0; - int ret = 1; - int build_chain = 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 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; - 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; - STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; - EVP_PKEY *s_key = NULL, *s_dkey = NULL; - int no_cache = 0, ext_cache = 0; - int rev = 0, naccept = -1; - int sdebug = 0; + 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; @@ -1064,449 +1037,394 @@ int MAIN(int argc, char *argv[]) char *srpuserseed = NULL; char *srp_verifier_file = NULL; #endif - SSL_EXCERT *exc = NULL; - SSL_CONF_CTX *cctx = NULL; - STACK_OF(OPENSSL_STRING) *ssl_args = NULL; - - char *crl_file = NULL; - int crl_format = FORMAT_PEM; - int crl_download = 0; - STACK_OF(X509_CRL) *crls = NULL; - - meth = SSLv23_server_method(); 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; - cctx = SSL_CONF_CTX_new(); - if (!cctx) + vpm = X509_VERIFY_PARAM_new(); + if (cctx == NULL || vpm == NULL) goto end; - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); - SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE); - - verify_depth = 0; -#ifdef FIONBIO - s_nbio = 0; -#endif - s_nbio_test = 0; - - argc--; - argv++; + 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; - 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, "-unix") == 0) { + 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 bad; + goto end; #else - if (--argc < 1) - goto bad; - unix_path = *(++argv); + unix_path = opt_arg(); #endif - } else if (strcmp(*argv, "-unlink") == 0) { + break; + case OPT_UNLINK: #ifdef NO_SYS_UN_H BIO_printf(bio_err, "unix domain sockets unsupported\n"); - goto bad; + goto end; #else unlink_unix_path = 1; #endif - } else if (strcmp(*argv, "-naccept") == 0) { - if (--argc < 1) - goto bad; - naccept = atol(*(++argv)); - if (naccept <= 0) { - BIO_printf(bio_err, "bad accept value %s\n", *argv); - goto bad; - } - } else if (strcmp(*argv, "-verify") == 0) { + break; + case OPT_NACCEPT: + naccept = atol(opt_arg()); + break; + case OPT_VERIFY: s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; - if (--argc < 1) - goto bad; - verify_depth = atoi(*(++argv)); + verify_depth = atoi(opt_arg()); if (!s_quiet) BIO_printf(bio_err, "verify depth is %d\n", verify_depth); - } else if (strcmp(*argv, "-Verify") == 0) { + break; + case OPT_UPPER_V_VERIFY: 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)); + verify_depth = atoi(opt_arg()); if (!s_quiet) 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, "-CRL") == 0) { - if (--argc < 1) - goto bad; - crl_file = *(++argv); - } else if (strcmp(*argv, "-crl_download") == 0) + 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 - else if (strcmp(*argv, "-serverinfo") == 0) { - if (--argc < 1) - goto bad; - s_serverinfo_file = *(++argv); - } + case OPT_SERVERINFO: + s_serverinfo_file = opt_arg(); + break; #endif - 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, "-cert_chain") == 0) { - if (--argc < 1) - goto bad; - s_chain_file = *(++argv); - } else if (strcmp(*argv, "-dhparam") == 0) { - if (--argc < 1) - goto bad; - dhfile = *(++argv); - } 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, "-dcert_chain") == 0) { - if (--argc < 1) - goto bad; - s_dchain_file = *(++argv); - } else if (strcmp(*argv, "-nocert") == 0) { + 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; - } else if (strcmp(*argv, "-CApath") == 0) { - if (--argc < 1) - goto bad; - CApath = *(++argv); - } else if (strcmp(*argv, "-chainCApath") == 0) { - if (--argc < 1) - goto bad; - chCApath = *(++argv); - } else if (strcmp(*argv, "-verifyCApath") == 0) { - if (--argc < 1) - goto bad; - vfyCApath = *(++argv); - } else if (strcmp(*argv, "-no_cache") == 0) + 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; - else if (strcmp(*argv, "-ext_cache") == 0) + break; + case OPT_EXT_C |