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 */
1112139Sjp161948 /* ====================================================================
1122139Sjp161948 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1132139Sjp161948 * ECC cipher suite support in OpenSSL originally developed by
1142139Sjp161948 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1152139Sjp161948 */
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
1312139Sjp161948 #define _XOPEN_SOURCE 500 /* Or isascii won't be declared properly on
1322139Sjp161948 VMS (at least with DECompHP C). */
1332139Sjp161948 #include <ctype.h>
1342139Sjp161948
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>
1392139Sjp161948 #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>
1462139Sjp161948 #ifndef OPENSSL_NO_RSA
1472139Sjp161948 #include <openssl/rsa.h>
1482139Sjp161948 #endif
1492139Sjp161948 #ifndef OPENSSL_NO_DSA
1502139Sjp161948 #include <openssl/dsa.h>
1512139Sjp161948 #endif
1522139Sjp161948 #ifndef OPENSSL_NO_DH
1532139Sjp161948 #include <openssl/dh.h>
1542139Sjp161948 #endif
1552139Sjp161948 #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"
1752139Sjp161948 #elif defined(OPENSSL_SYS_NETWARE)
1762139Sjp161948 # define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
1772139Sjp161948 # 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 */
1852139Sjp161948 #define COMP_RLE 255
1862139Sjp161948 #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);
1942139Sjp161948 #define APP_CALLBACK_STRING "Test Callback Argument"
1952139Sjp161948 struct app_verify_arg
1962139Sjp161948 {
1972139Sjp161948 char *string;
1982139Sjp161948 int app_verify;
1992139Sjp161948 int allow_proxy_certs;
2002139Sjp161948 char *proxy_auth;
2012139Sjp161948 char *proxy_cond;
2022139Sjp161948 };
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);
2272139Sjp161948 static int do_test_cipherlist(void);
sv_usage(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");
2342139Sjp161948 fprintf(stderr," -proxy - allow proxy certificates\n");
2352139Sjp161948 fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
2362139Sjp161948 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
2472139Sjp161948 #ifndef OPENSSL_NO_ECDH
2482139Sjp161948 fprintf(stderr," -no_ecdhe - disable ECDHE\n");
2492139Sjp161948 #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");
2702139Sjp161948 fprintf(stderr," -rle - use rle compression\n");
2712139Sjp161948 #ifndef OPENSSL_NO_ECDH
2722139Sjp161948 fprintf(stderr," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \
2732139Sjp161948 " Use \"openssl ecparam -list_curves\" for all names\n" \
2742139Sjp161948 " (default is sect163r2).\n");
2752139Sjp161948 #endif
2762139Sjp161948 fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate
print_details(SSL * c_ssl,const char * prefix)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
lock_dbg_cb(int mode,int type,const char * file,int line)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
3862139Sjp161948
main(int argc,char * argv[])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;
3962139Sjp161948 struct app_verify_arg app_verify_arg =
3972139Sjp161948 { 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;
4022139Sjp161948 #ifndef OPENSSL_NO_ECDH
4032139Sjp161948 char *named_curve = NULL;
4042139Sjp161948 #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;
4102139Sjp161948 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
4152139Sjp161948 #ifndef OPENSSL_NO_ECDH
4162139Sjp161948 EC_KEY *ecdh = NULL;
4172139Sjp161948 #endif
4180Sstevel@tonic-gate int no_dhe = 0;
4192139Sjp161948 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;
4232139Sjp161948 #ifndef OPENSSL_NO_COMP
4240Sstevel@tonic-gate COMP_METHOD *cm = NULL;
4252139Sjp161948 #endif
4262139Sjp161948 STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
4272139Sjp161948 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;
4632139Sjp161948 else if (strcmp(*argv,"-proxy_auth") == 0)
4642139Sjp161948 {
4652139Sjp161948 if (--argc < 1) goto bad;
4662139Sjp161948 app_verify_arg.proxy_auth= *(++argv);
4672139Sjp161948 }
4682139Sjp161948 else if (strcmp(*argv,"-proxy_cond") == 0)
4692139Sjp161948 {
4702139Sjp161948 if (--argc < 1) goto bad;
4712139Sjp161948 app_verify_arg.proxy_cond= *(++argv);
4722139Sjp161948 }
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;
4972139Sjp161948 else if (strcmp(*argv,"-no_ecdhe") == 0)
4982139Sjp161948 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 }
5852139Sjp161948 else if (strcmp(*argv,"-named_curve") == 0)
5862139Sjp161948 {
5872139Sjp161948 if (--argc < 1) goto bad;
5882139Sjp161948 #ifndef OPENSSL_NO_ECDH
5892139Sjp161948 named_curve = *(++argv);
5902139Sjp161948 #else
5912139Sjp161948 fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
5922139Sjp161948 ++argv;
5932139Sjp161948 #endif
5942139Sjp161948 }
5950Sstevel@tonic-gate else if (strcmp(*argv,"-app_verify") == 0)
5960Sstevel@tonic-gate {
5972139Sjp161948 app_verify_arg.app_verify = 1;
5982139Sjp161948 }
5992139Sjp161948 else if (strcmp(*argv,"-proxy") == 0)
6002139Sjp161948 {
6012139Sjp161948 app_verify_arg.allow_proxy_certs = 1;
6022139Sjp161948 }
6032139Sjp161948 else if (strcmp(*argv,"-test_cipherlist") == 0)
6042139Sjp161948 {
6052139Sjp161948 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
6232139Sjp161948 if (test_cipherlist == 1)
6242139Sjp161948 {
6252139Sjp161948 /* ensure that the cipher list are correctly sorted and exit */
6262139Sjp161948 if (do_test_cipherlist() == 0)
6272139Sjp161948 EXIT(1);
6282139Sjp161948 ret = 0;
6292139Sjp161948 goto end;
6302139Sjp161948 }
6312139Sjp161948
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
6572139Sjp161948 #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 }
6812139Sjp161948 ssl_comp_methods = SSL_COMP_get_compression_methods();
6822139Sjp161948 fprintf(stderr, "Available compression methods:\n");
6832139Sjp161948 {
6842139Sjp161948 int j, n = sk_SSL_COMP_num(ssl_comp_methods);
6852139Sjp161948 if (n == 0)
6862139Sjp161948 fprintf(stderr, " NONE\n");
6872139Sjp161948 else
6882139Sjp161948 for (j = 0; j < n; j++)
6892139Sjp161948 {
6902139Sjp161948 SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
6912139Sjp161948 fprintf(stderr, " %d: %s\n", c->id, c->name);
6922139Sjp161948 }
6932139Sjp161948 }
6942139Sjp161948 #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
7492139Sjp161948 #ifndef OPENSSL_NO_ECDH
7502139Sjp161948 if (!no_ecdhe)
7512139Sjp161948 {
7522139Sjp161948 int nid;
7532139Sjp161948
7542139Sjp161948 if (named_curve != NULL)
7552139Sjp161948 {
7562139Sjp161948 nid = OBJ_sn2nid(named_curve);
7572139Sjp161948 if (nid == 0)
7582139Sjp161948 {
7592139Sjp161948 BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
7602139Sjp161948 goto end;
7612139Sjp161948 }
7622139Sjp161948 }
7632139Sjp161948 else
7642139Sjp161948 nid = NID_sect163r2;
7652139Sjp161948
7662139Sjp161948 ecdh = EC_KEY_new_by_curve_name(nid);
7672139Sjp161948 if (ecdh == NULL)
7682139Sjp161948 {
7692139Sjp161948 BIO_printf(bio_err, "unable to create curve\n");
7702139Sjp161948 goto end;
7712139Sjp161948 }
7722139Sjp161948
7732139Sjp161948 SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
7742139Sjp161948 SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
7752139Sjp161948 EC_KEY_free(ecdh);
7762139Sjp161948 }
7772139Sjp161948 #else
7782139Sjp161948 (void)no_ecdhe;
7792139Sjp161948 #endif
7802139Sjp161948
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);
8212139Sjp161948 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);
8282139Sjp161948 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);
9172139Sjp161948 return ret;
9180Sstevel@tonic-gate }
9190Sstevel@tonic-gate
doit_biopair(SSL * s_ssl,SSL * c_ssl,long count,clock_t * s_time,clock_t * c_time)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
doit(SSL * s_ssl,SSL * c_ssl,long count)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 {
14082139Sjp161948 j = (cw_num > (long)sizeof(cbuf)) ?
14092139Sjp161948 (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 {
15392139Sjp161948 j = (sw_num > (long)sizeof(sbuf)) ?
15402139Sjp161948 (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
get_proxy_auth_ex_data_idx(void)16112139Sjp161948 static int get_proxy_auth_ex_data_idx(void)
16122139Sjp161948 {
16132139Sjp161948 static volatile int idx = -1;
16142139Sjp161948 if (idx < 0)
16152139Sjp161948 {
16162139Sjp161948 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
16172139Sjp161948 if (idx < 0)
16182139Sjp161948 {
16192139Sjp161948 idx = X509_STORE_CTX_get_ex_new_index(0,
16202139Sjp161948 "SSLtest for verify callback", NULL,NULL,NULL);
16212139Sjp161948 }
16222139Sjp161948 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
16232139Sjp161948 }
16242139Sjp161948 return idx;
16252139Sjp161948 }
16262139Sjp161948
verify_callback(int ok,X509_STORE_CTX * ctx)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)
16362139Sjp161948 fprintf(stderr,"depth=%d %s\n",
16372139Sjp161948 ctx->error_depth,buf);
16380Sstevel@tonic-gate else
16392139Sjp161948 {
16400Sstevel@tonic-gate fprintf(stderr,"depth=%d error=%d %s\n",
16410Sstevel@tonic-gate ctx->error_depth,ctx->error,buf);
16422139Sjp161948 }
16430Sstevel@tonic-gate }
16440Sstevel@tonic-gate
16450Sstevel@tonic-gate if (ok == 0)
16460Sstevel@tonic-gate {
16472139Sjp161948 fprintf(stderr,"Error string: %s\n",
16482139Sjp161948 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:
16542139Sjp161948 fprintf(stderr," ... ignored.\n");
16550Sstevel@tonic-gate ok=1;
16560Sstevel@tonic-gate }
16570Sstevel@tonic-gate }
16580Sstevel@tonic-gate
16592139Sjp161948 if (ok == 1)
16602139Sjp161948 {
16612139Sjp161948 X509 *xs = ctx->current_cert;
16622139Sjp161948 #if 0
16632139Sjp161948 X509 *xi = ctx->current_issuer;
16642139Sjp161948 #endif
16652139Sjp161948
16662139Sjp161948 if (xs->ex_flags & EXFLAG_PROXY)
16672139Sjp161948 {
16682139Sjp161948 unsigned int *letters =
16692139Sjp161948 X509_STORE_CTX_get_ex_data(ctx,
16702139Sjp161948 get_proxy_auth_ex_data_idx());
16712139Sjp161948
16722139Sjp161948 if (letters)
16732139Sjp161948 {
16742139Sjp161948 int found_any = 0;
16752139Sjp161948 int i;
16762139Sjp161948 PROXY_CERT_INFO_EXTENSION *pci =
16772139Sjp161948 X509_get_ext_d2i(xs, NID_proxyCertInfo,
16782139Sjp161948 NULL, NULL);
16792139Sjp161948
16802139Sjp161948 switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
16812139Sjp161948 {
16822139Sjp161948 case NID_Independent:
16832139Sjp161948 /* Completely meaningless in this
16842139Sjp161948 program, as there's no way to
16852139Sjp161948 grant explicit rights to a
16862139Sjp161948 specific PrC. Basically, using
16872139Sjp161948 id-ppl-Independent is the perfect
16882139Sjp161948 way to grant no rights at all. */
16892139Sjp161948 fprintf(stderr, " Independent proxy certificate");
16902139Sjp161948 for (i = 0; i < 26; i++)
16912139Sjp161948 letters[i] = 0;
16922139Sjp161948 break;
16932139Sjp161948 case NID_id_ppl_inheritAll:
16942139Sjp161948 /* This is basically a NOP, we
16952139Sjp161948 simply let the current rights
16962139Sjp161948 stand as they are. */
16972139Sjp161948 fprintf(stderr, " Proxy certificate inherits all");
16982139Sjp161948 break;
16992139Sjp161948 default:
17002139Sjp161948 s = (char *)
17012139Sjp161948 pci->proxyPolicy->policy->data;
17022139Sjp161948 i = pci->proxyPolicy->policy->length;
17032139Sjp161948
17042139Sjp161948 /* The algorithm works as follows:
17052139Sjp161948 it is assumed that previous
17062139Sjp161948 iterations or the initial granted
17072139Sjp161948 rights has already set some elements
17082139Sjp161948 of `letters'. What we need to do is
17092139Sjp161948 to clear those that weren't granted
17102139Sjp161948 by the current PrC as well. The
17112139Sjp161948 easiest way to do this is to add 1
17122139Sjp161948 to all the elements whose letters
17132139Sjp161948 are given with the current policy.
17142139Sjp161948 That way, all elements that are set
17152139Sjp161948 by the current policy and were
17162139Sjp161948 already set by earlier policies and
17172139Sjp161948 through the original grant of rights
17182139Sjp161948 will get the value 2 or higher.
17192139Sjp161948 The last thing to do is to sweep
17202139Sjp161948 through `letters' and keep the
17212139Sjp161948 elements having the value 2 as set,
17222139Sjp161948 and clear all the others. */
17232139Sjp161948
17242139Sjp161948 fprintf(stderr, " Certificate proxy rights = %*.*s", i, i, s);
17252139Sjp161948 while(i-- > 0)
17262139Sjp161948 {
17272139Sjp161948 int c = *s++;
17282139Sjp161948 if (isascii(c) && isalpha(c))
17292139Sjp161948 {
17302139Sjp161948 if (islower(c))
17312139Sjp161948 c = toupper(c);
17322139Sjp161948 letters[c - 'A']++;
17332139Sjp161948 }
17342139Sjp161948 }
17352139Sjp161948 for (i = 0; i < 26; i++)
17362139Sjp161948 if (letters[i] < 2)
17372139Sjp161948 letters[i] = 0;
17382139Sjp161948 else
17392139Sjp161948 letters[i] = 1;
17402139Sjp161948 }
17412139Sjp161948
17422139Sjp161948 found_any = 0;
17432139Sjp161948 fprintf(stderr,
17442139Sjp161948 ", resulting proxy rights = ");
17452139Sjp161948 for(i = 0; i < 26; i++)
17462139Sjp161948 if (letters[i])
17472139Sjp161948 {
17482139Sjp161948 fprintf(stderr, "%c", i + 'A');
17492139Sjp161948 found_any = 1;
17502139Sjp161948 }
17512139Sjp161948 if (!found_any)
17522139Sjp161948 fprintf(stderr, "none");
17532139Sjp161948 fprintf(stderr, "\n");
17542139Sjp161948
17552139Sjp161948 PROXY_CERT_INFO_EXTENSION_free(pci);
17562139Sjp161948 }
17572139Sjp161948 }
17582139Sjp161948 }
17592139Sjp161948
17600Sstevel@tonic-gate return(ok);
17610Sstevel@tonic-gate }
17620Sstevel@tonic-gate
process_proxy_debug(int indent,const char * format,...)17632139Sjp161948 static void process_proxy_debug(int indent, const char *format, ...)
17642139Sjp161948 {
17652139Sjp161948 static const char indentation[] =
17662139Sjp161948 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
17672139Sjp161948 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
17682139Sjp161948 char my_format[256];
17692139Sjp161948 va_list args;
17702139Sjp161948
17712139Sjp161948 BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
17722139Sjp161948 indent, indent, indentation, format);
17732139Sjp161948
17742139Sjp161948 va_start(args, format);
17752139Sjp161948 vfprintf(stderr, my_format, args);
17762139Sjp161948 va_end(args);
17772139Sjp161948 }
17782139Sjp161948 /* Priority levels:
17792139Sjp161948 0 [!]var, ()
17802139Sjp161948 1 & ^
17812139Sjp161948 2 |
17822139Sjp161948 */
17832139Sjp161948 static int process_proxy_cond_adders(unsigned int letters[26],
17842139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent);
process_proxy_cond_val(unsigned int letters[26],const char * cond,const char ** cond_end,int * pos,int indent)17852139Sjp161948 static int process_proxy_cond_val(unsigned int letters[26],
17862139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent)
17872139Sjp161948 {
17882139Sjp161948 int c;
17892139Sjp161948 int ok = 1;
17902139Sjp161948 int negate = 0;
17912139Sjp161948
17922139Sjp161948 while(isspace((int)*cond))
17932139Sjp161948 {
17942139Sjp161948 cond++; (*pos)++;
17952139Sjp161948 }
17962139Sjp161948 c = *cond;
17972139Sjp161948
17982139Sjp161948 if (debug)
17992139Sjp161948 process_proxy_debug(indent,
18002139Sjp161948 "Start process_proxy_cond_val at position %d: %s\n",
18012139Sjp161948 *pos, cond);
18022139Sjp161948
18032139Sjp161948 while(c == '!')
18042139Sjp161948 {
18052139Sjp161948 negate = !negate;
18062139Sjp161948 cond++; (*pos)++;
18072139Sjp161948 while(isspace((int)*cond))
18082139Sjp161948 {
18092139Sjp161948 cond++; (*pos)++;
18102139Sjp161948 }
18112139Sjp161948 c = *cond;
18122139Sjp161948 }
18132139Sjp161948
18142139Sjp161948 if (c == '(')
18152139Sjp161948 {
18162139Sjp161948 cond++; (*pos)++;
18172139Sjp161948 ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
18182139Sjp161948 indent + 1);
18192139Sjp161948 cond = *cond_end;
18202139Sjp161948 if (ok < 0)
18212139Sjp161948 goto end;
18222139Sjp161948 while(isspace((int)*cond))
18232139Sjp161948 {
18242139Sjp161948 cond++; (*pos)++;
18252139Sjp161948 }
18262139Sjp161948 c = *cond;
18272139Sjp161948 if (c != ')')
18282139Sjp161948 {
18292139Sjp161948 fprintf(stderr,
18302139Sjp161948 "Weird condition character in position %d: "
18312139Sjp161948 "%c\n", *pos, c);
18322139Sjp161948 ok = -1;
18332139Sjp161948 goto end;
18342139Sjp161948 }
18352139Sjp161948 cond++; (*pos)++;
18362139Sjp161948 }
18372139Sjp161948 else if (isascii(c) && isalpha(c))
18382139Sjp161948 {
18392139Sjp161948 if (islower(c))
18402139Sjp161948 c = toupper(c);
18412139Sjp161948 ok = letters[c - 'A'];
18422139Sjp161948 cond++; (*pos)++;
18432139Sjp161948 }
18442139Sjp161948 else
18452139Sjp161948 {
18462139Sjp161948 fprintf(stderr,
18472139Sjp161948 "Weird condition character in position %d: "
18482139Sjp161948 "%c\n", *pos, c);
18492139Sjp161948 ok = -1;
18502139Sjp161948 goto end;
18512139Sjp161948 }
18522139Sjp161948 end:
18532139Sjp161948 *cond_end = cond;
18542139Sjp161948 if (ok >= 0 && negate)
18552139Sjp161948 ok = !ok;
18562139Sjp161948
18572139Sjp161948 if (debug)
18582139Sjp161948 process_proxy_debug(indent,
18592139Sjp161948 "End process_proxy_cond_val at position %d: %s, returning %d\n",
18602139Sjp161948 *pos, cond, ok);
18612139Sjp161948
18622139Sjp161948 return ok;
18632139Sjp161948 }
process_proxy_cond_multipliers(unsigned int letters[26],const char * cond,const char ** cond_end,int * pos,int indent)18642139Sjp161948 static int process_proxy_cond_multipliers(unsigned int letters[26],
18652139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent)
18662139Sjp161948 {
18672139Sjp161948 int ok;
18682139Sjp161948 char c;
18692139Sjp161948
18702139Sjp161948 if (debug)
18712139Sjp161948 process_proxy_debug(indent,
18722139Sjp161948 "Start process_proxy_cond_multipliers at position %d: %s\n",
18732139Sjp161948 *pos, cond);
18742139Sjp161948
18752139Sjp161948 ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
18762139Sjp161948 cond = *cond_end;
18772139Sjp161948 if (ok < 0)
18782139Sjp161948 goto end;
18792139Sjp161948
18802139Sjp161948 while(ok >= 0)
18812139Sjp161948 {
18822139Sjp161948 while(isspace((int)*cond))
18832139Sjp161948 {
18842139Sjp161948 cond++; (*pos)++;
18852139Sjp161948 }
18862139Sjp161948 c = *cond;
18872139Sjp161948
18882139Sjp161948 switch(c)
18892139Sjp161948 {
18902139Sjp161948 case '&':
18912139Sjp161948 case '^':
18922139Sjp161948 {
18932139Sjp161948 int save_ok = ok;
18942139Sjp161948
18952139Sjp161948 cond++; (*pos)++;
18962139Sjp161948 ok = process_proxy_cond_val(letters,
18972139Sjp161948 cond, cond_end, pos, indent + 1);
18982139Sjp161948 cond = *cond_end;
18992139Sjp161948 if (ok < 0)
19002139Sjp161948 break;
19012139Sjp161948
19022139Sjp161948 switch(c)
19032139Sjp161948 {
19042139Sjp161948 case '&':
19052139Sjp161948 ok &= save_ok;
19062139Sjp161948 break;
19072139Sjp161948 case '^':
19082139Sjp161948 ok ^= save_ok;
19092139Sjp161948 break;
19102139Sjp161948 default:
19112139Sjp161948 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
19122139Sjp161948 " STOPPING\n");
19132139Sjp161948 EXIT(1);
19142139Sjp161948 }
19152139Sjp161948 }
19162139Sjp161948 break;
19172139Sjp161948 default:
19182139Sjp161948 goto end;
19192139Sjp161948 }
19202139Sjp161948 }
19212139Sjp161948 end:
19222139Sjp161948 if (debug)
19232139Sjp161948 process_proxy_debug(indent,
19242139Sjp161948 "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
19252139Sjp161948 *pos, cond, ok);
19262139Sjp161948
19272139Sjp161948 *cond_end = cond;
19282139Sjp161948 return ok;
19292139Sjp161948 }
process_proxy_cond_adders(unsigned int letters[26],const char * cond,const char ** cond_end,int * pos,int indent)19302139Sjp161948 static int process_proxy_cond_adders(unsigned int letters[26],
19312139Sjp161948 const char *cond, const char **cond_end, int *pos, int indent)
19322139Sjp161948 {
19332139Sjp161948 int ok;
19342139Sjp161948 char c;
19352139Sjp161948
19362139Sjp161948 if (debug)
19372139Sjp161948 process_proxy_debug(indent,
19382139Sjp161948 "Start process_proxy_cond_adders at position %d: %s\n",
19392139Sjp161948 *pos, cond);
19402139Sjp161948
19412139Sjp161948 ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
19422139Sjp161948 indent + 1);
19432139Sjp161948 cond = *cond_end;
19442139Sjp161948 if (ok < 0)
19452139Sjp161948 goto end;
19462139Sjp161948
19472139Sjp161948 while(ok >= 0)
19482139Sjp161948 {
19492139Sjp161948 while(isspace((int)*cond))
19502139Sjp161948 {
19512139Sjp161948 cond++; (*pos)++;
19522139Sjp161948 }
19532139Sjp161948 c = *cond;
19542139Sjp161948
19552139Sjp161948 switch(c)
19562139Sjp161948 {
19572139Sjp161948 case '|':
19582139Sjp161948 {
19592139Sjp161948 int save_ok = ok;
19602139Sjp161948
19612139Sjp161948 cond++; (*pos)++;
19622139Sjp161948 ok = process_proxy_cond_multipliers(letters,
19632139Sjp161948 cond, cond_end, pos, indent + 1);
19642139Sjp161948 cond = *cond_end;
19652139Sjp161948 if (ok < 0)
19662139Sjp161948 break;
19672139Sjp161948
19682139Sjp161948 switch(c)
19692139Sjp161948 {
19702139Sjp161948 case '|':
19712139Sjp161948 ok |= save_ok;
19722139Sjp161948 break;
19732139Sjp161948 default:
19742139Sjp161948 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
19752139Sjp161948 " STOPPING\n");
19762139Sjp161948 EXIT(1);
19772139Sjp161948 }
19782139Sjp161948 }
19792139Sjp161948 break;
19802139Sjp161948 default:
19812139Sjp161948 goto end;
19822139Sjp161948 }
19832139Sjp161948 }
19842139Sjp161948 end:
19852139Sjp161948 if (debug)
19862139Sjp161948 process_proxy_debug(indent,
19872139Sjp161948 "End process_proxy_cond_adders at position %d: %s, returning %d\n",
19882139Sjp161948 *pos, cond, ok);
19892139Sjp161948
19902139Sjp161948 *cond_end = cond;
19912139Sjp161948 return ok;
19922139Sjp161948 }
19932139Sjp161948
process_proxy_cond(unsigned int letters[26],const char * cond,const char ** cond_end)19942139Sjp161948 static int process_proxy_cond(unsigned int letters[26],
19952139Sjp161948 const char *cond, const char **cond_end)
19962139Sjp161948 {
19972139Sjp161948 int pos = 1;
19982139Sjp161948 return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
19992139Sjp161948 }
20002139Sjp161948
app_verify_callback(X509_STORE_CTX * ctx,void * arg)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;
20042139Sjp161948 struct app_verify_arg *cb_arg = arg;
20052139Sjp161948 unsigned int letters[26]; /* only used with proxy_auth */
20062139Sjp161948
20072139Sjp161948 if (cb_arg->app_verify)
20082139Sjp161948 {
20092139Sjp161948 char *s = NULL,buf[256];
20102139Sjp161948
20112139Sjp161948 fprintf(stderr, "In app_verify_callback, allowing cert. ");
20122139Sjp161948 fprintf(stderr, "Arg is: %s\n", cb_arg->string);
20132139Sjp161948 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
20142139Sjp161948 (void *)ctx, (void *)ctx->cert);
20152139Sjp161948 if (ctx->cert)
20162139Sjp161948 s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
20172139Sjp161948 if (s != NULL)
20182139Sjp161948 {
20192139Sjp161948 fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
20202139Sjp161948 }
20212139Sjp161948 return(1);
20222139Sjp161948 }
20232139Sjp161948 if (cb_arg->proxy_auth)
20242139Sjp161948 {
20252139Sjp161948 int found_any = 0, i;
20262139Sjp161948 char *sp;
20270Sstevel@tonic-gate
20282139Sjp161948 for(i = 0; i < 26; i++)
20292139Sjp161948 letters[i] = 0;
20302139Sjp161948 for(sp = cb_arg->proxy_auth; *sp; sp++)
20312139Sjp161948 {
20322139Sjp161948 int c = *sp;
20332139Sjp161948 if (isascii(c) && isalpha(c))
20342139Sjp161948 {
20352139Sjp161948 if (islower(c))
20362139Sjp161948 c = toupper(c);
20372139Sjp161948 letters[c - 'A'] = 1;
20382139Sjp161948 }
20392139Sjp161948 }
20402139Sjp161948
20412139Sjp161948 fprintf(stderr,
20422139Sjp161948 " Initial proxy rights = ");
20432139Sjp161948 for(i = 0; i < 26; i++)
20442139Sjp161948 if (letters[i])
20452139Sjp161948 {
20462139Sjp161948 fprintf(stderr, "%c", i + 'A');
20472139Sjp161948 found_any = 1;
20482139Sjp161948 }
20492139Sjp161948 if (!found_any)
20502139Sjp161948 fprintf(stderr, "none");
20512139Sjp161948 fprintf(stderr, "\n");
20522139Sjp161948
20532139Sjp161948 X509_STORE_CTX_set_ex_data(ctx,
20542139Sjp161948 get_proxy_auth_ex_data_idx(),letters);
20552139Sjp161948 }
20562139Sjp161948 if (cb_arg->allow_proxy_certs)
20570Sstevel@tonic-gate {
20582139Sjp161948 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
20590Sstevel@tonic-gate }
20600Sstevel@tonic-gate
20612139Sjp161948 #ifndef OPENSSL_NO_X509_VERIFY
20622139Sjp161948 # ifdef OPENSSL_FIPS
20632139Sjp161948 if(s->version == TLS1_VERSION)
20642139Sjp161948 FIPS_allow_md5(1);
20652139Sjp161948 # endif
20662139Sjp161948 ok = X509_verify_cert(ctx);
20672139Sjp161948 # ifdef OPENSSL_FIPS
20682139Sjp161948 if(s->version == TLS1_VERSION)
20692139Sjp161948 FIPS_allow_md5(0);
20702139Sjp161948 # endif
20712139Sjp161948 #endif
20722139Sjp161948
20732139Sjp161948 if (cb_arg->proxy_auth)
20742139Sjp161948 {
2075*8545SJan.Pechanec@Sun.COM if (ok > 0)
20762139Sjp161948 {
20772139Sjp161948 const char *cond_end = NULL;
20782139Sjp161948
20792139Sjp161948 ok = process_proxy_cond(letters,
20802139Sjp161948 cb_arg->proxy_cond, &cond_end);
20812139Sjp161948
20822139Sjp161948 if (ok < 0)
20832139Sjp161948 EXIT(3);
20842139Sjp161948 if (*cond_end)
20852139Sjp161948 {
20862139Sjp161948 fprintf(stderr, "Stopped processing condition before it's end.\n");
20872139Sjp161948 ok = 0;
20882139Sjp161948 }
20892139Sjp161948 if (!ok)
20902139Sjp161948 fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
20912139Sjp161948 cb_arg->proxy_cond);
20922139Sjp161948 else
20932139Sjp161948 fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
20942139Sjp161948 cb_arg->proxy_cond);
20952139Sjp161948 }
20962139Sjp161948 }
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
tmp_rsa_cb(SSL * s,int is_export,int keylength)21030Sstevel@tonic-gate static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
21040Sstevel@tonic-gate {
21052139Sjp161948 BIGNUM *bn = NULL;
21060Sstevel@tonic-gate if (rsa_tmp == NULL)
21070Sstevel@tonic-gate {
21082139Sjp161948 bn = BN_new();
21092139Sjp161948 rsa_tmp = RSA_new();
21102139Sjp161948 if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
21112139Sjp161948 {
21122139Sjp161948 BIO_printf(bio_err, "Memory error...");
21132139Sjp161948 goto end;
21142139Sjp161948 }
21150Sstevel@tonic-gate BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
21160Sstevel@tonic-gate (void)BIO_flush(bio_err);
21172139Sjp161948 if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
21182139Sjp161948 {
21192139Sjp161948 BIO_printf(bio_err, "Error generating key.");
21202139Sjp161948 RSA_free(rsa_tmp);
21212139Sjp161948 rsa_tmp = NULL;
21222139Sjp161948 }
21232139Sjp161948 end:
21240Sstevel@tonic-gate BIO_printf(bio_err,"\n");
21250Sstevel@tonic-gate (void)BIO_flush(bio_err);
21260Sstevel@tonic-gate }
21272139Sjp161948 if(bn) BN_free(bn);
21280Sstevel@tonic-gate return(rsa_tmp);
21290Sstevel@tonic-gate }
21300Sstevel@tonic-gate
free_tmp_rsa(void)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 */
get_dh512()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
get_dh1024()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
get_dh1024dsa()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 }
22372139Sjp161948
do_test_cipherlist(void)22382139Sjp161948 static int do_test_cipherlist(void)
22392139Sjp161948 {
22402139Sjp161948 int i = 0;
22412139Sjp161948 const SSL_METHOD *meth;
22422139Sjp161948 SSL_CIPHER *ci, *tci = NULL;
22432139Sjp161948
22442139Sjp161948 fprintf(stderr, "testing SSLv2 cipher list order: ");
22452139Sjp161948 meth = SSLv2_method();
22462139Sjp161948 while ((ci = meth->get_cipher(i++)) != NULL)
22472139Sjp161948 {
22482139Sjp161948 if (tci != NULL)
22492139Sjp161948 if (ci->id >= tci->id)
22502139Sjp161948 {
22512139Sjp161948 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
22522139Sjp161948 return 0;
22532139Sjp161948 }
22542139Sjp161948 tci = ci;
22552139Sjp161948 }
22562139Sjp161948 fprintf(stderr, "ok\n");
22572139Sjp161948
22582139Sjp161948 fprintf(stderr, "testing SSLv3 cipher list order: ");
22592139Sjp161948 meth = SSLv3_method();
22602139Sjp161948 tci = NULL;
22612139Sjp161948 while ((ci = meth->get_cipher(i++)) != NULL)
22622139Sjp161948 {
22632139Sjp161948 if (tci != NULL)
22642139Sjp161948 if (ci->id >= tci->id)
22652139Sjp161948 {
22662139Sjp161948 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
22672139Sjp161948 return 0;
22682139Sjp161948 }
22692139Sjp161948 tci = ci;
22702139Sjp161948 }
22712139Sjp161948 fprintf(stderr, "ok\n");
22722139Sjp161948
22732139Sjp161948 fprintf(stderr, "testing TLSv1 cipher list order: ");
22742139Sjp161948 meth = TLSv1_method();
22752139Sjp161948 tci = NULL;
22762139Sjp161948 while ((ci = meth->get_cipher(i++)) != NULL)
22772139Sjp161948 {
22782139Sjp161948 if (tci != NULL)
22792139Sjp161948 if (ci->id >= tci->id)
22802139Sjp161948 {
22812139Sjp161948 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
22822139Sjp161948 return 0;
22832139Sjp161948 }
22842139Sjp161948 tci = ci;
22852139Sjp161948 }
22862139Sjp161948 fprintf(stderr, "ok\n");
22872139Sjp161948
22882139Sjp161948 return 1;
22892139Sjp161948 }
22900Sstevel@tonic-gate #endif
2291