10Sstevel@tonic-gate /* apps/s_server.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate /* ====================================================================
590Sstevel@tonic-gate * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
600Sstevel@tonic-gate *
610Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
620Sstevel@tonic-gate * modification, are permitted provided that the following conditions
630Sstevel@tonic-gate * are met:
640Sstevel@tonic-gate *
650Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
660Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
670Sstevel@tonic-gate *
680Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
690Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
700Sstevel@tonic-gate * the documentation and/or other materials provided with the
710Sstevel@tonic-gate * distribution.
720Sstevel@tonic-gate *
730Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
740Sstevel@tonic-gate * software must display the following acknowledgment:
750Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
760Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
770Sstevel@tonic-gate *
780Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
790Sstevel@tonic-gate * endorse or promote products derived from this software without
800Sstevel@tonic-gate * prior written permission. For written permission, please contact
810Sstevel@tonic-gate * openssl-core@openssl.org.
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
840Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
850Sstevel@tonic-gate * permission of the OpenSSL Project.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
880Sstevel@tonic-gate * acknowledgment:
890Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
900Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
910Sstevel@tonic-gate *
920Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
930Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
940Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
950Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
960Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
970Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
980Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
990Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1000Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1010Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1020Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1030Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
1040Sstevel@tonic-gate * ====================================================================
1050Sstevel@tonic-gate *
1060Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
1070Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
1080Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
1090Sstevel@tonic-gate *
1100Sstevel@tonic-gate */
111*2139Sjp161948 /* ====================================================================
112*2139Sjp161948 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113*2139Sjp161948 * ECC cipher suite support in OpenSSL originally developed by
114*2139Sjp161948 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115*2139Sjp161948 */
116*2139Sjp161948
117*2139Sjp161948 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
118*2139Sjp161948 * deprecated functions for openssl-internal code */
119*2139Sjp161948 #ifdef OPENSSL_NO_DEPRECATED
120*2139Sjp161948 #undef OPENSSL_NO_DEPRECATED
121*2139Sjp161948 #endif
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate #include <assert.h>
1240Sstevel@tonic-gate #include <stdio.h>
1250Sstevel@tonic-gate #include <stdlib.h>
1260Sstevel@tonic-gate #include <string.h>
127*2139Sjp161948
1280Sstevel@tonic-gate #include <sys/stat.h>
1290Sstevel@tonic-gate #include <openssl/e_os2.h>
1300Sstevel@tonic-gate #ifdef OPENSSL_NO_STDIO
1310Sstevel@tonic-gate #define APPS_WIN16
1320Sstevel@tonic-gate #endif
1330Sstevel@tonic-gate
134*2139Sjp161948 #if !defined(OPENSSL_SYS_NETWARE) /* conflicts with winsock2 stuff on netware */
135*2139Sjp161948 #include <sys/types.h>
136*2139Sjp161948 #endif
137*2139Sjp161948
1380Sstevel@tonic-gate /* With IPv6, it looks like Digital has mixed up the proper order of
1390Sstevel@tonic-gate recursive header file inclusion, resulting in the compiler complaining
1400Sstevel@tonic-gate that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
1410Sstevel@tonic-gate is needed to have fileno() declared correctly... So let's define u_int */
1420Sstevel@tonic-gate #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
1430Sstevel@tonic-gate #define __U_INT
1440Sstevel@tonic-gate typedef unsigned int u_int;
1450Sstevel@tonic-gate #endif
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate #include <openssl/lhash.h>
1480Sstevel@tonic-gate #include <openssl/bn.h>
1490Sstevel@tonic-gate #define USE_SOCKETS
1500Sstevel@tonic-gate #include "apps.h"
1510Sstevel@tonic-gate #include <openssl/err.h>
1520Sstevel@tonic-gate #include <openssl/pem.h>
1530Sstevel@tonic-gate #include <openssl/x509.h>
1540Sstevel@tonic-gate #include <openssl/ssl.h>
1550Sstevel@tonic-gate #include <openssl/rand.h>
156*2139Sjp161948 #ifndef OPENSSL_NO_DH
157*2139Sjp161948 #include <openssl/dh.h>
158*2139Sjp161948 #endif
159*2139Sjp161948 #ifndef OPENSSL_NO_RSA
160*2139Sjp161948 #include <openssl/rsa.h>
161*2139Sjp161948 #endif
1620Sstevel@tonic-gate #include "s_apps.h"
163*2139Sjp161948 #include "timeouts.h"
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINCE
1660Sstevel@tonic-gate /* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
1670Sstevel@tonic-gate #ifdef fileno
1680Sstevel@tonic-gate #undef fileno
1690Sstevel@tonic-gate #endif
1700Sstevel@tonic-gate #define fileno(a) (int)_fileno(a)
1710Sstevel@tonic-gate #endif
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
1740Sstevel@tonic-gate /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
1750Sstevel@tonic-gate #undef FIONBIO
1760Sstevel@tonic-gate #endif
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
1790Sstevel@tonic-gate static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
1800Sstevel@tonic-gate #endif
1810Sstevel@tonic-gate static int sv_body(char *hostname, int s, unsigned char *context);
1820Sstevel@tonic-gate static int www_body(char *hostname, int s, unsigned char *context);
1830Sstevel@tonic-gate static void close_accept_socket(void );
1840Sstevel@tonic-gate static void sv_usage(void);
1850Sstevel@tonic-gate static int init_ssl_connection(SSL *s);
1860Sstevel@tonic-gate static void print_stats(BIO *bp,SSL_CTX *ctx);
1870Sstevel@tonic-gate static int generate_session_id(const SSL *ssl, unsigned char *id,
1880Sstevel@tonic-gate unsigned int *id_len);
1890Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
190*2139Sjp161948 static DH *load_dh_param(const char *dhfile);
1910Sstevel@tonic-gate static DH *get_dh512(void);
1920Sstevel@tonic-gate #endif
193*2139Sjp161948
1940Sstevel@tonic-gate #ifdef MONOLITH
1950Sstevel@tonic-gate static void s_server_init(void);
1960Sstevel@tonic-gate #endif
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate #ifndef S_ISDIR
1990Sstevel@tonic-gate # if defined(_S_IFMT) && defined(_S_IFDIR)
2000Sstevel@tonic-gate # define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
2010Sstevel@tonic-gate # else
2020Sstevel@tonic-gate # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
2030Sstevel@tonic-gate # endif
2040Sstevel@tonic-gate #endif
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
2070Sstevel@tonic-gate static unsigned char dh512_p[]={
2080Sstevel@tonic-gate 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
2090Sstevel@tonic-gate 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
2100Sstevel@tonic-gate 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
2110Sstevel@tonic-gate 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
2120Sstevel@tonic-gate 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
2130Sstevel@tonic-gate 0x47,0x74,0xE8,0x33,
2140Sstevel@tonic-gate };
2150Sstevel@tonic-gate static unsigned char dh512_g[]={
2160Sstevel@tonic-gate 0x02,
2170Sstevel@tonic-gate };
2180Sstevel@tonic-gate
get_dh512(void)2190Sstevel@tonic-gate static DH *get_dh512(void)
2200Sstevel@tonic-gate {
2210Sstevel@tonic-gate DH *dh=NULL;
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate if ((dh=DH_new()) == NULL) return(NULL);
2240Sstevel@tonic-gate dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
2250Sstevel@tonic-gate dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
2260Sstevel@tonic-gate if ((dh->p == NULL) || (dh->g == NULL))
2270Sstevel@tonic-gate return(NULL);
2280Sstevel@tonic-gate return(dh);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate #endif
2310Sstevel@tonic-gate
232*2139Sjp161948
2330Sstevel@tonic-gate /* static int load_CA(SSL_CTX *ctx, char *file);*/
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate #undef BUFSIZZ
2360Sstevel@tonic-gate #define BUFSIZZ 16*1024
2370Sstevel@tonic-gate static int bufsize=BUFSIZZ;
2380Sstevel@tonic-gate static int accept_socket= -1;
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate #define TEST_CERT "server.pem"
2410Sstevel@tonic-gate #undef PROG
2420Sstevel@tonic-gate #define PROG s_server_main
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate extern int verify_depth;
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate static char *cipher=NULL;
2470Sstevel@tonic-gate static int s_server_verify=SSL_VERIFY_NONE;
2480Sstevel@tonic-gate static int s_server_session_id_context = 1; /* anything will do */
249*2139Sjp161948 static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
2500Sstevel@tonic-gate static char *s_dcert_file=NULL,*s_dkey_file=NULL;
2510Sstevel@tonic-gate #ifdef FIONBIO
2520Sstevel@tonic-gate static int s_nbio=0;
2530Sstevel@tonic-gate #endif
2540Sstevel@tonic-gate static int s_nbio_test=0;
2550Sstevel@tonic-gate int s_crlf=0;
2560Sstevel@tonic-gate static SSL_CTX *ctx=NULL;
2570Sstevel@tonic-gate static int www=0;
2580Sstevel@tonic-gate
2590Sstevel@tonic-gate static BIO *bio_s_out=NULL;
2600Sstevel@tonic-gate static int s_debug=0;
2610Sstevel@tonic-gate static int s_msg=0;
2620Sstevel@tonic-gate static int s_quiet=0;
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate static int hack=0;
2650Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2660Sstevel@tonic-gate static char *engine_id=NULL;
2670Sstevel@tonic-gate #endif
2680Sstevel@tonic-gate static const char *session_id_prefix=NULL;
2690Sstevel@tonic-gate
270*2139Sjp161948 static int enable_timeouts = 0;
271*2139Sjp161948 #ifdef mtu
272*2139Sjp161948 #undef mtu
273*2139Sjp161948 #endif
274*2139Sjp161948 static long mtu;
275*2139Sjp161948 static int cert_chain = 0;
276*2139Sjp161948
277*2139Sjp161948
2780Sstevel@tonic-gate #ifdef MONOLITH
s_server_init(void)2790Sstevel@tonic-gate static void s_server_init(void)
2800Sstevel@tonic-gate {
2810Sstevel@tonic-gate accept_socket=-1;
2820Sstevel@tonic-gate cipher=NULL;
2830Sstevel@tonic-gate s_server_verify=SSL_VERIFY_NONE;
2840Sstevel@tonic-gate s_dcert_file=NULL;
2850Sstevel@tonic-gate s_dkey_file=NULL;
2860Sstevel@tonic-gate s_cert_file=TEST_CERT;
2870Sstevel@tonic-gate s_key_file=NULL;
2880Sstevel@tonic-gate #ifdef FIONBIO
2890Sstevel@tonic-gate s_nbio=0;
2900Sstevel@tonic-gate #endif
2910Sstevel@tonic-gate s_nbio_test=0;
2920Sstevel@tonic-gate ctx=NULL;
2930Sstevel@tonic-gate www=0;
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate bio_s_out=NULL;
2960Sstevel@tonic-gate s_debug=0;
2970Sstevel@tonic-gate s_msg=0;
2980Sstevel@tonic-gate s_quiet=0;
2990Sstevel@tonic-gate hack=0;
3000Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
3010Sstevel@tonic-gate engine_id=NULL;
3020Sstevel@tonic-gate #endif
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate #endif
3050Sstevel@tonic-gate
sv_usage(void)3060Sstevel@tonic-gate static void sv_usage(void)
3070Sstevel@tonic-gate {
3080Sstevel@tonic-gate BIO_printf(bio_err,"usage: s_server [args ...]\n");
3090Sstevel@tonic-gate BIO_printf(bio_err,"\n");
3100Sstevel@tonic-gate BIO_printf(bio_err," -accept arg - port to accept on (default is %d)\n",PORT);
3110Sstevel@tonic-gate BIO_printf(bio_err," -context arg - set session ID context\n");
3120Sstevel@tonic-gate BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n");
3130Sstevel@tonic-gate BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
314*2139Sjp161948 BIO_printf(bio_err," -cert arg - certificate file to use\n");
3150Sstevel@tonic-gate BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
316*2139Sjp161948 BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
317*2139Sjp161948 BIO_printf(bio_err," -key arg - Private Key file to use, in cert file if\n");
3180Sstevel@tonic-gate BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT);
319*2139Sjp161948 BIO_printf(bio_err," -keyform arg - key format (PEM, DER or ENGINE) PEM default\n");
320*2139Sjp161948 BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
3210Sstevel@tonic-gate BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n");
322*2139Sjp161948 BIO_printf(bio_err," -dcertform x - second certificate format (PEM or DER) PEM default\n");
3230Sstevel@tonic-gate BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n");
324*2139Sjp161948 BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
325*2139Sjp161948 BIO_printf(bio_err," -dpass arg - second private key file pass phrase source\n");
3260Sstevel@tonic-gate BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n");
3270Sstevel@tonic-gate BIO_printf(bio_err," or a default set of parameters is used\n");
328*2139Sjp161948 #ifndef OPENSSL_NO_ECDH
329*2139Sjp161948 BIO_printf(bio_err," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \
330*2139Sjp161948 " Use \"openssl ecparam -list_curves\" for all names\n" \
331*2139Sjp161948 " (default is sect163r2).\n");
332*2139Sjp161948 #endif
3330Sstevel@tonic-gate #ifdef FIONBIO
3340Sstevel@tonic-gate BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
3350Sstevel@tonic-gate #endif
3360Sstevel@tonic-gate BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n");
3370Sstevel@tonic-gate BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
3380Sstevel@tonic-gate BIO_printf(bio_err," -debug - Print more output\n");
3390Sstevel@tonic-gate BIO_printf(bio_err," -msg - Show protocol messages\n");
3400Sstevel@tonic-gate BIO_printf(bio_err," -state - Print the SSL states\n");
3410Sstevel@tonic-gate BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
3420Sstevel@tonic-gate BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
3430Sstevel@tonic-gate BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n");
3440Sstevel@tonic-gate BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n");
3450Sstevel@tonic-gate BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n");
3460Sstevel@tonic-gate BIO_printf(bio_err," -quiet - No server output\n");
3470Sstevel@tonic-gate BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n");
3480Sstevel@tonic-gate BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
3490Sstevel@tonic-gate BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
3500Sstevel@tonic-gate BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
351*2139Sjp161948 BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n");
352*2139Sjp161948 BIO_printf(bio_err," -timeout - Enable timeouts\n");
353*2139Sjp161948 BIO_printf(bio_err," -mtu - Set MTU\n");
354*2139Sjp161948 BIO_printf(bio_err," -chain - Read a certificate chain\n");
3550Sstevel@tonic-gate BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n");
3560Sstevel@tonic-gate BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
3570Sstevel@tonic-gate BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
3580Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
3590Sstevel@tonic-gate BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n");
3600Sstevel@tonic-gate #endif
361*2139Sjp161948 #ifndef OPENSSL_NO_ECDH
362*2139Sjp161948 BIO_printf(bio_err," -no_ecdhe - Disable ephemeral ECDH\n");
363*2139Sjp161948 #endif
3640Sstevel@tonic-gate BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n");
3650Sstevel@tonic-gate BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n");
3660Sstevel@tonic-gate BIO_printf(bio_err," -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
3670Sstevel@tonic-gate BIO_printf(bio_err," -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
3680Sstevel@tonic-gate BIO_printf(bio_err," with the assumption it contains a complete HTTP response.\n");
3690Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
3700Sstevel@tonic-gate BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
3710Sstevel@tonic-gate #endif
3720Sstevel@tonic-gate BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
3730Sstevel@tonic-gate BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate static int local_argc=0;
3770Sstevel@tonic-gate static char **local_argv;
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
3800Sstevel@tonic-gate static int ebcdic_new(BIO *bi);
3810Sstevel@tonic-gate static int ebcdic_free(BIO *a);
3820Sstevel@tonic-gate static int ebcdic_read(BIO *b, char *out, int outl);
3830Sstevel@tonic-gate static int ebcdic_write(BIO *b, const char *in, int inl);
3840Sstevel@tonic-gate static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
3850Sstevel@tonic-gate static int ebcdic_gets(BIO *bp, char *buf, int size);
3860Sstevel@tonic-gate static int ebcdic_puts(BIO *bp, const char *str);
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate #define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
3890Sstevel@tonic-gate static BIO_METHOD methods_ebcdic=
3900Sstevel@tonic-gate {
3910Sstevel@tonic-gate BIO_TYPE_EBCDIC_FILTER,
3920Sstevel@tonic-gate "EBCDIC/ASCII filter",
3930Sstevel@tonic-gate ebcdic_write,
3940Sstevel@tonic-gate ebcdic_read,
3950Sstevel@tonic-gate ebcdic_puts,
3960Sstevel@tonic-gate ebcdic_gets,
3970Sstevel@tonic-gate ebcdic_ctrl,
3980Sstevel@tonic-gate ebcdic_new,
3990Sstevel@tonic-gate ebcdic_free,
4000Sstevel@tonic-gate };
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate typedef struct
4030Sstevel@tonic-gate {
4040Sstevel@tonic-gate size_t alloced;
4050Sstevel@tonic-gate char buff[1];
4060Sstevel@tonic-gate } EBCDIC_OUTBUFF;
4070Sstevel@tonic-gate
BIO_f_ebcdic_filter()4080Sstevel@tonic-gate BIO_METHOD *BIO_f_ebcdic_filter()
4090Sstevel@tonic-gate {
4100Sstevel@tonic-gate return(&methods_ebcdic);
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate
ebcdic_new(BIO * bi)4130Sstevel@tonic-gate static int ebcdic_new(BIO *bi)
4140Sstevel@tonic-gate {
4150Sstevel@tonic-gate EBCDIC_OUTBUFF *wbuf;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
4180Sstevel@tonic-gate wbuf->alloced = 1024;
4190Sstevel@tonic-gate wbuf->buff[0] = '\0';
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate bi->ptr=(char *)wbuf;
4220Sstevel@tonic-gate bi->init=1;
4230Sstevel@tonic-gate bi->flags=0;
4240Sstevel@tonic-gate return(1);
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate
ebcdic_free(BIO * a)4270Sstevel@tonic-gate static int ebcdic_free(BIO *a)
4280Sstevel@tonic-gate {
4290Sstevel@tonic-gate if (a == NULL) return(0);
4300Sstevel@tonic-gate if (a->ptr != NULL)
4310Sstevel@tonic-gate OPENSSL_free(a->ptr);
4320Sstevel@tonic-gate a->ptr=NULL;
4330Sstevel@tonic-gate a->init=0;
4340Sstevel@tonic-gate a->flags=0;
4350Sstevel@tonic-gate return(1);
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate
ebcdic_read(BIO * b,char * out,int outl)4380Sstevel@tonic-gate static int ebcdic_read(BIO *b, char *out, int outl)
4390Sstevel@tonic-gate {
4400Sstevel@tonic-gate int ret=0;
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate if (out == NULL || outl == 0) return(0);
4430Sstevel@tonic-gate if (b->next_bio == NULL) return(0);
4440Sstevel@tonic-gate
4450Sstevel@tonic-gate ret=BIO_read(b->next_bio,out,outl);
4460Sstevel@tonic-gate if (ret > 0)
4470Sstevel@tonic-gate ascii2ebcdic(out,out,ret);
4480Sstevel@tonic-gate return(ret);
4490Sstevel@tonic-gate }
4500Sstevel@tonic-gate
ebcdic_write(BIO * b,const char * in,int inl)4510Sstevel@tonic-gate static int ebcdic_write(BIO *b, const char *in, int inl)
4520Sstevel@tonic-gate {
4530Sstevel@tonic-gate EBCDIC_OUTBUFF *wbuf;
4540Sstevel@tonic-gate int ret=0;
4550Sstevel@tonic-gate int num;
4560Sstevel@tonic-gate unsigned char n;
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate if ((in == NULL) || (inl <= 0)) return(0);
4590Sstevel@tonic-gate if (b->next_bio == NULL) return(0);
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate wbuf=(EBCDIC_OUTBUFF *)b->ptr;
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate if (inl > (num = wbuf->alloced))
4640Sstevel@tonic-gate {
4650Sstevel@tonic-gate num = num + num; /* double the size */
4660Sstevel@tonic-gate if (num < inl)
4670Sstevel@tonic-gate num = inl;
4680Sstevel@tonic-gate OPENSSL_free(wbuf);
4690Sstevel@tonic-gate wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate wbuf->alloced = num;
4720Sstevel@tonic-gate wbuf->buff[0] = '\0';
4730Sstevel@tonic-gate
4740Sstevel@tonic-gate b->ptr=(char *)wbuf;
4750Sstevel@tonic-gate }
4760Sstevel@tonic-gate
4770Sstevel@tonic-gate ebcdic2ascii(wbuf->buff, in, inl);
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate ret=BIO_write(b->next_bio, wbuf->buff, inl);
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate return(ret);
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate
ebcdic_ctrl(BIO * b,int cmd,long num,void * ptr)4840Sstevel@tonic-gate static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
4850Sstevel@tonic-gate {
4860Sstevel@tonic-gate long ret;
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate if (b->next_bio == NULL) return(0);
4890Sstevel@tonic-gate switch (cmd)
4900Sstevel@tonic-gate {
4910Sstevel@tonic-gate case BIO_CTRL_DUP:
4920Sstevel@tonic-gate ret=0L;
4930Sstevel@tonic-gate break;
4940Sstevel@tonic-gate default:
4950Sstevel@tonic-gate ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
4960Sstevel@tonic-gate break;
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate return(ret);
4990Sstevel@tonic-gate }
5000Sstevel@tonic-gate
ebcdic_gets(BIO * bp,char * buf,int size)5010Sstevel@tonic-gate static int ebcdic_gets(BIO *bp, char *buf, int size)
5020Sstevel@tonic-gate {
5030Sstevel@tonic-gate int i, ret=0;
5040Sstevel@tonic-gate if (bp->next_bio == NULL) return(0);
5050Sstevel@tonic-gate /* return(BIO_gets(bp->next_bio,buf,size));*/
5060Sstevel@tonic-gate for (i=0; i<size-1; ++i)
5070Sstevel@tonic-gate {
5080Sstevel@tonic-gate ret = ebcdic_read(bp,&buf[i],1);
5090Sstevel@tonic-gate if (ret <= 0)
5100Sstevel@tonic-gate break;
5110Sstevel@tonic-gate else if (buf[i] == '\n')
5120Sstevel@tonic-gate {
5130Sstevel@tonic-gate ++i;
5140Sstevel@tonic-gate break;
5150Sstevel@tonic-gate }
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate if (i < size)
5180Sstevel@tonic-gate buf[i] = '\0';
5190Sstevel@tonic-gate return (ret < 0 && i == 0) ? ret : i;
5200Sstevel@tonic-gate }
5210Sstevel@tonic-gate
ebcdic_puts(BIO * bp,const char * str)5220Sstevel@tonic-gate static int ebcdic_puts(BIO *bp, const char *str)
5230Sstevel@tonic-gate {
5240Sstevel@tonic-gate if (bp->next_bio == NULL) return(0);
5250Sstevel@tonic-gate return ebcdic_write(bp, str, strlen(str));
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate #endif
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate int MAIN(int, char **);
5300Sstevel@tonic-gate
MAIN(int argc,char * argv[])5310Sstevel@tonic-gate int MAIN(int argc, char *argv[])
5320Sstevel@tonic-gate {
5330Sstevel@tonic-gate X509_STORE *store = NULL;
5340Sstevel@tonic-gate int vflags = 0;
5350Sstevel@tonic-gate short port=PORT;
5360Sstevel@tonic-gate char *CApath=NULL,*CAfile=NULL;
537*2139Sjp161948 unsigned char *context = NULL;
5380Sstevel@tonic-gate char *dhfile = NULL;
539*2139Sjp161948 #ifndef OPENSSL_NO_ECDH
540*2139Sjp161948 char *named_curve = NULL;
541*2139Sjp161948 #endif
5420Sstevel@tonic-gate int badop=0,bugs=0;
5430Sstevel@tonic-gate int ret=1;
5440Sstevel@tonic-gate int off=0;
545*2139Sjp161948 int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
5460Sstevel@tonic-gate int state=0;
5470Sstevel@tonic-gate SSL_METHOD *meth=NULL;
548*2139Sjp161948 #ifdef sock_type
549*2139Sjp161948 #undef sock_type
550*2139Sjp161948 #endif
551*2139Sjp161948 int sock_type=SOCK_STREAM;
5520Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
5530Sstevel@tonic-gate ENGINE *e=NULL;
5540Sstevel@tonic-gate #endif
5550Sstevel@tonic-gate char *inrand=NULL;
556*2139Sjp161948 int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
557*2139Sjp161948 char *passarg = NULL, *pass = NULL;
558*2139Sjp161948 char *dpassarg = NULL, *dpass = NULL;
559*2139Sjp161948 int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
560*2139Sjp161948 X509 *s_cert = NULL, *s_dcert = NULL;
561*2139Sjp161948 EVP_PKEY *s_key = NULL, *s_dkey = NULL;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
5640Sstevel@tonic-gate meth=SSLv23_server_method();
5650Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL3)
5660Sstevel@tonic-gate meth=SSLv3_server_method();
5670Sstevel@tonic-gate #elif !defined(OPENSSL_NO_SSL2)
5680Sstevel@tonic-gate meth=SSLv2_server_method();
5690Sstevel@tonic-gate #endif
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate local_argc=argc;
5720Sstevel@tonic-gate local_argv=argv;
5730Sstevel@tonic-gate
5740Sstevel@tonic-gate apps_startup();
5750Sstevel@tonic-gate #ifdef MONOLITH
5760Sstevel@tonic-gate s_server_init();
5770Sstevel@tonic-gate #endif
5780Sstevel@tonic-gate
5790Sstevel@tonic-gate if (bio_err == NULL)
5800Sstevel@tonic-gate bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate if (!load_config(bio_err, NULL))
5830Sstevel@tonic-gate goto end;
5840Sstevel@tonic-gate
5850Sstevel@tonic-gate verify_depth=0;
5860Sstevel@tonic-gate #ifdef FIONBIO
5870Sstevel@tonic-gate s_nbio=0;
5880Sstevel@tonic-gate #endif
5890Sstevel@tonic-gate s_nbio_test=0;
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate argc--;
5920Sstevel@tonic-gate argv++;
5930Sstevel@tonic-gate
5940Sstevel@tonic-gate while (argc >= 1)
5950Sstevel@tonic-gate {
5960Sstevel@tonic-gate if ((strcmp(*argv,"-port") == 0) ||
5970Sstevel@tonic-gate (strcmp(*argv,"-accept") == 0))
5980Sstevel@tonic-gate {
5990Sstevel@tonic-gate if (--argc < 1) goto bad;
6000Sstevel@tonic-gate if (!extract_port(*(++argv),&port))
6010Sstevel@tonic-gate goto bad;
6020Sstevel@tonic-gate }
6030Sstevel@tonic-gate else if (strcmp(*argv,"-verify") == 0)
6040Sstevel@tonic-gate {
6050Sstevel@tonic-gate s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
6060Sstevel@tonic-gate if (--argc < 1) goto bad;
6070Sstevel@tonic-gate verify_depth=atoi(*(++argv));
6080Sstevel@tonic-gate BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
6090Sstevel@tonic-gate }
6100Sstevel@tonic-gate else if (strcmp(*argv,"-Verify") == 0)
6110Sstevel@tonic-gate {
6120Sstevel@tonic-gate s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
6130Sstevel@tonic-gate SSL_VERIFY_CLIENT_ONCE;
6140Sstevel@tonic-gate if (--argc < 1) goto bad;
6150Sstevel@tonic-gate verify_depth=atoi(*(++argv));
6160Sstevel@tonic-gate BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
6170Sstevel@tonic-gate }
6180Sstevel@tonic-gate else if (strcmp(*argv,"-context") == 0)
6190Sstevel@tonic-gate {
6200Sstevel@tonic-gate if (--argc < 1) goto bad;
621*2139Sjp161948 context= (unsigned char *)*(++argv);
6220Sstevel@tonic-gate }
6230Sstevel@tonic-gate else if (strcmp(*argv,"-cert") == 0)
6240Sstevel@tonic-gate {
6250Sstevel@tonic-gate if (--argc < 1) goto bad;
6260Sstevel@tonic-gate s_cert_file= *(++argv);
6270Sstevel@tonic-gate }
628*2139Sjp161948 else if (strcmp(*argv,"-certform") == 0)
629*2139Sjp161948 {
630*2139Sjp161948 if (--argc < 1) goto bad;
631*2139Sjp161948 s_cert_format = str2fmt(*(++argv));
632*2139Sjp161948 }
6330Sstevel@tonic-gate else if (strcmp(*argv,"-key") == 0)
6340Sstevel@tonic-gate {
6350Sstevel@tonic-gate if (--argc < 1) goto bad;
6360Sstevel@tonic-gate s_key_file= *(++argv);
6370Sstevel@tonic-gate }
638*2139Sjp161948 else if (strcmp(*argv,"-keyform") == 0)
639*2139Sjp161948 {
640*2139Sjp161948 if (--argc < 1) goto bad;
641*2139Sjp161948 s_key_format = str2fmt(*(++argv));
642*2139Sjp161948 }
643*2139Sjp161948 else if (strcmp(*argv,"-pass") == 0)
644*2139Sjp161948 {
645*2139Sjp161948 if (--argc < 1) goto bad;
646*2139Sjp161948 passarg = *(++argv);
647*2139Sjp161948 }
6480Sstevel@tonic-gate else if (strcmp(*argv,"-dhparam") == 0)
6490Sstevel@tonic-gate {
6500Sstevel@tonic-gate if (--argc < 1) goto bad;
6510Sstevel@tonic-gate dhfile = *(++argv);
6520Sstevel@tonic-gate }
653*2139Sjp161948 #ifndef OPENSSL_NO_ECDH
654*2139Sjp161948 else if (strcmp(*argv,"-named_curve") == 0)
655*2139Sjp161948 {
656*2139Sjp161948 if (--argc < 1) goto bad;
657*2139Sjp161948 named_curve = *(++argv);
658*2139Sjp161948 }
659*2139Sjp161948 #endif
660*2139Sjp161948 else if (strcmp(*argv,"-dcertform") == 0)
661*2139Sjp161948 {
662*2139Sjp161948 if (--argc < 1) goto bad;
663*2139Sjp161948 s_dcert_format = str2fmt(*(++argv));
664*2139Sjp161948 }
6650Sstevel@tonic-gate else if (strcmp(*argv,"-dcert") == 0)
6660Sstevel@tonic-gate {
6670Sstevel@tonic-gate if (--argc < 1) goto bad;
6680Sstevel@tonic-gate s_dcert_file= *(++argv);
6690Sstevel@tonic-gate }
670*2139Sjp161948 else if (strcmp(*argv,"-dkeyform") == 0)
671*2139Sjp161948 {
672*2139Sjp161948 if (--argc < 1) goto bad;
673*2139Sjp161948 s_dkey_format = str2fmt(*(++argv));
674*2139Sjp161948 }
675*2139Sjp161948 else if (strcmp(*argv,"-dpass") == 0)
676*2139Sjp161948 {
677*2139Sjp161948 if (--argc < 1) goto bad;
678*2139Sjp161948 dpassarg = *(++argv);
679*2139Sjp161948 }
6800Sstevel@tonic-gate else if (strcmp(*argv,"-dkey") == 0)
6810Sstevel@tonic-gate {
6820Sstevel@tonic-gate if (--argc < 1) goto bad;
6830Sstevel@tonic-gate s_dkey_file= *(++argv);
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate else if (strcmp(*argv,"-nocert") == 0)
6860Sstevel@tonic-gate {
6870Sstevel@tonic-gate nocert=1;
6880Sstevel@tonic-gate }
6890Sstevel@tonic-gate else if (strcmp(*argv,"-CApath") == 0)
6900Sstevel@tonic-gate {
6910Sstevel@tonic-gate if (--argc < 1) goto bad;
6920Sstevel@tonic-gate CApath= *(++argv);
6930Sstevel@tonic-gate }
6940Sstevel@tonic-gate else if (strcmp(*argv,"-crl_check") == 0)
6950Sstevel@tonic-gate {
6960Sstevel@tonic-gate vflags |= X509_V_FLAG_CRL_CHECK;
6970Sstevel@tonic-gate }
6980Sstevel@tonic-gate else if (strcmp(*argv,"-crl_check") == 0)
6990Sstevel@tonic-gate {
7000Sstevel@tonic-gate vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
7010Sstevel@tonic-gate }
7020Sstevel@tonic-gate else if (strcmp(*argv,"-serverpref") == 0)
7030Sstevel@tonic-gate { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
7040Sstevel@tonic-gate else if (strcmp(*argv,"-cipher") == 0)
7050Sstevel@tonic-gate {
7060Sstevel@tonic-gate if (--argc < 1) goto bad;
7070Sstevel@tonic-gate cipher= *(++argv);
7080Sstevel@tonic-gate }
7090Sstevel@tonic-gate else if (strcmp(*argv,"-CAfile") == 0)
7100Sstevel@tonic-gate {
7110Sstevel@tonic-gate if (--argc < 1) goto bad;
7120Sstevel@tonic-gate CAfile= *(++argv);
7130Sstevel@tonic-gate }
7140Sstevel@tonic-gate #ifdef FIONBIO
7150Sstevel@tonic-gate else if (strcmp(*argv,"-nbio") == 0)
7160Sstevel@tonic-gate { s_nbio=1; }
7170Sstevel@tonic-gate #endif
7180Sstevel@tonic-gate else if (strcmp(*argv,"-nbio_test") == 0)
7190Sstevel@tonic-gate {
7200Sstevel@tonic-gate #ifdef FIONBIO
7210Sstevel@tonic-gate s_nbio=1;
7220Sstevel@tonic-gate #endif
7230Sstevel@tonic-gate s_nbio_test=1;
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate else if (strcmp(*argv,"-debug") == 0)
7260Sstevel@tonic-gate { s_debug=1; }
7270Sstevel@tonic-gate else if (strcmp(*argv,"-msg") == 0)
7280Sstevel@tonic-gate { s_msg=1; }
7290Sstevel@tonic-gate else if (strcmp(*argv,"-hack") == 0)
7300Sstevel@tonic-gate { hack=1; }
7310Sstevel@tonic-gate else if (strcmp(*argv,"-state") == 0)
7320Sstevel@tonic-gate { state=1; }
7330Sstevel@tonic-gate else if (strcmp(*argv,"-crlf") == 0)
7340Sstevel@tonic-gate { s_crlf=1; }
7350Sstevel@tonic-gate else if (strcmp(*argv,"-quiet") == 0)
7360Sstevel@tonic-gate { s_quiet=1; }
7370Sstevel@tonic-gate else if (strcmp(*argv,"-bugs") == 0)
7380Sstevel@tonic-gate { bugs=1; }
7390Sstevel@tonic-gate else if (strcmp(*argv,"-no_tmp_rsa") == 0)
7400Sstevel@tonic-gate { no_tmp_rsa=1; }
7410Sstevel@tonic-gate else if (strcmp(*argv,"-no_dhe") == 0)
7420Sstevel@tonic-gate { no_dhe=1; }
743*2139Sjp161948 else if (strcmp(*argv,"-no_ecdhe") == 0)
744*2139Sjp161948 { no_ecdhe=1; }
7450Sstevel@tonic-gate else if (strcmp(*argv,"-www") == 0)
7460Sstevel@tonic-gate { www=1; }
7470Sstevel@tonic-gate else if (strcmp(*argv,"-WWW") == 0)
7480Sstevel@tonic-gate { www=2; }
7490Sstevel@tonic-gate else if (strcmp(*argv,"-HTTP") == 0)
7500Sstevel@tonic-gate { www=3; }
7510Sstevel@tonic-gate else if (strcmp(*argv,"-no_ssl2") == 0)
7520Sstevel@tonic-gate { off|=SSL_OP_NO_SSLv2; }
7530Sstevel@tonic-gate else if (strcmp(*argv,"-no_ssl3") == 0)
7540Sstevel@tonic-gate { off|=SSL_OP_NO_SSLv3; }
7550Sstevel@tonic-gate else if (strcmp(*argv,"-no_tls1") == 0)
7560Sstevel@tonic-gate { off|=SSL_OP_NO_TLSv1; }
7570Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL2
7580Sstevel@tonic-gate else if (strcmp(*argv,"-ssl2") == 0)
7590Sstevel@tonic-gate { meth=SSLv2_server_method(); }
7600Sstevel@tonic-gate #endif
7610Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL3
7620Sstevel@tonic-gate else if (strcmp(*argv,"-ssl3") == 0)
7630Sstevel@tonic-gate { meth=SSLv3_server_method(); }
7640Sstevel@tonic-gate #endif
7650Sstevel@tonic-gate #ifndef OPENSSL_NO_TLS1
7660Sstevel@tonic-gate else if (strcmp(*argv,"-tls1") == 0)
7670Sstevel@tonic-gate { meth=TLSv1_server_method(); }
7680Sstevel@tonic-gate #endif
769*2139Sjp161948 #ifndef OPENSSL_NO_DTLS1
770*2139Sjp161948 else if (strcmp(*argv,"-dtls1") == 0)
771*2139Sjp161948 {
772*2139Sjp161948 meth=DTLSv1_server_method();
773*2139Sjp161948 sock_type = SOCK_DGRAM;
774*2139Sjp161948 }
775*2139Sjp161948 else if (strcmp(*argv,"-timeout") == 0)
776*2139Sjp161948 enable_timeouts = 1;
777*2139Sjp161948 else if (strcmp(*argv,"-mtu") == 0)
778*2139Sjp161948 {
779*2139Sjp161948 if (--argc < 1) goto bad;
780*2139Sjp161948 mtu = atol(*(++argv));
781*2139Sjp161948 }
782*2139Sjp161948 else if (strcmp(*argv, "-chain") == 0)
783*2139Sjp161948 cert_chain = 1;
784*2139Sjp161948 #endif
7850Sstevel@tonic-gate else if (strcmp(*argv, "-id_prefix") == 0)
7860Sstevel@tonic-gate {
7870Sstevel@tonic-gate if (--argc < 1) goto bad;
7880Sstevel@tonic-gate session_id_prefix = *(++argv);
7890Sstevel@tonic-gate }
7900Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
7910Sstevel@tonic-gate else if (strcmp(*argv,"-engine") == 0)
7920Sstevel@tonic-gate {
7930Sstevel@tonic-gate if (--argc < 1) goto bad;
7940Sstevel@tonic-gate engine_id= *(++argv);
7950Sstevel@tonic-gate }
7960Sstevel@tonic-gate #endif
7970Sstevel@tonic-gate else if (strcmp(*argv,"-rand") == 0)
7980Sstevel@tonic-gate {
7990Sstevel@tonic-gate if (--argc < 1) goto bad;
8000Sstevel@tonic-gate inrand= *(++argv);
8010Sstevel@tonic-gate }
8020Sstevel@tonic-gate else
8030Sstevel@tonic-gate {
8040Sstevel@tonic-gate BIO_printf(bio_err,"unknown option %s\n",*argv);
8050Sstevel@tonic-gate badop=1;
8060Sstevel@tonic-gate break;
8070Sstevel@tonic-gate }
8080Sstevel@tonic-gate argc--;
8090Sstevel@tonic-gate argv++;
8100Sstevel@tonic-gate }
8110Sstevel@tonic-gate if (badop)
8120Sstevel@tonic-gate {
8130Sstevel@tonic-gate bad:
8140Sstevel@tonic-gate sv_usage();
8150Sstevel@tonic-gate goto end;
8160Sstevel@tonic-gate }
8170Sstevel@tonic-gate
8180Sstevel@tonic-gate SSL_load_error_strings();
8190Sstevel@tonic-gate OpenSSL_add_ssl_algorithms();
8200Sstevel@tonic-gate
8210Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
8220Sstevel@tonic-gate e = setup_engine(bio_err, engine_id, 1);
8230Sstevel@tonic-gate #endif
8240Sstevel@tonic-gate
825*2139Sjp161948 if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
826*2139Sjp161948 {
827*2139Sjp161948 BIO_printf(bio_err, "Error getting password\n");
828*2139Sjp161948 goto end;
829*2139Sjp161948 }
830*2139Sjp161948
831*2139Sjp161948
832*2139Sjp161948 if (s_key_file == NULL)
833*2139Sjp161948 s_key_file = s_cert_file;
834*2139Sjp161948
835*2139Sjp161948 if (nocert == 0)
836*2139Sjp161948 {
837*2139Sjp161948 s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
838*2139Sjp161948 "server certificate private key file");
839*2139Sjp161948 if (!s_key)
840*2139Sjp161948 {
841*2139Sjp161948 ERR_print_errors(bio_err);
842*2139Sjp161948 goto end;
843*2139Sjp161948 }
844*2139Sjp161948
845*2139Sjp161948 s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
846*2139Sjp161948 NULL, e, "server certificate file");
847*2139Sjp161948
848*2139Sjp161948 if (!s_cert)
849*2139Sjp161948 {
850*2139Sjp161948 ERR_print_errors(bio_err);
851*2139Sjp161948 goto end;
852*2139Sjp161948 }
853*2139Sjp161948 }
854*2139Sjp161948
855*2139Sjp161948 if (s_dcert_file)
856*2139Sjp161948 {
857*2139Sjp161948
858*2139Sjp161948 if (s_dkey_file == NULL)
859*2139Sjp161948 s_dkey_file = s_dcert_file;
860*2139Sjp161948
861*2139Sjp161948 s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
862*2139Sjp161948 0, dpass, e,
863*2139Sjp161948 "second certificate private key file");
864*2139Sjp161948 if (!s_dkey)
865*2139Sjp161948 {
866*2139Sjp161948 ERR_print_errors(bio_err);
867*2139Sjp161948 goto end;
868*2139Sjp161948 }
869*2139Sjp161948
870*2139Sjp161948 s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
871*2139Sjp161948 NULL, e, "second server certificate file");
872*2139Sjp161948
873*2139Sjp161948 if (!s_dcert)
874*2139Sjp161948 {
875*2139Sjp161948 ERR_print_errors(bio_err);
876*2139Sjp161948 goto end;
877*2139Sjp161948 }
878*2139Sjp161948
879*2139Sjp161948 }
880*2139Sjp161948
8810Sstevel@tonic-gate if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
8820Sstevel@tonic-gate && !RAND_status())
8830Sstevel@tonic-gate {
8840Sstevel@tonic-gate BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
8850Sstevel@tonic-gate }
8860Sstevel@tonic-gate if (inrand != NULL)
8870Sstevel@tonic-gate BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
8880Sstevel@tonic-gate app_RAND_load_files(inrand));
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate if (bio_s_out == NULL)
8910Sstevel@tonic-gate {
8920Sstevel@tonic-gate if (s_quiet && !s_debug && !s_msg)
8930Sstevel@tonic-gate {
8940Sstevel@tonic-gate bio_s_out=BIO_new(BIO_s_null());
8950Sstevel@tonic-gate }
8960Sstevel@tonic-gate else
8970Sstevel@tonic-gate {
8980Sstevel@tonic-gate if (bio_s_out == NULL)
8990Sstevel@tonic-gate bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
9000Sstevel@tonic-gate }
9010Sstevel@tonic-gate }
9020Sstevel@tonic-gate
903*2139Sjp161948 #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
9040Sstevel@tonic-gate if (nocert)
9050Sstevel@tonic-gate #endif
9060Sstevel@tonic-gate {
9070Sstevel@tonic-gate s_cert_file=NULL;
9080Sstevel@tonic-gate s_key_file=NULL;
9090Sstevel@tonic-gate s_dcert_file=NULL;
9100Sstevel@tonic-gate s_dkey_file=NULL;
9110Sstevel@tonic-gate }
9120Sstevel@tonic-gate
9130Sstevel@tonic-gate ctx=SSL_CTX_new(meth);
9140Sstevel@tonic-gate if (ctx == NULL)
9150Sstevel@tonic-gate {
9160Sstevel@tonic-gate ERR_print_errors(bio_err);
9170Sstevel@tonic-gate goto end;
9180Sstevel@tonic-gate }
9190Sstevel@tonic-gate if (session_id_prefix)
9200Sstevel@tonic-gate {
9210Sstevel@tonic-gate if(strlen(session_id_prefix) >= 32)
9220Sstevel@tonic-gate BIO_printf(bio_err,
9230Sstevel@tonic-gate "warning: id_prefix is too long, only one new session will be possible\n");
9240Sstevel@tonic-gate else if(strlen(session_id_prefix) >= 16)
9250Sstevel@tonic-gate BIO_printf(bio_err,
9260Sstevel@tonic-gate "warning: id_prefix is too long if you use SSLv2\n");
9270Sstevel@tonic-gate if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
9280Sstevel@tonic-gate {
9290Sstevel@tonic-gate BIO_printf(bio_err,"error setting 'id_prefix'\n");
9300Sstevel@tonic-gate ERR_print_errors(bio_err);
9310Sstevel@tonic-gate goto end;
9320Sstevel@tonic-gate }
9330Sstevel@tonic-gate BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
9340Sstevel@tonic-gate }
9350Sstevel@tonic-gate SSL_CTX_set_quiet_shutdown(ctx,1);
9360Sstevel@tonic-gate if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
9370Sstevel@tonic-gate if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
9380Sstevel@tonic-gate SSL_CTX_set_options(ctx,off);
939*2139Sjp161948 /* DTLS: partial reads end up discarding unread UDP bytes :-(
940*2139Sjp161948 * Setting read ahead solves this problem.
941*2139Sjp161948 */
942*2139Sjp161948 if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
9430Sstevel@tonic-gate
9440Sstevel@tonic-gate if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
9450Sstevel@tonic-gate
9460Sstevel@tonic-gate SSL_CTX_sess_set_cache_size(ctx,128);
9470Sstevel@tonic-gate
9480Sstevel@tonic-gate #if 0
9490Sstevel@tonic-gate if (cipher == NULL) cipher=getenv("SSL_CIPHER");
9500Sstevel@tonic-gate #endif
9510Sstevel@tonic-gate
9520Sstevel@tonic-gate #if 0
9530Sstevel@tonic-gate if (s_cert_file == NULL)
9540Sstevel@tonic-gate {
9550Sstevel@tonic-gate BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
9560Sstevel@tonic-gate goto end;
9570Sstevel@tonic-gate }
9580Sstevel@tonic-gate #endif
9590Sstevel@tonic-gate
9600Sstevel@tonic-gate if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
9610Sstevel@tonic-gate (!SSL_CTX_set_default_verify_paths(ctx)))
9620Sstevel@tonic-gate {
9630Sstevel@tonic-gate /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
9640Sstevel@tonic-gate ERR_print_errors(bio_err);
9650Sstevel@tonic-gate /* goto end; */
9660Sstevel@tonic-gate }
9670Sstevel@tonic-gate store = SSL_CTX_get_cert_store(ctx);
9680Sstevel@tonic-gate X509_STORE_set_flags(store, vflags);
9690Sstevel@tonic-gate
9700Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
9710Sstevel@tonic-gate if (!no_dhe)
9720Sstevel@tonic-gate {
9730Sstevel@tonic-gate DH *dh=NULL;
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate if (dhfile)
9760Sstevel@tonic-gate dh = load_dh_param(dhfile);
9770Sstevel@tonic-gate else if (s_cert_file)
9780Sstevel@tonic-gate dh = load_dh_param(s_cert_file);
9790Sstevel@tonic-gate
9800Sstevel@tonic-gate if (dh != NULL)
9810Sstevel@tonic-gate {
9820Sstevel@tonic-gate BIO_printf(bio_s_out,"Setting temp DH parameters\n");
9830Sstevel@tonic-gate }
9840Sstevel@tonic-gate else
9850Sstevel@tonic-gate {
9860Sstevel@tonic-gate BIO_printf(bio_s_out,"Using default temp DH parameters\n");
9870Sstevel@tonic-gate dh=get_dh512();
9880Sstevel@tonic-gate }
9890Sstevel@tonic-gate (void)BIO_flush(bio_s_out);
9900Sstevel@tonic-gate
9910Sstevel@tonic-gate SSL_CTX_set_tmp_dh(ctx,dh);
9920Sstevel@tonic-gate DH_free(dh);
9930Sstevel@tonic-gate }
9940Sstevel@tonic-gate #endif
995*2139Sjp161948
996*2139Sjp161948 #ifndef OPENSSL_NO_ECDH
997*2139Sjp161948 if (!no_ecdhe)
998*2139Sjp161948 {
999*2139Sjp161948 EC_KEY *ecdh=NULL;
1000*2139Sjp161948
1001*2139Sjp161948 if (named_curve)
1002*2139Sjp161948 {
1003*2139Sjp161948 int nid = OBJ_sn2nid(named_curve);
1004*2139Sjp161948
1005*2139Sjp161948 if (nid == 0)
1006*2139Sjp161948 {
1007*2139Sjp161948 BIO_printf(bio_err, "unknown curve name (%s)\n",
1008*2139Sjp161948 named_curve);
1009*2139Sjp161948 goto end;
1010*2139Sjp161948 }
1011*2139Sjp161948 ecdh = EC_KEY_new_by_curve_name(nid);
1012*2139Sjp161948 if (ecdh == NULL)
1013*2139Sjp161948 {
1014*2139Sjp161948 BIO_printf(bio_err, "unable to create curve (%s)\n",
1015*2139Sjp161948 named_curve);
1016*2139Sjp161948 goto end;
1017*2139Sjp161948 }
1018*2139Sjp161948 }
1019*2139Sjp161948
1020*2139Sjp161948 if (ecdh != NULL)
1021*2139Sjp161948 {
1022*2139Sjp161948 BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
1023*2139Sjp161948 }
1024*2139Sjp161948 else
1025*2139Sjp161948 {
1026*2139Sjp161948 BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
1027*2139Sjp161948 ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);
1028*2139Sjp161948 if (ecdh == NULL)
1029*2139Sjp161948 {
1030*2139Sjp161948 BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
1031*2139Sjp161948 goto end;
1032*2139Sjp161948 }
1033*2139Sjp161948 }
1034*2139Sjp161948 (void)BIO_flush(bio_s_out);
1035*2139Sjp161948
1036*2139Sjp161948 SSL_CTX_set_tmp_ecdh(ctx,ecdh);
1037*2139Sjp161948 EC_KEY_free(ecdh);
1038*2139Sjp161948 }
1039*2139Sjp161948 #endif
10400Sstevel@tonic-gate
1041*2139Sjp161948 if (!set_cert_key_stuff(ctx,s_cert,s_key))
10420Sstevel@tonic-gate goto end;
1043*2139Sjp161948 if (s_dcert != NULL)
10440Sstevel@tonic-gate {
1045*2139Sjp161948 if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
10460Sstevel@tonic-gate goto end;
10470Sstevel@tonic-gate }
10480Sstevel@tonic-gate
10490Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
10500Sstevel@tonic-gate #if 1
10510Sstevel@tonic-gate if (!no_tmp_rsa)
10520Sstevel@tonic-gate SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
10530Sstevel@tonic-gate #else
10540Sstevel@tonic-gate if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
10550Sstevel@tonic-gate {
10560Sstevel@tonic-gate RSA *rsa;
10570Sstevel@tonic-gate
10580Sstevel@tonic-gate BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
10590Sstevel@tonic-gate BIO_flush(bio_s_out);
10600Sstevel@tonic-gate
10610Sstevel@tonic-gate rsa=RSA_generate_key(512,RSA_F4,NULL);
10620Sstevel@tonic-gate
10630Sstevel@tonic-gate if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
10640Sstevel@tonic-gate {
10650Sstevel@tonic-gate ERR_print_errors(bio_err);
10660Sstevel@tonic-gate goto end;
10670Sstevel@tonic-gate }
10680Sstevel@tonic-gate RSA_free(rsa);
10690Sstevel@tonic-gate BIO_printf(bio_s_out,"\n");
10700Sstevel@tonic-gate }
10710Sstevel@tonic-gate #endif
10720Sstevel@tonic-gate #endif
10730Sstevel@tonic-gate
10740Sstevel@tonic-gate if (cipher != NULL)
10750Sstevel@tonic-gate if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
10760Sstevel@tonic-gate BIO_printf(bio_err,"error setting cipher list\n");
10770Sstevel@tonic-gate ERR_print_errors(bio_err);
10780Sstevel@tonic-gate goto end;
10790Sstevel@tonic-gate }
10800Sstevel@tonic-gate SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
10810Sstevel@tonic-gate SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
10820Sstevel@tonic-gate sizeof s_server_session_id_context);
10830Sstevel@tonic-gate
10840Sstevel@tonic-gate if (CAfile != NULL)
10850Sstevel@tonic-gate SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate BIO_printf(bio_s_out,"ACCEPT\n");
10880Sstevel@tonic-gate if (www)
1089*2139Sjp161948 do_server(port,sock_type,&accept_socket,www_body, context);
10900Sstevel@tonic-gate else
1091*2139Sjp161948 do_server(port,sock_type,&accept_socket,sv_body, context);
10920Sstevel@tonic-gate print_stats(bio_s_out,ctx);
10930Sstevel@tonic-gate ret=0;
10940Sstevel@tonic-gate end:
10950Sstevel@tonic-gate if (ctx != NULL) SSL_CTX_free(ctx);
1096*2139Sjp161948 if (s_cert)
1097*2139Sjp161948 X509_free(s_cert);
1098*2139Sjp161948 if (s_dcert)
1099*2139Sjp161948 X509_free(s_dcert);
1100*2139Sjp161948 if (s_key)
1101*2139Sjp161948 EVP_PKEY_free(s_key);
1102*2139Sjp161948 if (s_dkey)
1103*2139Sjp161948 EVP_PKEY_free(s_dkey);
1104*2139Sjp161948 if (pass)
1105*2139Sjp161948 OPENSSL_free(pass);
1106*2139Sjp161948 if (dpass)
1107*2139Sjp161948 OPENSSL_free(dpass);
11080Sstevel@tonic-gate if (bio_s_out != NULL)
11090Sstevel@tonic-gate {
1110*2139Sjp161948 BIO_free(bio_s_out);
11110Sstevel@tonic-gate bio_s_out=NULL;
11120Sstevel@tonic-gate }
11130Sstevel@tonic-gate apps_shutdown();
11140Sstevel@tonic-gate OPENSSL_EXIT(ret);
11150Sstevel@tonic-gate }
11160Sstevel@tonic-gate
print_stats(BIO * bio,SSL_CTX * ssl_ctx)11170Sstevel@tonic-gate static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
11180Sstevel@tonic-gate {
11190Sstevel@tonic-gate BIO_printf(bio,"%4ld items in the session cache\n",
11200Sstevel@tonic-gate SSL_CTX_sess_number(ssl_ctx));
1121*2139Sjp161948 BIO_printf(bio,"%4ld client connects (SSL_connect())\n",
11220Sstevel@tonic-gate SSL_CTX_sess_connect(ssl_ctx));
1123*2139Sjp161948 BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
11240Sstevel@tonic-gate SSL_CTX_sess_connect_renegotiate(ssl_ctx));
1125*2139Sjp161948 BIO_printf(bio,"%4ld client connects that finished\n",
11260Sstevel@tonic-gate SSL_CTX_sess_connect_good(ssl_ctx));
1127*2139Sjp161948 BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
11280Sstevel@tonic-gate SSL_CTX_sess_accept(ssl_ctx));
1129*2139Sjp161948 BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
11300Sstevel@tonic-gate SSL_CTX_sess_accept_renegotiate(ssl_ctx));
1131*2139Sjp161948 BIO_printf(bio,"%4ld server accepts that finished\n",
11320Sstevel@tonic-gate SSL_CTX_sess_accept_good(ssl_ctx));
1133*2139Sjp161948 BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
1134*2139Sjp161948 BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
1135*2139Sjp161948 BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
1136*2139Sjp161948 BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
1137*2139Sjp161948 BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",
11380Sstevel@tonic-gate SSL_CTX_sess_cache_full(ssl_ctx),
11390Sstevel@tonic-gate SSL_CTX_sess_get_cache_size(ssl_ctx));
11400Sstevel@tonic-gate }
11410Sstevel@tonic-gate
sv_body(char * hostname,int s,unsigned char * context)11420Sstevel@tonic-gate static int sv_body(char *hostname, int s, unsigned char *context)
11430Sstevel@tonic-gate {
11440Sstevel@tonic-gate char *buf=NULL;
11450Sstevel@tonic-gate fd_set readfds;
11460Sstevel@tonic-gate int ret=1,width;
11470Sstevel@tonic-gate int k,i;
11480Sstevel@tonic-gate unsigned long l;
11490Sstevel@tonic-gate SSL *con=NULL;
11500Sstevel@tonic-gate BIO *sbio;
1151*2139Sjp161948 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
11520Sstevel@tonic-gate struct timeval tv;
11530Sstevel@tonic-gate #endif
11540Sstevel@tonic-gate
11550Sstevel@tonic-gate if ((buf=OPENSSL_malloc(bufsize)) == NULL)
11560Sstevel@tonic-gate {
11570Sstevel@tonic-gate BIO_printf(bio_err,"out of memory\n");
11580Sstevel@tonic-gate goto err;
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate #ifdef FIONBIO
11610Sstevel@tonic-gate if (s_nbio)
11620Sstevel@tonic-gate {
11630Sstevel@tonic-gate unsigned long sl=1;
11640Sstevel@tonic-gate
11650Sstevel@tonic-gate if (!s_quiet)
11660Sstevel@tonic-gate BIO_printf(bio_err,"turning on non blocking io\n");
11670Sstevel@tonic-gate if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
11680Sstevel@tonic-gate ERR_print_errors(bio_err);
11690Sstevel@tonic-gate }
11700Sstevel@tonic-gate #endif
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate if (con == NULL) {
11730Sstevel@tonic-gate con=SSL_new(ctx);
11740Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
11750Sstevel@tonic-gate if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
11760Sstevel@tonic-gate {
11770Sstevel@tonic-gate kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
11780Sstevel@tonic-gate KRB5SVC);
11790Sstevel@tonic-gate kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
11800Sstevel@tonic-gate KRB5KEYTAB);
11810Sstevel@tonic-gate }
11820Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
11830Sstevel@tonic-gate if(context)
11840Sstevel@tonic-gate SSL_set_session_id_context(con, context,
11850Sstevel@tonic-gate strlen((char *)context));
11860Sstevel@tonic-gate }
11870Sstevel@tonic-gate SSL_clear(con);
11880Sstevel@tonic-gate
1189*2139Sjp161948 if (SSL_version(con) == DTLS1_VERSION)
1190*2139Sjp161948 {
1191*2139Sjp161948 struct timeval timeout;
1192*2139Sjp161948
1193*2139Sjp161948 sbio=BIO_new_dgram(s,BIO_NOCLOSE);
1194*2139Sjp161948
1195*2139Sjp161948 if ( enable_timeouts)
1196*2139Sjp161948 {
1197*2139Sjp161948 timeout.tv_sec = 0;
1198*2139Sjp161948 timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1199*2139Sjp161948 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
1200*2139Sjp161948
1201*2139Sjp161948 timeout.tv_sec = 0;
1202*2139Sjp161948 timeout.tv_usec = DGRAM_SND_TIMEOUT;
1203*2139Sjp161948 BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
1204*2139Sjp161948 }
1205*2139Sjp161948
1206*2139Sjp161948
1207*2139Sjp161948 if ( mtu > 0)
1208*2139Sjp161948 {
1209*2139Sjp161948 SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1210*2139Sjp161948 SSL_set_mtu(con, mtu);
1211*2139Sjp161948 }
1212*2139Sjp161948 else
1213*2139Sjp161948 /* want to do MTU discovery */
1214*2139Sjp161948 BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1215*2139Sjp161948
1216*2139Sjp161948 /* turn on cookie exchange */
1217*2139Sjp161948 SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
1218*2139Sjp161948 }
1219*2139Sjp161948 else
1220*2139Sjp161948 sbio=BIO_new_socket(s,BIO_NOCLOSE);
1221*2139Sjp161948
12220Sstevel@tonic-gate if (s_nbio_test)
12230Sstevel@tonic-gate {
12240Sstevel@tonic-gate BIO *test;
12250Sstevel@tonic-gate
12260Sstevel@tonic-gate test=BIO_new(BIO_f_nbio_test());
12270Sstevel@tonic-gate sbio=BIO_push(test,sbio);
12280Sstevel@tonic-gate }
12290Sstevel@tonic-gate SSL_set_bio(con,sbio,sbio);
12300Sstevel@tonic-gate SSL_set_accept_state(con);
12310Sstevel@tonic-gate /* SSL_set_fd(con,s); */
12320Sstevel@tonic-gate
12330Sstevel@tonic-gate if (s_debug)
12340Sstevel@tonic-gate {
12350Sstevel@tonic-gate con->debug=1;
1236*2139Sjp161948 BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
12370Sstevel@tonic-gate BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
12380Sstevel@tonic-gate }
12390Sstevel@tonic-gate if (s_msg)
12400Sstevel@tonic-gate {
12410Sstevel@tonic-gate SSL_set_msg_callback(con, msg_cb);
12420Sstevel@tonic-gate SSL_set_msg_callback_arg(con, bio_s_out);
12430Sstevel@tonic-gate }
12440Sstevel@tonic-gate
12450Sstevel@tonic-gate width=s+1;
12460Sstevel@tonic-gate for (;;)
12470Sstevel@tonic-gate {
12480Sstevel@tonic-gate int read_from_terminal;
12490Sstevel@tonic-gate int read_from_sslcon;
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate read_from_terminal = 0;
12520Sstevel@tonic-gate read_from_sslcon = SSL_pending(con);
12530Sstevel@tonic-gate
12540Sstevel@tonic-gate if (!read_from_sslcon)
12550Sstevel@tonic-gate {
12560Sstevel@tonic-gate FD_ZERO(&readfds);
1257*2139Sjp161948 #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
12580Sstevel@tonic-gate FD_SET(fileno(stdin),&readfds);
12590Sstevel@tonic-gate #endif
12600Sstevel@tonic-gate FD_SET(s,&readfds);
12610Sstevel@tonic-gate /* Note: under VMS with SOCKETSHR the second parameter is
12620Sstevel@tonic-gate * currently of type (int *) whereas under other systems
12630Sstevel@tonic-gate * it is (void *) if you don't have a cast it will choke
12640Sstevel@tonic-gate * the compiler: if you do have a cast then you can either
12650Sstevel@tonic-gate * go for (int *) or (void *).
12660Sstevel@tonic-gate */
1267*2139Sjp161948 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
12680Sstevel@tonic-gate /* Under DOS (non-djgpp) and Windows we can't select on stdin: only
12690Sstevel@tonic-gate * on sockets. As a workaround we timeout the select every
12700Sstevel@tonic-gate * second and check for any keypress. In a proper Windows
12710Sstevel@tonic-gate * application we wouldn't do this because it is inefficient.
12720Sstevel@tonic-gate */
12730Sstevel@tonic-gate tv.tv_sec = 1;
12740Sstevel@tonic-gate tv.tv_usec = 0;
12750Sstevel@tonic-gate i=select(width,(void *)&readfds,NULL,NULL,&tv);
12760Sstevel@tonic-gate if((i < 0) || (!i && !_kbhit() ) )continue;
12770Sstevel@tonic-gate if(_kbhit())
12780Sstevel@tonic-gate read_from_terminal = 1;
12790Sstevel@tonic-gate #else
12800Sstevel@tonic-gate i=select(width,(void *)&readfds,NULL,NULL,NULL);
12810Sstevel@tonic-gate if (i <= 0) continue;
12820Sstevel@tonic-gate if (FD_ISSET(fileno(stdin),&readfds))
12830Sstevel@tonic-gate read_from_terminal = 1;
12840Sstevel@tonic-gate #endif
12850Sstevel@tonic-gate if (FD_ISSET(s,&readfds))
12860Sstevel@tonic-gate read_from_sslcon = 1;
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate if (read_from_terminal)
12890Sstevel@tonic-gate {
12900Sstevel@tonic-gate if (s_crlf)
12910Sstevel@tonic-gate {
12920Sstevel@tonic-gate int j, lf_num;
12930Sstevel@tonic-gate
12940Sstevel@tonic-gate i=read(fileno(stdin), buf, bufsize/2);
12950Sstevel@tonic-gate lf_num = 0;
12960Sstevel@tonic-gate /* both loops are skipped when i <= 0 */
12970Sstevel@tonic-gate for (j = 0; j < i; j++)
12980Sstevel@tonic-gate if (buf[j] == '\n')
12990Sstevel@tonic-gate lf_num++;
13000Sstevel@tonic-gate for (j = i-1; j >= 0; j--)
13010Sstevel@tonic-gate {
13020Sstevel@tonic-gate buf[j+lf_num] = buf[j];
13030Sstevel@tonic-gate if (buf[j] == '\n')
13040Sstevel@tonic-gate {
13050Sstevel@tonic-gate lf_num--;
13060Sstevel@tonic-gate i++;
13070Sstevel@tonic-gate buf[j+lf_num] = '\r';
13080Sstevel@tonic-gate }
13090Sstevel@tonic-gate }
13100Sstevel@tonic-gate assert(lf_num == 0);
13110Sstevel@tonic-gate }
13120Sstevel@tonic-gate else
13130Sstevel@tonic-gate i=read(fileno(stdin),buf,bufsize);
13140Sstevel@tonic-gate if (!s_quiet)
13150Sstevel@tonic-gate {
13160Sstevel@tonic-gate if ((i <= 0) || (buf[0] == 'Q'))
13170Sstevel@tonic-gate {
13180Sstevel@tonic-gate BIO_printf(bio_s_out,"DONE\n");
13190Sstevel@tonic-gate SHUTDOWN(s);
13200Sstevel@tonic-gate close_accept_socket();
13210Sstevel@tonic-gate ret= -11;
13220Sstevel@tonic-gate goto err;
13230Sstevel@tonic-gate }
13240Sstevel@tonic-gate if ((i <= 0) || (buf[0] == 'q'))
13250Sstevel@tonic-gate {
13260Sstevel@tonic-gate BIO_printf(bio_s_out,"DONE\n");
1327*2139Sjp161948 if (SSL_version(con) != DTLS1_VERSION)
1328*2139Sjp161948 SHUTDOWN(s);
13290Sstevel@tonic-gate /* close_accept_socket();
13300Sstevel@tonic-gate ret= -11;*/
13310Sstevel@tonic-gate goto err;
13320Sstevel@tonic-gate }
13330Sstevel@tonic-gate if ((buf[0] == 'r') &&
13340Sstevel@tonic-gate ((buf[1] == '\n') || (buf[1] == '\r')))
13350Sstevel@tonic-gate {
13360Sstevel@tonic-gate SSL_renegotiate(con);
13370Sstevel@tonic-gate i=SSL_do_handshake(con);
13380Sstevel@tonic-gate printf("SSL_do_handshake -> %d\n",i);
13390Sstevel@tonic-gate i=0; /*13; */
13400Sstevel@tonic-gate continue;
13410Sstevel@tonic-gate /* strcpy(buf,"server side RE-NEGOTIATE\n"); */
13420Sstevel@tonic-gate }
13430Sstevel@tonic-gate if ((buf[0] == 'R') &&
13440Sstevel@tonic-gate ((buf[1] == '\n') || (buf[1] == '\r')))
13450Sstevel@tonic-gate {
13460Sstevel@tonic-gate SSL_set_verify(con,
13470Sstevel@tonic-gate SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
13480Sstevel@tonic-gate SSL_renegotiate(con);
13490Sstevel@tonic-gate i=SSL_do_handshake(con);
13500Sstevel@tonic-gate printf("SSL_do_handshake -> %d\n",i);
13510Sstevel@tonic-gate i=0; /* 13; */
13520Sstevel@tonic-gate continue;
13530Sstevel@tonic-gate /* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
13540Sstevel@tonic-gate }
13550Sstevel@tonic-gate if (buf[0] == 'P')
13560Sstevel@tonic-gate {
1357*2139Sjp161948 static const char *str="Lets print some clear text\n";
13580Sstevel@tonic-gate BIO_write(SSL_get_wbio(con),str,strlen(str));
13590Sstevel@tonic-gate }
13600Sstevel@tonic-gate if (buf[0] == 'S')
13610Sstevel@tonic-gate {
13620Sstevel@tonic-gate print_stats(bio_s_out,SSL_get_SSL_CTX(con));
13630Sstevel@tonic-gate }
13640Sstevel@tonic-gate }
13650Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
13660Sstevel@tonic-gate ebcdic2ascii(buf,buf,i);
13670Sstevel@tonic-gate #endif
13680Sstevel@tonic-gate l=k=0;
13690Sstevel@tonic-gate for (;;)
13700Sstevel@tonic-gate {
13710Sstevel@tonic-gate /* should do a select for the write */
13720Sstevel@tonic-gate #ifdef RENEG
13730Sstevel@tonic-gate { static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
13740Sstevel@tonic-gate #endif
13750Sstevel@tonic-gate k=SSL_write(con,&(buf[l]),(unsigned int)i);
13760Sstevel@tonic-gate switch (SSL_get_error(con,k))
13770Sstevel@tonic-gate {
13780Sstevel@tonic-gate case SSL_ERROR_NONE:
13790Sstevel@tonic-gate break;
13800Sstevel@tonic-gate case SSL_ERROR_WANT_WRITE:
13810Sstevel@tonic-gate case SSL_ERROR_WANT_READ:
13820Sstevel@tonic-gate case SSL_ERROR_WANT_X509_LOOKUP:
13830Sstevel@tonic-gate BIO_printf(bio_s_out,"Write BLOCK\n");
13840Sstevel@tonic-gate break;
13850Sstevel@tonic-gate case SSL_ERROR_SYSCALL:
13860Sstevel@tonic-gate case SSL_ERROR_SSL:
13870Sstevel@tonic-gate BIO_printf(bio_s_out,"ERROR\n");
13880Sstevel@tonic-gate ERR_print_errors(bio_err);
13890Sstevel@tonic-gate ret=1;
13900Sstevel@tonic-gate goto err;
13910Sstevel@tonic-gate /* break; */
13920Sstevel@tonic-gate case SSL_ERROR_ZERO_RETURN:
13930Sstevel@tonic-gate BIO_printf(bio_s_out,"DONE\n");
13940Sstevel@tonic-gate ret=1;
13950Sstevel@tonic-gate goto err;
13960Sstevel@tonic-gate }
13970Sstevel@tonic-gate l+=k;
13980Sstevel@tonic-gate i-=k;
13990Sstevel@tonic-gate if (i <= 0) break;
14000Sstevel@tonic-gate }
14010Sstevel@tonic-gate }
14020Sstevel@tonic-gate if (read_from_sslcon)
14030Sstevel@tonic-gate {
14040Sstevel@tonic-gate if (!SSL_is_init_finished(con))
14050Sstevel@tonic-gate {
14060Sstevel@tonic-gate i=init_ssl_connection(con);
14070Sstevel@tonic-gate
14080Sstevel@tonic-gate if (i < 0)
14090Sstevel@tonic-gate {
14100Sstevel@tonic-gate ret=0;
14110Sstevel@tonic-gate goto err;
14120Sstevel@tonic-gate }
14130Sstevel@tonic-gate else if (i == 0)
14140Sstevel@tonic-gate {
14150Sstevel@tonic-gate ret=1;
14160Sstevel@tonic-gate goto err;
14170Sstevel@tonic-gate }
14180Sstevel@tonic-gate }
14190Sstevel@tonic-gate else
14200Sstevel@tonic-gate {
14210Sstevel@tonic-gate again:
14220Sstevel@tonic-gate i=SSL_read(con,(char *)buf,bufsize);
14230Sstevel@tonic-gate switch (SSL_get_error(con,i))
14240Sstevel@tonic-gate {
14250Sstevel@tonic-gate case SSL_ERROR_NONE:
14260Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
14270Sstevel@tonic-gate ascii2ebcdic(buf,buf,i);
14280Sstevel@tonic-gate #endif
14290Sstevel@tonic-gate write(fileno(stdout),buf,
14300Sstevel@tonic-gate (unsigned int)i);
14310Sstevel@tonic-gate if (SSL_pending(con)) goto again;
14320Sstevel@tonic-gate break;
14330Sstevel@tonic-gate case SSL_ERROR_WANT_WRITE:
14340Sstevel@tonic-gate case SSL_ERROR_WANT_READ:
14350Sstevel@tonic-gate case SSL_ERROR_WANT_X509_LOOKUP:
14360Sstevel@tonic-gate BIO_printf(bio_s_out,"Read BLOCK\n");
14370Sstevel@tonic-gate break;
14380Sstevel@tonic-gate case SSL_ERROR_SYSCALL:
14390Sstevel@tonic-gate case SSL_ERROR_SSL:
14400Sstevel@tonic-gate BIO_printf(bio_s_out,"ERROR\n");
14410Sstevel@tonic-gate ERR_print_errors(bio_err);
14420Sstevel@tonic-gate ret=1;
14430Sstevel@tonic-gate goto err;
14440Sstevel@tonic-gate case SSL_ERROR_ZERO_RETURN:
14450Sstevel@tonic-gate BIO_printf(bio_s_out,"DONE\n");
14460Sstevel@tonic-gate ret=1;
14470Sstevel@tonic-gate goto err;
14480Sstevel@tonic-gate }
14490Sstevel@tonic-gate }
14500Sstevel@tonic-gate }
14510Sstevel@tonic-gate }
14520Sstevel@tonic-gate err:
14530Sstevel@tonic-gate BIO_printf(bio_s_out,"shutting down SSL\n");
14540Sstevel@tonic-gate #if 1
14550Sstevel@tonic-gate SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
14560Sstevel@tonic-gate #else
14570Sstevel@tonic-gate SSL_shutdown(con);
14580Sstevel@tonic-gate #endif
14590Sstevel@tonic-gate if (con != NULL) SSL_free(con);
14600Sstevel@tonic-gate BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
14610Sstevel@tonic-gate if (buf != NULL)
14620Sstevel@tonic-gate {
14630Sstevel@tonic-gate OPENSSL_cleanse(buf,bufsize);
14640Sstevel@tonic-gate OPENSSL_free(buf);
14650Sstevel@tonic-gate }
14660Sstevel@tonic-gate if (ret >= 0)
14670Sstevel@tonic-gate BIO_printf(bio_s_out,"ACCEPT\n");
14680Sstevel@tonic-gate return(ret);
14690Sstevel@tonic-gate }
14700Sstevel@tonic-gate
close_accept_socket(void)14710Sstevel@tonic-gate static void close_accept_socket(void)
14720Sstevel@tonic-gate {
14730Sstevel@tonic-gate BIO_printf(bio_err,"shutdown accept socket\n");
14740Sstevel@tonic-gate if (accept_socket >= 0)
14750Sstevel@tonic-gate {
14760Sstevel@tonic-gate SHUTDOWN2(accept_socket);
14770Sstevel@tonic-gate }
14780Sstevel@tonic-gate }
14790Sstevel@tonic-gate
init_ssl_connection(SSL * con)14800Sstevel@tonic-gate static int init_ssl_connection(SSL *con)
14810Sstevel@tonic-gate {
14820Sstevel@tonic-gate int i;
14830Sstevel@tonic-gate const char *str;
14840Sstevel@tonic-gate X509 *peer;
14850Sstevel@tonic-gate long verify_error;
14860Sstevel@tonic-gate MS_STATIC char buf[BUFSIZ];
14870Sstevel@tonic-gate
14880Sstevel@tonic-gate if ((i=SSL_accept(con)) <= 0)
14890Sstevel@tonic-gate {
14900Sstevel@tonic-gate if (BIO_sock_should_retry(i))
14910Sstevel@tonic-gate {
14920Sstevel@tonic-gate BIO_printf(bio_s_out,"DELAY\n");
14930Sstevel@tonic-gate return(1);
14940Sstevel@tonic-gate }
14950Sstevel@tonic-gate
14960Sstevel@tonic-gate BIO_printf(bio_err,"ERROR\n");
14970Sstevel@tonic-gate verify_error=SSL_get_verify_result(con);
14980Sstevel@tonic-gate if (verify_error != X509_V_OK)
14990Sstevel@tonic-gate {
15000Sstevel@tonic-gate BIO_printf(bio_err,"verify error:%s\n",
15010Sstevel@tonic-gate X509_verify_cert_error_string(verify_error));
15020Sstevel@tonic-gate }
15030Sstevel@tonic-gate else
15040Sstevel@tonic-gate ERR_print_errors(bio_err);
15050Sstevel@tonic-gate return(0);
15060Sstevel@tonic-gate }
15070Sstevel@tonic-gate
15080Sstevel@tonic-gate PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
15090Sstevel@tonic-gate
15100Sstevel@tonic-gate peer=SSL_get_peer_certificate(con);
15110Sstevel@tonic-gate if (peer != NULL)
15120Sstevel@tonic-gate {
15130Sstevel@tonic-gate BIO_printf(bio_s_out,"Client certificate\n");
15140Sstevel@tonic-gate PEM_write_bio_X509(bio_s_out,peer);
15150Sstevel@tonic-gate X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
15160Sstevel@tonic-gate BIO_printf(bio_s_out,"subject=%s\n",buf);
15170Sstevel@tonic-gate X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
15180Sstevel@tonic-gate BIO_printf(bio_s_out,"issuer=%s\n",buf);
15190Sstevel@tonic-gate X509_free(peer);
15200Sstevel@tonic-gate }
15210Sstevel@tonic-gate
15220Sstevel@tonic-gate if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
15230Sstevel@tonic-gate BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
15240Sstevel@tonic-gate str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
15250Sstevel@tonic-gate BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
15260Sstevel@tonic-gate if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
15270Sstevel@tonic-gate if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
15280Sstevel@tonic-gate TLS1_FLAGS_TLS_PADDING_BUG)
15290Sstevel@tonic-gate BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
15300Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
15310Sstevel@tonic-gate if (con->kssl_ctx->client_princ != NULL)
15320Sstevel@tonic-gate {
15330Sstevel@tonic-gate BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
15340Sstevel@tonic-gate con->kssl_ctx->client_princ);
15350Sstevel@tonic-gate }
15360Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
15370Sstevel@tonic-gate return(1);
15380Sstevel@tonic-gate }
15390Sstevel@tonic-gate
15400Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
load_dh_param(const char * dhfile)1541*2139Sjp161948 static DH *load_dh_param(const char *dhfile)
15420Sstevel@tonic-gate {
15430Sstevel@tonic-gate DH *ret=NULL;
15440Sstevel@tonic-gate BIO *bio;
15450Sstevel@tonic-gate
15460Sstevel@tonic-gate if ((bio=BIO_new_file(dhfile,"r")) == NULL)
15470Sstevel@tonic-gate goto err;
15480Sstevel@tonic-gate ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
15490Sstevel@tonic-gate err:
15500Sstevel@tonic-gate if (bio != NULL) BIO_free(bio);
15510Sstevel@tonic-gate return(ret);
15520Sstevel@tonic-gate }
15530Sstevel@tonic-gate #endif
15540Sstevel@tonic-gate
15550Sstevel@tonic-gate #if 0
15560Sstevel@tonic-gate static int load_CA(SSL_CTX *ctx, char *file)
15570Sstevel@tonic-gate {
15580Sstevel@tonic-gate FILE *in;
15590Sstevel@tonic-gate X509 *x=NULL;
15600Sstevel@tonic-gate
15610Sstevel@tonic-gate if ((in=fopen(file,"r")) == NULL)
15620Sstevel@tonic-gate return(0);
15630Sstevel@tonic-gate
15640Sstevel@tonic-gate for (;;)
15650Sstevel@tonic-gate {
15660Sstevel@tonic-gate if (PEM_read_X509(in,&x,NULL) == NULL)
15670Sstevel@tonic-gate break;
15680Sstevel@tonic-gate SSL_CTX_add_client_CA(ctx,x);
15690Sstevel@tonic-gate }
15700Sstevel@tonic-gate if (x != NULL) X509_free(x);
15710Sstevel@tonic-gate fclose(in);
15720Sstevel@tonic-gate return(1);
15730Sstevel@tonic-gate }
15740Sstevel@tonic-gate #endif
15750Sstevel@tonic-gate
www_body(char * hostname,int s,unsigned char * context)15760Sstevel@tonic-gate static int www_body(char *hostname, int s, unsigned char *context)
15770Sstevel@tonic-gate {
15780Sstevel@tonic-gate char *buf=NULL;
15790Sstevel@tonic-gate int ret=1;
15800Sstevel@tonic-gate int i,j,k,blank,dot;
15810Sstevel@tonic-gate struct stat st_buf;
15820Sstevel@tonic-gate SSL *con;
15830Sstevel@tonic-gate SSL_CIPHER *c;
15840Sstevel@tonic-gate BIO *io,*ssl_bio,*sbio;
15850Sstevel@tonic-gate long total_bytes;
15860Sstevel@tonic-gate
15870Sstevel@tonic-gate buf=OPENSSL_malloc(bufsize);
15880Sstevel@tonic-gate if (buf == NULL) return(0);
15890Sstevel@tonic-gate io=BIO_new(BIO_f_buffer());
15900Sstevel@tonic-gate ssl_bio=BIO_new(BIO_f_ssl());
15910Sstevel@tonic-gate if ((io == NULL) || (ssl_bio == NULL)) goto err;
15920Sstevel@tonic-gate
15930Sstevel@tonic-gate #ifdef FIONBIO
15940Sstevel@tonic-gate if (s_nbio)
15950Sstevel@tonic-gate {
15960Sstevel@tonic-gate unsigned long sl=1;
15970Sstevel@tonic-gate
15980Sstevel@tonic-gate if (!s_quiet)
15990Sstevel@tonic-gate BIO_printf(bio_err,"turning on non blocking io\n");
16000Sstevel@tonic-gate if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
16010Sstevel@tonic-gate ERR_print_errors(bio_err);
16020Sstevel@tonic-gate }
16030Sstevel@tonic-gate #endif
16040Sstevel@tonic-gate
16050Sstevel@tonic-gate /* lets make the output buffer a reasonable size */
16060Sstevel@tonic-gate if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
16070Sstevel@tonic-gate
16080Sstevel@tonic-gate if ((con=SSL_new(ctx)) == NULL) goto err;
16090Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5
16100Sstevel@tonic-gate if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
16110Sstevel@tonic-gate {
16120Sstevel@tonic-gate kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
16130Sstevel@tonic-gate kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
16140Sstevel@tonic-gate }
16150Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */
16160Sstevel@tonic-gate if(context) SSL_set_session_id_context(con, context,
16170Sstevel@tonic-gate strlen((char *)context));
16180Sstevel@tonic-gate
16190Sstevel@tonic-gate sbio=BIO_new_socket(s,BIO_NOCLOSE);
16200Sstevel@tonic-gate if (s_nbio_test)
16210Sstevel@tonic-gate {
16220Sstevel@tonic-gate BIO *test;
16230Sstevel@tonic-gate
16240Sstevel@tonic-gate test=BIO_new(BIO_f_nbio_test());
16250Sstevel@tonic-gate sbio=BIO_push(test,sbio);
16260Sstevel@tonic-gate }
16270Sstevel@tonic-gate SSL_set_bio(con,sbio,sbio);
16280Sstevel@tonic-gate SSL_set_accept_state(con);
16290Sstevel@tonic-gate
16300Sstevel@tonic-gate /* SSL_set_fd(con,s); */
16310Sstevel@tonic-gate BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
16320Sstevel@tonic-gate BIO_push(io,ssl_bio);
16330Sstevel@tonic-gate #ifdef CHARSET_EBCDIC
16340Sstevel@tonic-gate io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
16350Sstevel@tonic-gate #endif
16360Sstevel@tonic-gate
16370Sstevel@tonic-gate if (s_debug)
16380Sstevel@tonic-gate {
16390Sstevel@tonic-gate con->debug=1;
1640*2139Sjp161948 BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
16410Sstevel@tonic-gate BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
16420Sstevel@tonic-gate }
16430Sstevel@tonic-gate if (s_msg)
16440Sstevel@tonic-gate {
16450Sstevel@tonic-gate SSL_set_msg_callback(con, msg_cb);
16460Sstevel@tonic-gate SSL_set_msg_callback_arg(con, bio_s_out);
16470Sstevel@tonic-gate }
16480Sstevel@tonic-gate
16490Sstevel@tonic-gate blank=0;
16500Sstevel@tonic-gate for (;;)
16510Sstevel@tonic-gate {
16520Sstevel@tonic-gate if (hack)
16530Sstevel@tonic-gate {
16540Sstevel@tonic-gate i=SSL_accept(con);
16550Sstevel@tonic-gate
16560Sstevel@tonic-gate switch (SSL_get_error(con,i))
16570Sstevel@tonic-gate {
16580Sstevel@tonic-gate case SSL_ERROR_NONE:
16590Sstevel@tonic-gate break;
16600Sstevel@tonic-gate case SSL_ERROR_WANT_WRITE:
16610Sstevel@tonic-gate case SSL_ERROR_WANT_READ:
16620Sstevel@tonic-gate case SSL_ERROR_WANT_X509_LOOKUP:
16630Sstevel@tonic-gate continue;
16640Sstevel@tonic-gate case SSL_ERROR_SYSCALL:
16650Sstevel@tonic-gate case SSL_ERROR_SSL:
16660Sstevel@tonic-gate case SSL_ERROR_ZERO_RETURN:
16670Sstevel@tonic-gate ret=1;
16680Sstevel@tonic-gate goto err;
16690Sstevel@tonic-gate /* break; */
16700Sstevel@tonic-gate }
16710Sstevel@tonic-gate
16720Sstevel@tonic-gate SSL_renegotiate(con);
16730Sstevel@tonic-gate SSL_write(con,NULL,0);
16740Sstevel@tonic-gate }
16750Sstevel@tonic-gate
16760Sstevel@tonic-gate i=BIO_gets(io,buf,bufsize-1);
16770Sstevel@tonic-gate if (i < 0) /* error */
16780Sstevel@tonic-gate {
16790Sstevel@tonic-gate if (!BIO_should_retry(io))
16800Sstevel@tonic-gate {
16810Sstevel@tonic-gate if (!s_quiet)
16820Sstevel@tonic-gate ERR_print_errors(bio_err);
16830Sstevel@tonic-gate goto err;
16840Sstevel@tonic-gate }
16850Sstevel@tonic-gate else
16860Sstevel@tonic-gate {
16870Sstevel@tonic-gate BIO_printf(bio_s_out,"read R BLOCK\n");
1688*2139Sjp161948 #if defined(OPENSSL_SYS_NETWARE)
1689*2139Sjp161948 delay(1000);
1690*2139Sjp161948 #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
16910Sstevel@tonic-gate sleep(1);
16920Sstevel@tonic-gate #endif
16930Sstevel@tonic-gate continue;
16940Sstevel@tonic-gate }
16950Sstevel@tonic-gate }
16960Sstevel@tonic-gate else if (i == 0) /* end of input */
16970Sstevel@tonic-gate {
16980Sstevel@tonic-gate ret=1;
16990Sstevel@tonic-gate goto end;
17000Sstevel@tonic-gate }
17010Sstevel@tonic-gate
17020Sstevel@tonic-gate /* else we have data */
17030Sstevel@tonic-gate if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
17040Sstevel@tonic-gate ((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
17050Sstevel@tonic-gate {
17060Sstevel@tonic-gate char *p;
17070Sstevel@tonic-gate X509 *peer;
17080Sstevel@tonic-gate STACK_OF(SSL_CIPHER) *sk;
1709*2139Sjp161948 static const char *space=" ";
17100Sstevel@tonic-gate
17110Sstevel@tonic-gate BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
17120Sstevel@tonic-gate BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
17130Sstevel@tonic-gate BIO_puts(io,"<pre>\n");
17140Sstevel@tonic-gate /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
17150Sstevel@tonic-gate BIO_puts(io,"\n");
17160Sstevel@tonic-gate for (i=0; i<local_argc; i++)
17170Sstevel@tonic-gate {
17180Sstevel@tonic-gate BIO_puts(io,local_argv[i]);
17190Sstevel@tonic-gate BIO_write(io," ",1);
17200Sstevel@tonic-gate }
17210Sstevel@tonic-gate BIO_puts(io,"\n");
17220Sstevel@tonic-gate
17230Sstevel@tonic-gate /* The following is evil and should not really
17240Sstevel@tonic-gate * be done */
17250Sstevel@tonic-gate BIO_printf(io,"Ciphers supported in s_server binary\n");
17260Sstevel@tonic-gate sk=SSL_get_ciphers(con);
17270Sstevel@tonic-gate j=sk_SSL_CIPHER_num(sk);
17280Sstevel@tonic-gate for (i=0; i<j; i++)
17290Sstevel@tonic-gate {
17300Sstevel@tonic-gate c=sk_SSL_CIPHER_value(sk,i);
17310Sstevel@tonic-gate BIO_printf(io,"%-11s:%-25s",
17320Sstevel@tonic-gate SSL_CIPHER_get_version(c),
17330Sstevel@tonic-gate SSL_CIPHER_get_name(c));
17340Sstevel@tonic-gate if ((((i+1)%2) == 0) && (i+1 != j))
17350Sstevel@tonic-gate BIO_puts(io,"\n");
17360Sstevel@tonic-gate }
17370Sstevel@tonic-gate BIO_puts(io,"\n");
17380Sstevel@tonic-gate p=SSL_get_shared_ciphers(con,buf,bufsize);
17390Sstevel@tonic-gate if (p != NULL)
17400Sstevel@tonic-gate {
17410Sstevel@tonic-gate BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
17420Sstevel@tonic-gate j=i=0;
17430Sstevel@tonic-gate while (*p)
17440Sstevel@tonic-gate {
17450Sstevel@tonic-gate if (*p == ':')
17460Sstevel@tonic-gate {
17470Sstevel@tonic-gate BIO_write(io,space,26-j);
17480Sstevel@tonic-gate i++;
17490Sstevel@tonic-gate j=0;
17500Sstevel@tonic-gate BIO_write(io,((i%3)?" ":"\n"),1);
17510Sstevel@tonic-gate }
17520Sstevel@tonic-gate else
17530Sstevel@tonic-gate {
17540Sstevel@tonic-gate BIO_write(io,p,1);
17550Sstevel@tonic-gate j++;
17560Sstevel@tonic-gate }
17570Sstevel@tonic-gate p++;
17580Sstevel@tonic-gate }
17590Sstevel@tonic-gate BIO_puts(io,"\n");
17600Sstevel@tonic-gate }
17610Sstevel@tonic-gate BIO_printf(io,((con->hit)
17620Sstevel@tonic-gate ?"---\nReused, "
17630Sstevel@tonic-gate :"---\nNew, "));
17640Sstevel@tonic-gate c=SSL_get_current_cipher(con);
17650Sstevel@tonic-gate BIO_printf(io,"%s, Cipher is %s\n",
17660Sstevel@tonic-gate SSL_CIPHER_get_version(c),
17670Sstevel@tonic-gate SSL_CIPHER_get_name(c));
17680Sstevel@tonic-gate SSL_SESSION_print(io,SSL_get_session(con));
17690Sstevel@tonic-gate BIO_printf(io,"---\n");
17700Sstevel@tonic-gate print_stats(io,SSL_get_SSL_CTX(con));
17710Sstevel@tonic-gate BIO_printf(io,"---\n");
17720Sstevel@tonic-gate peer=SSL_get_peer_certificate(con);
17730Sstevel@tonic-gate if (peer != NULL)
17740Sstevel@tonic-gate {
17750Sstevel@tonic-gate BIO_printf(io,"Client certificate\n");
17760Sstevel@tonic-gate X509_print(io,peer);
17770Sstevel@tonic-gate PEM_write_bio_X509(io,peer);
17780Sstevel@tonic-gate }
17790Sstevel@tonic-gate else
17800Sstevel@tonic-gate BIO_puts(io,"no client certificate available\n");
17810Sstevel@tonic-gate BIO_puts(io,"</BODY></HTML>\r\n\r\n");
17820Sstevel@tonic-gate break;
17830Sstevel@tonic-gate }
17840Sstevel@tonic-gate else if ((www == 2 || www == 3)
17850Sstevel@tonic-gate && (strncmp("GET /",buf,5) == 0))
17860Sstevel@tonic-gate {
17870Sstevel@tonic-gate BIO *file;
17880Sstevel@tonic-gate char *p,*e;
1789*2139Sjp161948 static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
17900Sstevel@tonic-gate
17910Sstevel@tonic-gate /* skip the '/' */
17920Sstevel@tonic-gate p= &(buf[5]);
17930Sstevel@tonic-gate
17940Sstevel@tonic-gate dot = 1;
17950Sstevel@tonic-gate for (e=p; *e != '\0'; e++)
17960Sstevel@tonic-gate {
17970Sstevel@tonic-gate if (e[0] == ' ')
17980Sstevel@tonic-gate break;
17990Sstevel@tonic-gate
18000Sstevel@tonic-gate switch (dot)
18010Sstevel@tonic-gate {
18020Sstevel@tonic-gate case 1:
18030Sstevel@tonic-gate dot = (e[0] == '.') ? 2 : 0;
18040Sstevel@tonic-gate break;
18050Sstevel@tonic-gate case 2:
18060Sstevel@tonic-gate dot = (e[0] == '.') ? 3 : 0;
18070Sstevel@tonic-gate break;
18080Sstevel@tonic-gate case 3:
18090Sstevel@tonic-gate dot = (e[0] == '/') ? -1 : 0;
18100Sstevel@tonic-gate break;
18110Sstevel@tonic-gate }
18120Sstevel@tonic-gate if (dot == 0)
18130Sstevel@tonic-gate dot = (e[0] == '/') ? 1 : 0;
18140Sstevel@tonic-gate }
18150Sstevel@tonic-gate dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
18160Sstevel@tonic-gate
18170Sstevel@tonic-gate if (*e == '\0')
18180Sstevel@tonic-gate {
18190Sstevel@tonic-gate BIO_puts(io,text);
18200Sstevel@tonic-gate BIO_printf(io,"'%s' is an invalid file name\r\n",p);
18210Sstevel@tonic-gate break;
18220Sstevel@tonic-gate }
18230Sstevel@tonic-gate *e='\0';
18240Sstevel@tonic-gate
18250Sstevel@tonic-gate if (dot)
18260Sstevel@tonic-gate {
18270Sstevel@tonic-gate BIO_puts(io,text);
18280Sstevel@tonic-gate BIO_printf(io,"'%s' contains '..' reference\r\n",p);
18290Sstevel@tonic-gate break;
18300Sstevel@tonic-gate }
18310Sstevel@tonic-gate
18320Sstevel@tonic-gate if (*p == '/')
18330Sstevel@tonic-gate {
18340Sstevel@tonic-gate BIO_puts(io,text);
18350Sstevel@tonic-gate BIO_printf(io,"'%s' is an invalid path\r\n",p);
18360Sstevel@tonic-gate break;
18370Sstevel@tonic-gate }
18380Sstevel@tonic-gate
18390Sstevel@tonic-gate #if 0
18400Sstevel@tonic-gate /* append if a directory lookup */
18410Sstevel@tonic-gate if (e[-1] == '/')
18420Sstevel@tonic-gate strcat(p,"index.html");
18430Sstevel@tonic-gate #endif
18440Sstevel@tonic-gate
18450Sstevel@tonic-gate /* if a directory, do the index thang */
18460Sstevel@tonic-gate if (stat(p,&st_buf) < 0)
18470Sstevel@tonic-gate {
18480Sstevel@tonic-gate BIO_puts(io,text);
18490Sstevel@tonic-gate BIO_printf(io,"Error accessing '%s'\r\n",p);
18500Sstevel@tonic-gate ERR_print_errors(io);
18510Sstevel@tonic-gate break;
18520Sstevel@tonic-gate }
18530Sstevel@tonic-gate if (S_ISDIR(st_buf.st_mode))
18540Sstevel@tonic-gate {
18550Sstevel@tonic-gate #if 0 /* must check buffer size */
18560Sstevel@tonic-gate strcat(p,"/index.html");
18570Sstevel@tonic-gate #else
18580Sstevel@tonic-gate BIO_puts(io,text);
18590Sstevel@tonic-gate BIO_printf(io,"'%s' is a directory\r\n",p);
18600Sstevel@tonic-gate break;
18610Sstevel@tonic-gate #endif
18620Sstevel@tonic-gate }
18630Sstevel@tonic-gate
18640Sstevel@tonic-gate if ((file=BIO_new_file(p,"r")) == NULL)
18650Sstevel@tonic-gate {
18660Sstevel@tonic-gate BIO_puts(io,text);
18670Sstevel@tonic-gate BIO_printf(io,"Error opening '%s'\r\n",p);
18680Sstevel@tonic-gate ERR_print_errors(io);
18690Sstevel@tonic-gate break;
18700Sstevel@tonic-gate }
18710Sstevel@tonic-gate
18720Sstevel@tonic-gate if (!s_quiet)
18730Sstevel@tonic-gate BIO_printf(bio_err,"FILE:%s\n",p);
18740Sstevel@tonic-gate
18750Sstevel@tonic-gate if (www == 2)
18760Sstevel@tonic-gate {
18770Sstevel@tonic-gate i=strlen(p);
18780Sstevel@tonic-gate if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
18790Sstevel@tonic-gate ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
18800Sstevel@tonic-gate ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
18810Sstevel@tonic-gate BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
18820Sstevel@tonic-gate else
18830Sstevel@tonic-gate BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
18840Sstevel@tonic-gate }
18850Sstevel@tonic-gate /* send the file */
18860Sstevel@tonic-gate total_bytes=0;
18870Sstevel@tonic-gate for (;;)
18880Sstevel@tonic-gate {
18890Sstevel@tonic-gate i=BIO_read(file,buf,bufsize);
18900Sstevel@tonic-gate if (i <= 0) break;
18910Sstevel@tonic-gate
18920Sstevel@tonic-gate #ifdef RENEG
18930Sstevel@tonic-gate total_bytes+=i;
18940Sstevel@tonic-gate fprintf(stderr,"%d\n",i);
18950Sstevel@tonic-gate if (total_bytes > 3*1024)
18960Sstevel@tonic-gate {
18970Sstevel@tonic-gate total_bytes=0;
18980Sstevel@tonic-gate fprintf(stderr,"RENEGOTIATE\n");
18990Sstevel@tonic-gate SSL_renegotiate(con);
19000Sstevel@tonic-gate }
19010Sstevel@tonic-gate #endif
19020Sstevel@tonic-gate
19030Sstevel@tonic-gate for (j=0; j<i; )
19040Sstevel@tonic-gate {
19050Sstevel@tonic-gate #ifdef RENEG
19060Sstevel@tonic-gate { static count=0; if (++count == 13) { SSL_renegotiate(con); } }
19070Sstevel@tonic-gate #endif
19080Sstevel@tonic-gate k=BIO_write(io,&(buf[j]),i-j);
19090Sstevel@tonic-gate if (k <= 0)
19100Sstevel@tonic-gate {
19110Sstevel@tonic-gate if (!BIO_should_retry(io))
19120Sstevel@tonic-gate goto write_error;
19130Sstevel@tonic-gate else
19140Sstevel@tonic-gate {
19150Sstevel@tonic-gate BIO_printf(bio_s_out,"rwrite W BLOCK\n");
19160Sstevel@tonic-gate }
19170Sstevel@tonic-gate }
19180Sstevel@tonic-gate else
19190Sstevel@tonic-gate {
19200Sstevel@tonic-gate j+=k;
19210Sstevel@tonic-gate }
19220Sstevel@tonic-gate }
19230Sstevel@tonic-gate }
19240Sstevel@tonic-gate write_error:
19250Sstevel@tonic-gate BIO_free(file);
19260Sstevel@tonic-gate break;
19270Sstevel@tonic-gate }
19280Sstevel@tonic-gate }
19290Sstevel@tonic-gate
19300Sstevel@tonic-gate for (;;)
19310Sstevel@tonic-gate {
19320Sstevel@tonic-gate i=(int)BIO_flush(io);
19330Sstevel@tonic-gate if (i <= 0)
19340Sstevel@tonic-gate {
19350Sstevel@tonic-gate if (!BIO_should_retry(io))
19360Sstevel@tonic-gate break;
19370Sstevel@tonic-gate }
19380Sstevel@tonic-gate else
19390Sstevel@tonic-gate break;
19400Sstevel@tonic-gate }
19410Sstevel@tonic-gate end:
19420Sstevel@tonic-gate #if 1
19430Sstevel@tonic-gate /* make sure we re-use sessions */
19440Sstevel@tonic-gate SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
19450Sstevel@tonic-gate #else
19460Sstevel@tonic-gate /* This kills performance */
19470Sstevel@tonic-gate /* SSL_shutdown(con); A shutdown gets sent in the
19480Sstevel@tonic-gate * BIO_free_all(io) procession */
19490Sstevel@tonic-gate #endif
19500Sstevel@tonic-gate
19510Sstevel@tonic-gate err:
19520Sstevel@tonic-gate
19530Sstevel@tonic-gate if (ret >= 0)
19540Sstevel@tonic-gate BIO_printf(bio_s_out,"ACCEPT\n");
19550Sstevel@tonic-gate
19560Sstevel@tonic-gate if (buf != NULL) OPENSSL_free(buf);
19570Sstevel@tonic-gate if (io != NULL) BIO_free_all(io);
19580Sstevel@tonic-gate /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
19590Sstevel@tonic-gate return(ret);
19600Sstevel@tonic-gate }
19610Sstevel@tonic-gate
19620Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
tmp_rsa_cb(SSL * s,int is_export,int keylength)19630Sstevel@tonic-gate static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
19640Sstevel@tonic-gate {
1965*2139Sjp161948 BIGNUM *bn = NULL;
19660Sstevel@tonic-gate static RSA *rsa_tmp=NULL;
19670Sstevel@tonic-gate
1968*2139Sjp161948 if (!rsa_tmp && ((bn = BN_new()) == NULL))
1969*2139Sjp161948 BIO_printf(bio_err,"Allocation error in generating RSA key\n");
1970*2139Sjp161948 if (!rsa_tmp && bn)
19710Sstevel@tonic-gate {
19720Sstevel@tonic-gate if (!s_quiet)
19730Sstevel@tonic-gate {
19740Sstevel@tonic-gate BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
19750Sstevel@tonic-gate (void)BIO_flush(bio_err);
19760Sstevel@tonic-gate }
1977*2139Sjp161948 if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
1978*2139Sjp161948 !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
1979*2139Sjp161948 {
1980*2139Sjp161948 if(rsa_tmp) RSA_free(rsa_tmp);
1981*2139Sjp161948 rsa_tmp = NULL;
1982*2139Sjp161948 }
19830Sstevel@tonic-gate if (!s_quiet)
19840Sstevel@tonic-gate {
19850Sstevel@tonic-gate BIO_printf(bio_err,"\n");
19860Sstevel@tonic-gate (void)BIO_flush(bio_err);
19870Sstevel@tonic-gate }
1988*2139Sjp161948 BN_free(bn);
19890Sstevel@tonic-gate }
19900Sstevel@tonic-gate return(rsa_tmp);
19910Sstevel@tonic-gate }
19920Sstevel@tonic-gate #endif
19930Sstevel@tonic-gate
19940Sstevel@tonic-gate #define MAX_SESSION_ID_ATTEMPTS 10
generate_session_id(const SSL * ssl,unsigned char * id,unsigned int * id_len)19950Sstevel@tonic-gate static int generate_session_id(const SSL *ssl, unsigned char *id,
19960Sstevel@tonic-gate unsigned int *id_len)
19970Sstevel@tonic-gate {
19980Sstevel@tonic-gate unsigned int count = 0;
19990Sstevel@tonic-gate do {
20000Sstevel@tonic-gate RAND_pseudo_bytes(id, *id_len);
20010Sstevel@tonic-gate /* Prefix the session_id with the required prefix. NB: If our
20020Sstevel@tonic-gate * prefix is too long, clip it - but there will be worse effects
20030Sstevel@tonic-gate * anyway, eg. the server could only possibly create 1 session
20040Sstevel@tonic-gate * ID (ie. the prefix!) so all future session negotiations will
20050Sstevel@tonic-gate * fail due to conflicts. */
20060Sstevel@tonic-gate memcpy(id, session_id_prefix,
20070Sstevel@tonic-gate (strlen(session_id_prefix) < *id_len) ?
20080Sstevel@tonic-gate strlen(session_id_prefix) : *id_len);
20090Sstevel@tonic-gate }
20100Sstevel@tonic-gate while(SSL_has_matching_session_id(ssl, id, *id_len) &&
20110Sstevel@tonic-gate (++count < MAX_SESSION_ID_ATTEMPTS));
20120Sstevel@tonic-gate if(count >= MAX_SESSION_ID_ATTEMPTS)
20130Sstevel@tonic-gate return 0;
20140Sstevel@tonic-gate return 1;
20150Sstevel@tonic-gate }
2016