1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: s_server.c,v 1.54 2021/12/06 11:06:58 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino /* ====================================================================
59f5b1c8a1SJohn Marino  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60f5b1c8a1SJohn Marino  *
61f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
62f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
63f5b1c8a1SJohn Marino  * are met:
64f5b1c8a1SJohn Marino  *
65f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the above copyright
66f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
67f5b1c8a1SJohn Marino  *
68f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
69f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in
70f5b1c8a1SJohn Marino  *    the documentation and/or other materials provided with the
71f5b1c8a1SJohn Marino  *    distribution.
72f5b1c8a1SJohn Marino  *
73f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this
74f5b1c8a1SJohn Marino  *    software must display the following acknowledgment:
75f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
76f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77f5b1c8a1SJohn Marino  *
78f5b1c8a1SJohn Marino  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79f5b1c8a1SJohn Marino  *    endorse or promote products derived from this software without
80f5b1c8a1SJohn Marino  *    prior written permission. For written permission, please contact
81f5b1c8a1SJohn Marino  *    openssl-core@openssl.org.
82f5b1c8a1SJohn Marino  *
83f5b1c8a1SJohn Marino  * 5. Products derived from this software may not be called "OpenSSL"
84f5b1c8a1SJohn Marino  *    nor may "OpenSSL" appear in their names without prior written
85f5b1c8a1SJohn Marino  *    permission of the OpenSSL Project.
86f5b1c8a1SJohn Marino  *
87f5b1c8a1SJohn Marino  * 6. Redistributions of any form whatsoever must retain the following
88f5b1c8a1SJohn Marino  *    acknowledgment:
89f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
90f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91f5b1c8a1SJohn Marino  *
92f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93f5b1c8a1SJohn Marino  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95f5b1c8a1SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96f5b1c8a1SJohn Marino  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97f5b1c8a1SJohn Marino  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98f5b1c8a1SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99f5b1c8a1SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101f5b1c8a1SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102f5b1c8a1SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103f5b1c8a1SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
104f5b1c8a1SJohn Marino  * ====================================================================
105f5b1c8a1SJohn Marino  *
106f5b1c8a1SJohn Marino  * This product includes cryptographic software written by Eric Young
107f5b1c8a1SJohn Marino  * (eay@cryptsoft.com).  This product includes software written by Tim
108f5b1c8a1SJohn Marino  * Hudson (tjh@cryptsoft.com).
109f5b1c8a1SJohn Marino  *
110f5b1c8a1SJohn Marino  */
111f5b1c8a1SJohn Marino /* ====================================================================
112f5b1c8a1SJohn Marino  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113f5b1c8a1SJohn Marino  * ECC cipher suite support in OpenSSL originally developed by
114f5b1c8a1SJohn Marino  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115f5b1c8a1SJohn Marino  */
116f5b1c8a1SJohn Marino /* ====================================================================
117f5b1c8a1SJohn Marino  * Copyright 2005 Nokia. All rights reserved.
118f5b1c8a1SJohn Marino  *
119f5b1c8a1SJohn Marino  * The portions of the attached software ("Contribution") is developed by
120f5b1c8a1SJohn Marino  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
121f5b1c8a1SJohn Marino  * license.
122f5b1c8a1SJohn Marino  *
123f5b1c8a1SJohn Marino  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
124f5b1c8a1SJohn Marino  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
125f5b1c8a1SJohn Marino  * support (see RFC 4279) to OpenSSL.
126f5b1c8a1SJohn Marino  *
127f5b1c8a1SJohn Marino  * No patent licenses or other rights except those expressly stated in
128f5b1c8a1SJohn Marino  * the OpenSSL open source license shall be deemed granted or received
129f5b1c8a1SJohn Marino  * expressly, by implication, estoppel, or otherwise.
130f5b1c8a1SJohn Marino  *
131f5b1c8a1SJohn Marino  * No assurances are provided by Nokia that the Contribution does not
132f5b1c8a1SJohn Marino  * infringe the patent or other intellectual property rights of any third
133f5b1c8a1SJohn Marino  * party or that the license provides you with all the necessary rights
134f5b1c8a1SJohn Marino  * to make use of the Contribution.
135f5b1c8a1SJohn Marino  *
136f5b1c8a1SJohn Marino  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
137f5b1c8a1SJohn Marino  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
138f5b1c8a1SJohn Marino  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
139f5b1c8a1SJohn Marino  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
140f5b1c8a1SJohn Marino  * OTHERWISE.
141f5b1c8a1SJohn Marino  */
142f5b1c8a1SJohn Marino 
143f5b1c8a1SJohn Marino /* Until the key-gen callbacks are modified to use newer prototypes, we allow
144f5b1c8a1SJohn Marino  * deprecated functions for openssl-internal code */
145f5b1c8a1SJohn Marino #ifdef OPENSSL_NO_DEPRECATED
146f5b1c8a1SJohn Marino #undef OPENSSL_NO_DEPRECATED
147f5b1c8a1SJohn Marino #endif
148f5b1c8a1SJohn Marino 
149f5b1c8a1SJohn Marino #include <sys/types.h>
150f5b1c8a1SJohn Marino #include <sys/socket.h>
151f5b1c8a1SJohn Marino 
152f5b1c8a1SJohn Marino #include <assert.h>
153f5b1c8a1SJohn Marino #include <ctype.h>
154f5b1c8a1SJohn Marino #include <stdio.h>
155f5b1c8a1SJohn Marino #include <stdlib.h>
156f5b1c8a1SJohn Marino #include <limits.h>
157f5b1c8a1SJohn Marino #include <string.h>
158f5b1c8a1SJohn Marino #include <unistd.h>
159f5b1c8a1SJohn Marino #include <poll.h>
160f5b1c8a1SJohn Marino 
161f5b1c8a1SJohn Marino #include "apps.h"
162f5b1c8a1SJohn Marino 
163f5b1c8a1SJohn Marino #include <openssl/bn.h>
164f5b1c8a1SJohn Marino #include <openssl/err.h>
165f5b1c8a1SJohn Marino #include <openssl/lhash.h>
166f5b1c8a1SJohn Marino #include <openssl/ocsp.h>
167f5b1c8a1SJohn Marino #include <openssl/pem.h>
168f5b1c8a1SJohn Marino #include <openssl/ssl.h>
169f5b1c8a1SJohn Marino #include <openssl/x509.h>
170f5b1c8a1SJohn Marino 
171f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH
172f5b1c8a1SJohn Marino #include <openssl/dh.h>
173f5b1c8a1SJohn Marino #endif
174f5b1c8a1SJohn Marino 
175f5b1c8a1SJohn Marino #include <openssl/rsa.h>
176f5b1c8a1SJohn Marino 
177f5b1c8a1SJohn Marino #include "s_apps.h"
178f5b1c8a1SJohn Marino #include "timeouts.h"
179f5b1c8a1SJohn Marino 
1808edacedfSDaniel Fojt static void s_server_init(void);
181f5b1c8a1SJohn Marino static void sv_usage(void);
182f5b1c8a1SJohn Marino static void print_stats(BIO *bp, SSL_CTX *ctx);
183*de0e0e4dSAntonio Huete Jimenez static int sv_body(int s, unsigned char *context);
1848edacedfSDaniel Fojt static void close_accept_socket(void);
1858edacedfSDaniel Fojt static int init_ssl_connection(SSL *s);
186f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH
187f5b1c8a1SJohn Marino static DH *load_dh_param(const char *dhfile);
188f5b1c8a1SJohn Marino #endif
189*de0e0e4dSAntonio Huete Jimenez static int www_body(int s, unsigned char *context);
1908edacedfSDaniel Fojt static int generate_session_id(const SSL *ssl, unsigned char *id,
1918edacedfSDaniel Fojt     unsigned int *id_len);
1928edacedfSDaniel Fojt static int ssl_servername_cb(SSL *s, int *ad, void *arg);
1938edacedfSDaniel Fojt static int cert_status_cb(SSL * s, void *arg);
1948edacedfSDaniel Fojt static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
1958edacedfSDaniel Fojt     const unsigned char *in, unsigned int inlen, void *arg);
196f5b1c8a1SJohn Marino /* static int load_CA(SSL_CTX *ctx, char *file);*/
197f5b1c8a1SJohn Marino 
198f5b1c8a1SJohn Marino #define BUFSIZZ	16*1024
199f5b1c8a1SJohn Marino static int bufsize = BUFSIZZ;
200f5b1c8a1SJohn Marino static int accept_socket = -1;
201f5b1c8a1SJohn Marino 
202f5b1c8a1SJohn Marino #define TEST_CERT	"server.pem"
203f5b1c8a1SJohn Marino #define TEST_CERT2	"server2.pem"
204f5b1c8a1SJohn Marino 
205f5b1c8a1SJohn Marino static int s_server_session_id_context = 1;	/* anything will do */
206f5b1c8a1SJohn Marino static SSL_CTX *ctx = NULL;
207f5b1c8a1SJohn Marino static SSL_CTX *ctx2 = NULL;
208f5b1c8a1SJohn Marino static BIO *bio_s_out = NULL;
209f5b1c8a1SJohn Marino 
210f5b1c8a1SJohn Marino static int local_argc = 0;
211f5b1c8a1SJohn Marino static char **local_argv;
212f5b1c8a1SJohn Marino 
213f5b1c8a1SJohn Marino /* This is a context that we pass to callbacks */
214f5b1c8a1SJohn Marino typedef struct tlsextctx_st {
215f5b1c8a1SJohn Marino 	char *servername;
216f5b1c8a1SJohn Marino 	BIO *biodebug;
217f5b1c8a1SJohn Marino 	int extension_error;
218f5b1c8a1SJohn Marino } tlsextctx;
219f5b1c8a1SJohn Marino 
220f5b1c8a1SJohn Marino /* Structure passed to cert status callback */
221f5b1c8a1SJohn Marino typedef struct tlsextstatusctx_st {
222f5b1c8a1SJohn Marino 	/* Default responder to use */
223f5b1c8a1SJohn Marino 	char *host, *path, *port;
224f5b1c8a1SJohn Marino 	int use_ssl;
225f5b1c8a1SJohn Marino 	int timeout;
226f5b1c8a1SJohn Marino 	BIO *err;
227f5b1c8a1SJohn Marino 	int verbose;
228f5b1c8a1SJohn Marino } tlsextstatusctx;
229f5b1c8a1SJohn Marino 
230f5b1c8a1SJohn Marino /* This the context that we pass to alpn_cb */
231f5b1c8a1SJohn Marino typedef struct tlsextalpnctx_st {
232f5b1c8a1SJohn Marino 	unsigned char *data;
233f5b1c8a1SJohn Marino 	unsigned short len;
234f5b1c8a1SJohn Marino } tlsextalpnctx;
235f5b1c8a1SJohn Marino 
2368edacedfSDaniel Fojt static struct {
2378edacedfSDaniel Fojt 	char *alpn_in;
2388edacedfSDaniel Fojt 	char *npn_in; /* Ignored. */
2398edacedfSDaniel Fojt 	int bugs;
2408edacedfSDaniel Fojt 	char *CAfile;
2418edacedfSDaniel Fojt 	char *CApath;
242*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
2438edacedfSDaniel Fojt 	int cert_chain;
244f5b1c8a1SJohn Marino #endif
2458edacedfSDaniel Fojt 	char *cert_file;
2468edacedfSDaniel Fojt 	char *cert_file2;
2478edacedfSDaniel Fojt 	int cert_format;
2488edacedfSDaniel Fojt 	char *cipher;
2498edacedfSDaniel Fojt 	unsigned char *context;
2508edacedfSDaniel Fojt 	int crlf;
2518edacedfSDaniel Fojt 	char *dcert_file;
2528edacedfSDaniel Fojt 	int dcert_format;
2538edacedfSDaniel Fojt 	int debug;
2548edacedfSDaniel Fojt 	char *dhfile;
2558edacedfSDaniel Fojt 	char *dkey_file;
2568edacedfSDaniel Fojt 	int dkey_format;
2578edacedfSDaniel Fojt 	char *dpassarg;
2588edacedfSDaniel Fojt 	int enable_timeouts;
2598edacedfSDaniel Fojt 	const char *errstr;
2608edacedfSDaniel Fojt 	char *groups_in;
2618edacedfSDaniel Fojt 	char *key_file;
2628edacedfSDaniel Fojt 	char *key_file2;
2638edacedfSDaniel Fojt 	int key_format;
2648edacedfSDaniel Fojt 	char *keymatexportlabel;
2658edacedfSDaniel Fojt 	int keymatexportlen;
2668edacedfSDaniel Fojt 	uint16_t max_version;
2678edacedfSDaniel Fojt 	uint16_t min_version;
2688edacedfSDaniel Fojt 	const SSL_METHOD *meth;
2698edacedfSDaniel Fojt 	int msg;
270*de0e0e4dSAntonio Huete Jimenez 	int naccept;
2718edacedfSDaniel Fojt 	char *named_curve;
2728edacedfSDaniel Fojt 	int nbio;
2738edacedfSDaniel Fojt 	int nbio_test;
2748edacedfSDaniel Fojt 	int no_cache;
2758edacedfSDaniel Fojt 	int nocert;
2768edacedfSDaniel Fojt 	int no_dhe;
2778edacedfSDaniel Fojt 	int no_ecdhe;
2788edacedfSDaniel Fojt 	int no_tmp_rsa; /* No-op. */
2798edacedfSDaniel Fojt 	int off;
2808edacedfSDaniel Fojt 	char *passarg;
2818edacedfSDaniel Fojt 	short port;
2828edacedfSDaniel Fojt 	int quiet;
2838edacedfSDaniel Fojt 	int server_verify;
2848edacedfSDaniel Fojt 	char *session_id_prefix;
2858edacedfSDaniel Fojt 	long socket_mtu;
2868edacedfSDaniel Fojt 	int socket_type;
2878edacedfSDaniel Fojt #ifndef OPENSSL_NO_SRTP
2888edacedfSDaniel Fojt 	char *srtp_profiles;
2898edacedfSDaniel Fojt #endif
2908edacedfSDaniel Fojt 	int state;
2918edacedfSDaniel Fojt 	tlsextstatusctx tlscstatp;
2928edacedfSDaniel Fojt 	tlsextctx tlsextcbp;
2938edacedfSDaniel Fojt 	int tlsextdebug;
2948edacedfSDaniel Fojt 	int tlsextstatus;
2958edacedfSDaniel Fojt 	X509_VERIFY_PARAM *vpm;
2968edacedfSDaniel Fojt 	int www;
2978edacedfSDaniel Fojt } s_server_config;
2988edacedfSDaniel Fojt 
2998edacedfSDaniel Fojt static int
s_server_opt_context(char * arg)3008edacedfSDaniel Fojt s_server_opt_context(char *arg)
3018edacedfSDaniel Fojt {
3028edacedfSDaniel Fojt 	s_server_config.context = (unsigned char *) arg;
3038edacedfSDaniel Fojt 	return (0);
3048edacedfSDaniel Fojt }
3058edacedfSDaniel Fojt 
3068edacedfSDaniel Fojt static int
s_server_opt_keymatexportlen(char * arg)3078edacedfSDaniel Fojt s_server_opt_keymatexportlen(char *arg)
3088edacedfSDaniel Fojt {
3098edacedfSDaniel Fojt 	s_server_config.keymatexportlen = strtonum(arg, 1, INT_MAX,
3108edacedfSDaniel Fojt 	    &s_server_config.errstr);
3118edacedfSDaniel Fojt 	if (s_server_config.errstr != NULL) {
3128edacedfSDaniel Fojt 		BIO_printf(bio_err, "invalid argument %s: %s\n",
3138edacedfSDaniel Fojt 		    arg, s_server_config.errstr);
3148edacedfSDaniel Fojt 		return (1);
3158edacedfSDaniel Fojt 	}
3168edacedfSDaniel Fojt 	return (0);
3178edacedfSDaniel Fojt }
3188edacedfSDaniel Fojt 
319*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
3208edacedfSDaniel Fojt static int
s_server_opt_mtu(char * arg)3218edacedfSDaniel Fojt s_server_opt_mtu(char *arg)
3228edacedfSDaniel Fojt {
3238edacedfSDaniel Fojt 	s_server_config.socket_mtu = strtonum(arg, 0, LONG_MAX,
3248edacedfSDaniel Fojt 	    &s_server_config.errstr);
3258edacedfSDaniel Fojt 	if (s_server_config.errstr != NULL) {
3268edacedfSDaniel Fojt 		BIO_printf(bio_err, "invalid argument %s: %s\n",
3278edacedfSDaniel Fojt 		    arg, s_server_config.errstr);
3288edacedfSDaniel Fojt 		return (1);
3298edacedfSDaniel Fojt 	}
3308edacedfSDaniel Fojt 	return (0);
3318edacedfSDaniel Fojt }
332*de0e0e4dSAntonio Huete Jimenez #endif
3338edacedfSDaniel Fojt 
334*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
3358edacedfSDaniel Fojt static int
s_server_opt_protocol_version_dtls(void)336*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_dtls(void)
3378edacedfSDaniel Fojt {
3388edacedfSDaniel Fojt 	s_server_config.meth = DTLS_server_method();
3398edacedfSDaniel Fojt 	s_server_config.socket_type = SOCK_DGRAM;
3408edacedfSDaniel Fojt 	return (0);
3418edacedfSDaniel Fojt }
3428edacedfSDaniel Fojt #endif
3438edacedfSDaniel Fojt 
344*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS1
3458edacedfSDaniel Fojt static int
s_server_opt_protocol_version_dtls1(void)346*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_dtls1(void)
347*de0e0e4dSAntonio Huete Jimenez {
348*de0e0e4dSAntonio Huete Jimenez 	s_server_config.meth = DTLS_server_method();
349*de0e0e4dSAntonio Huete Jimenez 	s_server_config.min_version = DTLS1_VERSION;
350*de0e0e4dSAntonio Huete Jimenez 	s_server_config.max_version = DTLS1_VERSION;
351*de0e0e4dSAntonio Huete Jimenez 	s_server_config.socket_type = SOCK_DGRAM;
352*de0e0e4dSAntonio Huete Jimenez 	return (0);
353*de0e0e4dSAntonio Huete Jimenez }
354*de0e0e4dSAntonio Huete Jimenez #endif
355*de0e0e4dSAntonio Huete Jimenez 
356*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS1_2
357*de0e0e4dSAntonio Huete Jimenez static int
s_server_opt_protocol_version_dtls1_2(void)358*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_dtls1_2(void)
359*de0e0e4dSAntonio Huete Jimenez {
360*de0e0e4dSAntonio Huete Jimenez 	s_server_config.meth = DTLS_server_method();
361*de0e0e4dSAntonio Huete Jimenez 	s_server_config.min_version = DTLS1_2_VERSION;
362*de0e0e4dSAntonio Huete Jimenez 	s_server_config.max_version = DTLS1_2_VERSION;
363*de0e0e4dSAntonio Huete Jimenez 	s_server_config.socket_type = SOCK_DGRAM;
364*de0e0e4dSAntonio Huete Jimenez 	return (0);
365*de0e0e4dSAntonio Huete Jimenez }
366*de0e0e4dSAntonio Huete Jimenez #endif
367*de0e0e4dSAntonio Huete Jimenez 
368*de0e0e4dSAntonio Huete Jimenez static int
s_server_opt_protocol_version_tls1(void)369*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_tls1(void)
3708edacedfSDaniel Fojt {
3718edacedfSDaniel Fojt 	s_server_config.min_version = TLS1_VERSION;
3728edacedfSDaniel Fojt 	s_server_config.max_version = TLS1_VERSION;
3738edacedfSDaniel Fojt 	return (0);
3748edacedfSDaniel Fojt }
3758edacedfSDaniel Fojt 
3768edacedfSDaniel Fojt static int
s_server_opt_protocol_version_tls1_1(void)377*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_tls1_1(void)
3788edacedfSDaniel Fojt {
3798edacedfSDaniel Fojt 	s_server_config.min_version = TLS1_1_VERSION;
3808edacedfSDaniel Fojt 	s_server_config.max_version = TLS1_1_VERSION;
3818edacedfSDaniel Fojt 	return (0);
3828edacedfSDaniel Fojt }
3838edacedfSDaniel Fojt 
3848edacedfSDaniel Fojt static int
s_server_opt_protocol_version_tls1_2(void)385*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_tls1_2(void)
3868edacedfSDaniel Fojt {
3878edacedfSDaniel Fojt 	s_server_config.min_version = TLS1_2_VERSION;
3888edacedfSDaniel Fojt 	s_server_config.max_version = TLS1_2_VERSION;
3898edacedfSDaniel Fojt 	return (0);
3908edacedfSDaniel Fojt }
3918edacedfSDaniel Fojt 
3928edacedfSDaniel Fojt static int
s_server_opt_protocol_version_tls1_3(void)393*de0e0e4dSAntonio Huete Jimenez s_server_opt_protocol_version_tls1_3(void)
3948edacedfSDaniel Fojt {
3958edacedfSDaniel Fojt 	s_server_config.min_version = TLS1_3_VERSION;
3968edacedfSDaniel Fojt 	s_server_config.max_version = TLS1_3_VERSION;
3978edacedfSDaniel Fojt 	return (0);
3988edacedfSDaniel Fojt }
3998edacedfSDaniel Fojt 
4008edacedfSDaniel Fojt static int
s_server_opt_nbio_test(void)4018edacedfSDaniel Fojt s_server_opt_nbio_test(void)
4028edacedfSDaniel Fojt {
4038edacedfSDaniel Fojt 	s_server_config.nbio = 1;
4048edacedfSDaniel Fojt 	s_server_config.nbio_test = 1;
4058edacedfSDaniel Fojt 	return (0);
4068edacedfSDaniel Fojt }
4078edacedfSDaniel Fojt 
4088edacedfSDaniel Fojt static int
s_server_opt_port(char * arg)4098edacedfSDaniel Fojt s_server_opt_port(char *arg)
4108edacedfSDaniel Fojt {
4118edacedfSDaniel Fojt 	if (!extract_port(arg, &s_server_config.port))
4128edacedfSDaniel Fojt 		return (1);
4138edacedfSDaniel Fojt 	return (0);
4148edacedfSDaniel Fojt }
4158edacedfSDaniel Fojt 
4168edacedfSDaniel Fojt static int
s_server_opt_status_timeout(char * arg)4178edacedfSDaniel Fojt s_server_opt_status_timeout(char *arg)
4188edacedfSDaniel Fojt {
4198edacedfSDaniel Fojt 	s_server_config.tlsextstatus = 1;
4208edacedfSDaniel Fojt 	s_server_config.tlscstatp.timeout = strtonum(arg, 0, INT_MAX,
4218edacedfSDaniel Fojt 	    &s_server_config.errstr);
4228edacedfSDaniel Fojt 	if (s_server_config.errstr != NULL) {
4238edacedfSDaniel Fojt 		BIO_printf(bio_err, "invalid argument %s: %s\n",
4248edacedfSDaniel Fojt 		    arg, s_server_config.errstr);
4258edacedfSDaniel Fojt 		return (1);
4268edacedfSDaniel Fojt 	}
4278edacedfSDaniel Fojt 	return (0);
4288edacedfSDaniel Fojt }
4298edacedfSDaniel Fojt 
4308edacedfSDaniel Fojt static int
s_server_opt_status_url(char * arg)4318edacedfSDaniel Fojt s_server_opt_status_url(char *arg)
4328edacedfSDaniel Fojt {
4338edacedfSDaniel Fojt 	s_server_config.tlsextstatus = 1;
4348edacedfSDaniel Fojt 	if (!OCSP_parse_url(arg, &s_server_config.tlscstatp.host,
4358edacedfSDaniel Fojt 	    &s_server_config.tlscstatp.port, &s_server_config.tlscstatp.path,
4368edacedfSDaniel Fojt 	    &s_server_config.tlscstatp.use_ssl)) {
4378edacedfSDaniel Fojt 		BIO_printf(bio_err, "Error parsing URL\n");
4388edacedfSDaniel Fojt 		return (1);
4398edacedfSDaniel Fojt 	}
4408edacedfSDaniel Fojt 	return (0);
4418edacedfSDaniel Fojt }
4428edacedfSDaniel Fojt 
4438edacedfSDaniel Fojt static int
s_server_opt_status_verbose(void)4448edacedfSDaniel Fojt s_server_opt_status_verbose(void)
4458edacedfSDaniel Fojt {
4468edacedfSDaniel Fojt 	s_server_config.tlsextstatus = 1;
4478edacedfSDaniel Fojt 	s_server_config.tlscstatp.verbose = 1;
4488edacedfSDaniel Fojt 	return (0);
4498edacedfSDaniel Fojt }
4508edacedfSDaniel Fojt 
4518edacedfSDaniel Fojt static int
s_server_opt_verify(char * arg)4528edacedfSDaniel Fojt s_server_opt_verify(char *arg)
4538edacedfSDaniel Fojt {
4548edacedfSDaniel Fojt 	s_server_config.server_verify = SSL_VERIFY_PEER |
4558edacedfSDaniel Fojt 	    SSL_VERIFY_CLIENT_ONCE;
4568edacedfSDaniel Fojt 	verify_depth = strtonum(arg, 0, INT_MAX, &s_server_config.errstr);
4578edacedfSDaniel Fojt 	if (s_server_config.errstr != NULL) {
4588edacedfSDaniel Fojt 		BIO_printf(bio_err, "invalid argument %s: %s\n",
4598edacedfSDaniel Fojt 		    arg, s_server_config.errstr);
4608edacedfSDaniel Fojt 		return (1);
4618edacedfSDaniel Fojt 	}
4628edacedfSDaniel Fojt 	BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
4638edacedfSDaniel Fojt 	return (0);
4648edacedfSDaniel Fojt }
4658edacedfSDaniel Fojt 
4668edacedfSDaniel Fojt static int
s_server_opt_verify_fail(char * arg)4678edacedfSDaniel Fojt s_server_opt_verify_fail(char *arg)
4688edacedfSDaniel Fojt {
4698edacedfSDaniel Fojt 	s_server_config.server_verify = SSL_VERIFY_PEER |
4708edacedfSDaniel Fojt 	    SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
4718edacedfSDaniel Fojt 	verify_depth = strtonum(arg, 0, INT_MAX, &s_server_config.errstr);
4728edacedfSDaniel Fojt 	if (s_server_config.errstr != NULL) {
4738edacedfSDaniel Fojt 		BIO_printf(bio_err, "invalid argument %s: %s\n",
4748edacedfSDaniel Fojt 		    arg, s_server_config.errstr);
4758edacedfSDaniel Fojt 		return (1);
4768edacedfSDaniel Fojt 	}
4778edacedfSDaniel Fojt 	BIO_printf(bio_err, "verify depth is %d, must return a certificate\n",
4788edacedfSDaniel Fojt 	    verify_depth);
4798edacedfSDaniel Fojt 	return (0);
4808edacedfSDaniel Fojt }
4818edacedfSDaniel Fojt 
4828edacedfSDaniel Fojt static int
s_server_opt_verify_param(int argc,char ** argv,int * argsused)4838edacedfSDaniel Fojt s_server_opt_verify_param(int argc, char **argv, int *argsused)
4848edacedfSDaniel Fojt {
4858edacedfSDaniel Fojt 	char **pargs = argv;
4868edacedfSDaniel Fojt 	int pargc = argc;
4878edacedfSDaniel Fojt 	int badarg = 0;
4888edacedfSDaniel Fojt 
4898edacedfSDaniel Fojt 	if (!args_verify(&pargs, &pargc, &badarg, bio_err,
4908edacedfSDaniel Fojt 	    &s_server_config.vpm)) {
4918edacedfSDaniel Fojt 		BIO_printf(bio_err, "unknown option %s\n", *argv);
4928edacedfSDaniel Fojt 		return (1);
4938edacedfSDaniel Fojt 	}
4948edacedfSDaniel Fojt 	if (badarg)
4958edacedfSDaniel Fojt 		return (1);
4968edacedfSDaniel Fojt 
4978edacedfSDaniel Fojt 	*argsused = argc - pargc;
4988edacedfSDaniel Fojt 	return (0);
4998edacedfSDaniel Fojt }
5008edacedfSDaniel Fojt 
5018edacedfSDaniel Fojt static const struct option s_server_options[] = {
5028edacedfSDaniel Fojt 	{
503*de0e0e4dSAntonio Huete Jimenez 		.name = "4",
504*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_DISCARD,
505*de0e0e4dSAntonio Huete Jimenez 	},
506*de0e0e4dSAntonio Huete Jimenez 	{
507*de0e0e4dSAntonio Huete Jimenez 		.name = "6",
508*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_DISCARD,
509*de0e0e4dSAntonio Huete Jimenez 	},
510*de0e0e4dSAntonio Huete Jimenez 	{
5118edacedfSDaniel Fojt 		.name = "accept",
5128edacedfSDaniel Fojt 		.argname = "port",
5138edacedfSDaniel Fojt 		.desc = "Port to accept on (default is 4433)",
5148edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
5158edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_port,
5168edacedfSDaniel Fojt 	},
5178edacedfSDaniel Fojt 	{
5188edacedfSDaniel Fojt 		.name = "alpn",
5198edacedfSDaniel Fojt 		.argname = "protocols",
5208edacedfSDaniel Fojt 		.desc = "Set the advertised protocols for the ALPN extension"
5218edacedfSDaniel Fojt 			" (comma-separated list)",
5228edacedfSDaniel Fojt 		.type = OPTION_ARG,
5238edacedfSDaniel Fojt 		.opt.arg = &s_server_config.alpn_in,
5248edacedfSDaniel Fojt 	},
5258edacedfSDaniel Fojt 	{
5268edacedfSDaniel Fojt 		.name = "bugs",
5278edacedfSDaniel Fojt 		.desc = "Turn on SSL bug compatibility",
5288edacedfSDaniel Fojt 		.type = OPTION_FLAG,
5298edacedfSDaniel Fojt 		.opt.flag = &s_server_config.bugs,
5308edacedfSDaniel Fojt 	},
5318edacedfSDaniel Fojt 	{
5328edacedfSDaniel Fojt 		.name = "CAfile",
5338edacedfSDaniel Fojt 		.argname = "file",
5348edacedfSDaniel Fojt 		.desc = "PEM format file of CA certificates",
5358edacedfSDaniel Fojt 		.type = OPTION_ARG,
5368edacedfSDaniel Fojt 		.opt.arg = &s_server_config.CAfile,
5378edacedfSDaniel Fojt 	},
5388edacedfSDaniel Fojt 	{
5398edacedfSDaniel Fojt 		.name = "CApath",
5408edacedfSDaniel Fojt 		.argname = "directory",
5418edacedfSDaniel Fojt 		.desc = "PEM format directory of CA certificates",
5428edacedfSDaniel Fojt 		.type = OPTION_ARG,
5438edacedfSDaniel Fojt 		.opt.arg = &s_server_config.CApath,
5448edacedfSDaniel Fojt 	},
5458edacedfSDaniel Fojt 	{
5468edacedfSDaniel Fojt 		.name = "cert",
5478edacedfSDaniel Fojt 		.argname = "file",
5488edacedfSDaniel Fojt 		.desc = "Certificate file to use\n"
5498edacedfSDaniel Fojt 			"(default is " TEST_CERT ")",
5508edacedfSDaniel Fojt 		.type = OPTION_ARG,
5518edacedfSDaniel Fojt 		.opt.arg = &s_server_config.cert_file,
5528edacedfSDaniel Fojt 	},
5538edacedfSDaniel Fojt 	{
5548edacedfSDaniel Fojt 		.name = "cert2",
5558edacedfSDaniel Fojt 		.argname = "file",
5568edacedfSDaniel Fojt 		.desc = "Certificate file to use for servername\n"
5578edacedfSDaniel Fojt 			"(default is " TEST_CERT2 ")",
5588edacedfSDaniel Fojt 		.type = OPTION_ARG,
5598edacedfSDaniel Fojt 		.opt.arg = &s_server_config.cert_file2,
5608edacedfSDaniel Fojt 	},
5618edacedfSDaniel Fojt 	{
5628edacedfSDaniel Fojt 		.name = "certform",
5638edacedfSDaniel Fojt 		.argname = "fmt",
5648edacedfSDaniel Fojt 		.desc = "Certificate format (PEM or DER) PEM default",
5658edacedfSDaniel Fojt 		.type = OPTION_ARG_FORMAT,
5668edacedfSDaniel Fojt 		.opt.value = &s_server_config.cert_format,
5678edacedfSDaniel Fojt 	},
568*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
5698edacedfSDaniel Fojt 	{
5708edacedfSDaniel Fojt 		.name = "chain",
5718edacedfSDaniel Fojt 		.type = OPTION_FLAG,
5728edacedfSDaniel Fojt 		.opt.flag = &s_server_config.cert_chain,
5738edacedfSDaniel Fojt 	},
5748edacedfSDaniel Fojt #endif
5758edacedfSDaniel Fojt 	{
5768edacedfSDaniel Fojt 		.name = "cipher",
5778edacedfSDaniel Fojt 		.argname = "list",
5788edacedfSDaniel Fojt 		.desc = "List of ciphers to enable (see `openssl ciphers`)",
5798edacedfSDaniel Fojt 		.type = OPTION_ARG,
5808edacedfSDaniel Fojt 		.opt.arg = &s_server_config.cipher,
5818edacedfSDaniel Fojt 	},
5828edacedfSDaniel Fojt 	{
5838edacedfSDaniel Fojt 		.name = "context",
5848edacedfSDaniel Fojt 		.argname = "id",
5858edacedfSDaniel Fojt 		.desc = "Set session ID context",
5868edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
5878edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_context,
5888edacedfSDaniel Fojt 	},
5898edacedfSDaniel Fojt 	{
5908edacedfSDaniel Fojt 		.name = "crlf",
5918edacedfSDaniel Fojt 		.desc = "Convert LF from terminal into CRLF",
5928edacedfSDaniel Fojt 		.type = OPTION_FLAG,
5938edacedfSDaniel Fojt 		.opt.flag = &s_server_config.crlf,
5948edacedfSDaniel Fojt 	},
5958edacedfSDaniel Fojt 	{
5968edacedfSDaniel Fojt 		.name = "dcert",
5978edacedfSDaniel Fojt 		.argname = "file",
5988edacedfSDaniel Fojt 		.desc = "Second certificate file to use (usually for DSA)",
5998edacedfSDaniel Fojt 		.type = OPTION_ARG,
6008edacedfSDaniel Fojt 		.opt.arg = &s_server_config.dcert_file,
6018edacedfSDaniel Fojt 	},
6028edacedfSDaniel Fojt 	{
6038edacedfSDaniel Fojt 		.name = "dcertform",
6048edacedfSDaniel Fojt 		.argname = "fmt",
6058edacedfSDaniel Fojt 		.desc = "Second certificate format (PEM or DER) PEM default",
6068edacedfSDaniel Fojt 		.type = OPTION_ARG_FORMAT,
6078edacedfSDaniel Fojt 		.opt.value = &s_server_config.dcert_format,
6088edacedfSDaniel Fojt 	},
6098edacedfSDaniel Fojt 	{
6108edacedfSDaniel Fojt 		.name = "debug",
6118edacedfSDaniel Fojt 		.desc = "Print more output",
6128edacedfSDaniel Fojt 		.type = OPTION_FLAG,
6138edacedfSDaniel Fojt 		.opt.flag = &s_server_config.debug,
6148edacedfSDaniel Fojt 	},
6158edacedfSDaniel Fojt 	{
6168edacedfSDaniel Fojt 		.name = "dhparam",
6178edacedfSDaniel Fojt 		.argname = "file",
6188edacedfSDaniel Fojt 		.desc = "DH parameter file to use, in cert file if not specified",
6198edacedfSDaniel Fojt 		.type = OPTION_ARG,
6208edacedfSDaniel Fojt 		.opt.arg = &s_server_config.dhfile,
6218edacedfSDaniel Fojt 	},
6228edacedfSDaniel Fojt 	{
6238edacedfSDaniel Fojt 		.name = "dkey",
6248edacedfSDaniel Fojt 		.argname = "file",
6258edacedfSDaniel Fojt 		.desc = "Second private key file to use (usually for DSA)",
6268edacedfSDaniel Fojt 		.type = OPTION_ARG,
6278edacedfSDaniel Fojt 		.opt.arg = &s_server_config.dkey_file,
6288edacedfSDaniel Fojt 	},
6298edacedfSDaniel Fojt 	{
6308edacedfSDaniel Fojt 		.name = "dkeyform",
6318edacedfSDaniel Fojt 		.argname = "fmt",
6328edacedfSDaniel Fojt 		.desc = "Second key format (PEM or DER) PEM default",
6338edacedfSDaniel Fojt 		.type = OPTION_ARG_FORMAT,
6348edacedfSDaniel Fojt 		.opt.value = &s_server_config.dkey_format,
6358edacedfSDaniel Fojt 	},
6368edacedfSDaniel Fojt 	{
6378edacedfSDaniel Fojt 		.name = "dpass",
6388edacedfSDaniel Fojt 		.argname = "arg",
6398edacedfSDaniel Fojt 		.desc = "Second private key file pass phrase source",
6408edacedfSDaniel Fojt 		.type = OPTION_ARG,
6418edacedfSDaniel Fojt 		.opt.arg = &s_server_config.dpassarg,
6428edacedfSDaniel Fojt 	},
643*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
644*de0e0e4dSAntonio Huete Jimenez 	{
645*de0e0e4dSAntonio Huete Jimenez 		.name = "dtls",
646*de0e0e4dSAntonio Huete Jimenez 		.desc = "Use any version of DTLS",
647*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FUNC,
648*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_dtls,
649*de0e0e4dSAntonio Huete Jimenez 	},
650*de0e0e4dSAntonio Huete Jimenez #endif
6518edacedfSDaniel Fojt #ifndef OPENSSL_NO_DTLS1
6528edacedfSDaniel Fojt 	{
6538edacedfSDaniel Fojt 		.name = "dtls1",
654*de0e0e4dSAntonio Huete Jimenez 		.desc = "Just use DTLSv1",
6558edacedfSDaniel Fojt 		.type = OPTION_FUNC,
656*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_dtls1,
657*de0e0e4dSAntonio Huete Jimenez 	},
658*de0e0e4dSAntonio Huete Jimenez #endif
659*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS1_2
660*de0e0e4dSAntonio Huete Jimenez 	{
661*de0e0e4dSAntonio Huete Jimenez 		.name = "dtls1_2",
662*de0e0e4dSAntonio Huete Jimenez 		.desc = "Just use DTLSv1.2",
663*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FUNC,
664*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_dtls1_2,
6658edacedfSDaniel Fojt 	},
6668edacedfSDaniel Fojt #endif
6678edacedfSDaniel Fojt 	{
6688edacedfSDaniel Fojt 		.name = "groups",
6698edacedfSDaniel Fojt 		.argname = "list",
6708edacedfSDaniel Fojt 		.desc = "Specify EC groups (colon-separated list)",
6718edacedfSDaniel Fojt 		.type = OPTION_ARG,
6728edacedfSDaniel Fojt 		.opt.arg = &s_server_config.groups_in,
6738edacedfSDaniel Fojt 	},
6748edacedfSDaniel Fojt 	{
6758edacedfSDaniel Fojt 		.name = "HTTP",
6768edacedfSDaniel Fojt 		.desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>",
6778edacedfSDaniel Fojt 		.type = OPTION_VALUE,
6788edacedfSDaniel Fojt 		.opt.value = &s_server_config.www,
6798edacedfSDaniel Fojt 		.value = 3,
6808edacedfSDaniel Fojt 	},
6818edacedfSDaniel Fojt 	{
6828edacedfSDaniel Fojt 		.name = "id_prefix",
6838edacedfSDaniel Fojt 		.argname = "arg",
6848edacedfSDaniel Fojt 		.desc = "Generate SSL/TLS session IDs prefixed by 'arg'",
6858edacedfSDaniel Fojt 		.type = OPTION_ARG,
6868edacedfSDaniel Fojt 		.opt.arg = &s_server_config.session_id_prefix,
6878edacedfSDaniel Fojt 	},
6888edacedfSDaniel Fojt 	{
6898edacedfSDaniel Fojt 		.name = "key",
6908edacedfSDaniel Fojt 		.argname = "file",
6918edacedfSDaniel Fojt 		.desc = "Private Key file to use, in cert file if\n"
6928edacedfSDaniel Fojt 			"not specified (default is " TEST_CERT ")",
6938edacedfSDaniel Fojt 		.type = OPTION_ARG,
6948edacedfSDaniel Fojt 		.opt.arg = &s_server_config.key_file,
6958edacedfSDaniel Fojt 	},
6968edacedfSDaniel Fojt 	{
6978edacedfSDaniel Fojt 		.name = "key2",
6988edacedfSDaniel Fojt 		.argname = "file",
6998edacedfSDaniel Fojt 		.desc = "Private Key file to use for servername, in cert file if\n"
7008edacedfSDaniel Fojt 			"not specified (default is " TEST_CERT2 ")",
7018edacedfSDaniel Fojt 		.type = OPTION_ARG,
7028edacedfSDaniel Fojt 		.opt.arg = &s_server_config.key_file2,
7038edacedfSDaniel Fojt 	},
7048edacedfSDaniel Fojt 	{
7058edacedfSDaniel Fojt 		.name = "keyform",
7068edacedfSDaniel Fojt 		.argname = "fmt",
7078edacedfSDaniel Fojt 		.desc = "Key format (PEM or DER) PEM default",
7088edacedfSDaniel Fojt 		.type = OPTION_ARG_FORMAT,
7098edacedfSDaniel Fojt 		.opt.value = &s_server_config.key_format,
7108edacedfSDaniel Fojt 	},
7118edacedfSDaniel Fojt 	{
7128edacedfSDaniel Fojt 		.name = "keymatexport",
7138edacedfSDaniel Fojt 		.argname = "label",
7148edacedfSDaniel Fojt 		.desc = "Export keying material using label",
7158edacedfSDaniel Fojt 		.type = OPTION_ARG,
7168edacedfSDaniel Fojt 		.opt.arg = &s_server_config.keymatexportlabel,
7178edacedfSDaniel Fojt 	},
7188edacedfSDaniel Fojt 	{
7198edacedfSDaniel Fojt 		.name = "keymatexportlen",
7208edacedfSDaniel Fojt 		.argname = "len",
7218edacedfSDaniel Fojt 		.desc = "Export len bytes of keying material (default 20)",
7228edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
7238edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_keymatexportlen,
7248edacedfSDaniel Fojt 	},
7258edacedfSDaniel Fojt 	{
7268edacedfSDaniel Fojt 		.name = "legacy_renegotiation",
7278edacedfSDaniel Fojt 		.type = OPTION_DISCARD,
7288edacedfSDaniel Fojt 	},
7298edacedfSDaniel Fojt 	{
7308edacedfSDaniel Fojt 		.name = "msg",
7318edacedfSDaniel Fojt 		.desc = "Show protocol messages",
7328edacedfSDaniel Fojt 		.type = OPTION_FLAG,
7338edacedfSDaniel Fojt 		.opt.flag = &s_server_config.msg,
7348edacedfSDaniel Fojt 	},
735*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
7368edacedfSDaniel Fojt 	{
7378edacedfSDaniel Fojt 		.name = "mtu",
7388edacedfSDaniel Fojt 		.argname = "mtu",
7398edacedfSDaniel Fojt 		.desc = "Set link layer MTU",
7408edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
7418edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_mtu,
7428edacedfSDaniel Fojt 	},
7438edacedfSDaniel Fojt #endif
7448edacedfSDaniel Fojt 	{
745*de0e0e4dSAntonio Huete Jimenez 		.name = "naccept",
746*de0e0e4dSAntonio Huete Jimenez 		.argname = "num",
747*de0e0e4dSAntonio Huete Jimenez 		.desc = "Terminate after num connections",
748*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_INT,
749*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &s_server_config.naccept
750*de0e0e4dSAntonio Huete Jimenez 	},
751*de0e0e4dSAntonio Huete Jimenez 	{
7528edacedfSDaniel Fojt 		.name = "named_curve",
7538edacedfSDaniel Fojt 		.argname = "arg",
7548edacedfSDaniel Fojt 		.type = OPTION_ARG,
7558edacedfSDaniel Fojt 		.opt.arg = &s_server_config.named_curve,
7568edacedfSDaniel Fojt 	},
7578edacedfSDaniel Fojt 	{
7588edacedfSDaniel Fojt 		.name = "nbio",
7598edacedfSDaniel Fojt 		.desc = "Run with non-blocking I/O",
7608edacedfSDaniel Fojt 		.type = OPTION_FLAG,
7618edacedfSDaniel Fojt 		.opt.flag = &s_server_config.nbio,
7628edacedfSDaniel Fojt 	},
7638edacedfSDaniel Fojt 	{
7648edacedfSDaniel Fojt 		.name = "nbio_test",
7658edacedfSDaniel Fojt 		.desc = "Test with the non-blocking test bio",
7668edacedfSDaniel Fojt 		.type = OPTION_FUNC,
7678edacedfSDaniel Fojt 		.opt.func = s_server_opt_nbio_test,
7688edacedfSDaniel Fojt 	},
7698edacedfSDaniel Fojt 	{
7708edacedfSDaniel Fojt 		.name = "nextprotoneg",
7718edacedfSDaniel Fojt 		.argname = "arg",
7728edacedfSDaniel Fojt 		.type = OPTION_ARG,
7738edacedfSDaniel Fojt 		.opt.arg = &s_server_config.npn_in, /* Ignored. */
7748edacedfSDaniel Fojt 	},
7758edacedfSDaniel Fojt 	{
7768edacedfSDaniel Fojt 		.name = "no_cache",
7778edacedfSDaniel Fojt 		.desc = "Disable session cache",
7788edacedfSDaniel Fojt 		.type = OPTION_FLAG,
7798edacedfSDaniel Fojt 		.opt.flag = &s_server_config.no_cache,
7808edacedfSDaniel Fojt 	},
7818edacedfSDaniel Fojt 	{
7828edacedfSDaniel Fojt 		.name = "no_comp",
7838edacedfSDaniel Fojt 		.desc = "Disable SSL/TLS compression",
7848edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
7858edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
7868edacedfSDaniel Fojt 		.value = SSL_OP_NO_COMPRESSION,
7878edacedfSDaniel Fojt 	},
7888edacedfSDaniel Fojt 	{
7898edacedfSDaniel Fojt 		.name = "no_dhe",
7908edacedfSDaniel Fojt 		.desc = "Disable ephemeral DH",
7918edacedfSDaniel Fojt 		.type = OPTION_FLAG,
7928edacedfSDaniel Fojt 		.opt.flag = &s_server_config.no_dhe,
7938edacedfSDaniel Fojt 	},
7948edacedfSDaniel Fojt 	{
7958edacedfSDaniel Fojt 		.name = "no_ecdhe",
7968edacedfSDaniel Fojt 		.desc = "Disable ephemeral ECDH",
7978edacedfSDaniel Fojt 		.type = OPTION_FLAG,
7988edacedfSDaniel Fojt 		.opt.flag = &s_server_config.no_ecdhe,
7998edacedfSDaniel Fojt 	},
8008edacedfSDaniel Fojt 	{
8018edacedfSDaniel Fojt 		.name = "no_ticket",
8028edacedfSDaniel Fojt 		.desc = "Disable use of RFC4507bis session tickets",
8038edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8048edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8058edacedfSDaniel Fojt 		.value = SSL_OP_NO_TICKET,
8068edacedfSDaniel Fojt 	},
8078edacedfSDaniel Fojt 	{
8088edacedfSDaniel Fojt 		.name = "no_ssl2",
8098edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8108edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8118edacedfSDaniel Fojt 		.value = SSL_OP_NO_SSLv2,
8128edacedfSDaniel Fojt 	},
8138edacedfSDaniel Fojt 	{
8148edacedfSDaniel Fojt 		.name = "no_ssl3",
8158edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8168edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8178edacedfSDaniel Fojt 		.value = SSL_OP_NO_SSLv3,
8188edacedfSDaniel Fojt 	},
8198edacedfSDaniel Fojt 	{
8208edacedfSDaniel Fojt 		.name = "no_tls1",
8218edacedfSDaniel Fojt 		.desc = "Just disable TLSv1",
8228edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8238edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8248edacedfSDaniel Fojt 		.value = SSL_OP_NO_TLSv1,
8258edacedfSDaniel Fojt 	},
8268edacedfSDaniel Fojt 	{
8278edacedfSDaniel Fojt 		.name = "no_tls1_1",
8288edacedfSDaniel Fojt 		.desc = "Just disable TLSv1.1",
8298edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8308edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8318edacedfSDaniel Fojt 		.value = SSL_OP_NO_TLSv1_1,
8328edacedfSDaniel Fojt 	},
8338edacedfSDaniel Fojt 	{
8348edacedfSDaniel Fojt 		.name = "no_tls1_2",
8358edacedfSDaniel Fojt 		.desc = "Just disable TLSv1.2",
8368edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8378edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8388edacedfSDaniel Fojt 		.value = SSL_OP_NO_TLSv1_2,
8398edacedfSDaniel Fojt 	},
8408edacedfSDaniel Fojt 	{
8418edacedfSDaniel Fojt 		.name = "no_tls1_3",
8428edacedfSDaniel Fojt 		.desc = "Just disable TLSv1.3",
8438edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8448edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8458edacedfSDaniel Fojt 		.value = SSL_OP_NO_TLSv1_3,
8468edacedfSDaniel Fojt 	},
8478edacedfSDaniel Fojt 	{
8488edacedfSDaniel Fojt 		.name = "no_tmp_rsa",
8498edacedfSDaniel Fojt 		.type = OPTION_DISCARD,
8508edacedfSDaniel Fojt 	},
8518edacedfSDaniel Fojt 	{
8528edacedfSDaniel Fojt 		.name = "nocert",
8538edacedfSDaniel Fojt 		.desc = "Don't use any certificates (Anon-DH)",
8548edacedfSDaniel Fojt 		.type = OPTION_FLAG,
8558edacedfSDaniel Fojt 		.opt.flag = &s_server_config.nocert,
8568edacedfSDaniel Fojt 	},
8578edacedfSDaniel Fojt 	{
8588edacedfSDaniel Fojt 		.name = "pass",
8598edacedfSDaniel Fojt 		.argname = "arg",
8608edacedfSDaniel Fojt 		.desc = "Private key file pass phrase source",
8618edacedfSDaniel Fojt 		.type = OPTION_ARG,
8628edacedfSDaniel Fojt 		.opt.arg = &s_server_config.passarg,
8638edacedfSDaniel Fojt 	},
8648edacedfSDaniel Fojt 	{
8658edacedfSDaniel Fojt 		.name = "port",
8668edacedfSDaniel Fojt 		.argname = "port",
8678edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
8688edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_port,
8698edacedfSDaniel Fojt 	},
8708edacedfSDaniel Fojt 	{
8718edacedfSDaniel Fojt 		.name = "quiet",
8728edacedfSDaniel Fojt 		.desc = "Inhibit printing of session and certificate information",
8738edacedfSDaniel Fojt 		.type = OPTION_FLAG,
8748edacedfSDaniel Fojt 		.opt.flag = &s_server_config.quiet,
8758edacedfSDaniel Fojt 	},
8768edacedfSDaniel Fojt 	{
8778edacedfSDaniel Fojt 		.name = "servername",
8788edacedfSDaniel Fojt 		.argname = "name",
8798edacedfSDaniel Fojt 		.desc = "Servername for HostName TLS extension",
8808edacedfSDaniel Fojt 		.type = OPTION_ARG,
8818edacedfSDaniel Fojt 		.opt.arg = &s_server_config.tlsextcbp.servername,
8828edacedfSDaniel Fojt 	},
8838edacedfSDaniel Fojt 	{
8848edacedfSDaniel Fojt 		.name = "servername_fatal",
8858edacedfSDaniel Fojt 		.desc = "On mismatch send fatal alert (default warning alert)",
8868edacedfSDaniel Fojt 		.type = OPTION_VALUE,
8878edacedfSDaniel Fojt 		.opt.value = &s_server_config.tlsextcbp.extension_error,
8888edacedfSDaniel Fojt 		.value = SSL_TLSEXT_ERR_ALERT_FATAL,
8898edacedfSDaniel Fojt 	},
8908edacedfSDaniel Fojt 	{
8918edacedfSDaniel Fojt 		.name = "serverpref",
8928edacedfSDaniel Fojt 		.desc = "Use server's cipher preferences",
8938edacedfSDaniel Fojt 		.type = OPTION_VALUE_OR,
8948edacedfSDaniel Fojt 		.opt.value = &s_server_config.off,
8958edacedfSDaniel Fojt 		.value = SSL_OP_CIPHER_SERVER_PREFERENCE,
8968edacedfSDaniel Fojt 	},
8978edacedfSDaniel Fojt 	{
8988edacedfSDaniel Fojt 		.name = "state",
8998edacedfSDaniel Fojt 		.desc = "Print the SSL states",
9008edacedfSDaniel Fojt 		.type = OPTION_FLAG,
9018edacedfSDaniel Fojt 		.opt.flag = &s_server_config.state,
9028edacedfSDaniel Fojt 	},
9038edacedfSDaniel Fojt 	{
9048edacedfSDaniel Fojt 		.name = "status",
9058edacedfSDaniel Fojt 		.desc = "Respond to certificate status requests",
9068edacedfSDaniel Fojt 		.type = OPTION_FLAG,
9078edacedfSDaniel Fojt 		.opt.flag = &s_server_config.tlsextstatus,
9088edacedfSDaniel Fojt 	},
9098edacedfSDaniel Fojt 	{
9108edacedfSDaniel Fojt 		.name = "status_timeout",
9118edacedfSDaniel Fojt 		.argname = "nsec",
9128edacedfSDaniel Fojt 		.desc = "Status request responder timeout",
9138edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
9148edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_status_timeout,
9158edacedfSDaniel Fojt 	},
9168edacedfSDaniel Fojt 	{
9178edacedfSDaniel Fojt 		.name = "status_url",
9188edacedfSDaniel Fojt 		.argname = "url",
9198edacedfSDaniel Fojt 		.desc = "Status request fallback URL",
9208edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
9218edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_status_url,
9228edacedfSDaniel Fojt 	},
9238edacedfSDaniel Fojt 	{
9248edacedfSDaniel Fojt 		.name = "status_verbose",
9258edacedfSDaniel Fojt 		.desc = "Enable status request verbose printout",
9268edacedfSDaniel Fojt 		.type = OPTION_FUNC,
9278edacedfSDaniel Fojt 		.opt.func = s_server_opt_status_verbose,
9288edacedfSDaniel Fojt 	},
929*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DTLS
9308edacedfSDaniel Fojt 	{
9318edacedfSDaniel Fojt 		.name = "timeout",
9328edacedfSDaniel Fojt 		.desc = "Enable timeouts",
9338edacedfSDaniel Fojt 		.type = OPTION_FLAG,
9348edacedfSDaniel Fojt 		.opt.flag = &s_server_config.enable_timeouts,
9358edacedfSDaniel Fojt 	},
9368edacedfSDaniel Fojt #endif
9378edacedfSDaniel Fojt 	{
9388edacedfSDaniel Fojt 		.name = "tls1",
9398edacedfSDaniel Fojt 		.desc = "Just talk TLSv1",
9408edacedfSDaniel Fojt 		.type = OPTION_FUNC,
941*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_tls1,
9428edacedfSDaniel Fojt 	},
9438edacedfSDaniel Fojt 	{
9448edacedfSDaniel Fojt 		.name = "tls1_1",
9458edacedfSDaniel Fojt 		.desc = "Just talk TLSv1.1",
9468edacedfSDaniel Fojt 		.type = OPTION_FUNC,
947*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_tls1_1,
9488edacedfSDaniel Fojt 	},
9498edacedfSDaniel Fojt 	{
9508edacedfSDaniel Fojt 		.name = "tls1_2",
9518edacedfSDaniel Fojt 		.desc = "Just talk TLSv1.2",
9528edacedfSDaniel Fojt 		.type = OPTION_FUNC,
953*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_tls1_2,
9548edacedfSDaniel Fojt 	},
9558edacedfSDaniel Fojt 	{
9568edacedfSDaniel Fojt 		.name = "tls1_3",
9578edacedfSDaniel Fojt 		.desc = "Just talk TLSv1.3",
9588edacedfSDaniel Fojt 		.type = OPTION_FUNC,
959*de0e0e4dSAntonio Huete Jimenez 		.opt.func = s_server_opt_protocol_version_tls1_3,
9608edacedfSDaniel Fojt 	},
9618edacedfSDaniel Fojt 	{
9628edacedfSDaniel Fojt 		.name = "tlsextdebug",
9638edacedfSDaniel Fojt 		.desc = "Hex dump of all TLS extensions received",
9648edacedfSDaniel Fojt 		.type = OPTION_FLAG,
9658edacedfSDaniel Fojt 		.opt.flag = &s_server_config.tlsextdebug,
9668edacedfSDaniel Fojt 	},
9678edacedfSDaniel Fojt #ifndef OPENSSL_NO_SRTP
9688edacedfSDaniel Fojt 	{
9698edacedfSDaniel Fojt 		.name = "use_srtp",
9708edacedfSDaniel Fojt 		.argname = "profiles",
9718edacedfSDaniel Fojt 		.desc = "Offer SRTP key management with a colon-separated profile list",
9728edacedfSDaniel Fojt 		.type = OPTION_ARG,
9738edacedfSDaniel Fojt 		.opt.arg = &s_server_config.srtp_profiles,
9748edacedfSDaniel Fojt 	},
9758edacedfSDaniel Fojt #endif
9768edacedfSDaniel Fojt 	{
9778edacedfSDaniel Fojt 		.name = "Verify",
9788edacedfSDaniel Fojt 		.argname = "depth",
9798edacedfSDaniel Fojt 		.desc = "Turn on peer certificate verification, must have a cert",
9808edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
9818edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_verify_fail,
9828edacedfSDaniel Fojt 	},
9838edacedfSDaniel Fojt 	{
9848edacedfSDaniel Fojt 		.name = "verify",
9858edacedfSDaniel Fojt 		.argname = "depth",
9868edacedfSDaniel Fojt 		.desc = "Turn on peer certificate verification",
9878edacedfSDaniel Fojt 		.type = OPTION_ARG_FUNC,
9888edacedfSDaniel Fojt 		.opt.argfunc = s_server_opt_verify,
9898edacedfSDaniel Fojt 	},
9908edacedfSDaniel Fojt 	{
9918edacedfSDaniel Fojt 		.name = "verify_return_error",
9928edacedfSDaniel Fojt 		.desc = "Return verification error",
9938edacedfSDaniel Fojt 		.type = OPTION_FLAG,
9948edacedfSDaniel Fojt 		.opt.flag = &verify_return_error,
9958edacedfSDaniel Fojt 	},
9968edacedfSDaniel Fojt 	{
9978edacedfSDaniel Fojt 		.name = "WWW",
9988edacedfSDaniel Fojt 		.desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>",
9998edacedfSDaniel Fojt 		.type = OPTION_VALUE,
10008edacedfSDaniel Fojt 		.opt.value = &s_server_config.www,
10018edacedfSDaniel Fojt 		.value = 2,
10028edacedfSDaniel Fojt 	},
10038edacedfSDaniel Fojt 	{
10048edacedfSDaniel Fojt 		.name = "www",
10058edacedfSDaniel Fojt 		.desc = "Respond to a 'GET /' with a status page",
10068edacedfSDaniel Fojt 		.type = OPTION_VALUE,
10078edacedfSDaniel Fojt 		.opt.value = &s_server_config.www,
10088edacedfSDaniel Fojt 		.value = 1,
10098edacedfSDaniel Fojt 	},
10108edacedfSDaniel Fojt 	{
10118edacedfSDaniel Fojt 		.name = NULL,
10128edacedfSDaniel Fojt 		.desc = "",
10138edacedfSDaniel Fojt 		.type = OPTION_ARGV_FUNC,
10148edacedfSDaniel Fojt 		.opt.argvfunc = s_server_opt_verify_param,
10158edacedfSDaniel Fojt 	},
10168edacedfSDaniel Fojt 	{ NULL },
10178edacedfSDaniel Fojt };
10188edacedfSDaniel Fojt 
10198edacedfSDaniel Fojt static void
s_server_init(void)10208edacedfSDaniel Fojt s_server_init(void)
10218edacedfSDaniel Fojt {
10228edacedfSDaniel Fojt 	accept_socket = -1;
10238edacedfSDaniel Fojt 	s_server_config.cipher = NULL;
10248edacedfSDaniel Fojt 	s_server_config.server_verify = SSL_VERIFY_NONE;
10258edacedfSDaniel Fojt 	s_server_config.dcert_file = NULL;
10268edacedfSDaniel Fojt 	s_server_config.dkey_file = NULL;
10278edacedfSDaniel Fojt 	s_server_config.cert_file = TEST_CERT;
10288edacedfSDaniel Fojt 	s_server_config.key_file = NULL;
10298edacedfSDaniel Fojt 	s_server_config.cert_file2 = TEST_CERT2;
10308edacedfSDaniel Fojt 	s_server_config.key_file2 = NULL;
10318edacedfSDaniel Fojt 	ctx2 = NULL;
10328edacedfSDaniel Fojt 	s_server_config.nbio = 0;
10338edacedfSDaniel Fojt 	s_server_config.nbio_test = 0;
10348edacedfSDaniel Fojt 	ctx = NULL;
10358edacedfSDaniel Fojt 	s_server_config.www = 0;
10368edacedfSDaniel Fojt 
10378edacedfSDaniel Fojt 	bio_s_out = NULL;
10388edacedfSDaniel Fojt 	s_server_config.debug = 0;
10398edacedfSDaniel Fojt 	s_server_config.msg = 0;
10408edacedfSDaniel Fojt 	s_server_config.quiet = 0;
10418edacedfSDaniel Fojt }
10428edacedfSDaniel Fojt 
10438edacedfSDaniel Fojt static void
sv_usage(void)10448edacedfSDaniel Fojt sv_usage(void)
10458edacedfSDaniel Fojt {
10468edacedfSDaniel Fojt 	fprintf(stderr, "usage: s_server "
10478edacedfSDaniel Fojt 	    "[-accept port] [-alpn protocols] [-bugs] [-CAfile file]\n"
10488edacedfSDaniel Fojt 	    "    [-CApath directory] [-cert file] [-cert2 file]\n"
10498edacedfSDaniel Fojt 	    "    [-certform der | pem] [-cipher cipherlist]\n"
10508edacedfSDaniel Fojt 	    "    [-context id] [-crl_check] [-crl_check_all] [-crlf]\n"
10518edacedfSDaniel Fojt 	    "    [-dcert file] [-dcertform der | pem] [-debug]\n"
10528edacedfSDaniel Fojt 	    "    [-dhparam file] [-dkey file] [-dkeyform der | pem]\n"
1053*de0e0e4dSAntonio Huete Jimenez 	    "    [-dpass arg] [-dtls] [-dtls1] [-dtls1_2] [-groups list] [-HTTP]\n"
10548edacedfSDaniel Fojt 	    "    [-id_prefix arg] [-key keyfile] [-key2 keyfile]\n"
10558edacedfSDaniel Fojt 	    "    [-keyform der | pem] [-keymatexport label]\n"
1056*de0e0e4dSAntonio Huete Jimenez 	    "    [-keymatexportlen len] [-msg] [-mtu mtu] [-naccept num]\n"
10578edacedfSDaniel Fojt 	    "    [-named_curve arg] [-nbio] [-nbio_test] [-no_cache]\n"
10588edacedfSDaniel Fojt 	    "    [-no_dhe] [-no_ecdhe] [-no_ticket] [-no_tls1]\n"
10598edacedfSDaniel Fojt 	    "    [-no_tls1_1] [-no_tls1_2] [-no_tls1_3] [-no_tmp_rsa]\n"
10608edacedfSDaniel Fojt 	    "    [-nocert] [-pass arg] [-quiet] [-servername name]\n"
10618edacedfSDaniel Fojt 	    "    [-servername_fatal] [-serverpref] [-state] [-status]\n"
10628edacedfSDaniel Fojt 	    "    [-status_timeout nsec] [-status_url url]\n"
10638edacedfSDaniel Fojt 	    "    [-status_verbose] [-timeout] [-tls1] [-tls1_1]\n"
10648edacedfSDaniel Fojt 	    "    [-tls1_2] [-tls1_3] [-tlsextdebug] [-use_srtp profiles]\n"
10658edacedfSDaniel Fojt 	    "    [-Verify depth] [-verify depth] [-verify_return_error]\n"
10668edacedfSDaniel Fojt 	    "    [-WWW] [-www]\n");
10678edacedfSDaniel Fojt 	fprintf(stderr, "\n");
10688edacedfSDaniel Fojt 	options_usage(s_server_options);
10698edacedfSDaniel Fojt 	fprintf(stderr, "\n");
10708edacedfSDaniel Fojt }
1071f5b1c8a1SJohn Marino 
1072f5b1c8a1SJohn Marino int
s_server_main(int argc,char * argv[])1073f5b1c8a1SJohn Marino s_server_main(int argc, char *argv[])
1074f5b1c8a1SJohn Marino {
1075f5b1c8a1SJohn Marino 	int ret = 1;
10768edacedfSDaniel Fojt 	char *pass = NULL;
10778edacedfSDaniel Fojt 	char *dpass = NULL;
1078f5b1c8a1SJohn Marino 	X509 *s_cert = NULL, *s_dcert = NULL;
1079f5b1c8a1SJohn Marino 	EVP_PKEY *s_key = NULL, *s_dkey = NULL;
1080f5b1c8a1SJohn Marino 	EVP_PKEY *s_key2 = NULL;
1081f5b1c8a1SJohn Marino 	X509 *s_cert2 = NULL;
1082f5b1c8a1SJohn Marino 	tlsextalpnctx alpn_ctx = { NULL, 0 };
1083f5b1c8a1SJohn Marino 
1084f5b1c8a1SJohn Marino 	if (single_execution) {
108572c33676SMaxim Ag 		if (pledge("stdio rpath inet dns tty", NULL) == -1) {
1086f5b1c8a1SJohn Marino 			perror("pledge");
1087f5b1c8a1SJohn Marino 			exit(1);
1088f5b1c8a1SJohn Marino 		}
1089f5b1c8a1SJohn Marino 	}
1090f5b1c8a1SJohn Marino 
10918edacedfSDaniel Fojt 	memset(&s_server_config, 0, sizeof(s_server_config));
10928edacedfSDaniel Fojt 	s_server_config.keymatexportlen = 20;
10938edacedfSDaniel Fojt 	s_server_config.meth = TLS_server_method();
1094*de0e0e4dSAntonio Huete Jimenez 	s_server_config.naccept = -1;
10958edacedfSDaniel Fojt 	s_server_config.port = PORT;
10968edacedfSDaniel Fojt 	s_server_config.cert_file = TEST_CERT;
10978edacedfSDaniel Fojt 	s_server_config.cert_file2 = TEST_CERT2;
10988edacedfSDaniel Fojt 	s_server_config.cert_format = FORMAT_PEM;
10998edacedfSDaniel Fojt 	s_server_config.dcert_format = FORMAT_PEM;
11008edacedfSDaniel Fojt 	s_server_config.dkey_format = FORMAT_PEM;
11018edacedfSDaniel Fojt 	s_server_config.key_format = FORMAT_PEM;
11028edacedfSDaniel Fojt 	s_server_config.server_verify = SSL_VERIFY_NONE;
11038edacedfSDaniel Fojt 	s_server_config.socket_type = SOCK_STREAM;
11048edacedfSDaniel Fojt 	s_server_config.tlscstatp.timeout = -1;
11058edacedfSDaniel Fojt 	s_server_config.tlsextcbp.extension_error =
11068edacedfSDaniel Fojt 	    SSL_TLSEXT_ERR_ALERT_WARNING;
1107f5b1c8a1SJohn Marino 
1108f5b1c8a1SJohn Marino 	local_argc = argc;
1109f5b1c8a1SJohn Marino 	local_argv = argv;
1110f5b1c8a1SJohn Marino 
1111f5b1c8a1SJohn Marino 	s_server_init();
1112f5b1c8a1SJohn Marino 
1113f5b1c8a1SJohn Marino 	verify_depth = 0;
1114f5b1c8a1SJohn Marino 
11158edacedfSDaniel Fojt 	if (options_parse(argc, argv, s_server_options, NULL, NULL) != 0) {
11168edacedfSDaniel Fojt 		if (s_server_config.errstr == NULL)
1117f5b1c8a1SJohn Marino 			sv_usage();
1118f5b1c8a1SJohn Marino 		goto end;
1119f5b1c8a1SJohn Marino 	}
1120f5b1c8a1SJohn Marino 
11218edacedfSDaniel Fojt 	if (!app_passwd(bio_err, s_server_config.passarg,
11228edacedfSDaniel Fojt 	    s_server_config.dpassarg, &pass, &dpass)) {
1123f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "Error getting password\n");
1124f5b1c8a1SJohn Marino 		goto end;
1125f5b1c8a1SJohn Marino 	}
11268edacedfSDaniel Fojt 	if (s_server_config.key_file == NULL)
11278edacedfSDaniel Fojt 		s_server_config.key_file = s_server_config.cert_file;
11288edacedfSDaniel Fojt 	if (s_server_config.key_file2 == NULL)
11298edacedfSDaniel Fojt 		s_server_config.key_file2 = s_server_config.cert_file2;
1130f5b1c8a1SJohn Marino 
11318edacedfSDaniel Fojt 	if (s_server_config.nocert == 0) {
11328edacedfSDaniel Fojt 		s_key = load_key(bio_err, s_server_config.key_file,
11338edacedfSDaniel Fojt 		    s_server_config.key_format, 0, pass,
1134f5b1c8a1SJohn Marino 		    "server certificate private key file");
1135f5b1c8a1SJohn Marino 		if (!s_key) {
1136f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1137f5b1c8a1SJohn Marino 			goto end;
1138f5b1c8a1SJohn Marino 		}
11398edacedfSDaniel Fojt 		s_cert = load_cert(bio_err, s_server_config.cert_file,
11408edacedfSDaniel Fojt 		    s_server_config.cert_format,
1141f5b1c8a1SJohn Marino 		    NULL, "server certificate file");
1142f5b1c8a1SJohn Marino 
1143f5b1c8a1SJohn Marino 		if (!s_cert) {
1144f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1145f5b1c8a1SJohn Marino 			goto end;
1146f5b1c8a1SJohn Marino 		}
11478edacedfSDaniel Fojt 		if (s_server_config.tlsextcbp.servername) {
11488edacedfSDaniel Fojt 			s_key2 = load_key(bio_err, s_server_config.key_file2,
11498edacedfSDaniel Fojt 			    s_server_config.key_format, 0, pass,
1150f5b1c8a1SJohn Marino 			    "second server certificate private key file");
1151f5b1c8a1SJohn Marino 			if (!s_key2) {
1152f5b1c8a1SJohn Marino 				ERR_print_errors(bio_err);
1153f5b1c8a1SJohn Marino 				goto end;
1154f5b1c8a1SJohn Marino 			}
11558edacedfSDaniel Fojt 			s_cert2 = load_cert(bio_err, s_server_config.cert_file2,
11568edacedfSDaniel Fojt 			    s_server_config.cert_format,
1157f5b1c8a1SJohn Marino 			    NULL, "second server certificate file");
1158f5b1c8a1SJohn Marino 
1159f5b1c8a1SJohn Marino 			if (!s_cert2) {
1160f5b1c8a1SJohn Marino 				ERR_print_errors(bio_err);
1161f5b1c8a1SJohn Marino 				goto end;
1162f5b1c8a1SJohn Marino 			}
1163f5b1c8a1SJohn Marino 		}
1164f5b1c8a1SJohn Marino 	}
1165f5b1c8a1SJohn Marino 	alpn_ctx.data = NULL;
11668edacedfSDaniel Fojt 	if (s_server_config.alpn_in) {
1167f5b1c8a1SJohn Marino 		unsigned short len;
11688edacedfSDaniel Fojt 		alpn_ctx.data = next_protos_parse(&len,
11698edacedfSDaniel Fojt 		    s_server_config.alpn_in);
1170f5b1c8a1SJohn Marino 		if (alpn_ctx.data == NULL)
1171f5b1c8a1SJohn Marino 			goto end;
1172f5b1c8a1SJohn Marino 		alpn_ctx.len = len;
1173f5b1c8a1SJohn Marino 	}
1174f5b1c8a1SJohn Marino 
11758edacedfSDaniel Fojt 	if (s_server_config.dcert_file) {
1176f5b1c8a1SJohn Marino 
11778edacedfSDaniel Fojt 		if (s_server_config.dkey_file == NULL)
11788edacedfSDaniel Fojt 			s_server_config.dkey_file = s_server_config.dcert_file;
1179f5b1c8a1SJohn Marino 
11808edacedfSDaniel Fojt 		s_dkey = load_key(bio_err, s_server_config.dkey_file,
11818edacedfSDaniel Fojt 		    s_server_config.dkey_format,
1182f5b1c8a1SJohn Marino 		    0, dpass, "second certificate private key file");
1183f5b1c8a1SJohn Marino 		if (!s_dkey) {
1184f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1185f5b1c8a1SJohn Marino 			goto end;
1186f5b1c8a1SJohn Marino 		}
11878edacedfSDaniel Fojt 		s_dcert = load_cert(bio_err, s_server_config.dcert_file,
11888edacedfSDaniel Fojt 		    s_server_config.dcert_format,
1189f5b1c8a1SJohn Marino 		    NULL, "second server certificate file");
1190f5b1c8a1SJohn Marino 
1191f5b1c8a1SJohn Marino 		if (!s_dcert) {
1192f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1193f5b1c8a1SJohn Marino 			goto end;
1194f5b1c8a1SJohn Marino 		}
1195f5b1c8a1SJohn Marino 	}
1196f5b1c8a1SJohn Marino 	if (bio_s_out == NULL) {
11978edacedfSDaniel Fojt 		if (s_server_config.quiet && !s_server_config.debug &&
11988edacedfSDaniel Fojt 		    !s_server_config.msg) {
1199f5b1c8a1SJohn Marino 			bio_s_out = BIO_new(BIO_s_null());
1200f5b1c8a1SJohn Marino 		} else {
1201f5b1c8a1SJohn Marino 			if (bio_s_out == NULL)
1202f5b1c8a1SJohn Marino 				bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
1203f5b1c8a1SJohn Marino 		}
1204f5b1c8a1SJohn Marino 	}
12058edacedfSDaniel Fojt 	if (s_server_config.nocert) {
12068edacedfSDaniel Fojt 		s_server_config.cert_file = NULL;
12078edacedfSDaniel Fojt 		s_server_config.key_file = NULL;
12088edacedfSDaniel Fojt 		s_server_config.dcert_file = NULL;
12098edacedfSDaniel Fojt 		s_server_config.dkey_file = NULL;
12108edacedfSDaniel Fojt 		s_server_config.cert_file2 = NULL;
12118edacedfSDaniel Fojt 		s_server_config.key_file2 = NULL;
1212f5b1c8a1SJohn Marino 	}
12138edacedfSDaniel Fojt 	ctx = SSL_CTX_new(s_server_config.meth);
1214f5b1c8a1SJohn Marino 	if (ctx == NULL) {
1215f5b1c8a1SJohn Marino 		ERR_print_errors(bio_err);
1216f5b1c8a1SJohn Marino 		goto end;
1217f5b1c8a1SJohn Marino 	}
12188edacedfSDaniel Fojt 
12198edacedfSDaniel Fojt 	SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
12208edacedfSDaniel Fojt 
12218edacedfSDaniel Fojt 	if (!SSL_CTX_set_min_proto_version(ctx, s_server_config.min_version))
12228edacedfSDaniel Fojt 		goto end;
12238edacedfSDaniel Fojt 	if (!SSL_CTX_set_max_proto_version(ctx, s_server_config.max_version))
12248edacedfSDaniel Fojt 		goto end;
12258edacedfSDaniel Fojt 
12268edacedfSDaniel Fojt 	if (s_server_config.session_id_prefix) {
12278edacedfSDaniel Fojt 		if (strlen(s_server_config.session_id_prefix) >= 32)
1228f5b1c8a1SJohn Marino 			BIO_printf(bio_err,
1229f5b1c8a1SJohn Marino 			    "warning: id_prefix is too long, only one new session will be possible\n");
12308edacedfSDaniel Fojt 		else if (strlen(s_server_config.session_id_prefix) >= 16)
1231f5b1c8a1SJohn Marino 			BIO_printf(bio_err,
1232f5b1c8a1SJohn Marino 			    "warning: id_prefix is too long if you use SSLv2\n");
1233f5b1c8a1SJohn Marino 		if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
1234f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "error setting 'id_prefix'\n");
1235f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1236f5b1c8a1SJohn Marino 			goto end;
1237f5b1c8a1SJohn Marino 		}
12388edacedfSDaniel Fojt 		BIO_printf(bio_err, "id_prefix '%s' set.\n",
12398edacedfSDaniel Fojt 		    s_server_config.session_id_prefix);
1240f5b1c8a1SJohn Marino 	}
1241f5b1c8a1SJohn Marino 	SSL_CTX_set_quiet_shutdown(ctx, 1);
12428edacedfSDaniel Fojt 	if (s_server_config.bugs)
1243f5b1c8a1SJohn Marino 		SSL_CTX_set_options(ctx, SSL_OP_ALL);
12448edacedfSDaniel Fojt 	SSL_CTX_set_options(ctx, s_server_config.off);
1245f5b1c8a1SJohn Marino 
12468edacedfSDaniel Fojt 	if (s_server_config.state)
1247f5b1c8a1SJohn Marino 		SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
12488edacedfSDaniel Fojt 	if (s_server_config.no_cache)
1249f5b1c8a1SJohn Marino 		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1250f5b1c8a1SJohn Marino 	else
1251f5b1c8a1SJohn Marino 		SSL_CTX_sess_set_cache_size(ctx, 128);
1252f5b1c8a1SJohn Marino 
1253f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_SRTP
12548edacedfSDaniel Fojt 	if (s_server_config.srtp_profiles != NULL)
12558edacedfSDaniel Fojt 		SSL_CTX_set_tlsext_use_srtp(ctx, s_server_config.srtp_profiles);
1256f5b1c8a1SJohn Marino #endif
1257f5b1c8a1SJohn Marino 
12588edacedfSDaniel Fojt 	if ((!SSL_CTX_load_verify_locations(ctx, s_server_config.CAfile,
12598edacedfSDaniel Fojt 	    s_server_config.CApath)) ||
1260f5b1c8a1SJohn Marino 	    (!SSL_CTX_set_default_verify_paths(ctx))) {
1261f5b1c8a1SJohn Marino 		/* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
1262f5b1c8a1SJohn Marino 		ERR_print_errors(bio_err);
1263f5b1c8a1SJohn Marino 		/* goto end; */
1264f5b1c8a1SJohn Marino 	}
12658edacedfSDaniel Fojt 	if (s_server_config.vpm)
12668edacedfSDaniel Fojt 		SSL_CTX_set1_param(ctx, s_server_config.vpm);
1267f5b1c8a1SJohn Marino 
1268f5b1c8a1SJohn Marino 	if (s_cert2) {
12698edacedfSDaniel Fojt 		ctx2 = SSL_CTX_new(s_server_config.meth);
1270f5b1c8a1SJohn Marino 		if (ctx2 == NULL) {
1271f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1272f5b1c8a1SJohn Marino 			goto end;
1273f5b1c8a1SJohn Marino 		}
12748edacedfSDaniel Fojt 
12758edacedfSDaniel Fojt 		if (!SSL_CTX_set_min_proto_version(ctx2,
12768edacedfSDaniel Fojt 		    s_server_config.min_version))
12778edacedfSDaniel Fojt 			goto end;
12788edacedfSDaniel Fojt 		if (!SSL_CTX_set_max_proto_version(ctx2,
12798edacedfSDaniel Fojt 		    s_server_config.max_version))
12808edacedfSDaniel Fojt 			goto end;
12818edacedfSDaniel Fojt 		SSL_CTX_clear_mode(ctx2, SSL_MODE_AUTO_RETRY);
1282f5b1c8a1SJohn Marino 	}
1283f5b1c8a1SJohn Marino 	if (ctx2) {
1284f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
1285f5b1c8a1SJohn Marino 
12868edacedfSDaniel Fojt 		if (s_server_config.session_id_prefix) {
12878edacedfSDaniel Fojt 			if (strlen(s_server_config.session_id_prefix) >= 32)
1288f5b1c8a1SJohn Marino 				BIO_printf(bio_err,
1289f5b1c8a1SJohn Marino 				    "warning: id_prefix is too long, only one new session will be possible\n");
12908edacedfSDaniel Fojt 			else if (strlen(s_server_config.session_id_prefix) >= 16)
1291f5b1c8a1SJohn Marino 				BIO_printf(bio_err,
1292f5b1c8a1SJohn Marino 				    "warning: id_prefix is too long if you use SSLv2\n");
12938edacedfSDaniel Fojt 			if (!SSL_CTX_set_generate_session_id(ctx2,
12948edacedfSDaniel Fojt 			    generate_session_id)) {
12958edacedfSDaniel Fojt 				BIO_printf(bio_err,
12968edacedfSDaniel Fojt 				    "error setting 'id_prefix'\n");
1297f5b1c8a1SJohn Marino 				ERR_print_errors(bio_err);
1298f5b1c8a1SJohn Marino 				goto end;
1299f5b1c8a1SJohn Marino 			}
13008edacedfSDaniel Fojt 			BIO_printf(bio_err, "id_prefix '%s' set.\n",
13018edacedfSDaniel Fojt 			    s_server_config.session_id_prefix);
1302f5b1c8a1SJohn Marino 		}
1303f5b1c8a1SJohn Marino 		SSL_CTX_set_quiet_shutdown(ctx2, 1);
13048edacedfSDaniel Fojt 		if (s_server_config.bugs)
1305f5b1c8a1SJohn Marino 			SSL_CTX_set_options(ctx2, SSL_OP_ALL);
13068edacedfSDaniel Fojt 		SSL_CTX_set_options(ctx2, s_server_config.off);
1307f5b1c8a1SJohn Marino 
13088edacedfSDaniel Fojt 		if (s_server_config.state)
1309f5b1c8a1SJohn Marino 			SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
1310f5b1c8a1SJohn Marino 
13118edacedfSDaniel Fojt 		if (s_server_config.no_cache)
1312f5b1c8a1SJohn Marino 			SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
1313f5b1c8a1SJohn Marino 		else
1314f5b1c8a1SJohn Marino 			SSL_CTX_sess_set_cache_size(ctx2, 128);
1315f5b1c8a1SJohn Marino 
13168edacedfSDaniel Fojt 		if ((!SSL_CTX_load_verify_locations(ctx2,
13178edacedfSDaniel Fojt 		    s_server_config.CAfile, s_server_config.CApath)) ||
1318f5b1c8a1SJohn Marino 		    (!SSL_CTX_set_default_verify_paths(ctx2))) {
1319f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1320f5b1c8a1SJohn Marino 		}
13218edacedfSDaniel Fojt 		if (s_server_config.vpm)
13228edacedfSDaniel Fojt 			SSL_CTX_set1_param(ctx2, s_server_config.vpm);
1323f5b1c8a1SJohn Marino 	}
1324f5b1c8a1SJohn Marino 	if (alpn_ctx.data)
1325f5b1c8a1SJohn Marino 		SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
1326f5b1c8a1SJohn Marino 
13278edacedfSDaniel Fojt 	if (s_server_config.groups_in != NULL) {
13288edacedfSDaniel Fojt 		if (SSL_CTX_set1_groups_list(ctx, s_server_config.groups_in) != 1) {
1329cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Failed to set groups '%s'\n",
13308edacedfSDaniel Fojt 			    s_server_config.groups_in);
1331cca6fc52SDaniel Fojt 			goto end;
1332cca6fc52SDaniel Fojt 		}
1333cca6fc52SDaniel Fojt 	}
1334cca6fc52SDaniel Fojt 
1335f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH
13368edacedfSDaniel Fojt 	if (!s_server_config.no_dhe) {
1337f5b1c8a1SJohn Marino 		DH *dh = NULL;
1338f5b1c8a1SJohn Marino 
13398edacedfSDaniel Fojt 		if (s_server_config.dhfile)
13408edacedfSDaniel Fojt 			dh = load_dh_param(s_server_config.dhfile);
13418edacedfSDaniel Fojt 		else if (s_server_config.cert_file)
13428edacedfSDaniel Fojt 			dh = load_dh_param(s_server_config.cert_file);
1343f5b1c8a1SJohn Marino 
1344f5b1c8a1SJohn Marino 		if (dh != NULL)
1345f5b1c8a1SJohn Marino 			BIO_printf(bio_s_out, "Setting temp DH parameters\n");
1346f5b1c8a1SJohn Marino 		else
1347f5b1c8a1SJohn Marino 			BIO_printf(bio_s_out, "Using auto DH parameters\n");
1348f5b1c8a1SJohn Marino 		(void) BIO_flush(bio_s_out);
1349f5b1c8a1SJohn Marino 
1350f5b1c8a1SJohn Marino 		if (dh == NULL)
1351f5b1c8a1SJohn Marino 			SSL_CTX_set_dh_auto(ctx, 1);
1352f5b1c8a1SJohn Marino 		else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
1353f5b1c8a1SJohn Marino 			BIO_printf(bio_err,
1354f5b1c8a1SJohn Marino 			    "Error setting temp DH parameters\n");
1355f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1356f5b1c8a1SJohn Marino 			DH_free(dh);
1357f5b1c8a1SJohn Marino 			goto end;
1358f5b1c8a1SJohn Marino 		}
1359f5b1c8a1SJohn Marino 
1360f5b1c8a1SJohn Marino 		if (ctx2) {
13618edacedfSDaniel Fojt 			if (!s_server_config.dhfile) {
1362f5b1c8a1SJohn Marino 				DH *dh2 = NULL;
1363f5b1c8a1SJohn Marino 
13648edacedfSDaniel Fojt 				if (s_server_config.cert_file2 != NULL)
13658edacedfSDaniel Fojt 					dh2 = load_dh_param(
13668edacedfSDaniel Fojt 					    s_server_config.cert_file2);
1367f5b1c8a1SJohn Marino 				if (dh2 != NULL) {
13688edacedfSDaniel Fojt 					BIO_printf(bio_s_out,
13698edacedfSDaniel Fojt 					    "Setting temp DH parameters\n");
1370f5b1c8a1SJohn Marino 					(void) BIO_flush(bio_s_out);
1371f5b1c8a1SJohn Marino 
1372f5b1c8a1SJohn Marino 					DH_free(dh);
1373f5b1c8a1SJohn Marino 					dh = dh2;
1374f5b1c8a1SJohn Marino 				}
1375f5b1c8a1SJohn Marino 			}
1376f5b1c8a1SJohn Marino 			if (dh == NULL)
1377f5b1c8a1SJohn Marino 				SSL_CTX_set_dh_auto(ctx2, 1);
1378f5b1c8a1SJohn Marino 			else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
1379f5b1c8a1SJohn Marino 				BIO_printf(bio_err,
1380f5b1c8a1SJohn Marino 				    "Error setting temp DH parameters\n");
1381f5b1c8a1SJohn Marino 				ERR_print_errors(bio_err);
1382f5b1c8a1SJohn Marino 				DH_free(dh);
1383f5b1c8a1SJohn Marino 				goto end;
1384f5b1c8a1SJohn Marino 			}
1385f5b1c8a1SJohn Marino 		}
1386f5b1c8a1SJohn Marino 		DH_free(dh);
1387f5b1c8a1SJohn Marino 	}
1388f5b1c8a1SJohn Marino #endif
1389f5b1c8a1SJohn Marino 
13908edacedfSDaniel Fojt 	if (!s_server_config.no_ecdhe && s_server_config.named_curve != NULL) {
1391f5b1c8a1SJohn Marino 		EC_KEY *ecdh = NULL;
1392cca6fc52SDaniel Fojt 		int nid;
1393f5b1c8a1SJohn Marino 
13948edacedfSDaniel Fojt 		if ((nid = OBJ_sn2nid(s_server_config.named_curve)) == 0) {
1395f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "unknown curve name (%s)\n",
13968edacedfSDaniel Fojt 			    s_server_config.named_curve);
1397f5b1c8a1SJohn Marino 			goto end;
1398f5b1c8a1SJohn Marino  		}
1399cca6fc52SDaniel Fojt 		if ((ecdh = EC_KEY_new_by_curve_name(nid)) == NULL) {
1400f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "unable to create curve (%s)\n",
14018edacedfSDaniel Fojt 			    s_server_config.named_curve);
1402f5b1c8a1SJohn Marino 			goto end;
1403f5b1c8a1SJohn Marino  		}
1404f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "Setting temp ECDH parameters\n");
1405f5b1c8a1SJohn Marino 		(void) BIO_flush(bio_s_out);
1406f5b1c8a1SJohn Marino 
1407f5b1c8a1SJohn Marino 		SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1408f5b1c8a1SJohn Marino 		if (ctx2)
1409f5b1c8a1SJohn Marino 			SSL_CTX_set_tmp_ecdh(ctx2, ecdh);
1410f5b1c8a1SJohn Marino 		EC_KEY_free(ecdh);
1411f5b1c8a1SJohn Marino 	}
1412f5b1c8a1SJohn Marino 
1413f5b1c8a1SJohn Marino 	if (!set_cert_key_stuff(ctx, s_cert, s_key))
1414f5b1c8a1SJohn Marino 		goto end;
1415f5b1c8a1SJohn Marino 	if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2))
1416f5b1c8a1SJohn Marino 		goto end;
1417f5b1c8a1SJohn Marino 	if (s_dcert != NULL) {
1418f5b1c8a1SJohn Marino 		if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
1419f5b1c8a1SJohn Marino 			goto end;
1420f5b1c8a1SJohn Marino 	}
1421f5b1c8a1SJohn Marino 
14228edacedfSDaniel Fojt 	if (s_server_config.cipher != NULL) {
14238edacedfSDaniel Fojt 		if (!SSL_CTX_set_cipher_list(ctx, s_server_config.cipher)) {
1424f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "error setting cipher list\n");
1425f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1426f5b1c8a1SJohn Marino 			goto end;
1427f5b1c8a1SJohn Marino 		}
14288edacedfSDaniel Fojt 		if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,
14298edacedfSDaniel Fojt 		    s_server_config.cipher)) {
1430f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "error setting cipher list\n");
1431f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1432f5b1c8a1SJohn Marino 			goto end;
1433f5b1c8a1SJohn Marino 		}
1434f5b1c8a1SJohn Marino 	}
14358edacedfSDaniel Fojt 	SSL_CTX_set_verify(ctx, s_server_config.server_verify, verify_callback);
14368edacedfSDaniel Fojt 	SSL_CTX_set_session_id_context(ctx,
14378edacedfSDaniel Fojt 	    (void *) &s_server_session_id_context,
1438f5b1c8a1SJohn Marino 	    sizeof s_server_session_id_context);
1439f5b1c8a1SJohn Marino 
1440f5b1c8a1SJohn Marino 	/* Set DTLS cookie generation and verification callbacks */
1441f5b1c8a1SJohn Marino 	SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
1442f5b1c8a1SJohn Marino 	SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
1443f5b1c8a1SJohn Marino 
1444f5b1c8a1SJohn Marino 	if (ctx2) {
14458edacedfSDaniel Fojt 		SSL_CTX_set_verify(ctx2, s_server_config.server_verify,
14468edacedfSDaniel Fojt 		    verify_callback);
14478edacedfSDaniel Fojt 		SSL_CTX_set_session_id_context(ctx2,
14488edacedfSDaniel Fojt 		    (void *) &s_server_session_id_context,
1449f5b1c8a1SJohn Marino 		    sizeof s_server_session_id_context);
1450f5b1c8a1SJohn Marino 
14518edacedfSDaniel Fojt 		s_server_config.tlsextcbp.biodebug = bio_s_out;
1452f5b1c8a1SJohn Marino 		SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
14538edacedfSDaniel Fojt 		SSL_CTX_set_tlsext_servername_arg(ctx2,
14548edacedfSDaniel Fojt 		    &s_server_config.tlsextcbp);
1455f5b1c8a1SJohn Marino 		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
14568edacedfSDaniel Fojt 		SSL_CTX_set_tlsext_servername_arg(ctx,
14578edacedfSDaniel Fojt 		    &s_server_config.tlsextcbp);
1458f5b1c8a1SJohn Marino 	}
1459f5b1c8a1SJohn Marino 
14608edacedfSDaniel Fojt 	if (s_server_config.CAfile != NULL) {
14618edacedfSDaniel Fojt 		SSL_CTX_set_client_CA_list(ctx,
14628edacedfSDaniel Fojt 		    SSL_load_client_CA_file(s_server_config.CAfile));
1463f5b1c8a1SJohn Marino 		if (ctx2)
14648edacedfSDaniel Fojt 			SSL_CTX_set_client_CA_list(ctx2,
14658edacedfSDaniel Fojt 			    SSL_load_client_CA_file(s_server_config.CAfile));
1466f5b1c8a1SJohn Marino 	}
1467f5b1c8a1SJohn Marino 	BIO_printf(bio_s_out, "ACCEPT\n");
1468f5b1c8a1SJohn Marino 	(void) BIO_flush(bio_s_out);
14698edacedfSDaniel Fojt 	if (s_server_config.www)
14708edacedfSDaniel Fojt 		do_server(s_server_config.port, s_server_config.socket_type,
1471*de0e0e4dSAntonio Huete Jimenez 		    &accept_socket, www_body, s_server_config.context,
1472*de0e0e4dSAntonio Huete Jimenez 		    s_server_config.naccept);
1473f5b1c8a1SJohn Marino 	else
14748edacedfSDaniel Fojt 		do_server(s_server_config.port, s_server_config.socket_type,
1475*de0e0e4dSAntonio Huete Jimenez 		    &accept_socket, sv_body, s_server_config.context,
1476*de0e0e4dSAntonio Huete Jimenez 		    s_server_config.naccept);
1477f5b1c8a1SJohn Marino 	print_stats(bio_s_out, ctx);
1478f5b1c8a1SJohn Marino 	ret = 0;
1479f5b1c8a1SJohn Marino  end:
1480f5b1c8a1SJohn Marino 	SSL_CTX_free(ctx);
1481f5b1c8a1SJohn Marino 	X509_free(s_cert);
1482f5b1c8a1SJohn Marino 	X509_free(s_dcert);
1483f5b1c8a1SJohn Marino 	EVP_PKEY_free(s_key);
1484f5b1c8a1SJohn Marino 	EVP_PKEY_free(s_dkey);
1485f5b1c8a1SJohn Marino 	free(pass);
1486f5b1c8a1SJohn Marino 	free(dpass);
14878edacedfSDaniel Fojt 	X509_VERIFY_PARAM_free(s_server_config.vpm);
14888edacedfSDaniel Fojt 	free(s_server_config.tlscstatp.host);
14898edacedfSDaniel Fojt 	free(s_server_config.tlscstatp.port);
14908edacedfSDaniel Fojt 	free(s_server_config.tlscstatp.path);
1491f5b1c8a1SJohn Marino 	SSL_CTX_free(ctx2);
1492f5b1c8a1SJohn Marino 	X509_free(s_cert2);
1493f5b1c8a1SJohn Marino 	EVP_PKEY_free(s_key2);
1494f5b1c8a1SJohn Marino 	free(alpn_ctx.data);
1495f5b1c8a1SJohn Marino 	if (bio_s_out != NULL) {
1496f5b1c8a1SJohn Marino 		BIO_free(bio_s_out);
1497f5b1c8a1SJohn Marino 		bio_s_out = NULL;
1498f5b1c8a1SJohn Marino 	}
1499f5b1c8a1SJohn Marino 
1500f5b1c8a1SJohn Marino 	return (ret);
1501f5b1c8a1SJohn Marino }
1502f5b1c8a1SJohn Marino 
1503f5b1c8a1SJohn Marino static void
print_stats(BIO * bio,SSL_CTX * ssl_ctx)1504f5b1c8a1SJohn Marino print_stats(BIO *bio, SSL_CTX *ssl_ctx)
1505f5b1c8a1SJohn Marino {
1506f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld items in the session cache\n",
1507f5b1c8a1SJohn Marino 	    SSL_CTX_sess_number(ssl_ctx));
1508f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
1509f5b1c8a1SJohn Marino 	    SSL_CTX_sess_connect(ssl_ctx));
1510f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
1511f5b1c8a1SJohn Marino 	    SSL_CTX_sess_connect_renegotiate(ssl_ctx));
1512f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld client connects that finished\n",
1513f5b1c8a1SJohn Marino 	    SSL_CTX_sess_connect_good(ssl_ctx));
1514f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
1515f5b1c8a1SJohn Marino 	    SSL_CTX_sess_accept(ssl_ctx));
1516f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
1517f5b1c8a1SJohn Marino 	    SSL_CTX_sess_accept_renegotiate(ssl_ctx));
1518f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld server accepts that finished\n",
1519f5b1c8a1SJohn Marino 	    SSL_CTX_sess_accept_good(ssl_ctx));
15208edacedfSDaniel Fojt 	BIO_printf(bio, "%4ld session cache hits\n",
15218edacedfSDaniel Fojt 	    SSL_CTX_sess_hits(ssl_ctx));
15228edacedfSDaniel Fojt 	BIO_printf(bio, "%4ld session cache misses\n",
15238edacedfSDaniel Fojt 	    SSL_CTX_sess_misses(ssl_ctx));
15248edacedfSDaniel Fojt 	BIO_printf(bio, "%4ld session cache timeouts\n",
15258edacedfSDaniel Fojt 	    SSL_CTX_sess_timeouts(ssl_ctx));
15268edacedfSDaniel Fojt 	BIO_printf(bio, "%4ld callback cache hits\n",
15278edacedfSDaniel Fojt 	    SSL_CTX_sess_cb_hits(ssl_ctx));
1528f5b1c8a1SJohn Marino 	BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
1529f5b1c8a1SJohn Marino 	    SSL_CTX_sess_cache_full(ssl_ctx),
1530f5b1c8a1SJohn Marino 	    SSL_CTX_sess_get_cache_size(ssl_ctx));
1531f5b1c8a1SJohn Marino }
1532f5b1c8a1SJohn Marino 
1533f5b1c8a1SJohn Marino static int
sv_body(int s,unsigned char * context)1534*de0e0e4dSAntonio Huete Jimenez sv_body(int s, unsigned char *context)
1535f5b1c8a1SJohn Marino {
1536f5b1c8a1SJohn Marino 	char *buf = NULL;
1537f5b1c8a1SJohn Marino 	int ret = 1;
1538f5b1c8a1SJohn Marino 	int k, i;
1539f5b1c8a1SJohn Marino 	unsigned long l;
1540f5b1c8a1SJohn Marino 	SSL *con = NULL;
1541f5b1c8a1SJohn Marino 	BIO *sbio;
1542f5b1c8a1SJohn Marino 	struct timeval timeout;
1543f5b1c8a1SJohn Marino 
1544f5b1c8a1SJohn Marino 	if ((buf = malloc(bufsize)) == NULL) {
1545f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "out of memory\n");
1546f5b1c8a1SJohn Marino 		goto err;
1547f5b1c8a1SJohn Marino 	}
15488edacedfSDaniel Fojt 	if (s_server_config.nbio) {
15498edacedfSDaniel Fojt 		if (!s_server_config.quiet)
1550f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "turning on non blocking io\n");
1551f5b1c8a1SJohn Marino 		if (!BIO_socket_nbio(s, 1))
1552f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1553f5b1c8a1SJohn Marino 	}
1554f5b1c8a1SJohn Marino 
1555f5b1c8a1SJohn Marino 	if (con == NULL) {
1556f5b1c8a1SJohn Marino 		con = SSL_new(ctx);
15578edacedfSDaniel Fojt 		if (s_server_config.tlsextdebug) {
1558f5b1c8a1SJohn Marino 			SSL_set_tlsext_debug_callback(con, tlsext_cb);
1559f5b1c8a1SJohn Marino 			SSL_set_tlsext_debug_arg(con, bio_s_out);
1560f5b1c8a1SJohn Marino 		}
15618edacedfSDaniel Fojt 		if (s_server_config.tlsextstatus) {
1562f5b1c8a1SJohn Marino 			SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
15638edacedfSDaniel Fojt 			s_server_config.tlscstatp.err = bio_err;
15648edacedfSDaniel Fojt 			SSL_CTX_set_tlsext_status_arg(ctx,
15658edacedfSDaniel Fojt 			    &s_server_config.tlscstatp);
1566f5b1c8a1SJohn Marino 		}
1567f5b1c8a1SJohn Marino 		if (context)
1568f5b1c8a1SJohn Marino 			SSL_set_session_id_context(con, context,
1569f5b1c8a1SJohn Marino 			    strlen((char *) context));
1570f5b1c8a1SJohn Marino 	}
1571f5b1c8a1SJohn Marino 	SSL_clear(con);
1572f5b1c8a1SJohn Marino 
1573*de0e0e4dSAntonio Huete Jimenez 	if (SSL_is_dtls(con)) {
1574f5b1c8a1SJohn Marino 		sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1575f5b1c8a1SJohn Marino 
15768edacedfSDaniel Fojt 		if (s_server_config.enable_timeouts) {
1577f5b1c8a1SJohn Marino 			timeout.tv_sec = 0;
1578f5b1c8a1SJohn Marino 			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
15798edacedfSDaniel Fojt 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0,
15808edacedfSDaniel Fojt 			    &timeout);
1581f5b1c8a1SJohn Marino 
1582f5b1c8a1SJohn Marino 			timeout.tv_sec = 0;
1583f5b1c8a1SJohn Marino 			timeout.tv_usec = DGRAM_SND_TIMEOUT;
15848edacedfSDaniel Fojt 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0,
15858edacedfSDaniel Fojt 			    &timeout);
1586f5b1c8a1SJohn Marino 		}
15878edacedfSDaniel Fojt 		if (s_server_config.socket_mtu > 28) {
1588f5b1c8a1SJohn Marino 			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
15898edacedfSDaniel Fojt 			SSL_set_mtu(con, s_server_config.socket_mtu - 28);
1590f5b1c8a1SJohn Marino 		} else
1591f5b1c8a1SJohn Marino 			/* want to do MTU discovery */
1592f5b1c8a1SJohn Marino 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1593f5b1c8a1SJohn Marino 
1594f5b1c8a1SJohn Marino 		/* turn on cookie exchange */
1595f5b1c8a1SJohn Marino 		SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
1596f5b1c8a1SJohn Marino 	} else
1597f5b1c8a1SJohn Marino 		sbio = BIO_new_socket(s, BIO_NOCLOSE);
1598f5b1c8a1SJohn Marino 
15998edacedfSDaniel Fojt 	if (s_server_config.nbio_test) {
1600f5b1c8a1SJohn Marino 		BIO *test;
1601f5b1c8a1SJohn Marino 
1602f5b1c8a1SJohn Marino 		test = BIO_new(BIO_f_nbio_test());
1603f5b1c8a1SJohn Marino 		sbio = BIO_push(test, sbio);
1604f5b1c8a1SJohn Marino 	}
1605f5b1c8a1SJohn Marino 
1606f5b1c8a1SJohn Marino 	SSL_set_bio(con, sbio, sbio);
1607f5b1c8a1SJohn Marino 	SSL_set_accept_state(con);
1608f5b1c8a1SJohn Marino 	/* SSL_set_fd(con,s); */
1609f5b1c8a1SJohn Marino 
16108edacedfSDaniel Fojt 	if (s_server_config.debug) {
1611f5b1c8a1SJohn Marino 		SSL_set_debug(con, 1);
1612f5b1c8a1SJohn Marino 		BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
1613f5b1c8a1SJohn Marino 		BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out);
1614f5b1c8a1SJohn Marino 	}
16158edacedfSDaniel Fojt 	if (s_server_config.msg) {
1616f5b1c8a1SJohn Marino 		SSL_set_msg_callback(con, msg_cb);
1617f5b1c8a1SJohn Marino 		SSL_set_msg_callback_arg(con, bio_s_out);
1618f5b1c8a1SJohn Marino 	}
16198edacedfSDaniel Fojt 	if (s_server_config.tlsextdebug) {
1620f5b1c8a1SJohn Marino 		SSL_set_tlsext_debug_callback(con, tlsext_cb);
1621f5b1c8a1SJohn Marino 		SSL_set_tlsext_debug_arg(con, bio_s_out);
1622f5b1c8a1SJohn Marino 	}
1623f5b1c8a1SJohn Marino 
1624f5b1c8a1SJohn Marino 	for (;;) {
1625f5b1c8a1SJohn Marino 		int read_from_terminal;
1626f5b1c8a1SJohn Marino 		int read_from_sslcon;
1627f5b1c8a1SJohn Marino 		struct pollfd pfd[2];
1628f5b1c8a1SJohn Marino 		int ptimeout;
1629f5b1c8a1SJohn Marino 
1630f5b1c8a1SJohn Marino 		read_from_terminal = 0;
1631f5b1c8a1SJohn Marino 		read_from_sslcon = SSL_pending(con);
1632f5b1c8a1SJohn Marino 
1633f5b1c8a1SJohn Marino 		if (!read_from_sslcon) {
1634f5b1c8a1SJohn Marino 			pfd[0].fd = fileno(stdin);
1635f5b1c8a1SJohn Marino 			pfd[0].events = POLLIN;
1636f5b1c8a1SJohn Marino 			pfd[1].fd = s;
1637f5b1c8a1SJohn Marino 			pfd[1].events = POLLIN;
1638f5b1c8a1SJohn Marino 
1639*de0e0e4dSAntonio Huete Jimenez 			if (SSL_is_dtls(con) &&
1640f5b1c8a1SJohn Marino 			    DTLSv1_get_timeout(con, &timeout))
1641f5b1c8a1SJohn Marino 				ptimeout = timeout.tv_sec * 1000 +
1642f5b1c8a1SJohn Marino 				    timeout.tv_usec / 1000;
1643f5b1c8a1SJohn Marino 			else
1644f5b1c8a1SJohn Marino 				ptimeout = -1;
1645f5b1c8a1SJohn Marino 
1646f5b1c8a1SJohn Marino 			i = poll(pfd, 2, ptimeout);
1647f5b1c8a1SJohn Marino 
1648*de0e0e4dSAntonio Huete Jimenez 			if (SSL_is_dtls(con) &&
1649*de0e0e4dSAntonio Huete Jimenez 			    DTLSv1_handle_timeout(con) > 0)
1650f5b1c8a1SJohn Marino 				BIO_printf(bio_err, "TIMEOUT occured\n");
1651f5b1c8a1SJohn Marino 			if (i <= 0)
1652f5b1c8a1SJohn Marino 				continue;
1653f5b1c8a1SJohn Marino 			if (pfd[0].revents) {
1654f5b1c8a1SJohn Marino 				if ((pfd[0].revents & (POLLERR|POLLNVAL)))
1655f5b1c8a1SJohn Marino 					continue;
1656f5b1c8a1SJohn Marino 				read_from_terminal = 1;
1657f5b1c8a1SJohn Marino 			}
1658f5b1c8a1SJohn Marino 			if (pfd[1].revents) {
1659f5b1c8a1SJohn Marino 				if ((pfd[1].revents & (POLLERR|POLLNVAL)))
1660f5b1c8a1SJohn Marino 					continue;
1661f5b1c8a1SJohn Marino 				read_from_sslcon = 1;
1662f5b1c8a1SJohn Marino 			}
1663f5b1c8a1SJohn Marino 		}
1664f5b1c8a1SJohn Marino 		if (read_from_terminal) {
16658edacedfSDaniel Fojt 			if (s_server_config.crlf) {
1666f5b1c8a1SJohn Marino 				int j, lf_num;
1667f5b1c8a1SJohn Marino 
1668f5b1c8a1SJohn Marino 				i = read(fileno(stdin), buf, bufsize / 2);
1669f5b1c8a1SJohn Marino 				lf_num = 0;
1670f5b1c8a1SJohn Marino 				/* both loops are skipped when i <= 0 */
1671f5b1c8a1SJohn Marino 				for (j = 0; j < i; j++)
1672f5b1c8a1SJohn Marino 					if (buf[j] == '\n')
1673f5b1c8a1SJohn Marino 						lf_num++;
1674f5b1c8a1SJohn Marino 				for (j = i - 1; j >= 0; j--) {
1675f5b1c8a1SJohn Marino 					buf[j + lf_num] = buf[j];
1676f5b1c8a1SJohn Marino 					if (buf[j] == '\n') {
1677f5b1c8a1SJohn Marino 						lf_num--;
1678f5b1c8a1SJohn Marino 						i++;
1679f5b1c8a1SJohn Marino 						buf[j + lf_num] = '\r';
1680f5b1c8a1SJohn Marino 					}
1681f5b1c8a1SJohn Marino 				}
1682f5b1c8a1SJohn Marino 				assert(lf_num == 0);
1683f5b1c8a1SJohn Marino 			} else
1684f5b1c8a1SJohn Marino 				i = read(fileno(stdin), buf, bufsize);
16858edacedfSDaniel Fojt 			if (!s_server_config.quiet) {
1686f5b1c8a1SJohn Marino 				if ((i <= 0) || (buf[0] == 'Q')) {
1687f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "DONE\n");
1688f5b1c8a1SJohn Marino 					shutdown(s, SHUT_RD);
1689f5b1c8a1SJohn Marino 					close(s);
1690f5b1c8a1SJohn Marino 					close_accept_socket();
1691f5b1c8a1SJohn Marino 					ret = -11;
1692f5b1c8a1SJohn Marino 					goto err;
1693f5b1c8a1SJohn Marino 				}
1694f5b1c8a1SJohn Marino 				if ((i <= 0) || (buf[0] == 'q')) {
1695f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "DONE\n");
1696*de0e0e4dSAntonio Huete Jimenez 					if (!SSL_is_dtls(con)) {
1697f5b1c8a1SJohn Marino 						shutdown(s, SHUT_RD);
1698f5b1c8a1SJohn Marino 						close(s);
1699f5b1c8a1SJohn Marino 					}
1700f5b1c8a1SJohn Marino 					/*
1701f5b1c8a1SJohn Marino 					 * close_accept_socket(); ret= -11;
1702f5b1c8a1SJohn Marino 					 */
1703f5b1c8a1SJohn Marino 					goto err;
1704f5b1c8a1SJohn Marino 				}
1705f5b1c8a1SJohn Marino 				if ((buf[0] == 'r') &&
1706f5b1c8a1SJohn Marino 				    ((buf[1] == '\n') || (buf[1] == '\r'))) {
1707f5b1c8a1SJohn Marino 					SSL_renegotiate(con);
1708f5b1c8a1SJohn Marino 					i = SSL_do_handshake(con);
1709f5b1c8a1SJohn Marino 					printf("SSL_do_handshake -> %d\n", i);
1710f5b1c8a1SJohn Marino 					i = 0;	/* 13; */
1711f5b1c8a1SJohn Marino 					continue;
1712f5b1c8a1SJohn Marino 					/*
1713f5b1c8a1SJohn Marino 					 * RE-NEGOTIATE\n");
1714f5b1c8a1SJohn Marino 					 */
1715f5b1c8a1SJohn Marino 				}
1716f5b1c8a1SJohn Marino 				if ((buf[0] == 'R') &&
1717f5b1c8a1SJohn Marino 				    ((buf[1] == '\n') || (buf[1] == '\r'))) {
1718f5b1c8a1SJohn Marino 					SSL_set_verify(con,
17198edacedfSDaniel Fojt 					    SSL_VERIFY_PEER |
17208edacedfSDaniel Fojt 					    SSL_VERIFY_CLIENT_ONCE,
17218edacedfSDaniel Fojt 					    NULL);
1722f5b1c8a1SJohn Marino 					SSL_renegotiate(con);
1723f5b1c8a1SJohn Marino 					i = SSL_do_handshake(con);
1724f5b1c8a1SJohn Marino 					printf("SSL_do_handshake -> %d\n", i);
1725f5b1c8a1SJohn Marino 					i = 0;	/* 13; */
1726f5b1c8a1SJohn Marino 					continue;
1727f5b1c8a1SJohn Marino 					/*
1728f5b1c8a1SJohn Marino 					 * RE-NEGOTIATE asking for client
1729f5b1c8a1SJohn Marino 					 * cert\n");
1730f5b1c8a1SJohn Marino 					 */
1731f5b1c8a1SJohn Marino 				}
1732f5b1c8a1SJohn Marino 				if (buf[0] == 'P') {
17338edacedfSDaniel Fojt 					static const char *str =
17348edacedfSDaniel Fojt 					    "Lets print some clear text\n";
17358edacedfSDaniel Fojt 					BIO_write(SSL_get_wbio(con), str,
17368edacedfSDaniel Fojt 					    strlen(str));
1737f5b1c8a1SJohn Marino 				}
1738f5b1c8a1SJohn Marino 				if (buf[0] == 'S') {
17398edacedfSDaniel Fojt 					print_stats(bio_s_out,
17408edacedfSDaniel Fojt 					    SSL_get_SSL_CTX(con));
1741f5b1c8a1SJohn Marino 				}
1742f5b1c8a1SJohn Marino 			}
1743f5b1c8a1SJohn Marino 			l = k = 0;
1744f5b1c8a1SJohn Marino 			for (;;) {
1745f5b1c8a1SJohn Marino 				/* should do a select for the write */
1746f5b1c8a1SJohn Marino #ifdef RENEG
1747f5b1c8a1SJohn Marino 				{
1748f5b1c8a1SJohn Marino 					static count = 0;
1749f5b1c8a1SJohn Marino 					if (++count == 100) {
1750f5b1c8a1SJohn Marino 						count = 0;
1751f5b1c8a1SJohn Marino 						SSL_renegotiate(con);
1752f5b1c8a1SJohn Marino 					}
1753f5b1c8a1SJohn Marino 				}
1754f5b1c8a1SJohn Marino #endif
1755f5b1c8a1SJohn Marino 				k = SSL_write(con, &(buf[l]), (unsigned int) i);
1756f5b1c8a1SJohn Marino 				switch (SSL_get_error(con, k)) {
1757f5b1c8a1SJohn Marino 				case SSL_ERROR_NONE:
1758f5b1c8a1SJohn Marino 					break;
1759f5b1c8a1SJohn Marino 				case SSL_ERROR_WANT_WRITE:
1760f5b1c8a1SJohn Marino 				case SSL_ERROR_WANT_READ:
1761f5b1c8a1SJohn Marino 				case SSL_ERROR_WANT_X509_LOOKUP:
1762f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "Write BLOCK\n");
1763f5b1c8a1SJohn Marino 					break;
1764f5b1c8a1SJohn Marino 				case SSL_ERROR_SYSCALL:
1765f5b1c8a1SJohn Marino 				case SSL_ERROR_SSL:
1766f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "ERROR\n");
1767f5b1c8a1SJohn Marino 					ERR_print_errors(bio_err);
1768f5b1c8a1SJohn Marino 					ret = 1;
1769f5b1c8a1SJohn Marino 					goto err;
1770f5b1c8a1SJohn Marino 					/* break; */
1771f5b1c8a1SJohn Marino 				case SSL_ERROR_ZERO_RETURN:
1772f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "DONE\n");
1773f5b1c8a1SJohn Marino 					ret = 1;
1774f5b1c8a1SJohn Marino 					goto err;
1775f5b1c8a1SJohn Marino 				}
17768edacedfSDaniel Fojt 				if (k <= 0)
17778edacedfSDaniel Fojt 					continue;
1778f5b1c8a1SJohn Marino 				l += k;
1779f5b1c8a1SJohn Marino 				i -= k;
1780f5b1c8a1SJohn Marino 				if (i <= 0)
1781f5b1c8a1SJohn Marino 					break;
1782f5b1c8a1SJohn Marino 			}
1783f5b1c8a1SJohn Marino 		}
1784f5b1c8a1SJohn Marino 		if (read_from_sslcon) {
1785f5b1c8a1SJohn Marino 			if (!SSL_is_init_finished(con)) {
1786f5b1c8a1SJohn Marino 				i = init_ssl_connection(con);
1787f5b1c8a1SJohn Marino 
1788f5b1c8a1SJohn Marino 				if (i < 0) {
1789f5b1c8a1SJohn Marino 					ret = 0;
1790f5b1c8a1SJohn Marino 					goto err;
1791f5b1c8a1SJohn Marino 				} else if (i == 0) {
1792f5b1c8a1SJohn Marino 					ret = 1;
1793f5b1c8a1SJohn Marino 					goto err;
1794f5b1c8a1SJohn Marino 				}
1795f5b1c8a1SJohn Marino 			} else {
1796f5b1c8a1SJohn Marino 		again:
1797f5b1c8a1SJohn Marino 				i = SSL_read(con, (char *) buf, bufsize);
1798f5b1c8a1SJohn Marino 				switch (SSL_get_error(con, i)) {
1799f5b1c8a1SJohn Marino 				case SSL_ERROR_NONE: {
1800f5b1c8a1SJohn Marino 						int len, n;
1801f5b1c8a1SJohn Marino 						for (len = 0; len < i;) {
1802f5b1c8a1SJohn Marino 							do {
1803f5b1c8a1SJohn Marino 								n = write(fileno(stdout), buf + len, i - len);
1804f5b1c8a1SJohn Marino 							} while (n == -1 && errno == EINTR);
1805f5b1c8a1SJohn Marino 
1806cca6fc52SDaniel Fojt 							if (n == -1) {
1807f5b1c8a1SJohn Marino 								BIO_printf(bio_s_out, "ERROR\n");
1808f5b1c8a1SJohn Marino 								goto err;
1809f5b1c8a1SJohn Marino 							}
1810f5b1c8a1SJohn Marino 							len += n;
1811f5b1c8a1SJohn Marino 						}
1812f5b1c8a1SJohn Marino 					}
1813f5b1c8a1SJohn Marino 					if (SSL_pending(con))
1814f5b1c8a1SJohn Marino 						goto again;
1815f5b1c8a1SJohn Marino 					break;
1816f5b1c8a1SJohn Marino 				case SSL_ERROR_WANT_WRITE:
1817f5b1c8a1SJohn Marino 				case SSL_ERROR_WANT_READ:
1818f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "Read BLOCK\n");
1819f5b1c8a1SJohn Marino 					break;
1820f5b1c8a1SJohn Marino 				case SSL_ERROR_SYSCALL:
1821f5b1c8a1SJohn Marino 				case SSL_ERROR_SSL:
1822f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "ERROR\n");
1823f5b1c8a1SJohn Marino 					ERR_print_errors(bio_err);
1824f5b1c8a1SJohn Marino 					ret = 1;
1825f5b1c8a1SJohn Marino 					goto err;
1826f5b1c8a1SJohn Marino 				case SSL_ERROR_ZERO_RETURN:
1827f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "DONE\n");
1828f5b1c8a1SJohn Marino 					ret = 1;
1829f5b1c8a1SJohn Marino 					goto err;
1830f5b1c8a1SJohn Marino 				}
1831f5b1c8a1SJohn Marino 			}
1832f5b1c8a1SJohn Marino 		}
1833f5b1c8a1SJohn Marino 	}
1834f5b1c8a1SJohn Marino  err:
1835f5b1c8a1SJohn Marino 	if (con != NULL) {
1836f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "shutting down SSL\n");
18378edacedfSDaniel Fojt 		SSL_set_shutdown(con,
18388edacedfSDaniel Fojt 		    SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
1839f5b1c8a1SJohn Marino 		SSL_free(con);
1840f5b1c8a1SJohn Marino 	}
1841f5b1c8a1SJohn Marino 	BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
184272c33676SMaxim Ag 	freezero(buf, bufsize);
1843f5b1c8a1SJohn Marino 	if (ret >= 0)
1844f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "ACCEPT\n");
1845f5b1c8a1SJohn Marino 	return (ret);
1846f5b1c8a1SJohn Marino }
1847f5b1c8a1SJohn Marino 
1848f5b1c8a1SJohn Marino static void
close_accept_socket(void)1849f5b1c8a1SJohn Marino close_accept_socket(void)
1850f5b1c8a1SJohn Marino {
1851f5b1c8a1SJohn Marino 	BIO_printf(bio_err, "shutdown accept socket\n");
1852f5b1c8a1SJohn Marino 	if (accept_socket >= 0) {
1853f5b1c8a1SJohn Marino 		shutdown(accept_socket, SHUT_RDWR);
1854f5b1c8a1SJohn Marino 		close(accept_socket);
1855f5b1c8a1SJohn Marino 	}
1856f5b1c8a1SJohn Marino }
1857f5b1c8a1SJohn Marino 
1858f5b1c8a1SJohn Marino static int
init_ssl_connection(SSL * con)1859f5b1c8a1SJohn Marino init_ssl_connection(SSL *con)
1860f5b1c8a1SJohn Marino {
1861f5b1c8a1SJohn Marino 	int i;
1862f5b1c8a1SJohn Marino 	const char *str;
1863f5b1c8a1SJohn Marino 	X509 *peer;
1864f5b1c8a1SJohn Marino 	long verify_error;
1865f5b1c8a1SJohn Marino 	char buf[BUFSIZ];
1866f5b1c8a1SJohn Marino 	unsigned char *exportedkeymat;
1867f5b1c8a1SJohn Marino 
1868f5b1c8a1SJohn Marino 	i = SSL_accept(con);
1869f5b1c8a1SJohn Marino 	if (i <= 0) {
1870f5b1c8a1SJohn Marino 		if (BIO_sock_should_retry(i)) {
1871f5b1c8a1SJohn Marino 			BIO_printf(bio_s_out, "DELAY\n");
1872f5b1c8a1SJohn Marino 			return (1);
1873f5b1c8a1SJohn Marino 		}
1874f5b1c8a1SJohn Marino 		BIO_printf(bio_err, "ERROR\n");
1875f5b1c8a1SJohn Marino 		verify_error = SSL_get_verify_result(con);
1876f5b1c8a1SJohn Marino 		if (verify_error != X509_V_OK) {
1877f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "verify error:%s\n",
1878f5b1c8a1SJohn Marino 			    X509_verify_cert_error_string(verify_error));
1879f5b1c8a1SJohn Marino 		} else
1880f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1881f5b1c8a1SJohn Marino 		return (0);
1882f5b1c8a1SJohn Marino 	}
1883f5b1c8a1SJohn Marino 	PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
1884f5b1c8a1SJohn Marino 
1885f5b1c8a1SJohn Marino 	peer = SSL_get_peer_certificate(con);
1886f5b1c8a1SJohn Marino 	if (peer != NULL) {
1887f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "Client certificate\n");
1888f5b1c8a1SJohn Marino 		PEM_write_bio_X509(bio_s_out, peer);
1889f5b1c8a1SJohn Marino 		X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
1890f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "subject=%s\n", buf);
1891f5b1c8a1SJohn Marino 		X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
1892f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "issuer=%s\n", buf);
1893f5b1c8a1SJohn Marino 		X509_free(peer);
1894f5b1c8a1SJohn Marino 	}
1895f5b1c8a1SJohn Marino 	if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
1896f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
1897f5b1c8a1SJohn Marino 	str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
1898f5b1c8a1SJohn Marino 	BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
1899f5b1c8a1SJohn Marino 
1900f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_SRTP
1901f5b1c8a1SJohn Marino 	{
1902f5b1c8a1SJohn Marino 		SRTP_PROTECTION_PROFILE *srtp_profile
1903f5b1c8a1SJohn Marino 		= SSL_get_selected_srtp_profile(con);
1904f5b1c8a1SJohn Marino 
1905f5b1c8a1SJohn Marino 		if (srtp_profile)
19068edacedfSDaniel Fojt 			BIO_printf(bio_s_out,
19078edacedfSDaniel Fojt 			    "SRTP Extension negotiated, profile=%s\n",
1908f5b1c8a1SJohn Marino 			    srtp_profile->name);
1909f5b1c8a1SJohn Marino 	}
1910f5b1c8a1SJohn Marino #endif
1911f5b1c8a1SJohn Marino 	if (SSL_cache_hit(con))
1912f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "Reused session-id\n");
1913f5b1c8a1SJohn Marino 	BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
1914f5b1c8a1SJohn Marino 	    SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
19158edacedfSDaniel Fojt 	if (s_server_config.keymatexportlabel != NULL) {
1916f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "Keying material exporter:\n");
19178edacedfSDaniel Fojt 		BIO_printf(bio_s_out, "    Label: '%s'\n",
19188edacedfSDaniel Fojt 		    s_server_config.keymatexportlabel);
1919f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "    Length: %i bytes\n",
19208edacedfSDaniel Fojt 		    s_server_config.keymatexportlen);
19218edacedfSDaniel Fojt 		exportedkeymat = malloc(s_server_config.keymatexportlen);
1922f5b1c8a1SJohn Marino 		if (exportedkeymat != NULL) {
1923f5b1c8a1SJohn Marino 			if (!SSL_export_keying_material(con, exportedkeymat,
19248edacedfSDaniel Fojt 				s_server_config.keymatexportlen,
19258edacedfSDaniel Fojt 				s_server_config.keymatexportlabel,
19268edacedfSDaniel Fojt 				strlen(s_server_config.keymatexportlabel),
1927f5b1c8a1SJohn Marino 				NULL, 0, 0)) {
1928f5b1c8a1SJohn Marino 				BIO_printf(bio_s_out, "    Error\n");
1929f5b1c8a1SJohn Marino 			} else {
1930f5b1c8a1SJohn Marino 				BIO_printf(bio_s_out, "    Keying material: ");
19318edacedfSDaniel Fojt 				for (i = 0; i < s_server_config.keymatexportlen; i++)
1932f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "%02X",
1933f5b1c8a1SJohn Marino 					    exportedkeymat[i]);
1934f5b1c8a1SJohn Marino 				BIO_printf(bio_s_out, "\n");
1935f5b1c8a1SJohn Marino 			}
1936f5b1c8a1SJohn Marino 			free(exportedkeymat);
1937f5b1c8a1SJohn Marino 		}
1938f5b1c8a1SJohn Marino 	}
1939f5b1c8a1SJohn Marino 	return (1);
1940f5b1c8a1SJohn Marino }
1941f5b1c8a1SJohn Marino 
1942f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH
1943f5b1c8a1SJohn Marino static DH *
load_dh_param(const char * dhfile)1944f5b1c8a1SJohn Marino load_dh_param(const char *dhfile)
1945f5b1c8a1SJohn Marino {
1946f5b1c8a1SJohn Marino 	DH *ret = NULL;
1947f5b1c8a1SJohn Marino 	BIO *bio;
1948f5b1c8a1SJohn Marino 
1949f5b1c8a1SJohn Marino 	if ((bio = BIO_new_file(dhfile, "r")) == NULL)
1950f5b1c8a1SJohn Marino 		goto err;
1951f5b1c8a1SJohn Marino 	ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1952f5b1c8a1SJohn Marino  err:
1953f5b1c8a1SJohn Marino 	BIO_free(bio);
1954f5b1c8a1SJohn Marino 	return (ret);
1955f5b1c8a1SJohn Marino }
1956f5b1c8a1SJohn Marino #endif
1957f5b1c8a1SJohn Marino 
1958f5b1c8a1SJohn Marino static int
www_body(int s,unsigned char * context)1959*de0e0e4dSAntonio Huete Jimenez www_body(int s, unsigned char *context)
1960f5b1c8a1SJohn Marino {
1961f5b1c8a1SJohn Marino 	char *buf = NULL;
1962f5b1c8a1SJohn Marino 	int ret = 1;
1963f5b1c8a1SJohn Marino 	int i, j, k, dot;
1964f5b1c8a1SJohn Marino 	SSL *con;
1965f5b1c8a1SJohn Marino 	const SSL_CIPHER *c;
1966f5b1c8a1SJohn Marino 	BIO *io, *ssl_bio, *sbio;
1967f5b1c8a1SJohn Marino 
1968f5b1c8a1SJohn Marino 	buf = malloc(bufsize);
1969f5b1c8a1SJohn Marino 	if (buf == NULL)
1970f5b1c8a1SJohn Marino 		return (0);
1971f5b1c8a1SJohn Marino 	io = BIO_new(BIO_f_buffer());
1972f5b1c8a1SJohn Marino 	ssl_bio = BIO_new(BIO_f_ssl());
1973f5b1c8a1SJohn Marino 	if ((io == NULL) || (ssl_bio == NULL))
1974f5b1c8a1SJohn Marino 		goto err;
1975f5b1c8a1SJohn Marino 
19768edacedfSDaniel Fojt 	if (s_server_config.nbio) {
19778edacedfSDaniel Fojt 		if (!s_server_config.quiet)
1978f5b1c8a1SJohn Marino 			BIO_printf(bio_err, "turning on non blocking io\n");
1979f5b1c8a1SJohn Marino 		if (!BIO_socket_nbio(s, 1))
1980f5b1c8a1SJohn Marino 			ERR_print_errors(bio_err);
1981f5b1c8a1SJohn Marino 	}
1982f5b1c8a1SJohn Marino 
1983f5b1c8a1SJohn Marino 	/* lets make the output buffer a reasonable size */
1984f5b1c8a1SJohn Marino 	if (!BIO_set_write_buffer_size(io, bufsize))
1985f5b1c8a1SJohn Marino 		goto err;
1986f5b1c8a1SJohn Marino 
1987f5b1c8a1SJohn Marino 	if ((con = SSL_new(ctx)) == NULL)
1988f5b1c8a1SJohn Marino 		goto err;
19898edacedfSDaniel Fojt 	if (s_server_config.tlsextdebug) {
1990f5b1c8a1SJohn Marino 		SSL_set_tlsext_debug_callback(con, tlsext_cb);
1991f5b1c8a1SJohn Marino 		SSL_set_tlsext_debug_arg(con, bio_s_out);
1992f5b1c8a1SJohn Marino 	}
1993f5b1c8a1SJohn Marino 	if (context)
1994f5b1c8a1SJohn Marino 		SSL_set_session_id_context(con, context,
1995f5b1c8a1SJohn Marino 		    strlen((char *) context));
1996f5b1c8a1SJohn Marino 
1997f5b1c8a1SJohn Marino 	sbio = BIO_new_socket(s, BIO_NOCLOSE);
19988edacedfSDaniel Fojt 	if (s_server_config.nbio_test) {
1999f5b1c8a1SJohn Marino 		BIO *test;
2000f5b1c8a1SJohn Marino 
2001f5b1c8a1SJohn Marino 		test = BIO_new(BIO_f_nbio_test());
2002f5b1c8a1SJohn Marino 		sbio = BIO_push(test, sbio);
2003f5b1c8a1SJohn Marino 	}
2004f5b1c8a1SJohn Marino 	SSL_set_bio(con, sbio, sbio);
2005f5b1c8a1SJohn Marino 	SSL_set_accept_state(con);
2006f5b1c8a1SJohn Marino 
2007f5b1c8a1SJohn Marino 	/* SSL_set_fd(con,s); */
2008f5b1c8a1SJohn Marino 	BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
2009f5b1c8a1SJohn Marino 	BIO_push(io, ssl_bio);
2010f5b1c8a1SJohn Marino 
20118edacedfSDaniel Fojt 	if (s_server_config.debug) {
2012f5b1c8a1SJohn Marino 		SSL_set_debug(con, 1);
2013f5b1c8a1SJohn Marino 		BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
2014f5b1c8a1SJohn Marino 		BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out);
2015f5b1c8a1SJohn Marino 	}
20168edacedfSDaniel Fojt 	if (s_server_config.msg) {
2017f5b1c8a1SJohn Marino 		SSL_set_msg_callback(con, msg_cb);
2018f5b1c8a1SJohn Marino 		SSL_set_msg_callback_arg(con, bio_s_out);
2019f5b1c8a1SJohn Marino 	}
2020f5b1c8a1SJohn Marino 	for (;;) {
2021f5b1c8a1SJohn Marino 		i = BIO_gets(io, buf, bufsize - 1);
2022f5b1c8a1SJohn Marino 		if (i < 0) {	/* error */
2023f5b1c8a1SJohn Marino 			if (!BIO_should_retry(io)) {
20248edacedfSDaniel Fojt 				if (!s_server_config.quiet)
2025f5b1c8a1SJohn Marino 					ERR_print_errors(bio_err);
2026f5b1c8a1SJohn Marino 				goto err;
2027f5b1c8a1SJohn Marino 			} else {
20288edacedfSDaniel Fojt 				if (s_server_config.debug)  {
2029f5b1c8a1SJohn Marino 					BIO_printf(bio_s_out, "read R BLOCK\n");
2030f5b1c8a1SJohn Marino 					sleep(1);
20318edacedfSDaniel Fojt 				}
2032f5b1c8a1SJohn Marino 				continue;
2033f5b1c8a1SJohn Marino 			}
2034f5b1c8a1SJohn Marino 		} else if (i == 0) {	/* end of input */
2035f5b1c8a1SJohn Marino 			ret = 1;
2036f5b1c8a1SJohn Marino 			goto end;
2037f5b1c8a1SJohn Marino 		}
2038f5b1c8a1SJohn Marino 		/* else we have data */
20398edacedfSDaniel Fojt 		if (((s_server_config.www == 1) &&
20408edacedfSDaniel Fojt 		    (strncmp("GET ", buf, 4) == 0)) ||
20418edacedfSDaniel Fojt 		    ((s_server_config.www == 2) &&
20428edacedfSDaniel Fojt 		    (strncmp("GET /stats ", buf, 11) == 0))) {
2043f5b1c8a1SJohn Marino 			char *p;
2044f5b1c8a1SJohn Marino 			X509 *peer;
2045f5b1c8a1SJohn Marino 			STACK_OF(SSL_CIPHER) *sk;
2046f5b1c8a1SJohn Marino 			static const char *space = "                          ";
2047f5b1c8a1SJohn Marino 
2048f5b1c8a1SJohn Marino 			BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
2049f5b1c8a1SJohn Marino 			BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
2050f5b1c8a1SJohn Marino 			BIO_puts(io, "<pre>\n");
2051f5b1c8a1SJohn Marino /*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
2052f5b1c8a1SJohn Marino 			BIO_puts(io, "\n");
2053f5b1c8a1SJohn Marino 			for (i = 0; i < local_argc; i++) {
2054f5b1c8a1SJohn Marino 				BIO_puts(io, local_argv[i]);
2055f5b1c8a1SJohn Marino 				BIO_write(io, " ", 1);
2056f5b1c8a1SJohn Marino 			}
2057f5b1c8a1SJohn Marino 			BIO_puts(io, "\n");
2058f5b1c8a1SJohn Marino 
2059f5b1c8a1SJohn Marino 			BIO_printf(io,
2060f5b1c8a1SJohn Marino 			    "Secure Renegotiation IS%s supported\n",
2061f5b1c8a1SJohn Marino 			    SSL_get_secure_renegotiation_support(con) ?
2062f5b1c8a1SJohn Marino 			    "" : " NOT");
2063f5b1c8a1SJohn Marino 
2064f5b1c8a1SJohn Marino 			/*
2065f5b1c8a1SJohn Marino 			 * The following is evil and should not really be
2066f5b1c8a1SJohn Marino 			 * done
2067f5b1c8a1SJohn Marino 			 */
20688edacedfSDaniel Fojt 			BIO_printf(io,
20698edacedfSDaniel Fojt 			    "Ciphers supported in s_server binary\n");
2070f5b1c8a1SJohn Marino 			sk = SSL_get_ciphers(con);
2071f5b1c8a1SJohn Marino 			j = sk_SSL_CIPHER_num(sk);
2072f5b1c8a1SJohn Marino 			for (i = 0; i < j; i++) {
2073f5b1c8a1SJohn Marino 				c = sk_SSL_CIPHER_value(sk, i);
2074f5b1c8a1SJohn Marino 				BIO_printf(io, "%-11s:%-25s",
2075f5b1c8a1SJohn Marino 				    SSL_CIPHER_get_version(c),
2076f5b1c8a1SJohn Marino 				    SSL_CIPHER_get_name(c));
2077f5b1c8a1SJohn Marino 				if ((((i + 1) % 2) == 0) && (i + 1 != j))
2078f5b1c8a1SJohn Marino 					BIO_puts(io, "\n");
2079f5b1c8a1SJohn Marino 			}
2080f5b1c8a1SJohn Marino 			BIO_puts(io, "\n");
2081f5b1c8a1SJohn Marino 			p = SSL_get_shared_ciphers(con, buf, bufsize);
2082f5b1c8a1SJohn Marino 			if (p != NULL) {
20838edacedfSDaniel Fojt 				BIO_printf(io,
20848edacedfSDaniel Fojt 				    "---\nCiphers common between both SSL end points:\n");
2085f5b1c8a1SJohn Marino 				j = i = 0;
2086f5b1c8a1SJohn Marino 				while (*p) {
2087f5b1c8a1SJohn Marino 					if (*p == ':') {
2088f5b1c8a1SJohn Marino 						BIO_write(io, space, 26 - j);
2089f5b1c8a1SJohn Marino 						i++;
2090f5b1c8a1SJohn Marino 						j = 0;
20918edacedfSDaniel Fojt 						BIO_write(io,
20928edacedfSDaniel Fojt 						    ((i % 3) ?  " " : "\n"), 1);
2093f5b1c8a1SJohn Marino 					} else {
2094f5b1c8a1SJohn Marino 						BIO_write(io, p, 1);
2095f5b1c8a1SJohn Marino 						j++;
2096f5b1c8a1SJohn Marino 					}
2097f5b1c8a1SJohn Marino 					p++;
2098f5b1c8a1SJohn Marino 				}
2099f5b1c8a1SJohn Marino 				BIO_puts(io, "\n");
2100f5b1c8a1SJohn Marino 			}
2101f5b1c8a1SJohn Marino 			BIO_printf(io, (SSL_cache_hit(con)
2102f5b1c8a1SJohn Marino 				? "---\nReused, "
2103f5b1c8a1SJohn Marino 				: "---\nNew, "));
2104f5b1c8a1SJohn Marino 			c = SSL_get_current_cipher(con);
2105f5b1c8a1SJohn Marino 			BIO_printf(io, "%s, Cipher is %s\n",
2106f5b1c8a1SJohn Marino 			    SSL_CIPHER_get_version(c),
2107f5b1c8a1SJohn Marino 			    SSL_CIPHER_get_name(c));
2108f5b1c8a1SJohn Marino 			SSL_SESSION_print(io, SSL_get_session(con));
2109f5b1c8a1SJohn Marino 			BIO_printf(io, "---\n");
2110f5b1c8a1SJohn Marino 			print_stats(io, SSL_get_SSL_CTX(con));
2111f5b1c8a1SJohn Marino 			BIO_printf(io, "---\n");
2112f5b1c8a1SJohn Marino 			peer = SSL_get_peer_certificate(con);
2113f5b1c8a1SJohn Marino 			if (peer != NULL) {
2114f5b1c8a1SJohn Marino 				BIO_printf(io, "Client certificate\n");
2115f5b1c8a1SJohn Marino 				X509_print(io, peer);
2116f5b1c8a1SJohn Marino 				PEM_write_bio_X509(io, peer);
2117f5b1c8a1SJohn Marino 			} else
21188edacedfSDaniel Fojt 				BIO_puts(io,
21198edacedfSDaniel Fojt 				    "no client certificate available\n");
2120f5b1c8a1SJohn Marino 			BIO_puts(io, "</BODY></HTML>\r\n\r\n");
2121f5b1c8a1SJohn Marino 			break;
21228edacedfSDaniel Fojt 		} else if ((s_server_config.www == 2 ||
21238edacedfSDaniel Fojt 		    s_server_config.www == 3) &&
21248edacedfSDaniel Fojt 		    (strncmp("GET /", buf, 5) == 0)) {
2125f5b1c8a1SJohn Marino 			BIO *file;
2126f5b1c8a1SJohn Marino 			char *p, *e;
2127f5b1c8a1SJohn Marino 			static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
2128f5b1c8a1SJohn Marino 
2129f5b1c8a1SJohn Marino 			/* skip the '/' */
2130f5b1c8a1SJohn Marino 			p = &(buf[5]);
2131f5b1c8a1SJohn Marino 
2132f5b1c8a1SJohn Marino 			dot = 1;
2133f5b1c8a1SJohn Marino 			for (e = p; *e != '\0'; e++) {
2134f5b1c8a1SJohn Marino 				if (e[0] == ' ')
2135f5b1c8a1SJohn Marino 					break;
2136f5b1c8a1SJohn Marino 
2137f5b1c8a1SJohn Marino 				switch (dot) {
2138f5b1c8a1SJohn Marino 				case 1:
2139f5b1c8a1SJohn Marino 					dot = (e[0] == '.') ? 2 : 0;
2140f5b1c8a1SJohn Marino 					break;
2141f5b1c8a1SJohn Marino 				case 2:
2142f5b1c8a1SJohn Marino 					dot = (e[0] == '.') ? 3 : 0;
2143f5b1c8a1SJohn Marino 					break;
2144f5b1c8a1SJohn Marino 				case 3:
21458edacedfSDaniel Fojt 					dot = (e[0] == '/' || e[0] == '\\') ?
21468edacedfSDaniel Fojt 					    -1 : 0;
2147f5b1c8a1SJohn Marino 					break;
2148f5b1c8a1SJohn Marino 				}
2149f5b1c8a1SJohn Marino 				if (dot == 0)
21508edacedfSDaniel Fojt 					dot = (e[0] == '/' || e[0] == '\\') ?
21518edacedfSDaniel Fojt 					    1 : 0;
2152f5b1c8a1SJohn Marino 			}
2153f5b1c8a1SJohn Marino 			dot = (dot == 3) || (dot == -1);  /* filename contains
2154f5b1c8a1SJohn Marino 							   * ".." component */
2155f5b1c8a1SJohn Marino 
2156f5b1c8a1SJohn Marino 			if (*e == '\0') {
2157f5b1c8a1SJohn Marino 				BIO_puts(io, text);
21588edacedfSDaniel Fojt 				BIO_printf(io,
21598edacedfSDaniel Fojt 				    "'%s' is an invalid file name\r\n", p);
2160f5b1c8a1SJohn Marino 				break;
2161f5b1c8a1SJohn Marino 			}
2162f5b1c8a1SJohn Marino 			*e = '\0';
2163f5b1c8a1SJohn Marino 
2164f5b1c8a1SJohn Marino 			if (dot) {
2165f5b1c8a1SJohn Marino 				BIO_puts(io, text);
21668edacedfSDaniel Fojt 				BIO_printf(io,
21678edacedfSDaniel Fojt 				    "'%s' contains '..' reference\r\n", p);
2168f5b1c8a1SJohn Marino 				break;
2169f5b1c8a1SJohn Marino 			}
2170f5b1c8a1SJohn Marino 			if (*p == '/') {
2171f5b1c8a1SJohn Marino 				BIO_puts(io, text);
21728edacedfSDaniel Fojt 				BIO_printf(io,
21738edacedfSDaniel Fojt 				    "'%s' is an invalid path\r\n", p);
2174f5b1c8a1SJohn Marino 				break;
2175f5b1c8a1SJohn Marino 			}
2176f5b1c8a1SJohn Marino 			/* if a directory, do the index thang */
2177f5b1c8a1SJohn Marino 			if (app_isdir(p) > 0) {
2178f5b1c8a1SJohn Marino 				BIO_puts(io, text);
2179f5b1c8a1SJohn Marino 				BIO_printf(io, "'%s' is a directory\r\n", p);
2180f5b1c8a1SJohn Marino 				break;
2181f5b1c8a1SJohn Marino 			}
2182f5b1c8a1SJohn Marino 			if ((file = BIO_new_file(p, "r")) == NULL) {
2183f5b1c8a1SJohn Marino 				BIO_puts(io, text);
2184f5b1c8a1SJohn Marino 				BIO_printf(io, "Error opening '%s'\r\n", p);
2185f5b1c8a1SJohn Marino 				ERR_print_errors(io);
2186f5b1c8a1SJohn Marino 				break;
2187f5b1c8a1SJohn Marino 			}
21888edacedfSDaniel Fojt 			if (!s_server_config.quiet)
2189f5b1c8a1SJohn Marino 				BIO_printf(bio_err, "FILE:%s\n", p);
2190f5b1c8a1SJohn Marino 
21918edacedfSDaniel Fojt 			if (s_server_config.www == 2) {
2192f5b1c8a1SJohn Marino 				i = strlen(p);
2193f5b1c8a1SJohn Marino 				if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
2194f5b1c8a1SJohn Marino 				    ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
2195f5b1c8a1SJohn Marino 				    ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
2196f5b1c8a1SJohn Marino 					BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
2197f5b1c8a1SJohn Marino 				else
2198f5b1c8a1SJohn Marino 					BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
2199f5b1c8a1SJohn Marino 			}
2200f5b1c8a1SJohn Marino 			/* send the file */
2201f5b1c8a1SJohn Marino 			for (;;) {
2202f5b1c8a1SJohn Marino 				i = BIO_read(file, buf, bufsize);
2203f5b1c8a1SJohn Marino 				if (i <= 0)
2204f5b1c8a1SJohn Marino 					break;
2205f5b1c8a1SJohn Marino 
2206f5b1c8a1SJohn Marino #ifdef RENEG
2207f5b1c8a1SJohn Marino 				total_bytes += i;
2208f5b1c8a1SJohn Marino 				fprintf(stderr, "%d\n", i);
2209f5b1c8a1SJohn Marino 				if (total_bytes > 3 * 1024) {
2210f5b1c8a1SJohn Marino 					total_bytes = 0;
2211f5b1c8a1SJohn Marino 					fprintf(stderr, "RENEGOTIATE\n");
2212f5b1c8a1SJohn Marino 					SSL_renegotiate(con);
2213f5b1c8a1SJohn Marino 				}
2214f5b1c8a1SJohn Marino #endif
2215f5b1c8a1SJohn Marino 
2216f5b1c8a1SJohn Marino 				for (j = 0; j < i;) {
2217f5b1c8a1SJohn Marino #ifdef RENEG
2218f5b1c8a1SJohn Marino 					{
2219f5b1c8a1SJohn Marino 						static count = 0;
2220f5b1c8a1SJohn Marino 						if (++count == 13) {
2221f5b1c8a1SJohn Marino 							SSL_renegotiate(con);
2222f5b1c8a1SJohn Marino 						}
2223f5b1c8a1SJohn Marino 					}
2224f5b1c8a1SJohn Marino #endif
2225f5b1c8a1SJohn Marino 					k = BIO_write(io, &(buf[j]), i - j);
2226f5b1c8a1SJohn Marino 					if (k <= 0) {
2227f5b1c8a1SJohn Marino 						if (!BIO_should_retry(io))
2228f5b1c8a1SJohn Marino 							goto write_error;
2229f5b1c8a1SJohn Marino 						else {
22308edacedfSDaniel Fojt 							BIO_printf(bio_s_out,
22318edacedfSDaniel Fojt 							    "rwrite W BLOCK\n");
2232f5b1c8a1SJohn Marino 						}
2233f5b1c8a1SJohn Marino 					} else {
2234f5b1c8a1SJohn Marino 						j += k;
2235f5b1c8a1SJohn Marino 					}
2236f5b1c8a1SJohn Marino 				}
2237f5b1c8a1SJohn Marino 			}
2238f5b1c8a1SJohn Marino 	write_error:
2239f5b1c8a1SJohn Marino 			BIO_free(file);
2240f5b1c8a1SJohn Marino 			break;
2241f5b1c8a1SJohn Marino 		}
2242f5b1c8a1SJohn Marino 	}
2243f5b1c8a1SJohn Marino 
2244f5b1c8a1SJohn Marino 	for (;;) {
2245f5b1c8a1SJohn Marino 		i = (int) BIO_flush(io);
2246f5b1c8a1SJohn Marino 		if (i <= 0) {
2247f5b1c8a1SJohn Marino 			if (!BIO_should_retry(io))
2248f5b1c8a1SJohn Marino 				break;
2249f5b1c8a1SJohn Marino 		} else
2250f5b1c8a1SJohn Marino 			break;
2251f5b1c8a1SJohn Marino 	}
2252f5b1c8a1SJohn Marino  end:
2253f5b1c8a1SJohn Marino 	/* make sure we re-use sessions */
2254f5b1c8a1SJohn Marino 	SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
2255f5b1c8a1SJohn Marino 
2256f5b1c8a1SJohn Marino  err:
2257f5b1c8a1SJohn Marino 
2258f5b1c8a1SJohn Marino 	if (ret >= 0)
2259f5b1c8a1SJohn Marino 		BIO_printf(bio_s_out, "ACCEPT\n");
2260f5b1c8a1SJohn Marino 
2261f5b1c8a1SJohn Marino 	free(buf);
2262f5b1c8a1SJohn Marino 	BIO_free_all(io);
2263f5b1c8a1SJohn Marino /*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/
2264f5b1c8a1SJohn Marino 	return (ret);
2265f5b1c8a1SJohn Marino }
2266f5b1c8a1SJohn Marino 
2267f5b1c8a1SJohn Marino #define MAX_SESSION_ID_ATTEMPTS 10
2268f5b1c8a1SJohn Marino static int
generate_session_id(const SSL * ssl,unsigned char * id,unsigned int * id_len)22698edacedfSDaniel Fojt generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len)
2270f5b1c8a1SJohn Marino {
2271f5b1c8a1SJohn Marino 	unsigned int count = 0;
2272f5b1c8a1SJohn Marino 	do {
2273f5b1c8a1SJohn Marino 		arc4random_buf(id, *id_len);
2274f5b1c8a1SJohn Marino 		/*
2275f5b1c8a1SJohn Marino 		 * Prefix the session_id with the required prefix. NB: If our
2276f5b1c8a1SJohn Marino 		 * prefix is too long, clip it - but there will be worse
2277f5b1c8a1SJohn Marino 		 * effects anyway, eg. the server could only possibly create
2278f5b1c8a1SJohn Marino 		 * 1 session ID (ie. the prefix!) so all future session
2279f5b1c8a1SJohn Marino 		 * negotiations will fail due to conflicts.
2280f5b1c8a1SJohn Marino 		 */
22818edacedfSDaniel Fojt 		memcpy(id, s_server_config.session_id_prefix,
22828edacedfSDaniel Fojt 		    (strlen(s_server_config.session_id_prefix) < *id_len) ?
22838edacedfSDaniel Fojt 		    strlen(s_server_config.session_id_prefix) : *id_len);
2284f5b1c8a1SJohn Marino 	}
2285f5b1c8a1SJohn Marino 	while (SSL_has_matching_session_id(ssl, id, *id_len) &&
2286f5b1c8a1SJohn Marino 	    (++count < MAX_SESSION_ID_ATTEMPTS));
2287f5b1c8a1SJohn Marino 	if (count >= MAX_SESSION_ID_ATTEMPTS)
2288f5b1c8a1SJohn Marino 		return 0;
2289f5b1c8a1SJohn Marino 	return 1;
2290f5b1c8a1SJohn Marino }
22918edacedfSDaniel Fojt 
22928edacedfSDaniel Fojt static int
ssl_servername_cb(SSL * s,int * ad,void * arg)22938edacedfSDaniel Fojt ssl_servername_cb(SSL *s, int *ad, void *arg)
22948edacedfSDaniel Fojt {
22958edacedfSDaniel Fojt 	tlsextctx *p = (tlsextctx *) arg;
22968edacedfSDaniel Fojt 	const char *servername = SSL_get_servername(s,
22978edacedfSDaniel Fojt 	    TLSEXT_NAMETYPE_host_name);
22988edacedfSDaniel Fojt 
22998edacedfSDaniel Fojt 	if (servername && p->biodebug)
23008edacedfSDaniel Fojt 		BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
23018edacedfSDaniel Fojt 		    servername);
23028edacedfSDaniel Fojt 
23038edacedfSDaniel Fojt 	if (!p->servername)
23048edacedfSDaniel Fojt 		return SSL_TLSEXT_ERR_NOACK;
23058edacedfSDaniel Fojt 
23068edacedfSDaniel Fojt 	if (servername) {
23078edacedfSDaniel Fojt 		if (strcmp(servername, p->servername))
23088edacedfSDaniel Fojt 			return p->extension_error;
23098edacedfSDaniel Fojt 		if (ctx2) {
23108edacedfSDaniel Fojt 			BIO_printf(p->biodebug, "Switching server context.\n");
23118edacedfSDaniel Fojt 			SSL_set_SSL_CTX(s, ctx2);
23128edacedfSDaniel Fojt 		}
23138edacedfSDaniel Fojt 	}
23148edacedfSDaniel Fojt 	return SSL_TLSEXT_ERR_OK;
23158edacedfSDaniel Fojt }
23168edacedfSDaniel Fojt 
23178edacedfSDaniel Fojt /* Certificate Status callback. This is called when a client includes a
23188edacedfSDaniel Fojt  * certificate status request extension.
23198edacedfSDaniel Fojt  *
23208edacedfSDaniel Fojt  * This is a simplified version. It examines certificates each time and
23218edacedfSDaniel Fojt  * makes one OCSP responder query for each request.
23228edacedfSDaniel Fojt  *
23238edacedfSDaniel Fojt  * A full version would store details such as the OCSP certificate IDs and
23248edacedfSDaniel Fojt  * minimise the number of OCSP responses by caching them until they were
23258edacedfSDaniel Fojt  * considered "expired".
23268edacedfSDaniel Fojt  */
23278edacedfSDaniel Fojt 
23288edacedfSDaniel Fojt static int
cert_status_cb(SSL * s,void * arg)23298edacedfSDaniel Fojt cert_status_cb(SSL *s, void *arg)
23308edacedfSDaniel Fojt {
23318edacedfSDaniel Fojt 	tlsextstatusctx *srctx = arg;
23328edacedfSDaniel Fojt 	BIO *err = srctx->err;
23338edacedfSDaniel Fojt 	char *host = NULL, *port = NULL, *path = NULL;
23348edacedfSDaniel Fojt 	int use_ssl;
23358edacedfSDaniel Fojt 	unsigned char *rspder = NULL;
23368edacedfSDaniel Fojt 	int rspderlen;
23378edacedfSDaniel Fojt 	STACK_OF(OPENSSL_STRING) *aia = NULL;
23388edacedfSDaniel Fojt 	X509 *x = NULL;
2339*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX *inctx = NULL;
2340*de0e0e4dSAntonio Huete Jimenez 	X509_OBJECT *obj = NULL;
23418edacedfSDaniel Fojt 	OCSP_REQUEST *req = NULL;
23428edacedfSDaniel Fojt 	OCSP_RESPONSE *resp = NULL;
23438edacedfSDaniel Fojt 	OCSP_CERTID *id = NULL;
23448edacedfSDaniel Fojt 	STACK_OF(X509_EXTENSION) *exts;
23458edacedfSDaniel Fojt 	int ret = SSL_TLSEXT_ERR_NOACK;
23468edacedfSDaniel Fojt 	int i;
23478edacedfSDaniel Fojt 
23488edacedfSDaniel Fojt 	if (srctx->verbose)
23498edacedfSDaniel Fojt 		BIO_puts(err, "cert_status: callback called\n");
23508edacedfSDaniel Fojt 	/* Build up OCSP query from server certificate */
23518edacedfSDaniel Fojt 	x = SSL_get_certificate(s);
23528edacedfSDaniel Fojt 	aia = X509_get1_ocsp(x);
23538edacedfSDaniel Fojt 	if (aia) {
23548edacedfSDaniel Fojt 		if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
23558edacedfSDaniel Fojt 		    &host, &port, &path, &use_ssl)) {
23568edacedfSDaniel Fojt 			BIO_puts(err, "cert_status: can't parse AIA URL\n");
23578edacedfSDaniel Fojt 			goto err;
23588edacedfSDaniel Fojt 		}
23598edacedfSDaniel Fojt 		if (srctx->verbose)
23608edacedfSDaniel Fojt 			BIO_printf(err, "cert_status: AIA URL: %s\n",
23618edacedfSDaniel Fojt 			    sk_OPENSSL_STRING_value(aia, 0));
23628edacedfSDaniel Fojt 	} else {
23638edacedfSDaniel Fojt 		if (!srctx->host) {
23648edacedfSDaniel Fojt 			BIO_puts(srctx->err,
23658edacedfSDaniel Fojt 			    "cert_status: no AIA and no default responder URL\n");
23668edacedfSDaniel Fojt 			goto done;
23678edacedfSDaniel Fojt 		}
23688edacedfSDaniel Fojt 		host = srctx->host;
23698edacedfSDaniel Fojt 		path = srctx->path;
23708edacedfSDaniel Fojt 		port = srctx->port;
23718edacedfSDaniel Fojt 		use_ssl = srctx->use_ssl;
23728edacedfSDaniel Fojt 	}
23738edacedfSDaniel Fojt 
2374*de0e0e4dSAntonio Huete Jimenez 	if ((inctx = X509_STORE_CTX_new()) == NULL)
2375*de0e0e4dSAntonio Huete Jimenez 		goto err;
2376*de0e0e4dSAntonio Huete Jimenez 
2377*de0e0e4dSAntonio Huete Jimenez 	if (!X509_STORE_CTX_init(inctx,
23788edacedfSDaniel Fojt 	    SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
23798edacedfSDaniel Fojt 		NULL, NULL))
23808edacedfSDaniel Fojt 		goto err;
2381*de0e0e4dSAntonio Huete Jimenez 	if ((obj = X509_OBJECT_new()) == NULL)
2382*de0e0e4dSAntonio Huete Jimenez 		goto done;
2383*de0e0e4dSAntonio Huete Jimenez 	if (X509_STORE_get_by_subject(inctx, X509_LU_X509,
2384*de0e0e4dSAntonio Huete Jimenez 	    X509_get_issuer_name(x), obj) <= 0) {
23858edacedfSDaniel Fojt 		BIO_puts(err,
23868edacedfSDaniel Fojt 		    "cert_status: Can't retrieve issuer certificate.\n");
2387*de0e0e4dSAntonio Huete Jimenez 		X509_STORE_CTX_cleanup(inctx);
23888edacedfSDaniel Fojt 		goto done;
23898edacedfSDaniel Fojt 	}
23908edacedfSDaniel Fojt 	req = OCSP_REQUEST_new();
23918edacedfSDaniel Fojt 	if (!req)
23928edacedfSDaniel Fojt 		goto err;
2393*de0e0e4dSAntonio Huete Jimenez 	id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj));
2394*de0e0e4dSAntonio Huete Jimenez 	X509_OBJECT_free(obj);
2395*de0e0e4dSAntonio Huete Jimenez 	obj = NULL;
2396*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX_free(inctx);
2397*de0e0e4dSAntonio Huete Jimenez 	inctx = NULL;
23988edacedfSDaniel Fojt 	if (!id)
23998edacedfSDaniel Fojt 		goto err;
24008edacedfSDaniel Fojt 	if (!OCSP_request_add0_id(req, id))
24018edacedfSDaniel Fojt 		goto err;
24028edacedfSDaniel Fojt 	id = NULL;
24038edacedfSDaniel Fojt 	/* Add any extensions to the request */
24048edacedfSDaniel Fojt 	SSL_get_tlsext_status_exts(s, &exts);
24058edacedfSDaniel Fojt 	for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
24068edacedfSDaniel Fojt 		X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
24078edacedfSDaniel Fojt 		if (!OCSP_REQUEST_add_ext(req, ext, -1))
24088edacedfSDaniel Fojt 			goto err;
24098edacedfSDaniel Fojt 	}
24108edacedfSDaniel Fojt 	resp = process_responder(err, req, host, path, port, use_ssl, NULL,
24118edacedfSDaniel Fojt 	    srctx->timeout);
24128edacedfSDaniel Fojt 	if (!resp) {
24138edacedfSDaniel Fojt 		BIO_puts(err, "cert_status: error querying responder\n");
24148edacedfSDaniel Fojt 		goto done;
24158edacedfSDaniel Fojt 	}
24168edacedfSDaniel Fojt 	rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
24178edacedfSDaniel Fojt 	if (rspderlen <= 0)
24188edacedfSDaniel Fojt 		goto err;
24198edacedfSDaniel Fojt 	SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
24208edacedfSDaniel Fojt 	if (srctx->verbose) {
24218edacedfSDaniel Fojt 		BIO_puts(err, "cert_status: ocsp response sent:\n");
24228edacedfSDaniel Fojt 		OCSP_RESPONSE_print(err, resp, 2);
24238edacedfSDaniel Fojt 	}
24248edacedfSDaniel Fojt 	ret = SSL_TLSEXT_ERR_OK;
24258edacedfSDaniel Fojt  done:
2426*de0e0e4dSAntonio Huete Jimenez 	X509_STORE_CTX_free(inctx);
2427*de0e0e4dSAntonio Huete Jimenez 	X509_OBJECT_free(obj);
24288edacedfSDaniel Fojt 	if (ret != SSL_TLSEXT_ERR_OK)
24298edacedfSDaniel Fojt 		ERR_print_errors(err);
24308edacedfSDaniel Fojt 	if (aia) {
24318edacedfSDaniel Fojt 		free(host);
24328edacedfSDaniel Fojt 		free(path);
24338edacedfSDaniel Fojt 		free(port);
24348edacedfSDaniel Fojt 		X509_email_free(aia);
24358edacedfSDaniel Fojt 	}
24368edacedfSDaniel Fojt 	if (id)
24378edacedfSDaniel Fojt 		OCSP_CERTID_free(id);
24388edacedfSDaniel Fojt 	if (req)
24398edacedfSDaniel Fojt 		OCSP_REQUEST_free(req);
24408edacedfSDaniel Fojt 	if (resp)
24418edacedfSDaniel Fojt 		OCSP_RESPONSE_free(resp);
24428edacedfSDaniel Fojt 	return ret;
24438edacedfSDaniel Fojt  err:
24448edacedfSDaniel Fojt 	ret = SSL_TLSEXT_ERR_ALERT_FATAL;
24458edacedfSDaniel Fojt 	goto done;
24468edacedfSDaniel Fojt }
24478edacedfSDaniel Fojt 
24488edacedfSDaniel Fojt static int
alpn_cb(SSL * s,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)24498edacedfSDaniel Fojt alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
24508edacedfSDaniel Fojt     const unsigned char *in, unsigned int inlen, void *arg)
24518edacedfSDaniel Fojt {
24528edacedfSDaniel Fojt 	tlsextalpnctx *alpn_ctx = arg;
24538edacedfSDaniel Fojt 
24548edacedfSDaniel Fojt 	if (!s_server_config.quiet) {
24558edacedfSDaniel Fojt 		/* We can assume that in is syntactically valid. */
24568edacedfSDaniel Fojt 		unsigned i;
24578edacedfSDaniel Fojt 
24588edacedfSDaniel Fojt 		BIO_printf(bio_s_out,
24598edacedfSDaniel Fojt 		    "ALPN protocols advertised by the client: ");
24608edacedfSDaniel Fojt 		for (i = 0; i < inlen; ) {
24618edacedfSDaniel Fojt 			if (i)
24628edacedfSDaniel Fojt 				BIO_write(bio_s_out, ", ", 2);
24638edacedfSDaniel Fojt 			BIO_write(bio_s_out, &in[i + 1], in[i]);
24648edacedfSDaniel Fojt 			i += in[i] + 1;
24658edacedfSDaniel Fojt 		}
24668edacedfSDaniel Fojt 		BIO_write(bio_s_out, "\n", 1);
24678edacedfSDaniel Fojt 	}
24688edacedfSDaniel Fojt 
24698edacedfSDaniel Fojt 	if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data,
24708edacedfSDaniel Fojt 	    alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED)
24718edacedfSDaniel Fojt 		return (SSL_TLSEXT_ERR_NOACK);
24728edacedfSDaniel Fojt 
24738edacedfSDaniel Fojt 	if (!s_server_config.quiet) {
24748edacedfSDaniel Fojt 		BIO_printf(bio_s_out, "ALPN protocols selected: ");
24758edacedfSDaniel Fojt 		BIO_write(bio_s_out, *out, *outlen);
24768edacedfSDaniel Fojt 		BIO_write(bio_s_out, "\n", 1);
24778edacedfSDaniel Fojt 	}
24788edacedfSDaniel Fojt 
24798edacedfSDaniel Fojt 	return (SSL_TLSEXT_ERR_OK);
24808edacedfSDaniel Fojt }
2481