10Sstevel@tonic-gate /* ssl/ssltest.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-2000 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 */ 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate #define _BSD_SOURCE 1 /* Or gethostname won't be declared properly 1180Sstevel@tonic-gate on Linux and GNU platforms. */ 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate #include <assert.h> 1210Sstevel@tonic-gate #include <errno.h> 1220Sstevel@tonic-gate #include <limits.h> 1230Sstevel@tonic-gate #include <stdio.h> 1240Sstevel@tonic-gate #include <stdlib.h> 1250Sstevel@tonic-gate #include <string.h> 1260Sstevel@tonic-gate #include <time.h> 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate #define USE_SOCKETS 1290Sstevel@tonic-gate #include "e_os.h" 1300Sstevel@tonic-gate 131*2139Sjp161948 #define _XOPEN_SOURCE 500 /* Or isascii won't be declared properly on 132*2139Sjp161948 VMS (at least with DECompHP C). */ 133*2139Sjp161948 #include <ctype.h> 134*2139Sjp161948 1350Sstevel@tonic-gate #include <openssl/bio.h> 1360Sstevel@tonic-gate #include <openssl/crypto.h> 1370Sstevel@tonic-gate #include <openssl/evp.h> 1380Sstevel@tonic-gate #include <openssl/x509.h> 139*2139Sjp161948 #include <openssl/x509v3.h> 1400Sstevel@tonic-gate #include <openssl/ssl.h> 1410Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 1420Sstevel@tonic-gate #include <openssl/engine.h> 1430Sstevel@tonic-gate #endif 1440Sstevel@tonic-gate #include <openssl/err.h> 1450Sstevel@tonic-gate #include <openssl/rand.h> 146*2139Sjp161948 #ifndef OPENSSL_NO_RSA 147*2139Sjp161948 #include <openssl/rsa.h> 148*2139Sjp161948 #endif 149*2139Sjp161948 #ifndef OPENSSL_NO_DSA 150*2139Sjp161948 #include <openssl/dsa.h> 151*2139Sjp161948 #endif 152*2139Sjp161948 #ifndef OPENSSL_NO_DH 153*2139Sjp161948 #include <openssl/dh.h> 154*2139Sjp161948 #endif 155*2139Sjp161948 #include <openssl/bn.h> 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate #define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly 1580Sstevel@tonic-gate on Compaq platforms (at least with DEC C). 1590Sstevel@tonic-gate Do not try to put it earlier, or IPv6 includes 1600Sstevel@tonic-gate get screwed... 1610Sstevel@tonic-gate */ 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate #ifdef OPENSSL_SYS_WINDOWS 1640Sstevel@tonic-gate #include <winsock.h> 1650Sstevel@tonic-gate #else 1660Sstevel@tonic-gate #include OPENSSL_UNISTD 1670Sstevel@tonic-gate #endif 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS 1700Sstevel@tonic-gate # define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM" 1710Sstevel@tonic-gate # define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM" 1720Sstevel@tonic-gate #elif defined(OPENSSL_SYS_WINCE) 1730Sstevel@tonic-gate # define TEST_SERVER_CERT "\\OpenSSL\\server.pem" 1740Sstevel@tonic-gate # define TEST_CLIENT_CERT "\\OpenSSL\\client.pem" 175*2139Sjp161948 #elif defined(OPENSSL_SYS_NETWARE) 176*2139Sjp161948 # define TEST_SERVER_CERT "\\openssl\\apps\\server.pem" 177*2139Sjp161948 # define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem" 1780Sstevel@tonic-gate #else 1790Sstevel@tonic-gate # define TEST_SERVER_CERT "../apps/server.pem" 1800Sstevel@tonic-gate # define TEST_CLIENT_CERT "../apps/client.pem" 1810Sstevel@tonic-gate #endif 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate /* There is really no standard for this, so let's assign some tentative 1840Sstevel@tonic-gate numbers. In any case, these numbers are only for this test */ 185*2139Sjp161948 #define COMP_RLE 255 186*2139Sjp161948 #define COMP_ZLIB 1 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); 1890Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 1900Sstevel@tonic-gate static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength); 1910Sstevel@tonic-gate static void free_tmp_rsa(void); 1920Sstevel@tonic-gate #endif 1930Sstevel@tonic-gate static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg); 194*2139Sjp161948 #define APP_CALLBACK_STRING "Test Callback Argument" 195*2139Sjp161948 struct app_verify_arg 196*2139Sjp161948 { 197*2139Sjp161948 char *string; 198*2139Sjp161948 int app_verify; 199*2139Sjp161948 int allow_proxy_certs; 200*2139Sjp161948 char *proxy_auth; 201*2139Sjp161948 char *proxy_cond; 202*2139Sjp161948 }; 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 2050Sstevel@tonic-gate static DH *get_dh512(void); 2060Sstevel@tonic-gate static DH *get_dh1024(void); 2070Sstevel@tonic-gate static DH *get_dh1024dsa(void); 2080Sstevel@tonic-gate #endif 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate static BIO *bio_err=NULL; 2110Sstevel@tonic-gate static BIO *bio_stdout=NULL; 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate static char *cipher=NULL; 2140Sstevel@tonic-gate static int verbose=0; 2150Sstevel@tonic-gate static int debug=0; 2160Sstevel@tonic-gate #if 0 2170Sstevel@tonic-gate /* Not used yet. */ 2180Sstevel@tonic-gate #ifdef FIONBIO 2190Sstevel@tonic-gate static int s_nbio=0; 2200Sstevel@tonic-gate #endif 2210Sstevel@tonic-gate #endif 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate static const char rnd_seed[] = "string to make the random number generator think it has entropy"; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time); 2260Sstevel@tonic-gate int doit(SSL *s_ssl,SSL *c_ssl,long bytes); 227*2139Sjp161948 static int do_test_cipherlist(void); 2280Sstevel@tonic-gate static void sv_usage(void) 2290Sstevel@tonic-gate { 2300Sstevel@tonic-gate fprintf(stderr,"usage: ssltest [args ...]\n"); 2310Sstevel@tonic-gate fprintf(stderr,"\n"); 2320Sstevel@tonic-gate fprintf(stderr," -server_auth - check server certificate\n"); 2330Sstevel@tonic-gate fprintf(stderr," -client_auth - do client authentication\n"); 234*2139Sjp161948 fprintf(stderr," -proxy - allow proxy certificates\n"); 235*2139Sjp161948 fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n"); 236*2139Sjp161948 fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n"); 2370Sstevel@tonic-gate fprintf(stderr," -v - more output\n"); 2380Sstevel@tonic-gate fprintf(stderr," -d - debug output\n"); 2390Sstevel@tonic-gate fprintf(stderr," -reuse - use session-id reuse\n"); 2400Sstevel@tonic-gate fprintf(stderr," -num <val> - number of connections to perform\n"); 2410Sstevel@tonic-gate fprintf(stderr," -bytes <val> - number of bytes to swap between client/server\n"); 2420Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 2430Sstevel@tonic-gate fprintf(stderr," -dhe1024 - use 1024 bit key (safe prime) for DHE\n"); 2440Sstevel@tonic-gate fprintf(stderr," -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); 2450Sstevel@tonic-gate fprintf(stderr," -no_dhe - disable DHE\n"); 2460Sstevel@tonic-gate #endif 247*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 248*2139Sjp161948 fprintf(stderr," -no_ecdhe - disable ECDHE\n"); 249*2139Sjp161948 #endif 2500Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL2 2510Sstevel@tonic-gate fprintf(stderr," -ssl2 - use SSLv2\n"); 2520Sstevel@tonic-gate #endif 2530Sstevel@tonic-gate #ifndef OPENSSL_NO_SSL3 2540Sstevel@tonic-gate fprintf(stderr," -ssl3 - use SSLv3\n"); 2550Sstevel@tonic-gate #endif 2560Sstevel@tonic-gate #ifndef OPENSSL_NO_TLS1 2570Sstevel@tonic-gate fprintf(stderr," -tls1 - use TLSv1\n"); 2580Sstevel@tonic-gate #endif 2590Sstevel@tonic-gate fprintf(stderr," -CApath arg - PEM format directory of CA's\n"); 2600Sstevel@tonic-gate fprintf(stderr," -CAfile arg - PEM format file of CA's\n"); 2610Sstevel@tonic-gate fprintf(stderr," -cert arg - Server certificate file\n"); 2620Sstevel@tonic-gate fprintf(stderr," -key arg - Server key file (default: same as -cert)\n"); 2630Sstevel@tonic-gate fprintf(stderr," -c_cert arg - Client certificate file\n"); 2640Sstevel@tonic-gate fprintf(stderr," -c_key arg - Client key file (default: same as -c_cert)\n"); 2650Sstevel@tonic-gate fprintf(stderr," -cipher arg - The cipher list\n"); 2660Sstevel@tonic-gate fprintf(stderr," -bio_pair - Use BIO pairs\n"); 2670Sstevel@tonic-gate fprintf(stderr," -f - Test even cases that can't work\n"); 2680Sstevel@tonic-gate fprintf(stderr," -time - measure processor time used by client and server\n"); 2690Sstevel@tonic-gate fprintf(stderr," -zlib - use zlib compression\n"); 270*2139Sjp161948 fprintf(stderr," -rle - use rle compression\n"); 271*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 272*2139Sjp161948 fprintf(stderr," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ 273*2139Sjp161948 " Use \"openssl ecparam -list_curves\" for all names\n" \ 274*2139Sjp161948 " (default is sect163r2).\n"); 275*2139Sjp161948 #endif 276*2139Sjp161948 fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); 2770Sstevel@tonic-gate } 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate static void print_details(SSL *c_ssl, const char *prefix) 2800Sstevel@tonic-gate { 2810Sstevel@tonic-gate SSL_CIPHER *ciph; 2820Sstevel@tonic-gate X509 *cert; 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate ciph=SSL_get_current_cipher(c_ssl); 2850Sstevel@tonic-gate BIO_printf(bio_stdout,"%s%s, cipher %s %s", 2860Sstevel@tonic-gate prefix, 2870Sstevel@tonic-gate SSL_get_version(c_ssl), 2880Sstevel@tonic-gate SSL_CIPHER_get_version(ciph), 2890Sstevel@tonic-gate SSL_CIPHER_get_name(ciph)); 2900Sstevel@tonic-gate cert=SSL_get_peer_certificate(c_ssl); 2910Sstevel@tonic-gate if (cert != NULL) 2920Sstevel@tonic-gate { 2930Sstevel@tonic-gate EVP_PKEY *pkey = X509_get_pubkey(cert); 2940Sstevel@tonic-gate if (pkey != NULL) 2950Sstevel@tonic-gate { 2960Sstevel@tonic-gate if (0) 2970Sstevel@tonic-gate ; 2980Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 2990Sstevel@tonic-gate else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL 3000Sstevel@tonic-gate && pkey->pkey.rsa->n != NULL) 3010Sstevel@tonic-gate { 3020Sstevel@tonic-gate BIO_printf(bio_stdout, ", %d bit RSA", 3030Sstevel@tonic-gate BN_num_bits(pkey->pkey.rsa->n)); 3040Sstevel@tonic-gate } 3050Sstevel@tonic-gate #endif 3060Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 3070Sstevel@tonic-gate else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL 3080Sstevel@tonic-gate && pkey->pkey.dsa->p != NULL) 3090Sstevel@tonic-gate { 3100Sstevel@tonic-gate BIO_printf(bio_stdout, ", %d bit DSA", 3110Sstevel@tonic-gate BN_num_bits(pkey->pkey.dsa->p)); 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate #endif 3140Sstevel@tonic-gate EVP_PKEY_free(pkey); 3150Sstevel@tonic-gate } 3160Sstevel@tonic-gate X509_free(cert); 3170Sstevel@tonic-gate } 3180Sstevel@tonic-gate /* The SSL API does not allow us to look at temporary RSA/DH keys, 3190Sstevel@tonic-gate * otherwise we should print their lengths too */ 3200Sstevel@tonic-gate BIO_printf(bio_stdout,"\n"); 3210Sstevel@tonic-gate } 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate static void lock_dbg_cb(int mode, int type, const char *file, int line) 3240Sstevel@tonic-gate { 3250Sstevel@tonic-gate static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ 3260Sstevel@tonic-gate const char *errstr = NULL; 3270Sstevel@tonic-gate int rw; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate rw = mode & (CRYPTO_READ|CRYPTO_WRITE); 3300Sstevel@tonic-gate if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) 3310Sstevel@tonic-gate { 3320Sstevel@tonic-gate errstr = "invalid mode"; 3330Sstevel@tonic-gate goto err; 3340Sstevel@tonic-gate } 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate if (type < 0 || type >= CRYPTO_NUM_LOCKS) 3370Sstevel@tonic-gate { 3380Sstevel@tonic-gate errstr = "type out of bounds"; 3390Sstevel@tonic-gate goto err; 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate if (mode & CRYPTO_LOCK) 3430Sstevel@tonic-gate { 3440Sstevel@tonic-gate if (modes[type]) 3450Sstevel@tonic-gate { 3460Sstevel@tonic-gate errstr = "already locked"; 3470Sstevel@tonic-gate /* must not happen in a single-threaded program 3480Sstevel@tonic-gate * (would deadlock) */ 3490Sstevel@tonic-gate goto err; 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate modes[type] = rw; 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate else if (mode & CRYPTO_UNLOCK) 3550Sstevel@tonic-gate { 3560Sstevel@tonic-gate if (!modes[type]) 3570Sstevel@tonic-gate { 3580Sstevel@tonic-gate errstr = "not locked"; 3590Sstevel@tonic-gate goto err; 3600Sstevel@tonic-gate } 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate if (modes[type] != rw) 3630Sstevel@tonic-gate { 3640Sstevel@tonic-gate errstr = (rw == CRYPTO_READ) ? 3650Sstevel@tonic-gate "CRYPTO_r_unlock on write lock" : 3660Sstevel@tonic-gate "CRYPTO_w_unlock on read lock"; 3670Sstevel@tonic-gate } 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate modes[type] = 0; 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate else 3720Sstevel@tonic-gate { 3730Sstevel@tonic-gate errstr = "invalid mode"; 3740Sstevel@tonic-gate goto err; 3750Sstevel@tonic-gate } 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate err: 3780Sstevel@tonic-gate if (errstr) 3790Sstevel@tonic-gate { 3800Sstevel@tonic-gate /* we cannot use bio_err here */ 3810Sstevel@tonic-gate fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", 3820Sstevel@tonic-gate errstr, mode, type, file, line); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate } 3850Sstevel@tonic-gate 386*2139Sjp161948 3870Sstevel@tonic-gate int main(int argc, char *argv[]) 3880Sstevel@tonic-gate { 3890Sstevel@tonic-gate char *CApath=NULL,*CAfile=NULL; 3900Sstevel@tonic-gate int badop=0; 3910Sstevel@tonic-gate int bio_pair=0; 3920Sstevel@tonic-gate int force=0; 3930Sstevel@tonic-gate int tls1=0,ssl2=0,ssl3=0,ret=1; 3940Sstevel@tonic-gate int client_auth=0; 3950Sstevel@tonic-gate int server_auth=0,i; 396*2139Sjp161948 struct app_verify_arg app_verify_arg = 397*2139Sjp161948 { APP_CALLBACK_STRING, 0, 0, NULL, NULL }; 3980Sstevel@tonic-gate char *server_cert=TEST_SERVER_CERT; 3990Sstevel@tonic-gate char *server_key=NULL; 4000Sstevel@tonic-gate char *client_cert=TEST_CLIENT_CERT; 4010Sstevel@tonic-gate char *client_key=NULL; 402*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 403*2139Sjp161948 char *named_curve = NULL; 404*2139Sjp161948 #endif 4050Sstevel@tonic-gate SSL_CTX *s_ctx=NULL; 4060Sstevel@tonic-gate SSL_CTX *c_ctx=NULL; 4070Sstevel@tonic-gate SSL_METHOD *meth=NULL; 4080Sstevel@tonic-gate SSL *c_ssl,*s_ssl; 4090Sstevel@tonic-gate int number=1,reuse=0; 410*2139Sjp161948 long bytes=256L; 4110Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 4120Sstevel@tonic-gate DH *dh; 4130Sstevel@tonic-gate int dhe1024 = 0, dhe1024dsa = 0; 4140Sstevel@tonic-gate #endif 415*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 416*2139Sjp161948 EC_KEY *ecdh = NULL; 417*2139Sjp161948 #endif 4180Sstevel@tonic-gate int no_dhe = 0; 419*2139Sjp161948 int no_ecdhe = 0; 4200Sstevel@tonic-gate int print_time = 0; 4210Sstevel@tonic-gate clock_t s_time = 0, c_time = 0; 4220Sstevel@tonic-gate int comp = 0; 423*2139Sjp161948 #ifndef OPENSSL_NO_COMP 4240Sstevel@tonic-gate COMP_METHOD *cm = NULL; 425*2139Sjp161948 #endif 426*2139Sjp161948 STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; 427*2139Sjp161948 int test_cipherlist = 0; 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate verbose = 0; 4300Sstevel@tonic-gate debug = 0; 4310Sstevel@tonic-gate cipher = 0; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate CRYPTO_set_locking_callback(lock_dbg_cb); 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate /* enable memory leak checking unless explicitly disabled */ 4380Sstevel@tonic-gate if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) 4390Sstevel@tonic-gate { 4400Sstevel@tonic-gate CRYPTO_malloc_debug_init(); 4410Sstevel@tonic-gate CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 4420Sstevel@tonic-gate } 4430Sstevel@tonic-gate else 4440Sstevel@tonic-gate { 4450Sstevel@tonic-gate /* OPENSSL_DEBUG_MEMORY=off */ 4460Sstevel@tonic-gate CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 4470Sstevel@tonic-gate } 4480Sstevel@tonic-gate CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate RAND_seed(rnd_seed, sizeof rnd_seed); 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE); 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate argc--; 4550Sstevel@tonic-gate argv++; 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate while (argc >= 1) 4580Sstevel@tonic-gate { 4590Sstevel@tonic-gate if (strcmp(*argv,"-server_auth") == 0) 4600Sstevel@tonic-gate server_auth=1; 4610Sstevel@tonic-gate else if (strcmp(*argv,"-client_auth") == 0) 4620Sstevel@tonic-gate client_auth=1; 463*2139Sjp161948 else if (strcmp(*argv,"-proxy_auth") == 0) 464*2139Sjp161948 { 465*2139Sjp161948 if (--argc < 1) goto bad; 466*2139Sjp161948 app_verify_arg.proxy_auth= *(++argv); 467*2139Sjp161948 } 468*2139Sjp161948 else if (strcmp(*argv,"-proxy_cond") == 0) 469*2139Sjp161948 { 470*2139Sjp161948 if (--argc < 1) goto bad; 471*2139Sjp161948 app_verify_arg.proxy_cond= *(++argv); 472*2139Sjp161948 } 4730Sstevel@tonic-gate else if (strcmp(*argv,"-v") == 0) 4740Sstevel@tonic-gate verbose=1; 4750Sstevel@tonic-gate else if (strcmp(*argv,"-d") == 0) 4760Sstevel@tonic-gate debug=1; 4770Sstevel@tonic-gate else if (strcmp(*argv,"-reuse") == 0) 4780Sstevel@tonic-gate reuse=1; 4790Sstevel@tonic-gate else if (strcmp(*argv,"-dhe1024") == 0) 4800Sstevel@tonic-gate { 4810Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 4820Sstevel@tonic-gate dhe1024=1; 4830Sstevel@tonic-gate #else 4840Sstevel@tonic-gate fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n"); 4850Sstevel@tonic-gate #endif 4860Sstevel@tonic-gate } 4870Sstevel@tonic-gate else if (strcmp(*argv,"-dhe1024dsa") == 0) 4880Sstevel@tonic-gate { 4890Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 4900Sstevel@tonic-gate dhe1024dsa=1; 4910Sstevel@tonic-gate #else 4920Sstevel@tonic-gate fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n"); 4930Sstevel@tonic-gate #endif 4940Sstevel@tonic-gate } 4950Sstevel@tonic-gate else if (strcmp(*argv,"-no_dhe") == 0) 4960Sstevel@tonic-gate no_dhe=1; 497*2139Sjp161948 else if (strcmp(*argv,"-no_ecdhe") == 0) 498*2139Sjp161948 no_ecdhe=1; 4990Sstevel@tonic-gate else if (strcmp(*argv,"-ssl2") == 0) 5000Sstevel@tonic-gate ssl2=1; 5010Sstevel@tonic-gate else if (strcmp(*argv,"-tls1") == 0) 5020Sstevel@tonic-gate tls1=1; 5030Sstevel@tonic-gate else if (strcmp(*argv,"-ssl3") == 0) 5040Sstevel@tonic-gate ssl3=1; 5050Sstevel@tonic-gate else if (strncmp(*argv,"-num",4) == 0) 5060Sstevel@tonic-gate { 5070Sstevel@tonic-gate if (--argc < 1) goto bad; 5080Sstevel@tonic-gate number= atoi(*(++argv)); 5090Sstevel@tonic-gate if (number == 0) number=1; 5100Sstevel@tonic-gate } 5110Sstevel@tonic-gate else if (strcmp(*argv,"-bytes") == 0) 5120Sstevel@tonic-gate { 5130Sstevel@tonic-gate if (--argc < 1) goto bad; 5140Sstevel@tonic-gate bytes= atol(*(++argv)); 5150Sstevel@tonic-gate if (bytes == 0L) bytes=1L; 5160Sstevel@tonic-gate i=strlen(argv[0]); 5170Sstevel@tonic-gate if (argv[0][i-1] == 'k') bytes*=1024L; 5180Sstevel@tonic-gate if (argv[0][i-1] == 'm') bytes*=1024L*1024L; 5190Sstevel@tonic-gate } 5200Sstevel@tonic-gate else if (strcmp(*argv,"-cert") == 0) 5210Sstevel@tonic-gate { 5220Sstevel@tonic-gate if (--argc < 1) goto bad; 5230Sstevel@tonic-gate server_cert= *(++argv); 5240Sstevel@tonic-gate } 5250Sstevel@tonic-gate else if (strcmp(*argv,"-s_cert") == 0) 5260Sstevel@tonic-gate { 5270Sstevel@tonic-gate if (--argc < 1) goto bad; 5280Sstevel@tonic-gate server_cert= *(++argv); 5290Sstevel@tonic-gate } 5300Sstevel@tonic-gate else if (strcmp(*argv,"-key") == 0) 5310Sstevel@tonic-gate { 5320Sstevel@tonic-gate if (--argc < 1) goto bad; 5330Sstevel@tonic-gate server_key= *(++argv); 5340Sstevel@tonic-gate } 5350Sstevel@tonic-gate else if (strcmp(*argv,"-s_key") == 0) 5360Sstevel@tonic-gate { 5370Sstevel@tonic-gate if (--argc < 1) goto bad; 5380Sstevel@tonic-gate server_key= *(++argv); 5390Sstevel@tonic-gate } 5400Sstevel@tonic-gate else if (strcmp(*argv,"-c_cert") == 0) 5410Sstevel@tonic-gate { 5420Sstevel@tonic-gate if (--argc < 1) goto bad; 5430Sstevel@tonic-gate client_cert= *(++argv); 5440Sstevel@tonic-gate } 5450Sstevel@tonic-gate else if (strcmp(*argv,"-c_key") == 0) 5460Sstevel@tonic-gate { 5470Sstevel@tonic-gate if (--argc < 1) goto bad; 5480Sstevel@tonic-gate client_key= *(++argv); 5490Sstevel@tonic-gate } 5500Sstevel@tonic-gate else if (strcmp(*argv,"-cipher") == 0) 5510Sstevel@tonic-gate { 5520Sstevel@tonic-gate if (--argc < 1) goto bad; 5530Sstevel@tonic-gate cipher= *(++argv); 5540Sstevel@tonic-gate } 5550Sstevel@tonic-gate else if (strcmp(*argv,"-CApath") == 0) 5560Sstevel@tonic-gate { 5570Sstevel@tonic-gate if (--argc < 1) goto bad; 5580Sstevel@tonic-gate CApath= *(++argv); 5590Sstevel@tonic-gate } 5600Sstevel@tonic-gate else if (strcmp(*argv,"-CAfile") == 0) 5610Sstevel@tonic-gate { 5620Sstevel@tonic-gate if (--argc < 1) goto bad; 5630Sstevel@tonic-gate CAfile= *(++argv); 5640Sstevel@tonic-gate } 5650Sstevel@tonic-gate else if (strcmp(*argv,"-bio_pair") == 0) 5660Sstevel@tonic-gate { 5670Sstevel@tonic-gate bio_pair = 1; 5680Sstevel@tonic-gate } 5690Sstevel@tonic-gate else if (strcmp(*argv,"-f") == 0) 5700Sstevel@tonic-gate { 5710Sstevel@tonic-gate force = 1; 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate else if (strcmp(*argv,"-time") == 0) 5740Sstevel@tonic-gate { 5750Sstevel@tonic-gate print_time = 1; 5760Sstevel@tonic-gate } 5770Sstevel@tonic-gate else if (strcmp(*argv,"-zlib") == 0) 5780Sstevel@tonic-gate { 5790Sstevel@tonic-gate comp = COMP_ZLIB; 5800Sstevel@tonic-gate } 5810Sstevel@tonic-gate else if (strcmp(*argv,"-rle") == 0) 5820Sstevel@tonic-gate { 5830Sstevel@tonic-gate comp = COMP_RLE; 5840Sstevel@tonic-gate } 585*2139Sjp161948 else if (strcmp(*argv,"-named_curve") == 0) 586*2139Sjp161948 { 587*2139Sjp161948 if (--argc < 1) goto bad; 588*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 589*2139Sjp161948 named_curve = *(++argv); 590*2139Sjp161948 #else 591*2139Sjp161948 fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n"); 592*2139Sjp161948 ++argv; 593*2139Sjp161948 #endif 594*2139Sjp161948 } 5950Sstevel@tonic-gate else if (strcmp(*argv,"-app_verify") == 0) 5960Sstevel@tonic-gate { 597*2139Sjp161948 app_verify_arg.app_verify = 1; 598*2139Sjp161948 } 599*2139Sjp161948 else if (strcmp(*argv,"-proxy") == 0) 600*2139Sjp161948 { 601*2139Sjp161948 app_verify_arg.allow_proxy_certs = 1; 602*2139Sjp161948 } 603*2139Sjp161948 else if (strcmp(*argv,"-test_cipherlist") == 0) 604*2139Sjp161948 { 605*2139Sjp161948 test_cipherlist = 1; 6060Sstevel@tonic-gate } 6070Sstevel@tonic-gate else 6080Sstevel@tonic-gate { 6090Sstevel@tonic-gate fprintf(stderr,"unknown option %s\n",*argv); 6100Sstevel@tonic-gate badop=1; 6110Sstevel@tonic-gate break; 6120Sstevel@tonic-gate } 6130Sstevel@tonic-gate argc--; 6140Sstevel@tonic-gate argv++; 6150Sstevel@tonic-gate } 6160Sstevel@tonic-gate if (badop) 6170Sstevel@tonic-gate { 6180Sstevel@tonic-gate bad: 6190Sstevel@tonic-gate sv_usage(); 6200Sstevel@tonic-gate goto end; 6210Sstevel@tonic-gate } 6220Sstevel@tonic-gate 623*2139Sjp161948 if (test_cipherlist == 1) 624*2139Sjp161948 { 625*2139Sjp161948 /* ensure that the cipher list are correctly sorted and exit */ 626*2139Sjp161948 if (do_test_cipherlist() == 0) 627*2139Sjp161948 EXIT(1); 628*2139Sjp161948 ret = 0; 629*2139Sjp161948 goto end; 630*2139Sjp161948 } 631*2139Sjp161948 6320Sstevel@tonic-gate if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) 6330Sstevel@tonic-gate { 6340Sstevel@tonic-gate fprintf(stderr, "This case cannot work. Use -f to perform " 6350Sstevel@tonic-gate "the test anyway (and\n-d to see what happens), " 6360Sstevel@tonic-gate "or add one of -ssl2, -ssl3, -tls1, -reuse\n" 6370Sstevel@tonic-gate "to avoid protocol mismatch.\n"); 6380Sstevel@tonic-gate EXIT(1); 6390Sstevel@tonic-gate } 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate if (print_time) 6420Sstevel@tonic-gate { 6430Sstevel@tonic-gate if (!bio_pair) 6440Sstevel@tonic-gate { 6450Sstevel@tonic-gate fprintf(stderr, "Using BIO pair (-bio_pair)\n"); 6460Sstevel@tonic-gate bio_pair = 1; 6470Sstevel@tonic-gate } 6480Sstevel@tonic-gate if (number < 50 && !force) 6490Sstevel@tonic-gate fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n"); 6500Sstevel@tonic-gate } 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate /* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */ 6530Sstevel@tonic-gate 6540Sstevel@tonic-gate SSL_library_init(); 6550Sstevel@tonic-gate SSL_load_error_strings(); 6560Sstevel@tonic-gate 657*2139Sjp161948 #ifndef OPENSSL_NO_COMP 6580Sstevel@tonic-gate if (comp == COMP_ZLIB) cm = COMP_zlib(); 6590Sstevel@tonic-gate if (comp == COMP_RLE) cm = COMP_rle(); 6600Sstevel@tonic-gate if (cm != NULL) 6610Sstevel@tonic-gate { 6620Sstevel@tonic-gate if (cm->type != NID_undef) 6630Sstevel@tonic-gate { 6640Sstevel@tonic-gate if (SSL_COMP_add_compression_method(comp, cm) != 0) 6650Sstevel@tonic-gate { 6660Sstevel@tonic-gate fprintf(stderr, 6670Sstevel@tonic-gate "Failed to add compression method\n"); 6680Sstevel@tonic-gate ERR_print_errors_fp(stderr); 6690Sstevel@tonic-gate } 6700Sstevel@tonic-gate } 6710Sstevel@tonic-gate else 6720Sstevel@tonic-gate { 6730Sstevel@tonic-gate fprintf(stderr, 6740Sstevel@tonic-gate "Warning: %s compression not supported\n", 6750Sstevel@tonic-gate (comp == COMP_RLE ? "rle" : 6760Sstevel@tonic-gate (comp == COMP_ZLIB ? "zlib" : 6770Sstevel@tonic-gate "unknown"))); 6780Sstevel@tonic-gate ERR_print_errors_fp(stderr); 6790Sstevel@tonic-gate } 6800Sstevel@tonic-gate } 681*2139Sjp161948 ssl_comp_methods = SSL_COMP_get_compression_methods(); 682*2139Sjp161948 fprintf(stderr, "Available compression methods:\n"); 683*2139Sjp161948 { 684*2139Sjp161948 int j, n = sk_SSL_COMP_num(ssl_comp_methods); 685*2139Sjp161948 if (n == 0) 686*2139Sjp161948 fprintf(stderr, " NONE\n"); 687*2139Sjp161948 else 688*2139Sjp161948 for (j = 0; j < n; j++) 689*2139Sjp161948 { 690*2139Sjp161948 SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); 691*2139Sjp161948 fprintf(stderr, " %d: %s\n", c->id, c->name); 692*2139Sjp161948 } 693*2139Sjp161948 } 694*2139Sjp161948 #endif 6950Sstevel@tonic-gate 6960Sstevel@tonic-gate #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) 6970Sstevel@tonic-gate if (ssl2) 6980Sstevel@tonic-gate meth=SSLv2_method(); 6990Sstevel@tonic-gate else 7000Sstevel@tonic-gate if (tls1) 7010Sstevel@tonic-gate meth=TLSv1_method(); 7020Sstevel@tonic-gate else 7030Sstevel@tonic-gate if (ssl3) 7040Sstevel@tonic-gate meth=SSLv3_method(); 7050Sstevel@tonic-gate else 7060Sstevel@tonic-gate meth=SSLv23_method(); 7070Sstevel@tonic-gate #else 7080Sstevel@tonic-gate #ifdef OPENSSL_NO_SSL2 7090Sstevel@tonic-gate meth=SSLv3_method(); 7100Sstevel@tonic-gate #else 7110Sstevel@tonic-gate meth=SSLv2_method(); 7120Sstevel@tonic-gate #endif 7130Sstevel@tonic-gate #endif 7140Sstevel@tonic-gate 7150Sstevel@tonic-gate c_ctx=SSL_CTX_new(meth); 7160Sstevel@tonic-gate s_ctx=SSL_CTX_new(meth); 7170Sstevel@tonic-gate if ((c_ctx == NULL) || (s_ctx == NULL)) 7180Sstevel@tonic-gate { 7190Sstevel@tonic-gate ERR_print_errors(bio_err); 7200Sstevel@tonic-gate goto end; 7210Sstevel@tonic-gate } 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate if (cipher != NULL) 7240Sstevel@tonic-gate { 7250Sstevel@tonic-gate SSL_CTX_set_cipher_list(c_ctx,cipher); 7260Sstevel@tonic-gate SSL_CTX_set_cipher_list(s_ctx,cipher); 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate 7290Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 7300Sstevel@tonic-gate if (!no_dhe) 7310Sstevel@tonic-gate { 7320Sstevel@tonic-gate if (dhe1024dsa) 7330Sstevel@tonic-gate { 7340Sstevel@tonic-gate /* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */ 7350Sstevel@tonic-gate SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); 7360Sstevel@tonic-gate dh=get_dh1024dsa(); 7370Sstevel@tonic-gate } 7380Sstevel@tonic-gate else if (dhe1024) 7390Sstevel@tonic-gate dh=get_dh1024(); 7400Sstevel@tonic-gate else 7410Sstevel@tonic-gate dh=get_dh512(); 7420Sstevel@tonic-gate SSL_CTX_set_tmp_dh(s_ctx,dh); 7430Sstevel@tonic-gate DH_free(dh); 7440Sstevel@tonic-gate } 7450Sstevel@tonic-gate #else 7460Sstevel@tonic-gate (void)no_dhe; 7470Sstevel@tonic-gate #endif 7480Sstevel@tonic-gate 749*2139Sjp161948 #ifndef OPENSSL_NO_ECDH 750*2139Sjp161948 if (!no_ecdhe) 751*2139Sjp161948 { 752*2139Sjp161948 int nid; 753*2139Sjp161948 754*2139Sjp161948 if (named_curve != NULL) 755*2139Sjp161948 { 756*2139Sjp161948 nid = OBJ_sn2nid(named_curve); 757*2139Sjp161948 if (nid == 0) 758*2139Sjp161948 { 759*2139Sjp161948 BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); 760*2139Sjp161948 goto end; 761*2139Sjp161948 } 762*2139Sjp161948 } 763*2139Sjp161948 else 764*2139Sjp161948 nid = NID_sect163r2; 765*2139Sjp161948 766*2139Sjp161948 ecdh = EC_KEY_new_by_curve_name(nid); 767*2139Sjp161948 if (ecdh == NULL) 768*2139Sjp161948 { 769*2139Sjp161948 BIO_printf(bio_err, "unable to create curve\n"); 770*2139Sjp161948 goto end; 771*2139Sjp161948 } 772*2139Sjp161948 773*2139Sjp161948 SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); 774*2139Sjp161948 SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); 775*2139Sjp161948 EC_KEY_free(ecdh); 776*2139Sjp161948 } 777*2139Sjp161948 #else 778*2139Sjp161948 (void)no_ecdhe; 779*2139Sjp161948 #endif 780*2139Sjp161948 7810Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 7820Sstevel@tonic-gate SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb); 7830Sstevel@tonic-gate #endif 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM)) 7860Sstevel@tonic-gate { 7870Sstevel@tonic-gate ERR_print_errors(bio_err); 7880Sstevel@tonic-gate } 7890Sstevel@tonic-gate else if (!SSL_CTX_use_PrivateKey_file(s_ctx, 7900Sstevel@tonic-gate (server_key?server_key:server_cert), SSL_FILETYPE_PEM)) 7910Sstevel@tonic-gate { 7920Sstevel@tonic-gate ERR_print_errors(bio_err); 7930Sstevel@tonic-gate goto end; 7940Sstevel@tonic-gate } 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate if (client_auth) 7970Sstevel@tonic-gate { 7980Sstevel@tonic-gate SSL_CTX_use_certificate_file(c_ctx,client_cert, 7990Sstevel@tonic-gate SSL_FILETYPE_PEM); 8000Sstevel@tonic-gate SSL_CTX_use_PrivateKey_file(c_ctx, 8010Sstevel@tonic-gate (client_key?client_key:client_cert), 8020Sstevel@tonic-gate SSL_FILETYPE_PEM); 8030Sstevel@tonic-gate } 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate if ( (!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) || 8060Sstevel@tonic-gate (!SSL_CTX_set_default_verify_paths(s_ctx)) || 8070Sstevel@tonic-gate (!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) || 8080Sstevel@tonic-gate (!SSL_CTX_set_default_verify_paths(c_ctx))) 8090Sstevel@tonic-gate { 8100Sstevel@tonic-gate /* fprintf(stderr,"SSL_load_verify_locations\n"); */ 8110Sstevel@tonic-gate ERR_print_errors(bio_err); 8120Sstevel@tonic-gate /* goto end; */ 8130Sstevel@tonic-gate } 8140Sstevel@tonic-gate 8150Sstevel@tonic-gate if (client_auth) 8160Sstevel@tonic-gate { 8170Sstevel@tonic-gate BIO_printf(bio_err,"client authentication\n"); 8180Sstevel@tonic-gate SSL_CTX_set_verify(s_ctx, 8190Sstevel@tonic-gate SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 8200Sstevel@tonic-gate verify_callback); 821*2139Sjp161948 SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg); 8220Sstevel@tonic-gate } 8230Sstevel@tonic-gate if (server_auth) 8240Sstevel@tonic-gate { 8250Sstevel@tonic-gate BIO_printf(bio_err,"server authentication\n"); 8260Sstevel@tonic-gate SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER, 8270Sstevel@tonic-gate verify_callback); 828*2139Sjp161948 SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg); 8290Sstevel@tonic-gate } 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate { 8320Sstevel@tonic-gate int session_id_context = 0; 8330Sstevel@tonic-gate SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context); 8340Sstevel@tonic-gate } 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate c_ssl=SSL_new(c_ctx); 8370Sstevel@tonic-gate s_ssl=SSL_new(s_ctx); 8380Sstevel@tonic-gate 8390Sstevel@tonic-gate #ifndef OPENSSL_NO_KRB5 8400Sstevel@tonic-gate if (c_ssl && c_ssl->kssl_ctx) 8410Sstevel@tonic-gate { 8420Sstevel@tonic-gate char localhost[MAXHOSTNAMELEN+2]; 8430Sstevel@tonic-gate 8440Sstevel@tonic-gate if (gethostname(localhost, sizeof localhost-1) == 0) 8450Sstevel@tonic-gate { 8460Sstevel@tonic-gate localhost[sizeof localhost-1]='\0'; 8470Sstevel@tonic-gate if(strlen(localhost) == sizeof localhost-1) 8480Sstevel@tonic-gate { 8490Sstevel@tonic-gate BIO_printf(bio_err,"localhost name too long\n"); 8500Sstevel@tonic-gate goto end; 8510Sstevel@tonic-gate } 8520Sstevel@tonic-gate kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, 8530Sstevel@tonic-gate localhost); 8540Sstevel@tonic-gate } 8550Sstevel@tonic-gate } 8560Sstevel@tonic-gate #endif /* OPENSSL_NO_KRB5 */ 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate for (i=0; i<number; i++) 8590Sstevel@tonic-gate { 8600Sstevel@tonic-gate if (!reuse) SSL_set_session(c_ssl,NULL); 8610Sstevel@tonic-gate if (bio_pair) 8620Sstevel@tonic-gate ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time); 8630Sstevel@tonic-gate else 8640Sstevel@tonic-gate ret=doit(s_ssl,c_ssl,bytes); 8650Sstevel@tonic-gate } 8660Sstevel@tonic-gate 8670Sstevel@tonic-gate if (!verbose) 8680Sstevel@tonic-gate { 8690Sstevel@tonic-gate print_details(c_ssl, ""); 8700Sstevel@tonic-gate } 8710Sstevel@tonic-gate if ((number > 1) || (bytes > 1L)) 8720Sstevel@tonic-gate BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes); 8730Sstevel@tonic-gate if (print_time) 8740Sstevel@tonic-gate { 8750Sstevel@tonic-gate #ifdef CLOCKS_PER_SEC 8760Sstevel@tonic-gate /* "To determine the time in seconds, the value returned 8770Sstevel@tonic-gate * by the clock function should be divided by the value 8780Sstevel@tonic-gate * of the macro CLOCKS_PER_SEC." 8790Sstevel@tonic-gate * -- ISO/IEC 9899 */ 8800Sstevel@tonic-gate BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n" 8810Sstevel@tonic-gate "Approximate total client time: %6.2f s\n", 8820Sstevel@tonic-gate (double)s_time/CLOCKS_PER_SEC, 8830Sstevel@tonic-gate (double)c_time/CLOCKS_PER_SEC); 8840Sstevel@tonic-gate #else 8850Sstevel@tonic-gate /* "`CLOCKS_PER_SEC' undeclared (first use this function)" 8860Sstevel@tonic-gate * -- cc on NeXTstep/OpenStep */ 8870Sstevel@tonic-gate BIO_printf(bio_stdout, 8880Sstevel@tonic-gate "Approximate total server time: %6.2f units\n" 8890Sstevel@tonic-gate "Approximate total client time: %6.2f units\n", 8900Sstevel@tonic-gate (double)s_time, 8910Sstevel@tonic-gate (double)c_time); 8920Sstevel@tonic-gate #endif 8930Sstevel@tonic-gate } 8940Sstevel@tonic-gate 8950Sstevel@tonic-gate SSL_free(s_ssl); 8960Sstevel@tonic-gate SSL_free(c_ssl); 8970Sstevel@tonic-gate 8980Sstevel@tonic-gate end: 8990Sstevel@tonic-gate if (s_ctx != NULL) SSL_CTX_free(s_ctx); 9000Sstevel@tonic-gate if (c_ctx != NULL) SSL_CTX_free(c_ctx); 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate if (bio_stdout != NULL) BIO_free(bio_stdout); 9030Sstevel@tonic-gate 9040Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 9050Sstevel@tonic-gate free_tmp_rsa(); 9060Sstevel@tonic-gate #endif 9070Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE 9080Sstevel@tonic-gate ENGINE_cleanup(); 9090Sstevel@tonic-gate #endif 9100Sstevel@tonic-gate CRYPTO_cleanup_all_ex_data(); 9110Sstevel@tonic-gate ERR_free_strings(); 9120Sstevel@tonic-gate ERR_remove_state(0); 9130Sstevel@tonic-gate EVP_cleanup(); 9140Sstevel@tonic-gate CRYPTO_mem_leaks(bio_err); 9150Sstevel@tonic-gate if (bio_err != NULL) BIO_free(bio_err); 9160Sstevel@tonic-gate EXIT(ret); 917*2139Sjp161948 return ret; 9180Sstevel@tonic-gate } 9190Sstevel@tonic-gate 9200Sstevel@tonic-gate int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, 9210Sstevel@tonic-gate clock_t *s_time, clock_t *c_time) 9220Sstevel@tonic-gate { 9230Sstevel@tonic-gate long cw_num = count, cr_num = count, sw_num = count, sr_num = count; 9240Sstevel@tonic-gate BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; 9250Sstevel@tonic-gate BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL; 9260Sstevel@tonic-gate int ret = 1; 9270Sstevel@tonic-gate 9280Sstevel@tonic-gate size_t bufsiz = 256; /* small buffer for testing */ 9290Sstevel@tonic-gate 9300Sstevel@tonic-gate if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz)) 9310Sstevel@tonic-gate goto err; 9320Sstevel@tonic-gate if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz)) 9330Sstevel@tonic-gate goto err; 9340Sstevel@tonic-gate 9350Sstevel@tonic-gate s_ssl_bio = BIO_new(BIO_f_ssl()); 9360Sstevel@tonic-gate if (!s_ssl_bio) 9370Sstevel@tonic-gate goto err; 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate c_ssl_bio = BIO_new(BIO_f_ssl()); 9400Sstevel@tonic-gate if (!c_ssl_bio) 9410Sstevel@tonic-gate goto err; 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate SSL_set_connect_state(c_ssl); 9440Sstevel@tonic-gate SSL_set_bio(c_ssl, client, client); 9450Sstevel@tonic-gate (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE); 9460Sstevel@tonic-gate 9470Sstevel@tonic-gate SSL_set_accept_state(s_ssl); 9480Sstevel@tonic-gate SSL_set_bio(s_ssl, server, server); 9490Sstevel@tonic-gate (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE); 9500Sstevel@tonic-gate 9510Sstevel@tonic-gate do 9520Sstevel@tonic-gate { 9530Sstevel@tonic-gate /* c_ssl_bio: SSL filter BIO 9540Sstevel@tonic-gate * 9550Sstevel@tonic-gate * client: pseudo-I/O for SSL library 9560Sstevel@tonic-gate * 9570Sstevel@tonic-gate * client_io: client's SSL communication; usually to be 9580Sstevel@tonic-gate * relayed over some I/O facility, but in this 9590Sstevel@tonic-gate * test program, we're the server, too: 9600Sstevel@tonic-gate * 9610Sstevel@tonic-gate * server_io: server's SSL communication 9620Sstevel@tonic-gate * 9630Sstevel@tonic-gate * server: pseudo-I/O for SSL library 9640Sstevel@tonic-gate * 9650Sstevel@tonic-gate * s_ssl_bio: SSL filter BIO 9660Sstevel@tonic-gate * 9670Sstevel@tonic-gate * The client and the server each employ a "BIO pair": 9680Sstevel@tonic-gate * client + client_io, server + server_io. 9690Sstevel@tonic-gate * BIO pairs are symmetric. A BIO pair behaves similar 9700Sstevel@tonic-gate * to a non-blocking socketpair (but both endpoints must 9710Sstevel@tonic-gate * be handled by the same thread). 9720Sstevel@tonic-gate * [Here we could connect client and server to the ends 9730Sstevel@tonic-gate * of a single BIO pair, but then this code would be less 9740Sstevel@tonic-gate * suitable as an example for BIO pairs in general.] 9750Sstevel@tonic-gate * 9760Sstevel@tonic-gate * Useful functions for querying the state of BIO pair endpoints: 9770Sstevel@tonic-gate * 9780Sstevel@tonic-gate * BIO_ctrl_pending(bio) number of bytes we can read now 9790Sstevel@tonic-gate * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil 9800Sstevel@tonic-gate * other side's read attempt 9810Sstevel@tonic-gate * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now 9820Sstevel@tonic-gate * 9830Sstevel@tonic-gate * ..._read_request is never more than ..._write_guarantee; 9840Sstevel@tonic-gate * it depends on the application which one you should use. 9850Sstevel@tonic-gate */ 9860Sstevel@tonic-gate 9870Sstevel@tonic-gate /* We have non-blocking behaviour throughout this test program, but 9880Sstevel@tonic-gate * can be sure that there is *some* progress in each iteration; so 9890Sstevel@tonic-gate * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE 9900Sstevel@tonic-gate * -- we just try everything in each iteration 9910Sstevel@tonic-gate */ 9920Sstevel@tonic-gate 9930Sstevel@tonic-gate { 9940Sstevel@tonic-gate /* CLIENT */ 9950Sstevel@tonic-gate 9960Sstevel@tonic-gate MS_STATIC char cbuf[1024*8]; 9970Sstevel@tonic-gate int i, r; 9980Sstevel@tonic-gate clock_t c_clock = clock(); 9990Sstevel@tonic-gate 10000Sstevel@tonic-gate memset(cbuf, 0, sizeof(cbuf)); 10010Sstevel@tonic-gate 10020Sstevel@tonic-gate if (debug) 10030Sstevel@tonic-gate if (SSL_in_init(c_ssl)) 10040Sstevel@tonic-gate printf("client waiting in SSL_connect - %s\n", 10050Sstevel@tonic-gate SSL_state_string_long(c_ssl)); 10060Sstevel@tonic-gate 10070Sstevel@tonic-gate if (cw_num > 0) 10080Sstevel@tonic-gate { 10090Sstevel@tonic-gate /* Write to server. */ 10100Sstevel@tonic-gate 10110Sstevel@tonic-gate if (cw_num > (long)sizeof cbuf) 10120Sstevel@tonic-gate i = sizeof cbuf; 10130Sstevel@tonic-gate else 10140Sstevel@tonic-gate i = (int)cw_num; 10150Sstevel@tonic-gate r = BIO_write(c_ssl_bio, cbuf, i); 10160Sstevel@tonic-gate if (r < 0) 10170Sstevel@tonic-gate { 10180Sstevel@tonic-gate if (!BIO_should_retry(c_ssl_bio)) 10190Sstevel@tonic-gate { 10200Sstevel@tonic-gate fprintf(stderr,"ERROR in CLIENT\n"); 10210Sstevel@tonic-gate goto err; 10220Sstevel@tonic-gate } 10230Sstevel@tonic-gate /* BIO_should_retry(...) can just be ignored here. 10240Sstevel@tonic-gate * The library expects us to call BIO_write with 10250Sstevel@tonic-gate * the same arguments again, and that's what we will 10260Sstevel@tonic-gate * do in the next iteration. */ 10270Sstevel@tonic-gate } 10280Sstevel@tonic-gate else if (r == 0) 10290Sstevel@tonic-gate { 10300Sstevel@tonic-gate fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 10310Sstevel@tonic-gate goto err; 10320Sstevel@tonic-gate } 10330Sstevel@tonic-gate else 10340Sstevel@tonic-gate { 10350Sstevel@tonic-gate if (debug) 10360Sstevel@tonic-gate printf("client wrote %d\n", r); 10370Sstevel@tonic-gate cw_num -= r; 10380Sstevel@tonic-gate } 10390Sstevel@tonic-gate } 10400Sstevel@tonic-gate 10410Sstevel@tonic-gate if (cr_num > 0) 10420Sstevel@tonic-gate { 10430Sstevel@tonic-gate /* Read from server. */ 10440Sstevel@tonic-gate 10450Sstevel@tonic-gate r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf)); 10460Sstevel@tonic-gate if (r < 0) 10470Sstevel@tonic-gate { 10480Sstevel@tonic-gate if (!BIO_should_retry(c_ssl_bio)) 10490Sstevel@tonic-gate { 10500Sstevel@tonic-gate fprintf(stderr,"ERROR in CLIENT\n"); 10510Sstevel@tonic-gate goto err; 10520Sstevel@tonic-gate } 10530Sstevel@tonic-gate /* Again, "BIO_should_retry" can be ignored. */ 10540Sstevel@tonic-gate } 10550Sstevel@tonic-gate else if (r == 0) 10560Sstevel@tonic-gate { 10570Sstevel@tonic-gate fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 10580Sstevel@tonic-gate goto err; 10590Sstevel@tonic-gate } 10600Sstevel@tonic-gate else 10610Sstevel@tonic-gate { 10620Sstevel@tonic-gate if (debug) 10630Sstevel@tonic-gate printf("client read %d\n", r); 10640Sstevel@tonic-gate cr_num -= r; 10650Sstevel@tonic-gate } 10660Sstevel@tonic-gate } 10670Sstevel@tonic-gate 10680Sstevel@tonic-gate /* c_time and s_time increments will typically be very small 10690Sstevel@tonic-gate * (depending on machine speed and clock tick intervals), 10700Sstevel@tonic-gate * but sampling over a large number of connections should 10710Sstevel@tonic-gate * result in fairly accurate figures. We cannot guarantee 10720Sstevel@tonic-gate * a lot, however -- if each connection lasts for exactly 10730Sstevel@tonic-gate * one clock tick, it will be counted only for the client 10740Sstevel@tonic-gate * or only for the server or even not at all. 10750Sstevel@tonic-gate */ 10760Sstevel@tonic-gate *c_time += (clock() - c_clock); 10770Sstevel@tonic-gate } 10780Sstevel@tonic-gate 10790Sstevel@tonic-gate { 10800Sstevel@tonic-gate /* SERVER */ 10810Sstevel@tonic-gate 10820Sstevel@tonic-gate MS_STATIC char sbuf[1024*8]; 10830Sstevel@tonic-gate int i, r; 10840Sstevel@tonic-gate clock_t s_clock = clock(); 10850Sstevel@tonic-gate 10860Sstevel@tonic-gate memset(sbuf, 0, sizeof(sbuf)); 10870Sstevel@tonic-gate 10880Sstevel@tonic-gate if (debug) 10890Sstevel@tonic-gate if (SSL_in_init(s_ssl)) 10900Sstevel@tonic-gate printf("server waiting in SSL_accept - %s\n", 10910Sstevel@tonic-gate SSL_state_string_long(s_ssl)); 10920Sstevel@tonic-gate 10930Sstevel@tonic-gate if (sw_num > 0) 10940Sstevel@tonic-gate { 10950Sstevel@tonic-gate /* Write to client. */ 10960Sstevel@tonic-gate 10970Sstevel@tonic-gate if (sw_num > (long)sizeof sbuf) 10980Sstevel@tonic-gate i = sizeof sbuf; 10990Sstevel@tonic-gate else 11000Sstevel@tonic-gate i = (int)sw_num; 11010Sstevel@tonic-gate r = BIO_write(s_ssl_bio, sbuf, i); 11020Sstevel@tonic-gate if (r < 0) 11030Sstevel@tonic-gate { 11040Sstevel@tonic-gate if (!BIO_should_retry(s_ssl_bio)) 11050Sstevel@tonic-gate { 11060Sstevel@tonic-gate fprintf(stderr,"ERROR in SERVER\n"); 11070Sstevel@tonic-gate goto err; 11080Sstevel@tonic-gate } 11090Sstevel@tonic-gate /* Ignore "BIO_should_retry". */ 11100Sstevel@tonic-gate } 11110Sstevel@tonic-gate else if (r == 0) 11120Sstevel@tonic-gate { 11130Sstevel@tonic-gate fprintf(stderr,"SSL SERVER STARTUP FAILED\n"); 11140Sstevel@tonic-gate goto err; 11150Sstevel@tonic-gate } 11160Sstevel@tonic-gate else 11170Sstevel@tonic-gate { 11180Sstevel@tonic-gate if (debug) 11190Sstevel@tonic-gate printf("server wrote %d\n", r); 11200Sstevel@tonic-gate sw_num -= r; 11210Sstevel@tonic-gate } 11220Sstevel@tonic-gate } 11230Sstevel@tonic-gate 11240Sstevel@tonic-gate if (sr_num > 0) 11250Sstevel@tonic-gate { 11260Sstevel@tonic-gate /* Read from client. */ 11270Sstevel@tonic-gate 11280Sstevel@tonic-gate r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf)); 11290Sstevel@tonic-gate if (r < 0) 11300Sstevel@tonic-gate { 11310Sstevel@tonic-gate if (!BIO_should_retry(s_ssl_bio)) 11320Sstevel@tonic-gate { 11330Sstevel@tonic-gate fprintf(stderr,"ERROR in SERVER\n"); 11340Sstevel@tonic-gate goto err; 11350Sstevel@tonic-gate } 11360Sstevel@tonic-gate /* blah, blah */ 11370Sstevel@tonic-gate } 11380Sstevel@tonic-gate else if (r == 0) 11390Sstevel@tonic-gate { 11400Sstevel@tonic-gate fprintf(stderr,"SSL SERVER STARTUP FAILED\n"); 11410Sstevel@tonic-gate goto err; 11420Sstevel@tonic-gate } 11430Sstevel@tonic-gate else 11440Sstevel@tonic-gate { 11450Sstevel@tonic-gate if (debug) 11460Sstevel@tonic-gate printf("server read %d\n", r); 11470Sstevel@tonic-gate sr_num -= r; 11480Sstevel@tonic-gate } 11490Sstevel@tonic-gate } 11500Sstevel@tonic-gate 11510Sstevel@tonic-gate *s_time += (clock() - s_clock); 11520Sstevel@tonic-gate } 11530Sstevel@tonic-gate 11540Sstevel@tonic-gate { 11550Sstevel@tonic-gate /* "I/O" BETWEEN CLIENT AND SERVER. */ 11560Sstevel@tonic-gate 11570Sstevel@tonic-gate size_t r1, r2; 11580Sstevel@tonic-gate BIO *io1 = server_io, *io2 = client_io; 11590Sstevel@tonic-gate /* we use the non-copying interface for io1 11600Sstevel@tonic-gate * and the standard BIO_write/BIO_read interface for io2 11610Sstevel@tonic-gate */ 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate static int prev_progress = 1; 11640Sstevel@tonic-gate int progress = 0; 11650Sstevel@tonic-gate 11660Sstevel@tonic-gate /* io1 to io2 */ 11670Sstevel@tonic-gate do 11680Sstevel@tonic-gate { 11690Sstevel@tonic-gate size_t num; 11700Sstevel@tonic-gate int r; 11710Sstevel@tonic-gate 11720Sstevel@tonic-gate r1 = BIO_ctrl_pending(io1); 11730Sstevel@tonic-gate r2 = BIO_ctrl_get_write_guarantee(io2); 11740Sstevel@tonic-gate 11750Sstevel@tonic-gate num = r1; 11760Sstevel@tonic-gate if (r2 < num) 11770Sstevel@tonic-gate num = r2; 11780Sstevel@tonic-gate if (num) 11790Sstevel@tonic-gate { 11800Sstevel@tonic-gate char *dataptr; 11810Sstevel@tonic-gate 11820Sstevel@tonic-gate if (INT_MAX < num) /* yeah, right */ 11830Sstevel@tonic-gate num = INT_MAX; 11840Sstevel@tonic-gate 11850Sstevel@tonic-gate r = BIO_nread(io1, &dataptr, (int)num); 11860Sstevel@tonic-gate assert(r > 0); 11870Sstevel@tonic-gate assert(r <= (int)num); 11880Sstevel@tonic-gate /* possibly r < num (non-contiguous data) */ 11890Sstevel@tonic-gate num = r; 11900Sstevel@tonic-gate r = BIO_write(io2, dataptr, (int)num); 11910Sstevel@tonic-gate if (r != (int)num) /* can't happen */ 11920Sstevel@tonic-gate { 11930Sstevel@tonic-gate fprintf(stderr, "ERROR: BIO_write could not write " 11940Sstevel@tonic-gate "BIO_ctrl_get_write_guarantee() bytes"); 11950Sstevel@tonic-gate goto err; 11960Sstevel@tonic-gate } 11970Sstevel@tonic-gate progress = 1; 11980Sstevel@tonic-gate 11990Sstevel@tonic-gate if (debug) 12000Sstevel@tonic-gate printf((io1 == client_io) ? 12010Sstevel@tonic-gate "C->S relaying: %d bytes\n" : 12020Sstevel@tonic-gate "S->C relaying: %d bytes\n", 12030Sstevel@tonic-gate (int)num); 12040Sstevel@tonic-gate } 12050Sstevel@tonic-gate } 12060Sstevel@tonic-gate while (r1 && r2); 12070Sstevel@tonic-gate 12080Sstevel@tonic-gate /* io2 to io1 */ 12090Sstevel@tonic-gate { 12100Sstevel@tonic-gate size_t num; 12110Sstevel@tonic-gate int r; 12120Sstevel@tonic-gate 12130Sstevel@tonic-gate r1 = BIO_ctrl_pending(io2); 12140Sstevel@tonic-gate r2 = BIO_ctrl_get_read_request(io1); 12150Sstevel@tonic-gate /* here we could use ..._get_write_guarantee instead of 12160Sstevel@tonic-gate * ..._get_read_request, but by using the latter 12170Sstevel@tonic-gate * we test restartability of the SSL implementation 12180Sstevel@tonic-gate * more thoroughly */ 12190Sstevel@tonic-gate num = r1; 12200Sstevel@tonic-gate if (r2 < num) 12210Sstevel@tonic-gate num = r2; 12220Sstevel@tonic-gate if (num) 12230Sstevel@tonic-gate { 12240Sstevel@tonic-gate char *dataptr; 12250Sstevel@tonic-gate 12260Sstevel@tonic-gate if (INT_MAX < num) 12270Sstevel@tonic-gate num = INT_MAX; 12280Sstevel@tonic-gate 12290Sstevel@tonic-gate if (num > 1) 12300Sstevel@tonic-gate --num; /* test restartability even more thoroughly */ 12310Sstevel@tonic-gate 12320Sstevel@tonic-gate r = BIO_nwrite0(io1, &dataptr); 12330Sstevel@tonic-gate assert(r > 0); 12340Sstevel@tonic-gate if (r < (int)num) 12350Sstevel@tonic-gate num = r; 12360Sstevel@tonic-gate r = BIO_read(io2, dataptr, (int)num); 12370Sstevel@tonic-gate if (r != (int)num) /* can't happen */ 12380Sstevel@tonic-gate { 12390Sstevel@tonic-gate fprintf(stderr, "ERROR: BIO_read could not read " 12400Sstevel@tonic-gate "BIO_ctrl_pending() bytes"); 12410Sstevel@tonic-gate goto err; 12420Sstevel@tonic-gate } 12430Sstevel@tonic-gate progress = 1; 12440Sstevel@tonic-gate r = BIO_nwrite(io1, &dataptr, (int)num); 12450Sstevel@tonic-gate if (r != (int)num) /* can't happen */ 12460Sstevel@tonic-gate { 12470Sstevel@tonic-gate fprintf(stderr, "ERROR: BIO_nwrite() did not accept " 12480Sstevel@tonic-gate "BIO_nwrite0() bytes"); 12490Sstevel@tonic-gate goto err; 12500Sstevel@tonic-gate } 12510Sstevel@tonic-gate 12520Sstevel@tonic-gate if (debug) 12530Sstevel@tonic-gate printf((io2 == client_io) ? 12540Sstevel@tonic-gate "C->S relaying: %d bytes\n" : 12550Sstevel@tonic-gate "S->C relaying: %d bytes\n", 12560Sstevel@tonic-gate (int)num); 12570Sstevel@tonic-gate } 12580Sstevel@tonic-gate } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */ 12590Sstevel@tonic-gate 12600Sstevel@tonic-gate if (!progress && !prev_progress) 12610Sstevel@tonic-gate if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) 12620Sstevel@tonic-gate { 12630Sstevel@tonic-gate fprintf(stderr, "ERROR: got stuck\n"); 12640Sstevel@tonic-gate if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0) 12650Sstevel@tonic-gate { 12660Sstevel@tonic-gate fprintf(stderr, "This can happen for SSL2 because " 12670Sstevel@tonic-gate "CLIENT-FINISHED and SERVER-VERIFY are written \n" 12680Sstevel@tonic-gate "concurrently ..."); 12690Sstevel@tonic-gate if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0 12700Sstevel@tonic-gate && strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0) 12710Sstevel@tonic-gate { 12720Sstevel@tonic-gate fprintf(stderr, " ok.\n"); 12730Sstevel@tonic-gate goto end; 12740Sstevel@tonic-gate } 12750Sstevel@tonic-gate } 12760Sstevel@tonic-gate fprintf(stderr, " ERROR.\n"); 12770Sstevel@tonic-gate goto err; 12780Sstevel@tonic-gate } 12790Sstevel@tonic-gate prev_progress = progress; 12800Sstevel@tonic-gate } 12810Sstevel@tonic-gate } 12820Sstevel@tonic-gate while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); 12830Sstevel@tonic-gate 12840Sstevel@tonic-gate if (verbose) 12850Sstevel@tonic-gate print_details(c_ssl, "DONE via BIO pair: "); 12860Sstevel@tonic-gate end: 12870Sstevel@tonic-gate ret = 0; 12880Sstevel@tonic-gate 12890Sstevel@tonic-gate err: 12900Sstevel@tonic-gate ERR_print_errors(bio_err); 12910Sstevel@tonic-gate 12920Sstevel@tonic-gate if (server) 12930Sstevel@tonic-gate BIO_free(server); 12940Sstevel@tonic-gate if (server_io) 12950Sstevel@tonic-gate BIO_free(server_io); 12960Sstevel@tonic-gate if (client) 12970Sstevel@tonic-gate BIO_free(client); 12980Sstevel@tonic-gate if (client_io) 12990Sstevel@tonic-gate BIO_free(client_io); 13000Sstevel@tonic-gate if (s_ssl_bio) 13010Sstevel@tonic-gate BIO_free(s_ssl_bio); 13020Sstevel@tonic-gate if (c_ssl_bio) 13030Sstevel@tonic-gate BIO_free(c_ssl_bio); 13040Sstevel@tonic-gate 13050Sstevel@tonic-gate return ret; 13060Sstevel@tonic-gate } 13070Sstevel@tonic-gate 13080Sstevel@tonic-gate 13090Sstevel@tonic-gate #define W_READ 1 13100Sstevel@tonic-gate #define W_WRITE 2 13110Sstevel@tonic-gate #define C_DONE 1 13120Sstevel@tonic-gate #define S_DONE 2 13130Sstevel@tonic-gate 13140Sstevel@tonic-gate int doit(SSL *s_ssl, SSL *c_ssl, long count) 13150Sstevel@tonic-gate { 13160Sstevel@tonic-gate MS_STATIC char cbuf[1024*8],sbuf[1024*8]; 13170Sstevel@tonic-gate long cw_num=count,cr_num=count; 13180Sstevel@tonic-gate long sw_num=count,sr_num=count; 13190Sstevel@tonic-gate int ret=1; 13200Sstevel@tonic-gate BIO *c_to_s=NULL; 13210Sstevel@tonic-gate BIO *s_to_c=NULL; 13220Sstevel@tonic-gate BIO *c_bio=NULL; 13230Sstevel@tonic-gate BIO *s_bio=NULL; 13240Sstevel@tonic-gate int c_r,c_w,s_r,s_w; 13250Sstevel@tonic-gate int c_want,s_want; 13260Sstevel@tonic-gate int i,j; 13270Sstevel@tonic-gate int done=0; 13280Sstevel@tonic-gate int c_write,s_write; 13290Sstevel@tonic-gate int do_server=0,do_client=0; 13300Sstevel@tonic-gate 13310Sstevel@tonic-gate memset(cbuf,0,sizeof(cbuf)); 13320Sstevel@tonic-gate memset(sbuf,0,sizeof(sbuf)); 13330Sstevel@tonic-gate 13340Sstevel@tonic-gate c_to_s=BIO_new(BIO_s_mem()); 13350Sstevel@tonic-gate s_to_c=BIO_new(BIO_s_mem()); 13360Sstevel@tonic-gate if ((s_to_c == NULL) || (c_to_s == NULL)) 13370Sstevel@tonic-gate { 13380Sstevel@tonic-gate ERR_print_errors(bio_err); 13390Sstevel@tonic-gate goto err; 13400Sstevel@tonic-gate } 13410Sstevel@tonic-gate 13420Sstevel@tonic-gate c_bio=BIO_new(BIO_f_ssl()); 13430Sstevel@tonic-gate s_bio=BIO_new(BIO_f_ssl()); 13440Sstevel@tonic-gate if ((c_bio == NULL) || (s_bio == NULL)) 13450Sstevel@tonic-gate { 13460Sstevel@tonic-gate ERR_print_errors(bio_err); 13470Sstevel@tonic-gate goto err; 13480Sstevel@tonic-gate } 13490Sstevel@tonic-gate 13500Sstevel@tonic-gate SSL_set_connect_state(c_ssl); 13510Sstevel@tonic-gate SSL_set_bio(c_ssl,s_to_c,c_to_s); 13520Sstevel@tonic-gate BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE); 13530Sstevel@tonic-gate 13540Sstevel@tonic-gate SSL_set_accept_state(s_ssl); 13550Sstevel@tonic-gate SSL_set_bio(s_ssl,c_to_s,s_to_c); 13560Sstevel@tonic-gate BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE); 13570Sstevel@tonic-gate 13580Sstevel@tonic-gate c_r=0; s_r=1; 13590Sstevel@tonic-gate c_w=1; s_w=0; 13600Sstevel@tonic-gate c_want=W_WRITE; 13610Sstevel@tonic-gate s_want=0; 13620Sstevel@tonic-gate c_write=1,s_write=0; 13630Sstevel@tonic-gate 13640Sstevel@tonic-gate /* We can always do writes */ 13650Sstevel@tonic-gate for (;;) 13660Sstevel@tonic-gate { 13670Sstevel@tonic-gate do_server=0; 13680Sstevel@tonic-gate do_client=0; 13690Sstevel@tonic-gate 13700Sstevel@tonic-gate i=(int)BIO_pending(s_bio); 13710Sstevel@tonic-gate if ((i && s_r) || s_w) do_server=1; 13720Sstevel@tonic-gate 13730Sstevel@tonic-gate i=(int)BIO_pending(c_bio); 13740Sstevel@tonic-gate if ((i && c_r) || c_w) do_client=1; 13750Sstevel@tonic-gate 13760Sstevel@tonic-gate if (do_server && debug) 13770Sstevel@tonic-gate { 13780Sstevel@tonic-gate if (SSL_in_init(s_ssl)) 13790Sstevel@tonic-gate printf("server waiting in SSL_accept - %s\n", 13800Sstevel@tonic-gate SSL_state_string_long(s_ssl)); 13810Sstevel@tonic-gate /* else if (s_write) 13820Sstevel@tonic-gate printf("server:SSL_write()\n"); 13830Sstevel@tonic-gate else 13840Sstevel@tonic-gate printf("server:SSL_read()\n"); */ 13850Sstevel@tonic-gate } 13860Sstevel@tonic-gate 13870Sstevel@tonic-gate if (do_client && debug) 13880Sstevel@tonic-gate { 13890Sstevel@tonic-gate if (SSL_in_init(c_ssl)) 13900Sstevel@tonic-gate printf("client waiting in SSL_connect - %s\n", 13910Sstevel@tonic-gate SSL_state_string_long(c_ssl)); 13920Sstevel@tonic-gate /* else if (c_write) 13930Sstevel@tonic-gate printf("client:SSL_write()\n"); 13940Sstevel@tonic-gate else 13950Sstevel@tonic-gate printf("client:SSL_read()\n"); */ 13960Sstevel@tonic-gate } 13970Sstevel@tonic-gate 13980Sstevel@tonic-gate if (!do_client && !do_server) 13990Sstevel@tonic-gate { 14000Sstevel@tonic-gate fprintf(stdout,"ERROR IN STARTUP\n"); 14010Sstevel@tonic-gate ERR_print_errors(bio_err); 14020Sstevel@tonic-gate break; 14030Sstevel@tonic-gate } 14040Sstevel@tonic-gate if (do_client && !(done & C_DONE)) 14050Sstevel@tonic-gate { 14060Sstevel@tonic-gate if (c_write) 14070Sstevel@tonic-gate { 1408*2139Sjp161948 j = (cw_num > (long)sizeof(cbuf)) ? 1409*2139Sjp161948 (int)sizeof(cbuf) : (int)cw_num; 14100Sstevel@tonic-gate i=BIO_write(c_bio,cbuf,j); 14110Sstevel@tonic-gate if (i < 0) 14120Sstevel@tonic-gate { 14130Sstevel@tonic-gate c_r=0; 14140Sstevel@tonic-gate c_w=0; 14150Sstevel@tonic-gate if (BIO_should_retry(c_bio)) 14160Sstevel@tonic-gate { 14170Sstevel@tonic-gate if (BIO_should_read(c_bio)) 14180Sstevel@tonic-gate c_r=1; 14190Sstevel@tonic-gate if (BIO_should_write(c_bio)) 14200Sstevel@tonic-gate c_w=1; 14210Sstevel@tonic-gate } 14220Sstevel@tonic-gate else 14230Sstevel@tonic-gate { 14240Sstevel@tonic-gate fprintf(stderr,"ERROR in CLIENT\n"); 14250Sstevel@tonic-gate ERR_print_errors(bio_err); 14260Sstevel@tonic-gate goto err; 14270Sstevel@tonic-gate } 14280Sstevel@tonic-gate } 14290Sstevel@tonic-gate else if (i == 0) 14300Sstevel@tonic-gate { 14310Sstevel@tonic-gate fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 14320Sstevel@tonic-gate goto err; 14330Sstevel@tonic-gate } 14340Sstevel@tonic-gate else 14350Sstevel@tonic-gate { 14360Sstevel@tonic-gate if (debug) 14370Sstevel@tonic-gate printf("client wrote %d\n",i); 14380Sstevel@tonic-gate /* ok */ 14390Sstevel@tonic-gate s_r=1; 14400Sstevel@tonic-gate c_write=0; 14410Sstevel@tonic-gate cw_num-=i; 14420Sstevel@tonic-gate } 14430Sstevel@tonic-gate } 14440Sstevel@tonic-gate else 14450Sstevel@tonic-gate { 14460Sstevel@tonic-gate i=BIO_read(c_bio,cbuf,sizeof(cbuf)); 14470Sstevel@tonic-gate if (i < 0) 14480Sstevel@tonic-gate { 14490Sstevel@tonic-gate c_r=0; 14500Sstevel@tonic-gate c_w=0; 14510Sstevel@tonic-gate if (BIO_should_retry(c_bio)) 14520Sstevel@tonic-gate { 14530Sstevel@tonic-gate if (BIO_should_read(c_bio)) 14540Sstevel@tonic-gate c_r=1; 14550Sstevel@tonic-gate if (BIO_should_write(c_bio)) 14560Sstevel@tonic-gate c_w=1; 14570Sstevel@tonic-gate } 14580Sstevel@tonic-gate else 14590Sstevel@tonic-gate { 14600Sstevel@tonic-gate fprintf(stderr,"ERROR in CLIENT\n"); 14610Sstevel@tonic-gate ERR_print_errors(bio_err); 14620Sstevel@tonic-gate goto err; 14630Sstevel@tonic-gate } 14640Sstevel@tonic-gate } 14650Sstevel@tonic-gate else if (i == 0) 14660Sstevel@tonic-gate { 14670Sstevel@tonic-gate fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 14680Sstevel@tonic-gate goto err; 14690Sstevel@tonic-gate } 14700Sstevel@tonic-gate else 14710Sstevel@tonic-gate { 14720Sstevel@tonic-gate if (debug) 14730Sstevel@tonic-gate printf("client read %d\n",i); 14740Sstevel@tonic-gate cr_num-=i; 14750Sstevel@tonic-gate if (sw_num > 0) 14760Sstevel@tonic-gate { 14770Sstevel@tonic-gate s_write=1; 14780Sstevel@tonic-gate s_w=1; 14790Sstevel@tonic-gate } 14800Sstevel@tonic-gate if (cr_num <= 0) 14810Sstevel@tonic-gate { 14820Sstevel@tonic-gate s_write=1; 14830Sstevel@tonic-gate s_w=1; 14840Sstevel@tonic-gate done=S_DONE|C_DONE; 14850Sstevel@tonic-gate } 14860Sstevel@tonic-gate } 14870Sstevel@tonic-gate } 14880Sstevel@tonic-gate } 14890Sstevel@tonic-gate 14900Sstevel@tonic-gate if (do_server && !(done & S_DONE)) 14910Sstevel@tonic-gate { 14920Sstevel@tonic-gate if (!s_write) 14930Sstevel@tonic-gate { 14940Sstevel@tonic-gate i=BIO_read(s_bio,sbuf,sizeof(cbuf)); 14950Sstevel@tonic-gate if (i < 0) 14960Sstevel@tonic-gate { 14970Sstevel@tonic-gate s_r=0; 14980Sstevel@tonic-gate s_w=0; 14990Sstevel@tonic-gate if (BIO_should_retry(s_bio)) 15000Sstevel@tonic-gate { 15010Sstevel@tonic-gate if (BIO_should_read(s_bio)) 15020Sstevel@tonic-gate s_r=1; 15030Sstevel@tonic-gate if (BIO_should_write(s_bio)) 15040Sstevel@tonic-gate s_w=1; 15050Sstevel@tonic-gate } 15060Sstevel@tonic-gate else 15070Sstevel@tonic-gate { 15080Sstevel@tonic-gate fprintf(stderr,"ERROR in SERVER\n"); 15090Sstevel@tonic-gate ERR_print_errors(bio_err); 15100Sstevel@tonic-gate goto err; 15110Sstevel@tonic-gate } 15120Sstevel@tonic-gate } 15130Sstevel@tonic-gate else if (i == 0) 15140Sstevel@tonic-gate { 15150Sstevel@tonic-gate ERR_print_errors(bio_err); 15160Sstevel@tonic-gate fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n"); 15170Sstevel@tonic-gate goto err; 15180Sstevel@tonic-gate } 15190Sstevel@tonic-gate else 15200Sstevel@tonic-gate { 15210Sstevel@tonic-gate if (debug) 15220Sstevel@tonic-gate printf("server read %d\n",i); 15230Sstevel@tonic-gate sr_num-=i; 15240Sstevel@tonic-gate if (cw_num > 0) 15250Sstevel@tonic-gate { 15260Sstevel@tonic-gate c_write=1; 15270Sstevel@tonic-gate c_w=1; 15280Sstevel@tonic-gate } 15290Sstevel@tonic-gate if (sr_num <= 0) 15300Sstevel@tonic-gate { 15310Sstevel@tonic-gate s_write=1; 15320Sstevel@tonic-gate s_w=1; 15330Sstevel@tonic-gate c_write=0; 15340Sstevel@tonic-gate } 15350Sstevel@tonic-gate } 15360Sstevel@tonic-gate } 15370Sstevel@tonic-gate else 15380Sstevel@tonic-gate { 1539*2139Sjp161948 j = (sw_num > (long)sizeof(sbuf)) ? 1540*2139Sjp161948 (int)sizeof(sbuf) : (int)sw_num; 15410Sstevel@tonic-gate i=BIO_write(s_bio,sbuf,j); 15420Sstevel@tonic-gate if (i < 0) 15430Sstevel@tonic-gate { 15440Sstevel@tonic-gate s_r=0; 15450Sstevel@tonic-gate s_w=0; 15460Sstevel@tonic-gate if (BIO_should_retry(s_bio)) 15470Sstevel@tonic-gate { 15480Sstevel@tonic-gate if (BIO_should_read(s_bio)) 15490Sstevel@tonic-gate s_r=1; 15500Sstevel@tonic-gate if (BIO_should_write(s_bio)) 15510Sstevel@tonic-gate s_w=1; 15520Sstevel@tonic-gate } 15530Sstevel@tonic-gate else 15540Sstevel@tonic-gate { 15550Sstevel@tonic-gate fprintf(stderr,"ERROR in SERVER\n"); 15560Sstevel@tonic-gate ERR_print_errors(bio_err); 15570Sstevel@tonic-gate goto err; 15580Sstevel@tonic-gate } 15590Sstevel@tonic-gate } 15600Sstevel@tonic-gate else if (i == 0) 15610Sstevel@tonic-gate { 15620Sstevel@tonic-gate ERR_print_errors(bio_err); 15630Sstevel@tonic-gate fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n"); 15640Sstevel@tonic-gate goto err; 15650Sstevel@tonic-gate } 15660Sstevel@tonic-gate else 15670Sstevel@tonic-gate { 15680Sstevel@tonic-gate if (debug) 15690Sstevel@tonic-gate printf("server wrote %d\n",i); 15700Sstevel@tonic-gate sw_num-=i; 15710Sstevel@tonic-gate s_write=0; 15720Sstevel@tonic-gate c_r=1; 15730Sstevel@tonic-gate if (sw_num <= 0) 15740Sstevel@tonic-gate done|=S_DONE; 15750Sstevel@tonic-gate } 15760Sstevel@tonic-gate } 15770Sstevel@tonic-gate } 15780Sstevel@tonic-gate 15790Sstevel@tonic-gate if ((done & S_DONE) && (done & C_DONE)) break; 15800Sstevel@tonic-gate } 15810Sstevel@tonic-gate 15820Sstevel@tonic-gate if (verbose) 15830Sstevel@tonic-gate print_details(c_ssl, "DONE: "); 15840Sstevel@tonic-gate ret=0; 15850Sstevel@tonic-gate err: 15860Sstevel@tonic-gate /* We have to set the BIO's to NULL otherwise they will be 15870Sstevel@tonic-gate * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and 15880Sstevel@tonic-gate * again when c_ssl is SSL_free()ed. 15890Sstevel@tonic-gate * This is a hack required because s_ssl and c_ssl are sharing the same 15900Sstevel@tonic-gate * BIO structure and SSL_set_bio() and SSL_free() automatically 15910Sstevel@tonic-gate * BIO_free non NULL entries. 15920Sstevel@tonic-gate * You should not normally do this or be required to do this */ 15930Sstevel@tonic-gate if (s_ssl != NULL) 15940Sstevel@tonic-gate { 15950Sstevel@tonic-gate s_ssl->rbio=NULL; 15960Sstevel@tonic-gate s_ssl->wbio=NULL; 15970Sstevel@tonic-gate } 15980Sstevel@tonic-gate if (c_ssl != NULL) 15990Sstevel@tonic-gate { 16000Sstevel@tonic-gate c_ssl->rbio=NULL; 16010Sstevel@tonic-gate c_ssl->wbio=NULL; 16020Sstevel@tonic-gate } 16030Sstevel@tonic-gate 16040Sstevel@tonic-gate if (c_to_s != NULL) BIO_free(c_to_s); 16050Sstevel@tonic-gate if (s_to_c != NULL) BIO_free(s_to_c); 16060Sstevel@tonic-gate if (c_bio != NULL) BIO_free_all(c_bio); 16070Sstevel@tonic-gate if (s_bio != NULL) BIO_free_all(s_bio); 16080Sstevel@tonic-gate return(ret); 16090Sstevel@tonic-gate } 16100Sstevel@tonic-gate 1611*2139Sjp161948 static int get_proxy_auth_ex_data_idx(void) 1612*2139Sjp161948 { 1613*2139Sjp161948 static volatile int idx = -1; 1614*2139Sjp161948 if (idx < 0) 1615*2139Sjp161948 { 1616*2139Sjp161948 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 1617*2139Sjp161948 if (idx < 0) 1618*2139Sjp161948 { 1619*2139Sjp161948 idx = X509_STORE_CTX_get_ex_new_index(0, 1620*2139Sjp161948 "SSLtest for verify callback", NULL,NULL,NULL); 1621*2139Sjp161948 } 1622*2139Sjp161948 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 1623*2139Sjp161948 } 1624*2139Sjp161948 return idx; 1625*2139Sjp161948 } 1626*2139Sjp161948 16270Sstevel@tonic-gate static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 16280Sstevel@tonic-gate { 16290Sstevel@tonic-gate char *s,buf[256]; 16300Sstevel@tonic-gate 16310Sstevel@tonic-gate s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf, 16320Sstevel@tonic-gate sizeof buf); 16330Sstevel@tonic-gate if (s != NULL) 16340Sstevel@tonic-gate { 16350Sstevel@tonic-gate if (ok) 1636*2139Sjp161948 fprintf(stderr,"depth=%d %s\n", 1637*2139Sjp161948 ctx->error_depth,buf); 16380Sstevel@tonic-gate else 1639*2139Sjp161948 { 16400Sstevel@tonic-gate fprintf(stderr,"depth=%d error=%d %s\n", 16410Sstevel@tonic-gate ctx->error_depth,ctx->error,buf); 1642*2139Sjp161948 } 16430Sstevel@tonic-gate } 16440Sstevel@tonic-gate 16450Sstevel@tonic-gate if (ok == 0) 16460Sstevel@tonic-gate { 1647*2139Sjp161948 fprintf(stderr,"Error string: %s\n", 1648*2139Sjp161948 X509_verify_cert_error_string(ctx->error)); 16490Sstevel@tonic-gate switch (ctx->error) 16500Sstevel@tonic-gate { 16510Sstevel@tonic-gate case X509_V_ERR_CERT_NOT_YET_VALID: 16520Sstevel@tonic-gate case X509_V_ERR_CERT_HAS_EXPIRED: 16530Sstevel@tonic-gate case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1654*2139Sjp161948 fprintf(stderr," ... ignored.\n"); 16550Sstevel@tonic-gate ok=1; 16560Sstevel@tonic-gate } 16570Sstevel@tonic-gate } 16580Sstevel@tonic-gate 1659*2139Sjp161948 if (ok == 1) 1660*2139Sjp161948 { 1661*2139Sjp161948 X509 *xs = ctx->current_cert; 1662*2139Sjp161948 #if 0 1663*2139Sjp161948 X509 *xi = ctx->current_issuer; 1664*2139Sjp161948 #endif 1665*2139Sjp161948 1666*2139Sjp161948 if (xs->ex_flags & EXFLAG_PROXY) 1667*2139Sjp161948 { 1668*2139Sjp161948 unsigned int *letters = 1669*2139Sjp161948 X509_STORE_CTX_get_ex_data(ctx, 1670*2139Sjp161948 get_proxy_auth_ex_data_idx()); 1671*2139Sjp161948 1672*2139Sjp161948 if (letters) 1673*2139Sjp161948 { 1674*2139Sjp161948 int found_any = 0; 1675*2139Sjp161948 int i; 1676*2139Sjp161948 PROXY_CERT_INFO_EXTENSION *pci = 1677*2139Sjp161948 X509_get_ext_d2i(xs, NID_proxyCertInfo, 1678*2139Sjp161948 NULL, NULL); 1679*2139Sjp161948 1680*2139Sjp161948 switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) 1681*2139Sjp161948 { 1682*2139Sjp161948 case NID_Independent: 1683*2139Sjp161948 /* Completely meaningless in this 1684*2139Sjp161948 program, as there's no way to 1685*2139Sjp161948 grant explicit rights to a 1686*2139Sjp161948 specific PrC. Basically, using 1687*2139Sjp161948 id-ppl-Independent is the perfect 1688*2139Sjp161948 way to grant no rights at all. */ 1689*2139Sjp161948 fprintf(stderr, " Independent proxy certificate"); 1690*2139Sjp161948 for (i = 0; i < 26; i++) 1691*2139Sjp161948 letters[i] = 0; 1692*2139Sjp161948 break; 1693*2139Sjp161948 case NID_id_ppl_inheritAll: 1694*2139Sjp161948 /* This is basically a NOP, we 1695*2139Sjp161948 simply let the current rights 1696*2139Sjp161948 stand as they are. */ 1697*2139Sjp161948 fprintf(stderr, " Proxy certificate inherits all"); 1698*2139Sjp161948 break; 1699*2139Sjp161948 default: 1700*2139Sjp161948 s = (char *) 1701*2139Sjp161948 pci->proxyPolicy->policy->data; 1702*2139Sjp161948 i = pci->proxyPolicy->policy->length; 1703*2139Sjp161948 1704*2139Sjp161948 /* The algorithm works as follows: 1705*2139Sjp161948 it is assumed that previous 1706*2139Sjp161948 iterations or the initial granted 1707*2139Sjp161948 rights has already set some elements 1708*2139Sjp161948 of `letters'. What we need to do is 1709*2139Sjp161948 to clear those that weren't granted 1710*2139Sjp161948 by the current PrC as well. The 1711*2139Sjp161948 easiest way to do this is to add 1 1712*2139Sjp161948 to all the elements whose letters 1713*2139Sjp161948 are given with the current policy. 1714*2139Sjp161948 That way, all elements that are set 1715*2139Sjp161948 by the current policy and were 1716*2139Sjp161948 already set by earlier policies and 1717*2139Sjp161948 through the original grant of rights 1718*2139Sjp161948 will get the value 2 or higher. 1719*2139Sjp161948 The last thing to do is to sweep 1720*2139Sjp161948 through `letters' and keep the 1721*2139Sjp161948 elements having the value 2 as set, 1722*2139Sjp161948 and clear all the others. */ 1723*2139Sjp161948 1724*2139Sjp161948 fprintf(stderr, " Certificate proxy rights = %*.*s", i, i, s); 1725*2139Sjp161948 while(i-- > 0) 1726*2139Sjp161948 { 1727*2139Sjp161948 int c = *s++; 1728*2139Sjp161948 if (isascii(c) && isalpha(c)) 1729*2139Sjp161948 { 1730*2139Sjp161948 if (islower(c)) 1731*2139Sjp161948 c = toupper(c); 1732*2139Sjp161948 letters[c - 'A']++; 1733*2139Sjp161948 } 1734*2139Sjp161948 } 1735*2139Sjp161948 for (i = 0; i < 26; i++) 1736*2139Sjp161948 if (letters[i] < 2) 1737*2139Sjp161948 letters[i] = 0; 1738*2139Sjp161948 else 1739*2139Sjp161948 letters[i] = 1; 1740*2139Sjp161948 } 1741*2139Sjp161948 1742*2139Sjp161948 found_any = 0; 1743*2139Sjp161948 fprintf(stderr, 1744*2139Sjp161948 ", resulting proxy rights = "); 1745*2139Sjp161948 for(i = 0; i < 26; i++) 1746*2139Sjp161948 if (letters[i]) 1747*2139Sjp161948 { 1748*2139Sjp161948 fprintf(stderr, "%c", i + 'A'); 1749*2139Sjp161948 found_any = 1; 1750*2139Sjp161948 } 1751*2139Sjp161948 if (!found_any) 1752*2139Sjp161948 fprintf(stderr, "none"); 1753*2139Sjp161948 fprintf(stderr, "\n"); 1754*2139Sjp161948 1755*2139Sjp161948 PROXY_CERT_INFO_EXTENSION_free(pci); 1756*2139Sjp161948 } 1757*2139Sjp161948 } 1758*2139Sjp161948 } 1759*2139Sjp161948 17600Sstevel@tonic-gate return(ok); 17610Sstevel@tonic-gate } 17620Sstevel@tonic-gate 1763*2139Sjp161948 static void process_proxy_debug(int indent, const char *format, ...) 1764*2139Sjp161948 { 1765*2139Sjp161948 static const char indentation[] = 1766*2139Sjp161948 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 1767*2139Sjp161948 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */ 1768*2139Sjp161948 char my_format[256]; 1769*2139Sjp161948 va_list args; 1770*2139Sjp161948 1771*2139Sjp161948 BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s", 1772*2139Sjp161948 indent, indent, indentation, format); 1773*2139Sjp161948 1774*2139Sjp161948 va_start(args, format); 1775*2139Sjp161948 vfprintf(stderr, my_format, args); 1776*2139Sjp161948 va_end(args); 1777*2139Sjp161948 } 1778*2139Sjp161948 /* Priority levels: 1779*2139Sjp161948 0 [!]var, () 1780*2139Sjp161948 1 & ^ 1781*2139Sjp161948 2 | 1782*2139Sjp161948 */ 1783*2139Sjp161948 static int process_proxy_cond_adders(unsigned int letters[26], 1784*2139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent); 1785*2139Sjp161948 static int process_proxy_cond_val(unsigned int letters[26], 1786*2139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent) 1787*2139Sjp161948 { 1788*2139Sjp161948 int c; 1789*2139Sjp161948 int ok = 1; 1790*2139Sjp161948 int negate = 0; 1791*2139Sjp161948 1792*2139Sjp161948 while(isspace((int)*cond)) 1793*2139Sjp161948 { 1794*2139Sjp161948 cond++; (*pos)++; 1795*2139Sjp161948 } 1796*2139Sjp161948 c = *cond; 1797*2139Sjp161948 1798*2139Sjp161948 if (debug) 1799*2139Sjp161948 process_proxy_debug(indent, 1800*2139Sjp161948 "Start process_proxy_cond_val at position %d: %s\n", 1801*2139Sjp161948 *pos, cond); 1802*2139Sjp161948 1803*2139Sjp161948 while(c == '!') 1804*2139Sjp161948 { 1805*2139Sjp161948 negate = !negate; 1806*2139Sjp161948 cond++; (*pos)++; 1807*2139Sjp161948 while(isspace((int)*cond)) 1808*2139Sjp161948 { 1809*2139Sjp161948 cond++; (*pos)++; 1810*2139Sjp161948 } 1811*2139Sjp161948 c = *cond; 1812*2139Sjp161948 } 1813*2139Sjp161948 1814*2139Sjp161948 if (c == '(') 1815*2139Sjp161948 { 1816*2139Sjp161948 cond++; (*pos)++; 1817*2139Sjp161948 ok = process_proxy_cond_adders(letters, cond, cond_end, pos, 1818*2139Sjp161948 indent + 1); 1819*2139Sjp161948 cond = *cond_end; 1820*2139Sjp161948 if (ok < 0) 1821*2139Sjp161948 goto end; 1822*2139Sjp161948 while(isspace((int)*cond)) 1823*2139Sjp161948 { 1824*2139Sjp161948 cond++; (*pos)++; 1825*2139Sjp161948 } 1826*2139Sjp161948 c = *cond; 1827*2139Sjp161948 if (c != ')') 1828*2139Sjp161948 { 1829*2139Sjp161948 fprintf(stderr, 1830*2139Sjp161948 "Weird condition character in position %d: " 1831*2139Sjp161948 "%c\n", *pos, c); 1832*2139Sjp161948 ok = -1; 1833*2139Sjp161948 goto end; 1834*2139Sjp161948 } 1835*2139Sjp161948 cond++; (*pos)++; 1836*2139Sjp161948 } 1837*2139Sjp161948 else if (isascii(c) && isalpha(c)) 1838*2139Sjp161948 { 1839*2139Sjp161948 if (islower(c)) 1840*2139Sjp161948 c = toupper(c); 1841*2139Sjp161948 ok = letters[c - 'A']; 1842*2139Sjp161948 cond++; (*pos)++; 1843*2139Sjp161948 } 1844*2139Sjp161948 else 1845*2139Sjp161948 { 1846*2139Sjp161948 fprintf(stderr, 1847*2139Sjp161948 "Weird condition character in position %d: " 1848*2139Sjp161948 "%c\n", *pos, c); 1849*2139Sjp161948 ok = -1; 1850*2139Sjp161948 goto end; 1851*2139Sjp161948 } 1852*2139Sjp161948 end: 1853*2139Sjp161948 *cond_end = cond; 1854*2139Sjp161948 if (ok >= 0 && negate) 1855*2139Sjp161948 ok = !ok; 1856*2139Sjp161948 1857*2139Sjp161948 if (debug) 1858*2139Sjp161948 process_proxy_debug(indent, 1859*2139Sjp161948 "End process_proxy_cond_val at position %d: %s, returning %d\n", 1860*2139Sjp161948 *pos, cond, ok); 1861*2139Sjp161948 1862*2139Sjp161948 return ok; 1863*2139Sjp161948 } 1864*2139Sjp161948 static int process_proxy_cond_multipliers(unsigned int letters[26], 1865*2139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent) 1866*2139Sjp161948 { 1867*2139Sjp161948 int ok; 1868*2139Sjp161948 char c; 1869*2139Sjp161948 1870*2139Sjp161948 if (debug) 1871*2139Sjp161948 process_proxy_debug(indent, 1872*2139Sjp161948 "Start process_proxy_cond_multipliers at position %d: %s\n", 1873*2139Sjp161948 *pos, cond); 1874*2139Sjp161948 1875*2139Sjp161948 ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1); 1876*2139Sjp161948 cond = *cond_end; 1877*2139Sjp161948 if (ok < 0) 1878*2139Sjp161948 goto end; 1879*2139Sjp161948 1880*2139Sjp161948 while(ok >= 0) 1881*2139Sjp161948 { 1882*2139Sjp161948 while(isspace((int)*cond)) 1883*2139Sjp161948 { 1884*2139Sjp161948 cond++; (*pos)++; 1885*2139Sjp161948 } 1886*2139Sjp161948 c = *cond; 1887*2139Sjp161948 1888*2139Sjp161948 switch(c) 1889*2139Sjp161948 { 1890*2139Sjp161948 case '&': 1891*2139Sjp161948 case '^': 1892*2139Sjp161948 { 1893*2139Sjp161948 int save_ok = ok; 1894*2139Sjp161948 1895*2139Sjp161948 cond++; (*pos)++; 1896*2139Sjp161948 ok = process_proxy_cond_val(letters, 1897*2139Sjp161948 cond, cond_end, pos, indent + 1); 1898*2139Sjp161948 cond = *cond_end; 1899*2139Sjp161948 if (ok < 0) 1900*2139Sjp161948 break; 1901*2139Sjp161948 1902*2139Sjp161948 switch(c) 1903*2139Sjp161948 { 1904*2139Sjp161948 case '&': 1905*2139Sjp161948 ok &= save_ok; 1906*2139Sjp161948 break; 1907*2139Sjp161948 case '^': 1908*2139Sjp161948 ok ^= save_ok; 1909*2139Sjp161948 break; 1910*2139Sjp161948 default: 1911*2139Sjp161948 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 1912*2139Sjp161948 " STOPPING\n"); 1913*2139Sjp161948 EXIT(1); 1914*2139Sjp161948 } 1915*2139Sjp161948 } 1916*2139Sjp161948 break; 1917*2139Sjp161948 default: 1918*2139Sjp161948 goto end; 1919*2139Sjp161948 } 1920*2139Sjp161948 } 1921*2139Sjp161948 end: 1922*2139Sjp161948 if (debug) 1923*2139Sjp161948 process_proxy_debug(indent, 1924*2139Sjp161948 "End process_proxy_cond_multipliers at position %d: %s, returning %d\n", 1925*2139Sjp161948 *pos, cond, ok); 1926*2139Sjp161948 1927*2139Sjp161948 *cond_end = cond; 1928*2139Sjp161948 return ok; 1929*2139Sjp161948 } 1930*2139Sjp161948 static int process_proxy_cond_adders(unsigned int letters[26], 1931*2139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent) 1932*2139Sjp161948 { 1933*2139Sjp161948 int ok; 1934*2139Sjp161948 char c; 1935*2139Sjp161948 1936*2139Sjp161948 if (debug) 1937*2139Sjp161948 process_proxy_debug(indent, 1938*2139Sjp161948 "Start process_proxy_cond_adders at position %d: %s\n", 1939*2139Sjp161948 *pos, cond); 1940*2139Sjp161948 1941*2139Sjp161948 ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos, 1942*2139Sjp161948 indent + 1); 1943*2139Sjp161948 cond = *cond_end; 1944*2139Sjp161948 if (ok < 0) 1945*2139Sjp161948 goto end; 1946*2139Sjp161948 1947*2139Sjp161948 while(ok >= 0) 1948*2139Sjp161948 { 1949*2139Sjp161948 while(isspace((int)*cond)) 1950*2139Sjp161948 { 1951*2139Sjp161948 cond++; (*pos)++; 1952*2139Sjp161948 } 1953*2139Sjp161948 c = *cond; 1954*2139Sjp161948 1955*2139Sjp161948 switch(c) 1956*2139Sjp161948 { 1957*2139Sjp161948 case '|': 1958*2139Sjp161948 { 1959*2139Sjp161948 int save_ok = ok; 1960*2139Sjp161948 1961*2139Sjp161948 cond++; (*pos)++; 1962*2139Sjp161948 ok = process_proxy_cond_multipliers(letters, 1963*2139Sjp161948 cond, cond_end, pos, indent + 1); 1964*2139Sjp161948 cond = *cond_end; 1965*2139Sjp161948 if (ok < 0) 1966*2139Sjp161948 break; 1967*2139Sjp161948 1968*2139Sjp161948 switch(c) 1969*2139Sjp161948 { 1970*2139Sjp161948 case '|': 1971*2139Sjp161948 ok |= save_ok; 1972*2139Sjp161948 break; 1973*2139Sjp161948 default: 1974*2139Sjp161948 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 1975*2139Sjp161948 " STOPPING\n"); 1976*2139Sjp161948 EXIT(1); 1977*2139Sjp161948 } 1978*2139Sjp161948 } 1979*2139Sjp161948 break; 1980*2139Sjp161948 default: 1981*2139Sjp161948 goto end; 1982*2139Sjp161948 } 1983*2139Sjp161948 } 1984*2139Sjp161948 end: 1985*2139Sjp161948 if (debug) 1986*2139Sjp161948 process_proxy_debug(indent, 1987*2139Sjp161948 "End process_proxy_cond_adders at position %d: %s, returning %d\n", 1988*2139Sjp161948 *pos, cond, ok); 1989*2139Sjp161948 1990*2139Sjp161948 *cond_end = cond; 1991*2139Sjp161948 return ok; 1992*2139Sjp161948 } 1993*2139Sjp161948 1994*2139Sjp161948 static int process_proxy_cond(unsigned int letters[26], 1995*2139Sjp161948 const char *cond, const char **cond_end) 1996*2139Sjp161948 { 1997*2139Sjp161948 int pos = 1; 1998*2139Sjp161948 return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1); 1999*2139Sjp161948 } 2000*2139Sjp161948 20010Sstevel@tonic-gate static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) 20020Sstevel@tonic-gate { 20030Sstevel@tonic-gate int ok=1; 2004*2139Sjp161948 struct app_verify_arg *cb_arg = arg; 2005*2139Sjp161948 unsigned int letters[26]; /* only used with proxy_auth */ 2006*2139Sjp161948 2007*2139Sjp161948 if (cb_arg->app_verify) 2008*2139Sjp161948 { 2009*2139Sjp161948 char *s = NULL,buf[256]; 2010*2139Sjp161948 2011*2139Sjp161948 fprintf(stderr, "In app_verify_callback, allowing cert. "); 2012*2139Sjp161948 fprintf(stderr, "Arg is: %s\n", cb_arg->string); 2013*2139Sjp161948 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n", 2014*2139Sjp161948 (void *)ctx, (void *)ctx->cert); 2015*2139Sjp161948 if (ctx->cert) 2016*2139Sjp161948 s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256); 2017*2139Sjp161948 if (s != NULL) 2018*2139Sjp161948 { 2019*2139Sjp161948 fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf); 2020*2139Sjp161948 } 2021*2139Sjp161948 return(1); 2022*2139Sjp161948 } 2023*2139Sjp161948 if (cb_arg->proxy_auth) 2024*2139Sjp161948 { 2025*2139Sjp161948 int found_any = 0, i; 2026*2139Sjp161948 char *sp; 20270Sstevel@tonic-gate 2028*2139Sjp161948 for(i = 0; i < 26; i++) 2029*2139Sjp161948 letters[i] = 0; 2030*2139Sjp161948 for(sp = cb_arg->proxy_auth; *sp; sp++) 2031*2139Sjp161948 { 2032*2139Sjp161948 int c = *sp; 2033*2139Sjp161948 if (isascii(c) && isalpha(c)) 2034*2139Sjp161948 { 2035*2139Sjp161948 if (islower(c)) 2036*2139Sjp161948 c = toupper(c); 2037*2139Sjp161948 letters[c - 'A'] = 1; 2038*2139Sjp161948 } 2039*2139Sjp161948 } 2040*2139Sjp161948 2041*2139Sjp161948 fprintf(stderr, 2042*2139Sjp161948 " Initial proxy rights = "); 2043*2139Sjp161948 for(i = 0; i < 26; i++) 2044*2139Sjp161948 if (letters[i]) 2045*2139Sjp161948 { 2046*2139Sjp161948 fprintf(stderr, "%c", i + 'A'); 2047*2139Sjp161948 found_any = 1; 2048*2139Sjp161948 } 2049*2139Sjp161948 if (!found_any) 2050*2139Sjp161948 fprintf(stderr, "none"); 2051*2139Sjp161948 fprintf(stderr, "\n"); 2052*2139Sjp161948 2053*2139Sjp161948 X509_STORE_CTX_set_ex_data(ctx, 2054*2139Sjp161948 get_proxy_auth_ex_data_idx(),letters); 2055*2139Sjp161948 } 2056*2139Sjp161948 if (cb_arg->allow_proxy_certs) 20570Sstevel@tonic-gate { 2058*2139Sjp161948 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); 20590Sstevel@tonic-gate } 20600Sstevel@tonic-gate 2061*2139Sjp161948 #ifndef OPENSSL_NO_X509_VERIFY 2062*2139Sjp161948 # ifdef OPENSSL_FIPS 2063*2139Sjp161948 if(s->version == TLS1_VERSION) 2064*2139Sjp161948 FIPS_allow_md5(1); 2065*2139Sjp161948 # endif 2066*2139Sjp161948 ok = X509_verify_cert(ctx); 2067*2139Sjp161948 # ifdef OPENSSL_FIPS 2068*2139Sjp161948 if(s->version == TLS1_VERSION) 2069*2139Sjp161948 FIPS_allow_md5(0); 2070*2139Sjp161948 # endif 2071*2139Sjp161948 #endif 2072*2139Sjp161948 2073*2139Sjp161948 if (cb_arg->proxy_auth) 2074*2139Sjp161948 { 2075*2139Sjp161948 if (ok) 2076*2139Sjp161948 { 2077*2139Sjp161948 const char *cond_end = NULL; 2078*2139Sjp161948 2079*2139Sjp161948 ok = process_proxy_cond(letters, 2080*2139Sjp161948 cb_arg->proxy_cond, &cond_end); 2081*2139Sjp161948 2082*2139Sjp161948 if (ok < 0) 2083*2139Sjp161948 EXIT(3); 2084*2139Sjp161948 if (*cond_end) 2085*2139Sjp161948 { 2086*2139Sjp161948 fprintf(stderr, "Stopped processing condition before it's end.\n"); 2087*2139Sjp161948 ok = 0; 2088*2139Sjp161948 } 2089*2139Sjp161948 if (!ok) 2090*2139Sjp161948 fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n", 2091*2139Sjp161948 cb_arg->proxy_cond); 2092*2139Sjp161948 else 2093*2139Sjp161948 fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n", 2094*2139Sjp161948 cb_arg->proxy_cond); 2095*2139Sjp161948 } 2096*2139Sjp161948 } 20970Sstevel@tonic-gate return(ok); 20980Sstevel@tonic-gate } 20990Sstevel@tonic-gate 21000Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 21010Sstevel@tonic-gate static RSA *rsa_tmp=NULL; 21020Sstevel@tonic-gate 21030Sstevel@tonic-gate static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) 21040Sstevel@tonic-gate { 2105*2139Sjp161948 BIGNUM *bn = NULL; 21060Sstevel@tonic-gate if (rsa_tmp == NULL) 21070Sstevel@tonic-gate { 2108*2139Sjp161948 bn = BN_new(); 2109*2139Sjp161948 rsa_tmp = RSA_new(); 2110*2139Sjp161948 if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) 2111*2139Sjp161948 { 2112*2139Sjp161948 BIO_printf(bio_err, "Memory error..."); 2113*2139Sjp161948 goto end; 2114*2139Sjp161948 } 21150Sstevel@tonic-gate BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength); 21160Sstevel@tonic-gate (void)BIO_flush(bio_err); 2117*2139Sjp161948 if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL)) 2118*2139Sjp161948 { 2119*2139Sjp161948 BIO_printf(bio_err, "Error generating key."); 2120*2139Sjp161948 RSA_free(rsa_tmp); 2121*2139Sjp161948 rsa_tmp = NULL; 2122*2139Sjp161948 } 2123*2139Sjp161948 end: 21240Sstevel@tonic-gate BIO_printf(bio_err,"\n"); 21250Sstevel@tonic-gate (void)BIO_flush(bio_err); 21260Sstevel@tonic-gate } 2127*2139Sjp161948 if(bn) BN_free(bn); 21280Sstevel@tonic-gate return(rsa_tmp); 21290Sstevel@tonic-gate } 21300Sstevel@tonic-gate 21310Sstevel@tonic-gate static void free_tmp_rsa(void) 21320Sstevel@tonic-gate { 21330Sstevel@tonic-gate if (rsa_tmp != NULL) 21340Sstevel@tonic-gate { 21350Sstevel@tonic-gate RSA_free(rsa_tmp); 21360Sstevel@tonic-gate rsa_tmp = NULL; 21370Sstevel@tonic-gate } 21380Sstevel@tonic-gate } 21390Sstevel@tonic-gate #endif 21400Sstevel@tonic-gate 21410Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 21420Sstevel@tonic-gate /* These DH parameters have been generated as follows: 21430Sstevel@tonic-gate * $ openssl dhparam -C -noout 512 21440Sstevel@tonic-gate * $ openssl dhparam -C -noout 1024 21450Sstevel@tonic-gate * $ openssl dhparam -C -noout -dsaparam 1024 21460Sstevel@tonic-gate * (The third function has been renamed to avoid name conflicts.) 21470Sstevel@tonic-gate */ 21480Sstevel@tonic-gate static DH *get_dh512() 21490Sstevel@tonic-gate { 21500Sstevel@tonic-gate static unsigned char dh512_p[]={ 21510Sstevel@tonic-gate 0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6, 21520Sstevel@tonic-gate 0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0, 21530Sstevel@tonic-gate 0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F, 21540Sstevel@tonic-gate 0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8, 21550Sstevel@tonic-gate 0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33, 21560Sstevel@tonic-gate 0x02,0xC5,0xAE,0x23, 21570Sstevel@tonic-gate }; 21580Sstevel@tonic-gate static unsigned char dh512_g[]={ 21590Sstevel@tonic-gate 0x02, 21600Sstevel@tonic-gate }; 21610Sstevel@tonic-gate DH *dh; 21620Sstevel@tonic-gate 21630Sstevel@tonic-gate if ((dh=DH_new()) == NULL) return(NULL); 21640Sstevel@tonic-gate dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); 21650Sstevel@tonic-gate dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); 21660Sstevel@tonic-gate if ((dh->p == NULL) || (dh->g == NULL)) 21670Sstevel@tonic-gate { DH_free(dh); return(NULL); } 21680Sstevel@tonic-gate return(dh); 21690Sstevel@tonic-gate } 21700Sstevel@tonic-gate 21710Sstevel@tonic-gate static DH *get_dh1024() 21720Sstevel@tonic-gate { 21730Sstevel@tonic-gate static unsigned char dh1024_p[]={ 21740Sstevel@tonic-gate 0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A, 21750Sstevel@tonic-gate 0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2, 21760Sstevel@tonic-gate 0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0, 21770Sstevel@tonic-gate 0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2, 21780Sstevel@tonic-gate 0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C, 21790Sstevel@tonic-gate 0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8, 21800Sstevel@tonic-gate 0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52, 21810Sstevel@tonic-gate 0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1, 21820Sstevel@tonic-gate 0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1, 21830Sstevel@tonic-gate 0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB, 21840Sstevel@tonic-gate 0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53, 21850Sstevel@tonic-gate }; 21860Sstevel@tonic-gate static unsigned char dh1024_g[]={ 21870Sstevel@tonic-gate 0x02, 21880Sstevel@tonic-gate }; 21890Sstevel@tonic-gate DH *dh; 21900Sstevel@tonic-gate 21910Sstevel@tonic-gate if ((dh=DH_new()) == NULL) return(NULL); 21920Sstevel@tonic-gate dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL); 21930Sstevel@tonic-gate dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL); 21940Sstevel@tonic-gate if ((dh->p == NULL) || (dh->g == NULL)) 21950Sstevel@tonic-gate { DH_free(dh); return(NULL); } 21960Sstevel@tonic-gate return(dh); 21970Sstevel@tonic-gate } 21980Sstevel@tonic-gate 21990Sstevel@tonic-gate static DH *get_dh1024dsa() 22000Sstevel@tonic-gate { 22010Sstevel@tonic-gate static unsigned char dh1024_p[]={ 22020Sstevel@tonic-gate 0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00, 22030Sstevel@tonic-gate 0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19, 22040Sstevel@tonic-gate 0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2, 22050Sstevel@tonic-gate 0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55, 22060Sstevel@tonic-gate 0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC, 22070Sstevel@tonic-gate 0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97, 22080Sstevel@tonic-gate 0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D, 22090Sstevel@tonic-gate 0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB, 22100Sstevel@tonic-gate 0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6, 22110Sstevel@tonic-gate 0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E, 22120Sstevel@tonic-gate 0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39, 22130Sstevel@tonic-gate }; 22140Sstevel@tonic-gate static unsigned char dh1024_g[]={ 22150Sstevel@tonic-gate 0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05, 22160Sstevel@tonic-gate 0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3, 22170Sstevel@tonic-gate 0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9, 22180Sstevel@tonic-gate 0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C, 22190Sstevel@tonic-gate 0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65, 22200Sstevel@tonic-gate 0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60, 22210Sstevel@tonic-gate 0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6, 22220Sstevel@tonic-gate 0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7, 22230Sstevel@tonic-gate 0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1, 22240Sstevel@tonic-gate 0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60, 22250Sstevel@tonic-gate 0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2, 22260Sstevel@tonic-gate }; 22270Sstevel@tonic-gate DH *dh; 22280Sstevel@tonic-gate 22290Sstevel@tonic-gate if ((dh=DH_new()) == NULL) return(NULL); 22300Sstevel@tonic-gate dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL); 22310Sstevel@tonic-gate dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL); 22320Sstevel@tonic-gate if ((dh->p == NULL) || (dh->g == NULL)) 22330Sstevel@tonic-gate { DH_free(dh); return(NULL); } 22340Sstevel@tonic-gate dh->length = 160; 22350Sstevel@tonic-gate return(dh); 22360Sstevel@tonic-gate } 2237*2139Sjp161948 2238*2139Sjp161948 static int do_test_cipherlist(void) 2239*2139Sjp161948 { 2240*2139Sjp161948 int i = 0; 2241*2139Sjp161948 const SSL_METHOD *meth; 2242*2139Sjp161948 SSL_CIPHER *ci, *tci = NULL; 2243*2139Sjp161948 2244*2139Sjp161948 fprintf(stderr, "testing SSLv2 cipher list order: "); 2245*2139Sjp161948 meth = SSLv2_method(); 2246*2139Sjp161948 while ((ci = meth->get_cipher(i++)) != NULL) 2247*2139Sjp161948 { 2248*2139Sjp161948 if (tci != NULL) 2249*2139Sjp161948 if (ci->id >= tci->id) 2250*2139Sjp161948 { 2251*2139Sjp161948 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2252*2139Sjp161948 return 0; 2253*2139Sjp161948 } 2254*2139Sjp161948 tci = ci; 2255*2139Sjp161948 } 2256*2139Sjp161948 fprintf(stderr, "ok\n"); 2257*2139Sjp161948 2258*2139Sjp161948 fprintf(stderr, "testing SSLv3 cipher list order: "); 2259*2139Sjp161948 meth = SSLv3_method(); 2260*2139Sjp161948 tci = NULL; 2261*2139Sjp161948 while ((ci = meth->get_cipher(i++)) != NULL) 2262*2139Sjp161948 { 2263*2139Sjp161948 if (tci != NULL) 2264*2139Sjp161948 if (ci->id >= tci->id) 2265*2139Sjp161948 { 2266*2139Sjp161948 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2267*2139Sjp161948 return 0; 2268*2139Sjp161948 } 2269*2139Sjp161948 tci = ci; 2270*2139Sjp161948 } 2271*2139Sjp161948 fprintf(stderr, "ok\n"); 2272*2139Sjp161948 2273*2139Sjp161948 fprintf(stderr, "testing TLSv1 cipher list order: "); 2274*2139Sjp161948 meth = TLSv1_method(); 2275*2139Sjp161948 tci = NULL; 2276*2139Sjp161948 while ((ci = meth->get_cipher(i++)) != NULL) 2277*2139Sjp161948 { 2278*2139Sjp161948 if (tci != NULL) 2279*2139Sjp161948 if (ci->id >= tci->id) 2280*2139Sjp161948 { 2281*2139Sjp161948 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2282*2139Sjp161948 return 0; 2283*2139Sjp161948 } 2284*2139Sjp161948 tci = ci; 2285*2139Sjp161948 } 2286*2139Sjp161948 fprintf(stderr, "ok\n"); 2287*2139Sjp161948 2288*2139Sjp161948 return 1; 2289*2139Sjp161948 } 22900Sstevel@tonic-gate #endif 2291