1*23cc9d40Stb /* $OpenBSD: s_server.c,v 1.61 2025/01/02 13:10:03 tb Exp $ */ 2dab3f910Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3dab3f910Sjsing * All rights reserved. 4dab3f910Sjsing * 5dab3f910Sjsing * This package is an SSL implementation written 6dab3f910Sjsing * by Eric Young (eay@cryptsoft.com). 7dab3f910Sjsing * The implementation was written so as to conform with Netscapes SSL. 8dab3f910Sjsing * 9dab3f910Sjsing * This library is free for commercial and non-commercial use as long as 10dab3f910Sjsing * the following conditions are aheared to. The following conditions 11dab3f910Sjsing * apply to all code found in this distribution, be it the RC4, RSA, 12dab3f910Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13dab3f910Sjsing * included with this distribution is covered by the same copyright terms 14dab3f910Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15dab3f910Sjsing * 16dab3f910Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in 17dab3f910Sjsing * the code are not to be removed. 18dab3f910Sjsing * If this package is used in a product, Eric Young should be given attribution 19dab3f910Sjsing * as the author of the parts of the library used. 20dab3f910Sjsing * This can be in the form of a textual message at program startup or 21dab3f910Sjsing * in documentation (online or textual) provided with the package. 22dab3f910Sjsing * 23dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 24dab3f910Sjsing * modification, are permitted provided that the following conditions 25dab3f910Sjsing * are met: 26dab3f910Sjsing * 1. Redistributions of source code must retain the copyright 27dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 28dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 29dab3f910Sjsing * notice, this list of conditions and the following disclaimer in the 30dab3f910Sjsing * documentation and/or other materials provided with the distribution. 31dab3f910Sjsing * 3. All advertising materials mentioning features or use of this software 32dab3f910Sjsing * must display the following acknowledgement: 33dab3f910Sjsing * "This product includes cryptographic software written by 34dab3f910Sjsing * Eric Young (eay@cryptsoft.com)" 35dab3f910Sjsing * The word 'cryptographic' can be left out if the rouines from the library 36dab3f910Sjsing * being used are not cryptographic related :-). 37dab3f910Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from 38dab3f910Sjsing * the apps directory (application code) you must include an acknowledgement: 39dab3f910Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40dab3f910Sjsing * 41dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42dab3f910Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44dab3f910Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45dab3f910Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46dab3f910Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47dab3f910Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49dab3f910Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50dab3f910Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51dab3f910Sjsing * SUCH DAMAGE. 52dab3f910Sjsing * 53dab3f910Sjsing * The licence and distribution terms for any publically available version or 54dab3f910Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 55dab3f910Sjsing * copied and put under another distribution licence 56dab3f910Sjsing * [including the GNU Public Licence.] 57dab3f910Sjsing */ 58dab3f910Sjsing /* ==================================================================== 59dab3f910Sjsing * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 60dab3f910Sjsing * 61dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 62dab3f910Sjsing * modification, are permitted provided that the following conditions 63dab3f910Sjsing * are met: 64dab3f910Sjsing * 65dab3f910Sjsing * 1. Redistributions of source code must retain the above copyright 66dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 67dab3f910Sjsing * 68dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 69dab3f910Sjsing * notice, this list of conditions and the following disclaimer in 70dab3f910Sjsing * the documentation and/or other materials provided with the 71dab3f910Sjsing * distribution. 72dab3f910Sjsing * 73dab3f910Sjsing * 3. All advertising materials mentioning features or use of this 74dab3f910Sjsing * software must display the following acknowledgment: 75dab3f910Sjsing * "This product includes software developed by the OpenSSL Project 76dab3f910Sjsing * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77dab3f910Sjsing * 78dab3f910Sjsing * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79dab3f910Sjsing * endorse or promote products derived from this software without 80dab3f910Sjsing * prior written permission. For written permission, please contact 81dab3f910Sjsing * openssl-core@openssl.org. 82dab3f910Sjsing * 83dab3f910Sjsing * 5. Products derived from this software may not be called "OpenSSL" 84dab3f910Sjsing * nor may "OpenSSL" appear in their names without prior written 85dab3f910Sjsing * permission of the OpenSSL Project. 86dab3f910Sjsing * 87dab3f910Sjsing * 6. Redistributions of any form whatsoever must retain the following 88dab3f910Sjsing * acknowledgment: 89dab3f910Sjsing * "This product includes software developed by the OpenSSL Project 90dab3f910Sjsing * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91dab3f910Sjsing * 92dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93dab3f910Sjsing * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95dab3f910Sjsing * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96dab3f910Sjsing * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97dab3f910Sjsing * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98dab3f910Sjsing * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99dab3f910Sjsing * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101dab3f910Sjsing * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102dab3f910Sjsing * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103dab3f910Sjsing * OF THE POSSIBILITY OF SUCH DAMAGE. 104dab3f910Sjsing * ==================================================================== 105dab3f910Sjsing * 106dab3f910Sjsing * This product includes cryptographic software written by Eric Young 107dab3f910Sjsing * (eay@cryptsoft.com). This product includes software written by Tim 108dab3f910Sjsing * Hudson (tjh@cryptsoft.com). 109dab3f910Sjsing * 110dab3f910Sjsing */ 111dab3f910Sjsing /* ==================================================================== 112dab3f910Sjsing * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113dab3f910Sjsing * ECC cipher suite support in OpenSSL originally developed by 114dab3f910Sjsing * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 115dab3f910Sjsing */ 116dab3f910Sjsing /* ==================================================================== 117dab3f910Sjsing * Copyright 2005 Nokia. All rights reserved. 118dab3f910Sjsing * 119dab3f910Sjsing * The portions of the attached software ("Contribution") is developed by 120dab3f910Sjsing * Nokia Corporation and is licensed pursuant to the OpenSSL open source 121dab3f910Sjsing * license. 122dab3f910Sjsing * 123dab3f910Sjsing * The Contribution, originally written by Mika Kousa and Pasi Eronen of 124dab3f910Sjsing * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 125dab3f910Sjsing * support (see RFC 4279) to OpenSSL. 126dab3f910Sjsing * 127dab3f910Sjsing * No patent licenses or other rights except those expressly stated in 128dab3f910Sjsing * the OpenSSL open source license shall be deemed granted or received 129dab3f910Sjsing * expressly, by implication, estoppel, or otherwise. 130dab3f910Sjsing * 131dab3f910Sjsing * No assurances are provided by Nokia that the Contribution does not 132dab3f910Sjsing * infringe the patent or other intellectual property rights of any third 133dab3f910Sjsing * party or that the license provides you with all the necessary rights 134dab3f910Sjsing * to make use of the Contribution. 135dab3f910Sjsing * 136dab3f910Sjsing * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 137dab3f910Sjsing * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 138dab3f910Sjsing * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 139dab3f910Sjsing * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 140dab3f910Sjsing * OTHERWISE. 141dab3f910Sjsing */ 142dab3f910Sjsing 143dab3f910Sjsing /* Until the key-gen callbacks are modified to use newer prototypes, we allow 144dab3f910Sjsing * deprecated functions for openssl-internal code */ 145dab3f910Sjsing #ifdef OPENSSL_NO_DEPRECATED 146dab3f910Sjsing #undef OPENSSL_NO_DEPRECATED 147dab3f910Sjsing #endif 148dab3f910Sjsing 149dab3f910Sjsing #include <sys/types.h> 150dab3f910Sjsing #include <sys/socket.h> 151dab3f910Sjsing 152dab3f910Sjsing #include <assert.h> 153dab3f910Sjsing #include <ctype.h> 154dab3f910Sjsing #include <stdio.h> 155dab3f910Sjsing #include <stdlib.h> 156dab3f910Sjsing #include <limits.h> 157dab3f910Sjsing #include <string.h> 158dab3f910Sjsing #include <unistd.h> 1599c8ea7b6Sderaadt #include <poll.h> 160dab3f910Sjsing 161dab3f910Sjsing #include "apps.h" 162dab3f910Sjsing 163dab3f910Sjsing #include <openssl/bn.h> 164dab3f910Sjsing #include <openssl/err.h> 165dab3f910Sjsing #include <openssl/lhash.h> 166dab3f910Sjsing #include <openssl/ocsp.h> 167dab3f910Sjsing #include <openssl/pem.h> 168dab3f910Sjsing #include <openssl/ssl.h> 169dab3f910Sjsing #include <openssl/x509.h> 170dab3f910Sjsing 171dab3f910Sjsing #ifndef OPENSSL_NO_DH 172dab3f910Sjsing #include <openssl/dh.h> 173dab3f910Sjsing #endif 174dab3f910Sjsing 175dab3f910Sjsing #include <openssl/rsa.h> 176dab3f910Sjsing 17772a107cfSinoguchi static void s_server_init(void); 178dab3f910Sjsing static void sv_usage(void); 179dab3f910Sjsing static void print_stats(BIO *bp, SSL_CTX *ctx); 1807537a7c2Stb static int sv_body(int s, unsigned char *context); 18172a107cfSinoguchi static void close_accept_socket(void); 18272a107cfSinoguchi static int init_ssl_connection(SSL *s); 183dab3f910Sjsing #ifndef OPENSSL_NO_DH 184dab3f910Sjsing static DH *load_dh_param(const char *dhfile); 185dab3f910Sjsing #endif 1867537a7c2Stb static int www_body(int s, unsigned char *context); 18772a107cfSinoguchi static int generate_session_id(const SSL *ssl, unsigned char *id, 18872a107cfSinoguchi unsigned int *id_len); 18972a107cfSinoguchi static int ssl_servername_cb(SSL *s, int *ad, void *arg); 19072a107cfSinoguchi static int cert_status_cb(SSL * s, void *arg); 19172a107cfSinoguchi static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, 19272a107cfSinoguchi const unsigned char *in, unsigned int inlen, void *arg); 193dab3f910Sjsing /* static int load_CA(SSL_CTX *ctx, char *file);*/ 194dab3f910Sjsing 195dab3f910Sjsing #define BUFSIZZ 16*1024 196dab3f910Sjsing static int bufsize = BUFSIZZ; 197dab3f910Sjsing static int accept_socket = -1; 198dab3f910Sjsing 199dab3f910Sjsing #define TEST_CERT "server.pem" 200dab3f910Sjsing #define TEST_CERT2 "server2.pem" 201dab3f910Sjsing 202dab3f910Sjsing static int s_server_session_id_context = 1; /* anything will do */ 203dab3f910Sjsing static SSL_CTX *ctx = NULL; 204dab3f910Sjsing static SSL_CTX *ctx2 = NULL; 205dab3f910Sjsing static BIO *bio_s_out = NULL; 20672a107cfSinoguchi 20772a107cfSinoguchi static int local_argc = 0; 20872a107cfSinoguchi static char **local_argv; 209dab3f910Sjsing 210dab3f910Sjsing /* This is a context that we pass to callbacks */ 211dab3f910Sjsing typedef struct tlsextctx_st { 212dab3f910Sjsing char *servername; 213dab3f910Sjsing BIO *biodebug; 214dab3f910Sjsing int extension_error; 215dab3f910Sjsing } tlsextctx; 216dab3f910Sjsing 2175a233072Sinoguchi /* Structure passed to cert status callback */ 2185a233072Sinoguchi typedef struct tlsextstatusctx_st { 2195a233072Sinoguchi /* Default responder to use */ 2205a233072Sinoguchi char *host, *path, *port; 2215a233072Sinoguchi int use_ssl; 2225a233072Sinoguchi int timeout; 2235a233072Sinoguchi BIO *err; 2245a233072Sinoguchi int verbose; 2255a233072Sinoguchi } tlsextstatusctx; 2265a233072Sinoguchi 22772a107cfSinoguchi /* This the context that we pass to alpn_cb */ 22872a107cfSinoguchi typedef struct tlsextalpnctx_st { 22972a107cfSinoguchi unsigned char *data; 23072a107cfSinoguchi unsigned short len; 23172a107cfSinoguchi } tlsextalpnctx; 23272a107cfSinoguchi 2335a233072Sinoguchi static struct { 2345a233072Sinoguchi char *alpn_in; 2355a233072Sinoguchi char *npn_in; /* Ignored. */ 2365a233072Sinoguchi int bugs; 2375a233072Sinoguchi char *CAfile; 2385a233072Sinoguchi char *CApath; 23993dafd19Sjsing #ifndef OPENSSL_NO_DTLS 2405a233072Sinoguchi int cert_chain; 2415a233072Sinoguchi #endif 2420e15fe22Sinoguchi char *cert_file; 2430e15fe22Sinoguchi char *cert_file2; 2440e15fe22Sinoguchi int cert_format; 2455a233072Sinoguchi char *cipher; 2465a233072Sinoguchi unsigned char *context; 2470e15fe22Sinoguchi int crlf; 2480e15fe22Sinoguchi char *dcert_file; 2490e15fe22Sinoguchi int dcert_format; 2500e15fe22Sinoguchi int debug; 2515a233072Sinoguchi char *dhfile; 2520e15fe22Sinoguchi char *dkey_file; 2530e15fe22Sinoguchi int dkey_format; 2545a233072Sinoguchi char *dpassarg; 2555a233072Sinoguchi int enable_timeouts; 2565a233072Sinoguchi const char *errstr; 2575a233072Sinoguchi char *groups_in; 2580e15fe22Sinoguchi char *key_file; 2590e15fe22Sinoguchi char *key_file2; 2600e15fe22Sinoguchi int key_format; 2615a233072Sinoguchi char *keymatexportlabel; 2625a233072Sinoguchi int keymatexportlen; 2635a233072Sinoguchi uint16_t max_version; 2645a233072Sinoguchi uint16_t min_version; 2655a233072Sinoguchi const SSL_METHOD *meth; 2660e15fe22Sinoguchi int msg; 26713017aedStb int naccept; 2685a233072Sinoguchi char *named_curve; 2690e15fe22Sinoguchi int nbio; 2700e15fe22Sinoguchi int nbio_test; 2715a233072Sinoguchi int no_cache; 2725a233072Sinoguchi int nocert; 2735a233072Sinoguchi int no_dhe; 2745a233072Sinoguchi int no_ecdhe; 2755a233072Sinoguchi int no_tmp_rsa; /* No-op. */ 2765a233072Sinoguchi int off; 2775a233072Sinoguchi char *passarg; 2785a233072Sinoguchi short port; 2790e15fe22Sinoguchi int quiet; 2800e15fe22Sinoguchi int server_verify; 2815a233072Sinoguchi char *session_id_prefix; 2825a233072Sinoguchi long socket_mtu; 2835a233072Sinoguchi int socket_type; 2845a233072Sinoguchi #ifndef OPENSSL_NO_SRTP 2855a233072Sinoguchi char *srtp_profiles; 2865a233072Sinoguchi #endif 2875a233072Sinoguchi int state; 2885a233072Sinoguchi tlsextstatusctx tlscstatp; 2895a233072Sinoguchi tlsextctx tlsextcbp; 2900e15fe22Sinoguchi int tlsextdebug; 2910e15fe22Sinoguchi int tlsextstatus; 2925a233072Sinoguchi X509_VERIFY_PARAM *vpm; 2935a233072Sinoguchi int www; 294e7718adaStb } cfg; 2955a233072Sinoguchi 2965a233072Sinoguchi static int 2975a233072Sinoguchi s_server_opt_context(char *arg) 2985a233072Sinoguchi { 299e7718adaStb cfg.context = (unsigned char *) arg; 3005a233072Sinoguchi return (0); 3015a233072Sinoguchi } 3025a233072Sinoguchi 3035a233072Sinoguchi static int 3045a233072Sinoguchi s_server_opt_keymatexportlen(char *arg) 3055a233072Sinoguchi { 306e7718adaStb cfg.keymatexportlen = strtonum(arg, 1, INT_MAX, 307e7718adaStb &cfg.errstr); 308e7718adaStb if (cfg.errstr != NULL) { 3095a233072Sinoguchi BIO_printf(bio_err, "invalid argument %s: %s\n", 310e7718adaStb arg, cfg.errstr); 3115a233072Sinoguchi return (1); 3125a233072Sinoguchi } 3135a233072Sinoguchi return (0); 3145a233072Sinoguchi } 3155a233072Sinoguchi 31693dafd19Sjsing #ifndef OPENSSL_NO_DTLS 3175a233072Sinoguchi static int 3185a233072Sinoguchi s_server_opt_mtu(char *arg) 3195a233072Sinoguchi { 320e7718adaStb cfg.socket_mtu = strtonum(arg, 0, LONG_MAX, 321e7718adaStb &cfg.errstr); 322e7718adaStb if (cfg.errstr != NULL) { 3235a233072Sinoguchi BIO_printf(bio_err, "invalid argument %s: %s\n", 324e7718adaStb arg, cfg.errstr); 3255a233072Sinoguchi return (1); 3265a233072Sinoguchi } 3275a233072Sinoguchi return (0); 3285a233072Sinoguchi } 32993dafd19Sjsing #endif 3305a233072Sinoguchi 33193dafd19Sjsing #ifndef OPENSSL_NO_DTLS 3325a233072Sinoguchi static int 33393dafd19Sjsing s_server_opt_protocol_version_dtls(void) 3345a233072Sinoguchi { 335e7718adaStb cfg.meth = DTLS_server_method(); 336e7718adaStb cfg.socket_type = SOCK_DGRAM; 3375a233072Sinoguchi return (0); 3385a233072Sinoguchi } 3395a233072Sinoguchi #endif 3405a233072Sinoguchi 34193dafd19Sjsing #ifndef OPENSSL_NO_DTLS1_2 34293dafd19Sjsing static int 34393dafd19Sjsing s_server_opt_protocol_version_dtls1_2(void) 34493dafd19Sjsing { 345e7718adaStb cfg.meth = DTLS_server_method(); 346e7718adaStb cfg.min_version = DTLS1_2_VERSION; 347e7718adaStb cfg.max_version = DTLS1_2_VERSION; 348e7718adaStb cfg.socket_type = SOCK_DGRAM; 34993dafd19Sjsing return (0); 35093dafd19Sjsing } 35193dafd19Sjsing #endif 35293dafd19Sjsing 3535a233072Sinoguchi static int 35435ffcbeaSjsing s_server_opt_protocol_version_tls1_2(void) 3555a233072Sinoguchi { 356e7718adaStb cfg.min_version = TLS1_2_VERSION; 357e7718adaStb cfg.max_version = TLS1_2_VERSION; 3585a233072Sinoguchi return (0); 3595a233072Sinoguchi } 3605a233072Sinoguchi 3615a233072Sinoguchi static int 36235ffcbeaSjsing s_server_opt_protocol_version_tls1_3(void) 3635a233072Sinoguchi { 364e7718adaStb cfg.min_version = TLS1_3_VERSION; 365e7718adaStb cfg.max_version = TLS1_3_VERSION; 3665a233072Sinoguchi return (0); 3675a233072Sinoguchi } 3685a233072Sinoguchi 3695a233072Sinoguchi static int 3705a233072Sinoguchi s_server_opt_nbio_test(void) 3715a233072Sinoguchi { 372e7718adaStb cfg.nbio = 1; 373e7718adaStb cfg.nbio_test = 1; 3745a233072Sinoguchi return (0); 3755a233072Sinoguchi } 3765a233072Sinoguchi 3775a233072Sinoguchi static int 3785a233072Sinoguchi s_server_opt_port(char *arg) 3795a233072Sinoguchi { 380e7718adaStb if (!extract_port(arg, &cfg.port)) 3815a233072Sinoguchi return (1); 3825a233072Sinoguchi return (0); 3835a233072Sinoguchi } 3845a233072Sinoguchi 3855a233072Sinoguchi static int 3865a233072Sinoguchi s_server_opt_status_timeout(char *arg) 3875a233072Sinoguchi { 388e7718adaStb cfg.tlsextstatus = 1; 389e7718adaStb cfg.tlscstatp.timeout = strtonum(arg, 0, INT_MAX, 390e7718adaStb &cfg.errstr); 391e7718adaStb if (cfg.errstr != NULL) { 3925a233072Sinoguchi BIO_printf(bio_err, "invalid argument %s: %s\n", 393e7718adaStb arg, cfg.errstr); 3945a233072Sinoguchi return (1); 3955a233072Sinoguchi } 3965a233072Sinoguchi return (0); 3975a233072Sinoguchi } 3985a233072Sinoguchi 3995a233072Sinoguchi static int 4005a233072Sinoguchi s_server_opt_status_url(char *arg) 4015a233072Sinoguchi { 402e7718adaStb cfg.tlsextstatus = 1; 403e7718adaStb if (!OCSP_parse_url(arg, &cfg.tlscstatp.host, 404e7718adaStb &cfg.tlscstatp.port, &cfg.tlscstatp.path, 405e7718adaStb &cfg.tlscstatp.use_ssl)) { 4065a233072Sinoguchi BIO_printf(bio_err, "Error parsing URL\n"); 4075a233072Sinoguchi return (1); 4085a233072Sinoguchi } 4095a233072Sinoguchi return (0); 4105a233072Sinoguchi } 4115a233072Sinoguchi 4125a233072Sinoguchi static int 4135a233072Sinoguchi s_server_opt_status_verbose(void) 4145a233072Sinoguchi { 415e7718adaStb cfg.tlsextstatus = 1; 416e7718adaStb cfg.tlscstatp.verbose = 1; 4175a233072Sinoguchi return (0); 4185a233072Sinoguchi } 4195a233072Sinoguchi 4205a233072Sinoguchi static int 4215a233072Sinoguchi s_server_opt_verify(char *arg) 4225a233072Sinoguchi { 423e7718adaStb cfg.server_verify = SSL_VERIFY_PEER | 4245a233072Sinoguchi SSL_VERIFY_CLIENT_ONCE; 425e7718adaStb verify_depth = strtonum(arg, 0, INT_MAX, &cfg.errstr); 426e7718adaStb if (cfg.errstr != NULL) { 4275a233072Sinoguchi BIO_printf(bio_err, "invalid argument %s: %s\n", 428e7718adaStb arg, cfg.errstr); 4295a233072Sinoguchi return (1); 4305a233072Sinoguchi } 4315a233072Sinoguchi BIO_printf(bio_err, "verify depth is %d\n", verify_depth); 4325a233072Sinoguchi return (0); 4335a233072Sinoguchi } 4345a233072Sinoguchi 4355a233072Sinoguchi static int 4365a233072Sinoguchi s_server_opt_verify_fail(char *arg) 4375a233072Sinoguchi { 438e7718adaStb cfg.server_verify = SSL_VERIFY_PEER | 4395a233072Sinoguchi SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE; 440e7718adaStb verify_depth = strtonum(arg, 0, INT_MAX, &cfg.errstr); 441e7718adaStb if (cfg.errstr != NULL) { 4425a233072Sinoguchi BIO_printf(bio_err, "invalid argument %s: %s\n", 443e7718adaStb arg, cfg.errstr); 4445a233072Sinoguchi return (1); 4455a233072Sinoguchi } 4465a233072Sinoguchi BIO_printf(bio_err, "verify depth is %d, must return a certificate\n", 4475a233072Sinoguchi verify_depth); 4485a233072Sinoguchi return (0); 4495a233072Sinoguchi } 4505a233072Sinoguchi 4515a233072Sinoguchi static int 4525a233072Sinoguchi s_server_opt_verify_param(int argc, char **argv, int *argsused) 4535a233072Sinoguchi { 4545a233072Sinoguchi char **pargs = argv; 4555a233072Sinoguchi int pargc = argc; 4565a233072Sinoguchi int badarg = 0; 4575a233072Sinoguchi 4585a233072Sinoguchi if (!args_verify(&pargs, &pargc, &badarg, bio_err, 459e7718adaStb &cfg.vpm)) { 4605a233072Sinoguchi BIO_printf(bio_err, "unknown option %s\n", *argv); 4615a233072Sinoguchi return (1); 4625a233072Sinoguchi } 4635a233072Sinoguchi if (badarg) 4645a233072Sinoguchi return (1); 4655a233072Sinoguchi 4665a233072Sinoguchi *argsused = argc - pargc; 4675a233072Sinoguchi return (0); 4685a233072Sinoguchi } 4695a233072Sinoguchi 4705a233072Sinoguchi static const struct option s_server_options[] = { 4715a233072Sinoguchi { 47280b7bf82Stb .name = "4", 47380b7bf82Stb .type = OPTION_DISCARD, 47480b7bf82Stb }, 47580b7bf82Stb { 47680b7bf82Stb .name = "6", 47780b7bf82Stb .type = OPTION_DISCARD, 47880b7bf82Stb }, 47980b7bf82Stb { 4805a233072Sinoguchi .name = "accept", 4815a233072Sinoguchi .argname = "port", 4825a233072Sinoguchi .desc = "Port to accept on (default is 4433)", 4835a233072Sinoguchi .type = OPTION_ARG_FUNC, 4845a233072Sinoguchi .opt.argfunc = s_server_opt_port, 4855a233072Sinoguchi }, 4865a233072Sinoguchi { 4875a233072Sinoguchi .name = "alpn", 4885a233072Sinoguchi .argname = "protocols", 4895a233072Sinoguchi .desc = "Set the advertised protocols for the ALPN extension" 4905a233072Sinoguchi " (comma-separated list)", 4915a233072Sinoguchi .type = OPTION_ARG, 492e7718adaStb .opt.arg = &cfg.alpn_in, 4935a233072Sinoguchi }, 4945a233072Sinoguchi { 4955a233072Sinoguchi .name = "bugs", 4965a233072Sinoguchi .desc = "Turn on SSL bug compatibility", 4975a233072Sinoguchi .type = OPTION_FLAG, 498e7718adaStb .opt.flag = &cfg.bugs, 4995a233072Sinoguchi }, 5005a233072Sinoguchi { 5015a233072Sinoguchi .name = "CAfile", 5025a233072Sinoguchi .argname = "file", 5035a233072Sinoguchi .desc = "PEM format file of CA certificates", 5045a233072Sinoguchi .type = OPTION_ARG, 505e7718adaStb .opt.arg = &cfg.CAfile, 5065a233072Sinoguchi }, 5075a233072Sinoguchi { 5085a233072Sinoguchi .name = "CApath", 5095a233072Sinoguchi .argname = "directory", 5105a233072Sinoguchi .desc = "PEM format directory of CA certificates", 5115a233072Sinoguchi .type = OPTION_ARG, 512e7718adaStb .opt.arg = &cfg.CApath, 5135a233072Sinoguchi }, 5145a233072Sinoguchi { 5155a233072Sinoguchi .name = "cert", 5165a233072Sinoguchi .argname = "file", 5175a233072Sinoguchi .desc = "Certificate file to use\n" 5185a233072Sinoguchi "(default is " TEST_CERT ")", 5195a233072Sinoguchi .type = OPTION_ARG, 520e7718adaStb .opt.arg = &cfg.cert_file, 5215a233072Sinoguchi }, 5225a233072Sinoguchi { 5235a233072Sinoguchi .name = "cert2", 5245a233072Sinoguchi .argname = "file", 5255a233072Sinoguchi .desc = "Certificate file to use for servername\n" 5265a233072Sinoguchi "(default is " TEST_CERT2 ")", 5275a233072Sinoguchi .type = OPTION_ARG, 528e7718adaStb .opt.arg = &cfg.cert_file2, 5295a233072Sinoguchi }, 5305a233072Sinoguchi { 5315a233072Sinoguchi .name = "certform", 5325a233072Sinoguchi .argname = "fmt", 5335a233072Sinoguchi .desc = "Certificate format (PEM or DER) PEM default", 5345a233072Sinoguchi .type = OPTION_ARG_FORMAT, 535e7718adaStb .opt.value = &cfg.cert_format, 5365a233072Sinoguchi }, 53793dafd19Sjsing #ifndef OPENSSL_NO_DTLS 5385a233072Sinoguchi { 5395a233072Sinoguchi .name = "chain", 5405a233072Sinoguchi .type = OPTION_FLAG, 541e7718adaStb .opt.flag = &cfg.cert_chain, 5425a233072Sinoguchi }, 5435a233072Sinoguchi #endif 5445a233072Sinoguchi { 5455a233072Sinoguchi .name = "cipher", 5465a233072Sinoguchi .argname = "list", 5475a233072Sinoguchi .desc = "List of ciphers to enable (see `openssl ciphers`)", 5485a233072Sinoguchi .type = OPTION_ARG, 549e7718adaStb .opt.arg = &cfg.cipher, 5505a233072Sinoguchi }, 5515a233072Sinoguchi { 5525a233072Sinoguchi .name = "context", 5535a233072Sinoguchi .argname = "id", 5545a233072Sinoguchi .desc = "Set session ID context", 5555a233072Sinoguchi .type = OPTION_ARG_FUNC, 5565a233072Sinoguchi .opt.argfunc = s_server_opt_context, 5575a233072Sinoguchi }, 5585a233072Sinoguchi { 5595a233072Sinoguchi .name = "crlf", 5605a233072Sinoguchi .desc = "Convert LF from terminal into CRLF", 5615a233072Sinoguchi .type = OPTION_FLAG, 562e7718adaStb .opt.flag = &cfg.crlf, 5635a233072Sinoguchi }, 5645a233072Sinoguchi { 5655a233072Sinoguchi .name = "dcert", 5665a233072Sinoguchi .argname = "file", 5675a233072Sinoguchi .desc = "Second certificate file to use (usually for DSA)", 5685a233072Sinoguchi .type = OPTION_ARG, 569e7718adaStb .opt.arg = &cfg.dcert_file, 5705a233072Sinoguchi }, 5715a233072Sinoguchi { 5725a233072Sinoguchi .name = "dcertform", 5735a233072Sinoguchi .argname = "fmt", 5745a233072Sinoguchi .desc = "Second certificate format (PEM or DER) PEM default", 5755a233072Sinoguchi .type = OPTION_ARG_FORMAT, 576e7718adaStb .opt.value = &cfg.dcert_format, 5775a233072Sinoguchi }, 5785a233072Sinoguchi { 5795a233072Sinoguchi .name = "debug", 5805a233072Sinoguchi .desc = "Print more output", 5815a233072Sinoguchi .type = OPTION_FLAG, 582e7718adaStb .opt.flag = &cfg.debug, 5835a233072Sinoguchi }, 5845a233072Sinoguchi { 5855a233072Sinoguchi .name = "dhparam", 5865a233072Sinoguchi .argname = "file", 5875a233072Sinoguchi .desc = "DH parameter file to use, in cert file if not specified", 5885a233072Sinoguchi .type = OPTION_ARG, 589e7718adaStb .opt.arg = &cfg.dhfile, 5905a233072Sinoguchi }, 5915a233072Sinoguchi { 5925a233072Sinoguchi .name = "dkey", 5935a233072Sinoguchi .argname = "file", 5945a233072Sinoguchi .desc = "Second private key file to use (usually for DSA)", 5955a233072Sinoguchi .type = OPTION_ARG, 596e7718adaStb .opt.arg = &cfg.dkey_file, 5975a233072Sinoguchi }, 5985a233072Sinoguchi { 5995a233072Sinoguchi .name = "dkeyform", 6005a233072Sinoguchi .argname = "fmt", 6015a233072Sinoguchi .desc = "Second key format (PEM or DER) PEM default", 6025a233072Sinoguchi .type = OPTION_ARG_FORMAT, 603e7718adaStb .opt.value = &cfg.dkey_format, 6045a233072Sinoguchi }, 6055a233072Sinoguchi { 6065a233072Sinoguchi .name = "dpass", 6075a233072Sinoguchi .argname = "arg", 6085a233072Sinoguchi .desc = "Second private key file pass phrase source", 6095a233072Sinoguchi .type = OPTION_ARG, 610e7718adaStb .opt.arg = &cfg.dpassarg, 6115a233072Sinoguchi }, 61293dafd19Sjsing #ifndef OPENSSL_NO_DTLS 61393dafd19Sjsing { 61493dafd19Sjsing .name = "dtls", 61593dafd19Sjsing .desc = "Use any version of DTLS", 61693dafd19Sjsing .type = OPTION_FUNC, 61793dafd19Sjsing .opt.func = s_server_opt_protocol_version_dtls, 61893dafd19Sjsing }, 61993dafd19Sjsing #endif 62093dafd19Sjsing #ifndef OPENSSL_NO_DTLS1_2 62193dafd19Sjsing { 62293dafd19Sjsing .name = "dtls1_2", 62393dafd19Sjsing .desc = "Just use DTLSv1.2", 62493dafd19Sjsing .type = OPTION_FUNC, 62593dafd19Sjsing .opt.func = s_server_opt_protocol_version_dtls1_2, 6265a233072Sinoguchi }, 6275a233072Sinoguchi #endif 6285a233072Sinoguchi { 6295a233072Sinoguchi .name = "groups", 6305a233072Sinoguchi .argname = "list", 6315a233072Sinoguchi .desc = "Specify EC groups (colon-separated list)", 6325a233072Sinoguchi .type = OPTION_ARG, 633e7718adaStb .opt.arg = &cfg.groups_in, 6345a233072Sinoguchi }, 6355a233072Sinoguchi { 6365a233072Sinoguchi .name = "HTTP", 6375a233072Sinoguchi .desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>", 6385a233072Sinoguchi .type = OPTION_VALUE, 639e7718adaStb .opt.value = &cfg.www, 6405a233072Sinoguchi .value = 3, 6415a233072Sinoguchi }, 6425a233072Sinoguchi { 6435a233072Sinoguchi .name = "id_prefix", 6445a233072Sinoguchi .argname = "arg", 6455a233072Sinoguchi .desc = "Generate SSL/TLS session IDs prefixed by 'arg'", 6465a233072Sinoguchi .type = OPTION_ARG, 647e7718adaStb .opt.arg = &cfg.session_id_prefix, 6485a233072Sinoguchi }, 6495a233072Sinoguchi { 6505a233072Sinoguchi .name = "key", 6515a233072Sinoguchi .argname = "file", 6525a233072Sinoguchi .desc = "Private Key file to use, in cert file if\n" 6535a233072Sinoguchi "not specified (default is " TEST_CERT ")", 6545a233072Sinoguchi .type = OPTION_ARG, 655e7718adaStb .opt.arg = &cfg.key_file, 6565a233072Sinoguchi }, 6575a233072Sinoguchi { 6585a233072Sinoguchi .name = "key2", 6595a233072Sinoguchi .argname = "file", 6605a233072Sinoguchi .desc = "Private Key file to use for servername, in cert file if\n" 6615a233072Sinoguchi "not specified (default is " TEST_CERT2 ")", 6625a233072Sinoguchi .type = OPTION_ARG, 663e7718adaStb .opt.arg = &cfg.key_file2, 6645a233072Sinoguchi }, 6655a233072Sinoguchi { 6665a233072Sinoguchi .name = "keyform", 6675a233072Sinoguchi .argname = "fmt", 6685a233072Sinoguchi .desc = "Key format (PEM or DER) PEM default", 6695a233072Sinoguchi .type = OPTION_ARG_FORMAT, 670e7718adaStb .opt.value = &cfg.key_format, 6715a233072Sinoguchi }, 6725a233072Sinoguchi { 6735a233072Sinoguchi .name = "keymatexport", 6745a233072Sinoguchi .argname = "label", 6755a233072Sinoguchi .desc = "Export keying material using label", 6765a233072Sinoguchi .type = OPTION_ARG, 677e7718adaStb .opt.arg = &cfg.keymatexportlabel, 6785a233072Sinoguchi }, 6795a233072Sinoguchi { 6805a233072Sinoguchi .name = "keymatexportlen", 6815a233072Sinoguchi .argname = "len", 6825a233072Sinoguchi .desc = "Export len bytes of keying material (default 20)", 6835a233072Sinoguchi .type = OPTION_ARG_FUNC, 6845a233072Sinoguchi .opt.argfunc = s_server_opt_keymatexportlen, 6855a233072Sinoguchi }, 6865a233072Sinoguchi { 6875a233072Sinoguchi .name = "legacy_renegotiation", 6885a233072Sinoguchi .type = OPTION_DISCARD, 6895a233072Sinoguchi }, 6905a233072Sinoguchi { 6915a233072Sinoguchi .name = "msg", 6925a233072Sinoguchi .desc = "Show protocol messages", 6935a233072Sinoguchi .type = OPTION_FLAG, 694e7718adaStb .opt.flag = &cfg.msg, 6955a233072Sinoguchi }, 69693dafd19Sjsing #ifndef OPENSSL_NO_DTLS 6975a233072Sinoguchi { 6985a233072Sinoguchi .name = "mtu", 6995a233072Sinoguchi .argname = "mtu", 7005a233072Sinoguchi .desc = "Set link layer MTU", 7015a233072Sinoguchi .type = OPTION_ARG_FUNC, 7025a233072Sinoguchi .opt.argfunc = s_server_opt_mtu, 7035a233072Sinoguchi }, 7045a233072Sinoguchi #endif 7055a233072Sinoguchi { 70613017aedStb .name = "naccept", 70713017aedStb .argname = "num", 708a574f8cbStb .desc = "Terminate after num connections", 70913017aedStb .type = OPTION_ARG_INT, 710e7718adaStb .opt.value = &cfg.naccept 71113017aedStb }, 71213017aedStb { 7135a233072Sinoguchi .name = "named_curve", 7145a233072Sinoguchi .argname = "arg", 7155a233072Sinoguchi .type = OPTION_ARG, 716e7718adaStb .opt.arg = &cfg.named_curve, 7175a233072Sinoguchi }, 7185a233072Sinoguchi { 7195a233072Sinoguchi .name = "nbio", 7205a233072Sinoguchi .desc = "Run with non-blocking I/O", 7215a233072Sinoguchi .type = OPTION_FLAG, 722e7718adaStb .opt.flag = &cfg.nbio, 7235a233072Sinoguchi }, 7245a233072Sinoguchi { 7255a233072Sinoguchi .name = "nbio_test", 7265a233072Sinoguchi .desc = "Test with the non-blocking test bio", 7275a233072Sinoguchi .type = OPTION_FUNC, 7285a233072Sinoguchi .opt.func = s_server_opt_nbio_test, 7295a233072Sinoguchi }, 7305a233072Sinoguchi { 7315a233072Sinoguchi .name = "nextprotoneg", 7325a233072Sinoguchi .argname = "arg", 7335a233072Sinoguchi .type = OPTION_ARG, 734e7718adaStb .opt.arg = &cfg.npn_in, /* Ignored. */ 7355a233072Sinoguchi }, 7365a233072Sinoguchi { 7375a233072Sinoguchi .name = "no_cache", 7385a233072Sinoguchi .desc = "Disable session cache", 7395a233072Sinoguchi .type = OPTION_FLAG, 740e7718adaStb .opt.flag = &cfg.no_cache, 7415a233072Sinoguchi }, 7425a233072Sinoguchi { 7435a233072Sinoguchi .name = "no_comp", 7445a233072Sinoguchi .desc = "Disable SSL/TLS compression", 7455a233072Sinoguchi .type = OPTION_VALUE_OR, 746e7718adaStb .opt.value = &cfg.off, 7475a233072Sinoguchi .value = SSL_OP_NO_COMPRESSION, 7485a233072Sinoguchi }, 7495a233072Sinoguchi { 7505a233072Sinoguchi .name = "no_dhe", 7515a233072Sinoguchi .desc = "Disable ephemeral DH", 7525a233072Sinoguchi .type = OPTION_FLAG, 753e7718adaStb .opt.flag = &cfg.no_dhe, 7545a233072Sinoguchi }, 7555a233072Sinoguchi { 7565a233072Sinoguchi .name = "no_ecdhe", 7575a233072Sinoguchi .desc = "Disable ephemeral ECDH", 7585a233072Sinoguchi .type = OPTION_FLAG, 759e7718adaStb .opt.flag = &cfg.no_ecdhe, 7605a233072Sinoguchi }, 7615a233072Sinoguchi { 7625a233072Sinoguchi .name = "no_ticket", 7635a233072Sinoguchi .desc = "Disable use of RFC4507bis session tickets", 7645a233072Sinoguchi .type = OPTION_VALUE_OR, 765e7718adaStb .opt.value = &cfg.off, 7665a233072Sinoguchi .value = SSL_OP_NO_TICKET, 7675a233072Sinoguchi }, 7685a233072Sinoguchi { 7695a233072Sinoguchi .name = "no_ssl2", 770b5c24d4fSbeck .type = OPTION_DISCARD, 7715a233072Sinoguchi }, 7725a233072Sinoguchi { 7735a233072Sinoguchi .name = "no_ssl3", 774b5c24d4fSbeck .type = OPTION_DISCARD, 775b5c24d4fSbeck }, 776b5c24d4fSbeck { 777b5c24d4fSbeck .name = "no_tls1", 778b5c24d4fSbeck .type = OPTION_DISCARD, 779b5c24d4fSbeck }, 780b5c24d4fSbeck { 781b5c24d4fSbeck .name = "no_tls1_1", 782b5c24d4fSbeck .type = OPTION_DISCARD, 7835a233072Sinoguchi }, 7845a233072Sinoguchi { 7855a233072Sinoguchi .name = "no_tls1_2", 7865a233072Sinoguchi .desc = "Just disable TLSv1.2", 7875a233072Sinoguchi .type = OPTION_VALUE_OR, 788e7718adaStb .opt.value = &cfg.off, 7895a233072Sinoguchi .value = SSL_OP_NO_TLSv1_2, 7905a233072Sinoguchi }, 7915a233072Sinoguchi { 7925a233072Sinoguchi .name = "no_tls1_3", 7935a233072Sinoguchi .desc = "Just disable TLSv1.3", 7945a233072Sinoguchi .type = OPTION_VALUE_OR, 795e7718adaStb .opt.value = &cfg.off, 7965a233072Sinoguchi .value = SSL_OP_NO_TLSv1_3, 7975a233072Sinoguchi }, 7985a233072Sinoguchi { 7995a233072Sinoguchi .name = "no_tmp_rsa", 8005a233072Sinoguchi .type = OPTION_DISCARD, 8015a233072Sinoguchi }, 8025a233072Sinoguchi { 8035a233072Sinoguchi .name = "nocert", 8045a233072Sinoguchi .desc = "Don't use any certificates (Anon-DH)", 8055a233072Sinoguchi .type = OPTION_FLAG, 806e7718adaStb .opt.flag = &cfg.nocert, 8075a233072Sinoguchi }, 8085a233072Sinoguchi { 8095a233072Sinoguchi .name = "pass", 8105a233072Sinoguchi .argname = "arg", 8115a233072Sinoguchi .desc = "Private key file pass phrase source", 8125a233072Sinoguchi .type = OPTION_ARG, 813e7718adaStb .opt.arg = &cfg.passarg, 8145a233072Sinoguchi }, 8155a233072Sinoguchi { 8165a233072Sinoguchi .name = "port", 8175a233072Sinoguchi .argname = "port", 8185a233072Sinoguchi .type = OPTION_ARG_FUNC, 8195a233072Sinoguchi .opt.argfunc = s_server_opt_port, 8205a233072Sinoguchi }, 8215a233072Sinoguchi { 8225a233072Sinoguchi .name = "quiet", 8235a233072Sinoguchi .desc = "Inhibit printing of session and certificate information", 8245a233072Sinoguchi .type = OPTION_FLAG, 825e7718adaStb .opt.flag = &cfg.quiet, 8265a233072Sinoguchi }, 8275a233072Sinoguchi { 8285a233072Sinoguchi .name = "servername", 8295a233072Sinoguchi .argname = "name", 8305a233072Sinoguchi .desc = "Servername for HostName TLS extension", 8315a233072Sinoguchi .type = OPTION_ARG, 832e7718adaStb .opt.arg = &cfg.tlsextcbp.servername, 8335a233072Sinoguchi }, 8345a233072Sinoguchi { 8355a233072Sinoguchi .name = "servername_fatal", 8365a233072Sinoguchi .desc = "On mismatch send fatal alert (default warning alert)", 8375a233072Sinoguchi .type = OPTION_VALUE, 838e7718adaStb .opt.value = &cfg.tlsextcbp.extension_error, 8395a233072Sinoguchi .value = SSL_TLSEXT_ERR_ALERT_FATAL, 8405a233072Sinoguchi }, 8415a233072Sinoguchi { 8425a233072Sinoguchi .name = "serverpref", 8435a233072Sinoguchi .desc = "Use server's cipher preferences", 8445a233072Sinoguchi .type = OPTION_VALUE_OR, 845e7718adaStb .opt.value = &cfg.off, 8465a233072Sinoguchi .value = SSL_OP_CIPHER_SERVER_PREFERENCE, 8475a233072Sinoguchi }, 8485a233072Sinoguchi { 8495a233072Sinoguchi .name = "state", 8505a233072Sinoguchi .desc = "Print the SSL states", 8515a233072Sinoguchi .type = OPTION_FLAG, 852e7718adaStb .opt.flag = &cfg.state, 8535a233072Sinoguchi }, 8545a233072Sinoguchi { 8555a233072Sinoguchi .name = "status", 8565a233072Sinoguchi .desc = "Respond to certificate status requests", 8575a233072Sinoguchi .type = OPTION_FLAG, 858e7718adaStb .opt.flag = &cfg.tlsextstatus, 8595a233072Sinoguchi }, 8605a233072Sinoguchi { 8615a233072Sinoguchi .name = "status_timeout", 8625a233072Sinoguchi .argname = "nsec", 8635a233072Sinoguchi .desc = "Status request responder timeout", 8645a233072Sinoguchi .type = OPTION_ARG_FUNC, 8655a233072Sinoguchi .opt.argfunc = s_server_opt_status_timeout, 8665a233072Sinoguchi }, 8675a233072Sinoguchi { 8685a233072Sinoguchi .name = "status_url", 8695a233072Sinoguchi .argname = "url", 8705a233072Sinoguchi .desc = "Status request fallback URL", 8715a233072Sinoguchi .type = OPTION_ARG_FUNC, 8725a233072Sinoguchi .opt.argfunc = s_server_opt_status_url, 8735a233072Sinoguchi }, 8745a233072Sinoguchi { 8755a233072Sinoguchi .name = "status_verbose", 8765a233072Sinoguchi .desc = "Enable status request verbose printout", 8775a233072Sinoguchi .type = OPTION_FUNC, 8785a233072Sinoguchi .opt.func = s_server_opt_status_verbose, 8795a233072Sinoguchi }, 88093dafd19Sjsing #ifndef OPENSSL_NO_DTLS 8815a233072Sinoguchi { 8825a233072Sinoguchi .name = "timeout", 8835a233072Sinoguchi .desc = "Enable timeouts", 8845a233072Sinoguchi .type = OPTION_FLAG, 885e7718adaStb .opt.flag = &cfg.enable_timeouts, 8865a233072Sinoguchi }, 8875a233072Sinoguchi #endif 8885a233072Sinoguchi { 8895a233072Sinoguchi .name = "tls1_2", 8905a233072Sinoguchi .desc = "Just talk TLSv1.2", 8915a233072Sinoguchi .type = OPTION_FUNC, 89235ffcbeaSjsing .opt.func = s_server_opt_protocol_version_tls1_2, 8935a233072Sinoguchi }, 8945a233072Sinoguchi { 8955a233072Sinoguchi .name = "tls1_3", 8965a233072Sinoguchi .desc = "Just talk TLSv1.3", 8975a233072Sinoguchi .type = OPTION_FUNC, 89835ffcbeaSjsing .opt.func = s_server_opt_protocol_version_tls1_3, 8995a233072Sinoguchi }, 9005a233072Sinoguchi { 9015a233072Sinoguchi .name = "tlsextdebug", 9025a233072Sinoguchi .desc = "Hex dump of all TLS extensions received", 9035a233072Sinoguchi .type = OPTION_FLAG, 904e7718adaStb .opt.flag = &cfg.tlsextdebug, 9055a233072Sinoguchi }, 9065a233072Sinoguchi #ifndef OPENSSL_NO_SRTP 9075a233072Sinoguchi { 9085a233072Sinoguchi .name = "use_srtp", 9095a233072Sinoguchi .argname = "profiles", 9105a233072Sinoguchi .desc = "Offer SRTP key management with a colon-separated profile list", 9115a233072Sinoguchi .type = OPTION_ARG, 912e7718adaStb .opt.arg = &cfg.srtp_profiles, 9135a233072Sinoguchi }, 9145a233072Sinoguchi #endif 9155a233072Sinoguchi { 9165a233072Sinoguchi .name = "Verify", 9175a233072Sinoguchi .argname = "depth", 9185a233072Sinoguchi .desc = "Turn on peer certificate verification, must have a cert", 9195a233072Sinoguchi .type = OPTION_ARG_FUNC, 9205a233072Sinoguchi .opt.argfunc = s_server_opt_verify_fail, 9215a233072Sinoguchi }, 9225a233072Sinoguchi { 9235a233072Sinoguchi .name = "verify", 9245a233072Sinoguchi .argname = "depth", 9255a233072Sinoguchi .desc = "Turn on peer certificate verification", 9265a233072Sinoguchi .type = OPTION_ARG_FUNC, 9275a233072Sinoguchi .opt.argfunc = s_server_opt_verify, 9285a233072Sinoguchi }, 9295a233072Sinoguchi { 9305a233072Sinoguchi .name = "verify_return_error", 9315a233072Sinoguchi .desc = "Return verification error", 9325a233072Sinoguchi .type = OPTION_FLAG, 9335a233072Sinoguchi .opt.flag = &verify_return_error, 9345a233072Sinoguchi }, 9355a233072Sinoguchi { 9365a233072Sinoguchi .name = "WWW", 9375a233072Sinoguchi .desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>", 9385a233072Sinoguchi .type = OPTION_VALUE, 939e7718adaStb .opt.value = &cfg.www, 9405a233072Sinoguchi .value = 2, 9415a233072Sinoguchi }, 9425a233072Sinoguchi { 9435a233072Sinoguchi .name = "www", 9445a233072Sinoguchi .desc = "Respond to a 'GET /' with a status page", 9455a233072Sinoguchi .type = OPTION_VALUE, 946e7718adaStb .opt.value = &cfg.www, 9475a233072Sinoguchi .value = 1, 9485a233072Sinoguchi }, 9495a233072Sinoguchi { 9505a233072Sinoguchi .name = NULL, 9515a233072Sinoguchi .desc = "", 9525a233072Sinoguchi .type = OPTION_ARGV_FUNC, 9535a233072Sinoguchi .opt.argvfunc = s_server_opt_verify_param, 9545a233072Sinoguchi }, 9555a233072Sinoguchi { NULL }, 9565a233072Sinoguchi }; 9575a233072Sinoguchi 9585a233072Sinoguchi static void 9595a233072Sinoguchi s_server_init(void) 9605a233072Sinoguchi { 9615a233072Sinoguchi accept_socket = -1; 962e7718adaStb cfg.cipher = NULL; 963e7718adaStb cfg.server_verify = SSL_VERIFY_NONE; 964e7718adaStb cfg.dcert_file = NULL; 965e7718adaStb cfg.dkey_file = NULL; 966e7718adaStb cfg.cert_file = TEST_CERT; 967e7718adaStb cfg.key_file = NULL; 968e7718adaStb cfg.cert_file2 = TEST_CERT2; 969e7718adaStb cfg.key_file2 = NULL; 9705a233072Sinoguchi ctx2 = NULL; 971e7718adaStb cfg.nbio = 0; 972e7718adaStb cfg.nbio_test = 0; 9735a233072Sinoguchi ctx = NULL; 974e7718adaStb cfg.www = 0; 9755a233072Sinoguchi 9765a233072Sinoguchi bio_s_out = NULL; 977e7718adaStb cfg.debug = 0; 978e7718adaStb cfg.msg = 0; 979e7718adaStb cfg.quiet = 0; 9805a233072Sinoguchi } 9815a233072Sinoguchi 9825a233072Sinoguchi static void 9835a233072Sinoguchi sv_usage(void) 9845a233072Sinoguchi { 9855a233072Sinoguchi fprintf(stderr, "usage: s_server " 9865a233072Sinoguchi "[-accept port] [-alpn protocols] [-bugs] [-CAfile file]\n" 9875a233072Sinoguchi " [-CApath directory] [-cert file] [-cert2 file]\n" 9885a233072Sinoguchi " [-certform der | pem] [-cipher cipherlist]\n" 9895a233072Sinoguchi " [-context id] [-crl_check] [-crl_check_all] [-crlf]\n" 9905a233072Sinoguchi " [-dcert file] [-dcertform der | pem] [-debug]\n" 9915a233072Sinoguchi " [-dhparam file] [-dkey file] [-dkeyform der | pem]\n" 99291e7614aSbeck " [-dpass arg] [-dtls] [-dtls1_2] [-groups list] [-HTTP]\n" 9935a233072Sinoguchi " [-id_prefix arg] [-key keyfile] [-key2 keyfile]\n" 9945a233072Sinoguchi " [-keyform der | pem] [-keymatexport label]\n" 99513017aedStb " [-keymatexportlen len] [-msg] [-mtu mtu] [-naccept num]\n" 9965a233072Sinoguchi " [-named_curve arg] [-nbio] [-nbio_test] [-no_cache]\n" 99791e7614aSbeck " [-no_dhe] [-no_ecdhe] [-no_ticket] \n" 99891e7614aSbeck " [-no_tls1_2] [-no_tls1_3] [-no_tmp_rsa]\n" 9995a233072Sinoguchi " [-nocert] [-pass arg] [-quiet] [-servername name]\n" 10005a233072Sinoguchi " [-servername_fatal] [-serverpref] [-state] [-status]\n" 10015a233072Sinoguchi " [-status_timeout nsec] [-status_url url]\n" 100291e7614aSbeck " [-status_verbose] [-timeout] \n" 10035a233072Sinoguchi " [-tls1_2] [-tls1_3] [-tlsextdebug] [-use_srtp profiles]\n" 10045a233072Sinoguchi " [-Verify depth] [-verify depth] [-verify_return_error]\n" 10055a233072Sinoguchi " [-WWW] [-www]\n"); 10065a233072Sinoguchi fprintf(stderr, "\n"); 10075a233072Sinoguchi options_usage(s_server_options); 10085a233072Sinoguchi fprintf(stderr, "\n"); 10095a233072Sinoguchi } 10105a233072Sinoguchi 1011dab3f910Sjsing int 1012dab3f910Sjsing s_server_main(int argc, char *argv[]) 1013dab3f910Sjsing { 1014dab3f910Sjsing int ret = 1; 10155a233072Sinoguchi char *pass = NULL; 10165a233072Sinoguchi char *dpass = NULL; 1017dab3f910Sjsing X509 *s_cert = NULL, *s_dcert = NULL; 1018dab3f910Sjsing EVP_PKEY *s_key = NULL, *s_dkey = NULL; 1019dab3f910Sjsing EVP_PKEY *s_key2 = NULL; 1020dab3f910Sjsing X509 *s_cert2 = NULL; 10211b4c9cadSjsing tlsextalpnctx alpn_ctx = { NULL, 0 }; 10229bc487adSdoug 102351811eadSderaadt if (pledge("stdio rpath inet dns tty", NULL) == -1) { 10249bc487adSdoug perror("pledge"); 1025e370f0eeSdoug exit(1); 1026e370f0eeSdoug } 10279bc487adSdoug 1028e7718adaStb memset(&cfg, 0, sizeof(cfg)); 1029e7718adaStb cfg.keymatexportlen = 20; 1030e7718adaStb cfg.meth = TLS_server_method(); 1031e7718adaStb cfg.naccept = -1; 1032e7718adaStb cfg.port = PORT; 1033e7718adaStb cfg.cert_file = TEST_CERT; 1034e7718adaStb cfg.cert_file2 = TEST_CERT2; 1035e7718adaStb cfg.cert_format = FORMAT_PEM; 1036e7718adaStb cfg.dcert_format = FORMAT_PEM; 1037e7718adaStb cfg.dkey_format = FORMAT_PEM; 1038e7718adaStb cfg.key_format = FORMAT_PEM; 1039e7718adaStb cfg.server_verify = SSL_VERIFY_NONE; 1040e7718adaStb cfg.socket_type = SOCK_STREAM; 1041e7718adaStb cfg.tlscstatp.timeout = -1; 1042e7718adaStb cfg.tlsextcbp.extension_error = 10434da86b84Sinoguchi SSL_TLSEXT_ERR_ALERT_WARNING; 1044dab3f910Sjsing 1045dab3f910Sjsing local_argc = argc; 1046dab3f910Sjsing local_argv = argv; 1047dab3f910Sjsing 1048dab3f910Sjsing s_server_init(); 1049dab3f910Sjsing 1050dab3f910Sjsing verify_depth = 0; 1051dab3f910Sjsing 10525a233072Sinoguchi if (options_parse(argc, argv, s_server_options, NULL, NULL) != 0) { 1053e7718adaStb if (cfg.errstr == NULL) 1054dab3f910Sjsing sv_usage(); 1055dab3f910Sjsing goto end; 1056dab3f910Sjsing } 1057dab3f910Sjsing 1058e7718adaStb if (!app_passwd(bio_err, cfg.passarg, 1059e7718adaStb cfg.dpassarg, &pass, &dpass)) { 1060dab3f910Sjsing BIO_printf(bio_err, "Error getting password\n"); 1061dab3f910Sjsing goto end; 1062dab3f910Sjsing } 1063e7718adaStb if (cfg.key_file == NULL) 1064e7718adaStb cfg.key_file = cfg.cert_file; 1065e7718adaStb if (cfg.key_file2 == NULL) 1066e7718adaStb cfg.key_file2 = cfg.cert_file2; 1067dab3f910Sjsing 1068e7718adaStb if (cfg.nocert == 0) { 1069e7718adaStb s_key = load_key(bio_err, cfg.key_file, 1070e7718adaStb cfg.key_format, 0, pass, 1071dab3f910Sjsing "server certificate private key file"); 1072dab3f910Sjsing if (!s_key) { 1073dab3f910Sjsing ERR_print_errors(bio_err); 1074dab3f910Sjsing goto end; 1075dab3f910Sjsing } 1076e7718adaStb s_cert = load_cert(bio_err, cfg.cert_file, 1077e7718adaStb cfg.cert_format, 10785284dfeaSbcook NULL, "server certificate file"); 1079dab3f910Sjsing 1080dab3f910Sjsing if (!s_cert) { 1081dab3f910Sjsing ERR_print_errors(bio_err); 1082dab3f910Sjsing goto end; 1083dab3f910Sjsing } 1084e7718adaStb if (cfg.tlsextcbp.servername) { 1085e7718adaStb s_key2 = load_key(bio_err, cfg.key_file2, 1086e7718adaStb cfg.key_format, 0, pass, 1087dab3f910Sjsing "second server certificate private key file"); 1088dab3f910Sjsing if (!s_key2) { 1089dab3f910Sjsing ERR_print_errors(bio_err); 1090dab3f910Sjsing goto end; 1091dab3f910Sjsing } 1092e7718adaStb s_cert2 = load_cert(bio_err, cfg.cert_file2, 1093e7718adaStb cfg.cert_format, 10945284dfeaSbcook NULL, "second server certificate file"); 1095dab3f910Sjsing 1096dab3f910Sjsing if (!s_cert2) { 1097dab3f910Sjsing ERR_print_errors(bio_err); 1098dab3f910Sjsing goto end; 1099dab3f910Sjsing } 1100dab3f910Sjsing } 1101dab3f910Sjsing } 11021b4c9cadSjsing alpn_ctx.data = NULL; 1103e7718adaStb if (cfg.alpn_in) { 11041b4c9cadSjsing unsigned short len; 11054da86b84Sinoguchi alpn_ctx.data = next_protos_parse(&len, 1106e7718adaStb cfg.alpn_in); 11071b4c9cadSjsing if (alpn_ctx.data == NULL) 11081b4c9cadSjsing goto end; 11091b4c9cadSjsing alpn_ctx.len = len; 11101b4c9cadSjsing } 1111dab3f910Sjsing 1112e7718adaStb if (cfg.dcert_file) { 1113dab3f910Sjsing 1114e7718adaStb if (cfg.dkey_file == NULL) 1115e7718adaStb cfg.dkey_file = cfg.dcert_file; 1116dab3f910Sjsing 1117e7718adaStb s_dkey = load_key(bio_err, cfg.dkey_file, 1118e7718adaStb cfg.dkey_format, 11195284dfeaSbcook 0, dpass, "second certificate private key file"); 1120dab3f910Sjsing if (!s_dkey) { 1121dab3f910Sjsing ERR_print_errors(bio_err); 1122dab3f910Sjsing goto end; 1123dab3f910Sjsing } 1124e7718adaStb s_dcert = load_cert(bio_err, cfg.dcert_file, 1125e7718adaStb cfg.dcert_format, 11265284dfeaSbcook NULL, "second server certificate file"); 1127dab3f910Sjsing 1128dab3f910Sjsing if (!s_dcert) { 1129dab3f910Sjsing ERR_print_errors(bio_err); 1130dab3f910Sjsing goto end; 1131dab3f910Sjsing } 1132dab3f910Sjsing } 1133dab3f910Sjsing if (bio_s_out == NULL) { 1134e7718adaStb if (cfg.quiet && !cfg.debug && 1135e7718adaStb !cfg.msg) { 1136dab3f910Sjsing bio_s_out = BIO_new(BIO_s_null()); 1137dab3f910Sjsing } else { 1138dab3f910Sjsing if (bio_s_out == NULL) 1139dab3f910Sjsing bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE); 1140dab3f910Sjsing } 1141dab3f910Sjsing } 1142e7718adaStb if (cfg.nocert) { 1143e7718adaStb cfg.cert_file = NULL; 1144e7718adaStb cfg.key_file = NULL; 1145e7718adaStb cfg.dcert_file = NULL; 1146e7718adaStb cfg.dkey_file = NULL; 1147e7718adaStb cfg.cert_file2 = NULL; 1148e7718adaStb cfg.key_file2 = NULL; 1149dab3f910Sjsing } 1150e7718adaStb ctx = SSL_CTX_new(cfg.meth); 1151dab3f910Sjsing if (ctx == NULL) { 1152dab3f910Sjsing ERR_print_errors(bio_err); 1153dab3f910Sjsing goto end; 1154dab3f910Sjsing } 115595f83488Sinoguchi 1156f4cc3564Stb SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); 1157f4cc3564Stb 1158e7718adaStb if (!SSL_CTX_set_min_proto_version(ctx, cfg.min_version)) 115995f83488Sinoguchi goto end; 1160e7718adaStb if (!SSL_CTX_set_max_proto_version(ctx, cfg.max_version)) 116195f83488Sinoguchi goto end; 116295f83488Sinoguchi 1163e7718adaStb if (cfg.session_id_prefix) { 1164e7718adaStb if (strlen(cfg.session_id_prefix) >= 32) 1165dab3f910Sjsing BIO_printf(bio_err, 1166dab3f910Sjsing "warning: id_prefix is too long, only one new session will be possible\n"); 1167e7718adaStb else if (strlen(cfg.session_id_prefix) >= 16) 1168dab3f910Sjsing BIO_printf(bio_err, 1169dab3f910Sjsing "warning: id_prefix is too long if you use SSLv2\n"); 1170dab3f910Sjsing if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) { 1171dab3f910Sjsing BIO_printf(bio_err, "error setting 'id_prefix'\n"); 1172dab3f910Sjsing ERR_print_errors(bio_err); 1173dab3f910Sjsing goto end; 1174dab3f910Sjsing } 11754da86b84Sinoguchi BIO_printf(bio_err, "id_prefix '%s' set.\n", 1176e7718adaStb cfg.session_id_prefix); 1177dab3f910Sjsing } 1178dab3f910Sjsing SSL_CTX_set_quiet_shutdown(ctx, 1); 1179e7718adaStb if (cfg.bugs) 1180dab3f910Sjsing SSL_CTX_set_options(ctx, SSL_OP_ALL); 1181e7718adaStb SSL_CTX_set_options(ctx, cfg.off); 1182dab3f910Sjsing 1183e7718adaStb if (cfg.state) 1184dab3f910Sjsing SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); 1185e7718adaStb if (cfg.no_cache) 1186dab3f910Sjsing SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); 1187dab3f910Sjsing else 1188dab3f910Sjsing SSL_CTX_sess_set_cache_size(ctx, 128); 1189dab3f910Sjsing 1190dab3f910Sjsing #ifndef OPENSSL_NO_SRTP 1191e7718adaStb if (cfg.srtp_profiles != NULL) 1192e7718adaStb SSL_CTX_set_tlsext_use_srtp(ctx, cfg.srtp_profiles); 1193dab3f910Sjsing #endif 1194dab3f910Sjsing 1195e7718adaStb if ((!SSL_CTX_load_verify_locations(ctx, cfg.CAfile, 1196e7718adaStb cfg.CApath)) || 1197dab3f910Sjsing (!SSL_CTX_set_default_verify_paths(ctx))) { 1198dab3f910Sjsing /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ 1199dab3f910Sjsing ERR_print_errors(bio_err); 1200dab3f910Sjsing /* goto end; */ 1201dab3f910Sjsing } 1202e7718adaStb if (cfg.vpm) 1203e7718adaStb SSL_CTX_set1_param(ctx, cfg.vpm); 1204dab3f910Sjsing 1205dab3f910Sjsing if (s_cert2) { 1206e7718adaStb ctx2 = SSL_CTX_new(cfg.meth); 1207dab3f910Sjsing if (ctx2 == NULL) { 1208dab3f910Sjsing ERR_print_errors(bio_err); 1209dab3f910Sjsing goto end; 1210dab3f910Sjsing } 121195f83488Sinoguchi 12124da86b84Sinoguchi if (!SSL_CTX_set_min_proto_version(ctx2, 1213e7718adaStb cfg.min_version)) 121495f83488Sinoguchi goto end; 12154da86b84Sinoguchi if (!SSL_CTX_set_max_proto_version(ctx2, 1216e7718adaStb cfg.max_version)) 121795f83488Sinoguchi goto end; 1218a7150521Stb SSL_CTX_clear_mode(ctx2, SSL_MODE_AUTO_RETRY); 1219dab3f910Sjsing } 1220dab3f910Sjsing if (ctx2) { 1221dab3f910Sjsing BIO_printf(bio_s_out, "Setting secondary ctx parameters\n"); 1222dab3f910Sjsing 1223e7718adaStb if (cfg.session_id_prefix) { 1224e7718adaStb if (strlen(cfg.session_id_prefix) >= 32) 1225dab3f910Sjsing BIO_printf(bio_err, 1226dab3f910Sjsing "warning: id_prefix is too long, only one new session will be possible\n"); 1227e7718adaStb else if (strlen(cfg.session_id_prefix) >= 16) 1228dab3f910Sjsing BIO_printf(bio_err, 1229dab3f910Sjsing "warning: id_prefix is too long if you use SSLv2\n"); 12304da86b84Sinoguchi if (!SSL_CTX_set_generate_session_id(ctx2, 12314da86b84Sinoguchi generate_session_id)) { 12324da86b84Sinoguchi BIO_printf(bio_err, 12334da86b84Sinoguchi "error setting 'id_prefix'\n"); 1234dab3f910Sjsing ERR_print_errors(bio_err); 1235dab3f910Sjsing goto end; 1236dab3f910Sjsing } 12374da86b84Sinoguchi BIO_printf(bio_err, "id_prefix '%s' set.\n", 1238e7718adaStb cfg.session_id_prefix); 1239dab3f910Sjsing } 1240dab3f910Sjsing SSL_CTX_set_quiet_shutdown(ctx2, 1); 1241e7718adaStb if (cfg.bugs) 1242dab3f910Sjsing SSL_CTX_set_options(ctx2, SSL_OP_ALL); 1243e7718adaStb SSL_CTX_set_options(ctx2, cfg.off); 1244dab3f910Sjsing 1245e7718adaStb if (cfg.state) 1246dab3f910Sjsing SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback); 1247dab3f910Sjsing 1248e7718adaStb if (cfg.no_cache) 1249dab3f910Sjsing SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF); 1250dab3f910Sjsing else 1251dab3f910Sjsing SSL_CTX_sess_set_cache_size(ctx2, 128); 1252dab3f910Sjsing 12534da86b84Sinoguchi if ((!SSL_CTX_load_verify_locations(ctx2, 1254e7718adaStb cfg.CAfile, cfg.CApath)) || 1255dab3f910Sjsing (!SSL_CTX_set_default_verify_paths(ctx2))) { 1256dab3f910Sjsing ERR_print_errors(bio_err); 1257dab3f910Sjsing } 1258e7718adaStb if (cfg.vpm) 1259e7718adaStb SSL_CTX_set1_param(ctx2, cfg.vpm); 1260dab3f910Sjsing } 12611b4c9cadSjsing if (alpn_ctx.data) 12621b4c9cadSjsing SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx); 1263dab3f910Sjsing 1264e7718adaStb if (cfg.groups_in != NULL) { 1265e7718adaStb if (SSL_CTX_set1_groups_list(ctx, cfg.groups_in) != 1) { 1266480d2676Sjsing BIO_printf(bio_err, "Failed to set groups '%s'\n", 1267e7718adaStb cfg.groups_in); 1268480d2676Sjsing goto end; 1269480d2676Sjsing } 1270480d2676Sjsing } 1271480d2676Sjsing 1272dab3f910Sjsing #ifndef OPENSSL_NO_DH 1273e7718adaStb if (!cfg.no_dhe) { 1274dab3f910Sjsing DH *dh = NULL; 1275dab3f910Sjsing 1276e7718adaStb if (cfg.dhfile) 1277e7718adaStb dh = load_dh_param(cfg.dhfile); 1278e7718adaStb else if (cfg.cert_file) 1279e7718adaStb dh = load_dh_param(cfg.cert_file); 1280dab3f910Sjsing 1281c66e7edeSjsing if (dh != NULL) 1282dab3f910Sjsing BIO_printf(bio_s_out, "Setting temp DH parameters\n"); 1283c66e7edeSjsing else 1284c66e7edeSjsing BIO_printf(bio_s_out, "Using auto DH parameters\n"); 1285dab3f910Sjsing (void) BIO_flush(bio_s_out); 1286dab3f910Sjsing 1287c66e7edeSjsing if (dh == NULL) 1288c66e7edeSjsing SSL_CTX_set_dh_auto(ctx, 1); 1289c66e7edeSjsing else if (!SSL_CTX_set_tmp_dh(ctx, dh)) { 1290c66e7edeSjsing BIO_printf(bio_err, 1291c66e7edeSjsing "Error setting temp DH parameters\n"); 1292c66e7edeSjsing ERR_print_errors(bio_err); 1293c66e7edeSjsing DH_free(dh); 1294c66e7edeSjsing goto end; 1295c66e7edeSjsing } 1296c66e7edeSjsing 1297dab3f910Sjsing if (ctx2) { 1298e7718adaStb if (!cfg.dhfile) { 1299073abcbeSdoug DH *dh2 = NULL; 1300073abcbeSdoug 1301e7718adaStb if (cfg.cert_file2 != NULL) 13024da86b84Sinoguchi dh2 = load_dh_param( 1303e7718adaStb cfg.cert_file2); 1304dab3f910Sjsing if (dh2 != NULL) { 13054da86b84Sinoguchi BIO_printf(bio_s_out, 13064da86b84Sinoguchi "Setting temp DH parameters\n"); 1307dab3f910Sjsing (void) BIO_flush(bio_s_out); 1308dab3f910Sjsing 1309dab3f910Sjsing DH_free(dh); 1310dab3f910Sjsing dh = dh2; 1311dab3f910Sjsing } 1312dab3f910Sjsing } 1313c66e7edeSjsing if (dh == NULL) 1314c66e7edeSjsing SSL_CTX_set_dh_auto(ctx2, 1); 1315c66e7edeSjsing else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) { 1316c66e7edeSjsing BIO_printf(bio_err, 1317c66e7edeSjsing "Error setting temp DH parameters\n"); 1318c66e7edeSjsing ERR_print_errors(bio_err); 1319c66e7edeSjsing DH_free(dh); 1320c66e7edeSjsing goto end; 1321c66e7edeSjsing } 1322dab3f910Sjsing } 1323dab3f910Sjsing DH_free(dh); 1324dab3f910Sjsing } 1325dab3f910Sjsing #endif 1326dab3f910Sjsing 1327e7718adaStb if (!cfg.no_ecdhe && cfg.named_curve != NULL) { 1328dab3f910Sjsing EC_KEY *ecdh = NULL; 1329480d2676Sjsing int nid; 1330dab3f910Sjsing 1331e7718adaStb if ((nid = OBJ_sn2nid(cfg.named_curve)) == 0) { 1332dab3f910Sjsing BIO_printf(bio_err, "unknown curve name (%s)\n", 1333e7718adaStb cfg.named_curve); 1334dab3f910Sjsing goto end; 1335dab3f910Sjsing } 1336480d2676Sjsing if ((ecdh = EC_KEY_new_by_curve_name(nid)) == NULL) { 1337dab3f910Sjsing BIO_printf(bio_err, "unable to create curve (%s)\n", 1338e7718adaStb cfg.named_curve); 1339dab3f910Sjsing goto end; 1340dab3f910Sjsing } 1341dab3f910Sjsing BIO_printf(bio_s_out, "Setting temp ECDH parameters\n"); 1342dab3f910Sjsing (void) BIO_flush(bio_s_out); 1343dab3f910Sjsing 1344dab3f910Sjsing SSL_CTX_set_tmp_ecdh(ctx, ecdh); 1345dab3f910Sjsing if (ctx2) 1346dab3f910Sjsing SSL_CTX_set_tmp_ecdh(ctx2, ecdh); 1347dab3f910Sjsing EC_KEY_free(ecdh); 1348dab3f910Sjsing } 1349dab3f910Sjsing 1350dab3f910Sjsing if (!set_cert_key_stuff(ctx, s_cert, s_key)) 1351dab3f910Sjsing goto end; 1352dab3f910Sjsing if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2)) 1353dab3f910Sjsing goto end; 1354dab3f910Sjsing if (s_dcert != NULL) { 1355dab3f910Sjsing if (!set_cert_key_stuff(ctx, s_dcert, s_dkey)) 1356dab3f910Sjsing goto end; 1357dab3f910Sjsing } 1358dab3f910Sjsing 1359e7718adaStb if (cfg.cipher != NULL) { 1360e7718adaStb if (!SSL_CTX_set_cipher_list(ctx, cfg.cipher)) { 1361dab3f910Sjsing BIO_printf(bio_err, "error setting cipher list\n"); 1362dab3f910Sjsing ERR_print_errors(bio_err); 1363dab3f910Sjsing goto end; 1364dab3f910Sjsing } 13654da86b84Sinoguchi if (ctx2 && !SSL_CTX_set_cipher_list(ctx2, 1366e7718adaStb cfg.cipher)) { 1367dab3f910Sjsing BIO_printf(bio_err, "error setting cipher list\n"); 1368dab3f910Sjsing ERR_print_errors(bio_err); 1369dab3f910Sjsing goto end; 1370dab3f910Sjsing } 1371dab3f910Sjsing } 1372e7718adaStb SSL_CTX_set_verify(ctx, cfg.server_verify, verify_callback); 13734da86b84Sinoguchi SSL_CTX_set_session_id_context(ctx, 13744da86b84Sinoguchi (void *) &s_server_session_id_context, 1375dab3f910Sjsing sizeof s_server_session_id_context); 1376dab3f910Sjsing 1377dab3f910Sjsing /* Set DTLS cookie generation and verification callbacks */ 1378dab3f910Sjsing SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); 1379dab3f910Sjsing SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); 1380dab3f910Sjsing 1381dab3f910Sjsing if (ctx2) { 1382e7718adaStb SSL_CTX_set_verify(ctx2, cfg.server_verify, 13834da86b84Sinoguchi verify_callback); 13844da86b84Sinoguchi SSL_CTX_set_session_id_context(ctx2, 13854da86b84Sinoguchi (void *) &s_server_session_id_context, 1386dab3f910Sjsing sizeof s_server_session_id_context); 1387dab3f910Sjsing 1388e7718adaStb cfg.tlsextcbp.biodebug = bio_s_out; 1389dab3f910Sjsing SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); 13904da86b84Sinoguchi SSL_CTX_set_tlsext_servername_arg(ctx2, 1391e7718adaStb &cfg.tlsextcbp); 1392dab3f910Sjsing SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); 13934da86b84Sinoguchi SSL_CTX_set_tlsext_servername_arg(ctx, 1394e7718adaStb &cfg.tlsextcbp); 1395dab3f910Sjsing } 1396dab3f910Sjsing 1397e7718adaStb if (cfg.CAfile != NULL) { 13984da86b84Sinoguchi SSL_CTX_set_client_CA_list(ctx, 1399e7718adaStb SSL_load_client_CA_file(cfg.CAfile)); 1400dab3f910Sjsing if (ctx2) 14014da86b84Sinoguchi SSL_CTX_set_client_CA_list(ctx2, 1402e7718adaStb SSL_load_client_CA_file(cfg.CAfile)); 1403dab3f910Sjsing } 1404dab3f910Sjsing BIO_printf(bio_s_out, "ACCEPT\n"); 1405dab3f910Sjsing (void) BIO_flush(bio_s_out); 1406e7718adaStb if (cfg.www) 1407e7718adaStb do_server(cfg.port, cfg.socket_type, 1408e7718adaStb &accept_socket, www_body, cfg.context, 1409e7718adaStb cfg.naccept); 1410dab3f910Sjsing else 1411e7718adaStb do_server(cfg.port, cfg.socket_type, 1412e7718adaStb &accept_socket, sv_body, cfg.context, 1413e7718adaStb cfg.naccept); 1414dab3f910Sjsing print_stats(bio_s_out, ctx); 1415dab3f910Sjsing ret = 0; 1416dab3f910Sjsing end: 1417dab3f910Sjsing SSL_CTX_free(ctx); 1418dab3f910Sjsing X509_free(s_cert); 1419dab3f910Sjsing X509_free(s_dcert); 1420dab3f910Sjsing EVP_PKEY_free(s_key); 1421dab3f910Sjsing EVP_PKEY_free(s_dkey); 1422dab3f910Sjsing free(pass); 1423dab3f910Sjsing free(dpass); 1424e7718adaStb X509_VERIFY_PARAM_free(cfg.vpm); 1425e7718adaStb free(cfg.tlscstatp.host); 1426e7718adaStb free(cfg.tlscstatp.port); 1427e7718adaStb free(cfg.tlscstatp.path); 1428dab3f910Sjsing SSL_CTX_free(ctx2); 1429dab3f910Sjsing X509_free(s_cert2); 1430dab3f910Sjsing EVP_PKEY_free(s_key2); 14311b4c9cadSjsing free(alpn_ctx.data); 1432dab3f910Sjsing if (bio_s_out != NULL) { 1433dab3f910Sjsing BIO_free(bio_s_out); 1434dab3f910Sjsing bio_s_out = NULL; 1435dab3f910Sjsing } 1436dab3f910Sjsing 1437dab3f910Sjsing return (ret); 1438dab3f910Sjsing } 1439dab3f910Sjsing 1440dab3f910Sjsing static void 1441dab3f910Sjsing print_stats(BIO *bio, SSL_CTX *ssl_ctx) 1442dab3f910Sjsing { 1443dab3f910Sjsing BIO_printf(bio, "%4ld items in the session cache\n", 1444dab3f910Sjsing SSL_CTX_sess_number(ssl_ctx)); 1445dab3f910Sjsing BIO_printf(bio, "%4ld client connects (SSL_connect())\n", 1446dab3f910Sjsing SSL_CTX_sess_connect(ssl_ctx)); 1447dab3f910Sjsing BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n", 1448dab3f910Sjsing SSL_CTX_sess_connect_renegotiate(ssl_ctx)); 1449dab3f910Sjsing BIO_printf(bio, "%4ld client connects that finished\n", 1450dab3f910Sjsing SSL_CTX_sess_connect_good(ssl_ctx)); 1451dab3f910Sjsing BIO_printf(bio, "%4ld server accepts (SSL_accept())\n", 1452dab3f910Sjsing SSL_CTX_sess_accept(ssl_ctx)); 1453dab3f910Sjsing BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n", 1454dab3f910Sjsing SSL_CTX_sess_accept_renegotiate(ssl_ctx)); 1455dab3f910Sjsing BIO_printf(bio, "%4ld server accepts that finished\n", 1456dab3f910Sjsing SSL_CTX_sess_accept_good(ssl_ctx)); 14574da86b84Sinoguchi BIO_printf(bio, "%4ld session cache hits\n", 14584da86b84Sinoguchi SSL_CTX_sess_hits(ssl_ctx)); 14594da86b84Sinoguchi BIO_printf(bio, "%4ld session cache misses\n", 14604da86b84Sinoguchi SSL_CTX_sess_misses(ssl_ctx)); 14614da86b84Sinoguchi BIO_printf(bio, "%4ld session cache timeouts\n", 14624da86b84Sinoguchi SSL_CTX_sess_timeouts(ssl_ctx)); 14634da86b84Sinoguchi BIO_printf(bio, "%4ld callback cache hits\n", 14644da86b84Sinoguchi SSL_CTX_sess_cb_hits(ssl_ctx)); 1465dab3f910Sjsing BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n", 1466dab3f910Sjsing SSL_CTX_sess_cache_full(ssl_ctx), 1467dab3f910Sjsing SSL_CTX_sess_get_cache_size(ssl_ctx)); 1468dab3f910Sjsing } 1469dab3f910Sjsing 1470dab3f910Sjsing static int 14717537a7c2Stb sv_body(int s, unsigned char *context) 1472dab3f910Sjsing { 1473dab3f910Sjsing char *buf = NULL; 14749c8ea7b6Sderaadt int ret = 1; 1475dab3f910Sjsing int k, i; 1476dab3f910Sjsing unsigned long l; 1477dab3f910Sjsing SSL *con = NULL; 1478dab3f910Sjsing BIO *sbio; 1479dab3f910Sjsing struct timeval timeout; 1480dab3f910Sjsing 1481dab3f910Sjsing if ((buf = malloc(bufsize)) == NULL) { 1482dab3f910Sjsing BIO_printf(bio_err, "out of memory\n"); 1483dab3f910Sjsing goto err; 1484dab3f910Sjsing } 1485e7718adaStb if (cfg.nbio) { 1486e7718adaStb if (!cfg.quiet) 1487dab3f910Sjsing BIO_printf(bio_err, "turning on non blocking io\n"); 1488fcc700e7Sbcook if (!BIO_socket_nbio(s, 1)) 1489dab3f910Sjsing ERR_print_errors(bio_err); 1490dab3f910Sjsing } 1491dab3f910Sjsing 1492dab3f910Sjsing if (con == NULL) { 1493dab3f910Sjsing con = SSL_new(ctx); 1494e7718adaStb if (cfg.tlsextdebug) { 1495dab3f910Sjsing SSL_set_tlsext_debug_callback(con, tlsext_cb); 1496dab3f910Sjsing SSL_set_tlsext_debug_arg(con, bio_s_out); 1497dab3f910Sjsing } 1498e7718adaStb if (cfg.tlsextstatus) { 1499dab3f910Sjsing SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); 1500e7718adaStb cfg.tlscstatp.err = bio_err; 15014da86b84Sinoguchi SSL_CTX_set_tlsext_status_arg(ctx, 1502e7718adaStb &cfg.tlscstatp); 1503dab3f910Sjsing } 1504dab3f910Sjsing if (context) 1505dab3f910Sjsing SSL_set_session_id_context(con, context, 1506dab3f910Sjsing strlen((char *) context)); 1507dab3f910Sjsing } 1508dab3f910Sjsing SSL_clear(con); 1509dab3f910Sjsing 151093dafd19Sjsing if (SSL_is_dtls(con)) { 1511dab3f910Sjsing sbio = BIO_new_dgram(s, BIO_NOCLOSE); 1512dab3f910Sjsing 1513e7718adaStb if (cfg.enable_timeouts) { 1514dab3f910Sjsing timeout.tv_sec = 0; 1515dab3f910Sjsing timeout.tv_usec = DGRAM_RCV_TIMEOUT; 15164da86b84Sinoguchi BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, 15174da86b84Sinoguchi &timeout); 1518dab3f910Sjsing 1519dab3f910Sjsing timeout.tv_sec = 0; 1520dab3f910Sjsing timeout.tv_usec = DGRAM_SND_TIMEOUT; 15214da86b84Sinoguchi BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, 15224da86b84Sinoguchi &timeout); 1523dab3f910Sjsing } 1524e7718adaStb if (cfg.socket_mtu > 28) { 1525dab3f910Sjsing SSL_set_options(con, SSL_OP_NO_QUERY_MTU); 1526e7718adaStb SSL_set_mtu(con, cfg.socket_mtu - 28); 1527dab3f910Sjsing } else 1528dab3f910Sjsing /* want to do MTU discovery */ 1529dab3f910Sjsing BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); 1530dab3f910Sjsing 1531dab3f910Sjsing /* turn on cookie exchange */ 1532dab3f910Sjsing SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); 1533dab3f910Sjsing } else 1534dab3f910Sjsing sbio = BIO_new_socket(s, BIO_NOCLOSE); 1535dab3f910Sjsing 1536e7718adaStb if (cfg.nbio_test) { 1537dab3f910Sjsing BIO *test; 1538dab3f910Sjsing 1539dab3f910Sjsing test = BIO_new(BIO_f_nbio_test()); 1540dab3f910Sjsing sbio = BIO_push(test, sbio); 1541dab3f910Sjsing } 1542dab3f910Sjsing 1543dab3f910Sjsing SSL_set_bio(con, sbio, sbio); 1544dab3f910Sjsing SSL_set_accept_state(con); 1545dab3f910Sjsing /* SSL_set_fd(con,s); */ 1546dab3f910Sjsing 1547e7718adaStb if (cfg.debug) { 1548dab3f910Sjsing BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 1549dab3f910Sjsing BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); 1550dab3f910Sjsing } 1551e7718adaStb if (cfg.msg) { 1552dab3f910Sjsing SSL_set_msg_callback(con, msg_cb); 1553dab3f910Sjsing SSL_set_msg_callback_arg(con, bio_s_out); 1554dab3f910Sjsing } 1555e7718adaStb if (cfg.tlsextdebug) { 1556dab3f910Sjsing SSL_set_tlsext_debug_callback(con, tlsext_cb); 1557dab3f910Sjsing SSL_set_tlsext_debug_arg(con, bio_s_out); 1558dab3f910Sjsing } 1559dab3f910Sjsing 1560dab3f910Sjsing for (;;) { 1561dab3f910Sjsing int read_from_terminal; 1562dab3f910Sjsing int read_from_sslcon; 15639c8ea7b6Sderaadt struct pollfd pfd[2]; 15649c8ea7b6Sderaadt int ptimeout; 1565dab3f910Sjsing 1566dab3f910Sjsing read_from_terminal = 0; 1567dab3f910Sjsing read_from_sslcon = SSL_pending(con); 1568dab3f910Sjsing 1569dab3f910Sjsing if (!read_from_sslcon) { 15709c8ea7b6Sderaadt pfd[0].fd = fileno(stdin); 15719c8ea7b6Sderaadt pfd[0].events = POLLIN; 15729c8ea7b6Sderaadt pfd[1].fd = s; 15739c8ea7b6Sderaadt pfd[1].events = POLLIN; 15749c8ea7b6Sderaadt 157593dafd19Sjsing if (SSL_is_dtls(con) && 1576dab3f910Sjsing DTLSv1_get_timeout(con, &timeout)) 15779c8ea7b6Sderaadt ptimeout = timeout.tv_sec * 1000 + 15789c8ea7b6Sderaadt timeout.tv_usec / 1000; 1579dab3f910Sjsing else 15809c8ea7b6Sderaadt ptimeout = -1; 1581dab3f910Sjsing 15829c8ea7b6Sderaadt i = poll(pfd, 2, ptimeout); 1583dab3f910Sjsing 158493dafd19Sjsing if (SSL_is_dtls(con) && 158593dafd19Sjsing DTLSv1_handle_timeout(con) > 0) 1586dab3f910Sjsing BIO_printf(bio_err, "TIMEOUT occured\n"); 1587dab3f910Sjsing if (i <= 0) 1588dab3f910Sjsing continue; 15899c8ea7b6Sderaadt if (pfd[0].revents) { 15909c8ea7b6Sderaadt if ((pfd[0].revents & (POLLERR|POLLNVAL))) 15919c8ea7b6Sderaadt continue; 1592dab3f910Sjsing read_from_terminal = 1; 15939c8ea7b6Sderaadt } 15949c8ea7b6Sderaadt if (pfd[1].revents) { 15959c8ea7b6Sderaadt if ((pfd[1].revents & (POLLERR|POLLNVAL))) 15969c8ea7b6Sderaadt continue; 1597dab3f910Sjsing read_from_sslcon = 1; 1598dab3f910Sjsing } 15999c8ea7b6Sderaadt } 1600dab3f910Sjsing if (read_from_terminal) { 1601e7718adaStb if (cfg.crlf) { 1602dab3f910Sjsing int j, lf_num; 1603dab3f910Sjsing 1604dab3f910Sjsing i = read(fileno(stdin), buf, bufsize / 2); 1605dab3f910Sjsing lf_num = 0; 1606dab3f910Sjsing /* both loops are skipped when i <= 0 */ 1607dab3f910Sjsing for (j = 0; j < i; j++) 1608dab3f910Sjsing if (buf[j] == '\n') 1609dab3f910Sjsing lf_num++; 1610dab3f910Sjsing for (j = i - 1; j >= 0; j--) { 1611dab3f910Sjsing buf[j + lf_num] = buf[j]; 1612dab3f910Sjsing if (buf[j] == '\n') { 1613dab3f910Sjsing lf_num--; 1614dab3f910Sjsing i++; 1615dab3f910Sjsing buf[j + lf_num] = '\r'; 1616dab3f910Sjsing } 1617dab3f910Sjsing } 1618dab3f910Sjsing assert(lf_num == 0); 1619dab3f910Sjsing } else 1620dab3f910Sjsing i = read(fileno(stdin), buf, bufsize); 1621e7718adaStb if (!cfg.quiet) { 1622dab3f910Sjsing if ((i <= 0) || (buf[0] == 'Q')) { 1623dab3f910Sjsing BIO_printf(bio_s_out, "DONE\n"); 1624dab3f910Sjsing shutdown(s, SHUT_RD); 1625dab3f910Sjsing close(s); 1626dab3f910Sjsing close_accept_socket(); 1627dab3f910Sjsing ret = -11; 1628dab3f910Sjsing goto err; 1629dab3f910Sjsing } 1630dab3f910Sjsing if ((i <= 0) || (buf[0] == 'q')) { 1631dab3f910Sjsing BIO_printf(bio_s_out, "DONE\n"); 163293dafd19Sjsing if (!SSL_is_dtls(con)) { 1633dab3f910Sjsing shutdown(s, SHUT_RD); 1634dab3f910Sjsing close(s); 1635dab3f910Sjsing } 1636dab3f910Sjsing /* 1637dab3f910Sjsing * close_accept_socket(); ret= -11; 1638dab3f910Sjsing */ 1639dab3f910Sjsing goto err; 1640dab3f910Sjsing } 1641dab3f910Sjsing if ((buf[0] == 'r') && 1642dab3f910Sjsing ((buf[1] == '\n') || (buf[1] == '\r'))) { 1643dab3f910Sjsing SSL_renegotiate(con); 1644dab3f910Sjsing i = SSL_do_handshake(con); 1645dab3f910Sjsing printf("SSL_do_handshake -> %d\n", i); 1646dab3f910Sjsing i = 0; /* 13; */ 1647dab3f910Sjsing continue; 1648dab3f910Sjsing /* 1649dab3f910Sjsing * RE-NEGOTIATE\n"); 1650dab3f910Sjsing */ 1651dab3f910Sjsing } 1652dab3f910Sjsing if ((buf[0] == 'R') && 1653dab3f910Sjsing ((buf[1] == '\n') || (buf[1] == '\r'))) { 1654dab3f910Sjsing SSL_set_verify(con, 16554da86b84Sinoguchi SSL_VERIFY_PEER | 16564da86b84Sinoguchi SSL_VERIFY_CLIENT_ONCE, 16574da86b84Sinoguchi NULL); 1658dab3f910Sjsing SSL_renegotiate(con); 1659dab3f910Sjsing i = SSL_do_handshake(con); 1660dab3f910Sjsing printf("SSL_do_handshake -> %d\n", i); 1661dab3f910Sjsing i = 0; /* 13; */ 1662dab3f910Sjsing continue; 1663dab3f910Sjsing /* 1664dab3f910Sjsing * RE-NEGOTIATE asking for client 1665dab3f910Sjsing * cert\n"); 1666dab3f910Sjsing */ 1667dab3f910Sjsing } 1668dab3f910Sjsing if (buf[0] == 'P') { 16694da86b84Sinoguchi static const char *str = 16704da86b84Sinoguchi "Lets print some clear text\n"; 16714da86b84Sinoguchi BIO_write(SSL_get_wbio(con), str, 16724da86b84Sinoguchi strlen(str)); 1673dab3f910Sjsing } 1674dab3f910Sjsing if (buf[0] == 'S') { 16754da86b84Sinoguchi print_stats(bio_s_out, 16764da86b84Sinoguchi SSL_get_SSL_CTX(con)); 1677dab3f910Sjsing } 1678dab3f910Sjsing } 1679dab3f910Sjsing l = k = 0; 1680dab3f910Sjsing for (;;) { 1681dab3f910Sjsing /* should do a select for the write */ 1682dab3f910Sjsing #ifdef RENEG 1683dab3f910Sjsing { 1684dab3f910Sjsing static count = 0; 1685dab3f910Sjsing if (++count == 100) { 1686dab3f910Sjsing count = 0; 1687dab3f910Sjsing SSL_renegotiate(con); 1688dab3f910Sjsing } 1689dab3f910Sjsing } 1690dab3f910Sjsing #endif 1691dab3f910Sjsing k = SSL_write(con, &(buf[l]), (unsigned int) i); 1692dab3f910Sjsing switch (SSL_get_error(con, k)) { 1693dab3f910Sjsing case SSL_ERROR_NONE: 1694dab3f910Sjsing break; 1695dab3f910Sjsing case SSL_ERROR_WANT_WRITE: 1696dab3f910Sjsing case SSL_ERROR_WANT_READ: 1697dab3f910Sjsing case SSL_ERROR_WANT_X509_LOOKUP: 1698dab3f910Sjsing BIO_printf(bio_s_out, "Write BLOCK\n"); 1699dab3f910Sjsing break; 1700dab3f910Sjsing case SSL_ERROR_SYSCALL: 1701dab3f910Sjsing case SSL_ERROR_SSL: 1702dab3f910Sjsing BIO_printf(bio_s_out, "ERROR\n"); 1703dab3f910Sjsing ERR_print_errors(bio_err); 1704dab3f910Sjsing ret = 1; 1705dab3f910Sjsing goto err; 1706dab3f910Sjsing /* break; */ 1707dab3f910Sjsing case SSL_ERROR_ZERO_RETURN: 1708dab3f910Sjsing BIO_printf(bio_s_out, "DONE\n"); 1709dab3f910Sjsing ret = 1; 1710dab3f910Sjsing goto err; 1711dab3f910Sjsing } 17125285fdefStb if (k <= 0) 17135285fdefStb continue; 1714dab3f910Sjsing l += k; 1715dab3f910Sjsing i -= k; 1716dab3f910Sjsing if (i <= 0) 1717dab3f910Sjsing break; 1718dab3f910Sjsing } 1719dab3f910Sjsing } 1720dab3f910Sjsing if (read_from_sslcon) { 1721dab3f910Sjsing if (!SSL_is_init_finished(con)) { 1722dab3f910Sjsing i = init_ssl_connection(con); 1723dab3f910Sjsing 1724dab3f910Sjsing if (i < 0) { 1725dab3f910Sjsing ret = 0; 1726dab3f910Sjsing goto err; 1727dab3f910Sjsing } else if (i == 0) { 1728dab3f910Sjsing ret = 1; 1729dab3f910Sjsing goto err; 1730dab3f910Sjsing } 1731dab3f910Sjsing } else { 1732dab3f910Sjsing again: 1733dab3f910Sjsing i = SSL_read(con, (char *) buf, bufsize); 1734dab3f910Sjsing switch (SSL_get_error(con, i)) { 1735dab3f910Sjsing case SSL_ERROR_NONE: { 1736dab3f910Sjsing int len, n; 1737dab3f910Sjsing for (len = 0; len < i;) { 1738dab3f910Sjsing do { 1739dab3f910Sjsing n = write(fileno(stdout), buf + len, i - len); 1740dab3f910Sjsing } while (n == -1 && errno == EINTR); 1741dab3f910Sjsing 17423aaa63ebSderaadt if (n == -1) { 1743dab3f910Sjsing BIO_printf(bio_s_out, "ERROR\n"); 1744dab3f910Sjsing goto err; 1745dab3f910Sjsing } 1746dab3f910Sjsing len += n; 1747dab3f910Sjsing } 1748dab3f910Sjsing } 1749dab3f910Sjsing if (SSL_pending(con)) 1750dab3f910Sjsing goto again; 1751dab3f910Sjsing break; 1752dab3f910Sjsing case SSL_ERROR_WANT_WRITE: 1753dab3f910Sjsing case SSL_ERROR_WANT_READ: 1754dab3f910Sjsing BIO_printf(bio_s_out, "Read BLOCK\n"); 1755dab3f910Sjsing break; 1756dab3f910Sjsing case SSL_ERROR_SYSCALL: 1757dab3f910Sjsing case SSL_ERROR_SSL: 1758dab3f910Sjsing BIO_printf(bio_s_out, "ERROR\n"); 1759dab3f910Sjsing ERR_print_errors(bio_err); 1760dab3f910Sjsing ret = 1; 1761dab3f910Sjsing goto err; 1762dab3f910Sjsing case SSL_ERROR_ZERO_RETURN: 1763dab3f910Sjsing BIO_printf(bio_s_out, "DONE\n"); 1764dab3f910Sjsing ret = 1; 1765dab3f910Sjsing goto err; 1766dab3f910Sjsing } 1767dab3f910Sjsing } 1768dab3f910Sjsing } 1769dab3f910Sjsing } 1770dab3f910Sjsing err: 1771dab3f910Sjsing if (con != NULL) { 1772dab3f910Sjsing BIO_printf(bio_s_out, "shutting down SSL\n"); 17734da86b84Sinoguchi SSL_set_shutdown(con, 17744da86b84Sinoguchi SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 1775dab3f910Sjsing SSL_free(con); 1776dab3f910Sjsing } 1777dab3f910Sjsing BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); 1778cf4db30dSderaadt freezero(buf, bufsize); 1779dab3f910Sjsing if (ret >= 0) 1780dab3f910Sjsing BIO_printf(bio_s_out, "ACCEPT\n"); 1781dab3f910Sjsing return (ret); 1782dab3f910Sjsing } 1783dab3f910Sjsing 1784dab3f910Sjsing static void 1785dab3f910Sjsing close_accept_socket(void) 1786dab3f910Sjsing { 1787dab3f910Sjsing BIO_printf(bio_err, "shutdown accept socket\n"); 1788dab3f910Sjsing if (accept_socket >= 0) { 1789dab3f910Sjsing shutdown(accept_socket, SHUT_RDWR); 1790dab3f910Sjsing close(accept_socket); 1791dab3f910Sjsing } 1792dab3f910Sjsing } 1793dab3f910Sjsing 1794dab3f910Sjsing static int 1795dab3f910Sjsing init_ssl_connection(SSL *con) 1796dab3f910Sjsing { 1797dab3f910Sjsing int i; 1798dab3f910Sjsing const char *str; 1799dab3f910Sjsing X509 *peer; 1800dab3f910Sjsing long verify_error; 1801dab3f910Sjsing char buf[BUFSIZ]; 1802dab3f910Sjsing unsigned char *exportedkeymat; 1803dab3f910Sjsing 1804dab3f910Sjsing i = SSL_accept(con); 1805dab3f910Sjsing if (i <= 0) { 1806dab3f910Sjsing if (BIO_sock_should_retry(i)) { 1807dab3f910Sjsing BIO_printf(bio_s_out, "DELAY\n"); 1808dab3f910Sjsing return (1); 1809dab3f910Sjsing } 1810dab3f910Sjsing BIO_printf(bio_err, "ERROR\n"); 1811dab3f910Sjsing verify_error = SSL_get_verify_result(con); 1812dab3f910Sjsing if (verify_error != X509_V_OK) { 1813dab3f910Sjsing BIO_printf(bio_err, "verify error:%s\n", 1814dab3f910Sjsing X509_verify_cert_error_string(verify_error)); 1815dab3f910Sjsing } else 1816dab3f910Sjsing ERR_print_errors(bio_err); 1817dab3f910Sjsing return (0); 1818dab3f910Sjsing } 1819dab3f910Sjsing PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); 1820dab3f910Sjsing 1821dab3f910Sjsing peer = SSL_get_peer_certificate(con); 1822dab3f910Sjsing if (peer != NULL) { 1823dab3f910Sjsing BIO_printf(bio_s_out, "Client certificate\n"); 1824dab3f910Sjsing PEM_write_bio_X509(bio_s_out, peer); 1825dab3f910Sjsing X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf); 1826dab3f910Sjsing BIO_printf(bio_s_out, "subject=%s\n", buf); 1827dab3f910Sjsing X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf); 1828dab3f910Sjsing BIO_printf(bio_s_out, "issuer=%s\n", buf); 1829dab3f910Sjsing X509_free(peer); 1830dab3f910Sjsing } 1831dab3f910Sjsing if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) 1832dab3f910Sjsing BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); 1833dab3f910Sjsing str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); 1834dab3f910Sjsing BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); 1835dab3f910Sjsing 1836dab3f910Sjsing #ifndef OPENSSL_NO_SRTP 1837dab3f910Sjsing { 1838dab3f910Sjsing SRTP_PROTECTION_PROFILE *srtp_profile 1839dab3f910Sjsing = SSL_get_selected_srtp_profile(con); 1840dab3f910Sjsing 1841dab3f910Sjsing if (srtp_profile) 18424da86b84Sinoguchi BIO_printf(bio_s_out, 18434da86b84Sinoguchi "SRTP Extension negotiated, profile=%s\n", 1844dab3f910Sjsing srtp_profile->name); 1845dab3f910Sjsing } 1846dab3f910Sjsing #endif 1847dab3f910Sjsing if (SSL_cache_hit(con)) 1848dab3f910Sjsing BIO_printf(bio_s_out, "Reused session-id\n"); 1849dab3f910Sjsing BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", 1850dab3f910Sjsing SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); 1851e7718adaStb if (cfg.keymatexportlabel != NULL) { 1852dab3f910Sjsing BIO_printf(bio_s_out, "Keying material exporter:\n"); 18534da86b84Sinoguchi BIO_printf(bio_s_out, " Label: '%s'\n", 1854e7718adaStb cfg.keymatexportlabel); 1855dab3f910Sjsing BIO_printf(bio_s_out, " Length: %i bytes\n", 1856e7718adaStb cfg.keymatexportlen); 1857e7718adaStb exportedkeymat = malloc(cfg.keymatexportlen); 1858dab3f910Sjsing if (exportedkeymat != NULL) { 1859dab3f910Sjsing if (!SSL_export_keying_material(con, exportedkeymat, 1860e7718adaStb cfg.keymatexportlen, 1861e7718adaStb cfg.keymatexportlabel, 1862e7718adaStb strlen(cfg.keymatexportlabel), 1863dab3f910Sjsing NULL, 0, 0)) { 1864dab3f910Sjsing BIO_printf(bio_s_out, " Error\n"); 1865dab3f910Sjsing } else { 1866dab3f910Sjsing BIO_printf(bio_s_out, " Keying material: "); 1867e7718adaStb for (i = 0; i < cfg.keymatexportlen; i++) 1868dab3f910Sjsing BIO_printf(bio_s_out, "%02X", 1869dab3f910Sjsing exportedkeymat[i]); 1870dab3f910Sjsing BIO_printf(bio_s_out, "\n"); 1871dab3f910Sjsing } 1872dab3f910Sjsing free(exportedkeymat); 1873dab3f910Sjsing } 1874dab3f910Sjsing } 1875dab3f910Sjsing return (1); 1876dab3f910Sjsing } 1877dab3f910Sjsing 1878dab3f910Sjsing #ifndef OPENSSL_NO_DH 1879dab3f910Sjsing static DH * 1880dab3f910Sjsing load_dh_param(const char *dhfile) 1881dab3f910Sjsing { 1882dab3f910Sjsing DH *ret = NULL; 1883dab3f910Sjsing BIO *bio; 1884dab3f910Sjsing 1885dab3f910Sjsing if ((bio = BIO_new_file(dhfile, "r")) == NULL) 1886dab3f910Sjsing goto err; 1887dab3f910Sjsing ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); 1888dab3f910Sjsing err: 1889dab3f910Sjsing BIO_free(bio); 1890dab3f910Sjsing return (ret); 1891dab3f910Sjsing } 1892dab3f910Sjsing #endif 1893dab3f910Sjsing 1894dab3f910Sjsing static int 18957537a7c2Stb www_body(int s, unsigned char *context) 1896dab3f910Sjsing { 1897dab3f910Sjsing char *buf = NULL; 1898dab3f910Sjsing int ret = 1; 1899dab3f910Sjsing int i, j, k, dot; 1900dab3f910Sjsing SSL *con; 1901dab3f910Sjsing const SSL_CIPHER *c; 1902dab3f910Sjsing BIO *io, *ssl_bio, *sbio; 1903dab3f910Sjsing 1904dab3f910Sjsing buf = malloc(bufsize); 1905dab3f910Sjsing if (buf == NULL) 1906dab3f910Sjsing return (0); 1907dab3f910Sjsing io = BIO_new(BIO_f_buffer()); 1908dab3f910Sjsing ssl_bio = BIO_new(BIO_f_ssl()); 1909dab3f910Sjsing if ((io == NULL) || (ssl_bio == NULL)) 1910dab3f910Sjsing goto err; 1911dab3f910Sjsing 1912e7718adaStb if (cfg.nbio) { 1913e7718adaStb if (!cfg.quiet) 1914dab3f910Sjsing BIO_printf(bio_err, "turning on non blocking io\n"); 1915fcc700e7Sbcook if (!BIO_socket_nbio(s, 1)) 1916dab3f910Sjsing ERR_print_errors(bio_err); 1917dab3f910Sjsing } 1918dab3f910Sjsing 1919dab3f910Sjsing /* lets make the output buffer a reasonable size */ 1920dab3f910Sjsing if (!BIO_set_write_buffer_size(io, bufsize)) 1921dab3f910Sjsing goto err; 1922dab3f910Sjsing 1923dab3f910Sjsing if ((con = SSL_new(ctx)) == NULL) 1924dab3f910Sjsing goto err; 1925e7718adaStb if (cfg.tlsextdebug) { 1926dab3f910Sjsing SSL_set_tlsext_debug_callback(con, tlsext_cb); 1927dab3f910Sjsing SSL_set_tlsext_debug_arg(con, bio_s_out); 1928dab3f910Sjsing } 1929dab3f910Sjsing if (context) 1930dab3f910Sjsing SSL_set_session_id_context(con, context, 1931dab3f910Sjsing strlen((char *) context)); 1932dab3f910Sjsing 1933dab3f910Sjsing sbio = BIO_new_socket(s, BIO_NOCLOSE); 1934e7718adaStb if (cfg.nbio_test) { 1935dab3f910Sjsing BIO *test; 1936dab3f910Sjsing 1937dab3f910Sjsing test = BIO_new(BIO_f_nbio_test()); 1938dab3f910Sjsing sbio = BIO_push(test, sbio); 1939dab3f910Sjsing } 1940dab3f910Sjsing SSL_set_bio(con, sbio, sbio); 1941dab3f910Sjsing SSL_set_accept_state(con); 1942dab3f910Sjsing 1943dab3f910Sjsing /* SSL_set_fd(con,s); */ 1944dab3f910Sjsing BIO_set_ssl(ssl_bio, con, BIO_CLOSE); 1945dab3f910Sjsing BIO_push(io, ssl_bio); 1946dab3f910Sjsing 1947e7718adaStb if (cfg.debug) { 1948dab3f910Sjsing BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); 1949dab3f910Sjsing BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); 1950dab3f910Sjsing } 1951e7718adaStb if (cfg.msg) { 1952dab3f910Sjsing SSL_set_msg_callback(con, msg_cb); 1953dab3f910Sjsing SSL_set_msg_callback_arg(con, bio_s_out); 1954dab3f910Sjsing } 1955dab3f910Sjsing for (;;) { 1956dab3f910Sjsing i = BIO_gets(io, buf, bufsize - 1); 1957dab3f910Sjsing if (i < 0) { /* error */ 1958dab3f910Sjsing if (!BIO_should_retry(io)) { 1959e7718adaStb if (!cfg.quiet) 1960dab3f910Sjsing ERR_print_errors(bio_err); 1961dab3f910Sjsing goto err; 1962dab3f910Sjsing } else { 1963e7718adaStb if (cfg.debug) { 1964dab3f910Sjsing BIO_printf(bio_s_out, "read R BLOCK\n"); 1965dab3f910Sjsing sleep(1); 196630d5484aSbeck } 1967dab3f910Sjsing continue; 1968dab3f910Sjsing } 1969dab3f910Sjsing } else if (i == 0) { /* end of input */ 1970dab3f910Sjsing ret = 1; 1971dab3f910Sjsing goto end; 1972dab3f910Sjsing } 1973dab3f910Sjsing /* else we have data */ 1974e7718adaStb if (((cfg.www == 1) && 19754da86b84Sinoguchi (strncmp("GET ", buf, 4) == 0)) || 1976e7718adaStb ((cfg.www == 2) && 19774da86b84Sinoguchi (strncmp("GET /stats ", buf, 11) == 0))) { 1978dab3f910Sjsing char *p; 1979dab3f910Sjsing X509 *peer; 1980dab3f910Sjsing STACK_OF(SSL_CIPHER) *sk; 1981dab3f910Sjsing static const char *space = " "; 1982dab3f910Sjsing 1983dab3f910Sjsing BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 1984dab3f910Sjsing BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n"); 1985dab3f910Sjsing BIO_puts(io, "<pre>\n"); 1986dab3f910Sjsing /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ 1987dab3f910Sjsing BIO_puts(io, "\n"); 1988dab3f910Sjsing for (i = 0; i < local_argc; i++) { 1989dab3f910Sjsing BIO_puts(io, local_argv[i]); 1990dab3f910Sjsing BIO_write(io, " ", 1); 1991dab3f910Sjsing } 1992dab3f910Sjsing BIO_puts(io, "\n"); 1993dab3f910Sjsing 1994dab3f910Sjsing BIO_printf(io, 1995dab3f910Sjsing "Secure Renegotiation IS%s supported\n", 1996dab3f910Sjsing SSL_get_secure_renegotiation_support(con) ? 1997dab3f910Sjsing "" : " NOT"); 1998dab3f910Sjsing 1999dab3f910Sjsing /* 2000dab3f910Sjsing * The following is evil and should not really be 2001dab3f910Sjsing * done 2002dab3f910Sjsing */ 20034da86b84Sinoguchi BIO_printf(io, 20044da86b84Sinoguchi "Ciphers supported in s_server binary\n"); 2005dab3f910Sjsing sk = SSL_get_ciphers(con); 2006dab3f910Sjsing j = sk_SSL_CIPHER_num(sk); 2007dab3f910Sjsing for (i = 0; i < j; i++) { 2008dab3f910Sjsing c = sk_SSL_CIPHER_value(sk, i); 2009dab3f910Sjsing BIO_printf(io, "%-11s:%-25s", 2010dab3f910Sjsing SSL_CIPHER_get_version(c), 2011dab3f910Sjsing SSL_CIPHER_get_name(c)); 2012dab3f910Sjsing if ((((i + 1) % 2) == 0) && (i + 1 != j)) 2013dab3f910Sjsing BIO_puts(io, "\n"); 2014dab3f910Sjsing } 2015dab3f910Sjsing BIO_puts(io, "\n"); 2016dab3f910Sjsing p = SSL_get_shared_ciphers(con, buf, bufsize); 2017dab3f910Sjsing if (p != NULL) { 20184da86b84Sinoguchi BIO_printf(io, 20194da86b84Sinoguchi "---\nCiphers common between both SSL end points:\n"); 2020dab3f910Sjsing j = i = 0; 2021dab3f910Sjsing while (*p) { 2022dab3f910Sjsing if (*p == ':') { 2023dab3f910Sjsing BIO_write(io, space, 26 - j); 2024dab3f910Sjsing i++; 2025dab3f910Sjsing j = 0; 20264da86b84Sinoguchi BIO_write(io, 20274da86b84Sinoguchi ((i % 3) ? " " : "\n"), 1); 2028dab3f910Sjsing } else { 2029dab3f910Sjsing BIO_write(io, p, 1); 2030dab3f910Sjsing j++; 2031dab3f910Sjsing } 2032dab3f910Sjsing p++; 2033dab3f910Sjsing } 2034dab3f910Sjsing BIO_puts(io, "\n"); 2035dab3f910Sjsing } 2036dab3f910Sjsing BIO_printf(io, (SSL_cache_hit(con) 2037dab3f910Sjsing ? "---\nReused, " 2038dab3f910Sjsing : "---\nNew, ")); 2039dab3f910Sjsing c = SSL_get_current_cipher(con); 2040dab3f910Sjsing BIO_printf(io, "%s, Cipher is %s\n", 2041dab3f910Sjsing SSL_CIPHER_get_version(c), 2042dab3f910Sjsing SSL_CIPHER_get_name(c)); 2043dab3f910Sjsing SSL_SESSION_print(io, SSL_get_session(con)); 2044dab3f910Sjsing BIO_printf(io, "---\n"); 2045dab3f910Sjsing print_stats(io, SSL_get_SSL_CTX(con)); 2046dab3f910Sjsing BIO_printf(io, "---\n"); 2047dab3f910Sjsing peer = SSL_get_peer_certificate(con); 2048dab3f910Sjsing if (peer != NULL) { 2049dab3f910Sjsing BIO_printf(io, "Client certificate\n"); 2050dab3f910Sjsing X509_print(io, peer); 2051dab3f910Sjsing PEM_write_bio_X509(io, peer); 2052dab3f910Sjsing } else 20534da86b84Sinoguchi BIO_puts(io, 20544da86b84Sinoguchi "no client certificate available\n"); 2055dab3f910Sjsing BIO_puts(io, "</BODY></HTML>\r\n\r\n"); 2056dab3f910Sjsing break; 2057e7718adaStb } else if ((cfg.www == 2 || 2058e7718adaStb cfg.www == 3) && 20594da86b84Sinoguchi (strncmp("GET /", buf, 5) == 0)) { 2060dab3f910Sjsing BIO *file; 2061dab3f910Sjsing char *p, *e; 2062dab3f910Sjsing static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; 2063dab3f910Sjsing 2064dab3f910Sjsing /* skip the '/' */ 2065dab3f910Sjsing p = &(buf[5]); 2066dab3f910Sjsing 2067dab3f910Sjsing dot = 1; 2068dab3f910Sjsing for (e = p; *e != '\0'; e++) { 2069dab3f910Sjsing if (e[0] == ' ') 2070dab3f910Sjsing break; 2071dab3f910Sjsing 2072dab3f910Sjsing switch (dot) { 2073dab3f910Sjsing case 1: 2074dab3f910Sjsing dot = (e[0] == '.') ? 2 : 0; 2075dab3f910Sjsing break; 2076dab3f910Sjsing case 2: 2077dab3f910Sjsing dot = (e[0] == '.') ? 3 : 0; 2078dab3f910Sjsing break; 2079dab3f910Sjsing case 3: 20804da86b84Sinoguchi dot = (e[0] == '/' || e[0] == '\\') ? 20814da86b84Sinoguchi -1 : 0; 2082dab3f910Sjsing break; 2083dab3f910Sjsing } 2084dab3f910Sjsing if (dot == 0) 20854da86b84Sinoguchi dot = (e[0] == '/' || e[0] == '\\') ? 20864da86b84Sinoguchi 1 : 0; 2087dab3f910Sjsing } 2088dab3f910Sjsing dot = (dot == 3) || (dot == -1); /* filename contains 2089dab3f910Sjsing * ".." component */ 2090dab3f910Sjsing 2091dab3f910Sjsing if (*e == '\0') { 2092dab3f910Sjsing BIO_puts(io, text); 20934da86b84Sinoguchi BIO_printf(io, 20944da86b84Sinoguchi "'%s' is an invalid file name\r\n", p); 2095dab3f910Sjsing break; 2096dab3f910Sjsing } 2097dab3f910Sjsing *e = '\0'; 2098dab3f910Sjsing 2099dab3f910Sjsing if (dot) { 2100dab3f910Sjsing BIO_puts(io, text); 21014da86b84Sinoguchi BIO_printf(io, 21024da86b84Sinoguchi "'%s' contains '..' reference\r\n", p); 2103dab3f910Sjsing break; 2104dab3f910Sjsing } 2105dab3f910Sjsing if (*p == '/') { 2106dab3f910Sjsing BIO_puts(io, text); 21074da86b84Sinoguchi BIO_printf(io, 21084da86b84Sinoguchi "'%s' is an invalid path\r\n", p); 2109dab3f910Sjsing break; 2110dab3f910Sjsing } 2111dab3f910Sjsing /* if a directory, do the index thang */ 2112dab3f910Sjsing if (app_isdir(p) > 0) { 2113dab3f910Sjsing BIO_puts(io, text); 2114dab3f910Sjsing BIO_printf(io, "'%s' is a directory\r\n", p); 2115dab3f910Sjsing break; 2116dab3f910Sjsing } 2117dab3f910Sjsing if ((file = BIO_new_file(p, "r")) == NULL) { 2118dab3f910Sjsing BIO_puts(io, text); 2119dab3f910Sjsing BIO_printf(io, "Error opening '%s'\r\n", p); 2120dab3f910Sjsing ERR_print_errors(io); 2121dab3f910Sjsing break; 2122dab3f910Sjsing } 2123e7718adaStb if (!cfg.quiet) 2124dab3f910Sjsing BIO_printf(bio_err, "FILE:%s\n", p); 2125dab3f910Sjsing 2126e7718adaStb if (cfg.www == 2) { 2127dab3f910Sjsing i = strlen(p); 2128dab3f910Sjsing if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) || 2129dab3f910Sjsing ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) || 2130dab3f910Sjsing ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0))) 2131dab3f910Sjsing BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 2132dab3f910Sjsing else 2133dab3f910Sjsing BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); 2134dab3f910Sjsing } 2135dab3f910Sjsing /* send the file */ 2136dab3f910Sjsing for (;;) { 2137dab3f910Sjsing i = BIO_read(file, buf, bufsize); 2138dab3f910Sjsing if (i <= 0) 2139dab3f910Sjsing break; 2140dab3f910Sjsing 2141dab3f910Sjsing #ifdef RENEG 2142dab3f910Sjsing total_bytes += i; 2143dab3f910Sjsing fprintf(stderr, "%d\n", i); 2144dab3f910Sjsing if (total_bytes > 3 * 1024) { 2145dab3f910Sjsing total_bytes = 0; 2146dab3f910Sjsing fprintf(stderr, "RENEGOTIATE\n"); 2147dab3f910Sjsing SSL_renegotiate(con); 2148dab3f910Sjsing } 2149dab3f910Sjsing #endif 2150dab3f910Sjsing 2151dab3f910Sjsing for (j = 0; j < i;) { 2152dab3f910Sjsing #ifdef RENEG 2153dab3f910Sjsing { 2154dab3f910Sjsing static count = 0; 2155dab3f910Sjsing if (++count == 13) { 2156dab3f910Sjsing SSL_renegotiate(con); 2157dab3f910Sjsing } 2158dab3f910Sjsing } 2159dab3f910Sjsing #endif 2160dab3f910Sjsing k = BIO_write(io, &(buf[j]), i - j); 2161dab3f910Sjsing if (k <= 0) { 2162dab3f910Sjsing if (!BIO_should_retry(io)) 2163dab3f910Sjsing goto write_error; 2164dab3f910Sjsing else { 21654da86b84Sinoguchi BIO_printf(bio_s_out, 21664da86b84Sinoguchi "rwrite W BLOCK\n"); 2167dab3f910Sjsing } 2168dab3f910Sjsing } else { 2169dab3f910Sjsing j += k; 2170dab3f910Sjsing } 2171dab3f910Sjsing } 2172dab3f910Sjsing } 2173dab3f910Sjsing write_error: 2174dab3f910Sjsing BIO_free(file); 2175dab3f910Sjsing break; 2176dab3f910Sjsing } 2177dab3f910Sjsing } 2178dab3f910Sjsing 2179dab3f910Sjsing for (;;) { 2180dab3f910Sjsing i = (int) BIO_flush(io); 2181dab3f910Sjsing if (i <= 0) { 2182dab3f910Sjsing if (!BIO_should_retry(io)) 2183dab3f910Sjsing break; 2184dab3f910Sjsing } else 2185dab3f910Sjsing break; 2186dab3f910Sjsing } 2187dab3f910Sjsing end: 2188dab3f910Sjsing /* make sure we re-use sessions */ 2189dab3f910Sjsing SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); 2190dab3f910Sjsing 2191dab3f910Sjsing err: 2192dab3f910Sjsing 2193dab3f910Sjsing if (ret >= 0) 2194dab3f910Sjsing BIO_printf(bio_s_out, "ACCEPT\n"); 2195dab3f910Sjsing 2196dab3f910Sjsing free(buf); 2197dab3f910Sjsing BIO_free_all(io); 2198dab3f910Sjsing /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/ 2199dab3f910Sjsing return (ret); 2200dab3f910Sjsing } 2201dab3f910Sjsing 2202dab3f910Sjsing #define MAX_SESSION_ID_ATTEMPTS 10 2203dab3f910Sjsing static int 220472a107cfSinoguchi generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len) 2205dab3f910Sjsing { 2206dab3f910Sjsing unsigned int count = 0; 2207dab3f910Sjsing do { 2208fd6ab616Sjsing arc4random_buf(id, *id_len); 2209dab3f910Sjsing /* 2210dab3f910Sjsing * Prefix the session_id with the required prefix. NB: If our 2211dab3f910Sjsing * prefix is too long, clip it - but there will be worse 2212dab3f910Sjsing * effects anyway, eg. the server could only possibly create 2213dab3f910Sjsing * 1 session ID (ie. the prefix!) so all future session 2214dab3f910Sjsing * negotiations will fail due to conflicts. 2215dab3f910Sjsing */ 2216e7718adaStb memcpy(id, cfg.session_id_prefix, 2217e7718adaStb (strlen(cfg.session_id_prefix) < *id_len) ? 2218e7718adaStb strlen(cfg.session_id_prefix) : *id_len); 2219dab3f910Sjsing } 2220dab3f910Sjsing while (SSL_has_matching_session_id(ssl, id, *id_len) && 2221dab3f910Sjsing (++count < MAX_SESSION_ID_ATTEMPTS)); 2222dab3f910Sjsing if (count >= MAX_SESSION_ID_ATTEMPTS) 2223dab3f910Sjsing return 0; 2224dab3f910Sjsing return 1; 2225dab3f910Sjsing } 222672a107cfSinoguchi 222772a107cfSinoguchi static int 222872a107cfSinoguchi ssl_servername_cb(SSL *s, int *ad, void *arg) 222972a107cfSinoguchi { 223072a107cfSinoguchi tlsextctx *p = (tlsextctx *) arg; 22314da86b84Sinoguchi const char *servername = SSL_get_servername(s, 22324da86b84Sinoguchi TLSEXT_NAMETYPE_host_name); 22334da86b84Sinoguchi 223472a107cfSinoguchi if (servername && p->biodebug) 22354da86b84Sinoguchi BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", 22364da86b84Sinoguchi servername); 223772a107cfSinoguchi 223872a107cfSinoguchi if (!p->servername) 223972a107cfSinoguchi return SSL_TLSEXT_ERR_NOACK; 224072a107cfSinoguchi 224172a107cfSinoguchi if (servername) { 224272a107cfSinoguchi if (strcmp(servername, p->servername)) 224372a107cfSinoguchi return p->extension_error; 224472a107cfSinoguchi if (ctx2) { 224572a107cfSinoguchi BIO_printf(p->biodebug, "Switching server context.\n"); 224672a107cfSinoguchi SSL_set_SSL_CTX(s, ctx2); 224772a107cfSinoguchi } 224872a107cfSinoguchi } 224972a107cfSinoguchi return SSL_TLSEXT_ERR_OK; 225072a107cfSinoguchi } 225172a107cfSinoguchi 225272a107cfSinoguchi /* Certificate Status callback. This is called when a client includes a 225372a107cfSinoguchi * certificate status request extension. 225472a107cfSinoguchi * 225572a107cfSinoguchi * This is a simplified version. It examines certificates each time and 225672a107cfSinoguchi * makes one OCSP responder query for each request. 225772a107cfSinoguchi * 225872a107cfSinoguchi * A full version would store details such as the OCSP certificate IDs and 225972a107cfSinoguchi * minimise the number of OCSP responses by caching them until they were 226072a107cfSinoguchi * considered "expired". 226172a107cfSinoguchi */ 226272a107cfSinoguchi 226372a107cfSinoguchi static int 226472a107cfSinoguchi cert_status_cb(SSL *s, void *arg) 226572a107cfSinoguchi { 226672a107cfSinoguchi tlsextstatusctx *srctx = arg; 226772a107cfSinoguchi BIO *err = srctx->err; 226872a107cfSinoguchi char *host = NULL, *port = NULL, *path = NULL; 226972a107cfSinoguchi int use_ssl; 227072a107cfSinoguchi unsigned char *rspder = NULL; 227172a107cfSinoguchi int rspderlen; 227272a107cfSinoguchi STACK_OF(OPENSSL_STRING) *aia = NULL; 227372a107cfSinoguchi X509 *x = NULL; 2274dfa067d0Stb X509_STORE_CTX *inctx = NULL; 22753d522683Stb X509_OBJECT *obj = NULL; 227672a107cfSinoguchi OCSP_REQUEST *req = NULL; 227772a107cfSinoguchi OCSP_RESPONSE *resp = NULL; 227872a107cfSinoguchi OCSP_CERTID *id = NULL; 227972a107cfSinoguchi STACK_OF(X509_EXTENSION) *exts; 228072a107cfSinoguchi int ret = SSL_TLSEXT_ERR_NOACK; 228172a107cfSinoguchi int i; 228272a107cfSinoguchi 228372a107cfSinoguchi if (srctx->verbose) 228472a107cfSinoguchi BIO_puts(err, "cert_status: callback called\n"); 228572a107cfSinoguchi /* Build up OCSP query from server certificate */ 228672a107cfSinoguchi x = SSL_get_certificate(s); 228772a107cfSinoguchi aia = X509_get1_ocsp(x); 228872a107cfSinoguchi if (aia) { 228972a107cfSinoguchi if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), 229072a107cfSinoguchi &host, &port, &path, &use_ssl)) { 229172a107cfSinoguchi BIO_puts(err, "cert_status: can't parse AIA URL\n"); 229272a107cfSinoguchi goto err; 229372a107cfSinoguchi } 229472a107cfSinoguchi if (srctx->verbose) 229572a107cfSinoguchi BIO_printf(err, "cert_status: AIA URL: %s\n", 229672a107cfSinoguchi sk_OPENSSL_STRING_value(aia, 0)); 229772a107cfSinoguchi } else { 229872a107cfSinoguchi if (!srctx->host) { 22994da86b84Sinoguchi BIO_puts(srctx->err, 23004da86b84Sinoguchi "cert_status: no AIA and no default responder URL\n"); 230172a107cfSinoguchi goto done; 230272a107cfSinoguchi } 230372a107cfSinoguchi host = srctx->host; 230472a107cfSinoguchi path = srctx->path; 230572a107cfSinoguchi port = srctx->port; 230672a107cfSinoguchi use_ssl = srctx->use_ssl; 230772a107cfSinoguchi } 230872a107cfSinoguchi 2309dfa067d0Stb if ((inctx = X509_STORE_CTX_new()) == NULL) 2310dfa067d0Stb goto err; 2311dfa067d0Stb 2312dfa067d0Stb if (!X509_STORE_CTX_init(inctx, 231372a107cfSinoguchi SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), 231472a107cfSinoguchi NULL, NULL)) 231572a107cfSinoguchi goto err; 23163d522683Stb if ((obj = X509_OBJECT_new()) == NULL) 23173d522683Stb goto done; 2318dfa067d0Stb if (X509_STORE_get_by_subject(inctx, X509_LU_X509, 23193d522683Stb X509_get_issuer_name(x), obj) <= 0) { 23204da86b84Sinoguchi BIO_puts(err, 23214da86b84Sinoguchi "cert_status: Can't retrieve issuer certificate.\n"); 2322dfa067d0Stb X509_STORE_CTX_cleanup(inctx); 232372a107cfSinoguchi goto done; 232472a107cfSinoguchi } 232572a107cfSinoguchi req = OCSP_REQUEST_new(); 232672a107cfSinoguchi if (!req) 232772a107cfSinoguchi goto err; 23283d522683Stb id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj)); 23293d522683Stb X509_OBJECT_free(obj); 23303d522683Stb obj = NULL; 2331dfa067d0Stb X509_STORE_CTX_free(inctx); 2332dfa067d0Stb inctx = NULL; 233372a107cfSinoguchi if (!id) 233472a107cfSinoguchi goto err; 233572a107cfSinoguchi if (!OCSP_request_add0_id(req, id)) 233672a107cfSinoguchi goto err; 233772a107cfSinoguchi id = NULL; 233872a107cfSinoguchi /* Add any extensions to the request */ 233972a107cfSinoguchi SSL_get_tlsext_status_exts(s, &exts); 234072a107cfSinoguchi for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { 234172a107cfSinoguchi X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); 234272a107cfSinoguchi if (!OCSP_REQUEST_add_ext(req, ext, -1)) 234372a107cfSinoguchi goto err; 234472a107cfSinoguchi } 234572a107cfSinoguchi resp = process_responder(err, req, host, path, port, use_ssl, NULL, 234672a107cfSinoguchi srctx->timeout); 234772a107cfSinoguchi if (!resp) { 234872a107cfSinoguchi BIO_puts(err, "cert_status: error querying responder\n"); 234972a107cfSinoguchi goto done; 235072a107cfSinoguchi } 235172a107cfSinoguchi rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); 235272a107cfSinoguchi if (rspderlen <= 0) 235372a107cfSinoguchi goto err; 235472a107cfSinoguchi SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); 235572a107cfSinoguchi if (srctx->verbose) { 235672a107cfSinoguchi BIO_puts(err, "cert_status: ocsp response sent:\n"); 235772a107cfSinoguchi OCSP_RESPONSE_print(err, resp, 2); 235872a107cfSinoguchi } 235972a107cfSinoguchi ret = SSL_TLSEXT_ERR_OK; 236072a107cfSinoguchi done: 2361dfa067d0Stb X509_STORE_CTX_free(inctx); 23623d522683Stb X509_OBJECT_free(obj); 236372a107cfSinoguchi if (ret != SSL_TLSEXT_ERR_OK) 236472a107cfSinoguchi ERR_print_errors(err); 236572a107cfSinoguchi if (aia) { 236672a107cfSinoguchi free(host); 236772a107cfSinoguchi free(path); 236872a107cfSinoguchi free(port); 236972a107cfSinoguchi X509_email_free(aia); 237072a107cfSinoguchi } 237172a107cfSinoguchi if (id) 237272a107cfSinoguchi OCSP_CERTID_free(id); 237372a107cfSinoguchi if (req) 237472a107cfSinoguchi OCSP_REQUEST_free(req); 237572a107cfSinoguchi if (resp) 237672a107cfSinoguchi OCSP_RESPONSE_free(resp); 237772a107cfSinoguchi return ret; 237872a107cfSinoguchi err: 237972a107cfSinoguchi ret = SSL_TLSEXT_ERR_ALERT_FATAL; 238072a107cfSinoguchi goto done; 238172a107cfSinoguchi } 238272a107cfSinoguchi 238372a107cfSinoguchi static int 238472a107cfSinoguchi alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, 238572a107cfSinoguchi const unsigned char *in, unsigned int inlen, void *arg) 238672a107cfSinoguchi { 238772a107cfSinoguchi tlsextalpnctx *alpn_ctx = arg; 238872a107cfSinoguchi 2389e7718adaStb if (!cfg.quiet) { 239072a107cfSinoguchi /* We can assume that in is syntactically valid. */ 239172a107cfSinoguchi unsigned i; 239272a107cfSinoguchi 239372a107cfSinoguchi BIO_printf(bio_s_out, 239472a107cfSinoguchi "ALPN protocols advertised by the client: "); 239572a107cfSinoguchi for (i = 0; i < inlen; ) { 239672a107cfSinoguchi if (i) 239772a107cfSinoguchi BIO_write(bio_s_out, ", ", 2); 239872a107cfSinoguchi BIO_write(bio_s_out, &in[i + 1], in[i]); 239972a107cfSinoguchi i += in[i] + 1; 240072a107cfSinoguchi } 240172a107cfSinoguchi BIO_write(bio_s_out, "\n", 1); 240272a107cfSinoguchi } 240372a107cfSinoguchi 240472a107cfSinoguchi if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data, 240572a107cfSinoguchi alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED) 240672a107cfSinoguchi return (SSL_TLSEXT_ERR_NOACK); 240772a107cfSinoguchi 2408e7718adaStb if (!cfg.quiet) { 240972a107cfSinoguchi BIO_printf(bio_s_out, "ALPN protocols selected: "); 241072a107cfSinoguchi BIO_write(bio_s_out, *out, *outlen); 241172a107cfSinoguchi BIO_write(bio_s_out, "\n", 1); 241272a107cfSinoguchi } 241372a107cfSinoguchi 241472a107cfSinoguchi return (SSL_TLSEXT_ERR_OK); 241572a107cfSinoguchi } 2416