xref: /freebsd/crypto/openssl/apps/s_server.c (revision 80815a778ec9d0fc06b0e000c4608da4b4f3a711)
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
2127bded2dbSJung-uk Kim static int sv_body(char *hostname, int s, int stype, unsigned char *context);
2137bded2dbSJung-uk Kim static int www_body(char *hostname, int s, int stype, unsigned char *context);
2147bded2dbSJung-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);
2217bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx);
2227bded2dbSJung-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 
2927bded2dbSJung-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 */
2967bded2dbSJung-uk Kim static const char *s_cert_file = TEST_CERT, *s_key_file =
2977bded2dbSJung-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
3017bded2dbSJung-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;
3147bded2dbSJung-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
3217bded2dbSJung-uk Kim static int no_resume_ephemeral = 0;
3225c87c606SMark Murray static int s_msg = 0;
32374664626SKris Kennaway static int s_quiet = 0;
3247bded2dbSJung-uk Kim static int s_ign_eof = 0;
3257bded2dbSJung-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 
3427bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
3437bded2dbSJung-uk Kim static BIO *serverinfo_in = NULL;
3447bded2dbSJung-uk Kim static const char *s_serverinfo_file = NULL;
3457bded2dbSJung-uk Kim 
3467bded2dbSJung-uk Kim #endif
3477bded2dbSJung-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;
4667bded2dbSJung-uk Kim     s_dchain_file = NULL;
46774664626SKris Kennaway     s_cert_file = TEST_CERT;
46874664626SKris Kennaway     s_key_file = NULL;
4697bded2dbSJung-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;
4867bded2dbSJung-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);
5007bded2dbSJung-uk Kim     BIO_printf(bio_err,
5017bded2dbSJung-uk Kim                " -verify_host host - check peer certificate matches \"host\"\n");
5027bded2dbSJung-uk Kim     BIO_printf(bio_err,
5037bded2dbSJung-uk Kim                " -verify_email email - check peer certificate matches \"email\"\n");
5047bded2dbSJung-uk Kim     BIO_printf(bio_err,
5057bded2dbSJung-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);
5157bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
5167bded2dbSJung-uk Kim     BIO_printf(bio_err,
5177bded2dbSJung-uk Kim                " -serverinfo arg - PEM serverinfo file for certificate\n");
5187bded2dbSJung-uk Kim     BIO_printf(bio_err,
5197bded2dbSJung-uk Kim                " -auth               - send and receive RFC 5878 TLS auth extensions and supplemental data\n");
5207bded2dbSJung-uk Kim     BIO_printf(bio_err,
5217bded2dbSJung-uk Kim                " -auth_require_reneg - Do not send TLS auth extensions until renegotiation\n");
5227bded2dbSJung-uk Kim #endif
5237bded2dbSJung-uk Kim     BIO_printf(bio_err,
5247bded2dbSJung-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");
6037bded2dbSJung-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");
655*80815a77SJung-uk Kim     BIO_printf(bio_err,
656*80815a77SJung-uk Kim                " -sigalgs arg      - Signature algorithms to support (colon-separated list)\n");
657*80815a77SJung-uk Kim     BIO_printf(bio_err,
658*80815a77SJung-uk Kim                " -client_sigalgs arg  - Signature algorithms to support for client \n");
659*80815a77SJung-uk Kim     BIO_printf(bio_err,
660*80815a77SJung-uk Kim                "                        certificate authentication (colon-separated list)\n");
6611f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
6626f9291ceSJung-uk Kim     BIO_printf(bio_err,
6636f9291ceSJung-uk Kim                " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
664db522d3aSSimon L. B. Nielsen # endif
66509286989SJung-uk Kim # ifndef OPENSSL_NO_SRTP
6666f9291ceSJung-uk Kim     BIO_printf(bio_err,
6676f9291ceSJung-uk Kim                " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
6681f13597dSJung-uk Kim # endif
6697bded2dbSJung-uk Kim     BIO_printf(bio_err,
6707bded2dbSJung-uk Kim                " -alpn arg  - set the advertised protocols for the ALPN extension (comma-separated list)\n");
67109286989SJung-uk Kim #endif
6726f9291ceSJung-uk Kim     BIO_printf(bio_err,
6736f9291ceSJung-uk Kim                " -keymatexport label   - Export keying material using label\n");
6746f9291ceSJung-uk Kim     BIO_printf(bio_err,
6756f9291ceSJung-uk Kim                " -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
6766f9291ceSJung-uk Kim     BIO_printf(bio_err,
6776f9291ceSJung-uk Kim                " -status           - respond to certificate status requests\n");
6786f9291ceSJung-uk Kim     BIO_printf(bio_err,
6796f9291ceSJung-uk Kim                " -status_verbose   - enable status request verbose printout\n");
6806f9291ceSJung-uk Kim     BIO_printf(bio_err,
6816f9291ceSJung-uk Kim                " -status_timeout n - status request responder timeout\n");
682a93cbc2bSJung-uk Kim     BIO_printf(bio_err, " -status_url URL   - status request fallback URL\n");
68374664626SKris Kennaway }
68474664626SKris Kennaway 
68574664626SKris Kennaway static int local_argc = 0;
68674664626SKris Kennaway static char **local_argv;
68774664626SKris Kennaway 
68874664626SKris Kennaway #ifdef CHARSET_EBCDIC
68974664626SKris Kennaway static int ebcdic_new(BIO *bi);
69074664626SKris Kennaway static int ebcdic_free(BIO *a);
69174664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl);
6925c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl);
6935c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
69474664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size);
6955c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str);
69674664626SKris Kennaway 
69774664626SKris Kennaway # define BIO_TYPE_EBCDIC_FILTER  (18|0x0200)
6986f9291ceSJung-uk Kim static BIO_METHOD methods_ebcdic = {
69974664626SKris Kennaway     BIO_TYPE_EBCDIC_FILTER,
70074664626SKris Kennaway     "EBCDIC/ASCII filter",
70174664626SKris Kennaway     ebcdic_write,
70274664626SKris Kennaway     ebcdic_read,
70374664626SKris Kennaway     ebcdic_puts,
70474664626SKris Kennaway     ebcdic_gets,
70574664626SKris Kennaway     ebcdic_ctrl,
70674664626SKris Kennaway     ebcdic_new,
70774664626SKris Kennaway     ebcdic_free,
70874664626SKris Kennaway };
70974664626SKris Kennaway 
7106f9291ceSJung-uk Kim typedef struct {
71174664626SKris Kennaway     size_t alloced;
71274664626SKris Kennaway     char buff[1];
71374664626SKris Kennaway } EBCDIC_OUTBUFF;
71474664626SKris Kennaway 
71574664626SKris Kennaway BIO_METHOD *BIO_f_ebcdic_filter()
71674664626SKris Kennaway {
71774664626SKris Kennaway     return (&methods_ebcdic);
71874664626SKris Kennaway }
71974664626SKris Kennaway 
72074664626SKris Kennaway static int ebcdic_new(BIO *bi)
72174664626SKris Kennaway {
72274664626SKris Kennaway     EBCDIC_OUTBUFF *wbuf;
72374664626SKris Kennaway 
724ddd58736SKris Kennaway     wbuf = (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
7256f9291ceSJung-uk Kim     if (!wbuf)
7266f9291ceSJung-uk Kim         return 0;
72774664626SKris Kennaway     wbuf->alloced = 1024;
72874664626SKris Kennaway     wbuf->buff[0] = '\0';
72974664626SKris Kennaway 
73074664626SKris Kennaway     bi->ptr = (char *)wbuf;
73174664626SKris Kennaway     bi->init = 1;
73274664626SKris Kennaway     bi->flags = 0;
73374664626SKris Kennaway     return (1);
73474664626SKris Kennaway }
73574664626SKris Kennaway 
73674664626SKris Kennaway static int ebcdic_free(BIO *a)
73774664626SKris Kennaway {
7386f9291ceSJung-uk Kim     if (a == NULL)
7396f9291ceSJung-uk Kim         return (0);
74074664626SKris Kennaway     if (a->ptr != NULL)
741ddd58736SKris Kennaway         OPENSSL_free(a->ptr);
74274664626SKris Kennaway     a->ptr = NULL;
74374664626SKris Kennaway     a->init = 0;
74474664626SKris Kennaway     a->flags = 0;
74574664626SKris Kennaway     return (1);
74674664626SKris Kennaway }
74774664626SKris Kennaway 
74874664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl)
74974664626SKris Kennaway {
75074664626SKris Kennaway     int ret = 0;
75174664626SKris Kennaway 
7526f9291ceSJung-uk Kim     if (out == NULL || outl == 0)
7536f9291ceSJung-uk Kim         return (0);
7546f9291ceSJung-uk Kim     if (b->next_bio == NULL)
7556f9291ceSJung-uk Kim         return (0);
75674664626SKris Kennaway 
75774664626SKris Kennaway     ret = BIO_read(b->next_bio, out, outl);
75874664626SKris Kennaway     if (ret > 0)
75974664626SKris Kennaway         ascii2ebcdic(out, out, ret);
76074664626SKris Kennaway     return (ret);
76174664626SKris Kennaway }
76274664626SKris Kennaway 
7635c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl)
76474664626SKris Kennaway {
76574664626SKris Kennaway     EBCDIC_OUTBUFF *wbuf;
76674664626SKris Kennaway     int ret = 0;
76774664626SKris Kennaway     int num;
76874664626SKris Kennaway     unsigned char n;
76974664626SKris Kennaway 
7706f9291ceSJung-uk Kim     if ((in == NULL) || (inl <= 0))
7716f9291ceSJung-uk Kim         return (0);
7726f9291ceSJung-uk Kim     if (b->next_bio == NULL)
7736f9291ceSJung-uk Kim         return (0);
77474664626SKris Kennaway 
77574664626SKris Kennaway     wbuf = (EBCDIC_OUTBUFF *) b->ptr;
77674664626SKris Kennaway 
7776f9291ceSJung-uk Kim     if (inl > (num = wbuf->alloced)) {
77874664626SKris Kennaway         num = num + num;        /* double the size */
77974664626SKris Kennaway         if (num < inl)
78074664626SKris Kennaway             num = inl;
7816f9291ceSJung-uk Kim         wbuf =
7826f9291ceSJung-uk Kim             (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
7836f9291ceSJung-uk Kim         if (!wbuf)
7846f9291ceSJung-uk Kim             return 0;
7856f9291ceSJung-uk Kim         OPENSSL_free(b->ptr);
78674664626SKris Kennaway 
78774664626SKris Kennaway         wbuf->alloced = num;
78874664626SKris Kennaway         wbuf->buff[0] = '\0';
78974664626SKris Kennaway 
79074664626SKris Kennaway         b->ptr = (char *)wbuf;
79174664626SKris Kennaway     }
79274664626SKris Kennaway 
79374664626SKris Kennaway     ebcdic2ascii(wbuf->buff, in, inl);
79474664626SKris Kennaway 
79574664626SKris Kennaway     ret = BIO_write(b->next_bio, wbuf->buff, inl);
79674664626SKris Kennaway 
79774664626SKris Kennaway     return (ret);
79874664626SKris Kennaway }
79974664626SKris Kennaway 
8005c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
80174664626SKris Kennaway {
80274664626SKris Kennaway     long ret;
80374664626SKris Kennaway 
8046f9291ceSJung-uk Kim     if (b->next_bio == NULL)
8056f9291ceSJung-uk Kim         return (0);
8066f9291ceSJung-uk Kim     switch (cmd) {
80774664626SKris Kennaway     case BIO_CTRL_DUP:
80874664626SKris Kennaway         ret = 0L;
80974664626SKris Kennaway         break;
81074664626SKris Kennaway     default:
81174664626SKris Kennaway         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
81274664626SKris Kennaway         break;
81374664626SKris Kennaway     }
81474664626SKris Kennaway     return (ret);
81574664626SKris Kennaway }
81674664626SKris Kennaway 
81774664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size)
81874664626SKris Kennaway {
8195c87c606SMark Murray     int i, ret = 0;
8206f9291ceSJung-uk Kim     if (bp->next_bio == NULL)
8216f9291ceSJung-uk Kim         return (0);
82274664626SKris Kennaway /*      return(BIO_gets(bp->next_bio,buf,size));*/
8236f9291ceSJung-uk Kim     for (i = 0; i < size - 1; ++i) {
82474664626SKris Kennaway         ret = ebcdic_read(bp, &buf[i], 1);
82574664626SKris Kennaway         if (ret <= 0)
82674664626SKris Kennaway             break;
8276f9291ceSJung-uk Kim         else if (buf[i] == '\n') {
82874664626SKris Kennaway             ++i;
82974664626SKris Kennaway             break;
83074664626SKris Kennaway         }
83174664626SKris Kennaway     }
83274664626SKris Kennaway     if (i < size)
83374664626SKris Kennaway         buf[i] = '\0';
83474664626SKris Kennaway     return (ret < 0 && i == 0) ? ret : i;
83574664626SKris Kennaway }
83674664626SKris Kennaway 
8375c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str)
83874664626SKris Kennaway {
8396f9291ceSJung-uk Kim     if (bp->next_bio == NULL)
8406f9291ceSJung-uk Kim         return (0);
84174664626SKris Kennaway     return ebcdic_write(bp, str, strlen(str));
84274664626SKris Kennaway }
84374664626SKris Kennaway #endif
84474664626SKris Kennaway 
845db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
846db522d3aSSimon L. B. Nielsen 
847db522d3aSSimon L. B. Nielsen /* This is a context that we pass to callbacks */
848db522d3aSSimon L. B. Nielsen typedef struct tlsextctx_st {
849db522d3aSSimon L. B. Nielsen     char *servername;
850db522d3aSSimon L. B. Nielsen     BIO *biodebug;
851db522d3aSSimon L. B. Nielsen     int extension_error;
852db522d3aSSimon L. B. Nielsen } tlsextctx;
853db522d3aSSimon L. B. Nielsen 
854db522d3aSSimon L. B. Nielsen static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
855db522d3aSSimon L. B. Nielsen {
856db522d3aSSimon L. B. Nielsen     tlsextctx *p = (tlsextctx *) arg;
857db522d3aSSimon L. B. Nielsen     const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
858db522d3aSSimon L. B. Nielsen     if (servername && p->biodebug)
8596f9291ceSJung-uk Kim         BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
8606f9291ceSJung-uk Kim                    servername);
861db522d3aSSimon L. B. Nielsen 
862db522d3aSSimon L. B. Nielsen     if (!p->servername)
863db522d3aSSimon L. B. Nielsen         return SSL_TLSEXT_ERR_NOACK;
864db522d3aSSimon L. B. Nielsen 
8656f9291ceSJung-uk Kim     if (servername) {
866a93cbc2bSJung-uk Kim         if (strcasecmp(servername, p->servername))
867db522d3aSSimon L. B. Nielsen             return p->extension_error;
8686f9291ceSJung-uk Kim         if (ctx2) {
8691f13597dSJung-uk Kim             BIO_printf(p->biodebug, "Switching server context.\n");
870db522d3aSSimon L. B. Nielsen             SSL_set_SSL_CTX(s, ctx2);
871db522d3aSSimon L. B. Nielsen         }
872db522d3aSSimon L. B. Nielsen     }
873db522d3aSSimon L. B. Nielsen     return SSL_TLSEXT_ERR_OK;
874db522d3aSSimon L. B. Nielsen }
875db522d3aSSimon L. B. Nielsen 
876db522d3aSSimon L. B. Nielsen /* Structure passed to cert status callback */
877db522d3aSSimon L. B. Nielsen 
878db522d3aSSimon L. B. Nielsen typedef struct tlsextstatusctx_st {
879db522d3aSSimon L. B. Nielsen     /* Default responder to use */
880db522d3aSSimon L. B. Nielsen     char *host, *path, *port;
881db522d3aSSimon L. B. Nielsen     int use_ssl;
882db522d3aSSimon L. B. Nielsen     int timeout;
883db522d3aSSimon L. B. Nielsen     BIO *err;
884db522d3aSSimon L. B. Nielsen     int verbose;
885db522d3aSSimon L. B. Nielsen } tlsextstatusctx;
886db522d3aSSimon L. B. Nielsen 
887db522d3aSSimon L. B. Nielsen static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 };
888db522d3aSSimon L. B. Nielsen 
8896f9291ceSJung-uk Kim /*
8906f9291ceSJung-uk Kim  * Certificate Status callback. This is called when a client includes a
8916f9291ceSJung-uk Kim  * certificate status request extension. This is a simplified version. It
8926f9291ceSJung-uk Kim  * examines certificates each time and makes one OCSP responder query for
8936f9291ceSJung-uk Kim  * each request. A full version would store details such as the OCSP
8946f9291ceSJung-uk Kim  * certificate IDs and minimise the number of OCSP responses by caching them
8956f9291ceSJung-uk Kim  * until they were considered "expired".
896db522d3aSSimon L. B. Nielsen  */
897db522d3aSSimon L. B. Nielsen 
898db522d3aSSimon L. B. Nielsen static int cert_status_cb(SSL *s, void *arg)
899db522d3aSSimon L. B. Nielsen {
900db522d3aSSimon L. B. Nielsen     tlsextstatusctx *srctx = arg;
901db522d3aSSimon L. B. Nielsen     BIO *err = srctx->err;
902db522d3aSSimon L. B. Nielsen     char *host, *port, *path;
903db522d3aSSimon L. B. Nielsen     int use_ssl;
904db522d3aSSimon L. B. Nielsen     unsigned char *rspder = NULL;
905db522d3aSSimon L. B. Nielsen     int rspderlen;
9061f13597dSJung-uk Kim     STACK_OF(OPENSSL_STRING) *aia = NULL;
907db522d3aSSimon L. B. Nielsen     X509 *x = NULL;
908db522d3aSSimon L. B. Nielsen     X509_STORE_CTX inctx;
909db522d3aSSimon L. B. Nielsen     X509_OBJECT obj;
910db522d3aSSimon L. B. Nielsen     OCSP_REQUEST *req = NULL;
911db522d3aSSimon L. B. Nielsen     OCSP_RESPONSE *resp = NULL;
912db522d3aSSimon L. B. Nielsen     OCSP_CERTID *id = NULL;
913db522d3aSSimon L. B. Nielsen     STACK_OF(X509_EXTENSION) *exts;
914db522d3aSSimon L. B. Nielsen     int ret = SSL_TLSEXT_ERR_NOACK;
915db522d3aSSimon L. B. Nielsen     int i;
916db522d3aSSimon L. B. Nielsen # if 0
917db522d3aSSimon L. B. Nielsen     STACK_OF(OCSP_RESPID) *ids;
918db522d3aSSimon L. B. Nielsen     SSL_get_tlsext_status_ids(s, &ids);
9196f9291ceSJung-uk Kim     BIO_printf(err, "cert_status: received %d ids\n",
9206f9291ceSJung-uk Kim                sk_OCSP_RESPID_num(ids));
921db522d3aSSimon L. B. Nielsen # endif
922db522d3aSSimon L. B. Nielsen     if (srctx->verbose)
923db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: callback called\n");
924db522d3aSSimon L. B. Nielsen     /* Build up OCSP query from server certificate */
925db522d3aSSimon L. B. Nielsen     x = SSL_get_certificate(s);
926db522d3aSSimon L. B. Nielsen     aia = X509_get1_ocsp(x);
9276f9291ceSJung-uk Kim     if (aia) {
9281f13597dSJung-uk Kim         if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
9296f9291ceSJung-uk Kim                             &host, &port, &path, &use_ssl)) {
930db522d3aSSimon L. B. Nielsen             BIO_puts(err, "cert_status: can't parse AIA URL\n");
931db522d3aSSimon L. B. Nielsen             goto err;
932db522d3aSSimon L. B. Nielsen         }
933db522d3aSSimon L. B. Nielsen         if (srctx->verbose)
934db522d3aSSimon L. B. Nielsen             BIO_printf(err, "cert_status: AIA URL: %s\n",
9351f13597dSJung-uk Kim                        sk_OPENSSL_STRING_value(aia, 0));
9366f9291ceSJung-uk Kim     } else {
9376f9291ceSJung-uk Kim         if (!srctx->host) {
9386f9291ceSJung-uk Kim             BIO_puts(srctx->err,
9396f9291ceSJung-uk Kim                      "cert_status: no AIA and no default responder URL\n");
940db522d3aSSimon L. B. Nielsen             goto done;
941db522d3aSSimon L. B. Nielsen         }
942db522d3aSSimon L. B. Nielsen         host = srctx->host;
943db522d3aSSimon L. B. Nielsen         path = srctx->path;
944db522d3aSSimon L. B. Nielsen         port = srctx->port;
945db522d3aSSimon L. B. Nielsen         use_ssl = srctx->use_ssl;
946db522d3aSSimon L. B. Nielsen     }
947db522d3aSSimon L. B. Nielsen 
948db522d3aSSimon L. B. Nielsen     if (!X509_STORE_CTX_init(&inctx,
949db522d3aSSimon L. B. Nielsen                              SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
950db522d3aSSimon L. B. Nielsen                              NULL, NULL))
951db522d3aSSimon L. B. Nielsen         goto err;
952db522d3aSSimon L. B. Nielsen     if (X509_STORE_get_by_subject(&inctx, X509_LU_X509,
9536f9291ceSJung-uk Kim                                   X509_get_issuer_name(x), &obj) <= 0) {
954db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
955db522d3aSSimon L. B. Nielsen         X509_STORE_CTX_cleanup(&inctx);
956db522d3aSSimon L. B. Nielsen         goto done;
957db522d3aSSimon L. B. Nielsen     }
958db522d3aSSimon L. B. Nielsen     req = OCSP_REQUEST_new();
959db522d3aSSimon L. B. Nielsen     if (!req)
960db522d3aSSimon L. B. Nielsen         goto err;
961db522d3aSSimon L. B. Nielsen     id = OCSP_cert_to_id(NULL, x, obj.data.x509);
962db522d3aSSimon L. B. Nielsen     X509_free(obj.data.x509);
963db522d3aSSimon L. B. Nielsen     X509_STORE_CTX_cleanup(&inctx);
964db522d3aSSimon L. B. Nielsen     if (!id)
965db522d3aSSimon L. B. Nielsen         goto err;
966db522d3aSSimon L. B. Nielsen     if (!OCSP_request_add0_id(req, id))
967db522d3aSSimon L. B. Nielsen         goto err;
968db522d3aSSimon L. B. Nielsen     id = NULL;
969db522d3aSSimon L. B. Nielsen     /* Add any extensions to the request */
970db522d3aSSimon L. B. Nielsen     SSL_get_tlsext_status_exts(s, &exts);
9716f9291ceSJung-uk Kim     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
972db522d3aSSimon L. B. Nielsen         X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
973db522d3aSSimon L. B. Nielsen         if (!OCSP_REQUEST_add_ext(req, ext, -1))
974db522d3aSSimon L. B. Nielsen             goto err;
975db522d3aSSimon L. B. Nielsen     }
9761f13597dSJung-uk Kim     resp = process_responder(err, req, host, path, port, use_ssl, NULL,
977db522d3aSSimon L. B. Nielsen                              srctx->timeout);
9786f9291ceSJung-uk Kim     if (!resp) {
979db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: error querying responder\n");
980db522d3aSSimon L. B. Nielsen         goto done;
981db522d3aSSimon L. B. Nielsen     }
982db522d3aSSimon L. B. Nielsen     rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
983db522d3aSSimon L. B. Nielsen     if (rspderlen <= 0)
984db522d3aSSimon L. B. Nielsen         goto err;
985db522d3aSSimon L. B. Nielsen     SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
9866f9291ceSJung-uk Kim     if (srctx->verbose) {
987db522d3aSSimon L. B. Nielsen         BIO_puts(err, "cert_status: ocsp response sent:\n");
988db522d3aSSimon L. B. Nielsen         OCSP_RESPONSE_print(err, resp, 2);
989db522d3aSSimon L. B. Nielsen     }
990db522d3aSSimon L. B. Nielsen     ret = SSL_TLSEXT_ERR_OK;
991db522d3aSSimon L. B. Nielsen  done:
992db522d3aSSimon L. B. Nielsen     if (ret != SSL_TLSEXT_ERR_OK)
993db522d3aSSimon L. B. Nielsen         ERR_print_errors(err);
9946f9291ceSJung-uk Kim     if (aia) {
995db522d3aSSimon L. B. Nielsen         OPENSSL_free(host);
996db522d3aSSimon L. B. Nielsen         OPENSSL_free(path);
997db522d3aSSimon L. B. Nielsen         OPENSSL_free(port);
998db522d3aSSimon L. B. Nielsen         X509_email_free(aia);
999db522d3aSSimon L. B. Nielsen     }
1000db522d3aSSimon L. B. Nielsen     if (id)
1001db522d3aSSimon L. B. Nielsen         OCSP_CERTID_free(id);
1002db522d3aSSimon L. B. Nielsen     if (req)
1003db522d3aSSimon L. B. Nielsen         OCSP_REQUEST_free(req);
1004db522d3aSSimon L. B. Nielsen     if (resp)
1005db522d3aSSimon L. B. Nielsen         OCSP_RESPONSE_free(resp);
1006db522d3aSSimon L. B. Nielsen     return ret;
1007db522d3aSSimon L. B. Nielsen  err:
1008db522d3aSSimon L. B. Nielsen     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
1009db522d3aSSimon L. B. Nielsen     goto done;
1010db522d3aSSimon L. B. Nielsen }
10111f13597dSJung-uk Kim 
10121f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
10131f13597dSJung-uk Kim /* This is the context that we pass to next_proto_cb */
10141f13597dSJung-uk Kim typedef struct tlsextnextprotoctx_st {
10151f13597dSJung-uk Kim     unsigned char *data;
10161f13597dSJung-uk Kim     unsigned int len;
10171f13597dSJung-uk Kim } tlsextnextprotoctx;
10181f13597dSJung-uk Kim 
10196f9291ceSJung-uk Kim static int next_proto_cb(SSL *s, const unsigned char **data,
10206f9291ceSJung-uk Kim                          unsigned int *len, void *arg)
10211f13597dSJung-uk Kim {
10221f13597dSJung-uk Kim     tlsextnextprotoctx *next_proto = arg;
10231f13597dSJung-uk Kim 
10241f13597dSJung-uk Kim     *data = next_proto->data;
10251f13597dSJung-uk Kim     *len = next_proto->len;
10261f13597dSJung-uk Kim 
10271f13597dSJung-uk Kim     return SSL_TLSEXT_ERR_OK;
10281f13597dSJung-uk Kim }
10291f13597dSJung-uk Kim # endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
10301f13597dSJung-uk Kim 
10317bded2dbSJung-uk Kim /* This the context that we pass to alpn_cb */
10327bded2dbSJung-uk Kim typedef struct tlsextalpnctx_st {
10337bded2dbSJung-uk Kim     unsigned char *data;
10347bded2dbSJung-uk Kim     unsigned short len;
10357bded2dbSJung-uk Kim } tlsextalpnctx;
10367bded2dbSJung-uk Kim 
10377bded2dbSJung-uk Kim static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
10387bded2dbSJung-uk Kim                    const unsigned char *in, unsigned int inlen, void *arg)
10397bded2dbSJung-uk Kim {
10407bded2dbSJung-uk Kim     tlsextalpnctx *alpn_ctx = arg;
10417bded2dbSJung-uk Kim 
10427bded2dbSJung-uk Kim     if (!s_quiet) {
10437bded2dbSJung-uk Kim         /* We can assume that |in| is syntactically valid. */
10447bded2dbSJung-uk Kim         unsigned i;
10457bded2dbSJung-uk Kim         BIO_printf(bio_s_out, "ALPN protocols advertised by the client: ");
10467bded2dbSJung-uk Kim         for (i = 0; i < inlen;) {
10477bded2dbSJung-uk Kim             if (i)
10487bded2dbSJung-uk Kim                 BIO_write(bio_s_out, ", ", 2);
10497bded2dbSJung-uk Kim             BIO_write(bio_s_out, &in[i + 1], in[i]);
10507bded2dbSJung-uk Kim             i += in[i] + 1;
10517bded2dbSJung-uk Kim         }
10527bded2dbSJung-uk Kim         BIO_write(bio_s_out, "\n", 1);
10537bded2dbSJung-uk Kim     }
10547bded2dbSJung-uk Kim 
10557bded2dbSJung-uk Kim     if (SSL_select_next_proto
10567bded2dbSJung-uk Kim         ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in,
10577bded2dbSJung-uk Kim          inlen) != OPENSSL_NPN_NEGOTIATED) {
10587bded2dbSJung-uk Kim         return SSL_TLSEXT_ERR_NOACK;
10597bded2dbSJung-uk Kim     }
10607bded2dbSJung-uk Kim 
10617bded2dbSJung-uk Kim     if (!s_quiet) {
10627bded2dbSJung-uk Kim         BIO_printf(bio_s_out, "ALPN protocols selected: ");
10637bded2dbSJung-uk Kim         BIO_write(bio_s_out, *out, *outlen);
10647bded2dbSJung-uk Kim         BIO_write(bio_s_out, "\n", 1);
10657bded2dbSJung-uk Kim     }
10667bded2dbSJung-uk Kim 
10677bded2dbSJung-uk Kim     return SSL_TLSEXT_ERR_OK;
10687bded2dbSJung-uk Kim }
10697bded2dbSJung-uk Kim #endif                          /* ndef OPENSSL_NO_TLSEXT */
10701f13597dSJung-uk Kim 
1071f579bf8eSKris Kennaway int MAIN(int, char **);
1072f579bf8eSKris Kennaway 
1073db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
1074db522d3aSSimon L. B. Nielsen static char *jpake_secret = NULL;
10757bded2dbSJung-uk Kim # define no_jpake !jpake_secret
10767bded2dbSJung-uk Kim #else
10777bded2dbSJung-uk Kim # define no_jpake 1
1078db522d3aSSimon L. B. Nielsen #endif
10791f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
10801f13597dSJung-uk Kim static srpsrvparm srp_callback_parm;
10811f13597dSJung-uk Kim #endif
108209286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
10831f13597dSJung-uk Kim static char *srtp_profiles = NULL;
108409286989SJung-uk Kim #endif
1085db522d3aSSimon L. B. Nielsen 
108674664626SKris Kennaway int MAIN(int argc, char *argv[])
108774664626SKris Kennaway {
10881f13597dSJung-uk Kim     X509_VERIFY_PARAM *vpm = NULL;
10891f13597dSJung-uk Kim     int badarg = 0;
109074664626SKris Kennaway     short port = PORT;
109174664626SKris Kennaway     char *CApath = NULL, *CAfile = NULL;
10927bded2dbSJung-uk Kim     char *chCApath = NULL, *chCAfile = NULL;
10937bded2dbSJung-uk Kim     char *vfyCApath = NULL, *vfyCAfile = NULL;
10943b4e3dcbSSimon L. B. Nielsen     unsigned char *context = NULL;
1095f579bf8eSKris Kennaway     char *dhfile = NULL;
10967bded2dbSJung-uk Kim     int badop = 0;
109774664626SKris Kennaway     int ret = 1;
10987bded2dbSJung-uk Kim     int build_chain = 0;
10997bded2dbSJung-uk Kim     int no_tmp_rsa = 0, no_dhe = 0, no_ecdhe = 0, nocert = 0;
110074664626SKris Kennaway     int state = 0;
11011f13597dSJung-uk Kim     const SSL_METHOD *meth = NULL;
1102db522d3aSSimon L. B. Nielsen     int socket_type = SOCK_STREAM;
11035c87c606SMark Murray     ENGINE *e = NULL;
11045740a5e3SKris Kennaway     char *inrand = NULL;
11053b4e3dcbSSimon L. B. Nielsen     int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
11063b4e3dcbSSimon L. B. Nielsen     char *passarg = NULL, *pass = NULL;
11073b4e3dcbSSimon L. B. Nielsen     char *dpassarg = NULL, *dpass = NULL;
11083b4e3dcbSSimon L. B. Nielsen     int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
11093b4e3dcbSSimon L. B. Nielsen     X509 *s_cert = NULL, *s_dcert = NULL;
11107bded2dbSJung-uk Kim     STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL;
11113b4e3dcbSSimon L. B. Nielsen     EVP_PKEY *s_key = NULL, *s_dkey = NULL;
11127bded2dbSJung-uk Kim     int no_cache = 0, ext_cache = 0;
11137bded2dbSJung-uk Kim     int rev = 0, naccept = -1;
1114db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1115db522d3aSSimon L. B. Nielsen     EVP_PKEY *s_key2 = NULL;
1116db522d3aSSimon L. B. Nielsen     X509 *s_cert2 = NULL;
1117db522d3aSSimon L. B. Nielsen     tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING };
11181f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
11191f13597dSJung-uk Kim     const char *next_proto_neg_in = NULL;
11207bded2dbSJung-uk Kim     tlsextnextprotoctx next_proto = { NULL, 0 };
1121db522d3aSSimon L. B. Nielsen # endif
11227bded2dbSJung-uk Kim     const char *alpn_in = NULL;
11237bded2dbSJung-uk Kim     tlsextalpnctx alpn_ctx = { NULL, 0 };
11241f13597dSJung-uk Kim #endif
11251f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK
11261f13597dSJung-uk Kim     /* by default do not send a PSK identity hint */
11271f13597dSJung-uk Kim     static char *psk_identity_hint = NULL;
11281f13597dSJung-uk Kim #endif
11291f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
11301f13597dSJung-uk Kim     char *srpuserseed = NULL;
11311f13597dSJung-uk Kim     char *srp_verifier_file = NULL;
11321f13597dSJung-uk Kim #endif
11337bded2dbSJung-uk Kim     SSL_EXCERT *exc = NULL;
11347bded2dbSJung-uk Kim     SSL_CONF_CTX *cctx = NULL;
11357bded2dbSJung-uk Kim     STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
11367bded2dbSJung-uk Kim 
11377bded2dbSJung-uk Kim     char *crl_file = NULL;
11387bded2dbSJung-uk Kim     int crl_format = FORMAT_PEM;
11397bded2dbSJung-uk Kim     int crl_download = 0;
11407bded2dbSJung-uk Kim     STACK_OF(X509_CRL) *crls = NULL;
11417bded2dbSJung-uk Kim 
114274664626SKris Kennaway     meth = SSLv23_server_method();
114374664626SKris Kennaway 
114474664626SKris Kennaway     local_argc = argc;
114574664626SKris Kennaway     local_argv = argv;
114674664626SKris Kennaway 
114774664626SKris Kennaway     apps_startup();
1148f579bf8eSKris Kennaway #ifdef MONOLITH
1149f579bf8eSKris Kennaway     s_server_init();
1150f579bf8eSKris Kennaway #endif
115174664626SKris Kennaway 
115274664626SKris Kennaway     if (bio_err == NULL)
115374664626SKris Kennaway         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
115474664626SKris Kennaway 
11555c87c606SMark Murray     if (!load_config(bio_err, NULL))
11565c87c606SMark Murray         goto end;
11575c87c606SMark Murray 
11587bded2dbSJung-uk Kim     cctx = SSL_CONF_CTX_new();
11597bded2dbSJung-uk Kim     if (!cctx)
11607bded2dbSJung-uk Kim         goto end;
11617bded2dbSJung-uk Kim     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
11627bded2dbSJung-uk Kim     SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);
11637bded2dbSJung-uk Kim 
116474664626SKris Kennaway     verify_depth = 0;
116574664626SKris Kennaway #ifdef FIONBIO
116674664626SKris Kennaway     s_nbio = 0;
116774664626SKris Kennaway #endif
116874664626SKris Kennaway     s_nbio_test = 0;
116974664626SKris Kennaway 
117074664626SKris Kennaway     argc--;
117174664626SKris Kennaway     argv++;
117274664626SKris Kennaway 
11736f9291ceSJung-uk Kim     while (argc >= 1) {
11746f9291ceSJung-uk Kim         if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) {
11756f9291ceSJung-uk Kim             if (--argc < 1)
11766f9291ceSJung-uk Kim                 goto bad;
117774664626SKris Kennaway             if (!extract_port(*(++argv), &port))
117874664626SKris Kennaway                 goto bad;
11797bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-naccept") == 0) {
11807bded2dbSJung-uk Kim             if (--argc < 1)
11817bded2dbSJung-uk Kim                 goto bad;
11827bded2dbSJung-uk Kim             naccept = atol(*(++argv));
11837bded2dbSJung-uk Kim             if (naccept <= 0) {
11847bded2dbSJung-uk Kim                 BIO_printf(bio_err, "bad accept value %s\n", *argv);
11857bded2dbSJung-uk Kim                 goto bad;
11867bded2dbSJung-uk Kim             }
11876f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-verify") == 0) {
118874664626SKris Kennaway             s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
11896f9291ceSJung-uk Kim             if (--argc < 1)
11906f9291ceSJung-uk Kim                 goto bad;
119174664626SKris Kennaway             verify_depth = atoi(*(++argv));
11927bded2dbSJung-uk Kim             if (!s_quiet)
119374664626SKris Kennaway                 BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
11946f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-Verify") == 0) {
11956f9291ceSJung-uk Kim             s_server_verify =
11966f9291ceSJung-uk Kim                 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
119774664626SKris Kennaway                 SSL_VERIFY_CLIENT_ONCE;
11986f9291ceSJung-uk Kim             if (--argc < 1)
11996f9291ceSJung-uk Kim                 goto bad;
120074664626SKris Kennaway             verify_depth = atoi(*(++argv));
12017bded2dbSJung-uk Kim             if (!s_quiet)
12026f9291ceSJung-uk Kim                 BIO_printf(bio_err,
12036f9291ceSJung-uk Kim                            "verify depth is %d, must return a certificate\n",
12046f9291ceSJung-uk Kim                            verify_depth);
12056f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-context") == 0) {
12066f9291ceSJung-uk Kim             if (--argc < 1)
12076f9291ceSJung-uk Kim                 goto bad;
12083b4e3dcbSSimon L. B. Nielsen             context = (unsigned char *)*(++argv);
12096f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-cert") == 0) {
12106f9291ceSJung-uk Kim             if (--argc < 1)
12116f9291ceSJung-uk Kim                 goto bad;
121274664626SKris Kennaway             s_cert_file = *(++argv);
12137bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-CRL") == 0) {
12147bded2dbSJung-uk Kim             if (--argc < 1)
12157bded2dbSJung-uk Kim                 goto bad;
12167bded2dbSJung-uk Kim             crl_file = *(++argv);
12177bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-crl_download") == 0)
12187bded2dbSJung-uk Kim             crl_download = 1;
12197bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
12207bded2dbSJung-uk Kim         else if (strcmp(*argv, "-serverinfo") == 0) {
12217bded2dbSJung-uk Kim             if (--argc < 1)
12227bded2dbSJung-uk Kim                 goto bad;
12237bded2dbSJung-uk Kim             s_serverinfo_file = *(++argv);
12247bded2dbSJung-uk Kim         }
12257bded2dbSJung-uk Kim #endif
12267bded2dbSJung-uk Kim         else if (strcmp(*argv, "-certform") == 0) {
12276f9291ceSJung-uk Kim             if (--argc < 1)
12286f9291ceSJung-uk Kim                 goto bad;
12293b4e3dcbSSimon L. B. Nielsen             s_cert_format = str2fmt(*(++argv));
12306f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-key") == 0) {
12316f9291ceSJung-uk Kim             if (--argc < 1)
12326f9291ceSJung-uk Kim                 goto bad;
123374664626SKris Kennaway             s_key_file = *(++argv);
12346f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keyform") == 0) {
12356f9291ceSJung-uk Kim             if (--argc < 1)
12366f9291ceSJung-uk Kim                 goto bad;
12373b4e3dcbSSimon L. B. Nielsen             s_key_format = str2fmt(*(++argv));
12386f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-pass") == 0) {
12396f9291ceSJung-uk Kim             if (--argc < 1)
12406f9291ceSJung-uk Kim                 goto bad;
12413b4e3dcbSSimon L. B. Nielsen             passarg = *(++argv);
12427bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-cert_chain") == 0) {
12437bded2dbSJung-uk Kim             if (--argc < 1)
12447bded2dbSJung-uk Kim                 goto bad;
12457bded2dbSJung-uk Kim             s_chain_file = *(++argv);
12466f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dhparam") == 0) {
12476f9291ceSJung-uk Kim             if (--argc < 1)
12486f9291ceSJung-uk Kim                 goto bad;
1249f579bf8eSKris Kennaway             dhfile = *(++argv);
12507bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dcertform") == 0) {
12516f9291ceSJung-uk Kim             if (--argc < 1)
12526f9291ceSJung-uk Kim                 goto bad;
12533b4e3dcbSSimon L. B. Nielsen             s_dcert_format = str2fmt(*(++argv));
12546f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dcert") == 0) {
12556f9291ceSJung-uk Kim             if (--argc < 1)
12566f9291ceSJung-uk Kim                 goto bad;
125774664626SKris Kennaway             s_dcert_file = *(++argv);
12586f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dkeyform") == 0) {
12596f9291ceSJung-uk Kim             if (--argc < 1)
12606f9291ceSJung-uk Kim                 goto bad;
12613b4e3dcbSSimon L. B. Nielsen             s_dkey_format = str2fmt(*(++argv));
12626f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dpass") == 0) {
12636f9291ceSJung-uk Kim             if (--argc < 1)
12646f9291ceSJung-uk Kim                 goto bad;
12653b4e3dcbSSimon L. B. Nielsen             dpassarg = *(++argv);
12666f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-dkey") == 0) {
12676f9291ceSJung-uk Kim             if (--argc < 1)
12686f9291ceSJung-uk Kim                 goto bad;
126974664626SKris Kennaway             s_dkey_file = *(++argv);
12707bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dcert_chain") == 0) {
12717bded2dbSJung-uk Kim             if (--argc < 1)
12727bded2dbSJung-uk Kim                 goto bad;
12737bded2dbSJung-uk Kim             s_dchain_file = *(++argv);
12746f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-nocert") == 0) {
127574664626SKris Kennaway             nocert = 1;
12766f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-CApath") == 0) {
12776f9291ceSJung-uk Kim             if (--argc < 1)
12786f9291ceSJung-uk Kim                 goto bad;
127974664626SKris Kennaway             CApath = *(++argv);
12807bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-chainCApath") == 0) {
12817bded2dbSJung-uk Kim             if (--argc < 1)
12827bded2dbSJung-uk Kim                 goto bad;
12837bded2dbSJung-uk Kim             chCApath = *(++argv);
12847bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-verifyCApath") == 0) {
12857bded2dbSJung-uk Kim             if (--argc < 1)
12867bded2dbSJung-uk Kim                 goto bad;
12877bded2dbSJung-uk Kim             vfyCApath = *(++argv);
12886f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-no_cache") == 0)
12896a599222SSimon L. B. Nielsen             no_cache = 1;
12907bded2dbSJung-uk Kim         else if (strcmp(*argv, "-ext_cache") == 0)
12917bded2dbSJung-uk Kim             ext_cache = 1;
12927bded2dbSJung-uk Kim         else if (strcmp(*argv, "-CRLform") == 0) {
12937bded2dbSJung-uk Kim             if (--argc < 1)
12947bded2dbSJung-uk Kim                 goto bad;
12957bded2dbSJung-uk Kim             crl_format = str2fmt(*(++argv));
12967bded2dbSJung-uk Kim         } else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) {
12977bded2dbSJung-uk Kim             if (badarg)
12987bded2dbSJung-uk Kim                 goto bad;
12997bded2dbSJung-uk Kim             continue;
13007bded2dbSJung-uk Kim         } else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) {
13017bded2dbSJung-uk Kim             if (badarg)
13027bded2dbSJung-uk Kim                 goto bad;
13037bded2dbSJung-uk Kim             continue;
13047bded2dbSJung-uk Kim         } else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) {
13051f13597dSJung-uk Kim             if (badarg)
13061f13597dSJung-uk Kim                 goto bad;
13071f13597dSJung-uk Kim             continue;
13086f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-verify_return_error") == 0)
13091f13597dSJung-uk Kim             verify_return_error = 1;
13107bded2dbSJung-uk Kim         else if (strcmp(*argv, "-verify_quiet") == 0)
13117bded2dbSJung-uk Kim             verify_quiet = 1;
13127bded2dbSJung-uk Kim         else if (strcmp(*argv, "-build_chain") == 0)
13137bded2dbSJung-uk Kim             build_chain = 1;
13147bded2dbSJung-uk Kim         else if (strcmp(*argv, "-CAfile") == 0) {
13156f9291ceSJung-uk Kim             if (--argc < 1)
13166f9291ceSJung-uk Kim                 goto bad;
131774664626SKris Kennaway             CAfile = *(++argv);
13187bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-chainCAfile") == 0) {
13197bded2dbSJung-uk Kim             if (--argc < 1)
13207bded2dbSJung-uk Kim                 goto bad;
13217bded2dbSJung-uk Kim             chCAfile = *(++argv);
13227bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-verifyCAfile") == 0) {
13237bded2dbSJung-uk Kim             if (--argc < 1)
13247bded2dbSJung-uk Kim                 goto bad;
13257bded2dbSJung-uk Kim             vfyCAfile = *(++argv);
132674664626SKris Kennaway         }
132774664626SKris Kennaway #ifdef FIONBIO
13286f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nbio") == 0) {
13296f9291ceSJung-uk Kim             s_nbio = 1;
13306f9291ceSJung-uk Kim         }
133174664626SKris Kennaway #endif
13326f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nbio_test") == 0) {
133374664626SKris Kennaway #ifdef FIONBIO
133474664626SKris Kennaway             s_nbio = 1;
133574664626SKris Kennaway #endif
133674664626SKris Kennaway             s_nbio_test = 1;
13377bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-ign_eof") == 0)
13387bded2dbSJung-uk Kim             s_ign_eof = 1;
13397bded2dbSJung-uk Kim         else if (strcmp(*argv, "-no_ign_eof") == 0)
13407bded2dbSJung-uk Kim             s_ign_eof = 0;
13417bded2dbSJung-uk Kim         else if (strcmp(*argv, "-debug") == 0) {
13426f9291ceSJung-uk Kim             s_debug = 1;
134374664626SKris Kennaway         }
1344db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1345db522d3aSSimon L. B. Nielsen         else if (strcmp(*argv, "-tlsextdebug") == 0)
1346db522d3aSSimon L. B. Nielsen             s_tlsextdebug = 1;
1347db522d3aSSimon L. B. Nielsen         else if (strcmp(*argv, "-status") == 0)
1348db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
13496f9291ceSJung-uk Kim         else if (strcmp(*argv, "-status_verbose") == 0) {
1350db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
1351db522d3aSSimon L. B. Nielsen             tlscstatp.verbose = 1;
13526f9291ceSJung-uk Kim         } else if (!strcmp(*argv, "-status_timeout")) {
1353db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
13546f9291ceSJung-uk Kim             if (--argc < 1)
13556f9291ceSJung-uk Kim                 goto bad;
1356db522d3aSSimon L. B. Nielsen             tlscstatp.timeout = atoi(*(++argv));
13576f9291ceSJung-uk Kim         } else if (!strcmp(*argv, "-status_url")) {
1358db522d3aSSimon L. B. Nielsen             s_tlsextstatus = 1;
13596f9291ceSJung-uk Kim             if (--argc < 1)
13606f9291ceSJung-uk Kim                 goto bad;
1361db522d3aSSimon L. B. Nielsen             if (!OCSP_parse_url(*(++argv),
1362db522d3aSSimon L. B. Nielsen                                 &tlscstatp.host,
1363db522d3aSSimon L. B. Nielsen                                 &tlscstatp.port,
13646f9291ceSJung-uk Kim                                 &tlscstatp.path, &tlscstatp.use_ssl)) {
1365db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err, "Error parsing URL\n");
1366db522d3aSSimon L. B. Nielsen                 goto bad;
1367db522d3aSSimon L. B. Nielsen             }
1368db522d3aSSimon L. B. Nielsen         }
1369db522d3aSSimon L. B. Nielsen #endif
13706f9291ceSJung-uk Kim         else if (strcmp(*argv, "-msg") == 0) {
13716f9291ceSJung-uk Kim             s_msg = 1;
13727bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-msgfile") == 0) {
13737bded2dbSJung-uk Kim             if (--argc < 1)
13747bded2dbSJung-uk Kim                 goto bad;
13757bded2dbSJung-uk Kim             bio_s_msg = BIO_new_file(*(++argv), "w");
13767bded2dbSJung-uk Kim         }
13777bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
13787bded2dbSJung-uk Kim         else if (strcmp(*argv, "-trace") == 0) {
13797bded2dbSJung-uk Kim             s_msg = 2;
13807bded2dbSJung-uk Kim         }
13817bded2dbSJung-uk Kim #endif
13827bded2dbSJung-uk Kim         else if (strcmp(*argv, "-hack") == 0) {
13836f9291ceSJung-uk Kim             hack = 1;
13846f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-state") == 0) {
13856f9291ceSJung-uk Kim             state = 1;
13866f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-crlf") == 0) {
13876f9291ceSJung-uk Kim             s_crlf = 1;
13886f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-quiet") == 0) {
13896f9291ceSJung-uk Kim             s_quiet = 1;
13907bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-brief") == 0) {
13917bded2dbSJung-uk Kim             s_quiet = 1;
13927bded2dbSJung-uk Kim             s_brief = 1;
13937bded2dbSJung-uk Kim             verify_quiet = 1;
13946f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-no_tmp_rsa") == 0) {
13956f9291ceSJung-uk Kim             no_tmp_rsa = 1;
13966f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-no_dhe") == 0) {
13976f9291ceSJung-uk Kim             no_dhe = 1;
13987bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-no_ecdhe") == 0) {
13996f9291ceSJung-uk Kim             no_ecdhe = 1;
14007bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-no_resume_ephemeral") == 0) {
14017bded2dbSJung-uk Kim             no_resume_ephemeral = 1;
14026f9291ceSJung-uk Kim         }
14036f9291ceSJung-uk Kim #ifndef OPENSSL_NO_PSK
14046f9291ceSJung-uk Kim         else if (strcmp(*argv, "-psk_hint") == 0) {
14056f9291ceSJung-uk Kim             if (--argc < 1)
14066f9291ceSJung-uk Kim                 goto bad;
14076f9291ceSJung-uk Kim             psk_identity_hint = *(++argv);
14086f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-psk") == 0) {
14091f13597dSJung-uk Kim             size_t i;
14101f13597dSJung-uk Kim 
14116f9291ceSJung-uk Kim             if (--argc < 1)
14126f9291ceSJung-uk Kim                 goto bad;
14131f13597dSJung-uk Kim             psk_key = *(++argv);
14146f9291ceSJung-uk Kim             for (i = 0; i < strlen(psk_key); i++) {
14151f13597dSJung-uk Kim                 if (isxdigit((unsigned char)psk_key[i]))
14161f13597dSJung-uk Kim                     continue;
14171f13597dSJung-uk Kim                 BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
14181f13597dSJung-uk Kim                 goto bad;
14191f13597dSJung-uk Kim             }
14201f13597dSJung-uk Kim         }
14211f13597dSJung-uk Kim #endif
14221f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
14236f9291ceSJung-uk Kim         else if (strcmp(*argv, "-srpvfile") == 0) {
14246f9291ceSJung-uk Kim             if (--argc < 1)
14256f9291ceSJung-uk Kim                 goto bad;
14261f13597dSJung-uk Kim             srp_verifier_file = *(++argv);
14271f13597dSJung-uk Kim             meth = TLSv1_server_method();
14286f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-srpuserseed") == 0) {
14296f9291ceSJung-uk Kim             if (--argc < 1)
14306f9291ceSJung-uk Kim                 goto bad;
14311f13597dSJung-uk Kim             srpuserseed = *(++argv);
14321f13597dSJung-uk Kim             meth = TLSv1_server_method();
14331f13597dSJung-uk Kim         }
14341f13597dSJung-uk Kim #endif
14357bded2dbSJung-uk Kim         else if (strcmp(*argv, "-rev") == 0) {
14367bded2dbSJung-uk Kim             rev = 1;
14377bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-www") == 0) {
14386f9291ceSJung-uk Kim             www = 1;
14396f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-WWW") == 0) {
14406f9291ceSJung-uk Kim             www = 2;
14416f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-HTTP") == 0) {
14426f9291ceSJung-uk Kim             www = 3;
14436f9291ceSJung-uk Kim         }
14445c87c606SMark Murray #ifndef OPENSSL_NO_SSL2
14456f9291ceSJung-uk Kim         else if (strcmp(*argv, "-ssl2") == 0) {
14467bded2dbSJung-uk Kim             no_ecdhe = 1;
14476f9291ceSJung-uk Kim             meth = SSLv2_server_method();
14486f9291ceSJung-uk Kim         }
144974664626SKris Kennaway #endif
1450751d2991SJung-uk Kim #ifndef OPENSSL_NO_SSL3_METHOD
14516f9291ceSJung-uk Kim         else if (strcmp(*argv, "-ssl3") == 0) {
14526f9291ceSJung-uk Kim             meth = SSLv3_server_method();
14536f9291ceSJung-uk Kim         }
145474664626SKris Kennaway #endif
14555c87c606SMark Murray #ifndef OPENSSL_NO_TLS1
14566f9291ceSJung-uk Kim         else if (strcmp(*argv, "-tls1") == 0) {
14576f9291ceSJung-uk Kim             meth = TLSv1_server_method();
14586f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-tls1_1") == 0) {
14596f9291ceSJung-uk Kim             meth = TLSv1_1_server_method();
14606f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-tls1_2") == 0) {
14616f9291ceSJung-uk Kim             meth = TLSv1_2_server_method();
14626f9291ceSJung-uk Kim         }
146374664626SKris Kennaway #endif
14643b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DTLS1
14657bded2dbSJung-uk Kim         else if (strcmp(*argv, "-dtls") == 0) {
14667bded2dbSJung-uk Kim             meth = DTLS_server_method();
14677bded2dbSJung-uk Kim             socket_type = SOCK_DGRAM;
14687bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dtls1") == 0) {
14693b4e3dcbSSimon L. B. Nielsen             meth = DTLSv1_server_method();
1470db522d3aSSimon L. B. Nielsen             socket_type = SOCK_DGRAM;
14717bded2dbSJung-uk Kim         } else if (strcmp(*argv, "-dtls1_2") == 0) {
14727bded2dbSJung-uk Kim             meth = DTLSv1_2_server_method();
14737bded2dbSJung-uk Kim             socket_type = SOCK_DGRAM;
14746f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-timeout") == 0)
14753b4e3dcbSSimon L. B. Nielsen             enable_timeouts = 1;
14766f9291ceSJung-uk Kim         else if (strcmp(*argv, "-mtu") == 0) {
14776f9291ceSJung-uk Kim             if (--argc < 1)
14786f9291ceSJung-uk Kim                 goto bad;
14796a599222SSimon L. B. Nielsen             socket_mtu = atol(*(++argv));
14806f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-chain") == 0)
14813b4e3dcbSSimon L. B. Nielsen             cert_chain = 1;
14823b4e3dcbSSimon L. B. Nielsen #endif
14836f9291ceSJung-uk Kim         else if (strcmp(*argv, "-id_prefix") == 0) {
14846f9291ceSJung-uk Kim             if (--argc < 1)
14856f9291ceSJung-uk Kim                 goto bad;
14865c87c606SMark Murray             session_id_prefix = *(++argv);
14875c87c606SMark Murray         }
1488fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
14896f9291ceSJung-uk Kim         else if (strcmp(*argv, "-engine") == 0) {
14906f9291ceSJung-uk Kim             if (--argc < 1)
14916f9291ceSJung-uk Kim                 goto bad;
14925c87c606SMark Murray             engine_id = *(++argv);
14935c87c606SMark Murray         }
1494fceca8a3SJacques Vidrine #endif
14956f9291ceSJung-uk Kim         else if (strcmp(*argv, "-rand") == 0) {
14966f9291ceSJung-uk Kim             if (--argc < 1)
14976f9291ceSJung-uk Kim                 goto bad;
14985740a5e3SKris Kennaway             inrand = *(++argv);
14995740a5e3SKris Kennaway         }
1500db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
15016f9291ceSJung-uk Kim         else if (strcmp(*argv, "-servername") == 0) {
15026f9291ceSJung-uk Kim             if (--argc < 1)
15036f9291ceSJung-uk Kim                 goto bad;
1504db522d3aSSimon L. B. Nielsen             tlsextcbp.servername = *(++argv);
15056f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-servername_fatal") == 0) {
15066f9291ceSJung-uk Kim             tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL;
15076f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-cert2") == 0) {
15086f9291ceSJung-uk Kim             if (--argc < 1)
15096f9291ceSJung-uk Kim                 goto bad;
1510db522d3aSSimon L. B. Nielsen             s_cert_file2 = *(++argv);
15116f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-key2") == 0) {
15126f9291ceSJung-uk Kim             if (--argc < 1)
15136f9291ceSJung-uk Kim                 goto bad;
1514db522d3aSSimon L. B. Nielsen             s_key_file2 = *(++argv);
1515db522d3aSSimon L. B. Nielsen         }
15161f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
15176f9291ceSJung-uk Kim         else if (strcmp(*argv, "-nextprotoneg") == 0) {
15186f9291ceSJung-uk Kim             if (--argc < 1)
15196f9291ceSJung-uk Kim                 goto bad;
15201f13597dSJung-uk Kim             next_proto_neg_in = *(++argv);
15211f13597dSJung-uk Kim         }
1522db522d3aSSimon L. B. Nielsen # endif
15237bded2dbSJung-uk Kim         else if (strcmp(*argv, "-alpn") == 0) {
15247bded2dbSJung-uk Kim             if (--argc < 1)
15257bded2dbSJung-uk Kim                 goto bad;
15267bded2dbSJung-uk Kim             alpn_in = *(++argv);
15277bded2dbSJung-uk Kim         }
15281f13597dSJung-uk Kim #endif
15291f13597dSJung-uk Kim #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
15306f9291ceSJung-uk Kim         else if (strcmp(*argv, "-jpake") == 0) {
15316f9291ceSJung-uk Kim             if (--argc < 1)
15326f9291ceSJung-uk Kim                 goto bad;
1533db522d3aSSimon L. B. Nielsen             jpake_secret = *(++argv);
1534db522d3aSSimon L. B. Nielsen         }
1535db522d3aSSimon L. B. Nielsen #endif
153609286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
15376f9291ceSJung-uk Kim         else if (strcmp(*argv, "-use_srtp") == 0) {
15386f9291ceSJung-uk Kim             if (--argc < 1)
15396f9291ceSJung-uk Kim                 goto bad;
15401f13597dSJung-uk Kim             srtp_profiles = *(++argv);
15411f13597dSJung-uk Kim         }
154209286989SJung-uk Kim #endif
15436f9291ceSJung-uk Kim         else if (strcmp(*argv, "-keymatexport") == 0) {
15446f9291ceSJung-uk Kim             if (--argc < 1)
15456f9291ceSJung-uk Kim                 goto bad;
15461f13597dSJung-uk Kim             keymatexportlabel = *(++argv);
15476f9291ceSJung-uk Kim         } else if (strcmp(*argv, "-keymatexportlen") == 0) {
15486f9291ceSJung-uk Kim             if (--argc < 1)
15496f9291ceSJung-uk Kim                 goto bad;
15501f13597dSJung-uk Kim             keymatexportlen = atoi(*(++argv));
15516f9291ceSJung-uk Kim             if (keymatexportlen == 0)
15526f9291ceSJung-uk Kim                 goto bad;
15536f9291ceSJung-uk Kim         } else {
155474664626SKris Kennaway             BIO_printf(bio_err, "unknown option %s\n", *argv);
155574664626SKris Kennaway             badop = 1;
155674664626SKris Kennaway             break;
155774664626SKris Kennaway         }
155874664626SKris Kennaway         argc--;
155974664626SKris Kennaway         argv++;
156074664626SKris Kennaway     }
15616f9291ceSJung-uk Kim     if (badop) {
156274664626SKris Kennaway  bad:
156374664626SKris Kennaway         sv_usage();
156474664626SKris Kennaway         goto end;
156574664626SKris Kennaway     }
1566a93cbc2bSJung-uk Kim #ifndef OPENSSL_NO_DTLS1
15676f9291ceSJung-uk Kim     if (www && socket_type == SOCK_DGRAM) {
15686f9291ceSJung-uk Kim         BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n");
1569a93cbc2bSJung-uk Kim         goto end;
1570a93cbc2bSJung-uk Kim     }
1571a93cbc2bSJung-uk Kim #endif
157274664626SKris Kennaway 
15731f13597dSJung-uk Kim #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
15746f9291ceSJung-uk Kim     if (jpake_secret) {
15756f9291ceSJung-uk Kim         if (psk_key) {
15766f9291ceSJung-uk Kim             BIO_printf(bio_err, "Can't use JPAKE and PSK together\n");
15771f13597dSJung-uk Kim             goto end;
15781f13597dSJung-uk Kim         }
15791f13597dSJung-uk Kim         psk_identity = "JPAKE";
15801f13597dSJung-uk Kim     }
15811f13597dSJung-uk Kim #endif
15821f13597dSJung-uk Kim 
15835c87c606SMark Murray     SSL_load_error_strings();
15845c87c606SMark Murray     OpenSSL_add_ssl_algorithms();
15855c87c606SMark Murray 
1586fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
15875c87c606SMark Murray     e = setup_engine(bio_err, engine_id, 1);
1588fceca8a3SJacques Vidrine #endif
15895c87c606SMark Murray 
15906f9291ceSJung-uk Kim     if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) {
15913b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Error getting password\n");
15923b4e3dcbSSimon L. B. Nielsen         goto end;
15933b4e3dcbSSimon L. B. Nielsen     }
15943b4e3dcbSSimon L. B. Nielsen 
15953b4e3dcbSSimon L. B. Nielsen     if (s_key_file == NULL)
15963b4e3dcbSSimon L. B. Nielsen         s_key_file = s_cert_file;
1597db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1598db522d3aSSimon L. B. Nielsen     if (s_key_file2 == NULL)
1599db522d3aSSimon L. B. Nielsen         s_key_file2 = s_cert_file2;
1600db522d3aSSimon L. B. Nielsen #endif
16013b4e3dcbSSimon L. B. Nielsen 
16027bded2dbSJung-uk Kim     if (!load_excert(&exc, bio_err))
16037bded2dbSJung-uk Kim         goto end;
16047bded2dbSJung-uk Kim 
16056f9291ceSJung-uk Kim     if (nocert == 0) {
16063b4e3dcbSSimon L. B. Nielsen         s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
16073b4e3dcbSSimon L. B. Nielsen                          "server certificate private key file");
16086f9291ceSJung-uk Kim         if (!s_key) {
16093b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16103b4e3dcbSSimon L. B. Nielsen             goto end;
16113b4e3dcbSSimon L. B. Nielsen         }
16123b4e3dcbSSimon L. B. Nielsen 
16133b4e3dcbSSimon L. B. Nielsen         s_cert = load_cert(bio_err, s_cert_file, s_cert_format,
16143b4e3dcbSSimon L. B. Nielsen                            NULL, e, "server certificate file");
16153b4e3dcbSSimon L. B. Nielsen 
16166f9291ceSJung-uk Kim         if (!s_cert) {
16173b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16183b4e3dcbSSimon L. B. Nielsen             goto end;
16193b4e3dcbSSimon L. B. Nielsen         }
16207bded2dbSJung-uk Kim         if (s_chain_file) {
16217bded2dbSJung-uk Kim             s_chain = load_certs(bio_err, s_chain_file, FORMAT_PEM,
16227bded2dbSJung-uk Kim                                  NULL, e, "server certificate chain");
16237bded2dbSJung-uk Kim             if (!s_chain)
16247bded2dbSJung-uk Kim                 goto end;
16257bded2dbSJung-uk Kim         }
1626db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
16276f9291ceSJung-uk Kim         if (tlsextcbp.servername) {
1628db522d3aSSimon L. B. Nielsen             s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
1629db522d3aSSimon L. B. Nielsen                               "second server certificate private key file");
16306f9291ceSJung-uk Kim             if (!s_key2) {
1631db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1632db522d3aSSimon L. B. Nielsen                 goto end;
16333b4e3dcbSSimon L. B. Nielsen             }
16343b4e3dcbSSimon L. B. Nielsen 
1635db522d3aSSimon L. B. Nielsen             s_cert2 = load_cert(bio_err, s_cert_file2, s_cert_format,
1636db522d3aSSimon L. B. Nielsen                                 NULL, e, "second server certificate file");
1637db522d3aSSimon L. B. Nielsen 
16386f9291ceSJung-uk Kim             if (!s_cert2) {
1639db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1640db522d3aSSimon L. B. Nielsen                 goto end;
1641db522d3aSSimon L. B. Nielsen             }
1642db522d3aSSimon L. B. Nielsen         }
16437bded2dbSJung-uk Kim #endif                          /* OPENSSL_NO_TLSEXT */
164409286989SJung-uk Kim     }
16457bded2dbSJung-uk Kim #if !defined(OPENSSL_NO_TLSEXT)
16467bded2dbSJung-uk Kim # if !defined(OPENSSL_NO_NEXTPROTONEG)
16476f9291ceSJung-uk Kim     if (next_proto_neg_in) {
16481f13597dSJung-uk Kim         unsigned short len;
164909286989SJung-uk Kim         next_proto.data = next_protos_parse(&len, next_proto_neg_in);
16501f13597dSJung-uk Kim         if (next_proto.data == NULL)
16511f13597dSJung-uk Kim             goto end;
16521f13597dSJung-uk Kim         next_proto.len = len;
16536f9291ceSJung-uk Kim     } else {
16541f13597dSJung-uk Kim         next_proto.data = NULL;
16551f13597dSJung-uk Kim     }
16561f13597dSJung-uk Kim # endif
16577bded2dbSJung-uk Kim     alpn_ctx.data = NULL;
16587bded2dbSJung-uk Kim     if (alpn_in) {
16597bded2dbSJung-uk Kim         unsigned short len;
16607bded2dbSJung-uk Kim         alpn_ctx.data = next_protos_parse(&len, alpn_in);
16617bded2dbSJung-uk Kim         if (alpn_ctx.data == NULL)
16627bded2dbSJung-uk Kim             goto end;
16637bded2dbSJung-uk Kim         alpn_ctx.len = len;
16647bded2dbSJung-uk Kim     }
16657bded2dbSJung-uk Kim #endif
16667bded2dbSJung-uk Kim 
16677bded2dbSJung-uk Kim     if (crl_file) {
16687bded2dbSJung-uk Kim         X509_CRL *crl;
16697bded2dbSJung-uk Kim         crl = load_crl(crl_file, crl_format);
16707bded2dbSJung-uk Kim         if (!crl) {
16717bded2dbSJung-uk Kim             BIO_puts(bio_err, "Error loading CRL\n");
16727bded2dbSJung-uk Kim             ERR_print_errors(bio_err);
16737bded2dbSJung-uk Kim             goto end;
16747bded2dbSJung-uk Kim         }
16757bded2dbSJung-uk Kim         crls = sk_X509_CRL_new_null();
16767bded2dbSJung-uk Kim         if (!crls || !sk_X509_CRL_push(crls, crl)) {
16777bded2dbSJung-uk Kim             BIO_puts(bio_err, "Error adding CRL\n");
16787bded2dbSJung-uk Kim             ERR_print_errors(bio_err);
16797bded2dbSJung-uk Kim             X509_CRL_free(crl);
16807bded2dbSJung-uk Kim             goto end;
16817bded2dbSJung-uk Kim         }
16827bded2dbSJung-uk Kim     }
16831f13597dSJung-uk Kim 
16846f9291ceSJung-uk Kim     if (s_dcert_file) {
16853b4e3dcbSSimon L. B. Nielsen 
16863b4e3dcbSSimon L. B. Nielsen         if (s_dkey_file == NULL)
16873b4e3dcbSSimon L. B. Nielsen             s_dkey_file = s_dcert_file;
16883b4e3dcbSSimon L. B. Nielsen 
16893b4e3dcbSSimon L. B. Nielsen         s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
16906f9291ceSJung-uk Kim                           0, dpass, e, "second certificate private key file");
16916f9291ceSJung-uk Kim         if (!s_dkey) {
16923b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
16933b4e3dcbSSimon L. B. Nielsen             goto end;
16943b4e3dcbSSimon L. B. Nielsen         }
16953b4e3dcbSSimon L. B. Nielsen 
16963b4e3dcbSSimon L. B. Nielsen         s_dcert = load_cert(bio_err, s_dcert_file, s_dcert_format,
16973b4e3dcbSSimon L. B. Nielsen                             NULL, e, "second server certificate file");
16983b4e3dcbSSimon L. B. Nielsen 
16996f9291ceSJung-uk Kim         if (!s_dcert) {
17003b4e3dcbSSimon L. B. Nielsen             ERR_print_errors(bio_err);
17013b4e3dcbSSimon L. B. Nielsen             goto end;
17023b4e3dcbSSimon L. B. Nielsen         }
17037bded2dbSJung-uk Kim         if (s_dchain_file) {
17047bded2dbSJung-uk Kim             s_dchain = load_certs(bio_err, s_dchain_file, FORMAT_PEM,
17057bded2dbSJung-uk Kim                                   NULL, e, "second server certificate chain");
17067bded2dbSJung-uk Kim             if (!s_dchain)
17077bded2dbSJung-uk Kim                 goto end;
17087bded2dbSJung-uk Kim         }
17093b4e3dcbSSimon L. B. Nielsen 
17103b4e3dcbSSimon L. B. Nielsen     }
17113b4e3dcbSSimon L. B. Nielsen 
17125740a5e3SKris Kennaway     if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
17136f9291ceSJung-uk Kim         && !RAND_status()) {
17146f9291ceSJung-uk Kim         BIO_printf(bio_err,
17156f9291ceSJung-uk Kim                    "warning, not much extra random data, consider using the -rand option\n");
17165740a5e3SKris Kennaway     }
17175740a5e3SKris Kennaway     if (inrand != NULL)
17185740a5e3SKris Kennaway         BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
17195740a5e3SKris Kennaway                    app_RAND_load_files(inrand));
1720f579bf8eSKris Kennaway 
17216f9291ceSJung-uk Kim     if (bio_s_out == NULL) {
17227bded2dbSJung-uk Kim         if (s_quiet && !s_debug) {
172374664626SKris Kennaway             bio_s_out = BIO_new(BIO_s_null());
17247bded2dbSJung-uk Kim             if (s_msg && !bio_s_msg)
17257bded2dbSJung-uk Kim                 bio_s_msg = BIO_new_fp(stdout, BIO_NOCLOSE);
17266f9291ceSJung-uk Kim         } else {
172774664626SKris Kennaway             if (bio_s_out == NULL)
172874664626SKris Kennaway                 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
172974664626SKris Kennaway         }
173074664626SKris Kennaway     }
17313b4e3dcbSSimon L. B. Nielsen #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
173274664626SKris Kennaway     if (nocert)
173374664626SKris Kennaway #endif
173474664626SKris Kennaway     {
173574664626SKris Kennaway         s_cert_file = NULL;
173674664626SKris Kennaway         s_key_file = NULL;
173774664626SKris Kennaway         s_dcert_file = NULL;
173874664626SKris Kennaway         s_dkey_file = NULL;
1739db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1740db522d3aSSimon L. B. Nielsen         s_cert_file2 = NULL;
1741db522d3aSSimon L. B. Nielsen         s_key_file2 = NULL;
1742db522d3aSSimon L. B. Nielsen #endif
174374664626SKris Kennaway     }
174474664626SKris Kennaway 
174574664626SKris Kennaway     ctx = SSL_CTX_new(meth);
17466f9291ceSJung-uk Kim     if (ctx == NULL) {
174774664626SKris Kennaway         ERR_print_errors(bio_err);
174874664626SKris Kennaway         goto end;
174974664626SKris Kennaway     }
17506f9291ceSJung-uk Kim     if (session_id_prefix) {
17515c87c606SMark Murray         if (strlen(session_id_prefix) >= 32)
17525c87c606SMark Murray             BIO_printf(bio_err,
17535c87c606SMark Murray                        "warning: id_prefix is too long, only one new session will be possible\n");
17545c87c606SMark Murray         else if (strlen(session_id_prefix) >= 16)
17555c87c606SMark Murray             BIO_printf(bio_err,
17565c87c606SMark Murray                        "warning: id_prefix is too long if you use SSLv2\n");
17576f9291ceSJung-uk Kim         if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
17585c87c606SMark Murray             BIO_printf(bio_err, "error setting 'id_prefix'\n");
17595c87c606SMark Murray             ERR_print_errors(bio_err);
17605c87c606SMark Murray             goto end;
17615c87c606SMark Murray         }
17625c87c606SMark Murray         BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
17635c87c606SMark Murray     }
176474664626SKris Kennaway     SSL_CTX_set_quiet_shutdown(ctx, 1);
17656f9291ceSJung-uk Kim     if (hack)
17666f9291ceSJung-uk Kim         SSL_CTX_set_options(ctx, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
17677bded2dbSJung-uk Kim     if (exc)
17687bded2dbSJung-uk Kim         ssl_ctx_set_excert(ctx, exc);
176974664626SKris Kennaway 
17706f9291ceSJung-uk Kim     if (state)
17716f9291ceSJung-uk Kim         SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
17726a599222SSimon L. B. Nielsen     if (no_cache)
17736a599222SSimon L. B. Nielsen         SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
17747bded2dbSJung-uk Kim     else if (ext_cache)
17757bded2dbSJung-uk Kim         init_session_cache_ctx(ctx);
17766a599222SSimon L. B. Nielsen     else
177774664626SKris Kennaway         SSL_CTX_sess_set_cache_size(ctx, 128);
177874664626SKris Kennaway 
177909286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
17801f13597dSJung-uk Kim     if (srtp_profiles != NULL)
17811f13597dSJung-uk Kim         SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
178209286989SJung-uk Kim #endif
17831f13597dSJung-uk Kim 
178474664626SKris Kennaway #if 0
17856f9291ceSJung-uk Kim     if (cipher == NULL)
17866f9291ceSJung-uk Kim         cipher = getenv("SSL_CIPHER");
178774664626SKris Kennaway #endif
178874664626SKris Kennaway 
178974664626SKris Kennaway #if 0
17906f9291ceSJung-uk Kim     if (s_cert_file == NULL) {
17916f9291ceSJung-uk Kim         BIO_printf(bio_err,
17926f9291ceSJung-uk Kim                    "You must specify a certificate file for the server to use\n");
179374664626SKris Kennaway         goto end;
179474664626SKris Kennaway     }
179574664626SKris Kennaway #endif
179674664626SKris Kennaway 
179774664626SKris Kennaway     if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) ||
17986f9291ceSJung-uk Kim         (!SSL_CTX_set_default_verify_paths(ctx))) {
179974664626SKris Kennaway         /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
180074664626SKris Kennaway         ERR_print_errors(bio_err);
180174664626SKris Kennaway         /* goto end; */
180274664626SKris Kennaway     }
18031f13597dSJung-uk Kim     if (vpm)
18041f13597dSJung-uk Kim         SSL_CTX_set1_param(ctx, vpm);
18051f13597dSJung-uk Kim 
18067bded2dbSJung-uk Kim     ssl_ctx_add_crls(ctx, crls, 0);
18077bded2dbSJung-uk Kim 
18087bded2dbSJung-uk Kim     if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe, no_jpake))
18097bded2dbSJung-uk Kim         goto end;
18107bded2dbSJung-uk Kim 
18117bded2dbSJung-uk Kim     if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
18127bded2dbSJung-uk Kim                          crls, crl_download)) {
18137bded2dbSJung-uk Kim         BIO_printf(bio_err, "Error loading store locations\n");
18147bded2dbSJung-uk Kim         ERR_print_errors(bio_err);
18157bded2dbSJung-uk Kim         goto end;
18167bded2dbSJung-uk Kim     }
1817db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
18186f9291ceSJung-uk Kim     if (s_cert2) {
1819db522d3aSSimon L. B. Nielsen         ctx2 = SSL_CTX_new(meth);
18206f9291ceSJung-uk Kim         if (ctx2 == NULL) {
1821db522d3aSSimon L. B. Nielsen             ERR_print_errors(bio_err);
1822db522d3aSSimon L. B. Nielsen             goto end;
1823db522d3aSSimon L. B. Nielsen         }
1824db522d3aSSimon L. B. Nielsen     }
1825db522d3aSSimon L. B. Nielsen 
18266f9291ceSJung-uk Kim     if (ctx2) {
1827db522d3aSSimon L. B. Nielsen         BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
1828db522d3aSSimon L. B. Nielsen 
18296f9291ceSJung-uk Kim         if (session_id_prefix) {
1830db522d3aSSimon L. B. Nielsen             if (strlen(session_id_prefix) >= 32)
1831db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err,
1832db522d3aSSimon L. B. Nielsen                            "warning: id_prefix is too long, only one new session will be possible\n");
1833db522d3aSSimon L. B. Nielsen             else if (strlen(session_id_prefix) >= 16)
1834db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err,
1835db522d3aSSimon L. B. Nielsen                            "warning: id_prefix is too long if you use SSLv2\n");
18366f9291ceSJung-uk Kim             if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) {
1837db522d3aSSimon L. B. Nielsen                 BIO_printf(bio_err, "error setting 'id_prefix'\n");
1838db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1839db522d3aSSimon L. B. Nielsen                 goto end;
1840db522d3aSSimon L. B. Nielsen             }
1841db522d3aSSimon L. B. Nielsen             BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
1842db522d3aSSimon L. B. Nielsen         }
1843db522d3aSSimon L. B. Nielsen         SSL_CTX_set_quiet_shutdown(ctx2, 1);
18446f9291ceSJung-uk Kim         if (hack)
18456f9291ceSJung-uk Kim             SSL_CTX_set_options(ctx2, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
18467bded2dbSJung-uk Kim         if (exc)
18477bded2dbSJung-uk Kim             ssl_ctx_set_excert(ctx2, exc);
1848db522d3aSSimon L. B. Nielsen 
18496f9291ceSJung-uk Kim         if (state)
18506f9291ceSJung-uk Kim             SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
1851db522d3aSSimon L. B. Nielsen 
18526a599222SSimon L. B. Nielsen         if (no_cache)
18536a599222SSimon L. B. Nielsen             SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
18547bded2dbSJung-uk Kim         else if (ext_cache)
18557bded2dbSJung-uk Kim             init_session_cache_ctx(ctx2);
18566a599222SSimon L. B. Nielsen         else
1857db522d3aSSimon L. B. Nielsen             SSL_CTX_sess_set_cache_size(ctx2, 128);
1858db522d3aSSimon L. B. Nielsen 
1859db522d3aSSimon L. B. Nielsen         if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) ||
18606f9291ceSJung-uk Kim             (!SSL_CTX_set_default_verify_paths(ctx2))) {
1861db522d3aSSimon L. B. Nielsen             ERR_print_errors(bio_err);
1862db522d3aSSimon L. B. Nielsen         }
18631f13597dSJung-uk Kim         if (vpm)
18641f13597dSJung-uk Kim             SSL_CTX_set1_param(ctx2, vpm);
18657bded2dbSJung-uk Kim 
18667bded2dbSJung-uk Kim         ssl_ctx_add_crls(ctx2, crls, 0);
18677bded2dbSJung-uk Kim 
18687bded2dbSJung-uk Kim         if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe, no_jpake))
18697bded2dbSJung-uk Kim             goto end;
18707bded2dbSJung-uk Kim 
1871db522d3aSSimon L. B. Nielsen     }
18721f13597dSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
18731f13597dSJung-uk Kim     if (next_proto.data)
18746f9291ceSJung-uk Kim         SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb,
18756f9291ceSJung-uk Kim                                               &next_proto);
18761f13597dSJung-uk Kim # endif
18777bded2dbSJung-uk Kim     if (alpn_ctx.data)
18787bded2dbSJung-uk Kim         SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
18791f13597dSJung-uk Kim #endif
188074664626SKris Kennaway 
18815c87c606SMark Murray #ifndef OPENSSL_NO_DH
18826f9291ceSJung-uk Kim     if (!no_dhe) {
18835c87c606SMark Murray         DH *dh = NULL;
18845c87c606SMark Murray 
18855c87c606SMark Murray         if (dhfile)
18865c87c606SMark Murray             dh = load_dh_param(dhfile);
18875c87c606SMark Murray         else if (s_cert_file)
18885c87c606SMark Murray             dh = load_dh_param(s_cert_file);
18895c87c606SMark Murray 
18906f9291ceSJung-uk Kim         if (dh != NULL) {
189174664626SKris Kennaway             BIO_printf(bio_s_out, "Setting temp DH parameters\n");
18926f9291ceSJung-uk Kim         } else {
189374664626SKris Kennaway             BIO_printf(bio_s_out, "Using default temp DH parameters\n");
1894ed6b93beSJung-uk Kim             dh = get_dh2048();
1895ed6b93beSJung-uk Kim             if (dh == NULL) {
1896ed6b93beSJung-uk Kim                 ERR_print_errors(bio_err);
1897ed6b93beSJung-uk Kim                 goto end;
1898ed6b93beSJung-uk Kim             }
189974664626SKris Kennaway         }
190074664626SKris Kennaway         (void)BIO_flush(bio_s_out);
190174664626SKris Kennaway 
190274664626SKris Kennaway         SSL_CTX_set_tmp_dh(ctx, dh);
1903db522d3aSSimon L. B. Nielsen # ifndef OPENSSL_NO_TLSEXT
19046f9291ceSJung-uk Kim         if (ctx2) {
19056f9291ceSJung-uk Kim             if (!dhfile) {
1906db522d3aSSimon L. B. Nielsen                 DH *dh2 = load_dh_param(s_cert_file2);
19076f9291ceSJung-uk Kim                 if (dh2 != NULL) {
1908db522d3aSSimon L. B. Nielsen                     BIO_printf(bio_s_out, "Setting temp DH parameters\n");
1909db522d3aSSimon L. B. Nielsen                     (void)BIO_flush(bio_s_out);
1910db522d3aSSimon L. B. Nielsen 
1911db522d3aSSimon L. B. Nielsen                     DH_free(dh);
1912db522d3aSSimon L. B. Nielsen                     dh = dh2;
1913db522d3aSSimon L. B. Nielsen                 }
1914db522d3aSSimon L. B. Nielsen             }
1915db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tmp_dh(ctx2, dh);
1916db522d3aSSimon L. B. Nielsen         }
1917db522d3aSSimon L. B. Nielsen # endif
191874664626SKris Kennaway         DH_free(dh);
191974664626SKris Kennaway     }
192074664626SKris Kennaway #endif
192174664626SKris Kennaway 
19227bded2dbSJung-uk Kim     if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
19233b4e3dcbSSimon L. B. Nielsen         goto end;
1924db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
19257bded2dbSJung-uk Kim     if (s_serverinfo_file != NULL
19267bded2dbSJung-uk Kim         && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) {
19277bded2dbSJung-uk Kim         ERR_print_errors(bio_err);
19287bded2dbSJung-uk Kim         goto end;
19297bded2dbSJung-uk Kim     }
19307bded2dbSJung-uk Kim #endif
19317bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
19327bded2dbSJung-uk Kim     if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain))
1933db522d3aSSimon L. B. Nielsen         goto end;
1934db522d3aSSimon L. B. Nielsen #endif
19356f9291ceSJung-uk Kim     if (s_dcert != NULL) {
19367bded2dbSJung-uk Kim         if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain))
193774664626SKris Kennaway             goto end;
193874664626SKris Kennaway     }
19395c87c606SMark Murray #ifndef OPENSSL_NO_RSA
194074664626SKris Kennaway # if 1
19416f9291ceSJung-uk Kim     if (!no_tmp_rsa) {
194274664626SKris Kennaway         SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
1943db522d3aSSimon L. B. Nielsen #  ifndef OPENSSL_NO_TLSEXT
1944db522d3aSSimon L. B. Nielsen         if (ctx2)
1945db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tmp_rsa_callback(ctx2, tmp_rsa_cb);
1946db522d3aSSimon L. B. Nielsen #  endif
1947db522d3aSSimon L. B. Nielsen     }
194874664626SKris Kennaway # else
19496f9291ceSJung-uk Kim     if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) {
195074664626SKris Kennaway         RSA *rsa;
195174664626SKris Kennaway 
195274664626SKris Kennaway         BIO_printf(bio_s_out, "Generating temp (512 bit) RSA key...");
195374664626SKris Kennaway         BIO_flush(bio_s_out);
195474664626SKris Kennaway 
195574664626SKris Kennaway         rsa = RSA_generate_key(512, RSA_F4, NULL);
195674664626SKris Kennaway 
19576f9291ceSJung-uk Kim         if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
195874664626SKris Kennaway             ERR_print_errors(bio_err);
195974664626SKris Kennaway             goto end;
196074664626SKris Kennaway         }
1961db522d3aSSimon L. B. Nielsen #  ifndef OPENSSL_NO_TLSEXT
19626f9291ceSJung-uk Kim         if (ctx2) {
19636f9291ceSJung-uk Kim             if (!SSL_CTX_set_tmp_rsa(ctx2, rsa)) {
1964db522d3aSSimon L. B. Nielsen                 ERR_print_errors(bio_err);
1965db522d3aSSimon L. B. Nielsen                 goto end;
1966db522d3aSSimon L. B. Nielsen             }
1967db522d3aSSimon L. B. Nielsen         }
1968db522d3aSSimon L. B. Nielsen #  endif
196974664626SKris Kennaway         RSA_free(rsa);
197074664626SKris Kennaway         BIO_printf(bio_s_out, "\n");
197174664626SKris Kennaway     }
197274664626SKris Kennaway # endif
197374664626SKris Kennaway #endif
197474664626SKris Kennaway 
19751f13597dSJung-uk Kim #ifndef OPENSSL_NO_PSK
19761f13597dSJung-uk Kim # ifdef OPENSSL_NO_JPAKE
19771f13597dSJung-uk Kim     if (psk_key != NULL)
19781f13597dSJung-uk Kim # else
19791f13597dSJung-uk Kim     if (psk_key != NULL || jpake_secret)
19801f13597dSJung-uk Kim # endif
19811f13597dSJung-uk Kim     {
19821f13597dSJung-uk Kim         if (s_debug)
19836f9291ceSJung-uk Kim             BIO_printf(bio_s_out,
19846f9291ceSJung-uk Kim                        "PSK key given or JPAKE in use, setting server callback\n");
19851f13597dSJung-uk Kim         SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
19861f13597dSJung-uk Kim     }
19871f13597dSJung-uk Kim 
19886f9291ceSJung-uk Kim     if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
19891f13597dSJung-uk Kim         BIO_printf(bio_err, "error setting PSK identity hint to context\n");
19901f13597dSJung-uk Kim         ERR_print_errors(bio_err);
19911f13597dSJung-uk Kim         goto end;
19921f13597dSJung-uk Kim     }
19931f13597dSJung-uk Kim #endif
19941f13597dSJung-uk Kim 
199574664626SKris Kennaway     SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
199674664626SKris Kennaway     SSL_CTX_set_session_id_context(ctx, (void *)&s_server_session_id_context,
199774664626SKris Kennaway                                    sizeof s_server_session_id_context);
199874664626SKris Kennaway 
19996a599222SSimon L. B. Nielsen     /* Set DTLS cookie generation and verification callbacks */
20006a599222SSimon L. B. Nielsen     SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
20016a599222SSimon L. B. Nielsen     SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
20026a599222SSimon L. B. Nielsen 
2003db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
20046f9291ceSJung-uk Kim     if (ctx2) {
2005db522d3aSSimon L. B. Nielsen         SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
20066f9291ceSJung-uk Kim         SSL_CTX_set_session_id_context(ctx2,
20076f9291ceSJung-uk Kim                                        (void *)&s_server_session_id_context,
2008db522d3aSSimon L. B. Nielsen                                        sizeof s_server_session_id_context);
200974664626SKris Kennaway 
2010db522d3aSSimon L. B. Nielsen         tlsextcbp.biodebug = bio_s_out;
2011db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
2012db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
2013db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
2014db522d3aSSimon L. B. Nielsen         SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
2015db522d3aSSimon L. B. Nielsen     }
2016db522d3aSSimon L. B. Nielsen #endif
20171f13597dSJung-uk Kim 
20181f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
20196f9291ceSJung-uk Kim     if (srp_verifier_file != NULL) {
20201f13597dSJung-uk Kim         srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
20211f13597dSJung-uk Kim         srp_callback_parm.user = NULL;
20221f13597dSJung-uk Kim         srp_callback_parm.login = NULL;
20236f9291ceSJung-uk Kim         if ((ret =
20246f9291ceSJung-uk Kim              SRP_VBASE_init(srp_callback_parm.vb,
20256f9291ceSJung-uk Kim                             srp_verifier_file)) != SRP_NO_ERROR) {
20261f13597dSJung-uk Kim             BIO_printf(bio_err,
20271f13597dSJung-uk Kim                        "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
20281f13597dSJung-uk Kim                        srp_verifier_file, ret);
20291f13597dSJung-uk Kim             goto end;
20301f13597dSJung-uk Kim         }
20311f13597dSJung-uk Kim         SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
20321f13597dSJung-uk Kim         SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
20331f13597dSJung-uk Kim         SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
20346f9291ceSJung-uk Kim     } else
20351f13597dSJung-uk Kim #endif
20366f9291ceSJung-uk Kim     if (CAfile != NULL) {
2037db522d3aSSimon L. B. Nielsen         SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile));
2038db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
2039db522d3aSSimon L. B. Nielsen         if (ctx2)
2040db522d3aSSimon L. B. Nielsen             SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile));
2041db522d3aSSimon L. B. Nielsen #endif
2042db522d3aSSimon L. B. Nielsen     }
20431f13597dSJung-uk Kim 
204474664626SKris Kennaway     BIO_printf(bio_s_out, "ACCEPT\n");
20451f13597dSJung-uk Kim     (void)BIO_flush(bio_s_out);
20467bded2dbSJung-uk Kim     if (rev)
20477bded2dbSJung-uk Kim         do_server(port, socket_type, &accept_socket, rev_body, context,
20487bded2dbSJung-uk Kim                   naccept);
20497bded2dbSJung-uk Kim     else if (www)
20507bded2dbSJung-uk Kim         do_server(port, socket_type, &accept_socket, www_body, context,
20517bded2dbSJung-uk Kim                   naccept);
205274664626SKris Kennaway     else
20537bded2dbSJung-uk Kim         do_server(port, socket_type, &accept_socket, sv_body, context,
20547bded2dbSJung-uk Kim                   naccept);
205574664626SKris Kennaway     print_stats(bio_s_out, ctx);
205674664626SKris Kennaway     ret = 0;
205774664626SKris Kennaway  end:
20586f9291ceSJung-uk Kim     if (ctx != NULL)
20596f9291ceSJung-uk Kim         SSL_CTX_free(ctx);
20603b4e3dcbSSimon L. B. Nielsen     if (s_cert)
20613b4e3dcbSSimon L. B. Nielsen         X509_free(s_cert);
20627bded2dbSJung-uk Kim     if (crls)
20637bded2dbSJung-uk Kim         sk_X509_CRL_pop_free(crls, X509_CRL_free);
20643b4e3dcbSSimon L. B. Nielsen     if (s_dcert)
20653b4e3dcbSSimon L. B. Nielsen         X509_free(s_dcert);
20663b4e3dcbSSimon L. B. Nielsen     if (s_key)
20673b4e3dcbSSimon L. B. Nielsen         EVP_PKEY_free(s_key);
20683b4e3dcbSSimon L. B. Nielsen     if (s_dkey)
20693b4e3dcbSSimon L. B. Nielsen         EVP_PKEY_free(s_dkey);
20707bded2dbSJung-uk Kim     if (s_chain)
20717bded2dbSJung-uk Kim         sk_X509_pop_free(s_chain, X509_free);
20727bded2dbSJung-uk Kim     if (s_dchain)
20737bded2dbSJung-uk Kim         sk_X509_pop_free(s_dchain, X509_free);
20743b4e3dcbSSimon L. B. Nielsen     if (pass)
20753b4e3dcbSSimon L. B. Nielsen         OPENSSL_free(pass);
20763b4e3dcbSSimon L. B. Nielsen     if (dpass)
20773b4e3dcbSSimon L. B. Nielsen         OPENSSL_free(dpass);
207809286989SJung-uk Kim     if (vpm)
207909286989SJung-uk Kim         X509_VERIFY_PARAM_free(vpm);
20807bded2dbSJung-uk Kim     free_sessions();
2081db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
208209286989SJung-uk Kim     if (tlscstatp.host)
208309286989SJung-uk Kim         OPENSSL_free(tlscstatp.host);
208409286989SJung-uk Kim     if (tlscstatp.port)
208509286989SJung-uk Kim         OPENSSL_free(tlscstatp.port);
208609286989SJung-uk Kim     if (tlscstatp.path)
208709286989SJung-uk Kim         OPENSSL_free(tlscstatp.path);
20886f9291ceSJung-uk Kim     if (ctx2 != NULL)
20896f9291ceSJung-uk Kim         SSL_CTX_free(ctx2);
2090db522d3aSSimon L. B. Nielsen     if (s_cert2)
2091db522d3aSSimon L. B. Nielsen         X509_free(s_cert2);
2092db522d3aSSimon L. B. Nielsen     if (s_key2)
2093db522d3aSSimon L. B. Nielsen         EVP_PKEY_free(s_key2);
20947bded2dbSJung-uk Kim     if (serverinfo_in != NULL)
20957bded2dbSJung-uk Kim         BIO_free(serverinfo_in);
20967bded2dbSJung-uk Kim # ifndef OPENSSL_NO_NEXTPROTONEG
20977bded2dbSJung-uk Kim     if (next_proto.data)
20987bded2dbSJung-uk Kim         OPENSSL_free(next_proto.data);
20997bded2dbSJung-uk Kim # endif
21007bded2dbSJung-uk Kim     if (alpn_ctx.data)
21017bded2dbSJung-uk Kim         OPENSSL_free(alpn_ctx.data);
21027bded2dbSJung-uk Kim #endif
21037bded2dbSJung-uk Kim     ssl_excert_free(exc);
21047bded2dbSJung-uk Kim     if (ssl_args)
21057bded2dbSJung-uk Kim         sk_OPENSSL_STRING_free(ssl_args);
21067bded2dbSJung-uk Kim     if (cctx)
21077bded2dbSJung-uk Kim         SSL_CONF_CTX_free(cctx);
21087bded2dbSJung-uk Kim #ifndef OPENSSL_NO_JPAKE
21097bded2dbSJung-uk Kim     if (jpake_secret && psk_key)
21107bded2dbSJung-uk Kim         OPENSSL_free(psk_key);
2111db522d3aSSimon L. B. Nielsen #endif
21126f9291ceSJung-uk Kim     if (bio_s_out != NULL) {
211374664626SKris Kennaway         BIO_free(bio_s_out);
211474664626SKris Kennaway         bio_s_out = NULL;
211574664626SKris Kennaway     }
21167bded2dbSJung-uk Kim     if (bio_s_msg != NULL) {
21177bded2dbSJung-uk Kim         BIO_free(bio_s_msg);
21187bded2dbSJung-uk Kim         bio_s_msg = NULL;
21197bded2dbSJung-uk Kim     }
21205c87c606SMark Murray     apps_shutdown();
21215c87c606SMark Murray     OPENSSL_EXIT(ret);
212274664626SKris Kennaway }
212374664626SKris Kennaway 
212474664626SKris Kennaway static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
212574664626SKris Kennaway {
212674664626SKris Kennaway     BIO_printf(bio, "%4ld items in the session cache\n",
212774664626SKris Kennaway                SSL_CTX_sess_number(ssl_ctx));
21283b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
212974664626SKris Kennaway                SSL_CTX_sess_connect(ssl_ctx));
21303b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
213174664626SKris Kennaway                SSL_CTX_sess_connect_renegotiate(ssl_ctx));
21323b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld client connects that finished\n",
213374664626SKris Kennaway                SSL_CTX_sess_connect_good(ssl_ctx));
21343b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
213574664626SKris Kennaway                SSL_CTX_sess_accept(ssl_ctx));
21363b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
213774664626SKris Kennaway                SSL_CTX_sess_accept_renegotiate(ssl_ctx));
21383b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld server accepts that finished\n",
213974664626SKris Kennaway                SSL_CTX_sess_accept_good(ssl_ctx));
21403b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx));
21416f9291ceSJung-uk Kim     BIO_printf(bio, "%4ld session cache misses\n",
21426f9291ceSJung-uk Kim                SSL_CTX_sess_misses(ssl_ctx));
21436f9291ceSJung-uk Kim     BIO_printf(bio, "%4ld session cache timeouts\n",
21446f9291ceSJung-uk Kim                SSL_CTX_sess_timeouts(ssl_ctx));
21456f9291ceSJung-uk Kim     BIO_printf(bio, "%4ld callback cache hits\n",
21466f9291ceSJung-uk Kim                SSL_CTX_sess_cb_hits(ssl_ctx));
21473b4e3dcbSSimon L. B. Nielsen     BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
214874664626SKris Kennaway                SSL_CTX_sess_cache_full(ssl_ctx),
214974664626SKris Kennaway                SSL_CTX_sess_get_cache_size(ssl_ctx));
215074664626SKris Kennaway }
215174664626SKris Kennaway 
21527bded2dbSJung-uk Kim static int sv_body(char *hostname, int s, int stype, unsigned char *context)
215374664626SKris Kennaway {
215474664626SKris Kennaway     char *buf = NULL;
215574664626SKris Kennaway     fd_set readfds;
215674664626SKris Kennaway     int ret = 1, width;
215774664626SKris Kennaway     int k, i;
215874664626SKris Kennaway     unsigned long l;
215974664626SKris Kennaway     SSL *con = NULL;
216074664626SKris Kennaway     BIO *sbio;
21611f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
21621f13597dSJung-uk Kim     KSSL_CTX *kctx;
21631f13597dSJung-uk Kim #endif
21646a599222SSimon L. B. Nielsen     struct timeval timeout;
21651f13597dSJung-uk Kim #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
2166f579bf8eSKris Kennaway     struct timeval tv;
21676a599222SSimon L. B. Nielsen #else
21686a599222SSimon L. B. Nielsen     struct timeval *timeoutp;
2169f579bf8eSKris Kennaway #endif
217074664626SKris Kennaway 
21716f9291ceSJung-uk Kim     if ((buf = OPENSSL_malloc(bufsize)) == NULL) {
217274664626SKris Kennaway         BIO_printf(bio_err, "out of memory\n");
217374664626SKris Kennaway         goto err;
217474664626SKris Kennaway     }
217574664626SKris Kennaway #ifdef FIONBIO
21766f9291ceSJung-uk Kim     if (s_nbio) {
217774664626SKris Kennaway         unsigned long sl = 1;
217874664626SKris Kennaway 
217974664626SKris Kennaway         if (!s_quiet)
218074664626SKris Kennaway             BIO_printf(bio_err, "turning on non blocking io\n");
218174664626SKris Kennaway         if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0)
218274664626SKris Kennaway             ERR_print_errors(bio_err);
218374664626SKris Kennaway     }
218474664626SKris Kennaway #endif
218574664626SKris Kennaway 
218674664626SKris Kennaway     if (con == NULL) {
2187f579bf8eSKris Kennaway         con = SSL_new(ctx);
2188db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
21896f9291ceSJung-uk Kim         if (s_tlsextdebug) {
2190db522d3aSSimon L. B. Nielsen             SSL_set_tlsext_debug_callback(con, tlsext_cb);
2191db522d3aSSimon L. B. Nielsen             SSL_set_tlsext_debug_arg(con, bio_s_out);
2192db522d3aSSimon L. B. Nielsen         }
21936f9291ceSJung-uk Kim         if (s_tlsextstatus) {
2194db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
2195db522d3aSSimon L. B. Nielsen             tlscstatp.err = bio_err;
2196db522d3aSSimon L. B. Nielsen             SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
2197db522d3aSSimon L. B. Nielsen         }
2198db522d3aSSimon L. B. Nielsen #endif
21995c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
22006f9291ceSJung-uk Kim         if ((kctx = kssl_ctx_new()) != NULL) {
22011f13597dSJung-uk Kim             SSL_set0_kssl_ctx(con, kctx);
22021f13597dSJung-uk Kim             kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
22031f13597dSJung-uk Kim             kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
22045c87c606SMark Murray         }
22055c87c606SMark Murray #endif                          /* OPENSSL_NO_KRB5 */
220674664626SKris Kennaway         if (context)
22076f9291ceSJung-uk Kim             SSL_set_session_id_context(con, context, strlen((char *)context));
220874664626SKris Kennaway     }
220974664626SKris Kennaway     SSL_clear(con);
22101f13597dSJung-uk Kim #if 0
22111f13597dSJung-uk Kim # ifdef TLSEXT_TYPE_opaque_prf_input
22121f13597dSJung-uk Kim     SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
22131f13597dSJung-uk Kim # endif
22141f13597dSJung-uk Kim #endif
221574664626SKris Kennaway 
22167bded2dbSJung-uk Kim     if (stype == SOCK_DGRAM) {
22173b4e3dcbSSimon L. B. Nielsen 
22183b4e3dcbSSimon L. B. Nielsen         sbio = BIO_new_dgram(s, BIO_NOCLOSE);
22193b4e3dcbSSimon L. B. Nielsen 
22206f9291ceSJung-uk Kim         if (enable_timeouts) {
22213b4e3dcbSSimon L. B. Nielsen             timeout.tv_sec = 0;
22223b4e3dcbSSimon L. B. Nielsen             timeout.tv_usec = DGRAM_RCV_TIMEOUT;
22233b4e3dcbSSimon L. B. Nielsen             BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
22243b4e3dcbSSimon L. B. Nielsen 
22253b4e3dcbSSimon L. B. Nielsen             timeout.tv_sec = 0;
22263b4e3dcbSSimon L. B. Nielsen             timeout.tv_usec = DGRAM_SND_TIMEOUT;
22273b4e3dcbSSimon L. B. Nielsen             BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
22283b4e3dcbSSimon L. B. Nielsen         }
22293b4e3dcbSSimon L. B. Nielsen 
22306f9291ceSJung-uk Kim         if (socket_mtu) {
22316f9291ceSJung-uk Kim             if (socket_mtu < DTLS_get_link_min_mtu(con)) {
2232751d2991SJung-uk Kim                 BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
2233751d2991SJung-uk Kim                            DTLS_get_link_min_mtu(con));
2234751d2991SJung-uk Kim                 ret = -1;
2235751d2991SJung-uk Kim                 BIO_free(sbio);
2236751d2991SJung-uk Kim                 goto err;
2237751d2991SJung-uk Kim             }
22383b4e3dcbSSimon L. B. Nielsen             SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
22396f9291ceSJung-uk Kim             if (!DTLS_set_link_mtu(con, socket_mtu)) {
2240751d2991SJung-uk Kim                 BIO_printf(bio_err, "Failed to set MTU\n");
2241751d2991SJung-uk Kim                 ret = -1;
2242751d2991SJung-uk Kim                 BIO_free(sbio);
2243751d2991SJung-uk Kim                 goto err;
2244751d2991SJung-uk Kim             }
22456f9291ceSJung-uk Kim         } else
22463b4e3dcbSSimon L. B. Nielsen             /* want to do MTU discovery */
22473b4e3dcbSSimon L. B. Nielsen             BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
22483b4e3dcbSSimon L. B. Nielsen 
22493b4e3dcbSSimon L. B. Nielsen         /* turn on cookie exchange */
22503b4e3dcbSSimon L. B. Nielsen         SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
22516f9291ceSJung-uk Kim     } else
225274664626SKris Kennaway         sbio = BIO_new_socket(s, BIO_NOCLOSE);
22533b4e3dcbSSimon L. B. Nielsen 
22546f9291ceSJung-uk Kim     if (s_nbio_test) {
225574664626SKris Kennaway         BIO *test;
225674664626SKris Kennaway 
225774664626SKris Kennaway         test = BIO_new(BIO_f_nbio_test());
225874664626SKris Kennaway         sbio = BIO_push(test, sbio);
225974664626SKris Kennaway     }
2260db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
2261db522d3aSSimon L. B. Nielsen     if (jpake_secret)
2262db522d3aSSimon L. B. Nielsen         jpake_server_auth(bio_s_out, sbio, jpake_secret);
2263db522d3aSSimon L. B. Nielsen #endif
2264db522d3aSSimon L. B. Nielsen 
226574664626SKris Kennaway     SSL_set_bio(con, sbio, sbio);
226674664626SKris Kennaway     SSL_set_accept_state(con);
226774664626SKris Kennaway     /* SSL_set_fd(con,s); */
226874664626SKris Kennaway 
22696f9291ceSJung-uk Kim     if (s_debug) {
22701f13597dSJung-uk Kim         SSL_set_debug(con, 1);
22713b4e3dcbSSimon L. B. Nielsen         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
22725471f83eSSimon L. B. Nielsen         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
227374664626SKris Kennaway     }
22746f9291ceSJung-uk Kim     if (s_msg) {
22757bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
22767bded2dbSJung-uk Kim         if (s_msg == 2)
22777bded2dbSJung-uk Kim             SSL_set_msg_callback(con, SSL_trace);
22787bded2dbSJung-uk Kim         else
22797bded2dbSJung-uk Kim #endif
22805c87c606SMark Murray             SSL_set_msg_callback(con, msg_cb);
22817bded2dbSJung-uk Kim         SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
22825c87c606SMark Murray     }
2283db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
22846f9291ceSJung-uk Kim     if (s_tlsextdebug) {
2285db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_callback(con, tlsext_cb);
2286db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_arg(con, bio_s_out);
2287db522d3aSSimon L. B. Nielsen     }
2288db522d3aSSimon L. B. Nielsen #endif
228974664626SKris Kennaway 
229074664626SKris Kennaway     width = s + 1;
22916f9291ceSJung-uk Kim     for (;;) {
2292f579bf8eSKris Kennaway         int read_from_terminal;
2293f579bf8eSKris Kennaway         int read_from_sslcon;
2294f579bf8eSKris Kennaway 
2295f579bf8eSKris Kennaway         read_from_terminal = 0;
2296f579bf8eSKris Kennaway         read_from_sslcon = SSL_pending(con);
2297f579bf8eSKris Kennaway 
22986f9291ceSJung-uk Kim         if (!read_from_sslcon) {
229974664626SKris Kennaway             FD_ZERO(&readfds);
23001f13597dSJung-uk Kim #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
23011f13597dSJung-uk Kim             openssl_fdset(fileno(stdin), &readfds);
230274664626SKris Kennaway #endif
23031f13597dSJung-uk Kim             openssl_fdset(s, &readfds);
23046f9291ceSJung-uk Kim             /*
23056f9291ceSJung-uk Kim              * Note: under VMS with SOCKETSHR the second parameter is
23066f9291ceSJung-uk Kim              * currently of type (int *) whereas under other systems it is
23076f9291ceSJung-uk Kim              * (void *) if you don't have a cast it will choke the compiler:
23086f9291ceSJung-uk Kim              * if you do have a cast then you can either go for (int *) or
23096f9291ceSJung-uk Kim              * (void *).
231074664626SKris Kennaway              */
23113b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
23126f9291ceSJung-uk Kim             /*
23136f9291ceSJung-uk Kim              * Under DOS (non-djgpp) and Windows we can't select on stdin:
23146f9291ceSJung-uk Kim              * only on sockets. As a workaround we timeout the select every
2315f579bf8eSKris Kennaway              * second and check for any keypress. In a proper Windows
2316f579bf8eSKris Kennaway              * application we wouldn't do this because it is inefficient.
2317f579bf8eSKris Kennaway              */
2318f579bf8eSKris Kennaway             tv.tv_sec = 1;
2319f579bf8eSKris Kennaway             tv.tv_usec = 0;
2320f579bf8eSKris Kennaway             i = select(width, (void *)&readfds, NULL, NULL, &tv);
23216f9291ceSJung-uk Kim             if ((i < 0) || (!i && !_kbhit()))
23226f9291ceSJung-uk Kim                 continue;
2323f579bf8eSKris Kennaway             if (_kbhit())
2324f579bf8eSKris Kennaway                 read_from_terminal = 1;
23251f13597dSJung-uk Kim #elif defined(OPENSSL_SYS_BEOS_R5)
23261f13597dSJung-uk Kim             /* Under BeOS-R5 the situation is similar to DOS */
23271f13597dSJung-uk Kim             tv.tv_sec = 1;
23281f13597dSJung-uk Kim             tv.tv_usec = 0;
23291f13597dSJung-uk Kim             (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
23301f13597dSJung-uk Kim             i = select(width, (void *)&readfds, NULL, NULL, &tv);
23311f13597dSJung-uk Kim             if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
23321f13597dSJung-uk Kim                 continue;
23331f13597dSJung-uk Kim             if (read(fileno(stdin), buf, 0) >= 0)
23341f13597dSJung-uk Kim                 read_from_terminal = 1;
23351f13597dSJung-uk Kim             (void)fcntl(fileno(stdin), F_SETFL, 0);
2336f579bf8eSKris Kennaway #else
23376a599222SSimon L. B. Nielsen             if ((SSL_version(con) == DTLS1_VERSION) &&
23386a599222SSimon L. B. Nielsen                 DTLSv1_get_timeout(con, &timeout))
23396a599222SSimon L. B. Nielsen                 timeoutp = &timeout;
23406a599222SSimon L. B. Nielsen             else
23416a599222SSimon L. B. Nielsen                 timeoutp = NULL;
23426a599222SSimon L. B. Nielsen 
23436a599222SSimon L. B. Nielsen             i = select(width, (void *)&readfds, NULL, NULL, timeoutp);
23446a599222SSimon L. B. Nielsen 
23456f9291ceSJung-uk Kim             if ((SSL_version(con) == DTLS1_VERSION)
23466f9291ceSJung-uk Kim                 && DTLSv1_handle_timeout(con) > 0) {
23476a599222SSimon L. B. Nielsen                 BIO_printf(bio_err, "TIMEOUT occured\n");
23486a599222SSimon L. B. Nielsen             }
23496a599222SSimon L. B. Nielsen 
23506f9291ceSJung-uk Kim             if (i <= 0)
23516f9291ceSJung-uk Kim                 continue;
235274664626SKris Kennaway             if (FD_ISSET(fileno(stdin), &readfds))
2353f579bf8eSKris Kennaway                 read_from_terminal = 1;
2354f579bf8eSKris Kennaway #endif
2355f579bf8eSKris Kennaway             if (FD_ISSET(s, &readfds))
2356f579bf8eSKris Kennaway                 read_from_sslcon = 1;
2357f579bf8eSKris Kennaway         }
23586f9291ceSJung-uk Kim         if (read_from_terminal) {
23596f9291ceSJung-uk Kim             if (s_crlf) {
236074664626SKris Kennaway                 int j, lf_num;
236174664626SKris Kennaway 
23621f13597dSJung-uk Kim                 i = raw_read_stdin(buf, bufsize / 2);
236374664626SKris Kennaway                 lf_num = 0;
236474664626SKris Kennaway                 /* both loops are skipped when i <= 0 */
236574664626SKris Kennaway                 for (j = 0; j < i; j++)
236674664626SKris Kennaway                     if (buf[j] == '\n')
236774664626SKris Kennaway                         lf_num++;
23686f9291ceSJung-uk Kim                 for (j = i - 1; j >= 0; j--) {
236974664626SKris Kennaway                     buf[j + lf_num] = buf[j];
23706f9291ceSJung-uk Kim                     if (buf[j] == '\n') {
237174664626SKris Kennaway                         lf_num--;
237274664626SKris Kennaway                         i++;
237374664626SKris Kennaway                         buf[j + lf_num] = '\r';
237474664626SKris Kennaway                     }
237574664626SKris Kennaway                 }
237674664626SKris Kennaway                 assert(lf_num == 0);
23776f9291ceSJung-uk Kim             } else
23781f13597dSJung-uk Kim                 i = raw_read_stdin(buf, bufsize);
23797bded2dbSJung-uk Kim             if (!s_quiet && !s_brief) {
23806f9291ceSJung-uk Kim                 if ((i <= 0) || (buf[0] == 'Q')) {
238174664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
238274664626SKris Kennaway                     SHUTDOWN(s);
238374664626SKris Kennaway                     close_accept_socket();
238474664626SKris Kennaway                     ret = -11;
238574664626SKris Kennaway                     goto err;
238674664626SKris Kennaway                 }
23876f9291ceSJung-uk Kim                 if ((i <= 0) || (buf[0] == 'q')) {
238874664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
23893b4e3dcbSSimon L. B. Nielsen                     if (SSL_version(con) != DTLS1_VERSION)
239074664626SKris Kennaway                         SHUTDOWN(s);
23916f9291ceSJung-uk Kim                     /*
23926f9291ceSJung-uk Kim                      * close_accept_socket(); ret= -11;
23936f9291ceSJung-uk Kim                      */
239474664626SKris Kennaway                     goto err;
239574664626SKris Kennaway                 }
23961f13597dSJung-uk Kim #ifndef OPENSSL_NO_HEARTBEATS
23976f9291ceSJung-uk Kim                 if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
23981f13597dSJung-uk Kim                     BIO_printf(bio_err, "HEARTBEATING\n");
23991f13597dSJung-uk Kim                     SSL_heartbeat(con);
24001f13597dSJung-uk Kim                     i = 0;
24011f13597dSJung-uk Kim                     continue;
24021f13597dSJung-uk Kim                 }
24031f13597dSJung-uk Kim #endif
24046f9291ceSJung-uk Kim                 if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
240574664626SKris Kennaway                     SSL_renegotiate(con);
240674664626SKris Kennaway                     i = SSL_do_handshake(con);
240774664626SKris Kennaway                     printf("SSL_do_handshake -> %d\n", i);
240874664626SKris Kennaway                     i = 0;      /* 13; */
240974664626SKris Kennaway                     continue;
24106f9291ceSJung-uk Kim                     /*
24116f9291ceSJung-uk Kim                      * strcpy(buf,"server side RE-NEGOTIATE\n");
24126f9291ceSJung-uk Kim                      */
241374664626SKris Kennaway                 }
24146f9291ceSJung-uk Kim                 if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
241574664626SKris Kennaway                     SSL_set_verify(con,
24166f9291ceSJung-uk Kim                                    SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
24176f9291ceSJung-uk Kim                                    NULL);
241874664626SKris Kennaway                     SSL_renegotiate(con);
241974664626SKris Kennaway                     i = SSL_do_handshake(con);
242074664626SKris Kennaway                     printf("SSL_do_handshake -> %d\n", i);
242174664626SKris Kennaway                     i = 0;      /* 13; */
242274664626SKris Kennaway                     continue;
24236f9291ceSJung-uk Kim                     /*
24246f9291ceSJung-uk Kim                      * strcpy(buf,"server side RE-NEGOTIATE asking for client
24256f9291ceSJung-uk Kim                      * cert\n");
24266f9291ceSJung-uk Kim                      */
242774664626SKris Kennaway                 }
24286f9291ceSJung-uk Kim                 if (buf[0] == 'P') {
24293b4e3dcbSSimon L. B. Nielsen                     static const char *str = "Lets print some clear text\n";
243074664626SKris Kennaway                     BIO_write(SSL_get_wbio(con), str, strlen(str));
243174664626SKris Kennaway                 }
24326f9291ceSJung-uk Kim                 if (buf[0] == 'S') {
243374664626SKris Kennaway                     print_stats(bio_s_out, SSL_get_SSL_CTX(con));
243474664626SKris Kennaway                 }
243574664626SKris Kennaway             }
243674664626SKris Kennaway #ifdef CHARSET_EBCDIC
243774664626SKris Kennaway             ebcdic2ascii(buf, buf, i);
243874664626SKris Kennaway #endif
243974664626SKris Kennaway             l = k = 0;
24406f9291ceSJung-uk Kim             for (;;) {
244174664626SKris Kennaway                 /* should do a select for the write */
244274664626SKris Kennaway #ifdef RENEG
24436f9291ceSJung-uk Kim                 {
24446f9291ceSJung-uk Kim                     static count = 0;
24456f9291ceSJung-uk Kim                     if (++count == 100) {
24466f9291ceSJung-uk Kim                         count = 0;
24476f9291ceSJung-uk Kim                         SSL_renegotiate(con);
24486f9291ceSJung-uk Kim                     }
24496f9291ceSJung-uk Kim                 }
245074664626SKris Kennaway #endif
245174664626SKris Kennaway                 k = SSL_write(con, &(buf[l]), (unsigned int)i);
24521f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
24536f9291ceSJung-uk Kim                 while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) {
24541f13597dSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP renego during write\n");
24556f9291ceSJung-uk Kim                     srp_callback_parm.user =
24566f9291ceSJung-uk Kim                         SRP_VBASE_get_by_user(srp_callback_parm.vb,
24576f9291ceSJung-uk Kim                                               srp_callback_parm.login);
24581f13597dSJung-uk Kim                     if (srp_callback_parm.user)
24596f9291ceSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
24606f9291ceSJung-uk Kim                                    srp_callback_parm.user->info);
24611f13597dSJung-uk Kim                     else
24621f13597dSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
24631f13597dSJung-uk Kim                     k = SSL_write(con, &(buf[l]), (unsigned int)i);
24641f13597dSJung-uk Kim                 }
24651f13597dSJung-uk Kim #endif
24666f9291ceSJung-uk Kim                 switch (SSL_get_error(con, k)) {
246774664626SKris Kennaway                 case SSL_ERROR_NONE:
246874664626SKris Kennaway                     break;
246974664626SKris Kennaway                 case SSL_ERROR_WANT_WRITE:
247074664626SKris Kennaway                 case SSL_ERROR_WANT_READ:
247174664626SKris Kennaway                 case SSL_ERROR_WANT_X509_LOOKUP:
247274664626SKris Kennaway                     BIO_printf(bio_s_out, "Write BLOCK\n");
247374664626SKris Kennaway                     break;
247474664626SKris Kennaway                 case SSL_ERROR_SYSCALL:
247574664626SKris Kennaway                 case SSL_ERROR_SSL:
247674664626SKris Kennaway                     BIO_printf(bio_s_out, "ERROR\n");
247774664626SKris Kennaway                     ERR_print_errors(bio_err);
247874664626SKris Kennaway                     ret = 1;
247974664626SKris Kennaway                     goto err;
248074664626SKris Kennaway                     /* break; */
248174664626SKris Kennaway                 case SSL_ERROR_ZERO_RETURN:
248274664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
248374664626SKris Kennaway                     ret = 1;
248474664626SKris Kennaway                     goto err;
248574664626SKris Kennaway                 }
2486ed6b93beSJung-uk Kim                 if (k > 0) {
248774664626SKris Kennaway                     l += k;
248874664626SKris Kennaway                     i -= k;
2489ed6b93beSJung-uk Kim                 }
24906f9291ceSJung-uk Kim                 if (i <= 0)
24916f9291ceSJung-uk Kim                     break;
249274664626SKris Kennaway             }
249374664626SKris Kennaway         }
24946f9291ceSJung-uk Kim         if (read_from_sslcon) {
24956f9291ceSJung-uk Kim             if (!SSL_is_init_finished(con)) {
249674664626SKris Kennaway                 i = init_ssl_connection(con);
249774664626SKris Kennaway 
24986f9291ceSJung-uk Kim                 if (i < 0) {
249974664626SKris Kennaway                     ret = 0;
250074664626SKris Kennaway                     goto err;
25016f9291ceSJung-uk Kim                 } else if (i == 0) {
250274664626SKris Kennaway                     ret = 1;
250374664626SKris Kennaway                     goto err;
250474664626SKris Kennaway                 }
25056f9291ceSJung-uk Kim             } else {
250674664626SKris Kennaway  again:
250774664626SKris Kennaway                 i = SSL_read(con, (char *)buf, bufsize);
25081f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
25096f9291ceSJung-uk Kim                 while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
25101f13597dSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP renego during read\n");
25116f9291ceSJung-uk Kim                     srp_callback_parm.user =
25126f9291ceSJung-uk Kim                         SRP_VBASE_get_by_user(srp_callback_parm.vb,
25136f9291ceSJung-uk Kim                                               srp_callback_parm.login);
25141f13597dSJung-uk Kim                     if (srp_callback_parm.user)
25156f9291ceSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
25166f9291ceSJung-uk Kim                                    srp_callback_parm.user->info);
25171f13597dSJung-uk Kim                     else
25181f13597dSJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
25191f13597dSJung-uk Kim                     i = SSL_read(con, (char *)buf, bufsize);
25201f13597dSJung-uk Kim                 }
25211f13597dSJung-uk Kim #endif
25226f9291ceSJung-uk Kim                 switch (SSL_get_error(con, i)) {
252374664626SKris Kennaway                 case SSL_ERROR_NONE:
252474664626SKris Kennaway #ifdef CHARSET_EBCDIC
252574664626SKris Kennaway                     ascii2ebcdic(buf, buf, i);
252674664626SKris Kennaway #endif
25276f9291ceSJung-uk Kim                     raw_write_stdout(buf, (unsigned int)i);
25286f9291ceSJung-uk Kim                     if (SSL_pending(con))
25296f9291ceSJung-uk Kim                         goto again;
253074664626SKris Kennaway                     break;
253174664626SKris Kennaway                 case SSL_ERROR_WANT_WRITE:
253274664626SKris Kennaway                 case SSL_ERROR_WANT_READ:
253374664626SKris Kennaway                     BIO_printf(bio_s_out, "Read BLOCK\n");
253474664626SKris Kennaway                     break;
253574664626SKris Kennaway                 case SSL_ERROR_SYSCALL:
253674664626SKris Kennaway                 case SSL_ERROR_SSL:
253774664626SKris Kennaway                     BIO_printf(bio_s_out, "ERROR\n");
253874664626SKris Kennaway                     ERR_print_errors(bio_err);
253974664626SKris Kennaway                     ret = 1;
254074664626SKris Kennaway                     goto err;
254174664626SKris Kennaway                 case SSL_ERROR_ZERO_RETURN:
254274664626SKris Kennaway                     BIO_printf(bio_s_out, "DONE\n");
254374664626SKris Kennaway                     ret = 1;
254474664626SKris Kennaway                     goto err;
254574664626SKris Kennaway                 }
254674664626SKris Kennaway             }
254774664626SKris Kennaway         }
254874664626SKris Kennaway     }
254974664626SKris Kennaway  err:
25506f9291ceSJung-uk Kim     if (con != NULL) {
255174664626SKris Kennaway         BIO_printf(bio_s_out, "shutting down SSL\n");
255274664626SKris Kennaway #if 1
255374664626SKris Kennaway         SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
255474664626SKris Kennaway #else
255574664626SKris Kennaway         SSL_shutdown(con);
255674664626SKris Kennaway #endif
25571f13597dSJung-uk Kim         SSL_free(con);
25581f13597dSJung-uk Kim     }
255974664626SKris Kennaway     BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
25606f9291ceSJung-uk Kim     if (buf != NULL) {
25615c87c606SMark Murray         OPENSSL_cleanse(buf, bufsize);
2562ddd58736SKris Kennaway         OPENSSL_free(buf);
256374664626SKris Kennaway     }
256474664626SKris Kennaway     if (ret >= 0)
256574664626SKris Kennaway         BIO_printf(bio_s_out, "ACCEPT\n");
256674664626SKris Kennaway     return (ret);
256774664626SKris Kennaway }
256874664626SKris Kennaway 
256974664626SKris Kennaway static void close_accept_socket(void)
257074664626SKris Kennaway {
257174664626SKris Kennaway     BIO_printf(bio_err, "shutdown accept socket\n");
25726f9291ceSJung-uk Kim     if (accept_socket >= 0) {
257374664626SKris Kennaway         SHUTDOWN2(accept_socket);
257474664626SKris Kennaway     }
257574664626SKris Kennaway }
257674664626SKris Kennaway 
257774664626SKris Kennaway static int init_ssl_connection(SSL *con)
257874664626SKris Kennaway {
257974664626SKris Kennaway     int i;
258074664626SKris Kennaway     const char *str;
258174664626SKris Kennaway     X509 *peer;
258274664626SKris Kennaway     long verify_error;
258374664626SKris Kennaway     MS_STATIC char buf[BUFSIZ];
25841f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
25851f13597dSJung-uk Kim     char *client_princ;
25861f13597dSJung-uk Kim #endif
25871f13597dSJung-uk Kim #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
25881f13597dSJung-uk Kim     const unsigned char *next_proto_neg;
25891f13597dSJung-uk Kim     unsigned next_proto_neg_len;
25901f13597dSJung-uk Kim #endif
25911f13597dSJung-uk Kim     unsigned char *exportedkeymat;
259274664626SKris Kennaway 
25931f13597dSJung-uk Kim     i = SSL_accept(con);
25947bded2dbSJung-uk Kim #ifdef CERT_CB_TEST_RETRY
25957bded2dbSJung-uk Kim     {
25967bded2dbSJung-uk Kim         while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
25977bded2dbSJung-uk Kim                && SSL_state(con) == SSL3_ST_SR_CLNT_HELLO_C) {
25987bded2dbSJung-uk Kim             fprintf(stderr,
25997bded2dbSJung-uk Kim                     "LOOKUP from certificate callback during accept\n");
26007bded2dbSJung-uk Kim             i = SSL_accept(con);
26017bded2dbSJung-uk Kim         }
26027bded2dbSJung-uk Kim     }
26037bded2dbSJung-uk Kim #endif
26041f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
26056f9291ceSJung-uk Kim     while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
26066f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
26076f9291ceSJung-uk Kim                    srp_callback_parm.login);
26086f9291ceSJung-uk Kim         srp_callback_parm.user =
26096f9291ceSJung-uk Kim             SRP_VBASE_get_by_user(srp_callback_parm.vb,
26106f9291ceSJung-uk Kim                                   srp_callback_parm.login);
26111f13597dSJung-uk Kim         if (srp_callback_parm.user)
26126f9291ceSJung-uk Kim             BIO_printf(bio_s_out, "LOOKUP done %s\n",
26136f9291ceSJung-uk Kim                        srp_callback_parm.user->info);
26141f13597dSJung-uk Kim         else
26151f13597dSJung-uk Kim             BIO_printf(bio_s_out, "LOOKUP not successful\n");
26161f13597dSJung-uk Kim         i = SSL_accept(con);
26171f13597dSJung-uk Kim     }
26181f13597dSJung-uk Kim #endif
26197bded2dbSJung-uk Kim 
26206f9291ceSJung-uk Kim     if (i <= 0) {
26216f9291ceSJung-uk Kim         if (BIO_sock_should_retry(i)) {
262274664626SKris Kennaway             BIO_printf(bio_s_out, "DELAY\n");
262374664626SKris Kennaway             return (1);
262474664626SKris Kennaway         }
262574664626SKris Kennaway 
262674664626SKris Kennaway         BIO_printf(bio_err, "ERROR\n");
262774664626SKris Kennaway         verify_error = SSL_get_verify_result(con);
26286f9291ceSJung-uk Kim         if (verify_error != X509_V_OK) {
262974664626SKris Kennaway             BIO_printf(bio_err, "verify error:%s\n",
263074664626SKris Kennaway                        X509_verify_cert_error_string(verify_error));
26317bded2dbSJung-uk Kim         }
26327bded2dbSJung-uk Kim         /* Always print any error messages */
263374664626SKris Kennaway         ERR_print_errors(bio_err);
263474664626SKris Kennaway         return (0);
263574664626SKris Kennaway     }
263674664626SKris Kennaway 
26377bded2dbSJung-uk Kim     if (s_brief)
26387bded2dbSJung-uk Kim         print_ssl_summary(bio_err, con);
26397bded2dbSJung-uk Kim 
264074664626SKris Kennaway     PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
264174664626SKris Kennaway 
264274664626SKris Kennaway     peer = SSL_get_peer_certificate(con);
26436f9291ceSJung-uk Kim     if (peer != NULL) {
264474664626SKris Kennaway         BIO_printf(bio_s_out, "Client certificate\n");
264574664626SKris Kennaway         PEM_write_bio_X509(bio_s_out, peer);
26465c87c606SMark Murray         X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
264774664626SKris Kennaway         BIO_printf(bio_s_out, "subject=%s\n", buf);
26485c87c606SMark Murray         X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
264974664626SKris Kennaway         BIO_printf(bio_s_out, "issuer=%s\n", buf);
265074664626SKris Kennaway         X509_free(peer);
265174664626SKris Kennaway     }
265274664626SKris Kennaway 
26535c87c606SMark Murray     if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
265474664626SKris Kennaway         BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
265574664626SKris Kennaway     str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
26567bded2dbSJung-uk Kim     ssl_print_sigalgs(bio_s_out, con);
26577bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
26587bded2dbSJung-uk Kim     ssl_print_point_formats(bio_s_out, con);
26597bded2dbSJung-uk Kim     ssl_print_curves(bio_s_out, con, 0);
26607bded2dbSJung-uk Kim #endif
266174664626SKris Kennaway     BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
266209286989SJung-uk Kim 
26631f13597dSJung-uk Kim #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
26641f13597dSJung-uk Kim     SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
26656f9291ceSJung-uk Kim     if (next_proto_neg) {
26661f13597dSJung-uk Kim         BIO_printf(bio_s_out, "NEXTPROTO is ");
26671f13597dSJung-uk Kim         BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
26681f13597dSJung-uk Kim         BIO_printf(bio_s_out, "\n");
26691f13597dSJung-uk Kim     }
26701f13597dSJung-uk Kim #endif
267109286989SJung-uk Kim #ifndef OPENSSL_NO_SRTP
26721f13597dSJung-uk Kim     {
26731f13597dSJung-uk Kim         SRTP_PROTECTION_PROFILE *srtp_profile
26741f13597dSJung-uk Kim             = SSL_get_selected_srtp_profile(con);
26751f13597dSJung-uk Kim 
26761f13597dSJung-uk Kim         if (srtp_profile)
26771f13597dSJung-uk Kim             BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n",
26781f13597dSJung-uk Kim                        srtp_profile->name);
26791f13597dSJung-uk Kim     }
268009286989SJung-uk Kim #endif
26816f9291ceSJung-uk Kim     if (SSL_cache_hit(con))
26826f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "Reused session-id\n");
268374664626SKris Kennaway     if (SSL_ctrl(con, SSL_CTRL_GET_FLAGS, 0, NULL) &
268474664626SKris Kennaway         TLS1_FLAGS_TLS_PADDING_BUG)
26856f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "Peer has incorrect TLSv1 block padding\n");
268650ef0093SJacques Vidrine #ifndef OPENSSL_NO_KRB5
26871f13597dSJung-uk Kim     client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
26886f9291ceSJung-uk Kim     if (client_princ != NULL) {
268950ef0093SJacques Vidrine         BIO_printf(bio_s_out, "Kerberos peer principal is %s\n",
26901f13597dSJung-uk Kim                    client_princ);
269150ef0093SJacques Vidrine     }
269250ef0093SJacques Vidrine #endif                          /* OPENSSL_NO_KRB5 */
26936a599222SSimon L. B. Nielsen     BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
26946a599222SSimon L. B. Nielsen                SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
26956f9291ceSJung-uk Kim     if (keymatexportlabel != NULL) {
26961f13597dSJung-uk Kim         BIO_printf(bio_s_out, "Keying material exporter:\n");
26971f13597dSJung-uk Kim         BIO_printf(bio_s_out, "    Label: '%s'\n", keymatexportlabel);
26986f9291ceSJung-uk Kim         BIO_printf(bio_s_out, "    Length: %i bytes\n", keymatexportlen);
26991f13597dSJung-uk Kim         exportedkeymat = OPENSSL_malloc(keymatexportlen);
27006f9291ceSJung-uk Kim         if (exportedkeymat != NULL) {
27011f13597dSJung-uk Kim             if (!SSL_export_keying_material(con, exportedkeymat,
27021f13597dSJung-uk Kim                                             keymatexportlen,
27031f13597dSJung-uk Kim                                             keymatexportlabel,
27041f13597dSJung-uk Kim                                             strlen(keymatexportlabel),
27056f9291ceSJung-uk Kim                                             NULL, 0, 0)) {
27061f13597dSJung-uk Kim                 BIO_printf(bio_s_out, "    Error\n");
27076f9291ceSJung-uk Kim             } else {
27081f13597dSJung-uk Kim                 BIO_printf(bio_s_out, "    Keying material: ");
27091f13597dSJung-uk Kim                 for (i = 0; i < keymatexportlen; i++)
27106f9291ceSJung-uk Kim                     BIO_printf(bio_s_out, "%02X", exportedkeymat[i]);
27111f13597dSJung-uk Kim                 BIO_printf(bio_s_out, "\n");
27121f13597dSJung-uk Kim             }
27131f13597dSJung-uk Kim             OPENSSL_free(exportedkeymat);
27141f13597dSJung-uk Kim         }
27151f13597dSJung-uk Kim     }
27161f13597dSJung-uk Kim 
271774664626SKris Kennaway     return (1);
271874664626SKris Kennaway }
271974664626SKris Kennaway 
27205c87c606SMark Murray #ifndef OPENSSL_NO_DH
27213b4e3dcbSSimon L. B. Nielsen static DH *load_dh_param(const char *dhfile)
272274664626SKris Kennaway {
272374664626SKris Kennaway     DH *ret = NULL;
272474664626SKris Kennaway     BIO *bio;
272574664626SKris Kennaway 
2726f579bf8eSKris Kennaway     if ((bio = BIO_new_file(dhfile, "r")) == NULL)
272774664626SKris Kennaway         goto err;
272874664626SKris Kennaway     ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
272974664626SKris Kennaway  err:
27306f9291ceSJung-uk Kim     if (bio != NULL)
27316f9291ceSJung-uk Kim         BIO_free(bio);
273274664626SKris Kennaway     return (ret);
273374664626SKris Kennaway }
273474664626SKris Kennaway #endif
27351f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
27361f13597dSJung-uk Kim char *client_princ;
27371f13597dSJung-uk Kim #endif
273874664626SKris Kennaway 
273974664626SKris Kennaway #if 0
274074664626SKris Kennaway static int load_CA(SSL_CTX *ctx, char *file)
274174664626SKris Kennaway {
274274664626SKris Kennaway     FILE *in;
274374664626SKris Kennaway     X509 *x = NULL;
274474664626SKris Kennaway 
274574664626SKris Kennaway     if ((in = fopen(file, "r")) == NULL)
274674664626SKris Kennaway         return (0);
274774664626SKris Kennaway 
27486f9291ceSJung-uk Kim     for (;;) {
274974664626SKris Kennaway         if (PEM_read_X509(in, &x, NULL) == NULL)
275074664626SKris Kennaway             break;
275174664626SKris Kennaway         SSL_CTX_add_client_CA(ctx, x);
275274664626SKris Kennaway     }
27536f9291ceSJung-uk Kim     if (x != NULL)
27546f9291ceSJung-uk Kim         X509_free(x);
275574664626SKris Kennaway     fclose(in);
275674664626SKris Kennaway     return (1);
275774664626SKris Kennaway }
275874664626SKris Kennaway #endif
275974664626SKris Kennaway 
27607bded2dbSJung-uk Kim static int www_body(char *hostname, int s, int stype, unsigned char *context)
276174664626SKris Kennaway {
276274664626SKris Kennaway     char *buf = NULL;
276374664626SKris Kennaway     int ret = 1;
2764a3ddd25aSSimon L. B. Nielsen     int i, j, k, dot;
276574664626SKris Kennaway     SSL *con;
27661f13597dSJung-uk Kim     const SSL_CIPHER *c;
276774664626SKris Kennaway     BIO *io, *ssl_bio, *sbio;
27681f13597dSJung-uk Kim #ifndef OPENSSL_NO_KRB5
27691f13597dSJung-uk Kim     KSSL_CTX *kctx;
2770a3ddd25aSSimon L. B. Nielsen #endif
277174664626SKris Kennaway 
2772ddd58736SKris Kennaway     buf = OPENSSL_malloc(bufsize);
27736f9291ceSJung-uk Kim     if (buf == NULL)
27746f9291ceSJung-uk Kim         return (0);
277574664626SKris Kennaway     io = BIO_new(BIO_f_buffer());
277674664626SKris Kennaway     ssl_bio = BIO_new(BIO_f_ssl());
27776f9291ceSJung-uk Kim     if ((io == NULL) || (ssl_bio == NULL))
27786f9291ceSJung-uk Kim         goto err;
277974664626SKris Kennaway 
278074664626SKris Kennaway #ifdef FIONBIO
27816f9291ceSJung-uk Kim     if (s_nbio) {
278274664626SKris Kennaway         unsigned long sl = 1;
278374664626SKris Kennaway 
278474664626SKris Kennaway         if (!s_quiet)
278574664626SKris Kennaway             BIO_printf(bio_err, "turning on non blocking io\n");
278674664626SKris Kennaway         if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0)
278774664626SKris Kennaway             ERR_print_errors(bio_err);
278874664626SKris Kennaway     }
278974664626SKris Kennaway #endif
279074664626SKris Kennaway 
279174664626SKris Kennaway     /* lets make the output buffer a reasonable size */
27926f9291ceSJung-uk Kim     if (!BIO_set_write_buffer_size(io, bufsize))
27936f9291ceSJung-uk Kim         goto err;
279474664626SKris Kennaway 
27956f9291ceSJung-uk Kim     if ((con = SSL_new(ctx)) == NULL)
27966f9291ceSJung-uk Kim         goto err;
2797db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
27986f9291ceSJung-uk Kim     if (s_tlsextdebug) {
2799db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_callback(con, tlsext_cb);
2800db522d3aSSimon L. B. Nielsen         SSL_set_tlsext_debug_arg(con, bio_s_out);
2801db522d3aSSimon L. B. Nielsen     }
2802db522d3aSSimon L. B. Nielsen #endif
28035c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
28046f9291ceSJung-uk Kim     if ((kctx = kssl_ctx_new()) != NULL) {
28051f13597dSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
28061f13597dSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
28075c87c606SMark Murray     }
28085c87c606SMark Murray #endif                          /* OPENSSL_NO_KRB5 */
28096f9291ceSJung-uk Kim     if (context)
28106f9291ceSJung-uk Kim         SSL_set_session_id_context(con, context, strlen((char *)context));
281174664626SKris Kennaway 
281274664626SKris Kennaway     sbio = BIO_new_socket(s, BIO_NOCLOSE);
28136f9291ceSJung-uk Kim     if (s_nbio_test) {
281474664626SKris Kennaway         BIO *test;
281574664626SKris Kennaway 
281674664626SKris Kennaway         test = BIO_new(BIO_f_nbio_test());
281774664626SKris Kennaway         sbio = BIO_push(test, sbio);
281874664626SKris Kennaway     }
281974664626SKris Kennaway     SSL_set_bio(con, sbio, sbio);
282074664626SKris Kennaway     SSL_set_accept_state(con);
282174664626SKris Kennaway 
282274664626SKris Kennaway     /* SSL_set_fd(con,s); */
282374664626SKris Kennaway     BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
282474664626SKris Kennaway     BIO_push(io, ssl_bio);
282574664626SKris Kennaway #ifdef CHARSET_EBCDIC
282674664626SKris Kennaway     io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
282774664626SKris Kennaway #endif
282874664626SKris Kennaway 
28296f9291ceSJung-uk Kim     if (s_debug) {
28301f13597dSJung-uk Kim         SSL_set_debug(con, 1);
28313b4e3dcbSSimon L. B. Nielsen         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
28325471f83eSSimon L. B. Nielsen         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
283374664626SKris Kennaway     }
28346f9291ceSJung-uk Kim     if (s_msg) {
28357bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
28367bded2dbSJung-uk Kim         if (s_msg == 2)
28377bded2dbSJung-uk Kim             SSL_set_msg_callback(con, SSL_trace);
28387bded2dbSJung-uk Kim         else
28397bded2dbSJung-uk Kim #endif
28405c87c606SMark Murray             SSL_set_msg_callback(con, msg_cb);
28417bded2dbSJung-uk Kim         SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
28425c87c606SMark Murray     }
284374664626SKris Kennaway 
28446f9291ceSJung-uk Kim     for (;;) {
28456f9291ceSJung-uk Kim         if (hack) {
284674664626SKris Kennaway             i = SSL_accept(con);
28471f13597dSJung-uk Kim #ifndef OPENSSL_NO_SRP
28486f9291ceSJung-uk Kim             while (i <= 0
28496f9291ceSJung-uk Kim                    && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
28506f9291ceSJung-uk Kim                 BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
28516f9291ceSJung-uk Kim                            srp_callback_parm.login);
28526f9291ceSJung-uk Kim                 srp_callback_parm.user =
28536f9291ceSJung-uk Kim                     SRP_VBASE_get_by_user(srp_callback_parm.vb,
28546f9291ceSJung-uk Kim                                           srp_callback_parm.login);
28551f13597dSJung-uk Kim                 if (srp_callback_parm.user)
28566f9291ceSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP done %s\n",
28576f9291ceSJung-uk Kim                                srp_callback_parm.user->info);
28581f13597dSJung-uk Kim                 else
28591f13597dSJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP not successful\n");
28601f13597dSJung-uk Kim                 i = SSL_accept(con);
28611f13597dSJung-uk Kim             }
28621f13597dSJung-uk Kim #endif
28636f9291ceSJung-uk Kim             switch (SSL_get_error(con, i)) {
286474664626SKris Kennaway             case SSL_ERROR_NONE:
286574664626SKris Kennaway                 break;
286674664626SKris Kennaway             case SSL_ERROR_WANT_WRITE:
286774664626SKris Kennaway             case SSL_ERROR_WANT_READ:
286874664626SKris Kennaway             case SSL_ERROR_WANT_X509_LOOKUP:
286974664626SKris Kennaway                 continue;
287074664626SKris Kennaway             case SSL_ERROR_SYSCALL:
287174664626SKris Kennaway             case SSL_ERROR_SSL:
287274664626SKris Kennaway             case SSL_ERROR_ZERO_RETURN:
287374664626SKris Kennaway                 ret = 1;
287474664626SKris Kennaway                 goto err;
287574664626SKris Kennaway                 /* break; */
287674664626SKris Kennaway             }
287774664626SKris Kennaway 
287874664626SKris Kennaway             SSL_renegotiate(con);
287974664626SKris Kennaway             SSL_write(con, NULL, 0);
288074664626SKris Kennaway         }
288174664626SKris Kennaway 
288274664626SKris Kennaway         i = BIO_gets(io, buf, bufsize - 1);
28836f9291ceSJung-uk Kim         if (i < 0) {            /* error */
28846f9291ceSJung-uk Kim             if (!BIO_should_retry(io)) {
288574664626SKris Kennaway                 if (!s_quiet)
288674664626SKris Kennaway                     ERR_print_errors(bio_err);
288774664626SKris Kennaway                 goto err;
28886f9291ceSJung-uk Kim             } else {
288974664626SKris Kennaway                 BIO_printf(bio_s_out, "read R BLOCK\n");
2890*80815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP
2891*80815a77SJung-uk Kim                 if (BIO_should_io_special(io)
2892*80815a77SJung-uk Kim                     && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
2893*80815a77SJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP renego during read\n");
2894*80815a77SJung-uk Kim                     srp_callback_parm.user =
2895*80815a77SJung-uk Kim                         SRP_VBASE_get_by_user(srp_callback_parm.vb,
2896*80815a77SJung-uk Kim                                               srp_callback_parm.login);
2897*80815a77SJung-uk Kim                     if (srp_callback_parm.user)
2898*80815a77SJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
2899*80815a77SJung-uk Kim                                    srp_callback_parm.user->info);
2900*80815a77SJung-uk Kim                     else
2901*80815a77SJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
2902*80815a77SJung-uk Kim                     continue;
2903*80815a77SJung-uk Kim                 }
2904*80815a77SJung-uk Kim #endif
29053b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_NETWARE)
29063b4e3dcbSSimon L. B. Nielsen                 delay(1000);
29073b4e3dcbSSimon L. B. Nielsen #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
290874664626SKris Kennaway                 sleep(1);
290974664626SKris Kennaway #endif
291074664626SKris Kennaway                 continue;
291174664626SKris Kennaway             }
29126f9291ceSJung-uk Kim         } else if (i == 0) {    /* end of input */
291374664626SKris Kennaway             ret = 1;
291474664626SKris Kennaway             goto end;
291574664626SKris Kennaway         }
291674664626SKris Kennaway 
291774664626SKris Kennaway         /* else we have data */
291874664626SKris Kennaway         if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
29196f9291ceSJung-uk Kim             ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
292074664626SKris Kennaway             char *p;
292174664626SKris Kennaway             X509 *peer;
292274664626SKris Kennaway             STACK_OF(SSL_CIPHER) *sk;
29233b4e3dcbSSimon L. B. Nielsen             static const char *space = "                          ";
292474664626SKris Kennaway 
29256f9291ceSJung-uk Kim             BIO_puts(io,
29266f9291ceSJung-uk Kim                      "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
292774664626SKris Kennaway             BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
292874664626SKris Kennaway             BIO_puts(io, "<pre>\n");
292974664626SKris Kennaway /*                      BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
293074664626SKris Kennaway             BIO_puts(io, "\n");
29316f9291ceSJung-uk Kim             for (i = 0; i < local_argc; i++) {
293274664626SKris Kennaway                 BIO_puts(io, local_argv[i]);
293374664626SKris Kennaway                 BIO_write(io, " ", 1);
293474664626SKris Kennaway             }
293574664626SKris Kennaway             BIO_puts(io, "\n");
293674664626SKris Kennaway 
293709286989SJung-uk Kim             BIO_printf(io,
293809286989SJung-uk Kim                        "Secure Renegotiation IS%s supported\n",
293909286989SJung-uk Kim                        SSL_get_secure_renegotiation_support(con) ?
294009286989SJung-uk Kim                        "" : " NOT");
294109286989SJung-uk Kim 
29426f9291ceSJung-uk Kim             /*
29436f9291ceSJung-uk Kim              * The following is evil and should not really be done
29446f9291ceSJung-uk Kim              */
294574664626SKris Kennaway             BIO_printf(io, "Ciphers supported in s_server binary\n");
294674664626SKris Kennaway             sk = SSL_get_ciphers(con);
294774664626SKris Kennaway             j = sk_SSL_CIPHER_num(sk);
29486f9291ceSJung-uk Kim             for (i = 0; i < j; i++) {
294974664626SKris Kennaway                 c = sk_SSL_CIPHER_value(sk, i);
295074664626SKris Kennaway                 BIO_printf(io, "%-11s:%-25s",
29516f9291ceSJung-uk Kim                            SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
295274664626SKris Kennaway                 if ((((i + 1) % 2) == 0) && (i + 1 != j))
295374664626SKris Kennaway                     BIO_puts(io, "\n");
295474664626SKris Kennaway             }
295574664626SKris Kennaway             BIO_puts(io, "\n");
295674664626SKris Kennaway             p = SSL_get_shared_ciphers(con, buf, bufsize);
29576f9291ceSJung-uk Kim             if (p != NULL) {
29586f9291ceSJung-uk Kim                 BIO_printf(io,
29596f9291ceSJung-uk Kim                            "---\nCiphers common between both SSL end points:\n");
296074664626SKris Kennaway                 j = i = 0;
29616f9291ceSJung-uk Kim                 while (*p) {
29626f9291ceSJung-uk Kim                     if (*p == ':') {
296374664626SKris Kennaway                         BIO_write(io, space, 26 - j);
296474664626SKris Kennaway                         i++;
296574664626SKris Kennaway                         j = 0;
296674664626SKris Kennaway                         BIO_write(io, ((i % 3) ? " " : "\n"), 1);
29676f9291ceSJung-uk Kim                     } else {
296874664626SKris Kennaway                         BIO_write(io, p, 1);
296974664626SKris Kennaway                         j++;
297074664626SKris Kennaway                     }
297174664626SKris Kennaway                     p++;
297274664626SKris Kennaway                 }
297374664626SKris Kennaway                 BIO_puts(io, "\n");
297474664626SKris Kennaway             }
29757bded2dbSJung-uk Kim             ssl_print_sigalgs(io, con);
29767bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
29777bded2dbSJung-uk Kim             ssl_print_curves(io, con, 0);
29787bded2dbSJung-uk Kim #endif
29791f13597dSJung-uk Kim             BIO_printf(io, (SSL_cache_hit(con)
29806f9291ceSJung-uk Kim                             ? "---\nReused, " : "---\nNew, "));
298174664626SKris Kennaway             c = SSL_get_current_cipher(con);
298274664626SKris Kennaway             BIO_printf(io, "%s, Cipher is %s\n",
29836f9291ceSJung-uk Kim                        SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
298474664626SKris Kennaway             SSL_SESSION_print(io, SSL_get_session(con));
298574664626SKris Kennaway             BIO_printf(io, "---\n");
298674664626SKris Kennaway             print_stats(io, SSL_get_SSL_CTX(con));
298774664626SKris Kennaway             BIO_printf(io, "---\n");
298874664626SKris Kennaway             peer = SSL_get_peer_certificate(con);
29896f9291ceSJung-uk Kim             if (peer != NULL) {
299074664626SKris Kennaway                 BIO_printf(io, "Client certificate\n");
299174664626SKris Kennaway                 X509_print(io, peer);
299274664626SKris Kennaway                 PEM_write_bio_X509(io, peer);
29936f9291ceSJung-uk Kim             } else
299474664626SKris Kennaway                 BIO_puts(io, "no client certificate available\n");
299574664626SKris Kennaway             BIO_puts(io, "</BODY></HTML>\r\n\r\n");
299674664626SKris Kennaway             break;
29976f9291ceSJung-uk Kim         } else if ((www == 2 || www == 3)
29986f9291ceSJung-uk Kim                    && (strncmp("GET /", buf, 5) == 0)) {
299974664626SKris Kennaway             BIO *file;
300074664626SKris Kennaway             char *p, *e;
30016f9291ceSJung-uk Kim             static const char *text =
30026f9291ceSJung-uk Kim                 "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
300374664626SKris Kennaway 
300474664626SKris Kennaway             /* skip the '/' */
300574664626SKris Kennaway             p = &(buf[5]);
30065740a5e3SKris Kennaway 
30075740a5e3SKris Kennaway             dot = 1;
30086f9291ceSJung-uk Kim             for (e = p; *e != '\0'; e++) {
30095740a5e3SKris Kennaway                 if (e[0] == ' ')
30105740a5e3SKris Kennaway                     break;
301174664626SKris Kennaway 
30126f9291ceSJung-uk Kim                 switch (dot) {
30135740a5e3SKris Kennaway                 case 1:
30145740a5e3SKris Kennaway                     dot = (e[0] == '.') ? 2 : 0;
30155740a5e3SKris Kennaway                     break;
30165740a5e3SKris Kennaway                 case 2:
30175740a5e3SKris Kennaway                     dot = (e[0] == '.') ? 3 : 0;
30185740a5e3SKris Kennaway                     break;
30195740a5e3SKris Kennaway                 case 3:
30205740a5e3SKris Kennaway                     dot = (e[0] == '/') ? -1 : 0;
30215740a5e3SKris Kennaway                     break;
30225740a5e3SKris Kennaway                 }
30235740a5e3SKris Kennaway                 if (dot == 0)
30245740a5e3SKris Kennaway                     dot = (e[0] == '/') ? 1 : 0;
30255740a5e3SKris Kennaway             }
30266f9291ceSJung-uk Kim             dot = (dot == 3) || (dot == -1); /* filename contains ".."
30276f9291ceSJung-uk Kim                                               * component */
302874664626SKris Kennaway 
30296f9291ceSJung-uk Kim             if (*e == '\0') {
303074664626SKris Kennaway                 BIO_puts(io, text);
303174664626SKris Kennaway                 BIO_printf(io, "'%s' is an invalid file name\r\n", p);
303274664626SKris Kennaway                 break;
303374664626SKris Kennaway             }
303474664626SKris Kennaway             *e = '\0';
303574664626SKris Kennaway 
30366f9291ceSJung-uk Kim             if (dot) {
303774664626SKris Kennaway                 BIO_puts(io, text);
303874664626SKris Kennaway                 BIO_printf(io, "'%s' contains '..' reference\r\n", p);
303974664626SKris Kennaway                 break;
304074664626SKris Kennaway             }
304174664626SKris Kennaway 
30426f9291ceSJung-uk Kim             if (*p == '/') {
304374664626SKris Kennaway                 BIO_puts(io, text);
304474664626SKris Kennaway                 BIO_printf(io, "'%s' is an invalid path\r\n", p);
304574664626SKris Kennaway                 break;
304674664626SKris Kennaway             }
30475740a5e3SKris Kennaway #if 0
304874664626SKris Kennaway             /* append if a directory lookup */
304974664626SKris Kennaway             if (e[-1] == '/')
305074664626SKris Kennaway                 strcat(p, "index.html");
30515740a5e3SKris Kennaway #endif
305274664626SKris Kennaway 
305374664626SKris Kennaway             /* if a directory, do the index thang */
30546f9291ceSJung-uk Kim             if (app_isdir(p) > 0) {
30555740a5e3SKris Kennaway #if 0                           /* must check buffer size */
305674664626SKris Kennaway                 strcat(p, "/index.html");
30575740a5e3SKris Kennaway #else
30585740a5e3SKris Kennaway                 BIO_puts(io, text);
30595740a5e3SKris Kennaway                 BIO_printf(io, "'%s' is a directory\r\n", p);
30605740a5e3SKris Kennaway                 break;
30615740a5e3SKris Kennaway #endif
306274664626SKris Kennaway             }
306374664626SKris Kennaway 
30646f9291ceSJung-uk Kim             if ((file = BIO_new_file(p, "r")) == NULL) {
306574664626SKris Kennaway                 BIO_puts(io, text);
306674664626SKris Kennaway                 BIO_printf(io, "Error opening '%s'\r\n", p);
306774664626SKris Kennaway                 ERR_print_errors(io);
306874664626SKris Kennaway                 break;
306974664626SKris Kennaway             }
307074664626SKris Kennaway 
307174664626SKris Kennaway             if (!s_quiet)
307274664626SKris Kennaway                 BIO_printf(bio_err, "FILE:%s\n", p);
307374664626SKris Kennaway 
30746f9291ceSJung-uk Kim             if (www == 2) {
307574664626SKris Kennaway                 i = strlen(p);
307674664626SKris Kennaway                 if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
307774664626SKris Kennaway                     ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
307874664626SKris Kennaway                     ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
30796f9291ceSJung-uk Kim                     BIO_puts(io,
30806f9291ceSJung-uk Kim                              "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
308174664626SKris Kennaway                 else
30826f9291ceSJung-uk Kim                     BIO_puts(io,
30836f9291ceSJung-uk Kim                              "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
30845c87c606SMark Murray             }
308574664626SKris Kennaway             /* send the file */
30866f9291ceSJung-uk Kim             for (;;) {
308774664626SKris Kennaway                 i = BIO_read(file, buf, bufsize);
30886f9291ceSJung-uk Kim                 if (i <= 0)
30896f9291ceSJung-uk Kim                     break;
309074664626SKris Kennaway 
309174664626SKris Kennaway #ifdef RENEG
309274664626SKris Kennaway                 total_bytes += i;
309374664626SKris Kennaway                 fprintf(stderr, "%d\n", i);
30946f9291ceSJung-uk Kim                 if (total_bytes > 3 * 1024) {
309574664626SKris Kennaway                     total_bytes = 0;
309674664626SKris Kennaway                     fprintf(stderr, "RENEGOTIATE\n");
309774664626SKris Kennaway                     SSL_renegotiate(con);
309874664626SKris Kennaway                 }
309974664626SKris Kennaway #endif
310074664626SKris Kennaway 
31016f9291ceSJung-uk Kim                 for (j = 0; j < i;) {
310274664626SKris Kennaway #ifdef RENEG
31036f9291ceSJung-uk Kim                     {
31046f9291ceSJung-uk Kim                         static count = 0;
31056f9291ceSJung-uk Kim                         if (++count == 13) {
31066f9291ceSJung-uk Kim                             SSL_renegotiate(con);
31076f9291ceSJung-uk Kim                         }
31086f9291ceSJung-uk Kim                     }
310974664626SKris Kennaway #endif
311074664626SKris Kennaway                     k = BIO_write(io, &(buf[j]), i - j);
31116f9291ceSJung-uk Kim                     if (k <= 0) {
311274664626SKris Kennaway                         if (!BIO_should_retry(io))
311374664626SKris Kennaway                             goto write_error;
31146f9291ceSJung-uk Kim                         else {
311574664626SKris Kennaway                             BIO_printf(bio_s_out, "rwrite W BLOCK\n");
311674664626SKris Kennaway                         }
31176f9291ceSJung-uk Kim                     } else {
311874664626SKris Kennaway                         j += k;
311974664626SKris Kennaway                     }
312074664626SKris Kennaway                 }
312174664626SKris Kennaway             }
312274664626SKris Kennaway  write_error:
312374664626SKris Kennaway             BIO_free(file);
312474664626SKris Kennaway             break;
312574664626SKris Kennaway         }
312674664626SKris Kennaway     }
312774664626SKris Kennaway 
31286f9291ceSJung-uk Kim     for (;;) {
312974664626SKris Kennaway         i = (int)BIO_flush(io);
31306f9291ceSJung-uk Kim         if (i <= 0) {
313174664626SKris Kennaway             if (!BIO_should_retry(io))
313274664626SKris Kennaway                 break;
31336f9291ceSJung-uk Kim         } else
313474664626SKris Kennaway             break;
313574664626SKris Kennaway     }
313674664626SKris Kennaway  end:
313774664626SKris Kennaway #if 1
313874664626SKris Kennaway     /* make sure we re-use sessions */
313974664626SKris Kennaway     SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
314074664626SKris Kennaway #else
3141f579bf8eSKris Kennaway     /* This kills performance */
31426f9291ceSJung-uk Kim     /*
31436f9291ceSJung-uk Kim      * SSL_shutdown(con); A shutdown gets sent in the BIO_free_all(io)
31446f9291ceSJung-uk Kim      * procession
31456f9291ceSJung-uk Kim      */
314674664626SKris Kennaway #endif
314774664626SKris Kennaway 
314874664626SKris Kennaway  err:
314974664626SKris Kennaway 
315074664626SKris Kennaway     if (ret >= 0)
315174664626SKris Kennaway         BIO_printf(bio_s_out, "ACCEPT\n");
315274664626SKris Kennaway 
31536f9291ceSJung-uk Kim     if (buf != NULL)
31546f9291ceSJung-uk Kim         OPENSSL_free(buf);
31556f9291ceSJung-uk Kim     if (io != NULL)
31566f9291ceSJung-uk Kim         BIO_free_all(io);
315774664626SKris Kennaway /*      if (ssl_bio != NULL) BIO_free(ssl_bio);*/
315874664626SKris Kennaway     return (ret);
315974664626SKris Kennaway }
316074664626SKris Kennaway 
31617bded2dbSJung-uk Kim static int rev_body(char *hostname, int s, int stype, unsigned char *context)
31627bded2dbSJung-uk Kim {
31637bded2dbSJung-uk Kim     char *buf = NULL;
31647bded2dbSJung-uk Kim     int i;
31657bded2dbSJung-uk Kim     int ret = 1;
31667bded2dbSJung-uk Kim     SSL *con;
31677bded2dbSJung-uk Kim     BIO *io, *ssl_bio, *sbio;
31687bded2dbSJung-uk Kim #ifndef OPENSSL_NO_KRB5
31697bded2dbSJung-uk Kim     KSSL_CTX *kctx;
31707bded2dbSJung-uk Kim #endif
31717bded2dbSJung-uk Kim 
31727bded2dbSJung-uk Kim     buf = OPENSSL_malloc(bufsize);
31737bded2dbSJung-uk Kim     if (buf == NULL)
31747bded2dbSJung-uk Kim         return (0);
31757bded2dbSJung-uk Kim     io = BIO_new(BIO_f_buffer());
31767bded2dbSJung-uk Kim     ssl_bio = BIO_new(BIO_f_ssl());
31777bded2dbSJung-uk Kim     if ((io == NULL) || (ssl_bio == NULL))
31787bded2dbSJung-uk Kim         goto err;
31797bded2dbSJung-uk Kim 
31807bded2dbSJung-uk Kim     /* lets make the output buffer a reasonable size */
31817bded2dbSJung-uk Kim     if (!BIO_set_write_buffer_size(io, bufsize))
31827bded2dbSJung-uk Kim         goto err;
31837bded2dbSJung-uk Kim 
31847bded2dbSJung-uk Kim     if ((con = SSL_new(ctx)) == NULL)
31857bded2dbSJung-uk Kim         goto err;
31867bded2dbSJung-uk Kim #ifndef OPENSSL_NO_TLSEXT
31877bded2dbSJung-uk Kim     if (s_tlsextdebug) {
31887bded2dbSJung-uk Kim         SSL_set_tlsext_debug_callback(con, tlsext_cb);
31897bded2dbSJung-uk Kim         SSL_set_tlsext_debug_arg(con, bio_s_out);
31907bded2dbSJung-uk Kim     }
31917bded2dbSJung-uk Kim #endif
31927bded2dbSJung-uk Kim #ifndef OPENSSL_NO_KRB5
31937bded2dbSJung-uk Kim     if ((kctx = kssl_ctx_new()) != NULL) {
31947bded2dbSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
31957bded2dbSJung-uk Kim         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
31967bded2dbSJung-uk Kim     }
31977bded2dbSJung-uk Kim #endif                          /* OPENSSL_NO_KRB5 */
31987bded2dbSJung-uk Kim     if (context)
31997bded2dbSJung-uk Kim         SSL_set_session_id_context(con, context, strlen((char *)context));
32007bded2dbSJung-uk Kim 
32017bded2dbSJung-uk Kim     sbio = BIO_new_socket(s, BIO_NOCLOSE);
32027bded2dbSJung-uk Kim     SSL_set_bio(con, sbio, sbio);
32037bded2dbSJung-uk Kim     SSL_set_accept_state(con);
32047bded2dbSJung-uk Kim 
32057bded2dbSJung-uk Kim     BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
32067bded2dbSJung-uk Kim     BIO_push(io, ssl_bio);
32077bded2dbSJung-uk Kim #ifdef CHARSET_EBCDIC
32087bded2dbSJung-uk Kim     io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
32097bded2dbSJung-uk Kim #endif
32107bded2dbSJung-uk Kim 
32117bded2dbSJung-uk Kim     if (s_debug) {
32127bded2dbSJung-uk Kim         SSL_set_debug(con, 1);
32137bded2dbSJung-uk Kim         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
32147bded2dbSJung-uk Kim         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
32157bded2dbSJung-uk Kim     }
32167bded2dbSJung-uk Kim     if (s_msg) {
32177bded2dbSJung-uk Kim #ifndef OPENSSL_NO_SSL_TRACE
32187bded2dbSJung-uk Kim         if (s_msg == 2)
32197bded2dbSJung-uk Kim             SSL_set_msg_callback(con, SSL_trace);
32207bded2dbSJung-uk Kim         else
32217bded2dbSJung-uk Kim #endif
32227bded2dbSJung-uk Kim             SSL_set_msg_callback(con, msg_cb);
32237bded2dbSJung-uk Kim         SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
32247bded2dbSJung-uk Kim     }
32257bded2dbSJung-uk Kim 
32267bded2dbSJung-uk Kim     for (;;) {
32277bded2dbSJung-uk Kim         i = BIO_do_handshake(io);
32287bded2dbSJung-uk Kim         if (i > 0)
32297bded2dbSJung-uk Kim             break;
32307bded2dbSJung-uk Kim         if (!BIO_should_retry(io)) {
32317bded2dbSJung-uk Kim             BIO_puts(bio_err, "CONNECTION FAILURE\n");
32327bded2dbSJung-uk Kim             ERR_print_errors(bio_err);
32337bded2dbSJung-uk Kim             goto end;
32347bded2dbSJung-uk Kim         }
3235*80815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP
3236*80815a77SJung-uk Kim         if (BIO_should_io_special(io)
3237*80815a77SJung-uk Kim             && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
3238*80815a77SJung-uk Kim             BIO_printf(bio_s_out, "LOOKUP renego during accept\n");
3239*80815a77SJung-uk Kim             srp_callback_parm.user =
3240*80815a77SJung-uk Kim                 SRP_VBASE_get_by_user(srp_callback_parm.vb,
3241*80815a77SJung-uk Kim                                       srp_callback_parm.login);
3242*80815a77SJung-uk Kim             if (srp_callback_parm.user)
3243*80815a77SJung-uk Kim                 BIO_printf(bio_s_out, "LOOKUP done %s\n",
3244*80815a77SJung-uk Kim                            srp_callback_parm.user->info);
3245*80815a77SJung-uk Kim             else
3246*80815a77SJung-uk Kim                 BIO_printf(bio_s_out, "LOOKUP not successful\n");
3247*80815a77SJung-uk Kim             continue;
3248*80815a77SJung-uk Kim         }
3249*80815a77SJung-uk Kim #endif
32507bded2dbSJung-uk Kim     }
32517bded2dbSJung-uk Kim     BIO_printf(bio_err, "CONNECTION ESTABLISHED\n");
32527bded2dbSJung-uk Kim     print_ssl_summary(bio_err, con);
32537bded2dbSJung-uk Kim 
32547bded2dbSJung-uk Kim     for (;;) {
32557bded2dbSJung-uk Kim         i = BIO_gets(io, buf, bufsize - 1);
32567bded2dbSJung-uk Kim         if (i < 0) {            /* error */
32577bded2dbSJung-uk Kim             if (!BIO_should_retry(io)) {
32587bded2dbSJung-uk Kim                 if (!s_quiet)
32597bded2dbSJung-uk Kim                     ERR_print_errors(bio_err);
32607bded2dbSJung-uk Kim                 goto err;
32617bded2dbSJung-uk Kim             } else {
32627bded2dbSJung-uk Kim                 BIO_printf(bio_s_out, "read R BLOCK\n");
3263*80815a77SJung-uk Kim #ifndef OPENSSL_NO_SRP
3264*80815a77SJung-uk Kim                 if (BIO_should_io_special(io)
3265*80815a77SJung-uk Kim                     && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
3266*80815a77SJung-uk Kim                     BIO_printf(bio_s_out, "LOOKUP renego during read\n");
3267*80815a77SJung-uk Kim                     srp_callback_parm.user =
3268*80815a77SJung-uk Kim                         SRP_VBASE_get_by_user(srp_callback_parm.vb,
3269*80815a77SJung-uk Kim                                               srp_callback_parm.login);
3270*80815a77SJung-uk Kim                     if (srp_callback_parm.user)
3271*80815a77SJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
3272*80815a77SJung-uk Kim                                    srp_callback_parm.user->info);
3273*80815a77SJung-uk Kim                     else
3274*80815a77SJung-uk Kim                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
3275*80815a77SJung-uk Kim                     continue;
3276*80815a77SJung-uk Kim                 }
3277*80815a77SJung-uk Kim #endif
32787bded2dbSJung-uk Kim #if defined(OPENSSL_SYS_NETWARE)
32797bded2dbSJung-uk Kim                 delay(1000);
32807bded2dbSJung-uk Kim #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
32817bded2dbSJung-uk Kim                 sleep(1);
32827bded2dbSJung-uk Kim #endif
32837bded2dbSJung-uk Kim                 continue;
32847bded2dbSJung-uk Kim             }
32857bded2dbSJung-uk Kim         } else if (i == 0) {    /* end of input */
32867bded2dbSJung-uk Kim             ret = 1;
32877bded2dbSJung-uk Kim             BIO_printf(bio_err, "CONNECTION CLOSED\n");
32887bded2dbSJung-uk Kim             goto end;
32897bded2dbSJung-uk Kim         } else {
32907bded2dbSJung-uk Kim             char *p = buf + i - 1;
32917bded2dbSJung-uk Kim             while (i && (*p == '\n' || *p == '\r')) {
32927bded2dbSJung-uk Kim                 p--;
32937bded2dbSJung-uk Kim                 i--;
32947bded2dbSJung-uk Kim             }
32957bded2dbSJung-uk Kim             if (!s_ign_eof && i == 5 && !strncmp(buf, "CLOSE", 5)) {
32967bded2dbSJung-uk Kim                 ret = 1;
32977bded2dbSJung-uk Kim                 BIO_printf(bio_err, "CONNECTION CLOSED\n");
32987bded2dbSJung-uk Kim                 goto end;
32997bded2dbSJung-uk Kim             }
33007bded2dbSJung-uk Kim             BUF_reverse((unsigned char *)buf, NULL, i);
33017bded2dbSJung-uk Kim             buf[i] = '\n';
33027bded2dbSJung-uk Kim             BIO_write(io, buf, i + 1);
33037bded2dbSJung-uk Kim             for (;;) {
33047bded2dbSJung-uk Kim                 i = BIO_flush(io);
33057bded2dbSJung-uk Kim                 if (i > 0)
33067bded2dbSJung-uk Kim                     break;
33077bded2dbSJung-uk Kim                 if (!BIO_should_retry(io))
33087bded2dbSJung-uk Kim                     goto end;
33097bded2dbSJung-uk Kim             }
33107bded2dbSJung-uk Kim         }
33117bded2dbSJung-uk Kim     }
33127bded2dbSJung-uk Kim  end:
33137bded2dbSJung-uk Kim     /* make sure we re-use sessions */
33147bded2dbSJung-uk Kim     SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
33157bded2dbSJung-uk Kim 
33167bded2dbSJung-uk Kim  err:
33177bded2dbSJung-uk Kim 
33187bded2dbSJung-uk Kim     if (buf != NULL)
33197bded2dbSJung-uk Kim         OPENSSL_free(buf);
33207bded2dbSJung-uk Kim     if (io != NULL)
33217bded2dbSJung-uk Kim         BIO_free_all(io);
33227bded2dbSJung-uk Kim     return (ret);
33237bded2dbSJung-uk Kim }
33247bded2dbSJung-uk Kim 
33255c87c606SMark Murray #ifndef OPENSSL_NO_RSA
332674664626SKris Kennaway static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
332774664626SKris Kennaway {
33283b4e3dcbSSimon L. B. Nielsen     BIGNUM *bn = NULL;
332974664626SKris Kennaway     static RSA *rsa_tmp = NULL;
333074664626SKris Kennaway 
33313b4e3dcbSSimon L. B. Nielsen     if (!rsa_tmp && ((bn = BN_new()) == NULL))
33323b4e3dcbSSimon L. B. Nielsen         BIO_printf(bio_err, "Allocation error in generating RSA key\n");
33336f9291ceSJung-uk Kim     if (!rsa_tmp && bn) {
33346f9291ceSJung-uk Kim         if (!s_quiet) {
33356f9291ceSJung-uk Kim             BIO_printf(bio_err, "Generating temp (%d bit) RSA key...",
33366f9291ceSJung-uk Kim                        keylength);
333774664626SKris Kennaway             (void)BIO_flush(bio_err);
333874664626SKris Kennaway         }
33393b4e3dcbSSimon L. B. Nielsen         if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
33406f9291ceSJung-uk Kim             !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
33416f9291ceSJung-uk Kim             if (rsa_tmp)
33426f9291ceSJung-uk Kim                 RSA_free(rsa_tmp);
33433b4e3dcbSSimon L. B. Nielsen             rsa_tmp = NULL;
33443b4e3dcbSSimon L. B. Nielsen         }
33456f9291ceSJung-uk Kim         if (!s_quiet) {
334674664626SKris Kennaway             BIO_printf(bio_err, "\n");
334774664626SKris Kennaway             (void)BIO_flush(bio_err);
334874664626SKris Kennaway         }
33493b4e3dcbSSimon L. B. Nielsen         BN_free(bn);
335074664626SKris Kennaway     }
335174664626SKris Kennaway     return (rsa_tmp);
335274664626SKris Kennaway }
335374664626SKris Kennaway #endif
33545c87c606SMark Murray 
33555c87c606SMark Murray #define MAX_SESSION_ID_ATTEMPTS 10
33565c87c606SMark Murray static int generate_session_id(const SSL *ssl, unsigned char *id,
33575c87c606SMark Murray                                unsigned int *id_len)
33585c87c606SMark Murray {
33595c87c606SMark Murray     unsigned int count = 0;
33605c87c606SMark Murray     do {
3361ed6b93beSJung-uk Kim         if (RAND_pseudo_bytes(id, *id_len) < 0)
3362ed6b93beSJung-uk Kim             return 0;
33636f9291ceSJung-uk Kim         /*
33646f9291ceSJung-uk Kim          * Prefix the session_id with the required prefix. NB: If our prefix
33656f9291ceSJung-uk Kim          * is too long, clip it - but there will be worse effects anyway, eg.
33666f9291ceSJung-uk Kim          * the server could only possibly create 1 session ID (ie. the
33676f9291ceSJung-uk Kim          * prefix!) so all future session negotiations will fail due to
33686f9291ceSJung-uk Kim          * conflicts.
33696f9291ceSJung-uk Kim          */
33705c87c606SMark Murray         memcpy(id, session_id_prefix,
33715c87c606SMark Murray                (strlen(session_id_prefix) < *id_len) ?
33725c87c606SMark Murray                strlen(session_id_prefix) : *id_len);
33735c87c606SMark Murray     }
33745c87c606SMark Murray     while (SSL_has_matching_session_id(ssl, id, *id_len) &&
33755c87c606SMark Murray            (++count < MAX_SESSION_ID_ATTEMPTS));
33765c87c606SMark Murray     if (count >= MAX_SESSION_ID_ATTEMPTS)
33775c87c606SMark Murray         return 0;
33785c87c606SMark Murray     return 1;
33795c87c606SMark Murray }
33807bded2dbSJung-uk Kim 
33817bded2dbSJung-uk Kim /*
33827bded2dbSJung-uk Kim  * By default s_server uses an in-memory cache which caches SSL_SESSION
33837bded2dbSJung-uk Kim  * structures without any serialisation. This hides some bugs which only
33847bded2dbSJung-uk Kim  * become apparent in deployed servers. By implementing a basic external
33857bded2dbSJung-uk Kim  * session cache some issues can be debugged using s_server.
33867bded2dbSJung-uk Kim  */
33877bded2dbSJung-uk Kim 
33887bded2dbSJung-uk Kim typedef struct simple_ssl_session_st {
33897bded2dbSJung-uk Kim     unsigned char *id;
33907bded2dbSJung-uk Kim     unsigned int idlen;
33917bded2dbSJung-uk Kim     unsigned char *der;
33927bded2dbSJung-uk Kim     int derlen;
33937bded2dbSJung-uk Kim     struct simple_ssl_session_st *next;
33947bded2dbSJung-uk Kim } simple_ssl_session;
33957bded2dbSJung-uk Kim 
33967bded2dbSJung-uk Kim static simple_ssl_session *first = NULL;
33977bded2dbSJung-uk Kim 
33987bded2dbSJung-uk Kim static int add_session(SSL *ssl, SSL_SESSION *session)
33997bded2dbSJung-uk Kim {
34007bded2dbSJung-uk Kim     simple_ssl_session *sess;
34017bded2dbSJung-uk Kim     unsigned char *p;
34027bded2dbSJung-uk Kim 
34037bded2dbSJung-uk Kim     sess = OPENSSL_malloc(sizeof(simple_ssl_session));
34047bded2dbSJung-uk Kim     if (!sess) {
34057bded2dbSJung-uk Kim         BIO_printf(bio_err, "Out of memory adding session to external cache\n");
34067bded2dbSJung-uk Kim         return 0;
34077bded2dbSJung-uk Kim     }
34087bded2dbSJung-uk Kim 
34097bded2dbSJung-uk Kim     SSL_SESSION_get_id(session, &sess->idlen);
34107bded2dbSJung-uk Kim     sess->derlen = i2d_SSL_SESSION(session, NULL);
34117bded2dbSJung-uk Kim 
34127bded2dbSJung-uk Kim     sess->id = BUF_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen);
34137bded2dbSJung-uk Kim 
34147bded2dbSJung-uk Kim     sess->der = OPENSSL_malloc(sess->derlen);
34157bded2dbSJung-uk Kim     if (!sess->id || !sess->der) {
34167bded2dbSJung-uk Kim         BIO_printf(bio_err, "Out of memory adding session to external cache\n");
34177bded2dbSJung-uk Kim 
34187bded2dbSJung-uk Kim         if (sess->id)
34197bded2dbSJung-uk Kim             OPENSSL_free(sess->id);
34207bded2dbSJung-uk Kim         if (sess->der)
34217bded2dbSJung-uk Kim             OPENSSL_free(sess->der);
34227bded2dbSJung-uk Kim         OPENSSL_free(sess);
34237bded2dbSJung-uk Kim         return 0;
34247bded2dbSJung-uk Kim     }
34257bded2dbSJung-uk Kim     p = sess->der;
34267bded2dbSJung-uk Kim     i2d_SSL_SESSION(session, &p);
34277bded2dbSJung-uk Kim 
34287bded2dbSJung-uk Kim     sess->next = first;
34297bded2dbSJung-uk Kim     first = sess;
34307bded2dbSJung-uk Kim     BIO_printf(bio_err, "New session added to external cache\n");
34317bded2dbSJung-uk Kim     return 0;
34327bded2dbSJung-uk Kim }
34337bded2dbSJung-uk Kim 
34347bded2dbSJung-uk Kim static SSL_SESSION *get_session(SSL *ssl, unsigned char *id, int idlen,
34357bded2dbSJung-uk Kim                                 int *do_copy)
34367bded2dbSJung-uk Kim {
34377bded2dbSJung-uk Kim     simple_ssl_session *sess;
34387bded2dbSJung-uk Kim     *do_copy = 0;
34397bded2dbSJung-uk Kim     for (sess = first; sess; sess = sess->next) {
34407bded2dbSJung-uk Kim         if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) {
34417bded2dbSJung-uk Kim             const unsigned char *p = sess->der;
34427bded2dbSJung-uk Kim             BIO_printf(bio_err, "Lookup session: cache hit\n");
34437bded2dbSJung-uk Kim             return d2i_SSL_SESSION(NULL, &p, sess->derlen);
34447bded2dbSJung-uk Kim         }
34457bded2dbSJung-uk Kim     }
34467bded2dbSJung-uk Kim     BIO_printf(bio_err, "Lookup session: cache miss\n");
34477bded2dbSJung-uk Kim     return NULL;
34487bded2dbSJung-uk Kim }
34497bded2dbSJung-uk Kim 
34507bded2dbSJung-uk Kim static void del_session(SSL_CTX *sctx, SSL_SESSION *session)
34517bded2dbSJung-uk Kim {
34527bded2dbSJung-uk Kim     simple_ssl_session *sess, *prev = NULL;
34537bded2dbSJung-uk Kim     const unsigned char *id;
34547bded2dbSJung-uk Kim     unsigned int idlen;
34557bded2dbSJung-uk Kim     id = SSL_SESSION_get_id(session, &idlen);
34567bded2dbSJung-uk Kim     for (sess = first; sess; sess = sess->next) {
34577bded2dbSJung-uk Kim         if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) {
34587bded2dbSJung-uk Kim             if (prev)
34597bded2dbSJung-uk Kim                 prev->next = sess->next;
34607bded2dbSJung-uk Kim             else
34617bded2dbSJung-uk Kim                 first = sess->next;
34627bded2dbSJung-uk Kim             OPENSSL_free(sess->id);
34637bded2dbSJung-uk Kim             OPENSSL_free(sess->der);
34647bded2dbSJung-uk Kim             OPENSSL_free(sess);
34657bded2dbSJung-uk Kim             return;
34667bded2dbSJung-uk Kim         }
34677bded2dbSJung-uk Kim         prev = sess;
34687bded2dbSJung-uk Kim     }
34697bded2dbSJung-uk Kim }
34707bded2dbSJung-uk Kim 
34717bded2dbSJung-uk Kim static void init_session_cache_ctx(SSL_CTX *sctx)
34727bded2dbSJung-uk Kim {
34737bded2dbSJung-uk Kim     SSL_CTX_set_session_cache_mode(sctx,
34747bded2dbSJung-uk Kim                                    SSL_SESS_CACHE_NO_INTERNAL |
34757bded2dbSJung-uk Kim                                    SSL_SESS_CACHE_SERVER);
34767bded2dbSJung-uk Kim     SSL_CTX_sess_set_new_cb(sctx, add_session);
34777bded2dbSJung-uk Kim     SSL_CTX_sess_set_get_cb(sctx, get_session);
34787bded2dbSJung-uk Kim     SSL_CTX_sess_set_remove_cb(sctx, del_session);
34797bded2dbSJung-uk Kim }
34807bded2dbSJung-uk Kim 
34817bded2dbSJung-uk Kim static void free_sessions(void)
34827bded2dbSJung-uk Kim {
34837bded2dbSJung-uk Kim     simple_ssl_session *sess, *tsess;
34847bded2dbSJung-uk Kim     for (sess = first; sess;) {
34857bded2dbSJung-uk Kim         OPENSSL_free(sess->id);
34867bded2dbSJung-uk Kim         OPENSSL_free(sess->der);
34877bded2dbSJung-uk Kim         tsess = sess;
34887bded2dbSJung-uk Kim         sess = sess->next;
34897bded2dbSJung-uk Kim         OPENSSL_free(tsess);
34907bded2dbSJung-uk Kim     }
34917bded2dbSJung-uk Kim     first = NULL;
34927bded2dbSJung-uk Kim }
3493