xref: /freebsd/crypto/openssl/apps/s_server.c (revision 7bded2db17780f5b59bc532689d8a9541f06901e)
174664626SKris Kennaway /* apps/s_server.c */
274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
374664626SKris Kennaway  * All rights reserved.
474664626SKris Kennaway  *
574664626SKris Kennaway  * This package is an SSL implementation written
674664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
774664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
874664626SKris Kennaway  *
974664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1074664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1174664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1274664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1374664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1474664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1574664626SKris Kennaway  *
1674664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1774664626SKris Kennaway  * the code are not to be removed.
1874664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
1974664626SKris Kennaway  * as the author of the parts of the library used.
2074664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2174664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2274664626SKris Kennaway  *
2374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2474664626SKris Kennaway  * modification, are permitted provided that the following conditions
2574664626SKris Kennaway  * are met:
2674664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2774664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
2874664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3074664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3174664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3274664626SKris Kennaway  *    must display the following acknowledgement:
3374664626SKris Kennaway  *    "This product includes cryptographic software written by
3474664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3574664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3674664626SKris Kennaway  *    being used are not cryptographic related :-).
3774664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
3874664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
3974664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4074664626SKris Kennaway  *
4174664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4274664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4374664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4474664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4574664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4674664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4774664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4874664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4974664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5074664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5174664626SKris Kennaway  * SUCH DAMAGE.
5274664626SKris Kennaway  *
5374664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5474664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5574664626SKris Kennaway  * copied and put under another distribution licence
5674664626SKris Kennaway  * [including the GNU Public Licence.]
5774664626SKris Kennaway  */
585c87c606SMark Murray /* ====================================================================
591f13597dSJung-uk Kim  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
605c87c606SMark Murray  *
615c87c606SMark Murray  * Redistribution and use in source and binary forms, with or without
625c87c606SMark Murray  * modification, are permitted provided that the following conditions
635c87c606SMark Murray  * are met:
645c87c606SMark Murray  *
655c87c606SMark Murray  * 1. Redistributions of source code must retain the above copyright
665c87c606SMark Murray  *    notice, this list of conditions and the following disclaimer.
675c87c606SMark Murray  *
685c87c606SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
695c87c606SMark Murray  *    notice, this list of conditions and the following disclaimer in
705c87c606SMark Murray  *    the documentation and/or other materials provided with the
715c87c606SMark Murray  *    distribution.
725c87c606SMark Murray  *
735c87c606SMark Murray  * 3. All advertising materials mentioning features or use of this
745c87c606SMark Murray  *    software must display the following acknowledgment:
755c87c606SMark Murray  *    "This product includes software developed by the OpenSSL Project
765c87c606SMark Murray  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
775c87c606SMark Murray  *
785c87c606SMark Murray  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
795c87c606SMark Murray  *    endorse or promote products derived from this software without
805c87c606SMark Murray  *    prior written permission. For written permission, please contact
815c87c606SMark Murray  *    openssl-core@openssl.org.
825c87c606SMark Murray  *
835c87c606SMark Murray  * 5. Products derived from this software may not be called "OpenSSL"
845c87c606SMark Murray  *    nor may "OpenSSL" appear in their names without prior written
855c87c606SMark Murray  *    permission of the OpenSSL Project.
865c87c606SMark Murray  *
875c87c606SMark Murray  * 6. Redistributions of any form whatsoever must retain the following
885c87c606SMark Murray  *    acknowledgment:
895c87c606SMark Murray  *    "This product includes software developed by the OpenSSL Project
905c87c606SMark Murray  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
915c87c606SMark Murray  *
925c87c606SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
935c87c606SMark Murray  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
945c87c606SMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
955c87c606SMark Murray  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
965c87c606SMark Murray  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
975c87c606SMark Murray  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
985c87c606SMark Murray  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
995c87c606SMark Murray  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1005c87c606SMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1015c87c606SMark Murray  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1025c87c606SMark Murray  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1035c87c606SMark Murray  * OF THE POSSIBILITY OF SUCH DAMAGE.
1045c87c606SMark Murray  * ====================================================================
1055c87c606SMark Murray  *
1065c87c606SMark Murray  * This product includes cryptographic software written by Eric Young
1075c87c606SMark Murray  * (eay@cryptsoft.com).  This product includes software written by Tim
1085c87c606SMark Murray  * Hudson (tjh@cryptsoft.com).
1095c87c606SMark Murray  *
1105c87c606SMark Murray  */
1113b4e3dcbSSimon L. B. Nielsen /* ====================================================================
1123b4e3dcbSSimon L. B. Nielsen  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1133b4e3dcbSSimon L. B. Nielsen  * ECC cipher suite support in OpenSSL originally developed by
1143b4e3dcbSSimon L. B. Nielsen  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1153b4e3dcbSSimon L. B. Nielsen  */
1161f13597dSJung-uk Kim /* ====================================================================
1171f13597dSJung-uk Kim  * Copyright 2005 Nokia. All rights reserved.
1181f13597dSJung-uk Kim  *
1191f13597dSJung-uk Kim  * The portions of the attached software ("Contribution") is developed by
1201f13597dSJung-uk Kim  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
1211f13597dSJung-uk Kim  * license.
1221f13597dSJung-uk Kim  *
1231f13597dSJung-uk Kim  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
1241f13597dSJung-uk Kim  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
1251f13597dSJung-uk Kim  * support (see RFC 4279) to OpenSSL.
1261f13597dSJung-uk Kim  *
1271f13597dSJung-uk Kim  * No patent licenses or other rights except those expressly stated in
1281f13597dSJung-uk Kim  * the OpenSSL open source license shall be deemed granted or received
1291f13597dSJung-uk Kim  * expressly, by implication, estoppel, or otherwise.
1301f13597dSJung-uk Kim  *
1311f13597dSJung-uk Kim  * No assurances are provided by Nokia that the Contribution does not
1321f13597dSJung-uk Kim  * infringe the patent or other intellectual property rights of any third
1331f13597dSJung-uk Kim  * party or that the license provides you with all the necessary rights
1341f13597dSJung-uk Kim  * to make use of the Contribution.
1351f13597dSJung-uk Kim  *
1361f13597dSJung-uk Kim  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
1371f13597dSJung-uk Kim  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
1381f13597dSJung-uk Kim  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
1391f13597dSJung-uk Kim  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
1401f13597dSJung-uk Kim  * OTHERWISE.
1411f13597dSJung-uk Kim  */
1423b4e3dcbSSimon L. B. Nielsen 
1436f9291ceSJung-uk Kim /*
1446f9291ceSJung-uk Kim  * Until the key-gen callbacks are modified to use newer prototypes, we allow
1456f9291ceSJung-uk Kim  * deprecated functions for openssl-internal code
1466f9291ceSJung-uk Kim  */
1473b4e3dcbSSimon L. B. Nielsen #ifdef OPENSSL_NO_DEPRECATED
1483b4e3dcbSSimon L. B. Nielsen # undef OPENSSL_NO_DEPRECATED
1493b4e3dcbSSimon L. B. Nielsen #endif
15074664626SKris Kennaway 
15174664626SKris Kennaway #include <assert.h>
1521f13597dSJung-uk Kim #include <ctype.h>
15374664626SKris Kennaway #include <stdio.h>
15474664626SKris Kennaway #include <stdlib.h>
15574664626SKris Kennaway #include <string.h>
1563b4e3dcbSSimon L. B. Nielsen 
1575c87c606SMark Murray #include <openssl/e_os2.h>
1585c87c606SMark Murray #ifdef OPENSSL_NO_STDIO
15974664626SKris Kennaway # define APPS_WIN16
16074664626SKris Kennaway #endif
16174664626SKris Kennaway 
1626f9291ceSJung-uk Kim /* conflicts with winsock2 stuff on netware */
1636f9291ceSJung-uk Kim #if !defined(OPENSSL_SYS_NETWARE)
1643b4e3dcbSSimon L. B. Nielsen # include <sys/types.h>
1653b4e3dcbSSimon L. B. Nielsen #endif
1663b4e3dcbSSimon L. B. Nielsen 
1676f9291ceSJung-uk Kim /*
1686f9291ceSJung-uk Kim  * With IPv6, it looks like Digital has mixed up the proper order of
1696f9291ceSJung-uk Kim  * recursive header file inclusion, resulting in the compiler complaining
1706f9291ceSJung-uk Kim  * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
1716f9291ceSJung-uk Kim  * needed to have fileno() declared correctly...  So let's define u_int
1726f9291ceSJung-uk Kim  */
1735c87c606SMark Murray #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
17474664626SKris Kennaway # define __U_INT
17574664626SKris Kennaway typedef unsigned int u_int;
17674664626SKris Kennaway #endif
17774664626SKris Kennaway 
17874664626SKris Kennaway #include <openssl/lhash.h>
17974664626SKris Kennaway #include <openssl/bn.h>
18074664626SKris Kennaway #define USE_SOCKETS
18174664626SKris Kennaway #include "apps.h"
18274664626SKris Kennaway #include <openssl/err.h>
18374664626SKris Kennaway #include <openssl/pem.h>
18474664626SKris Kennaway #include <openssl/x509.h>
18574664626SKris Kennaway #include <openssl/ssl.h>
1865740a5e3SKris Kennaway #include <openssl/rand.h>
187db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h>
1883b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DH
1893b4e3dcbSSimon L. B. Nielsen # include <openssl/dh.h>
1903b4e3dcbSSimon L. B. Nielsen #endif
1913b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_RSA
1923b4e3dcbSSimon L. B. Nielsen # include <openssl/rsa.h>
1933b4e3dcbSSimon L. B. Nielsen #endif
1941f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
1951f13597dSJung-uk Kim # include <openssl/srp.h>
1961f13597dSJung-uk Kim #endif
19774664626SKris Kennaway #include "s_apps.h"
1983b4e3dcbSSimon L. B. Nielsen #include "timeouts.h"
19974664626SKris Kennaway 
2005c87c606SMark Murray #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
20174664626SKris Kennaway /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
20274664626SKris Kennaway # undef FIONBIO
20374664626SKris Kennaway #endif
20474664626SKris Kennaway 
2051f13597dSJung-uk Kim #if defined(OPENSSL_SYS_BEOS_R5)
2061f13597dSJung-uk Kim # include <fcntl.h>
2071f13597dSJung-uk Kim #endif
2081f13597dSJung-uk Kim 
2095c87c606SMark Murray #ifndef OPENSSL_NO_RSA
21074664626SKris Kennaway static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
21174664626SKris Kennaway #endif
212*7bded2dbSJung-uk Kim static int sv_body(char *hostname, int s, int stype, unsigned char *context);
213*7bded2dbSJung-uk Kim static int www_body(char *hostname, int s, int stype, unsigned char *context);
214*7bded2dbSJung-uk Kim static int rev_body(char *hostname, int s, int stype, unsigned char *context);
21574664626SKris Kennaway static void close_accept_socket(void);
21674664626SKris Kennaway static void sv_usage(void);
21774664626SKris Kennaway static int init_ssl_connection(SSL *s);
21874664626SKris Kennaway static void print_stats(BIO *bp, SSL_CTX *ctx);
2195c87c606SMark Murray static int generate_session_id(const SSL *ssl, unsigned char *id,
2205c87c606SMark Murray                                unsigned int *id_len);
221*7bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx);
222*7bded2dbSJung-uk Kim static void free_sessions(void);
2235c87c606SMark Murray #ifndef OPENSSL_NO_DH
2243b4e3dcbSSimon L. B. Nielsen static DH *load_dh_param(const char *dhfile);
225ed6b93beSJung-uk Kim static DH *get_dh2048(void);
22674664626SKris Kennaway #endif
2273b4e3dcbSSimon L. B. Nielsen 
228f579bf8eSKris Kennaway #ifdef MONOLITH
229f579bf8eSKris Kennaway static void s_server_init(void);
230f579bf8eSKris Kennaway #endif
23174664626SKris Kennaway 
2325c87c606SMark Murray #ifndef OPENSSL_NO_DH
233ed6b93beSJung-uk Kim static unsigned char dh2048_p[] = {
234ed6b93beSJung-uk Kim     0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
235ed6b93beSJung-uk Kim     0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
236ed6b93beSJung-uk Kim     0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
237ed6b93beSJung-uk Kim     0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
238ed6b93beSJung-uk Kim     0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
239ed6b93beSJung-uk Kim     0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
240ed6b93beSJung-uk Kim     0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
241ed6b93beSJung-uk Kim     0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
242ed6b93beSJung-uk Kim     0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
243ed6b93beSJung-uk Kim     0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
244ed6b93beSJung-uk Kim     0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
245ed6b93beSJung-uk Kim     0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
246ed6b93beSJung-uk Kim     0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
247ed6b93beSJung-uk Kim     0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
248ed6b93beSJung-uk Kim     0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
249ed6b93beSJung-uk Kim     0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
250ed6b93beSJung-uk Kim     0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
251ed6b93beSJung-uk Kim     0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
252ed6b93beSJung-uk Kim     0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
253ed6b93beSJung-uk Kim     0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
254ed6b93beSJung-uk Kim     0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
255ed6b93beSJung-uk Kim     0xE9,0x32,0x0B,0x3B,
25674664626SKris Kennaway };
2576f9291ceSJung-uk Kim 
258ed6b93beSJung-uk Kim static unsigned char dh2048_g[] = {
25974664626SKris Kennaway     0x02,
26074664626SKris Kennaway };
26174664626SKris Kennaway 
262ed6b93beSJung-uk Kim DH *get_dh2048()
26374664626SKris Kennaway {
264ed6b93beSJung-uk Kim     DH *dh;
26574664626SKris Kennaway 
2666f9291ceSJung-uk Kim     if ((dh = DH_new()) == NULL)
267ed6b93beSJung-uk Kim         return NULL;
268ed6b93beSJung-uk Kim     dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
269ed6b93beSJung-uk Kim     dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
270ed6b93beSJung-uk Kim     if (dh->p == NULL || dh->g == NULL) {
271ed6b93beSJung-uk Kim         DH_free(dh);
272ed6b93beSJung-uk Kim         return NULL;
273ed6b93beSJung-uk Kim     }
274ed6b93beSJung-uk Kim     return dh;
27574664626SKris Kennaway }
27674664626SKris Kennaway #endif
27774664626SKris Kennaway 
27874664626SKris Kennaway /* static int load_CA(SSL_CTX *ctx, char *file);*/
27974664626SKris Kennaway 
28074664626SKris Kennaway #undef BUFSIZZ
28174664626SKris Kennaway #define BUFSIZZ 16*1024
282f579bf8eSKris Kennaway static int bufsize = BUFSIZZ;
28374664626SKris Kennaway static int accept_socket = -1;
28474664626SKris Kennaway 
28574664626SKris Kennaway #define TEST_CERT       "server.pem"
286db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
287db522d3aSSimon L. B. Nielsen # define TEST_CERT2      "server2.pem"
288db522d3aSSimon L. B. Nielsen #endif
28974664626SKris Kennaway #undef PROG
29074664626SKris Kennaway #define PROG            s_server_main
29174664626SKris Kennaway 
292*7bded2dbSJung-uk Kim extern int verify_depth, verify_return_error, verify_quiet;
29374664626SKris Kennaway 
29474664626SKris Kennaway static int s_server_verify = SSL_VERIFY_NONE;
29574664626SKris Kennaway static int s_server_session_id_context = 1; /* anything will do */
296*7bded2dbSJung-uk Kim static const char *s_cert_file = TEST_CERT, *s_key_file =
297*7bded2dbSJung-uk Kim     NULL, *s_chain_file = NULL;
298db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
299db522d3aSSimon L. B. Nielsen static const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL;
300db522d3aSSimon L. B. Nielsen #endif
301*7bded2dbSJung-uk Kim static char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL;
30274664626SKris Kennaway #ifdef FIONBIO
30374664626SKris Kennaway static int s_nbio = 0;
30474664626SKris Kennaway #endif
30574664626SKris Kennaway static int s_nbio_test = 0;
30674664626SKris Kennaway int s_crlf = 0;
30774664626SKris Kennaway static SSL_CTX *ctx = NULL;
308db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
309db522d3aSSimon L. B. Nielsen static SSL_CTX *ctx2 = NULL;
310db522d3aSSimon L. B. Nielsen #endif
31174664626SKris Kennaway static int www = 0;
31274664626SKris Kennaway 
31374664626SKris Kennaway static BIO *bio_s_out = NULL;
314*7bded2dbSJung-uk Kim static BIO *bio_s_msg = NULL;
31574664626SKris Kennaway static int s_debug = 0;
316db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
317db522d3aSSimon L. B. Nielsen static int s_tlsextdebug = 0;
318db522d3aSSimon L. B. Nielsen static int s_tlsextstatus = 0;
319db522d3aSSimon L. B. Nielsen static int cert_status_cb(SSL *s, void *arg);
320db522d3aSSimon L. B. Nielsen #endif
321*7bded2dbSJung-uk Kim static int no_resume_ephemeral = 0;
3225c87c606SMark Murray static int s_msg = 0;
32374664626SKris Kennaway static int s_quiet = 0;
324*7bded2dbSJung-uk Kim static int s_ign_eof = 0;
325*7bded2dbSJung-uk Kim static int s_brief = 0;
32674664626SKris Kennaway 
3271f13597dSJung-uk Kim static char *keymatexportlabel = NULL;
3281f13597dSJung-uk Kim static int keymatexportlen = 20;
3291f13597dSJung-uk Kim 
330f579bf8eSKris Kennaway static int hack = 0;
331fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
3325c87c606SMark Murray static char *engine_id = NULL;
333fceca8a3SJacques Vidrine #endif
3345c87c606SMark Murray static const char *session_id_prefix = NULL;
335f579bf8eSKris Kennaway 
3363b4e3dcbSSimon L. B. Nielsen static int enable_timeouts = 0;
3376a599222SSimon L. B. Nielsen static long socket_mtu;
3386a599222SSimon L. B. Nielsen #ifndef OPENSSL_NO_DTLS1
3393b4e3dcbSSimon L. B. Nielsen static int cert_chain = 0;
3406a599222SSimon L. B. Nielsen #endif
3413b4e3dcbSSimon L. B. Nielsen 
342*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
343*7bded2dbSJung-uk Kim static BIO *serverinfo_in = NULL;
344*7bded2dbSJung-uk Kim static const char *s_serverinfo_file = NULL;
345*7bded2dbSJung-uk Kim 
346*7bded2dbSJung-uk Kim #endif
347*7bded2dbSJung-uk Kim 
3481f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK
3491f13597dSJung-uk Kim static char *psk_identity = "Client_identity";
3501f13597dSJung-uk Kim char *psk_key = NULL;           /* by default PSK is not used */
3511f13597dSJung-uk Kim 
3521f13597dSJung-uk Kim static unsigned int psk_server_cb(SSL *ssl, const char *identity,
3536f9291ceSJung-uk Kim                                   unsigned char *psk,
3546f9291ceSJung-uk Kim                                   unsigned int max_psk_len)
3551f13597dSJung-uk Kim {
3561f13597dSJung-uk Kim     unsigned int psk_len = 0;
3571f13597dSJung-uk Kim     int ret;
3581f13597dSJung-uk Kim     BIGNUM *bn = NULL;
3591f13597dSJung-uk Kim 
3601f13597dSJung-uk Kim     if (s_debug)
3611f13597dSJung-uk Kim         BIO_printf(bio_s_out, "psk_server_cb\n");
3626f9291ceSJung-uk Kim     if (!identity) {
3631f13597dSJung-uk Kim         BIO_printf(bio_err, "Error: client did not send PSK identity\n");
3641f13597dSJung-uk Kim         goto out_err;
3651f13597dSJung-uk Kim     }
3661f13597dSJung-uk Kim     if (s_debug)
3671f13597dSJung-uk Kim         BIO_printf(bio_s_out, "identity_len=%d identity=%s\n",
3686f9291ceSJung-uk Kim                    (int)strlen(identity), identity);
3691f13597dSJung-uk Kim 
3701f13597dSJung-uk Kim     /* here we could lookup the given identity e.g. from a database */
3716f9291ceSJung-uk Kim     if (strcmp(identity, psk_identity) != 0) {
3721f13597dSJung-uk Kim         BIO_printf(bio_s_out, "PSK error: client identity not found"
3736f9291ceSJung-uk Kim                    " (got '%s' expected '%s')\n", identity, psk_identity);
3741f13597dSJung-uk Kim         goto out_err;
3751f13597dSJung-uk Kim     }
3761f13597dSJung-uk Kim     if (s_debug)
3771f13597dSJung-uk Kim         BIO_printf(bio_s_out, "PSK client identity found\n");
3781f13597dSJung-uk Kim 
3791f13597dSJung-uk Kim     /* convert the PSK key to binary */
3801f13597dSJung-uk Kim     ret = BN_hex2bn(&bn, psk_key);
3816f9291ceSJung-uk Kim     if (!ret) {
3826f9291ceSJung-uk Kim         BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n",
3836f9291ceSJung-uk Kim                    psk_key);
3841f13597dSJung-uk Kim         if (bn)
3851f13597dSJung-uk Kim             BN_free(bn);
3861f13597dSJung-uk Kim         return 0;
3871f13597dSJung-uk Kim     }
3886f9291ceSJung-uk Kim     if (BN_num_bytes(bn) > (int)max_psk_len) {
3896f9291ceSJung-uk Kim         BIO_printf(bio_err,
3906f9291ceSJung-uk Kim                    "psk buffer of callback is too small (%d) for key (%d)\n",
3911f13597dSJung-uk Kim                    max_psk_len, BN_num_bytes(bn));
3921f13597dSJung-uk Kim         BN_free(bn);
3931f13597dSJung-uk Kim         return 0;
3941f13597dSJung-uk Kim     }
3951f13597dSJung-uk Kim 
3961f13597dSJung-uk Kim     ret = BN_bn2bin(bn, psk);
3971f13597dSJung-uk Kim     BN_free(bn);
3981f13597dSJung-uk Kim 
3991f13597dSJung-uk Kim     if (ret < 0)
4001f13597dSJung-uk Kim         goto out_err;
4011f13597dSJung-uk Kim     psk_len = (unsigned int)ret;
4021f13597dSJung-uk Kim 
4031f13597dSJung-uk Kim     if (s_debug)
4041f13597dSJung-uk Kim         BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
4051f13597dSJung-uk Kim     return psk_len;
4061f13597dSJung-uk Kim  out_err:
4071f13597dSJung-uk Kim     if (s_debug)
4081f13597dSJung-uk Kim         BIO_printf(bio_err, "Error in PSK server callback\n");
4091f13597dSJung-uk Kim     return 0;
4101f13597dSJung-uk Kim }
4111f13597dSJung-uk Kim #endif
4121f13597dSJung-uk Kim 
4131f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
4141f13597dSJung-uk Kim /* This is a context that we pass to callbacks */
4156f9291ceSJung-uk Kim typedef struct srpsrvparm_st {
4161f13597dSJung-uk Kim     char *login;
4171f13597dSJung-uk Kim     SRP_VBASE *vb;
4181f13597dSJung-uk Kim     SRP_user_pwd *user;
4191f13597dSJung-uk Kim } srpsrvparm;
4201f13597dSJung-uk Kim 
4216f9291ceSJung-uk Kim /*
4226f9291ceSJung-uk Kim  * This callback pretends to require some asynchronous logic in order to
4236f9291ceSJung-uk Kim  * obtain a verifier. When the callback is called for a new connection we
4246f9291ceSJung-uk Kim  * return with a negative value. This will provoke the accept etc to return
4256f9291ceSJung-uk Kim  * with an LOOKUP_X509. The main logic of the reinvokes the suspended call
4266f9291ceSJung-uk Kim  * (which would normally occur after a worker has finished) and we set the
4276f9291ceSJung-uk Kim  * user parameters.
4281f13597dSJung-uk Kim  */
4291f13597dSJung-uk Kim static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
4301f13597dSJung-uk Kim {
4311f13597dSJung-uk Kim     srpsrvparm *p = (srpsrvparm *) arg;
4326f9291ceSJung-uk Kim     if (p->login == NULL && p->user == NULL) {
4331f13597dSJung-uk Kim         p->login = SSL_get_srp_username(s);
4341f13597dSJung-uk Kim         BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
4351f13597dSJung-uk Kim         return (-1);
4361f13597dSJung-uk Kim     }
4371f13597dSJung-uk Kim 
4386f9291ceSJung-uk Kim     if (p->user == NULL) {
4391f13597dSJung-uk Kim         BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
4401f13597dSJung-uk Kim         return SSL3_AL_FATAL;
4411f13597dSJung-uk Kim     }
4426f9291ceSJung-uk Kim     if (SSL_set_srp_server_param
4436f9291ceSJung-uk Kim         (s, p->user->N, p->user->g, p->user->s, p->user->v,
4446f9291ceSJung-uk Kim          p->user->info) < 0) {
4451f13597dSJung-uk Kim         *ad = SSL_AD_INTERNAL_ERROR;
4461f13597dSJung-uk Kim         return SSL3_AL_FATAL;
4471f13597dSJung-uk Kim     }
4486f9291ceSJung-uk Kim     BIO_printf(bio_err,
4496f9291ceSJung-uk Kim                "SRP parameters set: username = \"%s\" info=\"%s\" \n",
4506f9291ceSJung-uk Kim                p->login, p->user->info);
4511f13597dSJung-uk Kim     /* need to check whether there are memory leaks */
4521f13597dSJung-uk Kim     p->user = NULL;
4531f13597dSJung-uk Kim     p->login = NULL;
4541f13597dSJung-uk Kim     return SSL_ERROR_NONE;
4551f13597dSJung-uk Kim }
4561f13597dSJung-uk Kim 
4571f13597dSJung-uk Kim #endif
4581f13597dSJung-uk Kim 
459f579bf8eSKris Kennaway #ifdef MONOLITH
46074664626SKris Kennaway static void s_server_init(void)
46174664626SKris Kennaway {
462f579bf8eSKris Kennaway     accept_socket = -1;
46374664626SKris Kennaway     s_server_verify = SSL_VERIFY_NONE;
46474664626SKris Kennaway     s_dcert_file = NULL;
46574664626SKris Kennaway     s_dkey_file = NULL;
466*7bded2dbSJung-uk Kim     s_dchain_file = NULL;
46774664626SKris Kennaway     s_cert_file = TEST_CERT;
46874664626SKris Kennaway     s_key_file = NULL;
469*7bded2dbSJung-uk Kim     s_chain_file = NULL;
470db522d3aSSimon L. B. Nielsen # ifndef OPENSSL_NO_TLSEXT
471db522d3aSSimon L. B. Nielsen     s_cert_file2 = TEST_CERT2;
472db522d3aSSimon L. B. Nielsen     s_key_file2 = NULL;
473db522d3aSSimon L. B. Nielsen     ctx2 = NULL;
474db522d3aSSimon L. B. Nielsen # endif
47574664626SKris Kennaway # ifdef FIONBIO
47674664626SKris Kennaway     s_nbio = 0;
47774664626SKris Kennaway # endif
47874664626SKris Kennaway     s_nbio_test = 0;
47974664626SKris Kennaway     ctx = NULL;
48074664626SKris Kennaway     www = 0;
48174664626SKris Kennaway 
48274664626SKris Kennaway     bio_s_out = NULL;
48374664626SKris Kennaway     s_debug = 0;
4845c87c606SMark Murray     s_msg = 0;
48574664626SKris Kennaway     s_quiet = 0;
486*7bded2dbSJung-uk Kim     s_brief = 0;
487f579bf8eSKris Kennaway     hack = 0;
488fceca8a3SJacques Vidrine # ifndef OPENSSL_NO_ENGINE
4895c87c606SMark Murray     engine_id = NULL;
490fceca8a3SJacques Vidrine # endif
49174664626SKris Kennaway }
49274664626SKris Kennaway #endif
49374664626SKris Kennaway 
49474664626SKris Kennaway static void sv_usage(void)
49574664626SKris Kennaway {
49674664626SKris Kennaway     BIO_printf(bio_err, "usage: s_server [args ...]\n");
49774664626SKris Kennaway     BIO_printf(bio_err, "\n");
4986f9291ceSJung-uk Kim     BIO_printf(bio_err,
4996f9291ceSJung-uk Kim                " -accept arg   - port to accept on (default is %d)\n", PORT);
500*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
501*7bded2dbSJung-uk Kim                " -verify_host host - check peer certificate matches \"host\"\n");
502*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
503*7bded2dbSJung-uk Kim                " -verify_email email - check peer certificate matches \"email\"\n");
504*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
505*7bded2dbSJung-uk Kim                " -verify_ip ipaddr - check peer certificate matches \"ipaddr\"\n");
50674664626SKris Kennaway     BIO_printf(bio_err, " -context arg  - set session ID context\n");
5076f9291ceSJung-uk Kim     BIO_printf(bio_err,
5086f9291ceSJung-uk Kim                " -verify arg   - turn on peer certificate verification\n");
5096f9291ceSJung-uk Kim     BIO_printf(bio_err,
5106f9291ceSJung-uk Kim                " -Verify arg   - turn on peer certificate verification, must have a cert.\n");
5116f9291ceSJung-uk Kim     BIO_printf(bio_err,
5126f9291ceSJung-uk Kim                " -verify_return_error - return verification errors\n");
5133b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio_err, " -cert arg     - certificate file to use\n");
51474664626SKris Kennaway     BIO_printf(bio_err, "                 (default is %s)\n", TEST_CERT);
515*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
516*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
517*7bded2dbSJung-uk Kim                " -serverinfo arg - PEM serverinfo file for certificate\n");
518*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
519*7bded2dbSJung-uk Kim                " -auth               - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
520*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
521*7bded2dbSJung-uk Kim                " -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
522*7bded2dbSJung-uk Kim #endif
523*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
524*7bded2dbSJung-uk Kim                " -no_resumption_on_reneg - set SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION flag\n");
5256f9291ceSJung-uk Kim     BIO_printf(bio_err,
5266f9291ceSJung-uk Kim                " -crl_check    - check the peer certificate has not been revoked by its CA.\n"
527db522d3aSSimon L. B. Nielsen                "                 The CRL(s) are appended to the certificate file\n");
5286f9291ceSJung-uk Kim     BIO_printf(bio_err,
5296f9291ceSJung-uk Kim                " -crl_check_all - check the peer certificate has not been revoked by its CA\n"
5306f9291ceSJung-uk Kim                "                 or any other CRL in the CA chain. CRL(s) are appened to the\n"
531db522d3aSSimon L. B. Nielsen                "                 the certificate file.\n");
5326f9291ceSJung-uk Kim     BIO_printf(bio_err,
5336f9291ceSJung-uk Kim                " -certform arg - certificate format (PEM or DER) PEM default\n");
5346f9291ceSJung-uk Kim     BIO_printf(bio_err,
5356f9291ceSJung-uk Kim                " -key arg      - Private Key file to use, in cert file if\n");
5366f9291ceSJung-uk Kim     BIO_printf(bio_err, "                 not specified (default is %s)\n",
5376f9291ceSJung-uk Kim                TEST_CERT);
5386f9291ceSJung-uk Kim     BIO_printf(bio_err,
5396f9291ceSJung-uk Kim                " -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
5406f9291ceSJung-uk Kim     BIO_printf(bio_err,
5416f9291ceSJung-uk Kim                " -pass arg     - private key file pass phrase source\n");
5426f9291ceSJung-uk Kim     BIO_printf(bio_err,
5436f9291ceSJung-uk Kim                " -dcert arg    - second certificate file to use (usually for DSA)\n");
5446f9291ceSJung-uk Kim     BIO_printf(bio_err,
5456f9291ceSJung-uk Kim                " -dcertform x  - second certificate format (PEM or DER) PEM default\n");
5466f9291ceSJung-uk Kim     BIO_printf(bio_err,
5476f9291ceSJung-uk Kim                " -dkey arg     - second private key file to use (usually for DSA)\n");
5486f9291ceSJung-uk Kim     BIO_printf(bio_err,
5496f9291ceSJung-uk Kim                " -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
5506f9291ceSJung-uk Kim     BIO_printf(bio_err,
5516f9291ceSJung-uk Kim                " -dpass arg    - second private key file pass phrase source\n");
5526f9291ceSJung-uk Kim     BIO_printf(bio_err,
5536f9291ceSJung-uk Kim                " -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
5546f9291ceSJung-uk Kim     BIO_printf(bio_err,
5556f9291ceSJung-uk Kim                "                 or a default set of parameters is used\n");
5563b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH
5576f9291ceSJung-uk Kim     BIO_printf(bio_err,
5586f9291ceSJung-uk Kim                " -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n"
5596f9291ceSJung-uk Kim                "                 Use \"openssl ecparam -list_curves\" for all names\n"
5601f13597dSJung-uk Kim                "                 (default is nistp256).\n");
5613b4e3dcbSSimon L. B. Nielsen #endif
56274664626SKris Kennaway #ifdef FIONBIO
56374664626SKris Kennaway     BIO_printf(bio_err, " -nbio         - Run with non-blocking IO\n");
56474664626SKris Kennaway #endif
5656f9291ceSJung-uk Kim     BIO_printf(bio_err,
5666f9291ceSJung-uk Kim                " -nbio_test    - test with the non-blocking test bio\n");
5676f9291ceSJung-uk Kim     BIO_printf(bio_err,
5686f9291ceSJung-uk Kim                " -crlf         - convert LF from terminal into CRLF\n");
56974664626SKris Kennaway     BIO_printf(bio_err, " -debug        - Print more output\n");
5705c87c606SMark Murray     BIO_printf(bio_err, " -msg          - Show protocol messages\n");
57174664626SKris Kennaway     BIO_printf(bio_err, " -state        - Print the SSL states\n");
57274664626SKris Kennaway     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
57374664626SKris Kennaway     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
5746f9291ceSJung-uk Kim     BIO_printf(bio_err,
575ed6b93beSJung-uk Kim                " -no_alt_chains - only ever use the first certificate chain found\n");
576ed6b93beSJung-uk Kim     BIO_printf(bio_err,
5776f9291ceSJung-uk Kim                " -nocert       - Don't use any certificates (Anon-DH)\n");
5786f9291ceSJung-uk Kim     BIO_printf(bio_err,
5796f9291ceSJung-uk Kim                " -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
5805c87c606SMark Murray     BIO_printf(bio_err, " -serverpref   - Use server's cipher preferences\n");
58174664626SKris Kennaway     BIO_printf(bio_err, " -quiet        - No server output\n");
58274664626SKris Kennaway     BIO_printf(bio_err, " -no_tmp_rsa   - Do not generate a tmp RSA key\n");
5831f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK
5841f13597dSJung-uk Kim     BIO_printf(bio_err, " -psk_hint arg - PSK identity hint to use\n");
5851f13597dSJung-uk Kim     BIO_printf(bio_err, " -psk arg      - PSK in hex (without 0x)\n");
5861f13597dSJung-uk Kim # ifndef OPENSSL_NO_JPAKE
5871f13597dSJung-uk Kim     BIO_printf(bio_err, " -jpake arg    - JPAKE secret to use\n");
5881f13597dSJung-uk Kim # endif
5891f13597dSJung-uk Kim #endif
5901f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
5911f13597dSJung-uk Kim     BIO_printf(bio_err, " -srpvfile file      - The verifier file for SRP\n");
5926f9291ceSJung-uk Kim     BIO_printf(bio_err,
5936f9291ceSJung-uk Kim                " -srpuserseed string - A seed string for a default user salt.\n");
5941f13597dSJung-uk Kim #endif
59574664626SKris Kennaway     BIO_printf(bio_err, " -ssl2         - Just talk SSLv2\n");
596751d2991SJung-uk Kim #ifndef OPENSSL_NO_SSL3_METHOD
59774664626SKris Kennaway     BIO_printf(bio_err, " -ssl3         - Just talk SSLv3\n");
598751d2991SJung-uk Kim #endif
5991f13597dSJung-uk Kim     BIO_printf(bio_err, " -tls1_2       - Just talk TLSv1.2\n");
6001f13597dSJung-uk Kim     BIO_printf(bio_err, " -tls1_1       - Just talk TLSv1.1\n");
60174664626SKris Kennaway     BIO_printf(bio_err, " -tls1         - Just talk TLSv1\n");
6023b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio_err, " -dtls1        - Just talk DTLSv1\n");
603*7bded2dbSJung-uk Kim     BIO_printf(bio_err, " -dtls1_2      - Just talk DTLSv1.2\n");
6043b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio_err, " -timeout      - Enable timeouts\n");
6056a599222SSimon L. B. Nielsen     BIO_printf(bio_err, " -mtu          - Set link layer MTU\n");
6063b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio_err, " -chain        - Read a certificate chain\n");
60774664626SKris Kennaway     BIO_printf(bio_err, " -no_ssl2      - Just disable SSLv2\n");
60874664626SKris Kennaway     BIO_printf(bio_err, " -no_ssl3      - Just disable SSLv3\n");
60974664626SKris Kennaway     BIO_printf(bio_err, " -no_tls1      - Just disable TLSv1\n");
6101f13597dSJung-uk Kim     BIO_printf(bio_err, " -no_tls1_1    - Just disable TLSv1.1\n");
6111f13597dSJung-uk Kim     BIO_printf(bio_err, " -no_tls1_2    - Just disable TLSv1.2\n");
6125c87c606SMark Murray #ifndef OPENSSL_NO_DH
61374664626SKris Kennaway     BIO_printf(bio_err, " -no_dhe       - Disable ephemeral DH\n");
61474664626SKris Kennaway #endif
6153b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH
6163b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio_err, " -no_ecdhe     - Disable ephemeral ECDH\n");
6173b4e3dcbSSimon L. B. Nielsen #endif
618f579bf8eSKris Kennaway     BIO_printf(bio_err, " -bugs         - Turn on SSL bug compatibility\n");
6196f9291ceSJung-uk Kim     BIO_printf(bio_err,
6206f9291ceSJung-uk Kim                " -hack         - workaround for early Netscape code\n");
6216f9291ceSJung-uk Kim     BIO_printf(bio_err,
6226f9291ceSJung-uk Kim                " -www          - Respond to a 'GET /' with a status page\n");
6236f9291ceSJung-uk Kim     BIO_printf(bio_err,
6246f9291ceSJung-uk Kim                " -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
6256f9291ceSJung-uk Kim     BIO_printf(bio_err,
6266f9291ceSJung-uk Kim                " -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
6276f9291ceSJung-uk Kim     BIO_printf(bio_err,
6286f9291ceSJung-uk Kim                "                 with the assumption it contains a complete HTTP response.\n");
629fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
6306f9291ceSJung-uk Kim     BIO_printf(bio_err,
6316f9291ceSJung-uk Kim                " -engine id    - Initialise and use the specified engine\n");
632fceca8a3SJacques Vidrine #endif
6336f9291ceSJung-uk Kim     BIO_printf(bio_err,
6346f9291ceSJung-uk Kim                " -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
6356f9291ceSJung-uk Kim     BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
6366f9291ceSJung-uk Kim                LIST_SEPARATOR_CHAR);
637db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
6386f9291ceSJung-uk Kim     BIO_printf(bio_err,
6396f9291ceSJung-uk Kim                " -servername host - servername for HostName TLS extension\n");
6406f9291ceSJung-uk Kim     BIO_printf(bio_err,
6416f9291ceSJung-uk Kim                " -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
6426f9291ceSJung-uk Kim     BIO_printf(bio_err,
6436f9291ceSJung-uk Kim                " -cert2 arg    - certificate file to use for servername\n");
644db522d3aSSimon L. B. Nielsen     BIO_printf(bio_err, "                 (default is %s)\n", TEST_CERT2);
6456f9291ceSJung-uk Kim     BIO_printf(bio_err,
6466f9291ceSJung-uk Kim                " -key2 arg     - Private Key file to use for servername, in cert file if\n");
6476f9291ceSJung-uk Kim     BIO_printf(bio_err, "                 not specified (default is %s)\n",
6486f9291ceSJung-uk Kim                TEST_CERT2);
6496f9291ceSJung-uk Kim     BIO_printf(bio_err,
6506f9291ceSJung-uk Kim                " -tlsextdebug  - hex dump of all TLS extensions received\n");
6516f9291ceSJung-uk Kim     BIO_printf(bio_err,
6526f9291ceSJung-uk Kim                " -no_ticket    - disable use of RFC4507bis session tickets\n");
6536f9291ceSJung-uk Kim     BIO_printf(bio_err,
6546f9291ceSJung-uk Kim                " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
6551f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
6566f9291ceSJung-uk Kim     BIO_printf(bio_err,
6576f9291ceSJung-uk Kim                " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
658db522d3aSSimon L. B. Nielsen # endif
65909286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
6606f9291ceSJung-uk Kim     BIO_printf(bio_err,
6616f9291ceSJung-uk Kim                " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
6621f13597dSJung-uk Kim # endif
663*7bded2dbSJung-uk Kim     BIO_printf(bio_err,
664*7bded2dbSJung-uk Kim                " -alpn arg  - set the advertised protocols for the ALPN extension (comma-separated list)\n");
66509286989SJung-uk Kim #endif
6666f9291ceSJung-uk Kim     BIO_printf(bio_err,
6676f9291ceSJung-uk Kim                " -keymatexport label   - Export keying material using label\n");
6686f9291ceSJung-uk Kim     BIO_printf(bio_err,
6696f9291ceSJung-uk Kim                " -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
6706f9291ceSJung-uk Kim     BIO_printf(bio_err,
6716f9291ceSJung-uk Kim                " -status           - respond to certificate status requests\n");
6726f9291ceSJung-uk Kim     BIO_printf(bio_err,
6736f9291ceSJung-uk Kim                " -status_verbose   - enable status request verbose printout\n");
6746f9291ceSJung-uk Kim     BIO_printf(bio_err,
6756f9291ceSJung-uk Kim                " -status_timeout n - status request responder timeout\n");
676a93cbc2bSJung-uk Kim     BIO_printf(bio_err, " -status_url URL   - status request fallback URL\n");
67774664626SKris Kennaway }
67874664626SKris Kennaway 
67974664626SKris Kennaway static int local_argc = 0;
68074664626SKris Kennaway static char **local_argv;
68174664626SKris Kennaway 
68274664626SKris Kennaway #ifdef CHARSET_EBCDIC
68374664626SKris Kennaway static int ebcdic_new(BIO *bi);
68474664626SKris Kennaway static int ebcdic_free(BIO *a);
68574664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl);
6865c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl);
6875c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
68874664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size);
6895c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str);
69074664626SKris Kennaway 
69174664626SKris Kennaway # define BIO_TYPE_EBCDIC_FILTER  (18|0x0200)
6926f9291ceSJung-uk Kim static BIO_METHOD methods_ebcdic = {
69374664626SKris Kennaway     BIO_TYPE_EBCDIC_FILTER,
69474664626SKris Kennaway     "EBCDIC/ASCII filter",
69574664626SKris Kennaway     ebcdic_write,
69674664626SKris Kennaway     ebcdic_read,
69774664626SKris Kennaway     ebcdic_puts,
69874664626SKris Kennaway     ebcdic_gets,
69974664626SKris Kennaway     ebcdic_ctrl,
70074664626SKris Kennaway     ebcdic_new,
70174664626SKris Kennaway     ebcdic_free,
70274664626SKris Kennaway };
70374664626SKris Kennaway 
7046f9291ceSJung-uk Kim typedef struct {
70574664626SKris Kennaway     size_t alloced;
70674664626SKris Kennaway     char buff[1];
70774664626SKris Kennaway } EBCDIC_OUTBUFF;
70874664626SKris Kennaway 
70974664626SKris Kennaway BIO_METHOD *BIO_f_ebcdic_filter()
71074664626SKris Kennaway {
71174664626SKris Kennaway     return (&methods_ebcdic);
71274664626SKris Kennaway }
71374664626SKris Kennaway 
71474664626SKris Kennaway static int ebcdic_new(BIO *bi)
71574664626SKris Kennaway {
71674664626SKris Kennaway     EBCDIC_OUTBUFF *wbuf;
71774664626SKris Kennaway 
718ddd58736SKris Kennaway     wbuf = (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
7196f9291ceSJung-uk Kim     if (!wbuf)
7206f9291ceSJung-uk Kim         return 0;
72174664626SKris Kennaway     wbuf->alloced = 1024;
72274664626SKris Kennaway     wbuf->buff[0] = '\0';
72374664626SKris Kennaway 
72474664626SKris Kennaway     bi->ptr = (char *)wbuf;
72574664626SKris Kennaway     bi->init = 1;
72674664626SKris Kennaway     bi->flags = 0;
72774664626SKris Kennaway     return (1);
72874664626SKris Kennaway }
72974664626SKris Kennaway 
73074664626SKris Kennaway static int ebcdic_free(BIO *a)
73174664626SKris Kennaway {
7326f9291ceSJung-uk Kim     if (a == NULL)
7336f9291ceSJung-uk Kim         return (0);
73474664626SKris Kennaway     if (a->ptr != NULL)
735ddd58736SKris Kennaway         OPENSSL_free(a->ptr);
73674664626SKris Kennaway     a->ptr = NULL;
73774664626SKris Kennaway     a->init = 0;
73874664626SKris Kennaway     a->flags = 0;
73974664626SKris Kennaway     return (1);
74074664626SKris Kennaway }
74174664626SKris Kennaway 
74274664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl)
74374664626SKris Kennaway {
74474664626SKris Kennaway     int ret = 0;
74574664626SKris Kennaway 
7466f9291ceSJung-uk Kim     if (out == NULL || outl == 0)
7476f9291ceSJung-uk Kim         return (0);
7486f9291ceSJung-uk Kim     if (b->next_bio == NULL)
7496f9291ceSJung-uk Kim         return (0);
75074664626SKris Kennaway 
75174664626SKris Kennaway     ret = BIO_read(b->next_bio, out, outl);
75274664626SKris Kennaway     if (ret > 0)
75374664626SKris Kennaway         ascii2ebcdic(out, out, ret);
75474664626SKris Kennaway     return (ret);
75574664626SKris Kennaway }
75674664626SKris Kennaway 
7575c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl)
75874664626SKris Kennaway {
75974664626SKris Kennaway     EBCDIC_OUTBUFF *wbuf;
76074664626SKris Kennaway     int ret = 0;
76174664626SKris Kennaway     int num;
76274664626SKris Kennaway     unsigned char n;
76374664626SKris Kennaway 
7646f9291ceSJung-uk Kim     if ((in == NULL) || (inl <= 0))
7656f9291ceSJung-uk Kim         return (0);
7666f9291ceSJung-uk Kim     if (b->next_bio == NULL)
7676f9291ceSJung-uk Kim         return (0);
76874664626SKris Kennaway 
76974664626SKris Kennaway     wbuf = (EBCDIC_OUTBUFF *) b->ptr;
77074664626SKris Kennaway 
7716f9291ceSJung-uk Kim     if (inl > (num = wbuf->alloced)) {
77274664626SKris Kennaway         num = num + num;        /* double the size */
77374664626SKris Kennaway         if (num < inl)
77474664626SKris Kennaway             num = inl;
7756f9291ceSJung-uk Kim         wbuf =
7766f9291ceSJung-uk Kim             (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
7776f9291ceSJung-uk Kim         if (!wbuf)
7786f9291ceSJung-uk Kim             return 0;
7796f9291ceSJung-uk Kim         OPENSSL_free(b->ptr);
78074664626SKris Kennaway 
78174664626SKris Kennaway         wbuf->alloced = num;
78274664626SKris Kennaway         wbuf->buff[0] = '\0';
78374664626SKris Kennaway 
78474664626SKris Kennaway         b->ptr = (char *)wbuf;
78574664626SKris Kennaway     }
78674664626SKris Kennaway 
78774664626SKris Kennaway     ebcdic2ascii(wbuf->buff, in, inl);
78874664626SKris Kennaway 
78974664626SKris Kennaway     ret = BIO_write(b->next_bio, wbuf->buff, inl);
79074664626SKris Kennaway 
79174664626SKris Kennaway     return (ret);
79274664626SKris Kennaway }
79374664626SKris Kennaway 
7945c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
79574664626SKris Kennaway {
79674664626SKris Kennaway     long ret;
79774664626SKris Kennaway 
7986f9291ceSJung-uk Kim     if (b->next_bio == NULL)
7996f9291ceSJung-uk Kim         return (0);
8006f9291ceSJung-uk Kim     switch (cmd) {
80174664626SKris Kennaway     case BIO_CTRL_DUP:
80274664626SKris Kennaway         ret = 0L;
80374664626SKris Kennaway         break;
80474664626SKris Kennaway     default:
80574664626SKris Kennaway         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
80674664626SKris Kennaway         break;
80774664626SKris Kennaway     }
80874664626SKris Kennaway     return (ret);
80974664626SKris Kennaway }
81074664626SKris Kennaway 
81174664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size)
81274664626SKris Kennaway {
8135c87c606SMark Murray     int i, ret = 0;
8146f9291ceSJung-uk Kim     if (bp->next_bio == NULL)
8156f9291ceSJung-uk Kim         return (0);
81674664626SKris Kennaway /*      return(BIO_gets(bp->next_bio,buf,size));*/
8176f9291ceSJung-uk Kim     for (i = 0; i < size - 1; ++i) {
81874664626SKris Kennaway         ret = ebcdic_read(bp, &buf[i], 1);
81974664626SKris Kennaway         if (ret <= 0)
82074664626SKris Kennaway             break;
8216f9291ceSJung-uk Kim         else if (buf[i] == '\n') {
82274664626SKris Kennaway             ++i;
82374664626SKris Kennaway             break;
82474664626SKris Kennaway         }
82574664626SKris Kennaway     }
82674664626SKris Kennaway     if (i < size)
82774664626SKris Kennaway         buf[i] = '\0';
82874664626SKris Kennaway     return (ret < 0 && i == 0) ? ret : i;
82974664626SKris Kennaway }
83074664626SKris Kennaway 
8315c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str)
83274664626SKris Kennaway {
8336f9291ceSJung-uk Kim     if (bp->next_bio == NULL)
8346f9291ceSJung-uk Kim         return (0);
83574664626SKris Kennaway     return ebcdic_write(bp, str, strlen(str));
83674664626SKris Kennaway }
83774664626SKris Kennaway #endif
83874664626SKris Kennaway 
839db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
840db522d3aSSimon L. B. Nielsen 
841db522d3aSSimon L. B. Nielsen /* This is a context that we pass to callbacks */
842db522d3aSSimon L. B. Nielsen typedef struct tlsextctx_st {
843db522d3aSSimon L. B. Nielsen     char *servername;
844db522d3aSSimon L. B. Nielsen     BIO *biodebug;
845db522d3aSSimon L. B. Nielsen     int extension_error;
846db522d3aSSimon L. B. Nielsen } tlsextctx;
847db522d3aSSimon L. B. Nielsen 
848db522d3aSSimon L. B. Nielsen static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
849db522d3aSSimon L. B. Nielsen {
850db522d3aSSimon L. B. Nielsen     tlsextctx *p = (tlsextctx *) arg;
851db522d3aSSimon L. B. Nielsen     const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
852db522d3aSSimon L. B. Nielsen     if (servername && p->biodebug)
8536f9291ceSJung-uk Kim         BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
8546f9291ceSJung-uk Kim                    servername);
855db522d3aSSimon L. B. Nielsen 
856db522d3aSSimon L. B. Nielsen     if (!p->servername)
857db522d3aSSimon L. B. Nielsen         return SSL_TLSEXT_ERR_NOACK;
858db522d3aSSimon L. B. Nielsen 
8596f9291ceSJung-uk Kim     if (servername) {
860a93cbc2bSJung-uk Kim         if (strcasecmp(servername, p->servername))
861db522d3aSSimon L. B. Nielsen             return p->extension_error;
8626f9291ceSJung-uk Kim         if (ctx2) {
8631f13597dSJung-uk Kim             BIO_printf(p->biodebug, "Switching server context.\n");
864db522d3aSSimon L. B. Nielsen             SSL_set_SSL_CTX(s, ctx2);
865db522d3aSSimon L. B. Nielsen         }
866db522d3aSSimon L. B. Nielsen     }
867db522d3aSSimon L. B. Nielsen     return SSL_TLSEXT_ERR_OK;
868db522d3aSSimon L. B. Nielsen }
869db522d3aSSimon L. B. Nielsen 
870db522d3aSSimon L. B. Nielsen /* Structure passed to cert status callback */
871db522d3aSSimon L. B. Nielsen 
872db522d3aSSimon L. B. Nielsen typedef struct tlsextstatusctx_st {
873db522d3aSSimon L. B. Nielsen     /* Default responder to use */
874db522d3aSSimon L. B. Nielsen     char *host, *path, *port;
875db522d3aSSimon L. B. Nielsen     int use_ssl;
876db522d3aSSimon L. B. Nielsen     int timeout;
877db522d3aSSimon L. B. Nielsen     BIO *err;
878db522d3aSSimon L. B. Nielsen     int verbose;
879db522d3aSSimon L. B. Nielsen } tlsextstatusctx;
880db522d3aSSimon L. B. Nielsen 
881db522d3aSSimon L. B. Nielsen static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 };
882db522d3aSSimon L. B. Nielsen 
8836f9291ceSJung-uk Kim /*
8846f9291ceSJung-uk Kim  * Certificate Status callback. This is called when a client includes a
8856f9291ceSJung-uk Kim  * certificate status request extension. This is a simplified version. It
8866f9291ceSJung-uk Kim  * examines certificates each time and makes one OCSP responder query for
8876f9291ceSJung-uk Kim  * each request. A full version would store details such as the OCSP
8886f9291ceSJung-uk Kim  * certificate IDs and minimise the number of OCSP responses by caching them
8896f9291ceSJung-uk Kim  * until they were considered "expired".
890db522d3aSSimon L. B. Nielsen  */
891db522d3aSSimon L. B. Nielsen 
892db522d3aSSimon L. B. Nielsen static int cert_status_cb(SSL *s, void *arg)
893db522d3aSSimon L. B. Nielsen {
894db522d3aSSimon L. B. Nielsen     tlsextstatusctx *srctx = arg;
895db522d3aSSimon L. B. Nielsen     BIO *err = srctx->err;
896db522d3aSSimon L. B. Nielsen     char *host, *port, *path;
897db522d3aSSimon L. B. Nielsen     int use_ssl;
898db522d3aSSimon L. B. Nielsen     unsigned char *rspder = NULL;
899db522d3aSSimon L. B. Nielsen     int rspderlen;
9001f13597dSJung-uk Kim     STACK_OF(OPENSSL_STRING) *aia = NULL;
901db522d3aSSimon L. B. Nielsen     X509 *x = NULL;
902db522d3aSSimon L. B. Nielsen     X509_STORE_CTX inctx;
903db522d3aSSimon L. B. Nielsen     X509_OBJECT obj;
904db522d3aSSimon L. B. Nielsen     OCSP_REQUEST *req = NULL;
905db522d3aSSimon L. B. Nielsen     OCSP_RESPONSE *resp = NULL;
906db522d3aSSimon L. B. Nielsen     OCSP_CERTID *id = NULL;
907db522d3aSSimon L. B. Nielsen     STACK_OF(X509_EXTENSION) *exts;
908db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
909db522d3aSSimon L. B. Nielsen     int i;
910db522d3aSSimon L. B. Nielsen # if 0
911db522d3aSSimon L. B. Nielsen     STACK_OF(OCSP_RESPID) *ids;
912db522d3aSSimon L. B. Nielsen     SSL_get_tlsext_status_ids(s, &ids);
9136f9291ceSJung-uk Kim     BIO_printf(err, "cert_status: received %d ids\n",
9146f9291ceSJung-uk Kim                sk_OCSP_RESPID_num(ids));
915db522d3aSSimon L. B. Nielsen # endif
916db522d3aSSimon L. B. Nielsen     if (srctx->verbose)
917db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: callback called\n");
918db522d3aSSimon L. B. Nielsen     /* Build up OCSP query from server certificate */
919db522d3aSSimon L. B. Nielsen     x = SSL_get_certificate(s);
920db522d3aSSimon L. B. Nielsen     aia = X509_get1_ocsp(x);
9216f9291ceSJung-uk Kim     if (aia) {
9221f13597dSJung-uk Kim         if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
9236f9291ceSJung-uk Kim                             &host, &port, &path, &use_ssl)) {
924db522d3aSSimon L. B. Nielsen             BIO_puts(err, "cert_status: can't parse AIA URL\n");
925db522d3aSSimon L. B. Nielsen             goto err;
926db522d3aSSimon L. B. Nielsen         }
927db522d3aSSimon L. B. Nielsen         if (srctx->verbose)
928db522d3aSSimon L. B. Nielsen             BIO_printf(err, "cert_status: AIA URL: %s\n",
9291f13597dSJung-uk Kim                        sk_OPENSSL_STRING_value(aia, 0));
9306f9291ceSJung-uk Kim     } else {
9316f9291ceSJung-uk Kim         if (!srctx->host) {
9326f9291ceSJung-uk Kim             BIO_puts(srctx->err,
9336f9291ceSJung-uk Kim                      "cert_status: no AIA and no default responder URL\n");
934db522d3aSSimon L. B. Nielsen             goto done;
935db522d3aSSimon L. B. Nielsen         }
936db522d3aSSimon L. B. Nielsen         host = srctx->host;
937db522d3aSSimon L. B. Nielsen         path = srctx->path;
938db522d3aSSimon L. B. Nielsen         port = srctx->port;
939db522d3aSSimon L. B. Nielsen         use_ssl = srctx->use_ssl;
940db522d3aSSimon L. B. Nielsen     }
941db522d3aSSimon L. B. Nielsen 
942db522d3aSSimon L. B. Nielsen     if (!X509_STORE_CTX_init(&inctx,
943db522d3aSSimon L. B. Nielsen                              SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
944db522d3aSSimon L. B. Nielsen                              NULL, NULL))
945db522d3aSSimon L. B. Nielsen         goto err;
946db522d3aSSimon L. B. Nielsen     if (X509_STORE_get_by_subject(&inctx, X509_LU_X509,
9476f9291ceSJung-uk Kim                                   X509_get_issuer_name(x), &obj) <= 0) {
948db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
949db522d3aSSimon L. B. Nielsen         X509_STORE_CTX_cleanup(&inctx);
950db522d3aSSimon L. B. Nielsen         goto done;
951db522d3aSSimon L. B. Nielsen     }
952db522d3aSSimon L. B. Nielsen     req = OCSP_REQUEST_new();
953db522d3aSSimon L. B. Nielsen     if (!req)
954db522d3aSSimon L. B. Nielsen         goto err;
955db522d3aSSimon L. B. Nielsen     id = OCSP_cert_to_id(NULL, x, obj.data.x509);
956db522d3aSSimon L. B. Nielsen     X509_free(obj.data.x509);
957db522d3aSSimon L. B. Nielsen     X509_STORE_CTX_cleanup(&inctx);
958db522d3aSSimon L. B. Nielsen     if (!id)
959db522d3aSSimon L. B. Nielsen         goto err;
960db522d3aSSimon L. B. Nielsen     if (!OCSP_request_add0_id(req, id))
961db522d3aSSimon L. B. Nielsen         goto err;
962db522d3aSSimon L. B. Nielsen     id = NULL;
963db522d3aSSimon L. B. Nielsen     /* Add any extensions to the request */
964db522d3aSSimon L. B. Nielsen     SSL_get_tlsext_status_exts(s, &exts);
9656f9291ceSJung-uk Kim     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
966db522d3aSSimon L. B. Nielsen         X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
967db522d3aSSimon L. B. Nielsen         if (!OCSP_REQUEST_add_ext(req, ext, -1))
968db522d3aSSimon L. B. Nielsen             goto err;
969db522d3aSSimon L. B. Nielsen     }
9701f13597dSJung-uk Kim     resp = process_responder(err, req, host, path, port, use_ssl, NULL,
971db522d3aSSimon L. B. Nielsen                              srctx->timeout);
9726f9291ceSJung-uk Kim     if (!resp) {
973db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: error querying responder\n");
974db522d3aSSimon L. B. Nielsen         goto done;
975db522d3aSSimon L. B. Nielsen     }
976db522d3aSSimon L. B. Nielsen     rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
977db522d3aSSimon L. B. Nielsen     if (rspderlen <= 0)
978db522d3aSSimon L. B. Nielsen         goto err;
979db522d3aSSimon L. B. Nielsen     SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
9806f9291ceSJung-uk Kim     if (srctx->verbose) {
981db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: ocsp response sent:\n");
982db522d3aSSimon L. B. Nielsen         OCSP_RESPONSE_print(err, resp, 2);
983db522d3aSSimon L. B. Nielsen     }
984db522d3aSSimon L. B. Nielsen     ret = SSL_TLSEXT_ERR_OK;
985db522d3aSSimon L. B. Nielsen  done:
986db522d3aSSimon L. B. Nielsen     if (ret != SSL_TLSEXT_ERR_OK)
987db522d3aSSimon L. B. Nielsen         ERR_print_errors(err);
9886f9291ceSJung-uk Kim     if (aia) {
989db522d3aSSimon L. B. Nielsen         OPENSSL_free(host);
990db522d3aSSimon L. B. Nielsen         OPENSSL_free(path);
991db522d3aSSimon L. B. Nielsen         OPENSSL_free(port);
992db522d3aSSimon L. B. Nielsen         X509_email_free(aia);
993db522d3aSSimon L. B. Nielsen     }
994db522d3aSSimon L. B. Nielsen     if (id)
995db522d3aSSimon L. B. Nielsen         OCSP_CERTID_free(id);
996db522d3aSSimon L. B. Nielsen     if (req)
997db522d3aSSimon L. B. Nielsen         OCSP_REQUEST_free(req);
998db522d3aSSimon L. B. Nielsen     if (resp)
999db522d3aSSimon L. B. Nielsen         OCSP_RESPONSE_free(resp);
1000db522d3aSSimon L. B. Nielsen     return ret;
1001db522d3aSSimon L. B. Nielsen  err:
1002db522d3aSSimon L. B. Nielsen     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
1003db522d3aSSimon L. B. Nielsen     goto done;
1004db522d3aSSimon L. B. Nielsen }
10051f13597dSJung-uk Kim 
10061f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
10071f13597dSJung-uk Kim /* This is the context that we pass to next_proto_cb */
10081f13597dSJung-uk Kim typedef struct tlsextnextprotoctx_st {
10091f13597dSJung-uk Kim     unsigned char *data;
10101f13597dSJung-uk Kim     unsigned int len;
10111f13597dSJung-uk Kim } tlsextnextprotoctx;
10121f13597dSJung-uk Kim 
10136f9291ceSJung-uk Kim static int next_proto_cb(SSL *s, const unsigned char **data,
10146f9291ceSJung-uk Kim                          unsigned int *len, void *arg)
10151f13597dSJung-uk Kim {
10161f13597dSJung-uk Kim     tlsextnextprotoctx *next_proto = arg;
10171f13597dSJung-uk Kim 
10181f13597dSJung-uk Kim     *data = next_proto->data;
10191f13597dSJung-uk Kim     *len = next_proto->len;
10201f13597dSJung-uk Kim 
10211f13597dSJung-uk Kim     return SSL_TLSEXT_ERR_OK;
10221f13597dSJung-uk Kim }
10231f13597dSJung-uk Kim # endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
10241f13597dSJung-uk Kim 
1025*7bded2dbSJung-uk Kim /* This the context that we pass to alpn_cb */
1026*7bded2dbSJung-uk Kim typedef struct tlsextalpnctx_st {
1027*7bded2dbSJung-uk Kim     unsigned char *data;
1028*7bded2dbSJung-uk Kim     unsigned short len;
1029*7bded2dbSJung-uk Kim } tlsextalpnctx;
1030*7bded2dbSJung-uk Kim 
1031*7bded2dbSJung-uk Kim static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
1032*7bded2dbSJung-uk Kim                    const unsigned char *in, unsigned int inlen, void *arg)
1033*7bded2dbSJung-uk Kim {
1034*7bded2dbSJung-uk Kim     tlsextalpnctx *alpn_ctx = arg;
1035*7bded2dbSJung-uk Kim 
1036*7bded2dbSJung-uk Kim     if (!s_quiet) {
1037*7bded2dbSJung-uk Kim         /* We can assume that |in| is syntactically valid. */
1038*7bded2dbSJung-uk Kim         unsigned i;
1039*7bded2dbSJung-uk Kim         BIO_printf(bio_s_out, "ALPN protocols advertised by the client: ");
1040*7bded2dbSJung-uk Kim         for (i = 0; i < inlen;) {
1041*7bded2dbSJung-uk Kim             if (i)
1042*7bded2dbSJung-uk Kim                 BIO_write(bio_s_out, ", ", 2);
1043*7bded2dbSJung-uk Kim             BIO_write(bio_s_out, &in[i + 1], in[i]);
1044*7bded2dbSJung-uk Kim             i += in[i] + 1;
1045*7bded2dbSJung-uk Kim         }
1046*7bded2dbSJung-uk Kim         BIO_write(bio_s_out, "\n", 1);
1047*7bded2dbSJung-uk Kim     }
1048*7bded2dbSJung-uk Kim 
1049*7bded2dbSJung-uk Kim     if (SSL_select_next_proto
1050*7bded2dbSJung-uk Kim         ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in,
1051*7bded2dbSJung-uk Kim          inlen) != OPENSSL_NPN_NEGOTIATED) {
1052*7bded2dbSJung-uk Kim         return SSL_TLSEXT_ERR_NOACK;
1053*7bded2dbSJung-uk Kim     }
1054*7bded2dbSJung-uk Kim 
1055*7bded2dbSJung-uk Kim     if (!s_quiet) {
1056*7bded2dbSJung-uk Kim         BIO_printf(bio_s_out, "ALPN protocols selected: ");
1057*7bded2dbSJung-uk Kim         BIO_write(bio_s_out, *out, *outlen);
1058*7bded2dbSJung-uk Kim         BIO_write(bio_s_out, "\n", 1);
1059*7bded2dbSJung-uk Kim     }
1060*7bded2dbSJung-uk Kim 
1061*7bded2dbSJung-uk Kim     return SSL_TLSEXT_ERR_OK;
1062*7bded2dbSJung-uk Kim }
1063*7bded2dbSJung-uk Kim #endif                          /* ndef OPENSSL_NO_TLSEXT */
10641f13597dSJung-uk Kim 
1065f579bf8eSKris Kennaway int MAIN(int, char **);
1066f579bf8eSKris Kennaway 
1067db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
1068db522d3aSSimon L. B. Nielsen static char *jpake_secret = NULL;
1069*7bded2dbSJung-uk Kim # define no_jpake !jpake_secret
1070*7bded2dbSJung-uk Kim #else
1071*7bded2dbSJung-uk Kim # define no_jpake 1
1072db522d3aSSimon L. B. Nielsen #endif
10731f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
10741f13597dSJung-uk Kim static srpsrvparm srp_callback_parm;
10751f13597dSJung-uk Kim #endif
107609286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
10771f13597dSJung-uk Kim static char *srtp_profiles = NULL;
107809286989SJung-uk Kim #endif
1079db522d3aSSimon L. B. Nielsen 
108074664626SKris Kennaway int MAIN(int argc, char *argv[])
108174664626SKris Kennaway {
10821f13597dSJung-uk Kim     X509_VERIFY_PARAM *vpm = NULL;
10831f13597dSJung-uk Kim     int badarg = 0;
108474664626SKris Kennaway     short port = PORT;
108574664626SKris Kennaway     char *CApath = NULL, *CAfile = NULL;
1086*7bded2dbSJung-uk Kim     char *chCApath = NULL, *chCAfile = NULL;
1087*7bded2dbSJung-uk Kim     char *vfyCApath = NULL, *vfyCAfile = NULL;
10883b4e3dcbSSimon L. B. Nielsen     unsigned char *context = NULL;
1089f579bf8eSKris Kennaway     char *dhfile = NULL;
1090*7bded2dbSJung-uk Kim     int badop = 0;
109174664626SKris Kennaway     int ret = 1;
1092*7bded2dbSJung-uk Kim     int build_chain = 0;
1093*7bded2dbSJung-uk Kim     int no_tmp_rsa = 0, no_dhe = 0, no_ecdhe = 0, nocert = 0;
109474664626SKris Kennaway     int state = 0;
10951f13597dSJung-uk Kim     const SSL_METHOD *meth = NULL;
1096db522d3aSSimon L. B. Nielsen     int socket_type = SOCK_STREAM;
10975c87c606SMark Murray     ENGINE *e = NULL;
10985740a5e3SKris Kennaway     char *inrand = NULL;
10993b4e3dcbSSimon L. B. Nielsen     int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
11003b4e3dcbSSimon L. B. Nielsen     char *passarg = NULL, *pass = NULL;
11013b4e3dcbSSimon L. B. Nielsen     char *dpassarg = NULL, *dpass = NULL;
11023b4e3dcbSSimon L. B. Nielsen     int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
11033b4e3dcbSSimon L. B. Nielsen     X509 *s_cert = NULL, *s_dcert = NULL;
1104*7bded2dbSJung-uk Kim     STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL;
11053b4e3dcbSSimon L. B. Nielsen     EVP_PKEY *s_key = NULL, *s_dkey = NULL;
1106*7bded2dbSJung-uk Kim     int no_cache = 0, ext_cache = 0;
1107*7bded2dbSJung-uk Kim     int rev = 0, naccept = -1;
1108db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1109db522d3aSSimon L. B. Nielsen     EVP_PKEY *s_key2 = NULL;
1110db522d3aSSimon L. B. Nielsen     X509 *s_cert2 = NULL;
1111db522d3aSSimon L. B. Nielsen     tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING };
11121f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
11131f13597dSJung-uk Kim     const char *next_proto_neg_in = NULL;
1114*7bded2dbSJung-uk Kim     tlsextnextprotoctx next_proto = { NULL, 0 };
1115db522d3aSSimon L. B. Nielsen # endif
1116*7bded2dbSJung-uk Kim     const char *alpn_in = NULL;
1117*7bded2dbSJung-uk Kim     tlsextalpnctx alpn_ctx = { NULL, 0 };
11181f13597dSJung-uk Kim #endif
11191f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK
11201f13597dSJung-uk Kim     /* by default do not send a PSK identity hint */
11211f13597dSJung-uk Kim     static char *psk_identity_hint = NULL;
11221f13597dSJung-uk Kim #endif
11231f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
11241f13597dSJung-uk Kim     char *srpuserseed = NULL;
11251f13597dSJung-uk Kim     char *srp_verifier_file = NULL;
11261f13597dSJung-uk Kim #endif
1127*7bded2dbSJung-uk Kim     SSL_EXCERT *exc = NULL;
1128*7bded2dbSJung-uk Kim     SSL_CONF_CTX *cctx = NULL;
1129*7bded2dbSJung-uk Kim     STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
1130*7bded2dbSJung-uk Kim 
1131*7bded2dbSJung-uk Kim     char *crl_file = NULL;
1132*7bded2dbSJung-uk Kim     int crl_format = FORMAT_PEM;
1133*7bded2dbSJung-uk Kim     int crl_download = 0;
1134*7bded2dbSJung-uk Kim     STACK_OF(X509_CRL) *crls = NULL;
1135*7bded2dbSJung-uk Kim 
113674664626SKris Kennaway     meth = SSLv23_server_method();
113774664626SKris Kennaway 
113874664626SKris Kennaway     local_argc = argc;
113974664626SKris Kennaway     local_argv = argv;
114074664626SKris Kennaway 
114174664626SKris Kennaway     apps_startup();
1142f579bf8eSKris Kennaway #ifdef MONOLITH
1143f579bf8eSKris Kennaway     s_server_init();
1144f579bf8eSKris Kennaway #endif
114574664626SKris Kennaway 
114674664626SKris Kennaway     if (bio_err == NULL)
114774664626SKris Kennaway         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
114874664626SKris Kennaway 
11495c87c606SMark Murray     if (!load_config(bio_err, NULL))
11505c87c606SMark Murray         goto end;
11515c87c606SMark Murray 
1152*7bded2dbSJung-uk Kim     cctx = SSL_CONF_CTX_new();
1153*7bded2dbSJung-uk Kim     if (!cctx)
1154*7bded2dbSJung-uk Kim         goto end;
1155*7bded2dbSJung-uk Kim     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
1156*7bded2dbSJung-uk Kim     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);
1157*7bded2dbSJung-uk Kim 
115874664626SKris Kennaway     verify_depth = 0;
115974664626SKris Kennaway #ifdef FIONBIO
116074664626SKris Kennaway     s_nbio = 0;
116174664626SKris Kennaway #endif
116274664626SKris Kennaway     s_nbio_test = 0;
116374664626SKris Kennaway 
116474664626SKris Kennaway     argc--;
116574664626SKris Kennaway     argv++;
116674664626SKris Kennaway 
11676f9291ceSJung-uk Kim     while (argc >= 1) {
11686f9291ceSJung-uk Kim         if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) {
11696f9291ceSJung-uk Kim             if (--argc < 1)
11706f9291ceSJung-uk Kim                 goto bad;
117174664626SKris Kennaway             if (!extract_port(*(++argv), &port))
117274664626SKris Kennaway                 goto bad;
1173*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-naccept") == 0) {
1174*7bded2dbSJung-uk Kim             if (--argc < 1)
1175*7bded2dbSJung-uk Kim                 goto bad;
1176*7bded2dbSJung-uk Kim             naccept = atol(*(++argv));
1177*7bded2dbSJung-uk Kim             if (naccept <= 0) {
1178*7bded2dbSJung-uk Kim                 BIO_printf(bio_err, "bad accept value %s\n", *argv);
1179*7bded2dbSJung-uk Kim                 goto bad;
1180*7bded2dbSJung-uk Kim             }
11816f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-verify") == 0) {
118274664626SKris Kennaway             s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
11836f9291ceSJung-uk Kim             if (--argc < 1)
11846f9291ceSJung-uk Kim                 goto bad;
118574664626SKris Kennaway             verify_depth = atoi(*(++argv));
1186*7bded2dbSJung-uk Kim             if (!s_quiet)
118774664626SKris Kennaway                 BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
11886f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-Verify") == 0) {
11896f9291ceSJung-uk Kim             s_server_verify =
11906f9291ceSJung-uk Kim                 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
119174664626SKris Kennaway                 SSL_VERIFY_CLIENT_ONCE;
11926f9291ceSJung-uk Kim             if (--argc < 1)
11936f9291ceSJung-uk Kim                 goto bad;
119474664626SKris Kennaway             verify_depth = atoi(*(++argv));
1195*7bded2dbSJung-uk Kim             if (!s_quiet)
11966f9291ceSJung-uk Kim                 BIO_printf(bio_err,
11976f9291ceSJung-uk Kim                            "verify depth is %d, must return a certificate\n",
11986f9291ceSJung-uk Kim                            verify_depth);
11996f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-context") == 0) {
12006f9291ceSJung-uk Kim             if (--argc < 1)
12016f9291ceSJung-uk Kim                 goto bad;
12023b4e3dcbSSimon L. B. Nielsen             context = (unsigned char *)*(++argv);
12036f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-cert") == 0) {
12046f9291ceSJung-uk Kim             if (--argc < 1)
12056f9291ceSJung-uk Kim                 goto bad;
120674664626SKris Kennaway             s_cert_file = *(++argv);
1207*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-CRL") == 0) {
1208*7bded2dbSJung-uk Kim             if (--argc < 1)
1209*7bded2dbSJung-uk Kim                 goto bad;
1210*7bded2dbSJung-uk Kim             crl_file = *(++argv);
1211*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-crl_download") == 0)
1212*7bded2dbSJung-uk Kim             crl_download = 1;
1213*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
1214*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-serverinfo") == 0) {
1215*7bded2dbSJung-uk Kim             if (--argc < 1)
1216*7bded2dbSJung-uk Kim                 goto bad;
1217*7bded2dbSJung-uk Kim             s_serverinfo_file = *(++argv);
1218*7bded2dbSJung-uk Kim         }
1219*7bded2dbSJung-uk Kim #endif
1220*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-certform") == 0) {
12216f9291ceSJung-uk Kim             if (--argc < 1)
12226f9291ceSJung-uk Kim                 goto bad;
12233b4e3dcbSSimon L. B. Nielsen             s_cert_format = str2fmt(*(++argv));
12246f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-key") == 0) {
12256f9291ceSJung-uk Kim             if (--argc < 1)
12266f9291ceSJung-uk Kim                 goto bad;
122774664626SKris Kennaway             s_key_file = *(++argv);
12286f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keyform") == 0) {
12296f9291ceSJung-uk Kim             if (--argc < 1)
12306f9291ceSJung-uk Kim                 goto bad;
12313b4e3dcbSSimon L. B. Nielsen             s_key_format = str2fmt(*(++argv));
12326f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-pass") == 0) {
12336f9291ceSJung-uk Kim             if (--argc < 1)
12346f9291ceSJung-uk Kim                 goto bad;
12353b4e3dcbSSimon L. B. Nielsen             passarg = *(++argv);
1236*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-cert_chain") == 0) {
1237*7bded2dbSJung-uk Kim             if (--argc < 1)
1238*7bded2dbSJung-uk Kim                 goto bad;
1239*7bded2dbSJung-uk Kim             s_chain_file = *(++argv);
12406f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dhparam") == 0) {
12416f9291ceSJung-uk Kim             if (--argc < 1)
12426f9291ceSJung-uk Kim                 goto bad;
1243f579bf8eSKris Kennaway             dhfile = *(++argv);
1244*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dcertform") == 0) {
12456f9291ceSJung-uk Kim             if (--argc < 1)
12466f9291ceSJung-uk Kim                 goto bad;
12473b4e3dcbSSimon L. B. Nielsen             s_dcert_format = str2fmt(*(++argv));
12486f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dcert") == 0) {
12496f9291ceSJung-uk Kim             if (--argc < 1)
12506f9291ceSJung-uk Kim                 goto bad;
125174664626SKris Kennaway             s_dcert_file = *(++argv);
12526f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dkeyform") == 0) {
12536f9291ceSJung-uk Kim             if (--argc < 1)
12546f9291ceSJung-uk Kim                 goto bad;
12553b4e3dcbSSimon L. B. Nielsen             s_dkey_format = str2fmt(*(++argv));
12566f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dpass") == 0) {
12576f9291ceSJung-uk Kim             if (--argc < 1)
12586f9291ceSJung-uk Kim                 goto bad;
12593b4e3dcbSSimon L. B. Nielsen             dpassarg = *(++argv);
12606f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dkey") == 0) {
12616f9291ceSJung-uk Kim             if (--argc < 1)
12626f9291ceSJung-uk Kim                 goto bad;
126374664626SKris Kennaway             s_dkey_file = *(++argv);
1264*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dcert_chain") == 0) {
1265*7bded2dbSJung-uk Kim             if (--argc < 1)
1266*7bded2dbSJung-uk Kim                 goto bad;
1267*7bded2dbSJung-uk Kim             s_dchain_file = *(++argv);
12686f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-nocert") == 0) {
126974664626SKris Kennaway             nocert = 1;
12706f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-CApath") == 0) {
12716f9291ceSJung-uk Kim             if (--argc < 1)
12726f9291ceSJung-uk Kim                 goto bad;
127374664626SKris Kennaway             CApath = *(++argv);
1274*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-chainCApath") == 0) {
1275*7bded2dbSJung-uk Kim             if (--argc < 1)
1276*7bded2dbSJung-uk Kim                 goto bad;
1277*7bded2dbSJung-uk Kim             chCApath = *(++argv);
1278*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-verifyCApath") == 0) {
1279*7bded2dbSJung-uk Kim             if (--argc < 1)
1280*7bded2dbSJung-uk Kim                 goto bad;
1281*7bded2dbSJung-uk Kim             vfyCApath = *(++argv);
12826f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-no_cache") == 0)
12836a599222SSimon L. B. Nielsen             no_cache = 1;
1284*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-ext_cache") == 0)
1285*7bded2dbSJung-uk Kim             ext_cache = 1;
1286*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-CRLform") == 0) {
1287*7bded2dbSJung-uk Kim             if (--argc < 1)
1288*7bded2dbSJung-uk Kim                 goto bad;
1289*7bded2dbSJung-uk Kim             crl_format = str2fmt(*(++argv));
1290*7bded2dbSJung-uk Kim         } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) {
1291*7bded2dbSJung-uk Kim             if (badarg)
1292*7bded2dbSJung-uk Kim                 goto bad;
1293*7bded2dbSJung-uk Kim             continue;
1294*7bded2dbSJung-uk Kim         } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) {
1295*7bded2dbSJung-uk Kim             if (badarg)
1296*7bded2dbSJung-uk Kim                 goto bad;
1297*7bded2dbSJung-uk Kim             continue;
1298*7bded2dbSJung-uk Kim         } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) {
12991f13597dSJung-uk Kim             if (badarg)
13001f13597dSJung-uk Kim                 goto bad;
13011f13597dSJung-uk Kim             continue;
13026f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-verify_return_error") == 0)
13031f13597dSJung-uk Kim             verify_return_error = 1;
1304*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-verify_quiet") == 0)
1305*7bded2dbSJung-uk Kim             verify_quiet = 1;
1306*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-build_chain") == 0)
1307*7bded2dbSJung-uk Kim             build_chain = 1;
1308*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-CAfile") == 0) {
13096f9291ceSJung-uk Kim             if (--argc < 1)
13106f9291ceSJung-uk Kim                 goto bad;
131174664626SKris Kennaway             CAfile = *(++argv);
1312*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-chainCAfile") == 0) {
1313*7bded2dbSJung-uk Kim             if (--argc < 1)
1314*7bded2dbSJung-uk Kim                 goto bad;
1315*7bded2dbSJung-uk Kim             chCAfile = *(++argv);
1316*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-verifyCAfile") == 0) {
1317*7bded2dbSJung-uk Kim             if (--argc < 1)
1318*7bded2dbSJung-uk Kim                 goto bad;
1319*7bded2dbSJung-uk Kim             vfyCAfile = *(++argv);
132074664626SKris Kennaway         }
132174664626SKris Kennaway #ifdef FIONBIO
13226f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nbio") == 0) {
13236f9291ceSJung-uk Kim             s_nbio = 1;
13246f9291ceSJung-uk Kim         }
132574664626SKris Kennaway #endif
13266f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nbio_test") == 0) {
132774664626SKris Kennaway #ifdef FIONBIO
132874664626SKris Kennaway             s_nbio = 1;
132974664626SKris Kennaway #endif
133074664626SKris Kennaway             s_nbio_test = 1;
1331*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-ign_eof") == 0)
1332*7bded2dbSJung-uk Kim             s_ign_eof = 1;
1333*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-no_ign_eof") == 0)
1334*7bded2dbSJung-uk Kim             s_ign_eof = 0;
1335*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-debug") == 0) {
13366f9291ceSJung-uk Kim             s_debug = 1;
133774664626SKris Kennaway         }
1338db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1339db522d3aSSimon L. B. Nielsen         else if (strcmp(*argv, "-tlsextdebug") == 0)
1340db522d3aSSimon L. B. Nielsen             s_tlsextdebug = 1;
1341db522d3aSSimon L. B. Nielsen         else if (strcmp(*argv, "-status") == 0)
1342db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
13436f9291ceSJung-uk Kim         else if (strcmp(*argv, "-status_verbose") == 0) {
1344db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
1345db522d3aSSimon L. B. Nielsen             tlscstatp.verbose = 1;
13466f9291ceSJung-uk Kim         } else if (!strcmp(*argv, "-status_timeout")) {
1347db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
13486f9291ceSJung-uk Kim             if (--argc < 1)
13496f9291ceSJung-uk Kim                 goto bad;
1350db522d3aSSimon L. B. Nielsen             tlscstatp.timeout = atoi(*(++argv));
13516f9291ceSJung-uk Kim         } else if (!strcmp(*argv, "-status_url")) {
1352db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
13536f9291ceSJung-uk Kim             if (--argc < 1)
13546f9291ceSJung-uk Kim                 goto bad;
1355db522d3aSSimon L. B. Nielsen             if (!OCSP_parse_url(*(++argv),
1356db522d3aSSimon L. B. Nielsen                                 &tlscstatp.host,
1357db522d3aSSimon L. B. Nielsen                                 &tlscstatp.port,
13586f9291ceSJung-uk Kim                                 &tlscstatp.path, &tlscstatp.use_ssl)) {
1359db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err, "Error parsing URL\n");
1360db522d3aSSimon L. B. Nielsen                 goto bad;
1361db522d3aSSimon L. B. Nielsen             }
1362db522d3aSSimon L. B. Nielsen         }
1363db522d3aSSimon L. B. Nielsen #endif
13646f9291ceSJung-uk Kim         else if (strcmp(*argv, "-msg") == 0) {
13656f9291ceSJung-uk Kim             s_msg = 1;
1366*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-msgfile") == 0) {
1367*7bded2dbSJung-uk Kim             if (--argc < 1)
1368*7bded2dbSJung-uk Kim                 goto bad;
1369*7bded2dbSJung-uk Kim             bio_s_msg = BIO_new_file(*(++argv), "w");
1370*7bded2dbSJung-uk Kim         }
1371*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
1372*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-trace") == 0) {
1373*7bded2dbSJung-uk Kim             s_msg = 2;
1374*7bded2dbSJung-uk Kim         }
1375*7bded2dbSJung-uk Kim #endif
1376*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-hack") == 0) {
13776f9291ceSJung-uk Kim             hack = 1;
13786f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-state") == 0) {
13796f9291ceSJung-uk Kim             state = 1;
13806f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-crlf") == 0) {
13816f9291ceSJung-uk Kim             s_crlf = 1;
13826f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-quiet") == 0) {
13836f9291ceSJung-uk Kim             s_quiet = 1;
1384*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-brief") == 0) {
1385*7bded2dbSJung-uk Kim             s_quiet = 1;
1386*7bded2dbSJung-uk Kim             s_brief = 1;
1387*7bded2dbSJung-uk Kim             verify_quiet = 1;
13886f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-no_tmp_rsa") == 0) {
13896f9291ceSJung-uk Kim             no_tmp_rsa = 1;
13906f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-no_dhe") == 0) {
13916f9291ceSJung-uk Kim             no_dhe = 1;
1392*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-no_ecdhe") == 0) {
13936f9291ceSJung-uk Kim             no_ecdhe = 1;
1394*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-no_resume_ephemeral") == 0) {
1395*7bded2dbSJung-uk Kim             no_resume_ephemeral = 1;
13966f9291ceSJung-uk Kim         }
13976f9291ceSJung-uk Kim #ifndef OPENSSL_NO_PSK
13986f9291ceSJung-uk Kim         else if (strcmp(*argv, "-psk_hint") == 0) {
13996f9291ceSJung-uk Kim             if (--argc < 1)
14006f9291ceSJung-uk Kim                 goto bad;
14016f9291ceSJung-uk Kim             psk_identity_hint = *(++argv);
14026f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-psk") == 0) {
14031f13597dSJung-uk Kim             size_t i;
14041f13597dSJung-uk Kim 
14056f9291ceSJung-uk Kim             if (--argc < 1)
14066f9291ceSJung-uk Kim                 goto bad;
14071f13597dSJung-uk Kim             psk_key = *(++argv);
14086f9291ceSJung-uk Kim             for (i = 0; i < strlen(psk_key); i++) {
14091f13597dSJung-uk Kim                 if (isxdigit((unsigned char)psk_key[i]))
14101f13597dSJung-uk Kim                     continue;
14111f13597dSJung-uk Kim                 BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
14121f13597dSJung-uk Kim                 goto bad;
14131f13597dSJung-uk Kim             }
14141f13597dSJung-uk Kim         }
14151f13597dSJung-uk Kim #endif
14161f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
14176f9291ceSJung-uk Kim         else if (strcmp(*argv, "-srpvfile") == 0) {
14186f9291ceSJung-uk Kim             if (--argc < 1)
14196f9291ceSJung-uk Kim                 goto bad;
14201f13597dSJung-uk Kim             srp_verifier_file = *(++argv);
14211f13597dSJung-uk Kim             meth = TLSv1_server_method();
14226f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-srpuserseed") == 0) {
14236f9291ceSJung-uk Kim             if (--argc < 1)
14246f9291ceSJung-uk Kim                 goto bad;
14251f13597dSJung-uk Kim             srpuserseed = *(++argv);
14261f13597dSJung-uk Kim             meth = TLSv1_server_method();
14271f13597dSJung-uk Kim         }
14281f13597dSJung-uk Kim #endif
1429*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-rev") == 0) {
1430*7bded2dbSJung-uk Kim             rev = 1;
1431*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-www") == 0) {
14326f9291ceSJung-uk Kim             www = 1;
14336f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-WWW") == 0) {
14346f9291ceSJung-uk Kim             www = 2;
14356f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-HTTP") == 0) {
14366f9291ceSJung-uk Kim             www = 3;
14376f9291ceSJung-uk Kim         }
14385c87c606SMark Murray #ifndef OPENSSL_NO_SSL2
14396f9291ceSJung-uk Kim         else if (strcmp(*argv, "-ssl2") == 0) {
1440*7bded2dbSJung-uk Kim             no_ecdhe = 1;
14416f9291ceSJung-uk Kim             meth = SSLv2_server_method();
14426f9291ceSJung-uk Kim         }
144374664626SKris Kennaway #endif
1444751d2991SJung-uk Kim #ifndef OPENSSL_NO_SSL3_METHOD
14456f9291ceSJung-uk Kim         else if (strcmp(*argv, "-ssl3") == 0) {
14466f9291ceSJung-uk Kim             meth = SSLv3_server_method();
14476f9291ceSJung-uk Kim         }
144874664626SKris Kennaway #endif
14495c87c606SMark Murray #ifndef OPENSSL_NO_TLS1
14506f9291ceSJung-uk Kim         else if (strcmp(*argv, "-tls1") == 0) {
14516f9291ceSJung-uk Kim             meth = TLSv1_server_method();
14526f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-tls1_1") == 0) {
14536f9291ceSJung-uk Kim             meth = TLSv1_1_server_method();
14546f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-tls1_2") == 0) {
14556f9291ceSJung-uk Kim             meth = TLSv1_2_server_method();
14566f9291ceSJung-uk Kim         }
145774664626SKris Kennaway #endif
14583b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DTLS1
1459*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-dtls") == 0) {
1460*7bded2dbSJung-uk Kim             meth = DTLS_server_method();
1461*7bded2dbSJung-uk Kim             socket_type = SOCK_DGRAM;
1462*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dtls1") == 0) {
14633b4e3dcbSSimon L. B. Nielsen             meth = DTLSv1_server_method();
1464db522d3aSSimon L. B. Nielsen             socket_type = SOCK_DGRAM;
1465*7bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dtls1_2") == 0) {
1466*7bded2dbSJung-uk Kim             meth = DTLSv1_2_server_method();
1467*7bded2dbSJung-uk Kim             socket_type = SOCK_DGRAM;
14686f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-timeout") == 0)
14693b4e3dcbSSimon L. B. Nielsen             enable_timeouts = 1;
14706f9291ceSJung-uk Kim         else if (strcmp(*argv, "-mtu") == 0) {
14716f9291ceSJung-uk Kim             if (--argc < 1)
14726f9291ceSJung-uk Kim                 goto bad;
14736a599222SSimon L. B. Nielsen             socket_mtu = atol(*(++argv));
14746f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-chain") == 0)
14753b4e3dcbSSimon L. B. Nielsen             cert_chain = 1;
14763b4e3dcbSSimon L. B. Nielsen #endif
14776f9291ceSJung-uk Kim         else if (strcmp(*argv, "-id_prefix") == 0) {
14786f9291ceSJung-uk Kim             if (--argc < 1)
14796f9291ceSJung-uk Kim                 goto bad;
14805c87c606SMark Murray             session_id_prefix = *(++argv);
14815c87c606SMark Murray         }
1482fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
14836f9291ceSJung-uk Kim         else if (strcmp(*argv, "-engine") == 0) {
14846f9291ceSJung-uk Kim             if (--argc < 1)
14856f9291ceSJung-uk Kim                 goto bad;
14865c87c606SMark Murray             engine_id = *(++argv);
14875c87c606SMark Murray         }
1488fceca8a3SJacques Vidrine #endif
14896f9291ceSJung-uk Kim         else if (strcmp(*argv, "-rand") == 0) {
14906f9291ceSJung-uk Kim             if (--argc < 1)
14916f9291ceSJung-uk Kim                 goto bad;
14925740a5e3SKris Kennaway             inrand = *(++argv);
14935740a5e3SKris Kennaway         }
1494db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
14956f9291ceSJung-uk Kim         else if (strcmp(*argv, "-servername") == 0) {
14966f9291ceSJung-uk Kim             if (--argc < 1)
14976f9291ceSJung-uk Kim                 goto bad;
1498db522d3aSSimon L. B. Nielsen             tlsextcbp.servername = *(++argv);
14996f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-servername_fatal") == 0) {
15006f9291ceSJung-uk Kim             tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL;
15016f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-cert2") == 0) {
15026f9291ceSJung-uk Kim             if (--argc < 1)
15036f9291ceSJung-uk Kim                 goto bad;
1504db522d3aSSimon L. B. Nielsen             s_cert_file2 = *(++argv);
15056f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-key2") == 0) {
15066f9291ceSJung-uk Kim             if (--argc < 1)
15076f9291ceSJung-uk Kim                 goto bad;
1508db522d3aSSimon L. B. Nielsen             s_key_file2 = *(++argv);
1509db522d3aSSimon L. B. Nielsen         }
15101f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
15116f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nextprotoneg") == 0) {
15126f9291ceSJung-uk Kim             if (--argc < 1)
15136f9291ceSJung-uk Kim                 goto bad;
15141f13597dSJung-uk Kim             next_proto_neg_in = *(++argv);
15151f13597dSJung-uk Kim         }
1516db522d3aSSimon L. B. Nielsen # endif
1517*7bded2dbSJung-uk Kim         else if (strcmp(*argv, "-alpn") == 0) {
1518*7bded2dbSJung-uk Kim             if (--argc < 1)
1519*7bded2dbSJung-uk Kim                 goto bad;
1520*7bded2dbSJung-uk Kim             alpn_in = *(++argv);
1521*7bded2dbSJung-uk Kim         }
15221f13597dSJung-uk Kim #endif
15231f13597dSJung-uk Kim #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
15246f9291ceSJung-uk Kim         else if (strcmp(*argv, "-jpake") == 0) {
15256f9291ceSJung-uk Kim             if (--argc < 1)
15266f9291ceSJung-uk Kim                 goto bad;
1527db522d3aSSimon L. B. Nielsen             jpake_secret = *(++argv);
1528db522d3aSSimon L. B. Nielsen         }
1529db522d3aSSimon L. B. Nielsen #endif
153009286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
15316f9291ceSJung-uk Kim         else if (strcmp(*argv, "-use_srtp") == 0) {
15326f9291ceSJung-uk Kim             if (--argc < 1)
15336f9291ceSJung-uk Kim                 goto bad;
15341f13597dSJung-uk Kim             srtp_profiles = *(++argv);
15351f13597dSJung-uk Kim         }
153609286989SJung-uk Kim #endif
15376f9291ceSJung-uk Kim         else if (strcmp(*argv, "-keymatexport") == 0) {
15386f9291ceSJung-uk Kim             if (--argc < 1)
15396f9291ceSJung-uk Kim                 goto bad;
15401f13597dSJung-uk Kim             keymatexportlabel = *(++argv);
15416f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keymatexportlen") == 0) {
15426f9291ceSJung-uk Kim             if (--argc < 1)
15436f9291ceSJung-uk Kim                 goto bad;
15441f13597dSJung-uk Kim             keymatexportlen = atoi(*(++argv));
15456f9291ceSJung-uk Kim             if (keymatexportlen == 0)
15466f9291ceSJung-uk Kim                 goto bad;
15476f9291ceSJung-uk Kim         } else {
154874664626SKris Kennaway             BIO_printf(bio_err, "unknown option %s\n", *argv);
154974664626SKris Kennaway             badop = 1;
155074664626SKris Kennaway             break;
155174664626SKris Kennaway         }
155274664626SKris Kennaway         argc--;
155374664626SKris Kennaway         argv++;
155474664626SKris Kennaway     }
15556f9291ceSJung-uk Kim     if (badop) {
155674664626SKris Kennaway  bad:
155774664626SKris Kennaway         sv_usage();
155874664626SKris Kennaway         goto end;
155974664626SKris Kennaway     }
1560a93cbc2bSJung-uk Kim #ifndef OPENSSL_NO_DTLS1
15616f9291ceSJung-uk Kim     if (www && socket_type == SOCK_DGRAM) {
15626f9291ceSJung-uk Kim         BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n");
1563a93cbc2bSJung-uk Kim         goto end;
1564a93cbc2bSJung-uk Kim     }
1565a93cbc2bSJung-uk Kim #endif
156674664626SKris Kennaway 
15671f13597dSJung-uk Kim #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
15686f9291ceSJung-uk Kim     if (jpake_secret) {
15696f9291ceSJung-uk Kim         if (psk_key) {
15706f9291ceSJung-uk Kim             BIO_printf(bio_err, "Can't use JPAKE and PSK together\n");
15711f13597dSJung-uk Kim             goto end;
15721f13597dSJung-uk Kim         }
15731f13597dSJung-uk Kim         psk_identity = "JPAKE";
15741f13597dSJung-uk Kim     }
15751f13597dSJung-uk Kim #endif
15761f13597dSJung-uk Kim 
15775c87c606SMark Murray     SSL_load_error_strings();
15785c87c606SMark Murray     OpenSSL_add_ssl_algorithms();
15795c87c606SMark Murray 
1580fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
15815c87c606SMark Murray     e = setup_engine(bio_err, engine_id, 1);
1582fceca8a3SJacques Vidrine #endif
15835c87c606SMark Murray 
15846f9291ceSJung-uk Kim     if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) {
15853b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Error getting password\n");
15863b4e3dcbSSimon L. B. Nielsen         goto end;
15873b4e3dcbSSimon L. B. Nielsen     }
15883b4e3dcbSSimon L. B. Nielsen 
15893b4e3dcbSSimon L. B. Nielsen     if (s_key_file == NULL)
15903b4e3dcbSSimon L. B. Nielsen         s_key_file = s_cert_file;
1591db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1592db522d3aSSimon L. B. Nielsen     if (s_key_file2 == NULL)
1593db522d3aSSimon L. B. Nielsen         s_key_file2 = s_cert_file2;
1594db522d3aSSimon L. B. Nielsen #endif
15953b4e3dcbSSimon L. B. Nielsen 
1596*7bded2dbSJung-uk Kim     if (!load_excert(&exc, bio_err))
1597*7bded2dbSJung-uk Kim         goto end;
1598*7bded2dbSJung-uk Kim 
15996f9291ceSJung-uk Kim     if (nocert == 0) {
16003b4e3dcbSSimon L. B. Nielsen         s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
16013b4e3dcbSSimon L. B. Nielsen                          "server certificate private key file");
16026f9291ceSJung-uk Kim         if (!s_key) {
16033b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16043b4e3dcbSSimon L. B. Nielsen             goto end;
16053b4e3dcbSSimon L. B. Nielsen         }
16063b4e3dcbSSimon L. B. Nielsen 
16073b4e3dcbSSimon L. B. Nielsen         s_cert = load_cert(bio_err, s_cert_file, s_cert_format,
16083b4e3dcbSSimon L. B. Nielsen                            NULL, e, "server certificate file");
16093b4e3dcbSSimon L. B. Nielsen 
16106f9291ceSJung-uk Kim         if (!s_cert) {
16113b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16123b4e3dcbSSimon L. B. Nielsen             goto end;
16133b4e3dcbSSimon L. B. Nielsen         }
1614*7bded2dbSJung-uk Kim         if (s_chain_file) {
1615*7bded2dbSJung-uk Kim             s_chain = load_certs(bio_err, s_chain_file, FORMAT_PEM,
1616*7bded2dbSJung-uk Kim                                  NULL, e, "server certificate chain");
1617*7bded2dbSJung-uk Kim             if (!s_chain)
1618*7bded2dbSJung-uk Kim                 goto end;
1619*7bded2dbSJung-uk Kim         }
1620db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
16216f9291ceSJung-uk Kim         if (tlsextcbp.servername) {
1622db522d3aSSimon L. B. Nielsen             s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
1623db522d3aSSimon L. B. Nielsen                               "second server certificate private key file");
16246f9291ceSJung-uk Kim             if (!s_key2) {
1625db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1626db522d3aSSimon L. B. Nielsen                 goto end;
16273b4e3dcbSSimon L. B. Nielsen             }
16283b4e3dcbSSimon L. B. Nielsen 
1629db522d3aSSimon L. B. Nielsen             s_cert2 = load_cert(bio_err, s_cert_file2, s_cert_format,
1630db522d3aSSimon L. B. Nielsen                                 NULL, e, "second server certificate file");
1631db522d3aSSimon L. B. Nielsen 
16326f9291ceSJung-uk Kim             if (!s_cert2) {
1633db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1634db522d3aSSimon L. B. Nielsen                 goto end;
1635db522d3aSSimon L. B. Nielsen             }
1636db522d3aSSimon L. B. Nielsen         }
1637*7bded2dbSJung-uk Kim #endif                          /* OPENSSL_NO_TLSEXT */
163809286989SJung-uk Kim     }
1639*7bded2dbSJung-uk Kim #if !defined(OPENSSL_NO_TLSEXT)
1640*7bded2dbSJung-uk Kim # if !defined(OPENSSL_NO_NEXTPROTONEG)
16416f9291ceSJung-uk Kim     if (next_proto_neg_in) {
16421f13597dSJung-uk Kim         unsigned short len;
164309286989SJung-uk Kim         next_proto.data = next_protos_parse(&len, next_proto_neg_in);
16441f13597dSJung-uk Kim         if (next_proto.data == NULL)
16451f13597dSJung-uk Kim             goto end;
16461f13597dSJung-uk Kim         next_proto.len = len;
16476f9291ceSJung-uk Kim     } else {
16481f13597dSJung-uk Kim         next_proto.data = NULL;
16491f13597dSJung-uk Kim     }
16501f13597dSJung-uk Kim # endif
1651*7bded2dbSJung-uk Kim     alpn_ctx.data = NULL;
1652*7bded2dbSJung-uk Kim     if (alpn_in) {
1653*7bded2dbSJung-uk Kim         unsigned short len;
1654*7bded2dbSJung-uk Kim         alpn_ctx.data = next_protos_parse(&len, alpn_in);
1655*7bded2dbSJung-uk Kim         if (alpn_ctx.data == NULL)
1656*7bded2dbSJung-uk Kim             goto end;
1657*7bded2dbSJung-uk Kim         alpn_ctx.len = len;
1658*7bded2dbSJung-uk Kim     }
1659*7bded2dbSJung-uk Kim #endif
1660*7bded2dbSJung-uk Kim 
1661*7bded2dbSJung-uk Kim     if (crl_file) {
1662*7bded2dbSJung-uk Kim         X509_CRL *crl;
1663*7bded2dbSJung-uk Kim         crl = load_crl(crl_file, crl_format);
1664*7bded2dbSJung-uk Kim         if (!crl) {
1665*7bded2dbSJung-uk Kim             BIO_puts(bio_err, "Error loading CRL\n");
1666*7bded2dbSJung-uk Kim             ERR_print_errors(bio_err);
1667*7bded2dbSJung-uk Kim             goto end;
1668*7bded2dbSJung-uk Kim         }
1669*7bded2dbSJung-uk Kim         crls = sk_X509_CRL_new_null();
1670*7bded2dbSJung-uk Kim         if (!crls || !sk_X509_CRL_push(crls, crl)) {
1671*7bded2dbSJung-uk Kim             BIO_puts(bio_err, "Error adding CRL\n");
1672*7bded2dbSJung-uk Kim             ERR_print_errors(bio_err);
1673*7bded2dbSJung-uk Kim             X509_CRL_free(crl);
1674*7bded2dbSJung-uk Kim             goto end;
1675*7bded2dbSJung-uk Kim         }
1676*7bded2dbSJung-uk Kim     }
16771f13597dSJung-uk Kim 
16786f9291ceSJung-uk Kim     if (s_dcert_file) {
16793b4e3dcbSSimon L. B. Nielsen 
16803b4e3dcbSSimon L. B. Nielsen         if (s_dkey_file == NULL)
16813b4e3dcbSSimon L. B. Nielsen             s_dkey_file = s_dcert_file;
16823b4e3dcbSSimon L. B. Nielsen 
16833b4e3dcbSSimon L. B. Nielsen         s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
16846f9291ceSJung-uk Kim                           0, dpass, e, "second certificate private key file");
16856f9291ceSJung-uk Kim         if (!s_dkey) {
16863b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16873b4e3dcbSSimon L. B. Nielsen             goto end;
16883b4e3dcbSSimon L. B. Nielsen         }
16893b4e3dcbSSimon L. B. Nielsen 
16903b4e3dcbSSimon L. B. Nielsen         s_dcert = load_cert(bio_err, s_dcert_file, s_dcert_format,
16913b4e3dcbSSimon L. B. Nielsen                             NULL, e, "second server certificate file");
16923b4e3dcbSSimon L. B. Nielsen 
16936f9291ceSJung-uk Kim         if (!s_dcert) {
16943b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16953b4e3dcbSSimon L. B. Nielsen             goto end;
16963b4e3dcbSSimon L. B. Nielsen         }
1697*7bded2dbSJung-uk Kim         if (s_dchain_file) {
1698*7bded2dbSJung-uk Kim             s_dchain = load_certs(bio_err, s_dchain_file, FORMAT_PEM,
1699*7bded2dbSJung-uk Kim                                   NULL, e, "second server certificate chain");
1700*7bded2dbSJung-uk Kim             if (!s_dchain)
1701*7bded2dbSJung-uk Kim                 goto end;
1702*7bded2dbSJung-uk Kim         }
17033b4e3dcbSSimon L. B. Nielsen 
17043b4e3dcbSSimon L. B. Nielsen     }
17053b4e3dcbSSimon L. B. Nielsen 
17065740a5e3SKris Kennaway     if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
17076f9291ceSJung-uk Kim         && !RAND_status()) {
17086f9291ceSJung-uk Kim         BIO_printf(bio_err,
17096f9291ceSJung-uk Kim                    "warning, not much extra random data, consider using the -rand option\n");
17105740a5e3SKris Kennaway     }
17115740a5e3SKris Kennaway     if (inrand != NULL)
17125740a5e3SKris Kennaway         BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
17135740a5e3SKris Kennaway                    app_RAND_load_files(inrand));
1714f579bf8eSKris Kennaway 
17156f9291ceSJung-uk Kim     if (bio_s_out == NULL) {
1716*7bded2dbSJung-uk Kim         if (s_quiet && !s_debug) {
171774664626SKris Kennaway             bio_s_out = BIO_new(BIO_s_null());
1718*7bded2dbSJung-uk Kim             if (s_msg && !bio_s_msg)
1719*7bded2dbSJung-uk Kim                 bio_s_msg = BIO_new_fp(stdout, BIO_NOCLOSE);
17206f9291ceSJung-uk Kim         } else {
172174664626SKris Kennaway             if (bio_s_out == NULL)
172274664626SKris Kennaway                 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
172374664626SKris Kennaway         }
172474664626SKris Kennaway     }
17253b4e3dcbSSimon L. B. Nielsen #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
172674664626SKris Kennaway     if (nocert)
172774664626SKris Kennaway #endif
172874664626SKris Kennaway     {
172974664626SKris Kennaway         s_cert_file = NULL;
173074664626SKris Kennaway         s_key_file = NULL;
173174664626SKris Kennaway         s_dcert_file = NULL;
173274664626SKris Kennaway         s_dkey_file = NULL;
1733db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1734db522d3aSSimon L. B. Nielsen         s_cert_file2 = NULL;
1735db522d3aSSimon L. B. Nielsen         s_key_file2 = NULL;
1736db522d3aSSimon L. B. Nielsen #endif
173774664626SKris Kennaway     }
173874664626SKris Kennaway 
173974664626SKris Kennaway     ctx = SSL_CTX_new(meth);
17406f9291ceSJung-uk Kim     if (ctx == NULL) {
174174664626SKris Kennaway         ERR_print_errors(bio_err);
174274664626SKris Kennaway         goto end;
174374664626SKris Kennaway     }
17446f9291ceSJung-uk Kim     if (session_id_prefix) {
17455c87c606SMark Murray         if (strlen(session_id_prefix) >= 32)
17465c87c606SMark Murray             BIO_printf(bio_err,
17475c87c606SMark Murray                        "warning: id_prefix is too long, only one new session will be possible\n");
17485c87c606SMark Murray         else if (strlen(session_id_prefix) >= 16)
17495c87c606SMark Murray             BIO_printf(bio_err,
17505c87c606SMark Murray                        "warning: id_prefix is too long if you use SSLv2\n");
17516f9291ceSJung-uk Kim         if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
17525c87c606SMark Murray             BIO_printf(bio_err, "error setting 'id_prefix'\n");
17535c87c606SMark Murray             ERR_print_errors(bio_err);
17545c87c606SMark Murray             goto end;
17555c87c606SMark Murray         }
17565c87c606SMark Murray         BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
17575c87c606SMark Murray     }
175874664626SKris Kennaway     SSL_CTX_set_quiet_shutdown(ctx, 1);
17596f9291ceSJung-uk Kim     if (hack)
17606f9291ceSJung-uk Kim         SSL_CTX_set_options(ctx, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
1761*7bded2dbSJung-uk Kim     if (exc)
1762*7bded2dbSJung-uk Kim         ssl_ctx_set_excert(ctx, exc);
176374664626SKris Kennaway 
17646f9291ceSJung-uk Kim     if (state)
17656f9291ceSJung-uk Kim         SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
17666a599222SSimon L. B. Nielsen     if (no_cache)
17676a599222SSimon L. B. Nielsen         SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1768*7bded2dbSJung-uk Kim     else if (ext_cache)
1769*7bded2dbSJung-uk Kim         init_session_cache_ctx(ctx);
17706a599222SSimon L. B. Nielsen     else
177174664626SKris Kennaway         SSL_CTX_sess_set_cache_size(ctx, 128);
177274664626SKris Kennaway 
177309286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
17741f13597dSJung-uk Kim     if (srtp_profiles != NULL)
17751f13597dSJung-uk Kim         SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
177609286989SJung-uk Kim #endif
17771f13597dSJung-uk Kim 
177874664626SKris Kennaway #if 0
17796f9291ceSJung-uk Kim     if (cipher == NULL)
17806f9291ceSJung-uk Kim         cipher = getenv("SSL_CIPHER");
178174664626SKris Kennaway #endif
178274664626SKris Kennaway 
178374664626SKris Kennaway #if 0
17846f9291ceSJung-uk Kim     if (s_cert_file == NULL) {
17856f9291ceSJung-uk Kim         BIO_printf(bio_err,
17866f9291ceSJung-uk Kim                    "You must specify a certificate file for the server to use\n");
178774664626SKris Kennaway         goto end;
178874664626SKris Kennaway     }
178974664626SKris Kennaway #endif
179074664626SKris Kennaway 
179174664626SKris Kennaway     if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) ||
17926f9291ceSJung-uk Kim         (!SSL_CTX_set_default_verify_paths(ctx))) {
179374664626SKris Kennaway         /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
179474664626SKris Kennaway         ERR_print_errors(bio_err);
179574664626SKris Kennaway         /* goto end; */
179674664626SKris Kennaway     }
17971f13597dSJung-uk Kim     if (vpm)
17981f13597dSJung-uk Kim         SSL_CTX_set1_param(ctx, vpm);
17991f13597dSJung-uk Kim 
1800*7bded2dbSJung-uk Kim     ssl_ctx_add_crls(ctx, crls, 0);
1801*7bded2dbSJung-uk Kim 
1802*7bded2dbSJung-uk Kim     if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe, no_jpake))
1803*7bded2dbSJung-uk Kim         goto end;
1804*7bded2dbSJung-uk Kim 
1805*7bded2dbSJung-uk Kim     if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
1806*7bded2dbSJung-uk Kim                          crls, crl_download)) {
1807*7bded2dbSJung-uk Kim         BIO_printf(bio_err, "Error loading store locations\n");
1808*7bded2dbSJung-uk Kim         ERR_print_errors(bio_err);
1809*7bded2dbSJung-uk Kim         goto end;
1810*7bded2dbSJung-uk Kim     }
1811db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
18126f9291ceSJung-uk Kim     if (s_cert2) {
1813db522d3aSSimon L. B. Nielsen         ctx2 = SSL_CTX_new(meth);
18146f9291ceSJung-uk Kim         if (ctx2 == NULL) {
1815db522d3aSSimon L. B. Nielsen             ERR_print_errors(bio_err);
1816db522d3aSSimon L. B. Nielsen             goto end;
1817db522d3aSSimon L. B. Nielsen         }
1818db522d3aSSimon L. B. Nielsen     }
1819db522d3aSSimon L. B. Nielsen 
18206f9291ceSJung-uk Kim     if (ctx2) {
1821db522d3aSSimon L. B. Nielsen         BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
1822db522d3aSSimon L. B. Nielsen 
18236f9291ceSJung-uk Kim         if (session_id_prefix) {
1824db522d3aSSimon L. B. Nielsen             if (strlen(session_id_prefix) >= 32)
1825db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err,
1826db522d3aSSimon L. B. Nielsen                            "warning: id_prefix is too long, only one new session will be possible\n");
1827db522d3aSSimon L. B. Nielsen             else if (strlen(session_id_prefix) >= 16)
1828db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err,
1829db522d3aSSimon L. B. Nielsen                            "warning: id_prefix is too long if you use SSLv2\n");
18306f9291ceSJung-uk Kim             if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) {
1831db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err, "error setting 'id_prefix'\n");
1832db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1833db522d3aSSimon L. B. Nielsen                 goto end;
1834db522d3aSSimon L. B. Nielsen             }
1835db522d3aSSimon L. B. Nielsen             BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
1836db522d3aSSimon L. B. Nielsen         }
1837db522d3aSSimon L. B. Nielsen         SSL_CTX_set_quiet_shutdown(ctx2, 1);
18386f9291ceSJung-uk Kim         if (hack)
18396f9291ceSJung-uk Kim             SSL_CTX_set_options(ctx2, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
1840*7bded2dbSJung-uk Kim         if (exc)
1841*7bded2dbSJung-uk Kim             ssl_ctx_set_excert(ctx2, exc);
1842db522d3aSSimon L. B. Nielsen 
18436f9291ceSJung-uk Kim         if (state)
18446f9291ceSJung-uk Kim             SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
1845db522d3aSSimon L. B. Nielsen 
18466a599222SSimon L. B. Nielsen         if (no_cache)
18476a599222SSimon L. B. Nielsen             SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
1848*7bded2dbSJung-uk Kim         else if (ext_cache)
1849*7bded2dbSJung-uk Kim             init_session_cache_ctx(ctx2);
18506a599222SSimon L. B. Nielsen         else
1851db522d3aSSimon L. B. Nielsen             SSL_CTX_sess_set_cache_size(ctx2, 128);
1852db522d3aSSimon L. B. Nielsen 
1853db522d3aSSimon L. B. Nielsen         if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) ||
18546f9291ceSJung-uk Kim             (!SSL_CTX_set_default_verify_paths(ctx2))) {
1855db522d3aSSimon L. B. Nielsen             ERR_print_errors(bio_err);
1856db522d3aSSimon L. B. Nielsen         }
18571f13597dSJung-uk Kim         if (vpm)
18581f13597dSJung-uk Kim             SSL_CTX_set1_param(ctx2, vpm);
1859*7bded2dbSJung-uk Kim 
1860*7bded2dbSJung-uk Kim         ssl_ctx_add_crls(ctx2, crls, 0);
1861*7bded2dbSJung-uk Kim 
1862*7bded2dbSJung-uk Kim         if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe, no_jpake))
1863*7bded2dbSJung-uk Kim             goto end;
1864*7bded2dbSJung-uk Kim 
1865db522d3aSSimon L. B. Nielsen     }
18661f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
18671f13597dSJung-uk Kim     if (next_proto.data)
18686f9291ceSJung-uk Kim         SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb,
18696f9291ceSJung-uk Kim                                               &next_proto);
18701f13597dSJung-uk Kim # endif
1871*7bded2dbSJung-uk Kim     if (alpn_ctx.data)
1872*7bded2dbSJung-uk Kim         SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
18731f13597dSJung-uk Kim #endif
187474664626SKris Kennaway 
18755c87c606SMark Murray #ifndef OPENSSL_NO_DH
18766f9291ceSJung-uk Kim     if (!no_dhe) {
18775c87c606SMark Murray         DH *dh = NULL;
18785c87c606SMark Murray 
18795c87c606SMark Murray         if (dhfile)
18805c87c606SMark Murray             dh = load_dh_param(dhfile);
18815c87c606SMark Murray         else if (s_cert_file)
18825c87c606SMark Murray             dh = load_dh_param(s_cert_file);
18835c87c606SMark Murray 
18846f9291ceSJung-uk Kim         if (dh != NULL) {
188574664626SKris Kennaway             BIO_printf(bio_s_out, "Setting temp DH parameters\n");
18866f9291ceSJung-uk Kim         } else {
188774664626SKris Kennaway             BIO_printf(bio_s_out, "Using default temp DH parameters\n");
1888ed6b93beSJung-uk Kim             dh = get_dh2048();
1889ed6b93beSJung-uk Kim             if (dh == NULL) {
1890ed6b93beSJung-uk Kim                 ERR_print_errors(bio_err);
1891ed6b93beSJung-uk Kim                 goto end;
1892ed6b93beSJung-uk Kim             }
189374664626SKris Kennaway         }
189474664626SKris Kennaway         (void)BIO_flush(bio_s_out);
189574664626SKris Kennaway 
189674664626SKris Kennaway         SSL_CTX_set_tmp_dh(ctx, dh);
1897db522d3aSSimon L. B. Nielsen # ifndef OPENSSL_NO_TLSEXT
18986f9291ceSJung-uk Kim         if (ctx2) {
18996f9291ceSJung-uk Kim             if (!dhfile) {
1900db522d3aSSimon L. B. Nielsen                 DH *dh2 = load_dh_param(s_cert_file2);
19016f9291ceSJung-uk Kim                 if (dh2 != NULL) {
1902db522d3aSSimon L. B. Nielsen                     BIO_printf(bio_s_out, "Setting temp DH parameters\n");
1903db522d3aSSimon L. B. Nielsen                     (void)BIO_flush(bio_s_out);
1904db522d3aSSimon L. B. Nielsen 
1905db522d3aSSimon L. B. Nielsen                     DH_free(dh);
1906db522d3aSSimon L. B. Nielsen                     dh = dh2;
1907db522d3aSSimon L. B. Nielsen                 }
1908db522d3aSSimon L. B. Nielsen             }
1909db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tmp_dh(ctx2, dh);
1910db522d3aSSimon L. B. Nielsen         }
1911db522d3aSSimon L. B. Nielsen # endif
191274664626SKris Kennaway         DH_free(dh);
191374664626SKris Kennaway     }
191474664626SKris Kennaway #endif
191574664626SKris Kennaway 
1916*7bded2dbSJung-uk Kim     if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
19173b4e3dcbSSimon L. B. Nielsen         goto end;
1918db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1919*7bded2dbSJung-uk Kim     if (s_serverinfo_file != NULL
1920*7bded2dbSJung-uk Kim         && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) {
1921*7bded2dbSJung-uk Kim         ERR_print_errors(bio_err);
1922*7bded2dbSJung-uk Kim         goto end;
1923*7bded2dbSJung-uk Kim     }
1924*7bded2dbSJung-uk Kim #endif
1925*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
1926*7bded2dbSJung-uk Kim     if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain))
1927db522d3aSSimon L. B. Nielsen         goto end;
1928db522d3aSSimon L. B. Nielsen #endif
19296f9291ceSJung-uk Kim     if (s_dcert != NULL) {
1930*7bded2dbSJung-uk Kim         if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain))
193174664626SKris Kennaway             goto end;
193274664626SKris Kennaway     }
19335c87c606SMark Murray #ifndef OPENSSL_NO_RSA
193474664626SKris Kennaway # if 1
19356f9291ceSJung-uk Kim     if (!no_tmp_rsa) {
193674664626SKris Kennaway         SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
1937db522d3aSSimon L. B. Nielsen #  ifndef OPENSSL_NO_TLSEXT
1938db522d3aSSimon L. B. Nielsen         if (ctx2)
1939db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tmp_rsa_callback(ctx2, tmp_rsa_cb);
1940db522d3aSSimon L. B. Nielsen #  endif
1941db522d3aSSimon L. B. Nielsen     }
194274664626SKris Kennaway # else
19436f9291ceSJung-uk Kim     if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) {
194474664626SKris Kennaway         RSA *rsa;
194574664626SKris Kennaway 
194674664626SKris Kennaway         BIO_printf(bio_s_out, "Generating temp (512 bit) RSA key...");
194774664626SKris Kennaway         BIO_flush(bio_s_out);
194874664626SKris Kennaway 
194974664626SKris Kennaway         rsa = RSA_generate_key(512, RSA_F4, NULL);
195074664626SKris Kennaway 
19516f9291ceSJung-uk Kim         if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
195274664626SKris Kennaway             ERR_print_errors(bio_err);
195374664626SKris Kennaway             goto end;
195474664626SKris Kennaway         }
1955db522d3aSSimon L. B. Nielsen #  ifndef OPENSSL_NO_TLSEXT
19566f9291ceSJung-uk Kim         if (ctx2) {
19576f9291ceSJung-uk Kim             if (!SSL_CTX_set_tmp_rsa(ctx2, rsa)) {
1958db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1959db522d3aSSimon L. B. Nielsen                 goto end;
1960db522d3aSSimon L. B. Nielsen             }
1961db522d3aSSimon L. B. Nielsen         }
1962db522d3aSSimon L. B. Nielsen #  endif
196374664626SKris Kennaway         RSA_free(rsa);
196474664626SKris Kennaway         BIO_printf(bio_s_out, "\n");
196574664626SKris Kennaway     }
196674664626SKris Kennaway # endif
196774664626SKris Kennaway #endif
196874664626SKris Kennaway 
19691f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK
19701f13597dSJung-uk Kim # ifdef OPENSSL_NO_JPAKE
19711f13597dSJung-uk Kim     if (psk_key != NULL)
19721f13597dSJung-uk Kim # else
19731f13597dSJung-uk Kim     if (psk_key != NULL || jpake_secret)
19741f13597dSJung-uk Kim # endif
19751f13597dSJung-uk Kim     {
19761f13597dSJung-uk Kim         if (s_debug)
19776f9291ceSJung-uk Kim             BIO_printf(bio_s_out,
19786f9291ceSJung-uk Kim                        "PSK key given or JPAKE in use, setting server callback\n");
19791f13597dSJung-uk Kim         SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
19801f13597dSJung-uk Kim     }
19811f13597dSJung-uk Kim 
19826f9291ceSJung-uk Kim     if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
19831f13597dSJung-uk Kim         BIO_printf(bio_err, "error setting PSK identity hint to context\n");
19841f13597dSJung-uk Kim         ERR_print_errors(bio_err);
19851f13597dSJung-uk Kim         goto end;
19861f13597dSJung-uk Kim     }
19871f13597dSJung-uk Kim #endif
19881f13597dSJung-uk Kim 
198974664626SKris Kennaway     SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
199074664626SKris Kennaway     SSL_CTX_set_session_id_context(ctx, (void *)&s_server_session_id_context,
199174664626SKris Kennaway                                    sizeof s_server_session_id_context);
199274664626SKris Kennaway 
19936a599222SSimon L. B. Nielsen     /* Set DTLS cookie generation and verification callbacks */
19946a599222SSimon L. B. Nielsen     SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
19956a599222SSimon L. B. Nielsen     SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
19966a599222SSimon L. B. Nielsen 
1997db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
19986f9291ceSJung-uk Kim     if (ctx2) {
1999db522d3aSSimon L. B. Nielsen         SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
20006f9291ceSJung-uk Kim         SSL_CTX_set_session_id_context(ctx2,
20016f9291ceSJung-uk Kim                                        (void *)&s_server_session_id_context,
2002db522d3aSSimon L. B. Nielsen                                        sizeof s_server_session_id_context);
200374664626SKris Kennaway 
2004db522d3aSSimon L. B. Nielsen         tlsextcbp.biodebug = bio_s_out;
2005db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
2006db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
2007db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
2008db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
2009db522d3aSSimon L. B. Nielsen     }
2010db522d3aSSimon L. B. Nielsen #endif
20111f13597dSJung-uk Kim 
20121f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
20136f9291ceSJung-uk Kim     if (srp_verifier_file != NULL) {
20141f13597dSJung-uk Kim         srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
20151f13597dSJung-uk Kim         srp_callback_parm.user = NULL;
20161f13597dSJung-uk Kim         srp_callback_parm.login = NULL;
20176f9291ceSJung-uk Kim         if ((ret =
20186f9291ceSJung-uk Kim              SRP_VBASE_init(srp_callback_parm.vb,
20196f9291ceSJung-uk Kim                             srp_verifier_file)) != SRP_NO_ERROR) {
20201f13597dSJung-uk Kim             BIO_printf(bio_err,
20211f13597dSJung-uk Kim                        "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
20221f13597dSJung-uk Kim                        srp_verifier_file, ret);
20231f13597dSJung-uk Kim             goto end;
20241f13597dSJung-uk Kim         }
20251f13597dSJung-uk Kim         SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
20261f13597dSJung-uk Kim         SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
20271f13597dSJung-uk Kim         SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
20286f9291ceSJung-uk Kim     } else
20291f13597dSJung-uk Kim #endif
20306f9291ceSJung-uk Kim     if (CAfile != NULL) {
2031db522d3aSSimon L. B. Nielsen         SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile));
2032db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
2033db522d3aSSimon L. B. Nielsen         if (ctx2)
2034db522d3aSSimon L. B. Nielsen             SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile));
2035db522d3aSSimon L. B. Nielsen #endif
2036db522d3aSSimon L. B. Nielsen     }
20371f13597dSJung-uk Kim 
203874664626SKris Kennaway     BIO_printf(bio_s_out, "ACCEPT\n");
20391f13597dSJung-uk Kim     (void)BIO_flush(bio_s_out);
2040*7bded2dbSJung-uk Kim     if (rev)
2041*7bded2dbSJung-uk Kim         do_server(port, socket_type, &accept_socket, rev_body, context,
2042*7bded2dbSJung-uk Kim                   naccept);
2043*7bded2dbSJung-uk Kim     else if (www)
2044*7bded2dbSJung-uk Kim         do_server(port, socket_type, &accept_socket, www_body, context,
2045*7bded2dbSJung-uk Kim                   naccept);
204674664626SKris Kennaway     else
2047*7bded2dbSJung-uk Kim         do_server(port, socket_type, &accept_socket, sv_body, context,
2048*7bded2dbSJung-uk Kim                   naccept);
204974664626SKris Kennaway     print_stats(bio_s_out, ctx);
205074664626SKris Kennaway     ret = 0;
205174664626SKris Kennaway  end:
20526f9291ceSJung-uk Kim     if (ctx != NULL)
20536f9291ceSJung-uk Kim         SSL_CTX_free(ctx);
20543b4e3dcbSSimon L. B. Nielsen     if (s_cert)
20553b4e3dcbSSimon L. B. Nielsen         X509_free(s_cert);
2056*7bded2dbSJung-uk Kim     if (crls)
2057*7bded2dbSJung-uk Kim         sk_X509_CRL_pop_free(crls, X509_CRL_free);
20583b4e3dcbSSimon L. B. Nielsen     if (s_dcert)
20593b4e3dcbSSimon L. B. Nielsen         X509_free(s_dcert);
20603b4e3dcbSSimon L. B. Nielsen     if (s_key)
20613b4e3dcbSSimon L. B. Nielsen         EVP_PKEY_free(s_key);
20623b4e3dcbSSimon L. B. Nielsen     if (s_dkey)
20633b4e3dcbSSimon L. B. Nielsen         EVP_PKEY_free(s_dkey);
2064*7bded2dbSJung-uk Kim     if (s_chain)
2065*7bded2dbSJung-uk Kim         sk_X509_pop_free(s_chain, X509_free);
2066*7bded2dbSJung-uk Kim     if (s_dchain)
2067*7bded2dbSJung-uk Kim         sk_X509_pop_free(s_dchain, X509_free);
20683b4e3dcbSSimon L. B. Nielsen     if (pass)
20693b4e3dcbSSimon L. B. Nielsen         OPENSSL_free(pass);
20703b4e3dcbSSimon L. B. Nielsen     if (dpass)
20713b4e3dcbSSimon L. B. Nielsen         OPENSSL_free(dpass);
207209286989SJung-uk Kim     if (vpm)
207309286989SJung-uk Kim         X509_VERIFY_PARAM_free(vpm);
2074*7bded2dbSJung-uk Kim     free_sessions();
2075db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
207609286989SJung-uk Kim     if (tlscstatp.host)
207709286989SJung-uk Kim         OPENSSL_free(tlscstatp.host);
207809286989SJung-uk Kim     if (tlscstatp.port)
207909286989SJung-uk Kim         OPENSSL_free(tlscstatp.port);
208009286989SJung-uk Kim     if (tlscstatp.path)
208109286989SJung-uk Kim         OPENSSL_free(tlscstatp.path);
20826f9291ceSJung-uk Kim     if (ctx2 != NULL)
20836f9291ceSJung-uk Kim         SSL_CTX_free(ctx2);
2084db522d3aSSimon L. B. Nielsen     if (s_cert2)
2085db522d3aSSimon L. B. Nielsen         X509_free(s_cert2);
2086db522d3aSSimon L. B. Nielsen     if (s_key2)
2087db522d3aSSimon L. B. Nielsen         EVP_PKEY_free(s_key2);
2088*7bded2dbSJung-uk Kim     if (serverinfo_in != NULL)
2089*7bded2dbSJung-uk Kim         BIO_free(serverinfo_in);
2090*7bded2dbSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
2091*7bded2dbSJung-uk Kim     if (next_proto.data)
2092*7bded2dbSJung-uk Kim         OPENSSL_free(next_proto.data);
2093*7bded2dbSJung-uk Kim # endif
2094*7bded2dbSJung-uk Kim     if (alpn_ctx.data)
2095*7bded2dbSJung-uk Kim         OPENSSL_free(alpn_ctx.data);
2096*7bded2dbSJung-uk Kim #endif
2097*7bded2dbSJung-uk Kim     ssl_excert_free(exc);
2098*7bded2dbSJung-uk Kim     if (ssl_args)
2099*7bded2dbSJung-uk Kim         sk_OPENSSL_STRING_free(ssl_args);
2100*7bded2dbSJung-uk Kim     if (cctx)
2101*7bded2dbSJung-uk Kim         SSL_CONF_CTX_free(cctx);
2102*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_JPAKE
2103*7bded2dbSJung-uk Kim     if (jpake_secret && psk_key)
2104*7bded2dbSJung-uk Kim         OPENSSL_free(psk_key);
2105db522d3aSSimon L. B. Nielsen #endif
21066f9291ceSJung-uk Kim     if (bio_s_out != NULL) {
210774664626SKris Kennaway         BIO_free(bio_s_out);
210874664626SKris Kennaway         bio_s_out = NULL;
210974664626SKris Kennaway     }
2110*7bded2dbSJung-uk Kim     if (bio_s_msg != NULL) {
2111*7bded2dbSJung-uk Kim         BIO_free(bio_s_msg);
2112*7bded2dbSJung-uk Kim         bio_s_msg = NULL;
2113*7bded2dbSJung-uk Kim     }
21145c87c606SMark Murray     apps_shutdown();
21155c87c606SMark Murray     OPENSSL_EXIT(ret);
211674664626SKris Kennaway }
211774664626SKris Kennaway 
211874664626SKris Kennaway static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
211974664626SKris Kennaway {
212074664626SKris Kennaway     BIO_printf(bio, "%4ld items in the session cache\n",
212174664626SKris Kennaway                SSL_CTX_sess_number(ssl_ctx));
21223b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
212374664626SKris Kennaway                SSL_CTX_sess_connect(ssl_ctx));
21243b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
212574664626SKris Kennaway                SSL_CTX_sess_connect_renegotiate(ssl_ctx));
21263b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld client connects that finished\n",
212774664626SKris Kennaway                SSL_CTX_sess_connect_good(ssl_ctx));
21283b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
212974664626SKris Kennaway                SSL_CTX_sess_accept(ssl_ctx));
21303b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
213174664626SKris Kennaway                SSL_CTX_sess_accept_renegotiate(ssl_ctx));
21323b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld server accepts that finished\n",
213374664626SKris Kennaway                SSL_CTX_sess_accept_good(ssl_ctx));
21343b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx));
21356f9291ceSJung-uk Kim     BIO_printf(bio, "%4ld session cache misses\n",
21366f9291ceSJung-uk Kim                SSL_CTX_sess_misses(ssl_ctx));
21376f9291ceSJung-uk Kim     BIO_printf(bio, "%4ld session cache timeouts\n",
21386f9291ceSJung-uk Kim                SSL_CTX_sess_timeouts(ssl_ctx));
21396f9291ceSJung-uk Kim     BIO_printf(bio, "%4ld callback cache hits\n",
21406f9291ceSJung-uk Kim                SSL_CTX_sess_cb_hits(ssl_ctx));
21413b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
214274664626SKris Kennaway                SSL_CTX_sess_cache_full(ssl_ctx),
214374664626SKris Kennaway                SSL_CTX_sess_get_cache_size(ssl_ctx));
214474664626SKris Kennaway }
214574664626SKris Kennaway 
2146*7bded2dbSJung-uk Kim static int sv_body(char *hostname, int s, int stype, unsigned char *context)
214774664626SKris Kennaway {
214874664626SKris Kennaway     char *buf = NULL;
214974664626SKris Kennaway     fd_set readfds;
215074664626SKris Kennaway     int ret = 1, width;
215174664626SKris Kennaway     int k, i;
215274664626SKris Kennaway     unsigned long l;
215374664626SKris Kennaway     SSL *con = NULL;
215474664626SKris Kennaway     BIO *sbio;
21551f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
21561f13597dSJung-uk Kim     KSSL_CTX *kctx;
21571f13597dSJung-uk Kim #endif
21586a599222SSimon L. B. Nielsen     struct timeval timeout;
21591f13597dSJung-uk Kim #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
2160f579bf8eSKris Kennaway     struct timeval tv;
21616a599222SSimon L. B. Nielsen #else
21626a599222SSimon L. B. Nielsen     struct timeval *timeoutp;
2163f579bf8eSKris Kennaway #endif
216474664626SKris Kennaway 
21656f9291ceSJung-uk Kim     if ((buf = OPENSSL_malloc(bufsize)) == NULL) {
216674664626SKris Kennaway         BIO_printf(bio_err, "out of memory\n");
216774664626SKris Kennaway         goto err;
216874664626SKris Kennaway     }
216974664626SKris Kennaway #ifdef FIONBIO
21706f9291ceSJung-uk Kim     if (s_nbio) {
217174664626SKris Kennaway         unsigned long sl = 1;
217274664626SKris Kennaway 
217374664626SKris Kennaway         if (!s_quiet)
217474664626SKris Kennaway             BIO_printf(bio_err, "turning on non blocking io\n");
217574664626SKris Kennaway         if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0)
217674664626SKris Kennaway             ERR_print_errors(bio_err);
217774664626SKris Kennaway     }
217874664626SKris Kennaway #endif
217974664626SKris Kennaway 
218074664626SKris Kennaway     if (con == NULL) {
2181f579bf8eSKris Kennaway         con = SSL_new(ctx);
2182db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
21836f9291ceSJung-uk Kim         if (s_tlsextdebug) {
2184db522d3aSSimon L. B. Nielsen             SSL_set_tlsext_debug_callback(con, tlsext_cb);
2185db522d3aSSimon L. B. Nielsen             SSL_set_tlsext_debug_arg(con, bio_s_out);
2186db522d3aSSimon L. B. Nielsen         }
21876f9291ceSJung-uk Kim         if (s_tlsextstatus) {
2188db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
2189db522d3aSSimon L. B. Nielsen             tlscstatp.err = bio_err;
2190db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
2191db522d3aSSimon L. B. Nielsen         }
2192db522d3aSSimon L. B. Nielsen #endif
21935c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
21946f9291ceSJung-uk Kim         if ((kctx = kssl_ctx_new()) != NULL) {
21951f13597dSJung-uk Kim             SSL_set0_kssl_ctx(con, kctx);
21961f13597dSJung-uk Kim             kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
21971f13597dSJung-uk Kim             kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
21985c87c606SMark Murray         }
21995c87c606SMark Murray #endif                          /* OPENSSL_NO_KRB5 */
220074664626SKris Kennaway         if (context)
22016f9291ceSJung-uk Kim             SSL_set_session_id_context(con, context, strlen((char *)context));
220274664626SKris Kennaway     }
220374664626SKris Kennaway     SSL_clear(con);
22041f13597dSJung-uk Kim #if 0
22051f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
22061f13597dSJung-uk Kim     SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
22071f13597dSJung-uk Kim # endif
22081f13597dSJung-uk Kim #endif
220974664626SKris Kennaway 
2210*7bded2dbSJung-uk Kim     if (stype == SOCK_DGRAM) {
22113b4e3dcbSSimon L. B. Nielsen 
22123b4e3dcbSSimon L. B. Nielsen         sbio = BIO_new_dgram(s, BIO_NOCLOSE);
22133b4e3dcbSSimon L. B. Nielsen 
22146f9291ceSJung-uk Kim         if (enable_timeouts) {
22153b4e3dcbSSimon L. B. Nielsen             timeout.tv_sec = 0;
22163b4e3dcbSSimon L. B. Nielsen             timeout.tv_usec = DGRAM_RCV_TIMEOUT;
22173b4e3dcbSSimon L. B. Nielsen             BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
22183b4e3dcbSSimon L. B. Nielsen 
22193b4e3dcbSSimon L. B. Nielsen             timeout.tv_sec = 0;
22203b4e3dcbSSimon L. B. Nielsen             timeout.tv_usec = DGRAM_SND_TIMEOUT;
22213b4e3dcbSSimon L. B. Nielsen             BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
22223b4e3dcbSSimon L. B. Nielsen         }
22233b4e3dcbSSimon L. B. Nielsen 
22246f9291ceSJung-uk Kim         if (socket_mtu) {
22256f9291ceSJung-uk Kim             if (socket_mtu < DTLS_get_link_min_mtu(con)) {
2226751d2991SJung-uk Kim                 BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
2227751d2991SJung-uk Kim                            DTLS_get_link_min_mtu(con));
2228751d2991SJung-uk Kim                 ret = -1;
2229751d2991SJung-uk Kim                 BIO_free(sbio);
2230751d2991SJung-uk Kim                 goto err;
2231751d2991SJung-uk Kim             }
22323b4e3dcbSSimon L. B. Nielsen             SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
22336f9291ceSJung-uk Kim             if (!DTLS_set_link_mtu(con, socket_mtu)) {
2234751d2991SJung-uk Kim                 BIO_printf(bio_err, "Failed to set MTU\n");
2235751d2991SJung-uk Kim                 ret = -1;
2236751d2991SJung-uk Kim                 BIO_free(sbio);
2237751d2991SJung-uk Kim                 goto err;
2238751d2991SJung-uk Kim             }
22396f9291ceSJung-uk Kim         } else
22403b4e3dcbSSimon L. B. Nielsen             /* want to do MTU discovery */
22413b4e3dcbSSimon L. B. Nielsen             BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
22423b4e3dcbSSimon L. B. Nielsen 
22433b4e3dcbSSimon L. B. Nielsen         /* turn on cookie exchange */
22443b4e3dcbSSimon L. B. Nielsen         SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
22456f9291ceSJung-uk Kim     } else
224674664626SKris Kennaway         sbio = BIO_new_socket(s, BIO_NOCLOSE);
22473b4e3dcbSSimon L. B. Nielsen 
22486f9291ceSJung-uk Kim     if (s_nbio_test) {
224974664626SKris Kennaway         BIO *test;
225074664626SKris Kennaway 
225174664626SKris Kennaway         test = BIO_new(BIO_f_nbio_test());
225274664626SKris Kennaway         sbio = BIO_push(test, sbio);
225374664626SKris Kennaway     }
2254db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
2255db522d3aSSimon L. B. Nielsen     if (jpake_secret)
2256db522d3aSSimon L. B. Nielsen         jpake_server_auth(bio_s_out, sbio, jpake_secret);
2257db522d3aSSimon L. B. Nielsen #endif
2258db522d3aSSimon L. B. Nielsen 
225974664626SKris Kennaway     SSL_set_bio(con, sbio, sbio);
226074664626SKris Kennaway     SSL_set_accept_state(con);
226174664626SKris Kennaway     /* SSL_set_fd(con,s); */
226274664626SKris Kennaway 
22636f9291ceSJung-uk Kim     if (s_debug) {
22641f13597dSJung-uk Kim         SSL_set_debug(con, 1);
22653b4e3dcbSSimon L. B. Nielsen         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
22665471f83eSSimon L. B. Nielsen         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
226774664626SKris Kennaway     }
22686f9291ceSJung-uk Kim     if (s_msg) {
2269*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
2270*7bded2dbSJung-uk Kim         if (s_msg == 2)
2271*7bded2dbSJung-uk Kim             SSL_set_msg_callback(con, SSL_trace);
2272*7bded2dbSJung-uk Kim         else
2273*7bded2dbSJung-uk Kim #endif
22745c87c606SMark Murray             SSL_set_msg_callback(con, msg_cb);
2275*7bded2dbSJung-uk Kim         SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
22765c87c606SMark Murray     }
2277db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
22786f9291ceSJung-uk Kim     if (s_tlsextdebug) {
2279db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_callback(con, tlsext_cb);
2280db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_arg(con, bio_s_out);
2281db522d3aSSimon L. B. Nielsen     }
2282db522d3aSSimon L. B. Nielsen #endif
228374664626SKris Kennaway 
228474664626SKris Kennaway     width = s + 1;
22856f9291ceSJung-uk Kim     for (;;) {
2286f579bf8eSKris Kennaway         int read_from_terminal;
2287f579bf8eSKris Kennaway         int read_from_sslcon;
2288f579bf8eSKris Kennaway 
2289f579bf8eSKris Kennaway         read_from_terminal = 0;
2290f579bf8eSKris Kennaway         read_from_sslcon = SSL_pending(con);
2291f579bf8eSKris Kennaway 
22926f9291ceSJung-uk Kim         if (!read_from_sslcon) {
229374664626SKris Kennaway             FD_ZERO(&readfds);
22941f13597dSJung-uk Kim #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
22951f13597dSJung-uk Kim             openssl_fdset(fileno(stdin), &readfds);
229674664626SKris Kennaway #endif
22971f13597dSJung-uk Kim             openssl_fdset(s, &readfds);
22986f9291ceSJung-uk Kim             /*
22996f9291ceSJung-uk Kim              * Note: under VMS with SOCKETSHR the second parameter is
23006f9291ceSJung-uk Kim              * currently of type (int *) whereas under other systems it is
23016f9291ceSJung-uk Kim              * (void *) if you don't have a cast it will choke the compiler:
23026f9291ceSJung-uk Kim              * if you do have a cast then you can either go for (int *) or
23036f9291ceSJung-uk Kim              * (void *).
230474664626SKris Kennaway              */
23053b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
23066f9291ceSJung-uk Kim             /*
23076f9291ceSJung-uk Kim              * Under DOS (non-djgpp) and Windows we can't select on stdin:
23086f9291ceSJung-uk Kim              * only on sockets. As a workaround we timeout the select every
2309f579bf8eSKris Kennaway              * second and check for any keypress. In a proper Windows
2310f579bf8eSKris Kennaway              * application we wouldn't do this because it is inefficient.
2311f579bf8eSKris Kennaway              */
2312f579bf8eSKris Kennaway             tv.tv_sec = 1;
2313f579bf8eSKris Kennaway             tv.tv_usec = 0;
2314f579bf8eSKris Kennaway             i = select(width, (void *)&readfds, NULL, NULL, &tv);
23156f9291ceSJung-uk Kim             if ((i < 0) || (!i && !_kbhit()))
23166f9291ceSJung-uk Kim                 continue;
2317f579bf8eSKris Kennaway             if (_kbhit())
2318f579bf8eSKris Kennaway                 read_from_terminal = 1;
23191f13597dSJung-uk Kim #elif defined(OPENSSL_SYS_BEOS_R5)
23201f13597dSJung-uk Kim             /* Under BeOS-R5 the situation is similar to DOS */
23211f13597dSJung-uk Kim             tv.tv_sec = 1;
23221f13597dSJung-uk Kim             tv.tv_usec = 0;
23231f13597dSJung-uk Kim             (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
23241f13597dSJung-uk Kim             i = select(width, (void *)&readfds, NULL, NULL, &tv);
23251f13597dSJung-uk Kim             if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
23261f13597dSJung-uk Kim                 continue;
23271f13597dSJung-uk Kim             if (read(fileno(stdin), buf, 0) >= 0)
23281f13597dSJung-uk Kim                 read_from_terminal = 1;
23291f13597dSJung-uk Kim             (void)fcntl(fileno(stdin), F_SETFL, 0);
2330f579bf8eSKris Kennaway #else
23316a599222SSimon L. B. Nielsen             if ((SSL_version(con) == DTLS1_VERSION) &&
23326a599222SSimon L. B. Nielsen                 DTLSv1_get_timeout(con, &timeout))
23336a599222SSimon L. B. Nielsen                 timeoutp = &timeout;
23346a599222SSimon L. B. Nielsen             else
23356a599222SSimon L. B. Nielsen                 timeoutp = NULL;
23366a599222SSimon L. B. Nielsen 
23376a599222SSimon L. B. Nielsen             i = select(width, (void *)&readfds, NULL, NULL, timeoutp);
23386a599222SSimon L. B. Nielsen 
23396f9291ceSJung-uk Kim             if ((SSL_version(con) == DTLS1_VERSION)
23406f9291ceSJung-uk Kim                 && DTLSv1_handle_timeout(con) > 0) {
23416a599222SSimon L. B. Nielsen                 BIO_printf(bio_err, "TIMEOUT occured\n");
23426a599222SSimon L. B. Nielsen             }
23436a599222SSimon L. B. Nielsen 
23446f9291ceSJung-uk Kim             if (i <= 0)
23456f9291ceSJung-uk Kim                 continue;
234674664626SKris Kennaway             if (FD_ISSET(fileno(stdin), &readfds))
2347f579bf8eSKris Kennaway                 read_from_terminal = 1;
2348f579bf8eSKris Kennaway #endif
2349f579bf8eSKris Kennaway             if (FD_ISSET(s, &readfds))
2350f579bf8eSKris Kennaway                 read_from_sslcon = 1;
2351f579bf8eSKris Kennaway         }
23526f9291ceSJung-uk Kim         if (read_from_terminal) {
23536f9291ceSJung-uk Kim             if (s_crlf) {
235474664626SKris Kennaway                 int j, lf_num;
235574664626SKris Kennaway 
23561f13597dSJung-uk Kim                 i = raw_read_stdin(buf, bufsize / 2);
235774664626SKris Kennaway                 lf_num = 0;
235874664626SKris Kennaway                 /* both loops are skipped when i <= 0 */
235974664626SKris Kennaway                 for (j = 0; j < i; j++)
236074664626SKris Kennaway                     if (buf[j] == '\n')
236174664626SKris Kennaway                         lf_num++;
23626f9291ceSJung-uk Kim                 for (j = i - 1; j >= 0; j--) {
236374664626SKris Kennaway                     buf[j + lf_num] = buf[j];
23646f9291ceSJung-uk Kim                     if (buf[j] == '\n') {
236574664626SKris Kennaway                         lf_num--;
236674664626SKris Kennaway                         i++;
236774664626SKris Kennaway                         buf[j + lf_num] = '\r';
236874664626SKris Kennaway                     }
236974664626SKris Kennaway                 }
237074664626SKris Kennaway                 assert(lf_num == 0);
23716f9291ceSJung-uk Kim             } else
23721f13597dSJung-uk Kim                 i = raw_read_stdin(buf, bufsize);
2373*7bded2dbSJung-uk Kim             if (!s_quiet && !s_brief) {
23746f9291ceSJung-uk Kim                 if ((i <= 0) || (buf[0] == 'Q')) {
237574664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
237674664626SKris Kennaway                     SHUTDOWN(s);
237774664626SKris Kennaway                     close_accept_socket();
237874664626SKris Kennaway                     ret = -11;
237974664626SKris Kennaway                     goto err;
238074664626SKris Kennaway                 }
23816f9291ceSJung-uk Kim                 if ((i <= 0) || (buf[0] == 'q')) {
238274664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
23833b4e3dcbSSimon L. B. Nielsen                     if (SSL_version(con) != DTLS1_VERSION)
238474664626SKris Kennaway                         SHUTDOWN(s);
23856f9291ceSJung-uk Kim                     /*
23866f9291ceSJung-uk Kim                      * close_accept_socket(); ret= -11;
23876f9291ceSJung-uk Kim                      */
238874664626SKris Kennaway                     goto err;
238974664626SKris Kennaway                 }
23901f13597dSJung-uk Kim #ifndef OPENSSL_NO_HEARTBEATS
23916f9291ceSJung-uk Kim                 if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
23921f13597dSJung-uk Kim                     BIO_printf(bio_err, "HEARTBEATING\n");
23931f13597dSJung-uk Kim                     SSL_heartbeat(con);
23941f13597dSJung-uk Kim                     i = 0;
23951f13597dSJung-uk Kim                     continue;
23961f13597dSJung-uk Kim                 }
23971f13597dSJung-uk Kim #endif
23986f9291ceSJung-uk Kim                 if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
239974664626SKris Kennaway                     SSL_renegotiate(con);
240074664626SKris Kennaway                     i = SSL_do_handshake(con);
240174664626SKris Kennaway                     printf("SSL_do_handshake -> %d\n", i);
240274664626SKris Kennaway                     i = 0;      /* 13; */
240374664626SKris Kennaway                     continue;
24046f9291ceSJung-uk Kim                     /*
24056f9291ceSJung-uk Kim                      * strcpy(buf,"server side RE-NEGOTIATE\n");
24066f9291ceSJung-uk Kim                      */
240774664626SKris Kennaway                 }
24086f9291ceSJung-uk Kim                 if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
240974664626SKris Kennaway                     SSL_set_verify(con,
24106f9291ceSJung-uk Kim                                    SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
24116f9291ceSJung-uk Kim                                    NULL);
241274664626SKris Kennaway                     SSL_renegotiate(con);
241374664626SKris Kennaway                     i = SSL_do_handshake(con);
241474664626SKris Kennaway                     printf("SSL_do_handshake -> %d\n", i);
241574664626SKris Kennaway                     i = 0;      /* 13; */
241674664626SKris Kennaway                     continue;
24176f9291ceSJung-uk Kim                     /*
24186f9291ceSJung-uk Kim                      * strcpy(buf,"server side RE-NEGOTIATE asking for client
24196f9291ceSJung-uk Kim                      * cert\n");
24206f9291ceSJung-uk Kim                      */
242174664626SKris Kennaway                 }
24226f9291ceSJung-uk Kim                 if (buf[0] == 'P') {
24233b4e3dcbSSimon L. B. Nielsen                     static const char *str = "Lets print some clear text\n";
242474664626SKris Kennaway                     BIO_write(SSL_get_wbio(con), str, strlen(str));
242574664626SKris Kennaway                 }
24266f9291ceSJung-uk Kim                 if (buf[0] == 'S') {
242774664626SKris Kennaway                     print_stats(bio_s_out, SSL_get_SSL_CTX(con));
242874664626SKris Kennaway                 }
242974664626SKris Kennaway             }
243074664626SKris Kennaway #ifdef CHARSET_EBCDIC
243174664626SKris Kennaway             ebcdic2ascii(buf, buf, i);
243274664626SKris Kennaway #endif
243374664626SKris Kennaway             l = k = 0;
24346f9291ceSJung-uk Kim             for (;;) {
243574664626SKris Kennaway                 /* should do a select for the write */
243674664626SKris Kennaway #ifdef RENEG
24376f9291ceSJung-uk Kim                 {
24386f9291ceSJung-uk Kim                     static count = 0;
24396f9291ceSJung-uk Kim                     if (++count == 100) {
24406f9291ceSJung-uk Kim                         count = 0;
24416f9291ceSJung-uk Kim                         SSL_renegotiate(con);
24426f9291ceSJung-uk Kim                     }
24436f9291ceSJung-uk Kim                 }
244474664626SKris Kennaway #endif
244574664626SKris Kennaway                 k = SSL_write(con, &(buf[l]), (unsigned int)i);
24461f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
24476f9291ceSJung-uk Kim                 while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) {
24481f13597dSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP renego during write\n");
24496f9291ceSJung-uk Kim                     srp_callback_parm.user =
24506f9291ceSJung-uk Kim                         SRP_VBASE_get_by_user(srp_callback_parm.vb,
24516f9291ceSJung-uk Kim                                               srp_callback_parm.login);
24521f13597dSJung-uk Kim                     if (srp_callback_parm.user)
24536f9291ceSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
24546f9291ceSJung-uk Kim                                    srp_callback_parm.user->info);
24551f13597dSJung-uk Kim                     else
24561f13597dSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
24571f13597dSJung-uk Kim                     k = SSL_write(con, &(buf[l]), (unsigned int)i);
24581f13597dSJung-uk Kim                 }
24591f13597dSJung-uk Kim #endif
24606f9291ceSJung-uk Kim                 switch (SSL_get_error(con, k)) {
246174664626SKris Kennaway                 case SSL_ERROR_NONE:
246274664626SKris Kennaway                     break;
246374664626SKris Kennaway                 case SSL_ERROR_WANT_WRITE:
246474664626SKris Kennaway                 case SSL_ERROR_WANT_READ:
246574664626SKris Kennaway                 case SSL_ERROR_WANT_X509_LOOKUP:
246674664626SKris Kennaway                     BIO_printf(bio_s_out, "Write BLOCK\n");
246774664626SKris Kennaway                     break;
246874664626SKris Kennaway                 case SSL_ERROR_SYSCALL:
246974664626SKris Kennaway                 case SSL_ERROR_SSL:
247074664626SKris Kennaway                     BIO_printf(bio_s_out, "ERROR\n");
247174664626SKris Kennaway                     ERR_print_errors(bio_err);
247274664626SKris Kennaway                     ret = 1;
247374664626SKris Kennaway                     goto err;
247474664626SKris Kennaway                     /* break; */
247574664626SKris Kennaway                 case SSL_ERROR_ZERO_RETURN:
247674664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
247774664626SKris Kennaway                     ret = 1;
247874664626SKris Kennaway                     goto err;
247974664626SKris Kennaway                 }
2480ed6b93beSJung-uk Kim                 if (k > 0) {
248174664626SKris Kennaway                     l += k;
248274664626SKris Kennaway                     i -= k;
2483ed6b93beSJung-uk Kim                 }
24846f9291ceSJung-uk Kim                 if (i <= 0)
24856f9291ceSJung-uk Kim                     break;
248674664626SKris Kennaway             }
248774664626SKris Kennaway         }
24886f9291ceSJung-uk Kim         if (read_from_sslcon) {
24896f9291ceSJung-uk Kim             if (!SSL_is_init_finished(con)) {
249074664626SKris Kennaway                 i = init_ssl_connection(con);
249174664626SKris Kennaway 
24926f9291ceSJung-uk Kim                 if (i < 0) {
249374664626SKris Kennaway                     ret = 0;
249474664626SKris Kennaway                     goto err;
24956f9291ceSJung-uk Kim                 } else if (i == 0) {
249674664626SKris Kennaway                     ret = 1;
249774664626SKris Kennaway                     goto err;
249874664626SKris Kennaway                 }
24996f9291ceSJung-uk Kim             } else {
250074664626SKris Kennaway  again:
250174664626SKris Kennaway                 i = SSL_read(con, (char *)buf, bufsize);
25021f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
25036f9291ceSJung-uk Kim                 while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
25041f13597dSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP renego during read\n");
25056f9291ceSJung-uk Kim                     srp_callback_parm.user =
25066f9291ceSJung-uk Kim                         SRP_VBASE_get_by_user(srp_callback_parm.vb,
25076f9291ceSJung-uk Kim                                               srp_callback_parm.login);
25081f13597dSJung-uk Kim                     if (srp_callback_parm.user)
25096f9291ceSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
25106f9291ceSJung-uk Kim                                    srp_callback_parm.user->info);
25111f13597dSJung-uk Kim                     else
25121f13597dSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
25131f13597dSJung-uk Kim                     i = SSL_read(con, (char *)buf, bufsize);
25141f13597dSJung-uk Kim                 }
25151f13597dSJung-uk Kim #endif
25166f9291ceSJung-uk Kim                 switch (SSL_get_error(con, i)) {
251774664626SKris Kennaway                 case SSL_ERROR_NONE:
251874664626SKris Kennaway #ifdef CHARSET_EBCDIC
251974664626SKris Kennaway                     ascii2ebcdic(buf, buf, i);
252074664626SKris Kennaway #endif
25216f9291ceSJung-uk Kim                     raw_write_stdout(buf, (unsigned int)i);
25226f9291ceSJung-uk Kim                     if (SSL_pending(con))
25236f9291ceSJung-uk Kim                         goto again;
252474664626SKris Kennaway                     break;
252574664626SKris Kennaway                 case SSL_ERROR_WANT_WRITE:
252674664626SKris Kennaway                 case SSL_ERROR_WANT_READ:
252774664626SKris Kennaway                     BIO_printf(bio_s_out, "Read BLOCK\n");
252874664626SKris Kennaway                     break;
252974664626SKris Kennaway                 case SSL_ERROR_SYSCALL:
253074664626SKris Kennaway                 case SSL_ERROR_SSL:
253174664626SKris Kennaway                     BIO_printf(bio_s_out, "ERROR\n");
253274664626SKris Kennaway                     ERR_print_errors(bio_err);
253374664626SKris Kennaway                     ret = 1;
253474664626SKris Kennaway                     goto err;
253574664626SKris Kennaway                 case SSL_ERROR_ZERO_RETURN:
253674664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
253774664626SKris Kennaway                     ret = 1;
253874664626SKris Kennaway                     goto err;
253974664626SKris Kennaway                 }
254074664626SKris Kennaway             }
254174664626SKris Kennaway         }
254274664626SKris Kennaway     }
254374664626SKris Kennaway  err:
25446f9291ceSJung-uk Kim     if (con != NULL) {
254574664626SKris Kennaway         BIO_printf(bio_s_out, "shutting down SSL\n");
254674664626SKris Kennaway #if 1
254774664626SKris Kennaway         SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
254874664626SKris Kennaway #else
254974664626SKris Kennaway         SSL_shutdown(con);
255074664626SKris Kennaway #endif
25511f13597dSJung-uk Kim         SSL_free(con);
25521f13597dSJung-uk Kim     }
255374664626SKris Kennaway     BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
25546f9291ceSJung-uk Kim     if (buf != NULL) {
25555c87c606SMark Murray         OPENSSL_cleanse(buf, bufsize);
2556ddd58736SKris Kennaway         OPENSSL_free(buf);
255774664626SKris Kennaway     }
255874664626SKris Kennaway     if (ret >= 0)
255974664626SKris Kennaway         BIO_printf(bio_s_out, "ACCEPT\n");
256074664626SKris Kennaway     return (ret);
256174664626SKris Kennaway }
256274664626SKris Kennaway 
256374664626SKris Kennaway static void close_accept_socket(void)
256474664626SKris Kennaway {
256574664626SKris Kennaway     BIO_printf(bio_err, "shutdown accept socket\n");
25666f9291ceSJung-uk Kim     if (accept_socket >= 0) {
256774664626SKris Kennaway         SHUTDOWN2(accept_socket);
256874664626SKris Kennaway     }
256974664626SKris Kennaway }
257074664626SKris Kennaway 
257174664626SKris Kennaway static int init_ssl_connection(SSL *con)
257274664626SKris Kennaway {
257374664626SKris Kennaway     int i;
257474664626SKris Kennaway     const char *str;
257574664626SKris Kennaway     X509 *peer;
257674664626SKris Kennaway     long verify_error;
257774664626SKris Kennaway     MS_STATIC char buf[BUFSIZ];
25781f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
25791f13597dSJung-uk Kim     char *client_princ;
25801f13597dSJung-uk Kim #endif
25811f13597dSJung-uk Kim #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
25821f13597dSJung-uk Kim     const unsigned char *next_proto_neg;
25831f13597dSJung-uk Kim     unsigned next_proto_neg_len;
25841f13597dSJung-uk Kim #endif
25851f13597dSJung-uk Kim     unsigned char *exportedkeymat;
258674664626SKris Kennaway 
25871f13597dSJung-uk Kim     i = SSL_accept(con);
2588*7bded2dbSJung-uk Kim #ifdef CERT_CB_TEST_RETRY
2589*7bded2dbSJung-uk Kim     {
2590*7bded2dbSJung-uk Kim         while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
2591*7bded2dbSJung-uk Kim                && SSL_state(con) == SSL3_ST_SR_CLNT_HELLO_C) {
2592*7bded2dbSJung-uk Kim             fprintf(stderr,
2593*7bded2dbSJung-uk Kim                     "LOOKUP from certificate callback during accept\n");
2594*7bded2dbSJung-uk Kim             i = SSL_accept(con);
2595*7bded2dbSJung-uk Kim         }
2596*7bded2dbSJung-uk Kim     }
2597*7bded2dbSJung-uk Kim #endif
25981f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
25996f9291ceSJung-uk Kim     while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
26006f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
26016f9291ceSJung-uk Kim                    srp_callback_parm.login);
26026f9291ceSJung-uk Kim         srp_callback_parm.user =
26036f9291ceSJung-uk Kim             SRP_VBASE_get_by_user(srp_callback_parm.vb,
26046f9291ceSJung-uk Kim                                   srp_callback_parm.login);
26051f13597dSJung-uk Kim         if (srp_callback_parm.user)
26066f9291ceSJung-uk Kim             BIO_printf(bio_s_out, "LOOKUP done %s\n",
26076f9291ceSJung-uk Kim                        srp_callback_parm.user->info);
26081f13597dSJung-uk Kim         else
26091f13597dSJung-uk Kim             BIO_printf(bio_s_out, "LOOKUP not successful\n");
26101f13597dSJung-uk Kim         i = SSL_accept(con);
26111f13597dSJung-uk Kim     }
26121f13597dSJung-uk Kim #endif
2613*7bded2dbSJung-uk Kim 
26146f9291ceSJung-uk Kim     if (i <= 0) {
26156f9291ceSJung-uk Kim         if (BIO_sock_should_retry(i)) {
261674664626SKris Kennaway             BIO_printf(bio_s_out, "DELAY\n");
261774664626SKris Kennaway             return (1);
261874664626SKris Kennaway         }
261974664626SKris Kennaway 
262074664626SKris Kennaway         BIO_printf(bio_err, "ERROR\n");
262174664626SKris Kennaway         verify_error = SSL_get_verify_result(con);
26226f9291ceSJung-uk Kim         if (verify_error != X509_V_OK) {
262374664626SKris Kennaway             BIO_printf(bio_err, "verify error:%s\n",
262474664626SKris Kennaway                        X509_verify_cert_error_string(verify_error));
2625*7bded2dbSJung-uk Kim         }
2626*7bded2dbSJung-uk Kim         /* Always print any error messages */
262774664626SKris Kennaway         ERR_print_errors(bio_err);
262874664626SKris Kennaway         return (0);
262974664626SKris Kennaway     }
263074664626SKris Kennaway 
2631*7bded2dbSJung-uk Kim     if (s_brief)
2632*7bded2dbSJung-uk Kim         print_ssl_summary(bio_err, con);
2633*7bded2dbSJung-uk Kim 
263474664626SKris Kennaway     PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
263574664626SKris Kennaway 
263674664626SKris Kennaway     peer = SSL_get_peer_certificate(con);
26376f9291ceSJung-uk Kim     if (peer != NULL) {
263874664626SKris Kennaway         BIO_printf(bio_s_out, "Client certificate\n");
263974664626SKris Kennaway         PEM_write_bio_X509(bio_s_out, peer);
26405c87c606SMark Murray         X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
264174664626SKris Kennaway         BIO_printf(bio_s_out, "subject=%s\n", buf);
26425c87c606SMark Murray         X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
264374664626SKris Kennaway         BIO_printf(bio_s_out, "issuer=%s\n", buf);
264474664626SKris Kennaway         X509_free(peer);
264574664626SKris Kennaway     }
264674664626SKris Kennaway 
26475c87c606SMark Murray     if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
264874664626SKris Kennaway         BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
264974664626SKris Kennaway     str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
2650*7bded2dbSJung-uk Kim     ssl_print_sigalgs(bio_s_out, con);
2651*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
2652*7bded2dbSJung-uk Kim     ssl_print_point_formats(bio_s_out, con);
2653*7bded2dbSJung-uk Kim     ssl_print_curves(bio_s_out, con, 0);
2654*7bded2dbSJung-uk Kim #endif
265574664626SKris Kennaway     BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
265609286989SJung-uk Kim 
26571f13597dSJung-uk Kim #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
26581f13597dSJung-uk Kim     SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
26596f9291ceSJung-uk Kim     if (next_proto_neg) {
26601f13597dSJung-uk Kim         BIO_printf(bio_s_out, "NEXTPROTO is ");
26611f13597dSJung-uk Kim         BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
26621f13597dSJung-uk Kim         BIO_printf(bio_s_out, "\n");
26631f13597dSJung-uk Kim     }
26641f13597dSJung-uk Kim #endif
266509286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
26661f13597dSJung-uk Kim     {
26671f13597dSJung-uk Kim         SRTP_PROTECTION_PROFILE *srtp_profile
26681f13597dSJung-uk Kim             = SSL_get_selected_srtp_profile(con);
26691f13597dSJung-uk Kim 
26701f13597dSJung-uk Kim         if (srtp_profile)
26711f13597dSJung-uk Kim             BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n",
26721f13597dSJung-uk Kim                        srtp_profile->name);
26731f13597dSJung-uk Kim     }
267409286989SJung-uk Kim #endif
26756f9291ceSJung-uk Kim     if (SSL_cache_hit(con))
26766f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "Reused session-id\n");
267774664626SKris Kennaway     if (SSL_ctrl(con, SSL_CTRL_GET_FLAGS, 0, NULL) &
267874664626SKris Kennaway         TLS1_FLAGS_TLS_PADDING_BUG)
26796f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "Peer has incorrect TLSv1 block padding\n");
268050ef0093SJacques Vidrine #ifndef OPENSSL_NO_KRB5
26811f13597dSJung-uk Kim     client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
26826f9291ceSJung-uk Kim     if (client_princ != NULL) {
268350ef0093SJacques Vidrine         BIO_printf(bio_s_out, "Kerberos peer principal is %s\n",
26841f13597dSJung-uk Kim                    client_princ);
268550ef0093SJacques Vidrine     }
268650ef0093SJacques Vidrine #endif                          /* OPENSSL_NO_KRB5 */
26876a599222SSimon L. B. Nielsen     BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
26886a599222SSimon L. B. Nielsen                SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
26896f9291ceSJung-uk Kim     if (keymatexportlabel != NULL) {
26901f13597dSJung-uk Kim         BIO_printf(bio_s_out, "Keying material exporter:\n");
26911f13597dSJung-uk Kim         BIO_printf(bio_s_out, "    Label: '%s'\n", keymatexportlabel);
26926f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "    Length: %i bytes\n", keymatexportlen);
26931f13597dSJung-uk Kim         exportedkeymat = OPENSSL_malloc(keymatexportlen);
26946f9291ceSJung-uk Kim         if (exportedkeymat != NULL) {
26951f13597dSJung-uk Kim             if (!SSL_export_keying_material(con, exportedkeymat,
26961f13597dSJung-uk Kim                                             keymatexportlen,
26971f13597dSJung-uk Kim                                             keymatexportlabel,
26981f13597dSJung-uk Kim                                             strlen(keymatexportlabel),
26996f9291ceSJung-uk Kim                                             NULL, 0, 0)) {
27001f13597dSJung-uk Kim                 BIO_printf(bio_s_out, "    Error\n");
27016f9291ceSJung-uk Kim             } else {
27021f13597dSJung-uk Kim                 BIO_printf(bio_s_out, "    Keying material: ");
27031f13597dSJung-uk Kim                 for (i = 0; i < keymatexportlen; i++)
27046f9291ceSJung-uk Kim                     BIO_printf(bio_s_out, "%02X", exportedkeymat[i]);
27051f13597dSJung-uk Kim                 BIO_printf(bio_s_out, "\n");
27061f13597dSJung-uk Kim             }
27071f13597dSJung-uk Kim             OPENSSL_free(exportedkeymat);
27081f13597dSJung-uk Kim         }
27091f13597dSJung-uk Kim     }
27101f13597dSJung-uk Kim 
271174664626SKris Kennaway     return (1);
271274664626SKris Kennaway }
271374664626SKris Kennaway 
27145c87c606SMark Murray #ifndef OPENSSL_NO_DH
27153b4e3dcbSSimon L. B. Nielsen static DH *load_dh_param(const char *dhfile)
271674664626SKris Kennaway {
271774664626SKris Kennaway     DH *ret = NULL;
271874664626SKris Kennaway     BIO *bio;
271974664626SKris Kennaway 
2720f579bf8eSKris Kennaway     if ((bio = BIO_new_file(dhfile, "r")) == NULL)
272174664626SKris Kennaway         goto err;
272274664626SKris Kennaway     ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
272374664626SKris Kennaway  err:
27246f9291ceSJung-uk Kim     if (bio != NULL)
27256f9291ceSJung-uk Kim         BIO_free(bio);
272674664626SKris Kennaway     return (ret);
272774664626SKris Kennaway }
272874664626SKris Kennaway #endif
27291f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
27301f13597dSJung-uk Kim char *client_princ;
27311f13597dSJung-uk Kim #endif
273274664626SKris Kennaway 
273374664626SKris Kennaway #if 0
273474664626SKris Kennaway static int load_CA(SSL_CTX *ctx, char *file)
273574664626SKris Kennaway {
273674664626SKris Kennaway     FILE *in;
273774664626SKris Kennaway     X509 *x = NULL;
273874664626SKris Kennaway 
273974664626SKris Kennaway     if ((in = fopen(file, "r")) == NULL)
274074664626SKris Kennaway         return (0);
274174664626SKris Kennaway 
27426f9291ceSJung-uk Kim     for (;;) {
274374664626SKris Kennaway         if (PEM_read_X509(in, &x, NULL) == NULL)
274474664626SKris Kennaway             break;
274574664626SKris Kennaway         SSL_CTX_add_client_CA(ctx, x);
274674664626SKris Kennaway     }
27476f9291ceSJung-uk Kim     if (x != NULL)
27486f9291ceSJung-uk Kim         X509_free(x);
274974664626SKris Kennaway     fclose(in);
275074664626SKris Kennaway     return (1);
275174664626SKris Kennaway }
275274664626SKris Kennaway #endif
275374664626SKris Kennaway 
2754*7bded2dbSJung-uk Kim static int www_body(char *hostname, int s, int stype, unsigned char *context)
275574664626SKris Kennaway {
275674664626SKris Kennaway     char *buf = NULL;
275774664626SKris Kennaway     int ret = 1;
2758a3ddd25aSSimon L. B. Nielsen     int i, j, k, dot;
275974664626SKris Kennaway     SSL *con;
27601f13597dSJung-uk Kim     const SSL_CIPHER *c;
276174664626SKris Kennaway     BIO *io, *ssl_bio, *sbio;
27621f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
27631f13597dSJung-uk Kim     KSSL_CTX *kctx;
2764a3ddd25aSSimon L. B. Nielsen #endif
276574664626SKris Kennaway 
2766ddd58736SKris Kennaway     buf = OPENSSL_malloc(bufsize);
27676f9291ceSJung-uk Kim     if (buf == NULL)
27686f9291ceSJung-uk Kim         return (0);
276974664626SKris Kennaway     io = BIO_new(BIO_f_buffer());
277074664626SKris Kennaway     ssl_bio = BIO_new(BIO_f_ssl());
27716f9291ceSJung-uk Kim     if ((io == NULL) || (ssl_bio == NULL))
27726f9291ceSJung-uk Kim         goto err;
277374664626SKris Kennaway 
277474664626SKris Kennaway #ifdef FIONBIO
27756f9291ceSJung-uk Kim     if (s_nbio) {
277674664626SKris Kennaway         unsigned long sl = 1;
277774664626SKris Kennaway 
277874664626SKris Kennaway         if (!s_quiet)
277974664626SKris Kennaway             BIO_printf(bio_err, "turning on non blocking io\n");
278074664626SKris Kennaway         if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0)
278174664626SKris Kennaway             ERR_print_errors(bio_err);
278274664626SKris Kennaway     }
278374664626SKris Kennaway #endif
278474664626SKris Kennaway 
278574664626SKris Kennaway     /* lets make the output buffer a reasonable size */
27866f9291ceSJung-uk Kim     if (!BIO_set_write_buffer_size(io, bufsize))
27876f9291ceSJung-uk Kim         goto err;
278874664626SKris Kennaway 
27896f9291ceSJung-uk Kim     if ((con = SSL_new(ctx)) == NULL)
27906f9291ceSJung-uk Kim         goto err;
2791db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
27926f9291ceSJung-uk Kim     if (s_tlsextdebug) {
2793db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_callback(con, tlsext_cb);
2794db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_arg(con, bio_s_out);
2795db522d3aSSimon L. B. Nielsen     }
2796db522d3aSSimon L. B. Nielsen #endif
27975c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
27986f9291ceSJung-uk Kim     if ((kctx = kssl_ctx_new()) != NULL) {
27991f13597dSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
28001f13597dSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
28015c87c606SMark Murray     }
28025c87c606SMark Murray #endif                          /* OPENSSL_NO_KRB5 */
28036f9291ceSJung-uk Kim     if (context)
28046f9291ceSJung-uk Kim         SSL_set_session_id_context(con, context, strlen((char *)context));
280574664626SKris Kennaway 
280674664626SKris Kennaway     sbio = BIO_new_socket(s, BIO_NOCLOSE);
28076f9291ceSJung-uk Kim     if (s_nbio_test) {
280874664626SKris Kennaway         BIO *test;
280974664626SKris Kennaway 
281074664626SKris Kennaway         test = BIO_new(BIO_f_nbio_test());
281174664626SKris Kennaway         sbio = BIO_push(test, sbio);
281274664626SKris Kennaway     }
281374664626SKris Kennaway     SSL_set_bio(con, sbio, sbio);
281474664626SKris Kennaway     SSL_set_accept_state(con);
281574664626SKris Kennaway 
281674664626SKris Kennaway     /* SSL_set_fd(con,s); */
281774664626SKris Kennaway     BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
281874664626SKris Kennaway     BIO_push(io, ssl_bio);
281974664626SKris Kennaway #ifdef CHARSET_EBCDIC
282074664626SKris Kennaway     io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
282174664626SKris Kennaway #endif
282274664626SKris Kennaway 
28236f9291ceSJung-uk Kim     if (s_debug) {
28241f13597dSJung-uk Kim         SSL_set_debug(con, 1);
28253b4e3dcbSSimon L. B. Nielsen         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
28265471f83eSSimon L. B. Nielsen         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
282774664626SKris Kennaway     }
28286f9291ceSJung-uk Kim     if (s_msg) {
2829*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
2830*7bded2dbSJung-uk Kim         if (s_msg == 2)
2831*7bded2dbSJung-uk Kim             SSL_set_msg_callback(con, SSL_trace);
2832*7bded2dbSJung-uk Kim         else
2833*7bded2dbSJung-uk Kim #endif
28345c87c606SMark Murray             SSL_set_msg_callback(con, msg_cb);
2835*7bded2dbSJung-uk Kim         SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
28365c87c606SMark Murray     }
283774664626SKris Kennaway 
28386f9291ceSJung-uk Kim     for (;;) {
28396f9291ceSJung-uk Kim         if (hack) {
284074664626SKris Kennaway             i = SSL_accept(con);
28411f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
28426f9291ceSJung-uk Kim             while (i <= 0
28436f9291ceSJung-uk Kim                    && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
28446f9291ceSJung-uk Kim                 BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
28456f9291ceSJung-uk Kim                            srp_callback_parm.login);
28466f9291ceSJung-uk Kim                 srp_callback_parm.user =
28476f9291ceSJung-uk Kim                     SRP_VBASE_get_by_user(srp_callback_parm.vb,
28486f9291ceSJung-uk Kim                                           srp_callback_parm.login);
28491f13597dSJung-uk Kim                 if (srp_callback_parm.user)
28506f9291ceSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP done %s\n",
28516f9291ceSJung-uk Kim                                srp_callback_parm.user->info);
28521f13597dSJung-uk Kim                 else
28531f13597dSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP not successful\n");
28541f13597dSJung-uk Kim                 i = SSL_accept(con);
28551f13597dSJung-uk Kim             }
28561f13597dSJung-uk Kim #endif
28576f9291ceSJung-uk Kim             switch (SSL_get_error(con, i)) {
285874664626SKris Kennaway             case SSL_ERROR_NONE:
285974664626SKris Kennaway                 break;
286074664626SKris Kennaway             case SSL_ERROR_WANT_WRITE:
286174664626SKris Kennaway             case SSL_ERROR_WANT_READ:
286274664626SKris Kennaway             case SSL_ERROR_WANT_X509_LOOKUP:
286374664626SKris Kennaway                 continue;
286474664626SKris Kennaway             case SSL_ERROR_SYSCALL:
286574664626SKris Kennaway             case SSL_ERROR_SSL:
286674664626SKris Kennaway             case SSL_ERROR_ZERO_RETURN:
286774664626SKris Kennaway                 ret = 1;
286874664626SKris Kennaway                 goto err;
286974664626SKris Kennaway                 /* break; */
287074664626SKris Kennaway             }
287174664626SKris Kennaway 
287274664626SKris Kennaway             SSL_renegotiate(con);
287374664626SKris Kennaway             SSL_write(con, NULL, 0);
287474664626SKris Kennaway         }
287574664626SKris Kennaway 
287674664626SKris Kennaway         i = BIO_gets(io, buf, bufsize - 1);
28776f9291ceSJung-uk Kim         if (i < 0) {            /* error */
28786f9291ceSJung-uk Kim             if (!BIO_should_retry(io)) {
287974664626SKris Kennaway                 if (!s_quiet)
288074664626SKris Kennaway                     ERR_print_errors(bio_err);
288174664626SKris Kennaway                 goto err;
28826f9291ceSJung-uk Kim             } else {
288374664626SKris Kennaway                 BIO_printf(bio_s_out, "read R BLOCK\n");
28843b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_NETWARE)
28853b4e3dcbSSimon L. B. Nielsen                 delay(1000);
28863b4e3dcbSSimon L. B. Nielsen #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
288774664626SKris Kennaway                 sleep(1);
288874664626SKris Kennaway #endif
288974664626SKris Kennaway                 continue;
289074664626SKris Kennaway             }
28916f9291ceSJung-uk Kim         } else if (i == 0) {    /* end of input */
289274664626SKris Kennaway             ret = 1;
289374664626SKris Kennaway             goto end;
289474664626SKris Kennaway         }
289574664626SKris Kennaway 
289674664626SKris Kennaway         /* else we have data */
289774664626SKris Kennaway         if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
28986f9291ceSJung-uk Kim             ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
289974664626SKris Kennaway             char *p;
290074664626SKris Kennaway             X509 *peer;
290174664626SKris Kennaway             STACK_OF(SSL_CIPHER) *sk;
29023b4e3dcbSSimon L. B. Nielsen             static const char *space = "                          ";
290374664626SKris Kennaway 
29046f9291ceSJung-uk Kim             BIO_puts(io,
29056f9291ceSJung-uk Kim                      "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
290674664626SKris Kennaway             BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
290774664626SKris Kennaway             BIO_puts(io, "<pre>\n");
290874664626SKris Kennaway /*                      BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
290974664626SKris Kennaway             BIO_puts(io, "\n");
29106f9291ceSJung-uk Kim             for (i = 0; i < local_argc; i++) {
291174664626SKris Kennaway                 BIO_puts(io, local_argv[i]);
291274664626SKris Kennaway                 BIO_write(io, " ", 1);
291374664626SKris Kennaway             }
291474664626SKris Kennaway             BIO_puts(io, "\n");
291574664626SKris Kennaway 
291609286989SJung-uk Kim             BIO_printf(io,
291709286989SJung-uk Kim                        "Secure Renegotiation IS%s supported\n",
291809286989SJung-uk Kim                        SSL_get_secure_renegotiation_support(con) ?
291909286989SJung-uk Kim                        "" : " NOT");
292009286989SJung-uk Kim 
29216f9291ceSJung-uk Kim             /*
29226f9291ceSJung-uk Kim              * The following is evil and should not really be done
29236f9291ceSJung-uk Kim              */
292474664626SKris Kennaway             BIO_printf(io, "Ciphers supported in s_server binary\n");
292574664626SKris Kennaway             sk = SSL_get_ciphers(con);
292674664626SKris Kennaway             j = sk_SSL_CIPHER_num(sk);
29276f9291ceSJung-uk Kim             for (i = 0; i < j; i++) {
292874664626SKris Kennaway                 c = sk_SSL_CIPHER_value(sk, i);
292974664626SKris Kennaway                 BIO_printf(io, "%-11s:%-25s",
29306f9291ceSJung-uk Kim                            SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
293174664626SKris Kennaway                 if ((((i + 1) % 2) == 0) && (i + 1 != j))
293274664626SKris Kennaway                     BIO_puts(io, "\n");
293374664626SKris Kennaway             }
293474664626SKris Kennaway             BIO_puts(io, "\n");
293574664626SKris Kennaway             p = SSL_get_shared_ciphers(con, buf, bufsize);
29366f9291ceSJung-uk Kim             if (p != NULL) {
29376f9291ceSJung-uk Kim                 BIO_printf(io,
29386f9291ceSJung-uk Kim                            "---\nCiphers common between both SSL end points:\n");
293974664626SKris Kennaway                 j = i = 0;
29406f9291ceSJung-uk Kim                 while (*p) {
29416f9291ceSJung-uk Kim                     if (*p == ':') {
294274664626SKris Kennaway                         BIO_write(io, space, 26 - j);
294374664626SKris Kennaway                         i++;
294474664626SKris Kennaway                         j = 0;
294574664626SKris Kennaway                         BIO_write(io, ((i % 3) ? " " : "\n"), 1);
29466f9291ceSJung-uk Kim                     } else {
294774664626SKris Kennaway                         BIO_write(io, p, 1);
294874664626SKris Kennaway                         j++;
294974664626SKris Kennaway                     }
295074664626SKris Kennaway                     p++;
295174664626SKris Kennaway                 }
295274664626SKris Kennaway                 BIO_puts(io, "\n");
295374664626SKris Kennaway             }
2954*7bded2dbSJung-uk Kim             ssl_print_sigalgs(io, con);
2955*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
2956*7bded2dbSJung-uk Kim             ssl_print_curves(io, con, 0);
2957*7bded2dbSJung-uk Kim #endif
29581f13597dSJung-uk Kim             BIO_printf(io, (SSL_cache_hit(con)
29596f9291ceSJung-uk Kim                             ? "---\nReused, " : "---\nNew, "));
296074664626SKris Kennaway             c = SSL_get_current_cipher(con);
296174664626SKris Kennaway             BIO_printf(io, "%s, Cipher is %s\n",
29626f9291ceSJung-uk Kim                        SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
296374664626SKris Kennaway             SSL_SESSION_print(io, SSL_get_session(con));
296474664626SKris Kennaway             BIO_printf(io, "---\n");
296574664626SKris Kennaway             print_stats(io, SSL_get_SSL_CTX(con));
296674664626SKris Kennaway             BIO_printf(io, "---\n");
296774664626SKris Kennaway             peer = SSL_get_peer_certificate(con);
29686f9291ceSJung-uk Kim             if (peer != NULL) {
296974664626SKris Kennaway                 BIO_printf(io, "Client certificate\n");
297074664626SKris Kennaway                 X509_print(io, peer);
297174664626SKris Kennaway                 PEM_write_bio_X509(io, peer);
29726f9291ceSJung-uk Kim             } else
297374664626SKris Kennaway                 BIO_puts(io, "no client certificate available\n");
297474664626SKris Kennaway             BIO_puts(io, "</BODY></HTML>\r\n\r\n");
297574664626SKris Kennaway             break;
29766f9291ceSJung-uk Kim         } else if ((www == 2 || www == 3)
29776f9291ceSJung-uk Kim                    && (strncmp("GET /", buf, 5) == 0)) {
297874664626SKris Kennaway             BIO *file;
297974664626SKris Kennaway             char *p, *e;
29806f9291ceSJung-uk Kim             static const char *text =
29816f9291ceSJung-uk Kim                 "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
298274664626SKris Kennaway 
298374664626SKris Kennaway             /* skip the '/' */
298474664626SKris Kennaway             p = &(buf[5]);
29855740a5e3SKris Kennaway 
29865740a5e3SKris Kennaway             dot = 1;
29876f9291ceSJung-uk Kim             for (e = p; *e != '\0'; e++) {
29885740a5e3SKris Kennaway                 if (e[0] == ' ')
29895740a5e3SKris Kennaway                     break;
299074664626SKris Kennaway 
29916f9291ceSJung-uk Kim                 switch (dot) {
29925740a5e3SKris Kennaway                 case 1:
29935740a5e3SKris Kennaway                     dot = (e[0] == '.') ? 2 : 0;
29945740a5e3SKris Kennaway                     break;
29955740a5e3SKris Kennaway                 case 2:
29965740a5e3SKris Kennaway                     dot = (e[0] == '.') ? 3 : 0;
29975740a5e3SKris Kennaway                     break;
29985740a5e3SKris Kennaway                 case 3:
29995740a5e3SKris Kennaway                     dot = (e[0] == '/') ? -1 : 0;
30005740a5e3SKris Kennaway                     break;
30015740a5e3SKris Kennaway                 }
30025740a5e3SKris Kennaway                 if (dot == 0)
30035740a5e3SKris Kennaway                     dot = (e[0] == '/') ? 1 : 0;
30045740a5e3SKris Kennaway             }
30056f9291ceSJung-uk Kim             dot = (dot == 3) || (dot == -1); /* filename contains ".."
30066f9291ceSJung-uk Kim                                               * component */
300774664626SKris Kennaway 
30086f9291ceSJung-uk Kim             if (*e == '\0') {
300974664626SKris Kennaway                 BIO_puts(io, text);
301074664626SKris Kennaway                 BIO_printf(io, "'%s' is an invalid file name\r\n", p);
301174664626SKris Kennaway                 break;
301274664626SKris Kennaway             }
301374664626SKris Kennaway             *e = '\0';
301474664626SKris Kennaway 
30156f9291ceSJung-uk Kim             if (dot) {
301674664626SKris Kennaway                 BIO_puts(io, text);
301774664626SKris Kennaway                 BIO_printf(io, "'%s' contains '..' reference\r\n", p);
301874664626SKris Kennaway                 break;
301974664626SKris Kennaway             }
302074664626SKris Kennaway 
30216f9291ceSJung-uk Kim             if (*p == '/') {
302274664626SKris Kennaway                 BIO_puts(io, text);
302374664626SKris Kennaway                 BIO_printf(io, "'%s' is an invalid path\r\n", p);
302474664626SKris Kennaway                 break;
302574664626SKris Kennaway             }
30265740a5e3SKris Kennaway #if 0
302774664626SKris Kennaway             /* append if a directory lookup */
302874664626SKris Kennaway             if (e[-1] == '/')
302974664626SKris Kennaway                 strcat(p, "index.html");
30305740a5e3SKris Kennaway #endif
303174664626SKris Kennaway 
303274664626SKris Kennaway             /* if a directory, do the index thang */
30336f9291ceSJung-uk Kim             if (app_isdir(p) > 0) {
30345740a5e3SKris Kennaway #if 0                           /* must check buffer size */
303574664626SKris Kennaway                 strcat(p, "/index.html");
30365740a5e3SKris Kennaway #else
30375740a5e3SKris Kennaway                 BIO_puts(io, text);
30385740a5e3SKris Kennaway                 BIO_printf(io, "'%s' is a directory\r\n", p);
30395740a5e3SKris Kennaway                 break;
30405740a5e3SKris Kennaway #endif
304174664626SKris Kennaway             }
304274664626SKris Kennaway 
30436f9291ceSJung-uk Kim             if ((file = BIO_new_file(p, "r")) == NULL) {
304474664626SKris Kennaway                 BIO_puts(io, text);
304574664626SKris Kennaway                 BIO_printf(io, "Error opening '%s'\r\n", p);
304674664626SKris Kennaway                 ERR_print_errors(io);
304774664626SKris Kennaway                 break;
304874664626SKris Kennaway             }
304974664626SKris Kennaway 
305074664626SKris Kennaway             if (!s_quiet)
305174664626SKris Kennaway                 BIO_printf(bio_err, "FILE:%s\n", p);
305274664626SKris Kennaway 
30536f9291ceSJung-uk Kim             if (www == 2) {
305474664626SKris Kennaway                 i = strlen(p);
305574664626SKris Kennaway                 if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
305674664626SKris Kennaway                     ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
305774664626SKris Kennaway                     ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
30586f9291ceSJung-uk Kim                     BIO_puts(io,
30596f9291ceSJung-uk Kim                              "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
306074664626SKris Kennaway                 else
30616f9291ceSJung-uk Kim                     BIO_puts(io,
30626f9291ceSJung-uk Kim                              "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
30635c87c606SMark Murray             }
306474664626SKris Kennaway             /* send the file */
30656f9291ceSJung-uk Kim             for (;;) {
306674664626SKris Kennaway                 i = BIO_read(file, buf, bufsize);
30676f9291ceSJung-uk Kim                 if (i <= 0)
30686f9291ceSJung-uk Kim                     break;
306974664626SKris Kennaway 
307074664626SKris Kennaway #ifdef RENEG
307174664626SKris Kennaway                 total_bytes += i;
307274664626SKris Kennaway                 fprintf(stderr, "%d\n", i);
30736f9291ceSJung-uk Kim                 if (total_bytes > 3 * 1024) {
307474664626SKris Kennaway                     total_bytes = 0;
307574664626SKris Kennaway                     fprintf(stderr, "RENEGOTIATE\n");
307674664626SKris Kennaway                     SSL_renegotiate(con);
307774664626SKris Kennaway                 }
307874664626SKris Kennaway #endif
307974664626SKris Kennaway 
30806f9291ceSJung-uk Kim                 for (j = 0; j < i;) {
308174664626SKris Kennaway #ifdef RENEG
30826f9291ceSJung-uk Kim                     {
30836f9291ceSJung-uk Kim                         static count = 0;
30846f9291ceSJung-uk Kim                         if (++count == 13) {
30856f9291ceSJung-uk Kim                             SSL_renegotiate(con);
30866f9291ceSJung-uk Kim                         }
30876f9291ceSJung-uk Kim                     }
308874664626SKris Kennaway #endif
308974664626SKris Kennaway                     k = BIO_write(io, &(buf[j]), i - j);
30906f9291ceSJung-uk Kim                     if (k <= 0) {
309174664626SKris Kennaway                         if (!BIO_should_retry(io))
309274664626SKris Kennaway                             goto write_error;
30936f9291ceSJung-uk Kim                         else {
309474664626SKris Kennaway                             BIO_printf(bio_s_out, "rwrite W BLOCK\n");
309574664626SKris Kennaway                         }
30966f9291ceSJung-uk Kim                     } else {
309774664626SKris Kennaway                         j += k;
309874664626SKris Kennaway                     }
309974664626SKris Kennaway                 }
310074664626SKris Kennaway             }
310174664626SKris Kennaway  write_error:
310274664626SKris Kennaway             BIO_free(file);
310374664626SKris Kennaway             break;
310474664626SKris Kennaway         }
310574664626SKris Kennaway     }
310674664626SKris Kennaway 
31076f9291ceSJung-uk Kim     for (;;) {
310874664626SKris Kennaway         i = (int)BIO_flush(io);
31096f9291ceSJung-uk Kim         if (i <= 0) {
311074664626SKris Kennaway             if (!BIO_should_retry(io))
311174664626SKris Kennaway                 break;
31126f9291ceSJung-uk Kim         } else
311374664626SKris Kennaway             break;
311474664626SKris Kennaway     }
311574664626SKris Kennaway  end:
311674664626SKris Kennaway #if 1
311774664626SKris Kennaway     /* make sure we re-use sessions */
311874664626SKris Kennaway     SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
311974664626SKris Kennaway #else
3120f579bf8eSKris Kennaway     /* This kills performance */
31216f9291ceSJung-uk Kim     /*
31226f9291ceSJung-uk Kim      * SSL_shutdown(con); A shutdown gets sent in the BIO_free_all(io)
31236f9291ceSJung-uk Kim      * procession
31246f9291ceSJung-uk Kim      */
312574664626SKris Kennaway #endif
312674664626SKris Kennaway 
312774664626SKris Kennaway  err:
312874664626SKris Kennaway 
312974664626SKris Kennaway     if (ret >= 0)
313074664626SKris Kennaway         BIO_printf(bio_s_out, "ACCEPT\n");
313174664626SKris Kennaway 
31326f9291ceSJung-uk Kim     if (buf != NULL)
31336f9291ceSJung-uk Kim         OPENSSL_free(buf);
31346f9291ceSJung-uk Kim     if (io != NULL)
31356f9291ceSJung-uk Kim         BIO_free_all(io);
313674664626SKris Kennaway /*      if (ssl_bio != NULL) BIO_free(ssl_bio);*/
313774664626SKris Kennaway     return (ret);
313874664626SKris Kennaway }
313974664626SKris Kennaway 
3140*7bded2dbSJung-uk Kim static int rev_body(char *hostname, int s, int stype, unsigned char *context)
3141*7bded2dbSJung-uk Kim {
3142*7bded2dbSJung-uk Kim     char *buf = NULL;
3143*7bded2dbSJung-uk Kim     int i;
3144*7bded2dbSJung-uk Kim     int ret = 1;
3145*7bded2dbSJung-uk Kim     SSL *con;
3146*7bded2dbSJung-uk Kim     BIO *io, *ssl_bio, *sbio;
3147*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_KRB5
3148*7bded2dbSJung-uk Kim     KSSL_CTX *kctx;
3149*7bded2dbSJung-uk Kim #endif
3150*7bded2dbSJung-uk Kim 
3151*7bded2dbSJung-uk Kim     buf = OPENSSL_malloc(bufsize);
3152*7bded2dbSJung-uk Kim     if (buf == NULL)
3153*7bded2dbSJung-uk Kim         return (0);
3154*7bded2dbSJung-uk Kim     io = BIO_new(BIO_f_buffer());
3155*7bded2dbSJung-uk Kim     ssl_bio = BIO_new(BIO_f_ssl());
3156*7bded2dbSJung-uk Kim     if ((io == NULL) || (ssl_bio == NULL))
3157*7bded2dbSJung-uk Kim         goto err;
3158*7bded2dbSJung-uk Kim 
3159*7bded2dbSJung-uk Kim     /* lets make the output buffer a reasonable size */
3160*7bded2dbSJung-uk Kim     if (!BIO_set_write_buffer_size(io, bufsize))
3161*7bded2dbSJung-uk Kim         goto err;
3162*7bded2dbSJung-uk Kim 
3163*7bded2dbSJung-uk Kim     if ((con = SSL_new(ctx)) == NULL)
3164*7bded2dbSJung-uk Kim         goto err;
3165*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
3166*7bded2dbSJung-uk Kim     if (s_tlsextdebug) {
3167*7bded2dbSJung-uk Kim         SSL_set_tlsext_debug_callback(con, tlsext_cb);
3168*7bded2dbSJung-uk Kim         SSL_set_tlsext_debug_arg(con, bio_s_out);
3169*7bded2dbSJung-uk Kim     }
3170*7bded2dbSJung-uk Kim #endif
3171*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_KRB5
3172*7bded2dbSJung-uk Kim     if ((kctx = kssl_ctx_new()) != NULL) {
3173*7bded2dbSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
3174*7bded2dbSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
3175*7bded2dbSJung-uk Kim     }
3176*7bded2dbSJung-uk Kim #endif                          /* OPENSSL_NO_KRB5 */
3177*7bded2dbSJung-uk Kim     if (context)
3178*7bded2dbSJung-uk Kim         SSL_set_session_id_context(con, context, strlen((char *)context));
3179*7bded2dbSJung-uk Kim 
3180*7bded2dbSJung-uk Kim     sbio = BIO_new_socket(s, BIO_NOCLOSE);
3181*7bded2dbSJung-uk Kim     SSL_set_bio(con, sbio, sbio);
3182*7bded2dbSJung-uk Kim     SSL_set_accept_state(con);
3183*7bded2dbSJung-uk Kim 
3184*7bded2dbSJung-uk Kim     BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
3185*7bded2dbSJung-uk Kim     BIO_push(io, ssl_bio);
3186*7bded2dbSJung-uk Kim #ifdef CHARSET_EBCDIC
3187*7bded2dbSJung-uk Kim     io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
3188*7bded2dbSJung-uk Kim #endif
3189*7bded2dbSJung-uk Kim 
3190*7bded2dbSJung-uk Kim     if (s_debug) {
3191*7bded2dbSJung-uk Kim         SSL_set_debug(con, 1);
3192*7bded2dbSJung-uk Kim         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
3193*7bded2dbSJung-uk Kim         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
3194*7bded2dbSJung-uk Kim     }
3195*7bded2dbSJung-uk Kim     if (s_msg) {
3196*7bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
3197*7bded2dbSJung-uk Kim         if (s_msg == 2)
3198*7bded2dbSJung-uk Kim             SSL_set_msg_callback(con, SSL_trace);
3199*7bded2dbSJung-uk Kim         else
3200*7bded2dbSJung-uk Kim #endif
3201*7bded2dbSJung-uk Kim             SSL_set_msg_callback(con, msg_cb);
3202*7bded2dbSJung-uk Kim         SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
3203*7bded2dbSJung-uk Kim     }
3204*7bded2dbSJung-uk Kim 
3205*7bded2dbSJung-uk Kim     for (;;) {
3206*7bded2dbSJung-uk Kim         i = BIO_do_handshake(io);
3207*7bded2dbSJung-uk Kim         if (i > 0)
3208*7bded2dbSJung-uk Kim             break;
3209*7bded2dbSJung-uk Kim         if (!BIO_should_retry(io)) {
3210*7bded2dbSJung-uk Kim             BIO_puts(bio_err, "CONNECTION FAILURE\n");
3211*7bded2dbSJung-uk Kim             ERR_print_errors(bio_err);
3212*7bded2dbSJung-uk Kim             goto end;
3213*7bded2dbSJung-uk Kim         }
3214*7bded2dbSJung-uk Kim     }
3215*7bded2dbSJung-uk Kim     BIO_printf(bio_err, "CONNECTION ESTABLISHED\n");
3216*7bded2dbSJung-uk Kim     print_ssl_summary(bio_err, con);
3217*7bded2dbSJung-uk Kim 
3218*7bded2dbSJung-uk Kim     for (;;) {
3219*7bded2dbSJung-uk Kim         i = BIO_gets(io, buf, bufsize - 1);
3220*7bded2dbSJung-uk Kim         if (i < 0) {            /* error */
3221*7bded2dbSJung-uk Kim             if (!BIO_should_retry(io)) {
3222*7bded2dbSJung-uk Kim                 if (!s_quiet)
3223*7bded2dbSJung-uk Kim                     ERR_print_errors(bio_err);
3224*7bded2dbSJung-uk Kim                 goto err;
3225*7bded2dbSJung-uk Kim             } else {
3226*7bded2dbSJung-uk Kim                 BIO_printf(bio_s_out, "read R BLOCK\n");
3227*7bded2dbSJung-uk Kim #if defined(OPENSSL_SYS_NETWARE)
3228*7bded2dbSJung-uk Kim                 delay(1000);
3229*7bded2dbSJung-uk Kim #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
3230*7bded2dbSJung-uk Kim                 sleep(1);
3231*7bded2dbSJung-uk Kim #endif
3232*7bded2dbSJung-uk Kim                 continue;
3233*7bded2dbSJung-uk Kim             }
3234*7bded2dbSJung-uk Kim         } else if (i == 0) {    /* end of input */
3235*7bded2dbSJung-uk Kim             ret = 1;
3236*7bded2dbSJung-uk Kim             BIO_printf(bio_err, "CONNECTION CLOSED\n");
3237*7bded2dbSJung-uk Kim             goto end;
3238*7bded2dbSJung-uk Kim         } else {
3239*7bded2dbSJung-uk Kim             char *p = buf + i - 1;
3240*7bded2dbSJung-uk Kim             while (i && (*p == '\n' || *p == '\r')) {
3241*7bded2dbSJung-uk Kim                 p--;
3242*7bded2dbSJung-uk Kim                 i--;
3243*7bded2dbSJung-uk Kim             }
3244*7bded2dbSJung-uk Kim             if (!s_ign_eof && i == 5 && !strncmp(buf, "CLOSE", 5)) {
3245*7bded2dbSJung-uk Kim                 ret = 1;
3246*7bded2dbSJung-uk Kim                 BIO_printf(bio_err, "CONNECTION CLOSED\n");
3247*7bded2dbSJung-uk Kim                 goto end;
3248*7bded2dbSJung-uk Kim             }
3249*7bded2dbSJung-uk Kim             BUF_reverse((unsigned char *)buf, NULL, i);
3250*7bded2dbSJung-uk Kim             buf[i] = '\n';
3251*7bded2dbSJung-uk Kim             BIO_write(io, buf, i + 1);
3252*7bded2dbSJung-uk Kim             for (;;) {
3253*7bded2dbSJung-uk Kim                 i = BIO_flush(io);
3254*7bded2dbSJung-uk Kim                 if (i > 0)
3255*7bded2dbSJung-uk Kim                     break;
3256*7bded2dbSJung-uk Kim                 if (!BIO_should_retry(io))
3257*7bded2dbSJung-uk Kim                     goto end;
3258*7bded2dbSJung-uk Kim             }
3259*7bded2dbSJung-uk Kim         }
3260*7bded2dbSJung-uk Kim     }
3261*7bded2dbSJung-uk Kim  end:
3262*7bded2dbSJung-uk Kim     /* make sure we re-use sessions */
3263*7bded2dbSJung-uk Kim     SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
3264*7bded2dbSJung-uk Kim 
3265*7bded2dbSJung-uk Kim  err:
3266*7bded2dbSJung-uk Kim 
3267*7bded2dbSJung-uk Kim     if (buf != NULL)
3268*7bded2dbSJung-uk Kim         OPENSSL_free(buf);
3269*7bded2dbSJung-uk Kim     if (io != NULL)
3270*7bded2dbSJung-uk Kim         BIO_free_all(io);
3271*7bded2dbSJung-uk Kim     return (ret);
3272*7bded2dbSJung-uk Kim }
3273*7bded2dbSJung-uk Kim 
32745c87c606SMark Murray #ifndef OPENSSL_NO_RSA
327574664626SKris Kennaway static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
327674664626SKris Kennaway {
32773b4e3dcbSSimon L. B. Nielsen     BIGNUM *bn = NULL;
327874664626SKris Kennaway     static RSA *rsa_tmp = NULL;
327974664626SKris Kennaway 
32803b4e3dcbSSimon L. B. Nielsen     if (!rsa_tmp && ((bn = BN_new()) == NULL))
32813b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Allocation error in generating RSA key\n");
32826f9291ceSJung-uk Kim     if (!rsa_tmp && bn) {
32836f9291ceSJung-uk Kim         if (!s_quiet) {
32846f9291ceSJung-uk Kim             BIO_printf(bio_err, "Generating temp (%d bit) RSA key...",
32856f9291ceSJung-uk Kim                        keylength);
328674664626SKris Kennaway             (void)BIO_flush(bio_err);
328774664626SKris Kennaway         }
32883b4e3dcbSSimon L. B. Nielsen         if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
32896f9291ceSJung-uk Kim             !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
32906f9291ceSJung-uk Kim             if (rsa_tmp)
32916f9291ceSJung-uk Kim                 RSA_free(rsa_tmp);
32923b4e3dcbSSimon L. B. Nielsen             rsa_tmp = NULL;
32933b4e3dcbSSimon L. B. Nielsen         }
32946f9291ceSJung-uk Kim         if (!s_quiet) {
329574664626SKris Kennaway             BIO_printf(bio_err, "\n");
329674664626SKris Kennaway             (void)BIO_flush(bio_err);
329774664626SKris Kennaway         }
32983b4e3dcbSSimon L. B. Nielsen         BN_free(bn);
329974664626SKris Kennaway     }
330074664626SKris Kennaway     return (rsa_tmp);
330174664626SKris Kennaway }
330274664626SKris Kennaway #endif
33035c87c606SMark Murray 
33045c87c606SMark Murray #define MAX_SESSION_ID_ATTEMPTS 10
33055c87c606SMark Murray static int generate_session_id(const SSL *ssl, unsigned char *id,
33065c87c606SMark Murray                                unsigned int *id_len)
33075c87c606SMark Murray {
33085c87c606SMark Murray     unsigned int count = 0;
33095c87c606SMark Murray     do {
3310ed6b93beSJung-uk Kim         if (RAND_pseudo_bytes(id, *id_len) < 0)
3311ed6b93beSJung-uk Kim             return 0;
33126f9291ceSJung-uk Kim         /*
33136f9291ceSJung-uk Kim          * Prefix the session_id with the required prefix. NB: If our prefix
33146f9291ceSJung-uk Kim          * is too long, clip it - but there will be worse effects anyway, eg.
33156f9291ceSJung-uk Kim          * the server could only possibly create 1 session ID (ie. the
33166f9291ceSJung-uk Kim          * prefix!) so all future session negotiations will fail due to
33176f9291ceSJung-uk Kim          * conflicts.
33186f9291ceSJung-uk Kim          */
33195c87c606SMark Murray         memcpy(id, session_id_prefix,
33205c87c606SMark Murray                (strlen(session_id_prefix) < *id_len) ?
33215c87c606SMark Murray                strlen(session_id_prefix) : *id_len);
33225c87c606SMark Murray     }
33235c87c606SMark Murray     while (SSL_has_matching_session_id(ssl, id, *id_len) &&
33245c87c606SMark Murray            (++count < MAX_SESSION_ID_ATTEMPTS));
33255c87c606SMark Murray     if (count >= MAX_SESSION_ID_ATTEMPTS)
33265c87c606SMark Murray         return 0;
33275c87c606SMark Murray     return 1;
33285c87c606SMark Murray }
3329*7bded2dbSJung-uk Kim 
3330*7bded2dbSJung-uk Kim /*
3331*7bded2dbSJung-uk Kim  * By default s_server uses an in-memory cache which caches SSL_SESSION
3332*7bded2dbSJung-uk Kim  * structures without any serialisation. This hides some bugs which only
3333*7bded2dbSJung-uk Kim  * become apparent in deployed servers. By implementing a basic external
3334*7bded2dbSJung-uk Kim  * session cache some issues can be debugged using s_server.
3335*7bded2dbSJung-uk Kim  */
3336*7bded2dbSJung-uk Kim 
3337*7bded2dbSJung-uk Kim typedef struct simple_ssl_session_st {
3338*7bded2dbSJung-uk Kim     unsigned char *id;
3339*7bded2dbSJung-uk Kim     unsigned int idlen;
3340*7bded2dbSJung-uk Kim     unsigned char *der;
3341*7bded2dbSJung-uk Kim     int derlen;
3342*7bded2dbSJung-uk Kim     struct simple_ssl_session_st *next;
3343*7bded2dbSJung-uk Kim } simple_ssl_session;
3344*7bded2dbSJung-uk Kim 
3345*7bded2dbSJung-uk Kim static simple_ssl_session *first = NULL;
3346*7bded2dbSJung-uk Kim 
3347*7bded2dbSJung-uk Kim static int add_session(SSL *ssl, SSL_SESSION *session)
3348*7bded2dbSJung-uk Kim {
3349*7bded2dbSJung-uk Kim     simple_ssl_session *sess;
3350*7bded2dbSJung-uk Kim     unsigned char *p;
3351*7bded2dbSJung-uk Kim 
3352*7bded2dbSJung-uk Kim     sess = OPENSSL_malloc(sizeof(simple_ssl_session));
3353*7bded2dbSJung-uk Kim     if (!sess) {
3354*7bded2dbSJung-uk Kim         BIO_printf(bio_err, "Out of memory adding session to external cache\n");
3355*7bded2dbSJung-uk Kim         return 0;
3356*7bded2dbSJung-uk Kim     }
3357*7bded2dbSJung-uk Kim 
3358*7bded2dbSJung-uk Kim     SSL_SESSION_get_id(session, &sess->idlen);
3359*7bded2dbSJung-uk Kim     sess->derlen = i2d_SSL_SESSION(session, NULL);
3360*7bded2dbSJung-uk Kim 
3361*7bded2dbSJung-uk Kim     sess->id = BUF_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen);
3362*7bded2dbSJung-uk Kim 
3363*7bded2dbSJung-uk Kim     sess->der = OPENSSL_malloc(sess->derlen);
3364*7bded2dbSJung-uk Kim     if (!sess->id || !sess->der) {
3365*7bded2dbSJung-uk Kim         BIO_printf(bio_err, "Out of memory adding session to external cache\n");
3366*7bded2dbSJung-uk Kim 
3367*7bded2dbSJung-uk Kim         if (sess->id)
3368*7bded2dbSJung-uk Kim             OPENSSL_free(sess->id);
3369*7bded2dbSJung-uk Kim         if (sess->der)
3370*7bded2dbSJung-uk Kim             OPENSSL_free(sess->der);
3371*7bded2dbSJung-uk Kim         OPENSSL_free(sess);
3372*7bded2dbSJung-uk Kim         return 0;
3373*7bded2dbSJung-uk Kim     }
3374*7bded2dbSJung-uk Kim     p = sess->der;
3375*7bded2dbSJung-uk Kim     i2d_SSL_SESSION(session, &p);
3376*7bded2dbSJung-uk Kim 
3377*7bded2dbSJung-uk Kim     sess->next = first;
3378*7bded2dbSJung-uk Kim     first = sess;
3379*7bded2dbSJung-uk Kim     BIO_printf(bio_err, "New session added to external cache\n");
3380*7bded2dbSJung-uk Kim     return 0;
3381*7bded2dbSJung-uk Kim }
3382*7bded2dbSJung-uk Kim 
3383*7bded2dbSJung-uk Kim static SSL_SESSION *get_session(SSL *ssl, unsigned char *id, int idlen,
3384*7bded2dbSJung-uk Kim                                 int *do_copy)
3385*7bded2dbSJung-uk Kim {
3386*7bded2dbSJung-uk Kim     simple_ssl_session *sess;
3387*7bded2dbSJung-uk Kim     *do_copy = 0;
3388*7bded2dbSJung-uk Kim     for (sess = first; sess; sess = sess->next) {
3389*7bded2dbSJung-uk Kim         if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) {
3390*7bded2dbSJung-uk Kim             const unsigned char *p = sess->der;
3391*7bded2dbSJung-uk Kim             BIO_printf(bio_err, "Lookup session: cache hit\n");
3392*7bded2dbSJung-uk Kim             return d2i_SSL_SESSION(NULL, &p, sess->derlen);
3393*7bded2dbSJung-uk Kim         }
3394*7bded2dbSJung-uk Kim     }
3395*7bded2dbSJung-uk Kim     BIO_printf(bio_err, "Lookup session: cache miss\n");
3396*7bded2dbSJung-uk Kim     return NULL;
3397*7bded2dbSJung-uk Kim }
3398*7bded2dbSJung-uk Kim 
3399*7bded2dbSJung-uk Kim static void del_session(SSL_CTX *sctx, SSL_SESSION *session)
3400*7bded2dbSJung-uk Kim {
3401*7bded2dbSJung-uk Kim     simple_ssl_session *sess, *prev = NULL;
3402*7bded2dbSJung-uk Kim     const unsigned char *id;
3403*7bded2dbSJung-uk Kim     unsigned int idlen;
3404*7bded2dbSJung-uk Kim     id = SSL_SESSION_get_id(session, &idlen);
3405*7bded2dbSJung-uk Kim     for (sess = first; sess; sess = sess->next) {
3406*7bded2dbSJung-uk Kim         if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) {
3407*7bded2dbSJung-uk Kim             if (prev)
3408*7bded2dbSJung-uk Kim                 prev->next = sess->next;
3409*7bded2dbSJung-uk Kim             else
3410*7bded2dbSJung-uk Kim                 first = sess->next;
3411*7bded2dbSJung-uk Kim             OPENSSL_free(sess->id);
3412*7bded2dbSJung-uk Kim             OPENSSL_free(sess->der);
3413*7bded2dbSJung-uk Kim             OPENSSL_free(sess);
3414*7bded2dbSJung-uk Kim             return;
3415*7bded2dbSJung-uk Kim         }
3416*7bded2dbSJung-uk Kim         prev = sess;
3417*7bded2dbSJung-uk Kim     }
3418*7bded2dbSJung-uk Kim }
3419*7bded2dbSJung-uk Kim 
3420*7bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx)
3421*7bded2dbSJung-uk Kim {
3422*7bded2dbSJung-uk Kim     SSL_CTX_set_session_cache_mode(sctx,
3423*7bded2dbSJung-uk Kim                                    SSL_SESS_CACHE_NO_INTERNAL |
3424*7bded2dbSJung-uk Kim                                    SSL_SESS_CACHE_SERVER);
3425*7bded2dbSJung-uk Kim     SSL_CTX_sess_set_new_cb(sctx, add_session);
3426*7bded2dbSJung-uk Kim     SSL_CTX_sess_set_get_cb(sctx, get_session);
3427*7bded2dbSJung-uk Kim     SSL_CTX_sess_set_remove_cb(sctx, del_session);
3428*7bded2dbSJung-uk Kim }
3429*7bded2dbSJung-uk Kim 
3430*7bded2dbSJung-uk Kim static void free_sessions(void)
3431*7bded2dbSJung-uk Kim {
3432*7bded2dbSJung-uk Kim     simple_ssl_session *sess, *tsess;
3433*7bded2dbSJung-uk Kim     for (sess = first; sess;) {
3434*7bded2dbSJung-uk Kim         OPENSSL_free(sess->id);
3435*7bded2dbSJung-uk Kim         OPENSSL_free(sess->der);
3436*7bded2dbSJung-uk Kim         tsess = sess;
3437*7bded2dbSJung-uk Kim         sess = sess->next;
3438*7bded2dbSJung-uk Kim         OPENSSL_free(tsess);
3439*7bded2dbSJung-uk Kim     }
3440*7bded2dbSJung-uk Kim     first = NULL;
3441*7bded2dbSJung-uk Kim }
3442