os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/s_server.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/s_server.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2023 @@
     1.4 +/* apps/s_server.c */
     1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
     1.6 + * All rights reserved.
     1.7 + *
     1.8 + * This package is an SSL implementation written
     1.9 + * by Eric Young (eay@cryptsoft.com).
    1.10 + * The implementation was written so as to conform with Netscapes SSL.
    1.11 + * 
    1.12 + * This library is free for commercial and non-commercial use as long as
    1.13 + * the following conditions are aheared to.  The following conditions
    1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
    1.15 + * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
    1.16 + * included with this distribution is covered by the same copyright terms
    1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
    1.18 + * 
    1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
    1.20 + * the code are not to be removed.
    1.21 + * If this package is used in a product, Eric Young should be given attribution
    1.22 + * as the author of the parts of the library used.
    1.23 + * This can be in the form of a textual message at program startup or
    1.24 + * in documentation (online or textual) provided with the package.
    1.25 + * 
    1.26 + * Redistribution and use in source and binary forms, with or without
    1.27 + * modification, are permitted provided that the following conditions
    1.28 + * are met:
    1.29 + * 1. Redistributions of source code must retain the copyright
    1.30 + *    notice, this list of conditions and the following disclaimer.
    1.31 + * 2. Redistributions in binary form must reproduce the above copyright
    1.32 + *    notice, this list of conditions and the following disclaimer in the
    1.33 + *    documentation and/or other materials provided with the distribution.
    1.34 + * 3. All advertising materials mentioning features or use of this software
    1.35 + *    must display the following acknowledgement:
    1.36 + *    "This product includes cryptographic software written by
    1.37 + *     Eric Young (eay@cryptsoft.com)"
    1.38 + *    The word 'cryptographic' can be left out if the rouines from the library
    1.39 + *    being used are not cryptographic related :-).
    1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from 
    1.41 + *    the apps directory (application code) you must include an acknowledgement:
    1.42 + *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
    1.43 + * 
    1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
    1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.47 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.54 + * SUCH DAMAGE.
    1.55 + * 
    1.56 + * The licence and distribution terms for any publically available version or
    1.57 + * derivative of this code cannot be changed.  i.e. this code cannot simply be
    1.58 + * copied and put under another distribution licence
    1.59 + * [including the GNU Public Licence.]
    1.60 + */
    1.61 +/* ====================================================================
    1.62 + * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
    1.63 + *
    1.64 + * Redistribution and use in source and binary forms, with or without
    1.65 + * modification, are permitted provided that the following conditions
    1.66 + * are met:
    1.67 + *
    1.68 + * 1. Redistributions of source code must retain the above copyright
    1.69 + *    notice, this list of conditions and the following disclaimer. 
    1.70 + *
    1.71 + * 2. Redistributions in binary form must reproduce the above copyright
    1.72 + *    notice, this list of conditions and the following disclaimer in
    1.73 + *    the documentation and/or other materials provided with the
    1.74 + *    distribution.
    1.75 + *
    1.76 + * 3. All advertising materials mentioning features or use of this
    1.77 + *    software must display the following acknowledgment:
    1.78 + *    "This product includes software developed by the OpenSSL Project
    1.79 + *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    1.80 + *
    1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    1.82 + *    endorse or promote products derived from this software without
    1.83 + *    prior written permission. For written permission, please contact
    1.84 + *    openssl-core@openssl.org.
    1.85 + *
    1.86 + * 5. Products derived from this software may not be called "OpenSSL"
    1.87 + *    nor may "OpenSSL" appear in their names without prior written
    1.88 + *    permission of the OpenSSL Project.
    1.89 + *
    1.90 + * 6. Redistributions of any form whatsoever must retain the following
    1.91 + *    acknowledgment:
    1.92 + *    "This product includes software developed by the OpenSSL Project
    1.93 + *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    1.94 + *
    1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    1.98 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
   1.107 + * ====================================================================
   1.108 + *
   1.109 + * This product includes cryptographic software written by Eric Young
   1.110 + * (eay@cryptsoft.com).  This product includes software written by Tim
   1.111 + * Hudson (tjh@cryptsoft.com).
   1.112 + *
   1.113 + */
   1.114 +/* ====================================================================
   1.115 + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
   1.116 + * ECC cipher suite support in OpenSSL originally developed by 
   1.117 + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
   1.118 + */
   1.119 +
   1.120 +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
   1.121 + * deprecated functions for openssl-internal code */
   1.122 +#ifdef OPENSSL_NO_DEPRECATED
   1.123 +#undef OPENSSL_NO_DEPRECATED
   1.124 +#endif
   1.125 +
   1.126 +#include <assert.h>
   1.127 +#include <stdio.h>
   1.128 +#include <stdlib.h>
   1.129 +#include <string.h>
   1.130 +#include <sys/select.h>
   1.131 +#include <sys/stat.h>
   1.132 +#include <openssl/e_os2.h>
   1.133 +#ifdef OPENSSL_NO_STDIO
   1.134 +#define APPS_WIN16
   1.135 +#endif
   1.136 +
   1.137 +#if !defined(OPENSSL_SYS_NETWARE)  /* conflicts with winsock2 stuff on netware */
   1.138 +#include <sys/types.h>
   1.139 +#endif
   1.140 +
   1.141 +/* With IPv6, it looks like Digital has mixed up the proper order of
   1.142 +   recursive header file inclusion, resulting in the compiler complaining
   1.143 +   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
   1.144 +   is needed to have fileno() declared correctly...  So let's define u_int */
   1.145 +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
   1.146 +#define __U_INT
   1.147 +typedef unsigned int u_int;
   1.148 +#endif
   1.149 +
   1.150 +#include <openssl/lhash.h>
   1.151 +#include <openssl/bn.h>
   1.152 +#define USE_SOCKETS
   1.153 +#include "apps.h"
   1.154 +#include <openssl/err.h>
   1.155 +#include <openssl/pem.h>
   1.156 +#include <openssl/x509.h>
   1.157 +#include <openssl/ssl.h>
   1.158 +#include <openssl/rand.h>
   1.159 +#ifndef OPENSSL_NO_DH
   1.160 +#include <openssl/dh.h>
   1.161 +#endif
   1.162 +#ifndef OPENSSL_NO_RSA
   1.163 +#include <openssl/rsa.h>
   1.164 +#endif
   1.165 +#include "s_apps.h"
   1.166 +#include "timeouts.h"
   1.167 +
   1.168 +#ifdef OPENSSL_SYS_WINCE
   1.169 +/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
   1.170 +#ifdef fileno
   1.171 +#undef fileno
   1.172 +#endif
   1.173 +#define fileno(a) (int)_fileno(a)
   1.174 +#endif
   1.175 +
   1.176 +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
   1.177 +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
   1.178 +#undef FIONBIO
   1.179 +#endif
   1.180 +
   1.181 +#ifndef OPENSSL_NO_RSA
   1.182 +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
   1.183 +#endif
   1.184 +static int sv_body(char *hostname, int s, unsigned char *context);
   1.185 +static int www_body(char *hostname, int s, unsigned char *context);
   1.186 +static void close_accept_socket(void );
   1.187 +static void sv_usage(void);
   1.188 +static int init_ssl_connection(SSL *s);
   1.189 +static void print_stats(BIO *bp,SSL_CTX *ctx);
   1.190 +static int generate_session_id(const SSL *ssl, unsigned char *id,
   1.191 +				unsigned int *id_len);
   1.192 +#ifndef OPENSSL_NO_DH
   1.193 +static DH *load_dh_param(const char *dhfile);
   1.194 +static DH *get_dh512(void);
   1.195 +#endif
   1.196 +
   1.197 +
   1.198 +#ifdef MONOLITH
   1.199 +static void s_server_init(void);
   1.200 +#endif
   1.201 +
   1.202 +#ifndef S_ISDIR
   1.203 +# if defined(_S_IFMT) && defined(_S_IFDIR)
   1.204 +#  define S_ISDIR(a)	(((a) & _S_IFMT) == _S_IFDIR)
   1.205 +# else
   1.206 +#  define S_ISDIR(a)	(((a) & S_IFMT) == S_IFDIR)
   1.207 +# endif
   1.208 +#endif
   1.209 +
   1.210 +#ifndef OPENSSL_NO_DH
   1.211 +static unsigned char dh512_p[]={
   1.212 +	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
   1.213 +	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
   1.214 +	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
   1.215 +	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
   1.216 +	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
   1.217 +	0x47,0x74,0xE8,0x33,
   1.218 +	};
   1.219 +static unsigned char dh512_g[]={
   1.220 +	0x02,
   1.221 +	};
   1.222 +
   1.223 +static DH *get_dh512(void)
   1.224 +	{
   1.225 +	DH *dh=NULL;
   1.226 +
   1.227 +	if ((dh=DH_new()) == NULL) return(NULL);
   1.228 +	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
   1.229 +	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
   1.230 +	if ((dh->p == NULL) || (dh->g == NULL))
   1.231 +		return(NULL);
   1.232 +	return(dh);
   1.233 +	}
   1.234 +#endif
   1.235 +
   1.236 +
   1.237 +/* static int load_CA(SSL_CTX *ctx, char *file);*/
   1.238 +
   1.239 +#undef BUFSIZZ
   1.240 +#define BUFSIZZ	16*1024
   1.241 +static int bufsize=BUFSIZZ;
   1.242 +static int accept_socket= -1;
   1.243 +
   1.244 +#define TEST_CERT	"server.pem"
   1.245 +#undef PROG
   1.246 +#define PROG		s_server_main
   1.247 +
   1.248 +extern int verify_depth;
   1.249 +
   1.250 +static char *cipher=NULL;
   1.251 +static int s_server_verify=SSL_VERIFY_NONE;
   1.252 +static int s_server_session_id_context = 1; /* anything will do */
   1.253 +static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
   1.254 +static char *s_dcert_file=NULL,*s_dkey_file=NULL;
   1.255 +#ifdef FIONBIO
   1.256 +static int s_nbio=0;
   1.257 +#endif
   1.258 +static int s_nbio_test=0;
   1.259 +int s_crlf=0;
   1.260 +static SSL_CTX *ctx=NULL;
   1.261 +static int www=0;
   1.262 +
   1.263 +static BIO *bio_s_out=NULL;
   1.264 +static int s_debug=0;
   1.265 +static int s_msg=0;
   1.266 +static int s_quiet=0;
   1.267 +
   1.268 +static int hack=0;
   1.269 +#ifndef OPENSSL_NO_ENGINE
   1.270 +static char *engine_id=NULL;
   1.271 +#endif
   1.272 +static const char *session_id_prefix=NULL;
   1.273 +
   1.274 +static int enable_timeouts = 0;
   1.275 +#ifdef mtu
   1.276 +#undef mtu
   1.277 +#endif
   1.278 +static long mtu;
   1.279 +static int cert_chain = 0;
   1.280 +
   1.281 +
   1.282 +#ifdef MONOLITH
   1.283 +static void s_server_init(void)
   1.284 +	{
   1.285 +	accept_socket=-1;
   1.286 +	cipher=NULL;
   1.287 +	s_server_verify=SSL_VERIFY_NONE;
   1.288 +	s_dcert_file=NULL;
   1.289 +	s_dkey_file=NULL;
   1.290 +	s_cert_file=TEST_CERT;
   1.291 +	s_key_file=NULL;
   1.292 +#ifdef FIONBIO
   1.293 +	s_nbio=0;
   1.294 +#endif
   1.295 +	s_nbio_test=0;
   1.296 +	ctx=NULL;
   1.297 +	www=0;
   1.298 +
   1.299 +	bio_s_out=NULL;
   1.300 +	s_debug=0;
   1.301 +	s_msg=0;
   1.302 +	s_quiet=0;
   1.303 +	hack=0;
   1.304 +#ifndef OPENSSL_NO_ENGINE
   1.305 +	engine_id=NULL;
   1.306 +#endif
   1.307 +	}
   1.308 +#endif
   1.309 +
   1.310 +static void sv_usage(void)
   1.311 +	{
   1.312 +	BIO_printf(bio_err,"usage: s_server [args ...]\n");
   1.313 +	BIO_printf(bio_err,"\n");
   1.314 +	BIO_printf(bio_err," -accept arg   - port to accept on (default is %d)\n",PORT);
   1.315 +	BIO_printf(bio_err," -context arg  - set session ID context\n");
   1.316 +	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
   1.317 +	BIO_printf(bio_err," -Verify arg   - turn on peer certificate verification, must have a cert.\n");
   1.318 +	BIO_printf(bio_err," -cert arg     - certificate file to use\n");
   1.319 +	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
   1.320 +	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
   1.321 +	BIO_printf(bio_err," -key arg      - Private Key file to use, in cert file if\n");
   1.322 +	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT);
   1.323 +	BIO_printf(bio_err," -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
   1.324 +	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
   1.325 +	BIO_printf(bio_err," -dcert arg    - second certificate file to use (usually for DSA)\n");
   1.326 +	BIO_printf(bio_err," -dcertform x  - second certificate format (PEM or DER) PEM default\n");
   1.327 +	BIO_printf(bio_err," -dkey arg     - second private key file to use (usually for DSA)\n");
   1.328 +	BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
   1.329 +	BIO_printf(bio_err," -dpass arg    - second private key file pass phrase source\n");
   1.330 +	BIO_printf(bio_err," -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
   1.331 +	BIO_printf(bio_err,"                 or a default set of parameters is used\n");
   1.332 +#ifndef OPENSSL_NO_ECDH
   1.333 +	BIO_printf(bio_err," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
   1.334 +	                   "                 Use \"openssl ecparam -list_curves\" for all names\n" \
   1.335 +	                   "                 (default is sect163r2).\n");
   1.336 +#endif
   1.337 +#ifdef FIONBIO
   1.338 +	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
   1.339 +#endif
   1.340 +	BIO_printf(bio_err," -nbio_test    - test with the non-blocking test bio\n");
   1.341 +	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
   1.342 +	BIO_printf(bio_err," -debug        - Print more output\n");
   1.343 +	BIO_printf(bio_err," -msg          - Show protocol messages\n");
   1.344 +	BIO_printf(bio_err," -state        - Print the SSL states\n");
   1.345 +	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
   1.346 +	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
   1.347 +	BIO_printf(bio_err," -nocert       - Don't use any certificates (Anon-DH)\n");
   1.348 +	BIO_printf(bio_err," -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
   1.349 +	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences\n");
   1.350 +	BIO_printf(bio_err," -quiet        - No server output\n");
   1.351 +	BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
   1.352 +	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
   1.353 +	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
   1.354 +	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
   1.355 +	BIO_printf(bio_err," -dtls1        - Just talk DTLSv1\n");
   1.356 +	BIO_printf(bio_err," -timeout      - Enable timeouts\n");
   1.357 +	BIO_printf(bio_err," -mtu          - Set MTU\n");
   1.358 +	BIO_printf(bio_err," -chain        - Read a certificate chain\n");
   1.359 +	BIO_printf(bio_err," -no_ssl2      - Just disable SSLv2\n");
   1.360 +	BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n");
   1.361 +	BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n");
   1.362 +#ifndef OPENSSL_NO_DH
   1.363 +	BIO_printf(bio_err," -no_dhe       - Disable ephemeral DH\n");
   1.364 +#endif
   1.365 +#ifndef OPENSSL_NO_ECDH
   1.366 +	BIO_printf(bio_err," -no_ecdhe     - Disable ephemeral ECDH\n");
   1.367 +#endif
   1.368 +	BIO_printf(bio_err," -bugs         - Turn on SSL bug compatibility\n");
   1.369 +	BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
   1.370 +	BIO_printf(bio_err," -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
   1.371 +	BIO_printf(bio_err," -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
   1.372 +        BIO_printf(bio_err,"                 with the assumption it contains a complete HTTP response.\n");
   1.373 +#ifndef OPENSSL_NO_ENGINE
   1.374 +	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
   1.375 +#endif
   1.376 +	BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
   1.377 +	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
   1.378 +	}
   1.379 +
   1.380 +static int local_argc=0;
   1.381 +static char **local_argv;
   1.382 +
   1.383 +#ifdef CHARSET_EBCDIC
   1.384 +static int ebcdic_new(BIO *bi);
   1.385 +static int ebcdic_free(BIO *a);
   1.386 +static int ebcdic_read(BIO *b, char *out, int outl);
   1.387 +static int ebcdic_write(BIO *b, const char *in, int inl);
   1.388 +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
   1.389 +static int ebcdic_gets(BIO *bp, char *buf, int size);
   1.390 +static int ebcdic_puts(BIO *bp, const char *str);
   1.391 +
   1.392 +#define BIO_TYPE_EBCDIC_FILTER	(18|0x0200)
   1.393 +static BIO_METHOD methods_ebcdic=
   1.394 +	{
   1.395 +	BIO_TYPE_EBCDIC_FILTER,
   1.396 +	"EBCDIC/ASCII filter",
   1.397 +	ebcdic_write,
   1.398 +	ebcdic_read,
   1.399 +	ebcdic_puts,
   1.400 +	ebcdic_gets,
   1.401 +	ebcdic_ctrl,
   1.402 +	ebcdic_new,
   1.403 +	ebcdic_free,
   1.404 +	};
   1.405 +
   1.406 +typedef struct
   1.407 +{
   1.408 +	size_t	alloced;
   1.409 +	char	buff[1];
   1.410 +} EBCDIC_OUTBUFF;
   1.411 +
   1.412 +BIO_METHOD *BIO_f_ebcdic_filter()
   1.413 +{
   1.414 +	return(&methods_ebcdic);
   1.415 +}
   1.416 +
   1.417 +static int ebcdic_new(BIO *bi)
   1.418 +{
   1.419 +	EBCDIC_OUTBUFF *wbuf;
   1.420 +
   1.421 +	wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
   1.422 +	wbuf->alloced = 1024;
   1.423 +	wbuf->buff[0] = '\0';
   1.424 +
   1.425 +	bi->ptr=(char *)wbuf;
   1.426 +	bi->init=1;
   1.427 +	bi->flags=0;
   1.428 +	return(1);
   1.429 +}
   1.430 +
   1.431 +static int ebcdic_free(BIO *a)
   1.432 +{
   1.433 +	if (a == NULL) return(0);
   1.434 +	if (a->ptr != NULL)
   1.435 +		OPENSSL_free(a->ptr);
   1.436 +	a->ptr=NULL;
   1.437 +	a->init=0;
   1.438 +	a->flags=0;
   1.439 +	return(1);
   1.440 +}
   1.441 +	
   1.442 +static int ebcdic_read(BIO *b, char *out, int outl)
   1.443 +{
   1.444 +	int ret=0;
   1.445 +
   1.446 +	if (out == NULL || outl == 0) return(0);
   1.447 +	if (b->next_bio == NULL) return(0);
   1.448 +
   1.449 +	ret=BIO_read(b->next_bio,out,outl);
   1.450 +	if (ret > 0)
   1.451 +		ascii2ebcdic(out,out,ret);
   1.452 +	return(ret);
   1.453 +}
   1.454 +
   1.455 +static int ebcdic_write(BIO *b, const char *in, int inl)
   1.456 +{
   1.457 +	EBCDIC_OUTBUFF *wbuf;
   1.458 +	int ret=0;
   1.459 +	int num;
   1.460 +	unsigned char n;
   1.461 +
   1.462 +	if ((in == NULL) || (inl <= 0)) return(0);
   1.463 +	if (b->next_bio == NULL) return(0);
   1.464 +
   1.465 +	wbuf=(EBCDIC_OUTBUFF *)b->ptr;
   1.466 +
   1.467 +	if (inl > (num = wbuf->alloced))
   1.468 +	{
   1.469 +		num = num + num;  /* double the size */
   1.470 +		if (num < inl)
   1.471 +			num = inl;
   1.472 +		OPENSSL_free(wbuf);
   1.473 +		wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
   1.474 +
   1.475 +		wbuf->alloced = num;
   1.476 +		wbuf->buff[0] = '\0';
   1.477 +
   1.478 +		b->ptr=(char *)wbuf;
   1.479 +	}
   1.480 +
   1.481 +	ebcdic2ascii(wbuf->buff, in, inl);
   1.482 +
   1.483 +	ret=BIO_write(b->next_bio, wbuf->buff, inl);
   1.484 +
   1.485 +	return(ret);
   1.486 +}
   1.487 +
   1.488 +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
   1.489 +{
   1.490 +	long ret;
   1.491 +
   1.492 +	if (b->next_bio == NULL) return(0);
   1.493 +	switch (cmd)
   1.494 +	{
   1.495 +	case BIO_CTRL_DUP:
   1.496 +		ret=0L;
   1.497 +		break;
   1.498 +	default:
   1.499 +		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
   1.500 +		break;
   1.501 +	}
   1.502 +	return(ret);
   1.503 +}
   1.504 +
   1.505 +static int ebcdic_gets(BIO *bp, char *buf, int size)
   1.506 +{
   1.507 +	int i, ret=0;
   1.508 +	if (bp->next_bio == NULL) return(0);
   1.509 +/*	return(BIO_gets(bp->next_bio,buf,size));*/
   1.510 +	for (i=0; i<size-1; ++i)
   1.511 +	{
   1.512 +		ret = ebcdic_read(bp,&buf[i],1);
   1.513 +		if (ret <= 0)
   1.514 +			break;
   1.515 +		else if (buf[i] == '\n')
   1.516 +		{
   1.517 +			++i;
   1.518 +			break;
   1.519 +		}
   1.520 +	}
   1.521 +	if (i < size)
   1.522 +		buf[i] = '\0';
   1.523 +	return (ret < 0 && i == 0) ? ret : i;
   1.524 +}
   1.525 +
   1.526 +static int ebcdic_puts(BIO *bp, const char *str)
   1.527 +{
   1.528 +	if (bp->next_bio == NULL) return(0);
   1.529 +	return ebcdic_write(bp, str, strlen(str));
   1.530 +}
   1.531 +#endif
   1.532 +
   1.533 +int MAIN(int, char **);
   1.534 +
   1.535 +int MAIN(int argc, char *argv[])
   1.536 +	{
   1.537 +	X509_STORE *store = NULL;
   1.538 +	int vflags = 0;
   1.539 +	short port=PORT;
   1.540 +	char *CApath=NULL,*CAfile=NULL;
   1.541 +	unsigned char *context = NULL;
   1.542 +	char *dhfile = NULL;
   1.543 +#ifndef OPENSSL_NO_ECDH
   1.544 +	char *named_curve = NULL;
   1.545 +#endif
   1.546 +	int badop=0,bugs=0;
   1.547 +	int ret=1;
   1.548 +	int off=0;
   1.549 +	int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
   1.550 +	int state=0;
   1.551 +	SSL_METHOD *meth=NULL;
   1.552 +#ifdef sock_type
   1.553 +#undef sock_type
   1.554 +#endif
   1.555 +    int sock_type=SOCK_STREAM;
   1.556 +#ifndef OPENSSL_NO_ENGINE
   1.557 +	ENGINE *e=NULL;
   1.558 +#endif
   1.559 +	char *inrand=NULL;
   1.560 +	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
   1.561 +	char *passarg = NULL, *pass = NULL;
   1.562 +	char *dpassarg = NULL, *dpass = NULL;
   1.563 +	int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
   1.564 +	X509 *s_cert = NULL, *s_dcert = NULL;
   1.565 +	EVP_PKEY *s_key = NULL, *s_dkey = NULL;
   1.566 +
   1.567 +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
   1.568 +	meth=SSLv23_server_method();
   1.569 +#elif !defined(OPENSSL_NO_SSL3)
   1.570 +	meth=SSLv3_server_method();
   1.571 +#elif !defined(OPENSSL_NO_SSL2)
   1.572 +	meth=SSLv2_server_method();
   1.573 +#endif
   1.574 +
   1.575 +	local_argc=argc;
   1.576 +	local_argv=argv;
   1.577 +
   1.578 +	apps_startup();
   1.579 +#ifdef MONOLITH
   1.580 +	s_server_init();
   1.581 +#endif
   1.582 +
   1.583 +	if (bio_err == NULL)
   1.584 +		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
   1.585 +
   1.586 +	if (!load_config(bio_err, NULL))
   1.587 +		goto end;
   1.588 +
   1.589 +	verify_depth=0;
   1.590 +#ifdef FIONBIO
   1.591 +	s_nbio=0;
   1.592 +#endif
   1.593 +	s_nbio_test=0;
   1.594 +
   1.595 +	argc--;
   1.596 +	argv++;
   1.597 +
   1.598 +	while (argc >= 1)
   1.599 +		{
   1.600 +		if	((strcmp(*argv,"-port") == 0) ||
   1.601 +			 (strcmp(*argv,"-accept") == 0))
   1.602 +			{
   1.603 +			if (--argc < 1) goto bad;
   1.604 +			if (!extract_port(*(++argv),&port))
   1.605 +				goto bad;
   1.606 +			}
   1.607 +		else if	(strcmp(*argv,"-verify") == 0)
   1.608 +			{
   1.609 +			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
   1.610 +			if (--argc < 1) goto bad;
   1.611 +			verify_depth=atoi(*(++argv));
   1.612 +			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
   1.613 +			}
   1.614 +		else if	(strcmp(*argv,"-Verify") == 0)
   1.615 +			{
   1.616 +			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
   1.617 +				SSL_VERIFY_CLIENT_ONCE;
   1.618 +			if (--argc < 1) goto bad;
   1.619 +			verify_depth=atoi(*(++argv));
   1.620 +			BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
   1.621 +			}
   1.622 +		else if	(strcmp(*argv,"-context") == 0)
   1.623 +			{
   1.624 +			if (--argc < 1) goto bad;
   1.625 +			context= (unsigned char *)*(++argv);
   1.626 +			}
   1.627 +		else if	(strcmp(*argv,"-cert") == 0)
   1.628 +			{
   1.629 +			if (--argc < 1) goto bad;
   1.630 +			s_cert_file= *(++argv);
   1.631 +			}
   1.632 +		else if	(strcmp(*argv,"-certform") == 0)
   1.633 +			{
   1.634 +			if (--argc < 1) goto bad;
   1.635 +			s_cert_format = str2fmt(*(++argv));
   1.636 +			}
   1.637 +		else if	(strcmp(*argv,"-key") == 0)
   1.638 +			{
   1.639 +			if (--argc < 1) goto bad;
   1.640 +			s_key_file= *(++argv);
   1.641 +			}
   1.642 +		else if	(strcmp(*argv,"-keyform") == 0)
   1.643 +			{
   1.644 +			if (--argc < 1) goto bad;
   1.645 +			s_key_format = str2fmt(*(++argv));
   1.646 +			}
   1.647 +		else if	(strcmp(*argv,"-pass") == 0)
   1.648 +			{
   1.649 +			if (--argc < 1) goto bad;
   1.650 +			passarg = *(++argv);
   1.651 +			}
   1.652 +		else if	(strcmp(*argv,"-dhparam") == 0)
   1.653 +			{
   1.654 +			if (--argc < 1) goto bad;
   1.655 +			dhfile = *(++argv);
   1.656 +			}
   1.657 +#ifndef OPENSSL_NO_ECDH		
   1.658 +		else if	(strcmp(*argv,"-named_curve") == 0)
   1.659 +			{
   1.660 +			if (--argc < 1) goto bad;
   1.661 +			named_curve = *(++argv);
   1.662 +			}
   1.663 +#endif
   1.664 +		else if	(strcmp(*argv,"-dcertform") == 0)
   1.665 +			{
   1.666 +			if (--argc < 1) goto bad;
   1.667 +			s_dcert_format = str2fmt(*(++argv));
   1.668 +			}
   1.669 +		else if	(strcmp(*argv,"-dcert") == 0)
   1.670 +			{
   1.671 +			if (--argc < 1) goto bad;
   1.672 +			s_dcert_file= *(++argv);
   1.673 +			}
   1.674 +		else if	(strcmp(*argv,"-dkeyform") == 0)
   1.675 +			{
   1.676 +			if (--argc < 1) goto bad;
   1.677 +			s_dkey_format = str2fmt(*(++argv));
   1.678 +			}
   1.679 +		else if	(strcmp(*argv,"-dpass") == 0)
   1.680 +			{
   1.681 +			if (--argc < 1) goto bad;
   1.682 +			dpassarg = *(++argv);
   1.683 +			}
   1.684 +		else if	(strcmp(*argv,"-dkey") == 0)
   1.685 +			{
   1.686 +			if (--argc < 1) goto bad;
   1.687 +			s_dkey_file= *(++argv);
   1.688 +			}
   1.689 +		else if (strcmp(*argv,"-nocert") == 0)
   1.690 +			{
   1.691 +			nocert=1;
   1.692 +			}
   1.693 +		else if	(strcmp(*argv,"-CApath") == 0)
   1.694 +			{
   1.695 +			if (--argc < 1) goto bad;
   1.696 +			CApath= *(++argv);
   1.697 +			}
   1.698 +		else if (strcmp(*argv,"-crl_check") == 0)
   1.699 +			{
   1.700 +			vflags |= X509_V_FLAG_CRL_CHECK;
   1.701 +			}
   1.702 +		else if (strcmp(*argv,"-crl_check") == 0)
   1.703 +			{
   1.704 +			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
   1.705 +			}
   1.706 +		else if	(strcmp(*argv,"-serverpref") == 0)
   1.707 +			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
   1.708 +		else if	(strcmp(*argv,"-cipher") == 0)
   1.709 +			{
   1.710 +			if (--argc < 1) goto bad;
   1.711 +			cipher= *(++argv);
   1.712 +			}
   1.713 +		else if	(strcmp(*argv,"-CAfile") == 0)
   1.714 +			{
   1.715 +			if (--argc < 1) goto bad;
   1.716 +			CAfile= *(++argv);
   1.717 +			}
   1.718 +#ifdef FIONBIO	
   1.719 +		else if	(strcmp(*argv,"-nbio") == 0)
   1.720 +			{ s_nbio=1; }
   1.721 +#endif
   1.722 +		else if	(strcmp(*argv,"-nbio_test") == 0)
   1.723 +			{
   1.724 +#ifdef FIONBIO	
   1.725 +			s_nbio=1;
   1.726 +#endif
   1.727 +			s_nbio_test=1;
   1.728 +			}
   1.729 +		else if	(strcmp(*argv,"-debug") == 0)
   1.730 +			{ s_debug=1; }
   1.731 +		else if	(strcmp(*argv,"-msg") == 0)
   1.732 +			{ s_msg=1; }
   1.733 +		else if	(strcmp(*argv,"-hack") == 0)
   1.734 +			{ hack=1; }
   1.735 +		else if	(strcmp(*argv,"-state") == 0)
   1.736 +			{ state=1; }
   1.737 +		else if	(strcmp(*argv,"-crlf") == 0)
   1.738 +			{ s_crlf=1; }
   1.739 +		else if	(strcmp(*argv,"-quiet") == 0)
   1.740 +			{ s_quiet=1; }
   1.741 +		else if	(strcmp(*argv,"-bugs") == 0)
   1.742 +			{ bugs=1; }
   1.743 +		else if	(strcmp(*argv,"-no_tmp_rsa") == 0)
   1.744 +			{ no_tmp_rsa=1; }
   1.745 +		else if	(strcmp(*argv,"-no_dhe") == 0)
   1.746 +			{ no_dhe=1; }
   1.747 +		else if	(strcmp(*argv,"-no_ecdhe") == 0)
   1.748 +			{ no_ecdhe=1; }
   1.749 +		else if	(strcmp(*argv,"-www") == 0)
   1.750 +			{ www=1; }
   1.751 +		else if	(strcmp(*argv,"-WWW") == 0)
   1.752 +			{ www=2; }
   1.753 +		else if	(strcmp(*argv,"-HTTP") == 0)
   1.754 +			{ www=3; }
   1.755 +		else if	(strcmp(*argv,"-no_ssl2") == 0)
   1.756 +			{ off|=SSL_OP_NO_SSLv2; }
   1.757 +		else if	(strcmp(*argv,"-no_ssl3") == 0)
   1.758 +			{ off|=SSL_OP_NO_SSLv3; }
   1.759 +		else if	(strcmp(*argv,"-no_tls1") == 0)
   1.760 +			{ off|=SSL_OP_NO_TLSv1; }
   1.761 +#ifndef OPENSSL_NO_SSL2
   1.762 +		else if	(strcmp(*argv,"-ssl2") == 0)
   1.763 +			{ meth=SSLv2_server_method(); }
   1.764 +#endif
   1.765 +#ifndef OPENSSL_NO_SSL3
   1.766 +		else if	(strcmp(*argv,"-ssl3") == 0)
   1.767 +			{ meth=SSLv3_server_method(); }
   1.768 +#endif
   1.769 +#ifndef OPENSSL_NO_TLS1
   1.770 +		else if	(strcmp(*argv,"-tls1") == 0)
   1.771 +			{ meth=TLSv1_server_method(); }
   1.772 +#endif
   1.773 +#ifndef OPENSSL_NO_DTLS1
   1.774 +		else if	(strcmp(*argv,"-dtls1") == 0)
   1.775 +			{ 
   1.776 +			meth=DTLSv1_server_method();
   1.777 +			sock_type = SOCK_DGRAM;
   1.778 +			}
   1.779 +		else if (strcmp(*argv,"-timeout") == 0)
   1.780 +			enable_timeouts = 1;
   1.781 +		else if (strcmp(*argv,"-mtu") == 0)
   1.782 +			{
   1.783 +			if (--argc < 1) goto bad;
   1.784 +			mtu = atol(*(++argv));
   1.785 +			}
   1.786 +		else if (strcmp(*argv, "-chain") == 0)
   1.787 +			cert_chain = 1;
   1.788 +#endif
   1.789 +		else if (strcmp(*argv, "-id_prefix") == 0)
   1.790 +			{
   1.791 +			if (--argc < 1) goto bad;
   1.792 +			session_id_prefix = *(++argv);
   1.793 +			}
   1.794 +#ifndef OPENSSL_NO_ENGINE
   1.795 +		else if (strcmp(*argv,"-engine") == 0)
   1.796 +			{
   1.797 +			if (--argc < 1) goto bad;
   1.798 +			engine_id= *(++argv);
   1.799 +			}
   1.800 +#endif
   1.801 +		else if (strcmp(*argv,"-rand") == 0)
   1.802 +			{
   1.803 +			if (--argc < 1) goto bad;
   1.804 +			inrand= *(++argv);
   1.805 +			}
   1.806 +		else
   1.807 +			{
   1.808 +			BIO_printf(bio_err,"unknown option %s\n",*argv);
   1.809 +			badop=1;
   1.810 +			break;
   1.811 +			}
   1.812 +		argc--;
   1.813 +		argv++;
   1.814 +		}
   1.815 +	if (badop)
   1.816 +		{
   1.817 +bad:
   1.818 +		sv_usage();
   1.819 +		goto end;
   1.820 +		}
   1.821 +
   1.822 +	SSL_load_error_strings();
   1.823 +	OpenSSL_add_ssl_algorithms();
   1.824 +
   1.825 +#ifndef OPENSSL_NO_ENGINE
   1.826 +        e = setup_engine(bio_err, engine_id, 1);
   1.827 +#endif
   1.828 +
   1.829 +	if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
   1.830 +		{
   1.831 +		BIO_printf(bio_err, "Error getting password\n");
   1.832 +		goto end;
   1.833 +		}
   1.834 +
   1.835 +
   1.836 +	if (s_key_file == NULL)
   1.837 +		s_key_file = s_cert_file;
   1.838 +
   1.839 +	if (nocert == 0)
   1.840 +		{
   1.841 +		s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
   1.842 +		       "server certificate private key file");
   1.843 +		if (!s_key)
   1.844 +			{
   1.845 +			ERR_print_errors(bio_err);
   1.846 +			goto end;
   1.847 +			}
   1.848 +
   1.849 +		s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
   1.850 +			NULL, e, "server certificate file");
   1.851 +
   1.852 +		if (!s_cert)
   1.853 +			{
   1.854 +			ERR_print_errors(bio_err);
   1.855 +			goto end;
   1.856 +			}
   1.857 +		}
   1.858 +
   1.859 +	if (s_dcert_file)
   1.860 +		{
   1.861 +
   1.862 +		if (s_dkey_file == NULL)
   1.863 +			s_dkey_file = s_dcert_file;
   1.864 +
   1.865 +		s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
   1.866 +				0, dpass, e,
   1.867 +			       "second certificate private key file");
   1.868 +		if (!s_dkey)
   1.869 +			{
   1.870 +			ERR_print_errors(bio_err);
   1.871 +			goto end;
   1.872 +			}
   1.873 +
   1.874 +		s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
   1.875 +				NULL, e, "second server certificate file");
   1.876 +
   1.877 +		if (!s_dcert)
   1.878 +			{
   1.879 +			ERR_print_errors(bio_err);
   1.880 +			goto end;
   1.881 +			}
   1.882 +
   1.883 +		}
   1.884 +
   1.885 +	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
   1.886 +		&& !RAND_status())
   1.887 +		{
   1.888 +		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
   1.889 +		}
   1.890 +	if (inrand != NULL)
   1.891 +		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
   1.892 +			app_RAND_load_files(inrand));
   1.893 +
   1.894 +	if (bio_s_out == NULL)
   1.895 +		{
   1.896 +		if (s_quiet && !s_debug && !s_msg)
   1.897 +			{
   1.898 +			bio_s_out=BIO_new(BIO_s_null());
   1.899 +			}
   1.900 +		else
   1.901 +			{
   1.902 +			if (bio_s_out == NULL)
   1.903 +				bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
   1.904 +			
   1.905 +			}
   1.906 +		}
   1.907 +
   1.908 +#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
   1.909 +	if (nocert)
   1.910 +#endif
   1.911 +		{
   1.912 +		s_cert_file=NULL;
   1.913 +		s_key_file=NULL;
   1.914 +		s_dcert_file=NULL;
   1.915 +		s_dkey_file=NULL;
   1.916 +		}
   1.917 +
   1.918 +	ctx=SSL_CTX_new(meth);
   1.919 +	if (ctx == NULL)
   1.920 +		{
   1.921 +		ERR_print_errors(bio_err);
   1.922 +		goto end;
   1.923 +		}
   1.924 +	if (session_id_prefix)
   1.925 +		{
   1.926 +		if(strlen(session_id_prefix) >= 32)
   1.927 +			BIO_printf(bio_err,
   1.928 +"warning: id_prefix is too long, only one new session will be possible\n");
   1.929 +		else if(strlen(session_id_prefix) >= 16)
   1.930 +			BIO_printf(bio_err,
   1.931 +"warning: id_prefix is too long if you use SSLv2\n");
   1.932 +		if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
   1.933 +			{
   1.934 +			BIO_printf(bio_err,"error setting 'id_prefix'\n");
   1.935 +			ERR_print_errors(bio_err);
   1.936 +			goto end;
   1.937 +			}
   1.938 +		BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
   1.939 +		}
   1.940 +	SSL_CTX_set_quiet_shutdown(ctx,1);
   1.941 +	if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
   1.942 +	if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
   1.943 +	SSL_CTX_set_options(ctx,off);
   1.944 +	/* DTLS: partial reads end up discarding unread UDP bytes :-( 
   1.945 +	 * Setting read ahead solves this problem.
   1.946 +	 */
   1.947 +	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
   1.948 +
   1.949 +	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
   1.950 +
   1.951 +	SSL_CTX_sess_set_cache_size(ctx,128);
   1.952 +
   1.953 +#if 0
   1.954 +	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
   1.955 +#endif
   1.956 +
   1.957 +#if 0
   1.958 +	if (s_cert_file == NULL)
   1.959 +		{
   1.960 +		BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
   1.961 +		goto end;
   1.962 +		}
   1.963 +#endif
   1.964 +
   1.965 +	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
   1.966 +		(!SSL_CTX_set_default_verify_paths(ctx)))
   1.967 +		{
   1.968 +		/* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
   1.969 +		ERR_print_errors(bio_err);
   1.970 +		/* goto end; */
   1.971 +		}
   1.972 +	store = SSL_CTX_get_cert_store(ctx);
   1.973 +	X509_STORE_set_flags(store, vflags);
   1.974 +
   1.975 +#ifndef OPENSSL_NO_DH
   1.976 +	if (!no_dhe)
   1.977 +		{
   1.978 +		DH *dh=NULL;
   1.979 +
   1.980 +		if (dhfile)
   1.981 +			dh = load_dh_param(dhfile);
   1.982 +		else if (s_cert_file)
   1.983 +			dh = load_dh_param(s_cert_file);
   1.984 +
   1.985 +		if (dh != NULL)
   1.986 +			{
   1.987 +			BIO_printf(bio_s_out,"Setting temp DH parameters\n");
   1.988 +			}
   1.989 +		else
   1.990 +			{
   1.991 +			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
   1.992 +			dh=get_dh512();
   1.993 +			}
   1.994 +		(void)BIO_flush(bio_s_out);
   1.995 +
   1.996 +		SSL_CTX_set_tmp_dh(ctx,dh);
   1.997 +		DH_free(dh);
   1.998 +		}
   1.999 +#endif
  1.1000 +
  1.1001 +#ifndef OPENSSL_NO_ECDH
  1.1002 +	if (!no_ecdhe)
  1.1003 +		{
  1.1004 +		EC_KEY *ecdh=NULL;
  1.1005 +
  1.1006 +		if (named_curve)
  1.1007 +			{
  1.1008 +			int nid = OBJ_sn2nid(named_curve);
  1.1009 +
  1.1010 +			if (nid == 0)
  1.1011 +				{
  1.1012 +				BIO_printf(bio_err, "unknown curve name (%s)\n", 
  1.1013 +					named_curve);
  1.1014 +				goto end;
  1.1015 +				}
  1.1016 +			ecdh = EC_KEY_new_by_curve_name(nid);
  1.1017 +			if (ecdh == NULL)
  1.1018 +				{
  1.1019 +				BIO_printf(bio_err, "unable to create curve (%s)\n", 
  1.1020 +					named_curve);
  1.1021 +				goto end;
  1.1022 +				}
  1.1023 +			}
  1.1024 +
  1.1025 +		if (ecdh != NULL)
  1.1026 +			{
  1.1027 +			BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
  1.1028 +			}
  1.1029 +		else
  1.1030 +			{
  1.1031 +			BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
  1.1032 +			ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);
  1.1033 +			if (ecdh == NULL) 
  1.1034 +				{
  1.1035 +				BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
  1.1036 +				goto end;
  1.1037 +				}
  1.1038 +			}
  1.1039 +		(void)BIO_flush(bio_s_out);
  1.1040 +
  1.1041 +		SSL_CTX_set_tmp_ecdh(ctx,ecdh);
  1.1042 +		EC_KEY_free(ecdh);
  1.1043 +		}
  1.1044 +#endif
  1.1045 +	
  1.1046 +	if (!set_cert_key_stuff(ctx,s_cert,s_key))
  1.1047 +		goto end;
  1.1048 +	if (s_dcert != NULL)
  1.1049 +		{
  1.1050 +		if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
  1.1051 +			goto end;
  1.1052 +		}
  1.1053 +
  1.1054 +#ifndef OPENSSL_NO_RSA
  1.1055 +#if 1
  1.1056 +	if (!no_tmp_rsa)
  1.1057 +		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
  1.1058 +#else
  1.1059 +	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
  1.1060 +		{
  1.1061 +		RSA *rsa;
  1.1062 +
  1.1063 +		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
  1.1064 +		BIO_flush(bio_s_out);
  1.1065 +
  1.1066 +		rsa=RSA_generate_key(512,RSA_F4,NULL);
  1.1067 +
  1.1068 +		if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
  1.1069 +			{
  1.1070 +			ERR_print_errors(bio_err);
  1.1071 +			goto end;
  1.1072 +			}
  1.1073 +		RSA_free(rsa);
  1.1074 +		BIO_printf(bio_s_out,"\n");
  1.1075 +		}
  1.1076 +#endif
  1.1077 +#endif
  1.1078 +
  1.1079 +	if (cipher != NULL)
  1.1080 +		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
  1.1081 +		BIO_printf(bio_err,"error setting cipher list\n");
  1.1082 +		ERR_print_errors(bio_err);
  1.1083 +		goto end;
  1.1084 +	}
  1.1085 +	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
  1.1086 +	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
  1.1087 +		sizeof s_server_session_id_context);
  1.1088 +
  1.1089 +	if (CAfile != NULL)
  1.1090 +	    SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
  1.1091 +
  1.1092 +	BIO_printf(bio_s_out,"ACCEPT\n");
  1.1093 +	if (www)
  1.1094 +		do_server(port,sock_type,&accept_socket,www_body, context);
  1.1095 +	else
  1.1096 +		do_server(port,sock_type,&accept_socket,sv_body, context);
  1.1097 +	print_stats(bio_s_out,ctx);
  1.1098 +	ret=0;
  1.1099 +end:
  1.1100 +	if (ctx != NULL) SSL_CTX_free(ctx);
  1.1101 +	if (s_cert)
  1.1102 +		X509_free(s_cert);
  1.1103 +	if (s_dcert)
  1.1104 +		X509_free(s_dcert);
  1.1105 +	if (s_key)
  1.1106 +		EVP_PKEY_free(s_key);
  1.1107 +	if (s_dkey)
  1.1108 +		EVP_PKEY_free(s_dkey);
  1.1109 +	if (pass)
  1.1110 +		OPENSSL_free(pass);
  1.1111 +	if (dpass)
  1.1112 +		OPENSSL_free(dpass);
  1.1113 +	if (bio_s_out != NULL)
  1.1114 +		{
  1.1115 +        BIO_free(bio_s_out);
  1.1116 +		bio_s_out=NULL;
  1.1117 +		}
  1.1118 +	apps_shutdown();
  1.1119 +	OPENSSL_EXIT(ret);
  1.1120 +	}
  1.1121 +
  1.1122 +static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
  1.1123 +	{
  1.1124 +	BIO_printf(bio,"%4ld items in the session cache\n",
  1.1125 +		SSL_CTX_sess_number(ssl_ctx));
  1.1126 +	BIO_printf(bio,"%4ld client connects (SSL_connect())\n",
  1.1127 +		SSL_CTX_sess_connect(ssl_ctx));
  1.1128 +	BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
  1.1129 +		SSL_CTX_sess_connect_renegotiate(ssl_ctx));
  1.1130 +	BIO_printf(bio,"%4ld client connects that finished\n",
  1.1131 +		SSL_CTX_sess_connect_good(ssl_ctx));
  1.1132 +	BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
  1.1133 +		SSL_CTX_sess_accept(ssl_ctx));
  1.1134 +	BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
  1.1135 +		SSL_CTX_sess_accept_renegotiate(ssl_ctx));
  1.1136 +	BIO_printf(bio,"%4ld server accepts that finished\n",
  1.1137 +		SSL_CTX_sess_accept_good(ssl_ctx));
  1.1138 +	BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
  1.1139 +	BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
  1.1140 +	BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
  1.1141 +	BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
  1.1142 +	BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",
  1.1143 +		SSL_CTX_sess_cache_full(ssl_ctx),
  1.1144 +		SSL_CTX_sess_get_cache_size(ssl_ctx));
  1.1145 +	}
  1.1146 +
  1.1147 +static int sv_body(char *hostname, int s, unsigned char *context)
  1.1148 +	{
  1.1149 +	char *buf=NULL;
  1.1150 +	fd_set readfds;
  1.1151 +	int ret=1,width;
  1.1152 +	int k,i;
  1.1153 +	unsigned long l;
  1.1154 +	SSL *con=NULL;
  1.1155 +	BIO *sbio;
  1.1156 +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
  1.1157 +	struct timeval tv;
  1.1158 +#endif
  1.1159 +
  1.1160 +	if ((buf=OPENSSL_malloc(bufsize)) == NULL)
  1.1161 +		{
  1.1162 +		BIO_printf(bio_err,"out of memory\n");
  1.1163 +		goto err;
  1.1164 +		}
  1.1165 +#ifdef FIONBIO	
  1.1166 +	if (s_nbio)
  1.1167 +		{
  1.1168 +		unsigned long sl=1;
  1.1169 +
  1.1170 +		if (!s_quiet)
  1.1171 +			BIO_printf(bio_err,"turning on non blocking io\n");
  1.1172 +		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
  1.1173 +			ERR_print_errors(bio_err);
  1.1174 +		}
  1.1175 +#endif
  1.1176 +
  1.1177 +	if (con == NULL) {
  1.1178 +		con=SSL_new(ctx);
  1.1179 +#ifndef OPENSSL_NO_KRB5
  1.1180 +		if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
  1.1181 +                        {
  1.1182 +                        kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
  1.1183 +								KRB5SVC);
  1.1184 +                        kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
  1.1185 +								KRB5KEYTAB);
  1.1186 +                        }
  1.1187 +#endif	/* OPENSSL_NO_KRB5 */
  1.1188 +		if(context)
  1.1189 +		      SSL_set_session_id_context(con, context,
  1.1190 +						 strlen((char *)context));
  1.1191 +	}
  1.1192 +	SSL_clear(con);
  1.1193 +
  1.1194 +	if (SSL_version(con) == DTLS1_VERSION)
  1.1195 +		{
  1.1196 +		struct timeval timeout;
  1.1197 +
  1.1198 +		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
  1.1199 +
  1.1200 +		if ( enable_timeouts)
  1.1201 +			{
  1.1202 +			timeout.tv_sec = 0;
  1.1203 +			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
  1.1204 +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
  1.1205 +			
  1.1206 +			timeout.tv_sec = 0;
  1.1207 +			timeout.tv_usec = DGRAM_SND_TIMEOUT;
  1.1208 +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
  1.1209 +			}
  1.1210 +
  1.1211 +		
  1.1212 +		if ( mtu > 0)
  1.1213 +			{
  1.1214 +			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
  1.1215 +			SSL_set_mtu(con, mtu);
  1.1216 +			}
  1.1217 +		else
  1.1218 +			/* want to do MTU discovery */
  1.1219 +			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
  1.1220 +
  1.1221 +        /* turn on cookie exchange */
  1.1222 +        SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
  1.1223 +		}
  1.1224 +	else
  1.1225 +		sbio=BIO_new_socket(s,BIO_NOCLOSE);
  1.1226 +
  1.1227 +	if (s_nbio_test)
  1.1228 +		{
  1.1229 +		BIO *test;
  1.1230 +
  1.1231 +		test=BIO_new(BIO_f_nbio_test());
  1.1232 +		sbio=BIO_push(test,sbio);
  1.1233 +		}
  1.1234 +	SSL_set_bio(con,sbio,sbio);
  1.1235 +	SSL_set_accept_state(con);
  1.1236 +	/* SSL_set_fd(con,s); */
  1.1237 +
  1.1238 +	if (s_debug)
  1.1239 +		{
  1.1240 +		con->debug=1;
  1.1241 +		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
  1.1242 +		BIO_set_callback_arg(SSL_get_rbio(con),(char*)bio_s_out);
  1.1243 +		}
  1.1244 +	if (s_msg)
  1.1245 +		{
  1.1246 +		SSL_set_msg_callback(con, msg_cb);
  1.1247 +		SSL_set_msg_callback_arg(con, bio_s_out);
  1.1248 +		}
  1.1249 +
  1.1250 +	width=s+1;
  1.1251 +	for (;;)
  1.1252 +		{
  1.1253 +		int read_from_terminal;
  1.1254 +		int read_from_sslcon;
  1.1255 +
  1.1256 +		read_from_terminal = 0;
  1.1257 +		read_from_sslcon = SSL_pending(con);
  1.1258 +
  1.1259 +		if (!read_from_sslcon)
  1.1260 +			{
  1.1261 +			FD_ZERO(&readfds);
  1.1262 +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
  1.1263 +			FD_SET(fileno(stdin),&readfds);
  1.1264 +	
  1.1265 +#endif
  1.1266 +			FD_SET(s,&readfds);
  1.1267 +			/* Note: under VMS with SOCKETSHR the second parameter is
  1.1268 +			 * currently of type (int *) whereas under other systems
  1.1269 +			 * it is (void *) if you don't have a cast it will choke
  1.1270 +			 * the compiler: if you do have a cast then you can either
  1.1271 +			 * go for (int *) or (void *).
  1.1272 +			 */
  1.1273 +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
  1.1274 +                        /* Under DOS (non-djgpp) and Windows we can't select on stdin: only
  1.1275 +			 * on sockets. As a workaround we timeout the select every
  1.1276 +			 * second and check for any keypress. In a proper Windows
  1.1277 +			 * application we wouldn't do this because it is inefficient.
  1.1278 +			 */
  1.1279 +			tv.tv_sec = 1;
  1.1280 +			tv.tv_usec = 0;
  1.1281 +			i=select(width,(void *)&readfds,NULL,NULL,&tv);
  1.1282 +			if((i < 0) || (!i && !_kbhit() ) )continue;
  1.1283 +			if(_kbhit())
  1.1284 +				read_from_terminal = 1;
  1.1285 +#else
  1.1286 +			i=select(width,(void *)&readfds,NULL,NULL,NULL);
  1.1287 +			if (i <= 0) continue;
  1.1288 +			if (FD_ISSET(fileno(stdin),&readfds))
  1.1289 +			
  1.1290 +				read_from_terminal = 1;
  1.1291 +#endif
  1.1292 +			if (FD_ISSET(s,&readfds))
  1.1293 +				read_from_sslcon = 1;
  1.1294 +			}
  1.1295 +		if (read_from_terminal)
  1.1296 +			{
  1.1297 +			if (s_crlf)
  1.1298 +				{
  1.1299 +				int j, lf_num;
  1.1300 +				i=read(fileno(stdin), buf, bufsize/2);
  1.1301 +				lf_num = 0;
  1.1302 +				/* both loops are skipped when i <= 0 */
  1.1303 +				for (j = 0; j < i; j++)
  1.1304 +					if (buf[j] == '\n')
  1.1305 +						lf_num++;
  1.1306 +				for (j = i-1; j >= 0; j--)
  1.1307 +					{
  1.1308 +					buf[j+lf_num] = buf[j];
  1.1309 +					if (buf[j] == '\n')
  1.1310 +						{
  1.1311 +						lf_num--;
  1.1312 +						i++;
  1.1313 +						buf[j+lf_num] = '\r';
  1.1314 +						}
  1.1315 +					}
  1.1316 +				assert(lf_num == 0);
  1.1317 +				}
  1.1318 +			else
  1.1319 +				i=read(fileno(stdin),buf,bufsize);
  1.1320 +				
  1.1321 +			if (!s_quiet)
  1.1322 +				{
  1.1323 +				if ((i <= 0) || (buf[0] == 'Q'))
  1.1324 +					{
  1.1325 +					BIO_printf(bio_s_out,"DONE\n");
  1.1326 +					SHUTDOWN(s);
  1.1327 +					close_accept_socket();
  1.1328 +					ret= -11;
  1.1329 +					goto err;
  1.1330 +					}
  1.1331 +				if ((i <= 0) || (buf[0] == 'q'))
  1.1332 +					{
  1.1333 +					BIO_printf(bio_s_out,"DONE\n");
  1.1334 +					if (SSL_version(con) != DTLS1_VERSION)
  1.1335 +                        SHUTDOWN(s);
  1.1336 +	/*				close_accept_socket();
  1.1337 +					ret= -11;*/
  1.1338 +					goto err;
  1.1339 +					}
  1.1340 +				if ((buf[0] == 'r') && 
  1.1341 +					((buf[1] == '\n') || (buf[1] == '\r')))
  1.1342 +					{
  1.1343 +					SSL_renegotiate(con);
  1.1344 +					i=SSL_do_handshake(con);
  1.1345 +					printf("SSL_do_handshake -> %d\n",i);
  1.1346 +					
  1.1347 +					i=0; /*13; */
  1.1348 +					continue;
  1.1349 +					/* strcpy(buf,"server side RE-NEGOTIATE\n"); */
  1.1350 +					}
  1.1351 +				if ((buf[0] == 'R') &&
  1.1352 +					((buf[1] == '\n') || (buf[1] == '\r')))
  1.1353 +					{
  1.1354 +					SSL_set_verify(con,
  1.1355 +						SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
  1.1356 +					SSL_renegotiate(con);
  1.1357 +					i=SSL_do_handshake(con);
  1.1358 +					printf("SSL_do_handshake -> %d\n",i);
  1.1359 +				
  1.1360 +					i=0; /* 13; */
  1.1361 +					continue;
  1.1362 +					/* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
  1.1363 +					}
  1.1364 +				if (buf[0] == 'P')
  1.1365 +					{
  1.1366 +					static const char *str="Lets print some clear text\n";
  1.1367 +					BIO_write(SSL_get_wbio(con),str,strlen(str));
  1.1368 +					}
  1.1369 +				if (buf[0] == 'S')
  1.1370 +					{
  1.1371 +					print_stats(bio_s_out,SSL_get_SSL_CTX(con));
  1.1372 +					}
  1.1373 +				}
  1.1374 +#ifdef CHARSET_EBCDIC
  1.1375 +			ebcdic2ascii(buf,buf,i);
  1.1376 +#endif
  1.1377 +			l=k=0;
  1.1378 +			for (;;)
  1.1379 +				{
  1.1380 +				/* should do a select for the write */
  1.1381 +#ifdef RENEG
  1.1382 +{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
  1.1383 +#endif
  1.1384 +				k=SSL_write(con,&(buf[l]),(unsigned int)i);
  1.1385 +				switch (SSL_get_error(con,k))
  1.1386 +					{
  1.1387 +				case SSL_ERROR_NONE:
  1.1388 +					break;
  1.1389 +				case SSL_ERROR_WANT_WRITE:
  1.1390 +				case SSL_ERROR_WANT_READ:
  1.1391 +				case SSL_ERROR_WANT_X509_LOOKUP:
  1.1392 +					BIO_printf(bio_s_out,"Write BLOCK\n");
  1.1393 +					break;
  1.1394 +				case SSL_ERROR_SYSCALL:
  1.1395 +				case SSL_ERROR_SSL:
  1.1396 +					BIO_printf(bio_s_out,"ERROR\n");
  1.1397 +					ERR_print_errors(bio_err);
  1.1398 +					ret=1;
  1.1399 +					goto err;
  1.1400 +					/* break; */
  1.1401 +				case SSL_ERROR_ZERO_RETURN:
  1.1402 +					BIO_printf(bio_s_out,"DONE\n");
  1.1403 +					ret=1;
  1.1404 +					goto err;
  1.1405 +					}
  1.1406 +				l+=k;
  1.1407 +				i-=k;
  1.1408 +				if (i <= 0) break;
  1.1409 +				}
  1.1410 +			}
  1.1411 +		if (read_from_sslcon)
  1.1412 +			{
  1.1413 +			if (!SSL_is_init_finished(con))
  1.1414 +				{
  1.1415 +				i=init_ssl_connection(con);
  1.1416 +				
  1.1417 +				if (i < 0)
  1.1418 +					{
  1.1419 +					ret=0;
  1.1420 +					goto err;
  1.1421 +					}
  1.1422 +				else if (i == 0)
  1.1423 +					{
  1.1424 +					ret=1;
  1.1425 +					goto err;
  1.1426 +					}
  1.1427 +				}
  1.1428 +			else
  1.1429 +				{
  1.1430 +again:	
  1.1431 +				i=SSL_read(con,(char *)buf,bufsize);
  1.1432 +				switch (SSL_get_error(con,i))
  1.1433 +					{
  1.1434 +				case SSL_ERROR_NONE:
  1.1435 +#ifdef CHARSET_EBCDIC
  1.1436 +					ascii2ebcdic(buf,buf,i);
  1.1437 +#endif
  1.1438 +					write(fileno(stdout),buf,
  1.1439 +						(unsigned int)i);
  1.1440 +		
  1.1441 +					if (SSL_pending(con)) goto again;
  1.1442 +					break;
  1.1443 +				case SSL_ERROR_WANT_WRITE:
  1.1444 +				case SSL_ERROR_WANT_READ:
  1.1445 +				case SSL_ERROR_WANT_X509_LOOKUP:
  1.1446 +					BIO_printf(bio_s_out,"Read BLOCK\n");
  1.1447 +					break;
  1.1448 +				case SSL_ERROR_SYSCALL:
  1.1449 +				case SSL_ERROR_SSL:
  1.1450 +					BIO_printf(bio_s_out,"ERROR\n");
  1.1451 +					ERR_print_errors(bio_err);
  1.1452 +					ret=1;
  1.1453 +					goto err;
  1.1454 +				case SSL_ERROR_ZERO_RETURN:
  1.1455 +					BIO_printf(bio_s_out,"DONE\n");
  1.1456 +					ret=1;
  1.1457 +					goto err;
  1.1458 +					}
  1.1459 +				}
  1.1460 +			}
  1.1461 +		}
  1.1462 +err:
  1.1463 +	BIO_printf(bio_s_out,"shutting down SSL\n");
  1.1464 +#if 1
  1.1465 +	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
  1.1466 +#else
  1.1467 +	SSL_shutdown(con);
  1.1468 +#endif
  1.1469 +	if (con != NULL) SSL_free(con);
  1.1470 +	BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
  1.1471 +	if (buf != NULL)
  1.1472 +		{
  1.1473 +		OPENSSL_cleanse(buf,bufsize);
  1.1474 +		OPENSSL_free(buf);
  1.1475 +		}
  1.1476 +	if (ret >= 0)
  1.1477 +		BIO_printf(bio_s_out,"ACCEPT\n");
  1.1478 +	return(ret);
  1.1479 +	}
  1.1480 +
  1.1481 +static void close_accept_socket(void)
  1.1482 +	{
  1.1483 +	BIO_printf(bio_err,"shutdown accept socket\n");
  1.1484 +	if (accept_socket >= 0)
  1.1485 +		{
  1.1486 +		SHUTDOWN2(accept_socket);
  1.1487 +		}
  1.1488 +	}
  1.1489 +
  1.1490 +static int init_ssl_connection(SSL *con)
  1.1491 +	{
  1.1492 +	int i;
  1.1493 +	const char *str;
  1.1494 +	X509 *peer;
  1.1495 +	long verify_error;
  1.1496 +	MS_STATIC char buf[BUFSIZ];
  1.1497 +
  1.1498 +	if ((i=SSL_accept(con)) <= 0)
  1.1499 +		{
  1.1500 +		if (BIO_sock_should_retry(i))
  1.1501 +			{
  1.1502 +			BIO_printf(bio_s_out,"DELAY\n");
  1.1503 +			return(1);
  1.1504 +			}
  1.1505 +
  1.1506 +		BIO_printf(bio_err,"ERROR\n");
  1.1507 +		verify_error=SSL_get_verify_result(con);
  1.1508 +		if (verify_error != X509_V_OK)
  1.1509 +			{
  1.1510 +			BIO_printf(bio_err,"verify error:%s\n",
  1.1511 +				X509_verify_cert_error_string(verify_error));
  1.1512 +			}
  1.1513 +		else
  1.1514 +			ERR_print_errors(bio_err);
  1.1515 +		return(0);
  1.1516 +		}
  1.1517 +
  1.1518 +	PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
  1.1519 +
  1.1520 +	peer=SSL_get_peer_certificate(con);
  1.1521 +	if (peer != NULL)
  1.1522 +		{
  1.1523 +		BIO_printf(bio_s_out,"Client certificate\n");
  1.1524 +		PEM_write_bio_X509(bio_s_out,peer);
  1.1525 +		X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
  1.1526 +		BIO_printf(bio_s_out,"subject=%s\n",buf);
  1.1527 +		X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
  1.1528 +		BIO_printf(bio_s_out,"issuer=%s\n",buf);
  1.1529 +		X509_free(peer);
  1.1530 +		}
  1.1531 +
  1.1532 +	if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
  1.1533 +		BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
  1.1534 +	str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
  1.1535 +	BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
  1.1536 +	if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
  1.1537 +	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
  1.1538 +		TLS1_FLAGS_TLS_PADDING_BUG)
  1.1539 +		BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
  1.1540 +#ifndef OPENSSL_NO_KRB5
  1.1541 +	if (con->kssl_ctx->client_princ != NULL)
  1.1542 +		{
  1.1543 +		BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
  1.1544 +			con->kssl_ctx->client_princ);
  1.1545 +		}
  1.1546 +#endif /* OPENSSL_NO_KRB5 */
  1.1547 +	return(1);
  1.1548 +	}
  1.1549 +
  1.1550 +#ifndef OPENSSL_NO_DH
  1.1551 +static DH *load_dh_param(const char *dhfile)
  1.1552 +	{
  1.1553 +	DH *ret=NULL;
  1.1554 +	BIO *bio;
  1.1555 +
  1.1556 +	if ((bio=BIO_new_file(dhfile,"r")) == NULL)
  1.1557 +		goto err;
  1.1558 +	ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
  1.1559 +err:
  1.1560 +	if (bio != NULL) BIO_free(bio);
  1.1561 +	return(ret);
  1.1562 +	}
  1.1563 +#endif
  1.1564 +
  1.1565 +#if 0
  1.1566 +static int load_CA(SSL_CTX *ctx, char *file)
  1.1567 +	{
  1.1568 +	FILE *in;
  1.1569 +	X509 *x=NULL;
  1.1570 +
  1.1571 +	if ((in=fopen(file,"r")) == NULL)
  1.1572 +		return(0);
  1.1573 +
  1.1574 +	for (;;)
  1.1575 +		{
  1.1576 +		if (PEM_read_X509(in,&x,NULL) == NULL)
  1.1577 +			break;
  1.1578 +		SSL_CTX_add_client_CA(ctx,x);
  1.1579 +		}
  1.1580 +	if (x != NULL) X509_free(x);
  1.1581 +	fclose(in);
  1.1582 +	return(1);
  1.1583 +	}
  1.1584 +#endif
  1.1585 +
  1.1586 +static int www_body(char *hostname, int s, unsigned char *context)
  1.1587 +	{
  1.1588 +	char *buf=NULL;
  1.1589 +	int ret=1;
  1.1590 +	int i,j,k,blank,dot;
  1.1591 +	struct stat st_buf;
  1.1592 +	SSL *con;
  1.1593 +	SSL_CIPHER *c;
  1.1594 +	BIO *io,*ssl_bio,*sbio;
  1.1595 +	long total_bytes;
  1.1596 +
  1.1597 +	buf=OPENSSL_malloc(bufsize);
  1.1598 +	if (buf == NULL) return(0);
  1.1599 +	io=BIO_new(BIO_f_buffer());
  1.1600 +	ssl_bio=BIO_new(BIO_f_ssl());
  1.1601 +	if ((io == NULL) || (ssl_bio == NULL)) goto err;
  1.1602 +
  1.1603 +#ifdef FIONBIO	
  1.1604 +	if (s_nbio)
  1.1605 +		{
  1.1606 +		unsigned long sl=1;
  1.1607 +
  1.1608 +		if (!s_quiet)
  1.1609 +			BIO_printf(bio_err,"turning on non blocking io\n");
  1.1610 +		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
  1.1611 +			ERR_print_errors(bio_err);
  1.1612 +		}
  1.1613 +#endif
  1.1614 +
  1.1615 +	/* lets make the output buffer a reasonable size */
  1.1616 +	if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
  1.1617 +
  1.1618 +	if ((con=SSL_new(ctx)) == NULL) goto err;
  1.1619 +#ifndef OPENSSL_NO_KRB5
  1.1620 +	if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
  1.1621 +		{
  1.1622 +		kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
  1.1623 +		kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
  1.1624 +		}
  1.1625 +#endif	/* OPENSSL_NO_KRB5 */
  1.1626 +	if(context) SSL_set_session_id_context(con, context,
  1.1627 +					       strlen((char *)context));
  1.1628 +
  1.1629 +	sbio=BIO_new_socket(s,BIO_NOCLOSE);
  1.1630 +	if (s_nbio_test)
  1.1631 +		{
  1.1632 +		BIO *test;
  1.1633 +
  1.1634 +		test=BIO_new(BIO_f_nbio_test());
  1.1635 +		sbio=BIO_push(test,sbio);
  1.1636 +		}
  1.1637 +	SSL_set_bio(con,sbio,sbio);
  1.1638 +	SSL_set_accept_state(con);
  1.1639 +
  1.1640 +	/* SSL_set_fd(con,s); */
  1.1641 +	BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
  1.1642 +	BIO_push(io,ssl_bio);
  1.1643 +#ifdef CHARSET_EBCDIC
  1.1644 +	io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
  1.1645 +#endif
  1.1646 +
  1.1647 +	if (s_debug)
  1.1648 +		{
  1.1649 +		con->debug=1;
  1.1650 +		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
  1.1651 +		BIO_set_callback_arg(SSL_get_rbio(con),(char*)bio_s_out);
  1.1652 +		}
  1.1653 +	if (s_msg)
  1.1654 +		{
  1.1655 +		SSL_set_msg_callback(con, msg_cb);
  1.1656 +		SSL_set_msg_callback_arg(con, bio_s_out);
  1.1657 +		}
  1.1658 +
  1.1659 +	blank=0;
  1.1660 +	for (;;)
  1.1661 +		{
  1.1662 +		if (hack)
  1.1663 +			{
  1.1664 +			i=SSL_accept(con);
  1.1665 +
  1.1666 +			switch (SSL_get_error(con,i))
  1.1667 +				{
  1.1668 +			case SSL_ERROR_NONE:
  1.1669 +				break;
  1.1670 +			case SSL_ERROR_WANT_WRITE:
  1.1671 +			case SSL_ERROR_WANT_READ:
  1.1672 +			case SSL_ERROR_WANT_X509_LOOKUP:
  1.1673 +				continue;
  1.1674 +			case SSL_ERROR_SYSCALL:
  1.1675 +			case SSL_ERROR_SSL:
  1.1676 +			case SSL_ERROR_ZERO_RETURN:
  1.1677 +				ret=1;
  1.1678 +				goto err;
  1.1679 +				/* break; */
  1.1680 +				}
  1.1681 +
  1.1682 +			SSL_renegotiate(con);
  1.1683 +			SSL_write(con,NULL,0);
  1.1684 +			}
  1.1685 +
  1.1686 +		i=BIO_gets(io,buf,bufsize-1);
  1.1687 +		if (i < 0) /* error */
  1.1688 +			{
  1.1689 +			if (!BIO_should_retry(io))
  1.1690 +				{
  1.1691 +				if (!s_quiet)
  1.1692 +					ERR_print_errors(bio_err);
  1.1693 +				goto err;
  1.1694 +				}
  1.1695 +			else
  1.1696 +				{
  1.1697 +				BIO_printf(bio_s_out,"read R BLOCK\n");
  1.1698 +#if defined(OPENSSL_SYS_NETWARE)
  1.1699 +            delay(1000);
  1.1700 +#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
  1.1701 +				sleep(1);
  1.1702 +#endif
  1.1703 +				continue;
  1.1704 +				}
  1.1705 +			}
  1.1706 +		else if (i == 0) /* end of input */
  1.1707 +			{
  1.1708 +			ret=1;
  1.1709 +			goto end;
  1.1710 +			}
  1.1711 +
  1.1712 +		/* else we have data */
  1.1713 +		if (	((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
  1.1714 +			((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
  1.1715 +			{
  1.1716 +			char *p;
  1.1717 +			X509 *peer;
  1.1718 +			STACK_OF(SSL_CIPHER) *sk;
  1.1719 +			static const char *space="                          ";
  1.1720 +
  1.1721 +			BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
  1.1722 +			BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
  1.1723 +			BIO_puts(io,"<pre>\n");
  1.1724 +/*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
  1.1725 +			BIO_puts(io,"\n");
  1.1726 +			for (i=0; i<local_argc; i++)
  1.1727 +				{
  1.1728 +				BIO_puts(io,local_argv[i]);
  1.1729 +				BIO_write(io," ",1);
  1.1730 +				}
  1.1731 +			BIO_puts(io,"\n");
  1.1732 +
  1.1733 +			/* The following is evil and should not really
  1.1734 +			 * be done */
  1.1735 +			BIO_printf(io,"Ciphers supported in s_server binary\n");
  1.1736 +			sk=SSL_get_ciphers(con);
  1.1737 +			j=sk_SSL_CIPHER_num(sk);
  1.1738 +			for (i=0; i<j; i++)
  1.1739 +				{
  1.1740 +				c=sk_SSL_CIPHER_value(sk,i);
  1.1741 +				BIO_printf(io,"%-11s:%-25s",
  1.1742 +					SSL_CIPHER_get_version(c),
  1.1743 +					SSL_CIPHER_get_name(c));
  1.1744 +				if ((((i+1)%2) == 0) && (i+1 != j))
  1.1745 +					BIO_puts(io,"\n");
  1.1746 +				}
  1.1747 +			BIO_puts(io,"\n");
  1.1748 +			p=SSL_get_shared_ciphers(con,buf,bufsize);
  1.1749 +			if (p != NULL)
  1.1750 +				{
  1.1751 +				BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
  1.1752 +				j=i=0;
  1.1753 +				while (*p)
  1.1754 +					{
  1.1755 +					if (*p == ':')
  1.1756 +						{
  1.1757 +						BIO_write(io,space,26-j);
  1.1758 +						i++;
  1.1759 +						j=0;
  1.1760 +						BIO_write(io,((i%3)?" ":"\n"),1);
  1.1761 +						}
  1.1762 +					else
  1.1763 +						{
  1.1764 +						BIO_write(io,p,1);
  1.1765 +						j++;
  1.1766 +						}
  1.1767 +					p++;
  1.1768 +					}
  1.1769 +				BIO_puts(io,"\n");
  1.1770 +				}
  1.1771 +			BIO_printf(io,((con->hit)
  1.1772 +				?"---\nReused, "
  1.1773 +				:"---\nNew, "));
  1.1774 +			c=SSL_get_current_cipher(con);
  1.1775 +			BIO_printf(io,"%s, Cipher is %s\n",
  1.1776 +				SSL_CIPHER_get_version(c),
  1.1777 +				SSL_CIPHER_get_name(c));
  1.1778 +			SSL_SESSION_print(io,SSL_get_session(con));
  1.1779 +			BIO_printf(io,"---\n");
  1.1780 +			print_stats(io,SSL_get_SSL_CTX(con));
  1.1781 +			BIO_printf(io,"---\n");
  1.1782 +			peer=SSL_get_peer_certificate(con);
  1.1783 +			if (peer != NULL)
  1.1784 +				{
  1.1785 +				BIO_printf(io,"Client certificate\n");
  1.1786 +				X509_print(io,peer);
  1.1787 +				PEM_write_bio_X509(io,peer);
  1.1788 +				}
  1.1789 +			else
  1.1790 +				BIO_puts(io,"no client certificate available\n");
  1.1791 +			BIO_puts(io,"</BODY></HTML>\r\n\r\n");
  1.1792 +			break;
  1.1793 +			}
  1.1794 +		else if ((www == 2 || www == 3)
  1.1795 +                         && (strncmp("GET /",buf,5) == 0))
  1.1796 +			{
  1.1797 +			BIO *file;
  1.1798 +			char *p,*e;
  1.1799 +			static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
  1.1800 +
  1.1801 +			/* skip the '/' */
  1.1802 +			p= &(buf[5]);
  1.1803 +
  1.1804 +			dot = 1;
  1.1805 +			for (e=p; *e != '\0'; e++)
  1.1806 +				{
  1.1807 +				if (e[0] == ' ')
  1.1808 +					break;
  1.1809 +
  1.1810 +				switch (dot)
  1.1811 +					{
  1.1812 +				case 1:
  1.1813 +					dot = (e[0] == '.') ? 2 : 0;
  1.1814 +					break;
  1.1815 +				case 2:
  1.1816 +					dot = (e[0] == '.') ? 3 : 0;
  1.1817 +					break;
  1.1818 +				case 3:
  1.1819 +					dot = (e[0] == '/') ? -1 : 0;
  1.1820 +					break;
  1.1821 +					}
  1.1822 +				if (dot == 0)
  1.1823 +					dot = (e[0] == '/') ? 1 : 0;
  1.1824 +				}
  1.1825 +			dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
  1.1826 +
  1.1827 +			if (*e == '\0')
  1.1828 +				{
  1.1829 +				BIO_puts(io,text);
  1.1830 +				BIO_printf(io,"'%s' is an invalid file name\r\n",p);
  1.1831 +				break;
  1.1832 +				}
  1.1833 +			*e='\0';
  1.1834 +
  1.1835 +			if (dot)
  1.1836 +				{
  1.1837 +				BIO_puts(io,text);
  1.1838 +				BIO_printf(io,"'%s' contains '..' reference\r\n",p);
  1.1839 +				break;
  1.1840 +				}
  1.1841 +
  1.1842 +			if (*p == '/')
  1.1843 +				{
  1.1844 +				BIO_puts(io,text);
  1.1845 +				BIO_printf(io,"'%s' is an invalid path\r\n",p);
  1.1846 +				break;
  1.1847 +				}
  1.1848 +
  1.1849 +#if 0
  1.1850 +			/* append if a directory lookup */
  1.1851 +			if (e[-1] == '/')
  1.1852 +				strcat(p,"index.html");
  1.1853 +#endif
  1.1854 +
  1.1855 +			/* if a directory, do the index thang */
  1.1856 +			if (stat(p,&st_buf) < 0)
  1.1857 +				{
  1.1858 +				BIO_puts(io,text);
  1.1859 +				BIO_printf(io,"Error accessing '%s'\r\n",p);
  1.1860 +				ERR_print_errors(io);
  1.1861 +				break;
  1.1862 +				}
  1.1863 +			if (S_ISDIR(st_buf.st_mode))
  1.1864 +				{
  1.1865 +#if 0 /* must check buffer size */
  1.1866 +				strcat(p,"/index.html");
  1.1867 +#else
  1.1868 +				BIO_puts(io,text);
  1.1869 +				BIO_printf(io,"'%s' is a directory\r\n",p);
  1.1870 +				break;
  1.1871 +#endif
  1.1872 +				}
  1.1873 +
  1.1874 +			if ((file=BIO_new_file(p,"r")) == NULL)
  1.1875 +				{
  1.1876 +				BIO_puts(io,text);
  1.1877 +				BIO_printf(io,"Error opening '%s'\r\n",p);
  1.1878 +				ERR_print_errors(io);
  1.1879 +				break;
  1.1880 +				}
  1.1881 +
  1.1882 +			if (!s_quiet)
  1.1883 +				BIO_printf(bio_err,"FILE:%s\n",p);
  1.1884 +
  1.1885 +                        if (www == 2)
  1.1886 +                                {
  1.1887 +                                i=strlen(p);
  1.1888 +                                if (	((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
  1.1889 +                                        ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
  1.1890 +                                        ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
  1.1891 +                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
  1.1892 +                                else
  1.1893 +                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
  1.1894 +                                }
  1.1895 +			/* send the file */
  1.1896 +			total_bytes=0;
  1.1897 +			for (;;)
  1.1898 +				{
  1.1899 +				i=BIO_read(file,buf,bufsize);
  1.1900 +				if (i <= 0) break;
  1.1901 +
  1.1902 +#ifdef RENEG
  1.1903 +				total_bytes+=i;
  1.1904 +				fprintf(stderr,"%d\n",i);
  1.1905 +				if (total_bytes > 3*1024)
  1.1906 +					{
  1.1907 +					total_bytes=0;
  1.1908 +					fprintf(stderr,"RENEGOTIATE\n");
  1.1909 +					SSL_renegotiate(con);
  1.1910 +					}
  1.1911 +		
  1.1912 +#endif
  1.1913 +
  1.1914 +				for (j=0; j<i; )
  1.1915 +					{
  1.1916 +#ifdef RENEG
  1.1917 +{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }
  1.1918 +#endif
  1.1919 +					k=BIO_write(io,&(buf[j]),i-j);
  1.1920 +					if (k <= 0)
  1.1921 +						{
  1.1922 +						if (!BIO_should_retry(io))
  1.1923 +							goto write_error;
  1.1924 +						else
  1.1925 +							{
  1.1926 +							BIO_printf(bio_s_out,"rwrite W BLOCK\n");
  1.1927 +							}
  1.1928 +						}
  1.1929 +					else
  1.1930 +						{
  1.1931 +						j+=k;
  1.1932 +						}
  1.1933 +					}
  1.1934 +				}
  1.1935 +write_error:
  1.1936 +			BIO_free(file);
  1.1937 +			break;
  1.1938 +			}
  1.1939 +		}
  1.1940 +
  1.1941 +	for (;;)
  1.1942 +		{
  1.1943 +		i=(int)BIO_flush(io);
  1.1944 +		if (i <= 0)
  1.1945 +			{
  1.1946 +			if (!BIO_should_retry(io))
  1.1947 +				break;
  1.1948 +			}
  1.1949 +		else
  1.1950 +			break;
  1.1951 +		}
  1.1952 +end:
  1.1953 +#if 1
  1.1954 +	/* make sure we re-use sessions */
  1.1955 +	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
  1.1956 +#else
  1.1957 +	/* This kills performance */
  1.1958 +/*	SSL_shutdown(con); A shutdown gets sent in the
  1.1959 + *	BIO_free_all(io) procession */
  1.1960 +#endif
  1.1961 +
  1.1962 +err:
  1.1963 +
  1.1964 +	if (ret >= 0)
  1.1965 +		BIO_printf(bio_s_out,"ACCEPT\n");
  1.1966 +
  1.1967 +	if (buf != NULL) OPENSSL_free(buf);
  1.1968 +	if (io != NULL) BIO_free_all(io);
  1.1969 +/*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/
  1.1970 +	return(ret);
  1.1971 +	}
  1.1972 +
  1.1973 +#ifndef OPENSSL_NO_RSA
  1.1974 +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
  1.1975 +	{
  1.1976 +	BIGNUM *bn = NULL;
  1.1977 +	static RSA *rsa_tmp=NULL;
  1.1978 +
  1.1979 +	if (!rsa_tmp && ((bn = BN_new()) == NULL))
  1.1980 +		BIO_printf(bio_err,"Allocation error in generating RSA key\n");
  1.1981 +	if (!rsa_tmp && bn)
  1.1982 +		{
  1.1983 +		if (!s_quiet)
  1.1984 +			{
  1.1985 +			BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
  1.1986 +			(void)BIO_flush(bio_err);
  1.1987 +			}
  1.1988 +		if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
  1.1989 +				!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
  1.1990 +			{
  1.1991 +			if(rsa_tmp) RSA_free(rsa_tmp);
  1.1992 +			rsa_tmp = NULL;
  1.1993 +			}
  1.1994 +		if (!s_quiet)
  1.1995 +			{
  1.1996 +			BIO_printf(bio_err,"\n");
  1.1997 +			(void)BIO_flush(bio_err);
  1.1998 +			}
  1.1999 +		BN_free(bn);
  1.2000 +		}
  1.2001 +	return(rsa_tmp);
  1.2002 +	}
  1.2003 +#endif
  1.2004 +
  1.2005 +#define MAX_SESSION_ID_ATTEMPTS 10
  1.2006 +static int generate_session_id(const SSL *ssl, unsigned char *id,
  1.2007 +				unsigned int *id_len)
  1.2008 +	{
  1.2009 +	unsigned int count = 0;
  1.2010 +	do	{
  1.2011 +		RAND_pseudo_bytes(id, *id_len);
  1.2012 +		/* Prefix the session_id with the required prefix. NB: If our
  1.2013 +		 * prefix is too long, clip it - but there will be worse effects
  1.2014 +		 * anyway, eg. the server could only possibly create 1 session
  1.2015 +		 * ID (ie. the prefix!) so all future session negotiations will
  1.2016 +		 * fail due to conflicts. */
  1.2017 +		memcpy(id, session_id_prefix,
  1.2018 +			(strlen(session_id_prefix) < *id_len) ?
  1.2019 +			strlen(session_id_prefix) : *id_len);
  1.2020 +		}
  1.2021 +	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
  1.2022 +		(++count < MAX_SESSION_ID_ATTEMPTS));
  1.2023 +	if(count >= MAX_SESSION_ID_ATTEMPTS)
  1.2024 +		return 0;
  1.2025 +	return 1;
  1.2026 +	}