ssltest.c revision 280304
155714Skris/* ssl/ssltest.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280304Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280304Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280304Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280304Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280304Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 58109998Smarkm/* ==================================================================== 59109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 60109998Smarkm * 61109998Smarkm * Redistribution and use in source and binary forms, with or without 62109998Smarkm * modification, are permitted provided that the following conditions 63109998Smarkm * are met: 64109998Smarkm * 65109998Smarkm * 1. Redistributions of source code must retain the above copyright 66280304Sjkim * notice, this list of conditions and the following disclaimer. 67109998Smarkm * 68109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 69109998Smarkm * notice, this list of conditions and the following disclaimer in 70109998Smarkm * the documentation and/or other materials provided with the 71109998Smarkm * distribution. 72109998Smarkm * 73109998Smarkm * 3. All advertising materials mentioning features or use of this 74109998Smarkm * software must display the following acknowledgment: 75109998Smarkm * "This product includes software developed by the OpenSSL Project 76109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77109998Smarkm * 78109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79109998Smarkm * endorse or promote products derived from this software without 80109998Smarkm * prior written permission. For written permission, please contact 81109998Smarkm * openssl-core@openssl.org. 82109998Smarkm * 83109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 84109998Smarkm * nor may "OpenSSL" appear in their names without prior written 85109998Smarkm * permission of the OpenSSL Project. 86109998Smarkm * 87109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 88109998Smarkm * acknowledgment: 89109998Smarkm * "This product includes software developed by the OpenSSL Project 90109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91109998Smarkm * 92109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 104109998Smarkm * ==================================================================== 105109998Smarkm * 106109998Smarkm * This product includes cryptographic software written by Eric Young 107109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 108109998Smarkm * Hudson (tjh@cryptsoft.com). 109109998Smarkm * 110109998Smarkm */ 111160814Ssimon/* ==================================================================== 112160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113280304Sjkim * ECC cipher suite support in OpenSSL originally developed by 114160814Ssimon * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 115160814Ssimon */ 116238405Sjkim/* ==================================================================== 117238405Sjkim * Copyright 2005 Nokia. All rights reserved. 118238405Sjkim * 119238405Sjkim * The portions of the attached software ("Contribution") is developed by 120238405Sjkim * Nokia Corporation and is licensed pursuant to the OpenSSL open source 121238405Sjkim * license. 122238405Sjkim * 123238405Sjkim * The Contribution, originally written by Mika Kousa and Pasi Eronen of 124238405Sjkim * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 125238405Sjkim * support (see RFC 4279) to OpenSSL. 126238405Sjkim * 127238405Sjkim * No patent licenses or other rights except those expressly stated in 128238405Sjkim * the OpenSSL open source license shall be deemed granted or received 129238405Sjkim * expressly, by implication, estoppel, or otherwise. 130238405Sjkim * 131238405Sjkim * No assurances are provided by Nokia that the Contribution does not 132238405Sjkim * infringe the patent or other intellectual property rights of any third 133238405Sjkim * party or that the license provides you with all the necessary rights 134238405Sjkim * to make use of the Contribution. 135238405Sjkim * 136238405Sjkim * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 137238405Sjkim * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 138238405Sjkim * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 139238405Sjkim * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 140238405Sjkim * OTHERWISE. 141238405Sjkim */ 14255714Skris 143280304Sjkim/* Or gethostname won't be declared properly on Linux and GNU platforms. */ 144280304Sjkim#define _BSD_SOURCE 1 145109998Smarkm 14659191Skris#include <assert.h> 14759191Skris#include <errno.h> 14859191Skris#include <limits.h> 14955714Skris#include <stdio.h> 15055714Skris#include <stdlib.h> 15155714Skris#include <string.h> 15259191Skris#include <time.h> 15355714Skris 154109998Smarkm#define USE_SOCKETS 155109998Smarkm#include "e_os.h" 15655714Skris 157238405Sjkim#ifdef OPENSSL_SYS_VMS 158280304Sjkim/* 159280304Sjkim * Or isascii won't be declared properly on VMS (at least with DECompHP C). 160280304Sjkim */ 161280304Sjkim# define _XOPEN_SOURCE 500 162238405Sjkim#endif 163238405Sjkim 164160814Ssimon#include <ctype.h> 165160814Ssimon 16655714Skris#include <openssl/bio.h> 16755714Skris#include <openssl/crypto.h> 16859191Skris#include <openssl/evp.h> 16955714Skris#include <openssl/x509.h> 170160814Ssimon#include <openssl/x509v3.h> 17155714Skris#include <openssl/ssl.h> 172111147Snectar#ifndef OPENSSL_NO_ENGINE 173280304Sjkim# include <openssl/engine.h> 174111147Snectar#endif 17555714Skris#include <openssl/err.h> 17659191Skris#include <openssl/rand.h> 177160814Ssimon#ifndef OPENSSL_NO_RSA 178280304Sjkim# include <openssl/rsa.h> 179160814Ssimon#endif 180160814Ssimon#ifndef OPENSSL_NO_DSA 181280304Sjkim# include <openssl/dsa.h> 182160814Ssimon#endif 183160814Ssimon#ifndef OPENSSL_NO_DH 184280304Sjkim# include <openssl/dh.h> 185160814Ssimon#endif 186238405Sjkim#ifndef OPENSSL_NO_SRP 187280304Sjkim# include <openssl/srp.h> 188238405Sjkim#endif 189160814Ssimon#include <openssl/bn.h> 190109998Smarkm 191280304Sjkim/* 192280304Sjkim * Or gethostname won't be declared properly 193280304Sjkim * on Compaq platforms (at least with DEC C). 194280304Sjkim * Do not try to put it earlier, or IPv6 includes 195280304Sjkim * get screwed... 196280304Sjkim */ 197280304Sjkim#define _XOPEN_SOURCE_EXTENDED 1 198109998Smarkm 199109998Smarkm#ifdef OPENSSL_SYS_WINDOWS 200280304Sjkim# include <winsock.h> 201109998Smarkm#else 202280304Sjkim# include OPENSSL_UNISTD 20355714Skris#endif 20455714Skris 205109998Smarkm#ifdef OPENSSL_SYS_VMS 206280304Sjkim# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM" 207280304Sjkim# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM" 208109998Smarkm#elif defined(OPENSSL_SYS_WINCE) 209280304Sjkim# define TEST_SERVER_CERT "\\OpenSSL\\server.pem" 210280304Sjkim# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem" 211160814Ssimon#elif defined(OPENSSL_SYS_NETWARE) 212280304Sjkim# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem" 213280304Sjkim# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem" 21455714Skris#else 215280304Sjkim# define TEST_SERVER_CERT "../apps/server.pem" 216280304Sjkim# define TEST_CLIENT_CERT "../apps/client.pem" 21755714Skris#endif 21855714Skris 219280304Sjkim/* 220280304Sjkim * There is really no standard for this, so let's assign some tentative 221280304Sjkim * numbers. In any case, these numbers are only for this test 222280304Sjkim */ 223280304Sjkim#define COMP_RLE 255 224280304Sjkim#define COMP_ZLIB 1 225109998Smarkm 22659191Skrisstatic int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); 227109998Smarkm#ifndef OPENSSL_NO_RSA 228280304Sjkimstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); 22968651Skrisstatic void free_tmp_rsa(void); 23055714Skris#endif 231109998Smarkmstatic int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg); 232160814Ssimon#define APP_CALLBACK_STRING "Test Callback Argument" 233280304Sjkimstruct app_verify_arg { 234280304Sjkim char *string; 235280304Sjkim int app_verify; 236280304Sjkim int allow_proxy_certs; 237280304Sjkim char *proxy_auth; 238280304Sjkim char *proxy_cond; 239280304Sjkim}; 240109998Smarkm 241109998Smarkm#ifndef OPENSSL_NO_DH 24255714Skrisstatic DH *get_dh512(void); 24359191Skrisstatic DH *get_dh1024(void); 24459191Skrisstatic DH *get_dh1024dsa(void); 24555714Skris#endif 24655714Skris 247280304Sjkimstatic char *psk_key = NULL; /* by default PSK is not used */ 248238405Sjkim#ifndef OPENSSL_NO_PSK 249280304Sjkimstatic unsigned int psk_client_callback(SSL *ssl, const char *hint, 250280304Sjkim char *identity, 251280304Sjkim unsigned int max_identity_len, 252280304Sjkim unsigned char *psk, 253280304Sjkim unsigned int max_psk_len); 254280304Sjkimstatic unsigned int psk_server_callback(SSL *ssl, const char *identity, 255280304Sjkim unsigned char *psk, 256280304Sjkim unsigned int max_psk_len); 257238405Sjkim#endif 258238405Sjkim 259238405Sjkim#ifndef OPENSSL_NO_SRP 260238405Sjkim/* SRP client */ 261238405Sjkim/* This is a context that we pass to all callbacks */ 262280304Sjkimtypedef struct srp_client_arg_st { 263280304Sjkim char *srppassin; 264280304Sjkim char *srplogin; 265280304Sjkim} SRP_CLIENT_ARG; 266238405Sjkim 267280304Sjkim# define PWD_STRLEN 1024 268238405Sjkim 269280304Sjkimstatic char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg) 270280304Sjkim{ 271280304Sjkim SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; 272280304Sjkim return BUF_strdup((char *)srp_client_arg->srppassin); 273280304Sjkim} 274238405Sjkim 275238405Sjkim/* SRP server */ 276238405Sjkim/* This is a context that we pass to SRP server callbacks */ 277280304Sjkimtypedef struct srp_server_arg_st { 278280304Sjkim char *expected_user; 279280304Sjkim char *pass; 280280304Sjkim} SRP_SERVER_ARG; 281238405Sjkim 282238405Sjkimstatic int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) 283280304Sjkim{ 284280304Sjkim SRP_SERVER_ARG *p = (SRP_SERVER_ARG *)arg; 285238405Sjkim 286280304Sjkim if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0) { 287280304Sjkim fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s)); 288280304Sjkim return SSL3_AL_FATAL; 289280304Sjkim } 290280304Sjkim if (SSL_set_srp_server_param_pw(s, p->expected_user, p->pass, "1024") < 0) { 291280304Sjkim *ad = SSL_AD_INTERNAL_ERROR; 292280304Sjkim return SSL3_AL_FATAL; 293280304Sjkim } 294280304Sjkim return SSL_ERROR_NONE; 295280304Sjkim} 296238405Sjkim#endif 297238405Sjkim 298280304Sjkimstatic BIO *bio_err = NULL; 299280304Sjkimstatic BIO *bio_stdout = NULL; 30059191Skris 301280304Sjkimstatic char *cipher = NULL; 302280304Sjkimstatic int verbose = 0; 303280304Sjkimstatic int debug = 0; 30455714Skris#if 0 30555714Skris/* Not used yet. */ 306280304Sjkim# ifdef FIONBIO 307280304Sjkimstatic int s_nbio = 0; 308280304Sjkim# endif 30955714Skris#endif 31055714Skris 311280304Sjkimstatic const char rnd_seed[] = 312280304Sjkim "string to make the random number generator think it has entropy"; 31355714Skris 314280304Sjkimint doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time, 315280304Sjkim clock_t *c_time); 316280304Sjkimint doit(SSL *s_ssl, SSL *c_ssl, long bytes); 317160814Ssimonstatic int do_test_cipherlist(void); 31855714Skrisstatic void sv_usage(void) 319280304Sjkim{ 320280304Sjkim fprintf(stderr, "usage: ssltest [args ...]\n"); 321280304Sjkim fprintf(stderr, "\n"); 322194206Ssimon#ifdef OPENSSL_FIPS 323280304Sjkim fprintf(stderr, "-F - run test in FIPS mode\n"); 324194206Ssimon#endif 325280304Sjkim fprintf(stderr, " -server_auth - check server certificate\n"); 326280304Sjkim fprintf(stderr, " -client_auth - do client authentication\n"); 327280304Sjkim fprintf(stderr, " -proxy - allow proxy certificates\n"); 328280304Sjkim fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n"); 329280304Sjkim fprintf(stderr, 330280304Sjkim " -proxy_cond <val> - experssion to test proxy policy rights\n"); 331280304Sjkim fprintf(stderr, " -v - more output\n"); 332280304Sjkim fprintf(stderr, " -d - debug output\n"); 333280304Sjkim fprintf(stderr, " -reuse - use session-id reuse\n"); 334280304Sjkim fprintf(stderr, " -num <val> - number of connections to perform\n"); 335280304Sjkim fprintf(stderr, 336280304Sjkim " -bytes <val> - number of bytes to swap between client/server\n"); 337109998Smarkm#ifndef OPENSSL_NO_DH 338280304Sjkim fprintf(stderr, 339280304Sjkim " -dhe1024 - use 1024 bit key (safe prime) for DHE\n"); 340280304Sjkim fprintf(stderr, 341280304Sjkim " -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); 342280304Sjkim fprintf(stderr, " -no_dhe - disable DHE\n"); 34355714Skris#endif 344160814Ssimon#ifndef OPENSSL_NO_ECDH 345280304Sjkim fprintf(stderr, " -no_ecdhe - disable ECDHE\n"); 346160814Ssimon#endif 347238405Sjkim#ifndef OPENSSL_NO_PSK 348280304Sjkim fprintf(stderr, " -psk arg - PSK in hex (without 0x)\n"); 349238405Sjkim#endif 350238405Sjkim#ifndef OPENSSL_NO_SRP 351280304Sjkim fprintf(stderr, " -srpuser user - SRP username to use\n"); 352280304Sjkim fprintf(stderr, " -srppass arg - password for 'user'\n"); 353238405Sjkim#endif 354109998Smarkm#ifndef OPENSSL_NO_SSL2 355280304Sjkim fprintf(stderr, " -ssl2 - use SSLv2\n"); 35655714Skris#endif 357276864Sjkim#ifndef OPENSSL_NO_SSL3_METHOD 358280304Sjkim fprintf(stderr, " -ssl3 - use SSLv3\n"); 35955714Skris#endif 360109998Smarkm#ifndef OPENSSL_NO_TLS1 361280304Sjkim fprintf(stderr, " -tls1 - use TLSv1\n"); 36255714Skris#endif 363280304Sjkim fprintf(stderr, " -CApath arg - PEM format directory of CA's\n"); 364280304Sjkim fprintf(stderr, " -CAfile arg - PEM format file of CA's\n"); 365280304Sjkim fprintf(stderr, " -cert arg - Server certificate file\n"); 366280304Sjkim fprintf(stderr, 367280304Sjkim " -key arg - Server key file (default: same as -cert)\n"); 368280304Sjkim fprintf(stderr, " -c_cert arg - Client certificate file\n"); 369280304Sjkim fprintf(stderr, 370280304Sjkim " -c_key arg - Client key file (default: same as -c_cert)\n"); 371280304Sjkim fprintf(stderr, " -cipher arg - The cipher list\n"); 372280304Sjkim fprintf(stderr, " -bio_pair - Use BIO pairs\n"); 373280304Sjkim fprintf(stderr, " -f - Test even cases that can't work\n"); 374280304Sjkim fprintf(stderr, 375280304Sjkim " -time - measure processor time used by client and server\n"); 376280304Sjkim fprintf(stderr, " -zlib - use zlib compression\n"); 377280304Sjkim fprintf(stderr, " -rle - use rle compression\n"); 378160814Ssimon#ifndef OPENSSL_NO_ECDH 379280304Sjkim fprintf(stderr, 380280304Sjkim " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" 381280304Sjkim " Use \"openssl ecparam -list_curves\" for all names\n" 382280304Sjkim " (default is sect163r2).\n"); 383160814Ssimon#endif 384280304Sjkim fprintf(stderr, 385280304Sjkim " -test_cipherlist - Verifies the order of the ssl cipher lists.\n" 386280304Sjkim " When this option is requested, the cipherlist\n" 387280304Sjkim " tests are run instead of handshake tests.\n"); 388280304Sjkim} 38955714Skris 39059191Skrisstatic void print_details(SSL *c_ssl, const char *prefix) 391280304Sjkim{ 392280304Sjkim const SSL_CIPHER *ciph; 393280304Sjkim X509 *cert; 394280304Sjkim 395280304Sjkim ciph = SSL_get_current_cipher(c_ssl); 396280304Sjkim BIO_printf(bio_stdout, "%s%s, cipher %s %s", 397280304Sjkim prefix, 398280304Sjkim SSL_get_version(c_ssl), 399280304Sjkim SSL_CIPHER_get_version(ciph), SSL_CIPHER_get_name(ciph)); 400280304Sjkim cert = SSL_get_peer_certificate(c_ssl); 401280304Sjkim if (cert != NULL) { 402280304Sjkim EVP_PKEY *pkey = X509_get_pubkey(cert); 403280304Sjkim if (pkey != NULL) { 404280304Sjkim if (0) ; 405109998Smarkm#ifndef OPENSSL_NO_RSA 406280304Sjkim else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL 407280304Sjkim && pkey->pkey.rsa->n != NULL) { 408280304Sjkim BIO_printf(bio_stdout, ", %d bit RSA", 409280304Sjkim BN_num_bits(pkey->pkey.rsa->n)); 410280304Sjkim } 41159191Skris#endif 412109998Smarkm#ifndef OPENSSL_NO_DSA 413280304Sjkim else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL 414280304Sjkim && pkey->pkey.dsa->p != NULL) { 415280304Sjkim BIO_printf(bio_stdout, ", %d bit DSA", 416280304Sjkim BN_num_bits(pkey->pkey.dsa->p)); 417280304Sjkim } 41859191Skris#endif 419280304Sjkim EVP_PKEY_free(pkey); 420280304Sjkim } 421280304Sjkim X509_free(cert); 422280304Sjkim } 423280304Sjkim /* 424280304Sjkim * The SSL API does not allow us to look at temporary RSA/DH keys, 425280304Sjkim * otherwise we should print their lengths too 426280304Sjkim */ 427280304Sjkim BIO_printf(bio_stdout, "\n"); 428280304Sjkim} 42959191Skris 430109998Smarkmstatic void lock_dbg_cb(int mode, int type, const char *file, int line) 431280304Sjkim{ 432280304Sjkim static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ 433280304Sjkim const char *errstr = NULL; 434280304Sjkim int rw; 435109998Smarkm 436280304Sjkim rw = mode & (CRYPTO_READ | CRYPTO_WRITE); 437280304Sjkim if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { 438280304Sjkim errstr = "invalid mode"; 439280304Sjkim goto err; 440280304Sjkim } 441109998Smarkm 442280304Sjkim if (type < 0 || type >= CRYPTO_NUM_LOCKS) { 443280304Sjkim errstr = "type out of bounds"; 444280304Sjkim goto err; 445280304Sjkim } 446109998Smarkm 447280304Sjkim if (mode & CRYPTO_LOCK) { 448280304Sjkim if (modes[type]) { 449280304Sjkim errstr = "already locked"; 450280304Sjkim /* 451280304Sjkim * must not happen in a single-threaded program (would deadlock) 452280304Sjkim */ 453280304Sjkim goto err; 454280304Sjkim } 455109998Smarkm 456280304Sjkim modes[type] = rw; 457280304Sjkim } else if (mode & CRYPTO_UNLOCK) { 458280304Sjkim if (!modes[type]) { 459280304Sjkim errstr = "not locked"; 460280304Sjkim goto err; 461280304Sjkim } 462109998Smarkm 463280304Sjkim if (modes[type] != rw) { 464280304Sjkim errstr = (rw == CRYPTO_READ) ? 465280304Sjkim "CRYPTO_r_unlock on write lock" : 466280304Sjkim "CRYPTO_w_unlock on read lock"; 467280304Sjkim } 468280304Sjkim 469280304Sjkim modes[type] = 0; 470280304Sjkim } else { 471280304Sjkim errstr = "invalid mode"; 472280304Sjkim goto err; 473280304Sjkim } 474280304Sjkim 475109998Smarkm err: 476280304Sjkim if (errstr) { 477280304Sjkim /* we cannot use bio_err here */ 478280304Sjkim fprintf(stderr, 479280304Sjkim "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", 480280304Sjkim errstr, mode, type, file, line); 481280304Sjkim } 482280304Sjkim} 483109998Smarkm 484238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 485280304Sjkimstruct cb_info_st { 486280304Sjkim void *input; 487280304Sjkim size_t len; 488280304Sjkim int ret; 489280304Sjkim}; 490238405Sjkimstruct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */ 491238405Sjkimstruct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */ 492238405Sjkimstruct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */ 493238405Sjkimstruct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */ 494160814Ssimon 495238405Sjkimint opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_) 496280304Sjkim{ 497280304Sjkim struct cb_info_st *arg = arg_; 498238405Sjkim 499280304Sjkim if (arg == NULL) 500280304Sjkim return 1; 501280304Sjkim 502280304Sjkim if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len)) 503280304Sjkim return 0; 504280304Sjkim return arg->ret; 505280304Sjkim} 506238405Sjkim#endif 507238405Sjkim 50855714Skrisint main(int argc, char *argv[]) 509280304Sjkim{ 510280304Sjkim char *CApath = NULL, *CAfile = NULL; 511280304Sjkim int badop = 0; 512280304Sjkim int bio_pair = 0; 513280304Sjkim int force = 0; 514280304Sjkim int tls1 = 0, ssl2 = 0, ssl3 = 0, ret = 1; 515280304Sjkim int client_auth = 0; 516280304Sjkim int server_auth = 0, i; 517280304Sjkim struct app_verify_arg app_verify_arg = 518280304Sjkim { APP_CALLBACK_STRING, 0, 0, NULL, NULL }; 519280304Sjkim char *server_cert = TEST_SERVER_CERT; 520280304Sjkim char *server_key = NULL; 521280304Sjkim char *client_cert = TEST_CLIENT_CERT; 522280304Sjkim char *client_key = NULL; 523160814Ssimon#ifndef OPENSSL_NO_ECDH 524280304Sjkim char *named_curve = NULL; 525160814Ssimon#endif 526280304Sjkim SSL_CTX *s_ctx = NULL; 527280304Sjkim SSL_CTX *c_ctx = NULL; 528280304Sjkim const SSL_METHOD *meth = NULL; 529280304Sjkim SSL *c_ssl, *s_ssl; 530280304Sjkim int number = 1, reuse = 0; 531280304Sjkim long bytes = 256L; 532109998Smarkm#ifndef OPENSSL_NO_DH 533280304Sjkim DH *dh; 534280304Sjkim int dhe1024 = 0, dhe1024dsa = 0; 53555714Skris#endif 536160814Ssimon#ifndef OPENSSL_NO_ECDH 537280304Sjkim EC_KEY *ecdh = NULL; 538160814Ssimon#endif 539238405Sjkim#ifndef OPENSSL_NO_SRP 540280304Sjkim /* client */ 541280304Sjkim SRP_CLIENT_ARG srp_client_arg = { NULL, NULL }; 542280304Sjkim /* server */ 543280304Sjkim SRP_SERVER_ARG srp_server_arg = { NULL, NULL }; 544238405Sjkim#endif 545280304Sjkim int no_dhe = 0; 546280304Sjkim int no_ecdhe = 0; 547280304Sjkim int no_psk = 0; 548280304Sjkim int print_time = 0; 549280304Sjkim clock_t s_time = 0, c_time = 0; 550280304Sjkim int comp = 0; 551160814Ssimon#ifndef OPENSSL_NO_COMP 552280304Sjkim COMP_METHOD *cm = NULL; 553280304Sjkim STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; 554142425Snectar#endif 555280304Sjkim int test_cipherlist = 0; 556194206Ssimon#ifdef OPENSSL_FIPS 557280304Sjkim int fips_mode = 0; 558194206Ssimon#endif 559280304Sjkim int no_protocol = 0; 56055714Skris 561280304Sjkim verbose = 0; 562280304Sjkim debug = 0; 563280304Sjkim cipher = 0; 564109998Smarkm 565280304Sjkim bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 566109998Smarkm 567280304Sjkim CRYPTO_set_locking_callback(lock_dbg_cb); 568109998Smarkm 569280304Sjkim /* enable memory leak checking unless explicitly disabled */ 570280304Sjkim if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) 571280304Sjkim && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 572280304Sjkim CRYPTO_malloc_debug_init(); 573280304Sjkim CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 574280304Sjkim } else { 575280304Sjkim /* OPENSSL_DEBUG_MEMORY=off */ 576280304Sjkim CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 577280304Sjkim } 578280304Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 57959191Skris 580280304Sjkim RAND_seed(rnd_seed, sizeof rnd_seed); 58159191Skris 582280304Sjkim bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); 58355714Skris 584280304Sjkim argc--; 585280304Sjkim argv++; 58655714Skris 587280304Sjkim while (argc >= 1) { 588280304Sjkim if (!strcmp(*argv, "-F")) { 589194206Ssimon#ifdef OPENSSL_FIPS 590280304Sjkim fips_mode = 1; 591194206Ssimon#else 592280304Sjkim fprintf(stderr, 593280304Sjkim "not compiled with FIPS support, so exitting without running.\n"); 594280304Sjkim EXIT(0); 595194206Ssimon#endif 596280304Sjkim } else if (strcmp(*argv, "-server_auth") == 0) 597280304Sjkim server_auth = 1; 598280304Sjkim else if (strcmp(*argv, "-client_auth") == 0) 599280304Sjkim client_auth = 1; 600280304Sjkim else if (strcmp(*argv, "-proxy_auth") == 0) { 601280304Sjkim if (--argc < 1) 602280304Sjkim goto bad; 603280304Sjkim app_verify_arg.proxy_auth = *(++argv); 604280304Sjkim } else if (strcmp(*argv, "-proxy_cond") == 0) { 605280304Sjkim if (--argc < 1) 606280304Sjkim goto bad; 607280304Sjkim app_verify_arg.proxy_cond = *(++argv); 608280304Sjkim } else if (strcmp(*argv, "-v") == 0) 609280304Sjkim verbose = 1; 610280304Sjkim else if (strcmp(*argv, "-d") == 0) 611280304Sjkim debug = 1; 612280304Sjkim else if (strcmp(*argv, "-reuse") == 0) 613280304Sjkim reuse = 1; 614280304Sjkim else if (strcmp(*argv, "-dhe1024") == 0) { 615109998Smarkm#ifndef OPENSSL_NO_DH 616280304Sjkim dhe1024 = 1; 617109998Smarkm#else 618280304Sjkim fprintf(stderr, 619280304Sjkim "ignoring -dhe1024, since I'm compiled without DH\n"); 620109998Smarkm#endif 621280304Sjkim } else if (strcmp(*argv, "-dhe1024dsa") == 0) { 622109998Smarkm#ifndef OPENSSL_NO_DH 623280304Sjkim dhe1024dsa = 1; 624109998Smarkm#else 625280304Sjkim fprintf(stderr, 626280304Sjkim "ignoring -dhe1024, since I'm compiled without DH\n"); 62759191Skris#endif 628280304Sjkim } else if (strcmp(*argv, "-no_dhe") == 0) 629280304Sjkim no_dhe = 1; 630280304Sjkim else if (strcmp(*argv, "-no_ecdhe") == 0) 631280304Sjkim no_ecdhe = 1; 632280304Sjkim else if (strcmp(*argv, "-psk") == 0) { 633280304Sjkim if (--argc < 1) 634280304Sjkim goto bad; 635280304Sjkim psk_key = *(++argv); 636238405Sjkim#ifndef OPENSSL_NO_PSK 637280304Sjkim if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key)) { 638280304Sjkim BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); 639280304Sjkim goto bad; 640280304Sjkim } 641238405Sjkim#else 642280304Sjkim no_psk = 1; 643238405Sjkim#endif 644280304Sjkim } 645238405Sjkim#ifndef OPENSSL_NO_SRP 646280304Sjkim else if (strcmp(*argv, "-srpuser") == 0) { 647280304Sjkim if (--argc < 1) 648280304Sjkim goto bad; 649280304Sjkim srp_server_arg.expected_user = srp_client_arg.srplogin = 650280304Sjkim *(++argv); 651280304Sjkim tls1 = 1; 652280304Sjkim } else if (strcmp(*argv, "-srppass") == 0) { 653280304Sjkim if (--argc < 1) 654280304Sjkim goto bad; 655280304Sjkim srp_server_arg.pass = srp_client_arg.srppassin = *(++argv); 656280304Sjkim tls1 = 1; 657280304Sjkim } 658238405Sjkim#endif 659280304Sjkim else if (strcmp(*argv, "-ssl2") == 0) { 660276864Sjkim#ifdef OPENSSL_NO_SSL2 661280304Sjkim no_protocol = 1; 662276864Sjkim#endif 663280304Sjkim ssl2 = 1; 664280304Sjkim } else if (strcmp(*argv, "-tls1") == 0) { 665276864Sjkim#ifdef OPENSSL_NO_TLS1 666280304Sjkim no_protocol = 1; 667276864Sjkim#endif 668280304Sjkim tls1 = 1; 669280304Sjkim } else if (strcmp(*argv, "-ssl3") == 0) { 670276864Sjkim#ifdef OPENSSL_NO_SSL3_METHOD 671280304Sjkim no_protocol = 1; 672276864Sjkim#endif 673280304Sjkim ssl3 = 1; 674280304Sjkim } else if (strncmp(*argv, "-num", 4) == 0) { 675280304Sjkim if (--argc < 1) 676280304Sjkim goto bad; 677280304Sjkim number = atoi(*(++argv)); 678280304Sjkim if (number == 0) 679280304Sjkim number = 1; 680280304Sjkim } else if (strcmp(*argv, "-bytes") == 0) { 681280304Sjkim if (--argc < 1) 682280304Sjkim goto bad; 683280304Sjkim bytes = atol(*(++argv)); 684280304Sjkim if (bytes == 0L) 685280304Sjkim bytes = 1L; 686280304Sjkim i = strlen(argv[0]); 687280304Sjkim if (argv[0][i - 1] == 'k') 688280304Sjkim bytes *= 1024L; 689280304Sjkim if (argv[0][i - 1] == 'm') 690280304Sjkim bytes *= 1024L * 1024L; 691280304Sjkim } else if (strcmp(*argv, "-cert") == 0) { 692280304Sjkim if (--argc < 1) 693280304Sjkim goto bad; 694280304Sjkim server_cert = *(++argv); 695280304Sjkim } else if (strcmp(*argv, "-s_cert") == 0) { 696280304Sjkim if (--argc < 1) 697280304Sjkim goto bad; 698280304Sjkim server_cert = *(++argv); 699280304Sjkim } else if (strcmp(*argv, "-key") == 0) { 700280304Sjkim if (--argc < 1) 701280304Sjkim goto bad; 702280304Sjkim server_key = *(++argv); 703280304Sjkim } else if (strcmp(*argv, "-s_key") == 0) { 704280304Sjkim if (--argc < 1) 705280304Sjkim goto bad; 706280304Sjkim server_key = *(++argv); 707280304Sjkim } else if (strcmp(*argv, "-c_cert") == 0) { 708280304Sjkim if (--argc < 1) 709280304Sjkim goto bad; 710280304Sjkim client_cert = *(++argv); 711280304Sjkim } else if (strcmp(*argv, "-c_key") == 0) { 712280304Sjkim if (--argc < 1) 713280304Sjkim goto bad; 714280304Sjkim client_key = *(++argv); 715280304Sjkim } else if (strcmp(*argv, "-cipher") == 0) { 716280304Sjkim if (--argc < 1) 717280304Sjkim goto bad; 718280304Sjkim cipher = *(++argv); 719280304Sjkim } else if (strcmp(*argv, "-CApath") == 0) { 720280304Sjkim if (--argc < 1) 721280304Sjkim goto bad; 722280304Sjkim CApath = *(++argv); 723280304Sjkim } else if (strcmp(*argv, "-CAfile") == 0) { 724280304Sjkim if (--argc < 1) 725280304Sjkim goto bad; 726280304Sjkim CAfile = *(++argv); 727280304Sjkim } else if (strcmp(*argv, "-bio_pair") == 0) { 728280304Sjkim bio_pair = 1; 729280304Sjkim } else if (strcmp(*argv, "-f") == 0) { 730280304Sjkim force = 1; 731280304Sjkim } else if (strcmp(*argv, "-time") == 0) { 732280304Sjkim print_time = 1; 733280304Sjkim } else if (strcmp(*argv, "-zlib") == 0) { 734280304Sjkim comp = COMP_ZLIB; 735280304Sjkim } else if (strcmp(*argv, "-rle") == 0) { 736280304Sjkim comp = COMP_RLE; 737280304Sjkim } else if (strcmp(*argv, "-named_curve") == 0) { 738280304Sjkim if (--argc < 1) 739280304Sjkim goto bad; 740280304Sjkim#ifndef OPENSSL_NO_ECDH 741280304Sjkim named_curve = *(++argv); 742160814Ssimon#else 743280304Sjkim fprintf(stderr, 744280304Sjkim "ignoring -named_curve, since I'm compiled without ECDH\n"); 745280304Sjkim ++argv; 746160814Ssimon#endif 747280304Sjkim } else if (strcmp(*argv, "-app_verify") == 0) { 748280304Sjkim app_verify_arg.app_verify = 1; 749280304Sjkim } else if (strcmp(*argv, "-proxy") == 0) { 750280304Sjkim app_verify_arg.allow_proxy_certs = 1; 751280304Sjkim } else if (strcmp(*argv, "-test_cipherlist") == 0) { 752280304Sjkim test_cipherlist = 1; 753280304Sjkim } else { 754280304Sjkim fprintf(stderr, "unknown option %s\n", *argv); 755280304Sjkim badop = 1; 756280304Sjkim break; 757280304Sjkim } 758280304Sjkim argc--; 759280304Sjkim argv++; 760280304Sjkim } 761280304Sjkim if (badop) { 762280304Sjkim bad: 763280304Sjkim sv_usage(); 764280304Sjkim goto end; 765280304Sjkim } 76655714Skris 767280304Sjkim /* 768280304Sjkim * test_cipherlist prevails over protocol switch: we test the cipherlist 769280304Sjkim * for all enabled protocols. 770280304Sjkim */ 771280304Sjkim if (test_cipherlist == 1) { 772280304Sjkim /* 773280304Sjkim * ensure that the cipher list are correctly sorted and exit 774280304Sjkim */ 775280304Sjkim fprintf(stdout, "Testing cipherlist order only. Ignoring all " 776280304Sjkim "other options.\n"); 777280304Sjkim if (do_test_cipherlist() == 0) 778280304Sjkim EXIT(1); 779280304Sjkim ret = 0; 780280304Sjkim goto end; 781280304Sjkim } 782142425Snectar 783280304Sjkim if (ssl2 + ssl3 + tls1 > 1) { 784280304Sjkim fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should " 785280304Sjkim "be requested.\n"); 786280304Sjkim EXIT(1); 787280304Sjkim } 788276864Sjkim 789280304Sjkim /* 790280304Sjkim * Testing was requested for a compiled-out protocol (e.g. SSLv2). 791280304Sjkim * Ideally, we would error out, but the generic test wrapper can't know 792280304Sjkim * when to expect failure. So we do nothing and return success. 793280304Sjkim */ 794280304Sjkim if (no_protocol) { 795280304Sjkim fprintf(stderr, "Testing was requested for a disabled protocol. " 796280304Sjkim "Skipping tests.\n"); 797280304Sjkim ret = 0; 798280304Sjkim goto end; 799280304Sjkim } 800276864Sjkim 801280304Sjkim if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) { 802280304Sjkim fprintf(stderr, "This case cannot work. Use -f to perform " 803280304Sjkim "the test anyway (and\n-d to see what happens), " 804280304Sjkim "or add one of -ssl2, -ssl3, -tls1, -reuse\n" 805280304Sjkim "to avoid protocol mismatch.\n"); 806280304Sjkim EXIT(1); 807280304Sjkim } 808194206Ssimon#ifdef OPENSSL_FIPS 809280304Sjkim if (fips_mode) { 810280304Sjkim if (!FIPS_mode_set(1)) { 811280304Sjkim ERR_load_crypto_strings(); 812280304Sjkim ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE)); 813280304Sjkim EXIT(1); 814280304Sjkim } else 815280304Sjkim fprintf(stderr, "*** IN FIPS MODE ***\n"); 816280304Sjkim } 817194206Ssimon#endif 818194206Ssimon 819280304Sjkim if (print_time) { 820280304Sjkim if (!bio_pair) { 821280304Sjkim fprintf(stderr, "Using BIO pair (-bio_pair)\n"); 822280304Sjkim bio_pair = 1; 823280304Sjkim } 824280304Sjkim if (number < 50 && !force) 825280304Sjkim fprintf(stderr, 826280304Sjkim "Warning: For accurate timings, use more connections (e.g. -num 1000)\n"); 827280304Sjkim } 82859191Skris 829280304Sjkim/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */ 83055714Skris 831280304Sjkim SSL_library_init(); 832280304Sjkim SSL_load_error_strings(); 83355714Skris 834160814Ssimon#ifndef OPENSSL_NO_COMP 835280304Sjkim if (comp == COMP_ZLIB) 836280304Sjkim cm = COMP_zlib(); 837280304Sjkim if (comp == COMP_RLE) 838280304Sjkim cm = COMP_rle(); 839280304Sjkim if (cm != NULL) { 840280304Sjkim if (cm->type != NID_undef) { 841280304Sjkim if (SSL_COMP_add_compression_method(comp, cm) != 0) { 842280304Sjkim fprintf(stderr, "Failed to add compression method\n"); 843280304Sjkim ERR_print_errors_fp(stderr); 844280304Sjkim } 845280304Sjkim } else { 846280304Sjkim fprintf(stderr, 847280304Sjkim "Warning: %s compression not supported\n", 848280304Sjkim (comp == COMP_RLE ? "rle" : 849280304Sjkim (comp == COMP_ZLIB ? "zlib" : "unknown"))); 850280304Sjkim ERR_print_errors_fp(stderr); 851280304Sjkim } 852280304Sjkim } 853280304Sjkim ssl_comp_methods = SSL_COMP_get_compression_methods(); 854280304Sjkim fprintf(stderr, "Available compression methods:\n"); 855280304Sjkim { 856280304Sjkim int j, n = sk_SSL_COMP_num(ssl_comp_methods); 857280304Sjkim if (n == 0) 858280304Sjkim fprintf(stderr, " NONE\n"); 859280304Sjkim else 860280304Sjkim for (j = 0; j < n; j++) { 861280304Sjkim SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); 862280304Sjkim fprintf(stderr, " %d: %s\n", c->id, c->name); 863280304Sjkim } 864280304Sjkim } 865160814Ssimon#endif 866109998Smarkm 867280304Sjkim /* 868280304Sjkim * At this point, ssl2/ssl3/tls1 is only set if the protocol is 869280304Sjkim * available. (Otherwise we exit early.) However the compiler doesn't 870280304Sjkim * know this, so we ifdef. 871280304Sjkim */ 872276864Sjkim#ifndef OPENSSL_NO_SSL2 873280304Sjkim if (ssl2) 874280304Sjkim meth = SSLv2_method(); 875280304Sjkim else 876276864Sjkim#endif 877276864Sjkim#ifndef OPENSSL_NO_SSL3 878280304Sjkim if (ssl3) 879280304Sjkim meth = SSLv3_method(); 880280304Sjkim else 881276864Sjkim#endif 882276864Sjkim#ifndef OPENSSL_NO_TLS1 883280304Sjkim if (tls1) 884280304Sjkim meth = TLSv1_method(); 885280304Sjkim else 88655714Skris#endif 887280304Sjkim meth = SSLv23_method(); 88855714Skris 889280304Sjkim c_ctx = SSL_CTX_new(meth); 890280304Sjkim s_ctx = SSL_CTX_new(meth); 891280304Sjkim if ((c_ctx == NULL) || (s_ctx == NULL)) { 892280304Sjkim ERR_print_errors(bio_err); 893280304Sjkim goto end; 894280304Sjkim } 89555714Skris 896280304Sjkim if (cipher != NULL) { 897280304Sjkim SSL_CTX_set_cipher_list(c_ctx, cipher); 898280304Sjkim SSL_CTX_set_cipher_list(s_ctx, cipher); 899280304Sjkim } 900109998Smarkm#ifndef OPENSSL_NO_DH 901280304Sjkim if (!no_dhe) { 902280304Sjkim if (dhe1024dsa) { 903280304Sjkim /* 904280304Sjkim * use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks 905280304Sjkim */ 906280304Sjkim SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); 907280304Sjkim dh = get_dh1024dsa(); 908280304Sjkim } else if (dhe1024) 909280304Sjkim dh = get_dh1024(); 910280304Sjkim else 911280304Sjkim dh = get_dh512(); 912280304Sjkim SSL_CTX_set_tmp_dh(s_ctx, dh); 913280304Sjkim DH_free(dh); 914280304Sjkim } 91559191Skris#else 916280304Sjkim (void)no_dhe; 91755714Skris#endif 91855714Skris 919160814Ssimon#ifndef OPENSSL_NO_ECDH 920280304Sjkim if (!no_ecdhe) { 921280304Sjkim int nid; 922160814Ssimon 923280304Sjkim if (named_curve != NULL) { 924280304Sjkim nid = OBJ_sn2nid(named_curve); 925280304Sjkim if (nid == 0) { 926280304Sjkim BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); 927280304Sjkim goto end; 928280304Sjkim } 929280304Sjkim } else 930280304Sjkim# ifdef OPENSSL_NO_EC2M 931280304Sjkim nid = NID_X9_62_prime256v1; 932280304Sjkim# else 933280304Sjkim nid = NID_sect163r2; 934280304Sjkim# endif 935160814Ssimon 936280304Sjkim ecdh = EC_KEY_new_by_curve_name(nid); 937280304Sjkim if (ecdh == NULL) { 938280304Sjkim BIO_printf(bio_err, "unable to create curve\n"); 939280304Sjkim goto end; 940280304Sjkim } 941160814Ssimon 942280304Sjkim SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); 943280304Sjkim SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); 944280304Sjkim EC_KEY_free(ecdh); 945280304Sjkim } 946160814Ssimon#else 947280304Sjkim (void)no_ecdhe; 948160814Ssimon#endif 949160814Ssimon 950109998Smarkm#ifndef OPENSSL_NO_RSA 951280304Sjkim SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb); 95255714Skris#endif 95355714Skris 954238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 955280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb); 956280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb); 957280304Sjkim /* or &co2 or NULL */ 958280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); 959280304Sjkim /* or &so2 or NULL */ 960280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); 961238405Sjkim#endif 962238405Sjkim 963280304Sjkim if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, SSL_FILETYPE_PEM)) { 964280304Sjkim ERR_print_errors(bio_err); 965280304Sjkim } else if (!SSL_CTX_use_PrivateKey_file(s_ctx, 966280304Sjkim (server_key ? server_key : 967280304Sjkim server_cert), 968280304Sjkim SSL_FILETYPE_PEM)) { 969280304Sjkim ERR_print_errors(bio_err); 970280304Sjkim goto end; 971280304Sjkim } 97255714Skris 973280304Sjkim if (client_auth) { 974280304Sjkim SSL_CTX_use_certificate_file(c_ctx, client_cert, SSL_FILETYPE_PEM); 975280304Sjkim SSL_CTX_use_PrivateKey_file(c_ctx, 976280304Sjkim (client_key ? client_key : client_cert), 977280304Sjkim SSL_FILETYPE_PEM); 978280304Sjkim } 97955714Skris 980280304Sjkim if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || 981280304Sjkim (!SSL_CTX_set_default_verify_paths(s_ctx)) || 982280304Sjkim (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || 983280304Sjkim (!SSL_CTX_set_default_verify_paths(c_ctx))) { 984280304Sjkim /* fprintf(stderr,"SSL_load_verify_locations\n"); */ 985280304Sjkim ERR_print_errors(bio_err); 986280304Sjkim /* goto end; */ 987280304Sjkim } 98855714Skris 989280304Sjkim if (client_auth) { 990280304Sjkim BIO_printf(bio_err, "client authentication\n"); 991280304Sjkim SSL_CTX_set_verify(s_ctx, 992280304Sjkim SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 993280304Sjkim verify_callback); 994280304Sjkim SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, 995280304Sjkim &app_verify_arg); 996280304Sjkim } 997280304Sjkim if (server_auth) { 998280304Sjkim BIO_printf(bio_err, "server authentication\n"); 999280304Sjkim SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); 1000280304Sjkim SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, 1001280304Sjkim &app_verify_arg); 1002280304Sjkim } 100355714Skris 1004280304Sjkim { 1005280304Sjkim int session_id_context = 0; 1006280304Sjkim SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, 1007280304Sjkim sizeof session_id_context); 1008280304Sjkim } 1009280304Sjkim 1010280304Sjkim /* Use PSK only if PSK key is given */ 1011280304Sjkim if (psk_key != NULL) { 1012280304Sjkim /* 1013280304Sjkim * no_psk is used to avoid putting psk command to openssl tool 1014280304Sjkim */ 1015280304Sjkim if (no_psk) { 1016280304Sjkim /* 1017280304Sjkim * if PSK is not compiled in and psk key is given, do nothing and 1018280304Sjkim * exit successfully 1019280304Sjkim */ 1020280304Sjkim ret = 0; 1021280304Sjkim goto end; 1022280304Sjkim } 1023238405Sjkim#ifndef OPENSSL_NO_PSK 1024280304Sjkim SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback); 1025280304Sjkim SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback); 1026280304Sjkim if (debug) 1027280304Sjkim BIO_printf(bio_err, "setting PSK identity hint to s_ctx\n"); 1028280304Sjkim if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint")) { 1029280304Sjkim BIO_printf(bio_err, "error setting PSK identity hint to s_ctx\n"); 1030280304Sjkim ERR_print_errors(bio_err); 1031280304Sjkim goto end; 1032280304Sjkim } 1033238405Sjkim#endif 1034280304Sjkim } 1035238405Sjkim#ifndef OPENSSL_NO_SRP 1036280304Sjkim if (srp_client_arg.srplogin) { 1037280304Sjkim if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin)) { 1038280304Sjkim BIO_printf(bio_err, "Unable to set SRP username\n"); 1039280304Sjkim goto end; 1040280304Sjkim } 1041280304Sjkim SSL_CTX_set_srp_cb_arg(c_ctx, &srp_client_arg); 1042280304Sjkim SSL_CTX_set_srp_client_pwd_callback(c_ctx, 1043280304Sjkim ssl_give_srp_client_pwd_cb); 1044280304Sjkim /* 1045280304Sjkim * SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength); 1046280304Sjkim */ 1047280304Sjkim } 1048238405Sjkim 1049280304Sjkim if (srp_server_arg.expected_user != NULL) { 1050280304Sjkim SSL_CTX_set_verify(s_ctx, SSL_VERIFY_NONE, verify_callback); 1051280304Sjkim SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); 1052280304Sjkim SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); 1053280304Sjkim } 1054238405Sjkim#endif 1055238405Sjkim 1056280304Sjkim c_ssl = SSL_new(c_ctx); 1057280304Sjkim s_ssl = SSL_new(s_ctx); 105855714Skris 1059109998Smarkm#ifndef OPENSSL_NO_KRB5 1060280304Sjkim if (c_ssl && c_ssl->kssl_ctx) { 1061280304Sjkim char localhost[MAXHOSTNAMELEN + 2]; 1062109998Smarkm 1063280304Sjkim if (gethostname(localhost, sizeof localhost - 1) == 0) { 1064280304Sjkim localhost[sizeof localhost - 1] = '\0'; 1065280304Sjkim if (strlen(localhost) == sizeof localhost - 1) { 1066280304Sjkim BIO_printf(bio_err, "localhost name too long\n"); 1067280304Sjkim goto end; 1068280304Sjkim } 1069280304Sjkim kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost); 1070280304Sjkim } 1071280304Sjkim } 1072280304Sjkim#endif /* OPENSSL_NO_KRB5 */ 1073109998Smarkm 1074280304Sjkim for (i = 0; i < number; i++) { 1075280304Sjkim if (!reuse) 1076280304Sjkim SSL_set_session(c_ssl, NULL); 1077280304Sjkim if (bio_pair) 1078280304Sjkim ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time); 1079280304Sjkim else 1080280304Sjkim ret = doit(s_ssl, c_ssl, bytes); 1081280304Sjkim } 108255714Skris 1083280304Sjkim if (!verbose) { 1084280304Sjkim print_details(c_ssl, ""); 1085280304Sjkim } 1086280304Sjkim if ((number > 1) || (bytes > 1L)) 1087280304Sjkim BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", number, 1088280304Sjkim bytes); 1089280304Sjkim if (print_time) { 109059191Skris#ifdef CLOCKS_PER_SEC 1091280304Sjkim /* 1092280304Sjkim * "To determine the time in seconds, the value returned by the clock 1093280304Sjkim * function should be divided by the value of the macro 1094280304Sjkim * CLOCKS_PER_SEC." -- ISO/IEC 9899 1095280304Sjkim */ 1096280304Sjkim BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n" 1097280304Sjkim "Approximate total client time: %6.2f s\n", 1098280304Sjkim (double)s_time / CLOCKS_PER_SEC, 1099280304Sjkim (double)c_time / CLOCKS_PER_SEC); 110059191Skris#else 1101280304Sjkim /* 1102280304Sjkim * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on 1103280304Sjkim * NeXTstep/OpenStep 1104280304Sjkim */ 1105280304Sjkim BIO_printf(bio_stdout, 1106280304Sjkim "Approximate total server time: %6.2f units\n" 1107280304Sjkim "Approximate total client time: %6.2f units\n", 1108280304Sjkim (double)s_time, (double)c_time); 110959191Skris#endif 1110280304Sjkim } 111155714Skris 1112280304Sjkim SSL_free(s_ssl); 1113280304Sjkim SSL_free(c_ssl); 111455714Skris 1115280304Sjkim end: 1116280304Sjkim if (s_ctx != NULL) 1117280304Sjkim SSL_CTX_free(s_ctx); 1118280304Sjkim if (c_ctx != NULL) 1119280304Sjkim SSL_CTX_free(c_ctx); 112055714Skris 1121280304Sjkim if (bio_stdout != NULL) 1122280304Sjkim BIO_free(bio_stdout); 112355714Skris 1124109998Smarkm#ifndef OPENSSL_NO_RSA 1125280304Sjkim free_tmp_rsa(); 112668651Skris#endif 1127111147Snectar#ifndef OPENSSL_NO_ENGINE 1128280304Sjkim ENGINE_cleanup(); 1129111147Snectar#endif 1130280304Sjkim CRYPTO_cleanup_all_ex_data(); 1131280304Sjkim ERR_free_strings(); 1132280304Sjkim ERR_remove_thread_state(NULL); 1133280304Sjkim EVP_cleanup(); 1134280304Sjkim CRYPTO_mem_leaks(bio_err); 1135280304Sjkim if (bio_err != NULL) 1136280304Sjkim BIO_free(bio_err); 1137280304Sjkim EXIT(ret); 1138280304Sjkim return ret; 1139280304Sjkim} 114055714Skris 114159191Skrisint doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, 1142280304Sjkim clock_t *s_time, clock_t *c_time) 1143280304Sjkim{ 1144280304Sjkim long cw_num = count, cr_num = count, sw_num = count, sr_num = count; 1145280304Sjkim BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; 1146280304Sjkim BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL; 1147280304Sjkim int ret = 1; 114855714Skris 1149280304Sjkim size_t bufsiz = 256; /* small buffer for testing */ 115055714Skris 1151280304Sjkim if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz)) 1152280304Sjkim goto err; 1153280304Sjkim if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz)) 1154280304Sjkim goto err; 115555714Skris 1156280304Sjkim s_ssl_bio = BIO_new(BIO_f_ssl()); 1157280304Sjkim if (!s_ssl_bio) 1158280304Sjkim goto err; 115955714Skris 1160280304Sjkim c_ssl_bio = BIO_new(BIO_f_ssl()); 1161280304Sjkim if (!c_ssl_bio) 1162280304Sjkim goto err; 116355714Skris 1164280304Sjkim SSL_set_connect_state(c_ssl); 1165280304Sjkim SSL_set_bio(c_ssl, client, client); 1166280304Sjkim (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE); 116755714Skris 1168280304Sjkim SSL_set_accept_state(s_ssl); 1169280304Sjkim SSL_set_bio(s_ssl, server, server); 1170280304Sjkim (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE); 117155714Skris 1172280304Sjkim do { 1173280304Sjkim /*- 1174280304Sjkim * c_ssl_bio: SSL filter BIO 1175280304Sjkim * 1176280304Sjkim * client: pseudo-I/O for SSL library 1177280304Sjkim * 1178280304Sjkim * client_io: client's SSL communication; usually to be 1179280304Sjkim * relayed over some I/O facility, but in this 1180280304Sjkim * test program, we're the server, too: 1181280304Sjkim * 1182280304Sjkim * server_io: server's SSL communication 1183280304Sjkim * 1184280304Sjkim * server: pseudo-I/O for SSL library 1185280304Sjkim * 1186280304Sjkim * s_ssl_bio: SSL filter BIO 1187280304Sjkim * 1188280304Sjkim * The client and the server each employ a "BIO pair": 1189280304Sjkim * client + client_io, server + server_io. 1190280304Sjkim * BIO pairs are symmetric. A BIO pair behaves similar 1191280304Sjkim * to a non-blocking socketpair (but both endpoints must 1192280304Sjkim * be handled by the same thread). 1193280304Sjkim * [Here we could connect client and server to the ends 1194280304Sjkim * of a single BIO pair, but then this code would be less 1195280304Sjkim * suitable as an example for BIO pairs in general.] 1196280304Sjkim * 1197280304Sjkim * Useful functions for querying the state of BIO pair endpoints: 1198280304Sjkim * 1199280304Sjkim * BIO_ctrl_pending(bio) number of bytes we can read now 1200280304Sjkim * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil 1201280304Sjkim * other side's read attempt 1202280304Sjkim * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now 1203280304Sjkim * 1204280304Sjkim * ..._read_request is never more than ..._write_guarantee; 1205280304Sjkim * it depends on the application which one you should use. 1206280304Sjkim */ 120755714Skris 1208280304Sjkim /* 1209280304Sjkim * We have non-blocking behaviour throughout this test program, but 1210280304Sjkim * can be sure that there is *some* progress in each iteration; so we 1211280304Sjkim * don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE -- 1212280304Sjkim * we just try everything in each iteration 1213280304Sjkim */ 1214109998Smarkm 1215280304Sjkim { 1216280304Sjkim /* CLIENT */ 121755714Skris 1218280304Sjkim MS_STATIC char cbuf[1024 * 8]; 1219280304Sjkim int i, r; 1220280304Sjkim clock_t c_clock = clock(); 122155714Skris 1222280304Sjkim memset(cbuf, 0, sizeof(cbuf)); 122355714Skris 1224280304Sjkim if (debug) 1225280304Sjkim if (SSL_in_init(c_ssl)) 1226280304Sjkim printf("client waiting in SSL_connect - %s\n", 1227280304Sjkim SSL_state_string_long(c_ssl)); 122859191Skris 1229280304Sjkim if (cw_num > 0) { 1230280304Sjkim /* Write to server. */ 123155714Skris 1232280304Sjkim if (cw_num > (long)sizeof cbuf) 1233280304Sjkim i = sizeof cbuf; 1234280304Sjkim else 1235280304Sjkim i = (int)cw_num; 1236280304Sjkim r = BIO_write(c_ssl_bio, cbuf, i); 1237280304Sjkim if (r < 0) { 1238280304Sjkim if (!BIO_should_retry(c_ssl_bio)) { 1239280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1240280304Sjkim goto err; 1241280304Sjkim } 1242280304Sjkim /* 1243280304Sjkim * BIO_should_retry(...) can just be ignored here. The 1244280304Sjkim * library expects us to call BIO_write with the same 1245280304Sjkim * arguments again, and that's what we will do in the 1246280304Sjkim * next iteration. 1247280304Sjkim */ 1248280304Sjkim } else if (r == 0) { 1249280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1250280304Sjkim goto err; 1251280304Sjkim } else { 1252280304Sjkim if (debug) 1253280304Sjkim printf("client wrote %d\n", r); 1254280304Sjkim cw_num -= r; 1255280304Sjkim } 1256280304Sjkim } 125755714Skris 1258280304Sjkim if (cr_num > 0) { 1259280304Sjkim /* Read from server. */ 1260109998Smarkm 1261280304Sjkim r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf)); 1262280304Sjkim if (r < 0) { 1263280304Sjkim if (!BIO_should_retry(c_ssl_bio)) { 1264280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1265280304Sjkim goto err; 1266280304Sjkim } 1267280304Sjkim /* 1268280304Sjkim * Again, "BIO_should_retry" can be ignored. 1269280304Sjkim */ 1270280304Sjkim } else if (r == 0) { 1271280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1272280304Sjkim goto err; 1273280304Sjkim } else { 1274280304Sjkim if (debug) 1275280304Sjkim printf("client read %d\n", r); 1276280304Sjkim cr_num -= r; 1277280304Sjkim } 1278280304Sjkim } 127955714Skris 1280280304Sjkim /* 1281280304Sjkim * c_time and s_time increments will typically be very small 1282280304Sjkim * (depending on machine speed and clock tick intervals), but 1283280304Sjkim * sampling over a large number of connections should result in 1284280304Sjkim * fairly accurate figures. We cannot guarantee a lot, however 1285280304Sjkim * -- if each connection lasts for exactly one clock tick, it 1286280304Sjkim * will be counted only for the client or only for the server or 1287280304Sjkim * even not at all. 1288280304Sjkim */ 1289280304Sjkim *c_time += (clock() - c_clock); 1290280304Sjkim } 129155714Skris 1292280304Sjkim { 1293280304Sjkim /* SERVER */ 129455714Skris 1295280304Sjkim MS_STATIC char sbuf[1024 * 8]; 1296280304Sjkim int i, r; 1297280304Sjkim clock_t s_clock = clock(); 129859191Skris 1299280304Sjkim memset(sbuf, 0, sizeof(sbuf)); 130055714Skris 1301280304Sjkim if (debug) 1302280304Sjkim if (SSL_in_init(s_ssl)) 1303280304Sjkim printf("server waiting in SSL_accept - %s\n", 1304280304Sjkim SSL_state_string_long(s_ssl)); 130555714Skris 1306280304Sjkim if (sw_num > 0) { 1307280304Sjkim /* Write to client. */ 130859191Skris 1309280304Sjkim if (sw_num > (long)sizeof sbuf) 1310280304Sjkim i = sizeof sbuf; 1311280304Sjkim else 1312280304Sjkim i = (int)sw_num; 1313280304Sjkim r = BIO_write(s_ssl_bio, sbuf, i); 1314280304Sjkim if (r < 0) { 1315280304Sjkim if (!BIO_should_retry(s_ssl_bio)) { 1316280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1317280304Sjkim goto err; 1318280304Sjkim } 1319280304Sjkim /* Ignore "BIO_should_retry". */ 1320280304Sjkim } else if (r == 0) { 1321280304Sjkim fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 1322280304Sjkim goto err; 1323280304Sjkim } else { 1324280304Sjkim if (debug) 1325280304Sjkim printf("server wrote %d\n", r); 1326280304Sjkim sw_num -= r; 1327280304Sjkim } 1328280304Sjkim } 132959191Skris 1330280304Sjkim if (sr_num > 0) { 1331280304Sjkim /* Read from client. */ 133255714Skris 1333280304Sjkim r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf)); 1334280304Sjkim if (r < 0) { 1335280304Sjkim if (!BIO_should_retry(s_ssl_bio)) { 1336280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1337280304Sjkim goto err; 1338280304Sjkim } 1339280304Sjkim /* blah, blah */ 1340280304Sjkim } else if (r == 0) { 1341280304Sjkim fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 1342280304Sjkim goto err; 1343280304Sjkim } else { 1344280304Sjkim if (debug) 1345280304Sjkim printf("server read %d\n", r); 1346280304Sjkim sr_num -= r; 1347280304Sjkim } 1348280304Sjkim } 134955714Skris 1350280304Sjkim *s_time += (clock() - s_clock); 1351280304Sjkim } 135255714Skris 1353280304Sjkim { 1354280304Sjkim /* "I/O" BETWEEN CLIENT AND SERVER. */ 135559191Skris 1356280304Sjkim size_t r1, r2; 1357280304Sjkim BIO *io1 = server_io, *io2 = client_io; 1358280304Sjkim /* 1359280304Sjkim * we use the non-copying interface for io1 and the standard 1360280304Sjkim * BIO_write/BIO_read interface for io2 1361280304Sjkim */ 136255714Skris 1363280304Sjkim static int prev_progress = 1; 1364280304Sjkim int progress = 0; 136555714Skris 1366280304Sjkim /* io1 to io2 */ 1367280304Sjkim do { 1368280304Sjkim size_t num; 1369280304Sjkim int r; 137055714Skris 1371280304Sjkim r1 = BIO_ctrl_pending(io1); 1372280304Sjkim r2 = BIO_ctrl_get_write_guarantee(io2); 1373280304Sjkim 1374280304Sjkim num = r1; 1375280304Sjkim if (r2 < num) 1376280304Sjkim num = r2; 1377280304Sjkim if (num) { 1378280304Sjkim char *dataptr; 1379280304Sjkim 1380280304Sjkim if (INT_MAX < num) /* yeah, right */ 1381280304Sjkim num = INT_MAX; 1382280304Sjkim 1383280304Sjkim r = BIO_nread(io1, &dataptr, (int)num); 1384280304Sjkim assert(r > 0); 1385280304Sjkim assert(r <= (int)num); 1386280304Sjkim /* 1387280304Sjkim * possibly r < num (non-contiguous data) 1388280304Sjkim */ 1389280304Sjkim num = r; 1390280304Sjkim r = BIO_write(io2, dataptr, (int)num); 1391280304Sjkim if (r != (int)num) { /* can't happen */ 1392280304Sjkim fprintf(stderr, "ERROR: BIO_write could not write " 1393280304Sjkim "BIO_ctrl_get_write_guarantee() bytes"); 1394280304Sjkim goto err; 1395280304Sjkim } 1396280304Sjkim progress = 1; 1397280304Sjkim 1398280304Sjkim if (debug) 1399280304Sjkim printf((io1 == client_io) ? 1400280304Sjkim "C->S relaying: %d bytes\n" : 1401280304Sjkim "S->C relaying: %d bytes\n", (int)num); 1402280304Sjkim } 1403280304Sjkim } 1404280304Sjkim while (r1 && r2); 1405280304Sjkim 1406280304Sjkim /* io2 to io1 */ 1407280304Sjkim { 1408280304Sjkim size_t num; 1409280304Sjkim int r; 1410280304Sjkim 1411280304Sjkim r1 = BIO_ctrl_pending(io2); 1412280304Sjkim r2 = BIO_ctrl_get_read_request(io1); 1413280304Sjkim /* 1414280304Sjkim * here we could use ..._get_write_guarantee instead of 1415280304Sjkim * ..._get_read_request, but by using the latter we test 1416280304Sjkim * restartability of the SSL implementation more thoroughly 1417280304Sjkim */ 1418280304Sjkim num = r1; 1419280304Sjkim if (r2 < num) 1420280304Sjkim num = r2; 1421280304Sjkim if (num) { 1422280304Sjkim char *dataptr; 1423280304Sjkim 1424280304Sjkim if (INT_MAX < num) 1425280304Sjkim num = INT_MAX; 1426280304Sjkim 1427280304Sjkim if (num > 1) 1428280304Sjkim --num; /* test restartability even more thoroughly */ 1429280304Sjkim 1430280304Sjkim r = BIO_nwrite0(io1, &dataptr); 1431280304Sjkim assert(r > 0); 1432280304Sjkim if (r < (int)num) 1433280304Sjkim num = r; 1434280304Sjkim r = BIO_read(io2, dataptr, (int)num); 1435280304Sjkim if (r != (int)num) { /* can't happen */ 1436280304Sjkim fprintf(stderr, "ERROR: BIO_read could not read " 1437280304Sjkim "BIO_ctrl_pending() bytes"); 1438280304Sjkim goto err; 1439280304Sjkim } 1440280304Sjkim progress = 1; 1441280304Sjkim r = BIO_nwrite(io1, &dataptr, (int)num); 1442280304Sjkim if (r != (int)num) { /* can't happen */ 1443280304Sjkim fprintf(stderr, "ERROR: BIO_nwrite() did not accept " 1444280304Sjkim "BIO_nwrite0() bytes"); 1445280304Sjkim goto err; 1446280304Sjkim } 1447280304Sjkim 1448280304Sjkim if (debug) 1449280304Sjkim printf((io2 == client_io) ? 1450280304Sjkim "C->S relaying: %d bytes\n" : 1451280304Sjkim "S->C relaying: %d bytes\n", (int)num); 1452280304Sjkim } 1453280304Sjkim } /* no loop, BIO_ctrl_get_read_request now 1454280304Sjkim * returns 0 anyway */ 1455280304Sjkim 1456280304Sjkim if (!progress && !prev_progress) 1457280304Sjkim if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) { 1458280304Sjkim fprintf(stderr, "ERROR: got stuck\n"); 1459280304Sjkim if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0) { 1460280304Sjkim fprintf(stderr, "This can happen for SSL2 because " 1461280304Sjkim "CLIENT-FINISHED and SERVER-VERIFY are written \n" 1462280304Sjkim "concurrently ..."); 1463280304Sjkim if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0 1464280304Sjkim && strncmp("2SSV", SSL_state_string(s_ssl), 1465280304Sjkim 4) == 0) { 1466280304Sjkim fprintf(stderr, " ok.\n"); 1467280304Sjkim goto end; 1468280304Sjkim } 1469280304Sjkim } 1470280304Sjkim fprintf(stderr, " ERROR.\n"); 1471280304Sjkim goto err; 1472280304Sjkim } 1473280304Sjkim prev_progress = progress; 1474280304Sjkim } 1475280304Sjkim } 1476280304Sjkim while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); 1477280304Sjkim 1478280304Sjkim if (verbose) 1479280304Sjkim print_details(c_ssl, "DONE via BIO pair: "); 1480280304Sjkim end: 1481280304Sjkim ret = 0; 1482280304Sjkim 148355714Skris err: 1484280304Sjkim ERR_print_errors(bio_err); 148555714Skris 1486280304Sjkim if (server) 1487280304Sjkim BIO_free(server); 1488280304Sjkim if (server_io) 1489280304Sjkim BIO_free(server_io); 1490280304Sjkim if (client) 1491280304Sjkim BIO_free(client); 1492280304Sjkim if (client_io) 1493280304Sjkim BIO_free(client_io); 1494280304Sjkim if (s_ssl_bio) 1495280304Sjkim BIO_free(s_ssl_bio); 1496280304Sjkim if (c_ssl_bio) 1497280304Sjkim BIO_free(c_ssl_bio); 149855714Skris 1499280304Sjkim return ret; 1500280304Sjkim} 150155714Skris 1502280304Sjkim#define W_READ 1 1503280304Sjkim#define W_WRITE 2 1504280304Sjkim#define C_DONE 1 1505280304Sjkim#define S_DONE 2 150655714Skris 150755714Skrisint doit(SSL *s_ssl, SSL *c_ssl, long count) 1508280304Sjkim{ 1509280304Sjkim MS_STATIC char cbuf[1024 * 8], sbuf[1024 * 8]; 1510280304Sjkim long cw_num = count, cr_num = count; 1511280304Sjkim long sw_num = count, sr_num = count; 1512280304Sjkim int ret = 1; 1513280304Sjkim BIO *c_to_s = NULL; 1514280304Sjkim BIO *s_to_c = NULL; 1515280304Sjkim BIO *c_bio = NULL; 1516280304Sjkim BIO *s_bio = NULL; 1517280304Sjkim int c_r, c_w, s_r, s_w; 1518280304Sjkim int i, j; 1519280304Sjkim int done = 0; 1520280304Sjkim int c_write, s_write; 1521280304Sjkim int do_server = 0, do_client = 0; 152255714Skris 1523280304Sjkim memset(cbuf, 0, sizeof(cbuf)); 1524280304Sjkim memset(sbuf, 0, sizeof(sbuf)); 1525109998Smarkm 1526280304Sjkim c_to_s = BIO_new(BIO_s_mem()); 1527280304Sjkim s_to_c = BIO_new(BIO_s_mem()); 1528280304Sjkim if ((s_to_c == NULL) || (c_to_s == NULL)) { 1529280304Sjkim ERR_print_errors(bio_err); 1530280304Sjkim goto err; 1531280304Sjkim } 153255714Skris 1533280304Sjkim c_bio = BIO_new(BIO_f_ssl()); 1534280304Sjkim s_bio = BIO_new(BIO_f_ssl()); 1535280304Sjkim if ((c_bio == NULL) || (s_bio == NULL)) { 1536280304Sjkim ERR_print_errors(bio_err); 1537280304Sjkim goto err; 1538280304Sjkim } 153955714Skris 1540280304Sjkim SSL_set_connect_state(c_ssl); 1541280304Sjkim SSL_set_bio(c_ssl, s_to_c, c_to_s); 1542280304Sjkim BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE); 154355714Skris 1544280304Sjkim SSL_set_accept_state(s_ssl); 1545280304Sjkim SSL_set_bio(s_ssl, c_to_s, s_to_c); 1546280304Sjkim BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE); 154755714Skris 1548280304Sjkim c_r = 0; 1549280304Sjkim s_r = 1; 1550280304Sjkim c_w = 1; 1551280304Sjkim s_w = 0; 1552280304Sjkim c_write = 1, s_write = 0; 155355714Skris 1554280304Sjkim /* We can always do writes */ 1555280304Sjkim for (;;) { 1556280304Sjkim do_server = 0; 1557280304Sjkim do_client = 0; 155855714Skris 1559280304Sjkim i = (int)BIO_pending(s_bio); 1560280304Sjkim if ((i && s_r) || s_w) 1561280304Sjkim do_server = 1; 156255714Skris 1563280304Sjkim i = (int)BIO_pending(c_bio); 1564280304Sjkim if ((i && c_r) || c_w) 1565280304Sjkim do_client = 1; 156655714Skris 1567280304Sjkim if (do_server && debug) { 1568280304Sjkim if (SSL_in_init(s_ssl)) 1569280304Sjkim printf("server waiting in SSL_accept - %s\n", 1570280304Sjkim SSL_state_string_long(s_ssl)); 1571280304Sjkim/*- 1572280304Sjkim else if (s_write) 1573280304Sjkim printf("server:SSL_write()\n"); 1574280304Sjkim else 1575280304Sjkim printf("server:SSL_read()\n"); */ 1576280304Sjkim } 157755714Skris 1578280304Sjkim if (do_client && debug) { 1579280304Sjkim if (SSL_in_init(c_ssl)) 1580280304Sjkim printf("client waiting in SSL_connect - %s\n", 1581280304Sjkim SSL_state_string_long(c_ssl)); 1582280304Sjkim/*- 1583280304Sjkim else if (c_write) 1584280304Sjkim printf("client:SSL_write()\n"); 1585280304Sjkim else 1586280304Sjkim printf("client:SSL_read()\n"); */ 1587280304Sjkim } 158855714Skris 1589280304Sjkim if (!do_client && !do_server) { 1590280304Sjkim fprintf(stdout, "ERROR IN STARTUP\n"); 1591280304Sjkim ERR_print_errors(bio_err); 1592280304Sjkim goto err; 1593280304Sjkim } 1594280304Sjkim if (do_client && !(done & C_DONE)) { 1595280304Sjkim if (c_write) { 1596280304Sjkim j = (cw_num > (long)sizeof(cbuf)) ? 1597280304Sjkim (int)sizeof(cbuf) : (int)cw_num; 1598280304Sjkim i = BIO_write(c_bio, cbuf, j); 1599280304Sjkim if (i < 0) { 1600280304Sjkim c_r = 0; 1601280304Sjkim c_w = 0; 1602280304Sjkim if (BIO_should_retry(c_bio)) { 1603280304Sjkim if (BIO_should_read(c_bio)) 1604280304Sjkim c_r = 1; 1605280304Sjkim if (BIO_should_write(c_bio)) 1606280304Sjkim c_w = 1; 1607280304Sjkim } else { 1608280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1609280304Sjkim ERR_print_errors(bio_err); 1610280304Sjkim goto err; 1611280304Sjkim } 1612280304Sjkim } else if (i == 0) { 1613280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1614280304Sjkim goto err; 1615280304Sjkim } else { 1616280304Sjkim if (debug) 1617280304Sjkim printf("client wrote %d\n", i); 1618280304Sjkim /* ok */ 1619280304Sjkim s_r = 1; 1620280304Sjkim c_write = 0; 1621280304Sjkim cw_num -= i; 1622280304Sjkim } 1623280304Sjkim } else { 1624280304Sjkim i = BIO_read(c_bio, cbuf, sizeof(cbuf)); 1625280304Sjkim if (i < 0) { 1626280304Sjkim c_r = 0; 1627280304Sjkim c_w = 0; 1628280304Sjkim if (BIO_should_retry(c_bio)) { 1629280304Sjkim if (BIO_should_read(c_bio)) 1630280304Sjkim c_r = 1; 1631280304Sjkim if (BIO_should_write(c_bio)) 1632280304Sjkim c_w = 1; 1633280304Sjkim } else { 1634280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1635280304Sjkim ERR_print_errors(bio_err); 1636280304Sjkim goto err; 1637280304Sjkim } 1638280304Sjkim } else if (i == 0) { 1639280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1640280304Sjkim goto err; 1641280304Sjkim } else { 1642280304Sjkim if (debug) 1643280304Sjkim printf("client read %d\n", i); 1644280304Sjkim cr_num -= i; 1645280304Sjkim if (sw_num > 0) { 1646280304Sjkim s_write = 1; 1647280304Sjkim s_w = 1; 1648280304Sjkim } 1649280304Sjkim if (cr_num <= 0) { 1650280304Sjkim s_write = 1; 1651280304Sjkim s_w = 1; 1652280304Sjkim done = S_DONE | C_DONE; 1653280304Sjkim } 1654280304Sjkim } 1655280304Sjkim } 1656280304Sjkim } 165755714Skris 1658280304Sjkim if (do_server && !(done & S_DONE)) { 1659280304Sjkim if (!s_write) { 1660280304Sjkim i = BIO_read(s_bio, sbuf, sizeof(cbuf)); 1661280304Sjkim if (i < 0) { 1662280304Sjkim s_r = 0; 1663280304Sjkim s_w = 0; 1664280304Sjkim if (BIO_should_retry(s_bio)) { 1665280304Sjkim if (BIO_should_read(s_bio)) 1666280304Sjkim s_r = 1; 1667280304Sjkim if (BIO_should_write(s_bio)) 1668280304Sjkim s_w = 1; 1669280304Sjkim } else { 1670280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1671280304Sjkim ERR_print_errors(bio_err); 1672280304Sjkim goto err; 1673280304Sjkim } 1674280304Sjkim } else if (i == 0) { 1675280304Sjkim ERR_print_errors(bio_err); 1676280304Sjkim fprintf(stderr, 1677280304Sjkim "SSL SERVER STARTUP FAILED in SSL_read\n"); 1678280304Sjkim goto err; 1679280304Sjkim } else { 1680280304Sjkim if (debug) 1681280304Sjkim printf("server read %d\n", i); 1682280304Sjkim sr_num -= i; 1683280304Sjkim if (cw_num > 0) { 1684280304Sjkim c_write = 1; 1685280304Sjkim c_w = 1; 1686280304Sjkim } 1687280304Sjkim if (sr_num <= 0) { 1688280304Sjkim s_write = 1; 1689280304Sjkim s_w = 1; 1690280304Sjkim c_write = 0; 1691280304Sjkim } 1692280304Sjkim } 1693280304Sjkim } else { 1694280304Sjkim j = (sw_num > (long)sizeof(sbuf)) ? 1695280304Sjkim (int)sizeof(sbuf) : (int)sw_num; 1696280304Sjkim i = BIO_write(s_bio, sbuf, j); 1697280304Sjkim if (i < 0) { 1698280304Sjkim s_r = 0; 1699280304Sjkim s_w = 0; 1700280304Sjkim if (BIO_should_retry(s_bio)) { 1701280304Sjkim if (BIO_should_read(s_bio)) 1702280304Sjkim s_r = 1; 1703280304Sjkim if (BIO_should_write(s_bio)) 1704280304Sjkim s_w = 1; 1705280304Sjkim } else { 1706280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1707280304Sjkim ERR_print_errors(bio_err); 1708280304Sjkim goto err; 1709280304Sjkim } 1710280304Sjkim } else if (i == 0) { 1711280304Sjkim ERR_print_errors(bio_err); 1712280304Sjkim fprintf(stderr, 1713280304Sjkim "SSL SERVER STARTUP FAILED in SSL_write\n"); 1714280304Sjkim goto err; 1715280304Sjkim } else { 1716280304Sjkim if (debug) 1717280304Sjkim printf("server wrote %d\n", i); 1718280304Sjkim sw_num -= i; 1719280304Sjkim s_write = 0; 1720280304Sjkim c_r = 1; 1721280304Sjkim if (sw_num <= 0) 1722280304Sjkim done |= S_DONE; 1723280304Sjkim } 1724280304Sjkim } 1725280304Sjkim } 172655714Skris 1727280304Sjkim if ((done & S_DONE) && (done & C_DONE)) 1728280304Sjkim break; 1729280304Sjkim } 173055714Skris 1731280304Sjkim if (verbose) 1732280304Sjkim print_details(c_ssl, "DONE: "); 1733280304Sjkim ret = 0; 1734280304Sjkim err: 1735280304Sjkim /* 1736280304Sjkim * We have to set the BIO's to NULL otherwise they will be 1737280304Sjkim * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and again 1738280304Sjkim * when c_ssl is SSL_free()ed. This is a hack required because s_ssl and 1739280304Sjkim * c_ssl are sharing the same BIO structure and SSL_set_bio() and 1740280304Sjkim * SSL_free() automatically BIO_free non NULL entries. You should not 1741280304Sjkim * normally do this or be required to do this 1742280304Sjkim */ 1743280304Sjkim if (s_ssl != NULL) { 1744280304Sjkim s_ssl->rbio = NULL; 1745280304Sjkim s_ssl->wbio = NULL; 1746280304Sjkim } 1747280304Sjkim if (c_ssl != NULL) { 1748280304Sjkim c_ssl->rbio = NULL; 1749280304Sjkim c_ssl->wbio = NULL; 1750280304Sjkim } 175155714Skris 1752280304Sjkim if (c_to_s != NULL) 1753280304Sjkim BIO_free(c_to_s); 1754280304Sjkim if (s_to_c != NULL) 1755280304Sjkim BIO_free(s_to_c); 1756280304Sjkim if (c_bio != NULL) 1757280304Sjkim BIO_free_all(c_bio); 1758280304Sjkim if (s_bio != NULL) 1759280304Sjkim BIO_free_all(s_bio); 1760280304Sjkim return (ret); 1761280304Sjkim} 176255714Skris 1763160814Ssimonstatic int get_proxy_auth_ex_data_idx(void) 1764280304Sjkim{ 1765280304Sjkim static volatile int idx = -1; 1766280304Sjkim if (idx < 0) { 1767280304Sjkim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 1768280304Sjkim if (idx < 0) { 1769280304Sjkim idx = X509_STORE_CTX_get_ex_new_index(0, 1770280304Sjkim "SSLtest for verify callback", 1771280304Sjkim NULL, NULL, NULL); 1772280304Sjkim } 1773280304Sjkim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 1774280304Sjkim } 1775280304Sjkim return idx; 1776280304Sjkim} 1777160814Ssimon 177859191Skrisstatic int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 1779280304Sjkim{ 1780280304Sjkim char *s, buf[256]; 178155714Skris 1782280304Sjkim s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, 1783280304Sjkim sizeof buf); 1784280304Sjkim if (s != NULL) { 1785280304Sjkim if (ok) 1786280304Sjkim fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf); 1787280304Sjkim else { 1788280304Sjkim fprintf(stderr, "depth=%d error=%d %s\n", 1789280304Sjkim ctx->error_depth, ctx->error, buf); 1790280304Sjkim } 1791280304Sjkim } 179255714Skris 1793280304Sjkim if (ok == 0) { 1794280304Sjkim fprintf(stderr, "Error string: %s\n", 1795280304Sjkim X509_verify_cert_error_string(ctx->error)); 1796280304Sjkim switch (ctx->error) { 1797280304Sjkim case X509_V_ERR_CERT_NOT_YET_VALID: 1798280304Sjkim case X509_V_ERR_CERT_HAS_EXPIRED: 1799280304Sjkim case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1800280304Sjkim fprintf(stderr, " ... ignored.\n"); 1801280304Sjkim ok = 1; 1802280304Sjkim } 1803280304Sjkim } 180455714Skris 1805280304Sjkim if (ok == 1) { 1806280304Sjkim X509 *xs = ctx->current_cert; 1807160814Ssimon#if 0 1808280304Sjkim X509 *xi = ctx->current_issuer; 1809160814Ssimon#endif 1810160814Ssimon 1811280304Sjkim if (xs->ex_flags & EXFLAG_PROXY) { 1812280304Sjkim unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx, 1813280304Sjkim get_proxy_auth_ex_data_idx 1814280304Sjkim ()); 1815160814Ssimon 1816280304Sjkim if (letters) { 1817280304Sjkim int found_any = 0; 1818280304Sjkim int i; 1819280304Sjkim PROXY_CERT_INFO_EXTENSION *pci = 1820280304Sjkim X509_get_ext_d2i(xs, NID_proxyCertInfo, 1821280304Sjkim NULL, NULL); 1822160814Ssimon 1823280304Sjkim switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { 1824280304Sjkim case NID_Independent: 1825280304Sjkim /* 1826280304Sjkim * Completely meaningless in this program, as there's no 1827280304Sjkim * way to grant explicit rights to a specific PrC. 1828280304Sjkim * Basically, using id-ppl-Independent is the perfect way 1829280304Sjkim * to grant no rights at all. 1830280304Sjkim */ 1831280304Sjkim fprintf(stderr, " Independent proxy certificate"); 1832280304Sjkim for (i = 0; i < 26; i++) 1833280304Sjkim letters[i] = 0; 1834280304Sjkim break; 1835280304Sjkim case NID_id_ppl_inheritAll: 1836280304Sjkim /* 1837280304Sjkim * This is basically a NOP, we simply let the current 1838280304Sjkim * rights stand as they are. 1839280304Sjkim */ 1840280304Sjkim fprintf(stderr, " Proxy certificate inherits all"); 1841280304Sjkim break; 1842280304Sjkim default: 1843280304Sjkim s = (char *) 1844280304Sjkim pci->proxyPolicy->policy->data; 1845280304Sjkim i = pci->proxyPolicy->policy->length; 1846160814Ssimon 1847280304Sjkim /* 1848280304Sjkim * The algorithm works as follows: it is assumed that 1849280304Sjkim * previous iterations or the initial granted rights has 1850280304Sjkim * already set some elements of `letters'. What we need 1851280304Sjkim * to do is to clear those that weren't granted by the 1852280304Sjkim * current PrC as well. The easiest way to do this is to 1853280304Sjkim * add 1 to all the elements whose letters are given with 1854280304Sjkim * the current policy. That way, all elements that are 1855280304Sjkim * set by the current policy and were already set by 1856280304Sjkim * earlier policies and through the original grant of 1857280304Sjkim * rights will get the value 2 or higher. The last thing 1858280304Sjkim * to do is to sweep through `letters' and keep the 1859280304Sjkim * elements having the value 2 as set, and clear all the 1860280304Sjkim * others. 1861280304Sjkim */ 1862160814Ssimon 1863280304Sjkim fprintf(stderr, " Certificate proxy rights = %*.*s", i, 1864280304Sjkim i, s); 1865280304Sjkim while (i-- > 0) { 1866280304Sjkim int c = *s++; 1867280304Sjkim if (isascii(c) && isalpha(c)) { 1868280304Sjkim if (islower(c)) 1869280304Sjkim c = toupper(c); 1870280304Sjkim letters[c - 'A']++; 1871280304Sjkim } 1872280304Sjkim } 1873280304Sjkim for (i = 0; i < 26; i++) 1874280304Sjkim if (letters[i] < 2) 1875280304Sjkim letters[i] = 0; 1876280304Sjkim else 1877280304Sjkim letters[i] = 1; 1878280304Sjkim } 1879160814Ssimon 1880280304Sjkim found_any = 0; 1881280304Sjkim fprintf(stderr, ", resulting proxy rights = "); 1882280304Sjkim for (i = 0; i < 26; i++) 1883280304Sjkim if (letters[i]) { 1884280304Sjkim fprintf(stderr, "%c", i + 'A'); 1885280304Sjkim found_any = 1; 1886280304Sjkim } 1887280304Sjkim if (!found_any) 1888280304Sjkim fprintf(stderr, "none"); 1889280304Sjkim fprintf(stderr, "\n"); 1890160814Ssimon 1891280304Sjkim PROXY_CERT_INFO_EXTENSION_free(pci); 1892280304Sjkim } 1893280304Sjkim } 1894280304Sjkim } 1895160814Ssimon 1896280304Sjkim return (ok); 1897280304Sjkim} 189855714Skris 1899160814Ssimonstatic void process_proxy_debug(int indent, const char *format, ...) 1900280304Sjkim{ 1901280304Sjkim /* That's 80 > */ 1902280304Sjkim static const char indentation[] = 1903280304Sjkim ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 1904280304Sjkim ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; 1905280304Sjkim char my_format[256]; 1906280304Sjkim va_list args; 1907160814Ssimon 1908280304Sjkim BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s", 1909280304Sjkim indent, indent, indentation, format); 1910160814Ssimon 1911280304Sjkim va_start(args, format); 1912280304Sjkim vfprintf(stderr, my_format, args); 1913280304Sjkim va_end(args); 1914280304Sjkim} 1915280304Sjkim 1916280304Sjkim/*- 1917280304Sjkim * Priority levels: 1918280304Sjkim * 0 [!]var, () 1919280304Sjkim * 1 & ^ 1920280304Sjkim * 2 | 1921280304Sjkim */ 1922160814Ssimonstatic int process_proxy_cond_adders(unsigned int letters[26], 1923280304Sjkim const char *cond, const char **cond_end, 1924280304Sjkim int *pos, int indent); 1925280304Sjkimstatic int process_proxy_cond_val(unsigned int letters[26], const char *cond, 1926280304Sjkim const char **cond_end, int *pos, int indent) 1927280304Sjkim{ 1928280304Sjkim int c; 1929280304Sjkim int ok = 1; 1930280304Sjkim int negate = 0; 1931160814Ssimon 1932280304Sjkim while (isspace((int)*cond)) { 1933280304Sjkim cond++; 1934280304Sjkim (*pos)++; 1935280304Sjkim } 1936280304Sjkim c = *cond; 1937160814Ssimon 1938280304Sjkim if (debug) 1939280304Sjkim process_proxy_debug(indent, 1940280304Sjkim "Start process_proxy_cond_val at position %d: %s\n", 1941280304Sjkim *pos, cond); 1942160814Ssimon 1943280304Sjkim while (c == '!') { 1944280304Sjkim negate = !negate; 1945280304Sjkim cond++; 1946280304Sjkim (*pos)++; 1947280304Sjkim while (isspace((int)*cond)) { 1948280304Sjkim cond++; 1949280304Sjkim (*pos)++; 1950280304Sjkim } 1951280304Sjkim c = *cond; 1952280304Sjkim } 1953160814Ssimon 1954280304Sjkim if (c == '(') { 1955280304Sjkim cond++; 1956280304Sjkim (*pos)++; 1957280304Sjkim ok = process_proxy_cond_adders(letters, cond, cond_end, pos, 1958280304Sjkim indent + 1); 1959280304Sjkim cond = *cond_end; 1960280304Sjkim if (ok < 0) 1961280304Sjkim goto end; 1962280304Sjkim while (isspace((int)*cond)) { 1963280304Sjkim cond++; 1964280304Sjkim (*pos)++; 1965280304Sjkim } 1966280304Sjkim c = *cond; 1967280304Sjkim if (c != ')') { 1968280304Sjkim fprintf(stderr, 1969280304Sjkim "Weird condition character in position %d: " 1970280304Sjkim "%c\n", *pos, c); 1971280304Sjkim ok = -1; 1972280304Sjkim goto end; 1973280304Sjkim } 1974280304Sjkim cond++; 1975280304Sjkim (*pos)++; 1976280304Sjkim } else if (isascii(c) && isalpha(c)) { 1977280304Sjkim if (islower(c)) 1978280304Sjkim c = toupper(c); 1979280304Sjkim ok = letters[c - 'A']; 1980280304Sjkim cond++; 1981280304Sjkim (*pos)++; 1982280304Sjkim } else { 1983280304Sjkim fprintf(stderr, 1984280304Sjkim "Weird condition character in position %d: " "%c\n", *pos, c); 1985280304Sjkim ok = -1; 1986280304Sjkim goto end; 1987280304Sjkim } 1988160814Ssimon end: 1989280304Sjkim *cond_end = cond; 1990280304Sjkim if (ok >= 0 && negate) 1991280304Sjkim ok = !ok; 1992160814Ssimon 1993280304Sjkim if (debug) 1994280304Sjkim process_proxy_debug(indent, 1995280304Sjkim "End process_proxy_cond_val at position %d: %s, returning %d\n", 1996280304Sjkim *pos, cond, ok); 1997160814Ssimon 1998280304Sjkim return ok; 1999280304Sjkim} 2000280304Sjkim 2001160814Ssimonstatic int process_proxy_cond_multipliers(unsigned int letters[26], 2002280304Sjkim const char *cond, 2003280304Sjkim const char **cond_end, int *pos, 2004280304Sjkim int indent) 2005280304Sjkim{ 2006280304Sjkim int ok; 2007280304Sjkim char c; 2008160814Ssimon 2009280304Sjkim if (debug) 2010280304Sjkim process_proxy_debug(indent, 2011280304Sjkim "Start process_proxy_cond_multipliers at position %d: %s\n", 2012280304Sjkim *pos, cond); 2013160814Ssimon 2014280304Sjkim ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1); 2015280304Sjkim cond = *cond_end; 2016280304Sjkim if (ok < 0) 2017280304Sjkim goto end; 2018160814Ssimon 2019280304Sjkim while (ok >= 0) { 2020280304Sjkim while (isspace((int)*cond)) { 2021280304Sjkim cond++; 2022280304Sjkim (*pos)++; 2023280304Sjkim } 2024280304Sjkim c = *cond; 2025160814Ssimon 2026280304Sjkim switch (c) { 2027280304Sjkim case '&': 2028280304Sjkim case '^': 2029280304Sjkim { 2030280304Sjkim int save_ok = ok; 2031160814Ssimon 2032280304Sjkim cond++; 2033280304Sjkim (*pos)++; 2034280304Sjkim ok = process_proxy_cond_val(letters, 2035280304Sjkim cond, cond_end, pos, indent + 1); 2036280304Sjkim cond = *cond_end; 2037280304Sjkim if (ok < 0) 2038280304Sjkim break; 2039160814Ssimon 2040280304Sjkim switch (c) { 2041280304Sjkim case '&': 2042280304Sjkim ok &= save_ok; 2043280304Sjkim break; 2044280304Sjkim case '^': 2045280304Sjkim ok ^= save_ok; 2046280304Sjkim break; 2047280304Sjkim default: 2048280304Sjkim fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 2049280304Sjkim " STOPPING\n"); 2050280304Sjkim EXIT(1); 2051280304Sjkim } 2052280304Sjkim } 2053280304Sjkim break; 2054280304Sjkim default: 2055280304Sjkim goto end; 2056280304Sjkim } 2057280304Sjkim } 2058160814Ssimon end: 2059280304Sjkim if (debug) 2060280304Sjkim process_proxy_debug(indent, 2061280304Sjkim "End process_proxy_cond_multipliers at position %d: %s, returning %d\n", 2062280304Sjkim *pos, cond, ok); 2063160814Ssimon 2064280304Sjkim *cond_end = cond; 2065280304Sjkim return ok; 2066280304Sjkim} 2067280304Sjkim 2068160814Ssimonstatic int process_proxy_cond_adders(unsigned int letters[26], 2069280304Sjkim const char *cond, const char **cond_end, 2070280304Sjkim int *pos, int indent) 2071280304Sjkim{ 2072280304Sjkim int ok; 2073280304Sjkim char c; 2074160814Ssimon 2075280304Sjkim if (debug) 2076280304Sjkim process_proxy_debug(indent, 2077280304Sjkim "Start process_proxy_cond_adders at position %d: %s\n", 2078280304Sjkim *pos, cond); 2079160814Ssimon 2080280304Sjkim ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos, 2081280304Sjkim indent + 1); 2082280304Sjkim cond = *cond_end; 2083280304Sjkim if (ok < 0) 2084280304Sjkim goto end; 2085160814Ssimon 2086280304Sjkim while (ok >= 0) { 2087280304Sjkim while (isspace((int)*cond)) { 2088280304Sjkim cond++; 2089280304Sjkim (*pos)++; 2090280304Sjkim } 2091280304Sjkim c = *cond; 2092160814Ssimon 2093280304Sjkim switch (c) { 2094280304Sjkim case '|': 2095280304Sjkim { 2096280304Sjkim int save_ok = ok; 2097160814Ssimon 2098280304Sjkim cond++; 2099280304Sjkim (*pos)++; 2100280304Sjkim ok = process_proxy_cond_multipliers(letters, 2101280304Sjkim cond, cond_end, pos, 2102280304Sjkim indent + 1); 2103280304Sjkim cond = *cond_end; 2104280304Sjkim if (ok < 0) 2105280304Sjkim break; 2106160814Ssimon 2107280304Sjkim switch (c) { 2108280304Sjkim case '|': 2109280304Sjkim ok |= save_ok; 2110280304Sjkim break; 2111280304Sjkim default: 2112280304Sjkim fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 2113280304Sjkim " STOPPING\n"); 2114280304Sjkim EXIT(1); 2115280304Sjkim } 2116280304Sjkim } 2117280304Sjkim break; 2118280304Sjkim default: 2119280304Sjkim goto end; 2120280304Sjkim } 2121280304Sjkim } 2122160814Ssimon end: 2123280304Sjkim if (debug) 2124280304Sjkim process_proxy_debug(indent, 2125280304Sjkim "End process_proxy_cond_adders at position %d: %s, returning %d\n", 2126280304Sjkim *pos, cond, ok); 2127160814Ssimon 2128280304Sjkim *cond_end = cond; 2129280304Sjkim return ok; 2130280304Sjkim} 2131160814Ssimon 2132160814Ssimonstatic int process_proxy_cond(unsigned int letters[26], 2133280304Sjkim const char *cond, const char **cond_end) 2134280304Sjkim{ 2135280304Sjkim int pos = 1; 2136280304Sjkim return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1); 2137280304Sjkim} 2138160814Ssimon 2139109998Smarkmstatic int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) 2140280304Sjkim{ 2141280304Sjkim int ok = 1; 2142280304Sjkim struct app_verify_arg *cb_arg = arg; 2143280304Sjkim unsigned int letters[26]; /* only used with proxy_auth */ 2144109998Smarkm 2145280304Sjkim if (cb_arg->app_verify) { 2146280304Sjkim char *s = NULL, buf[256]; 2147160814Ssimon 2148280304Sjkim fprintf(stderr, "In app_verify_callback, allowing cert. "); 2149280304Sjkim fprintf(stderr, "Arg is: %s\n", cb_arg->string); 2150280304Sjkim fprintf(stderr, 2151280304Sjkim "Finished printing do we have a context? 0x%p a cert? 0x%p\n", 2152280304Sjkim (void *)ctx, (void *)ctx->cert); 2153280304Sjkim if (ctx->cert) 2154280304Sjkim s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256); 2155280304Sjkim if (s != NULL) { 2156280304Sjkim fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf); 2157280304Sjkim } 2158280304Sjkim return (1); 2159280304Sjkim } 2160280304Sjkim if (cb_arg->proxy_auth) { 2161280304Sjkim int found_any = 0, i; 2162280304Sjkim char *sp; 2163109998Smarkm 2164280304Sjkim for (i = 0; i < 26; i++) 2165280304Sjkim letters[i] = 0; 2166280304Sjkim for (sp = cb_arg->proxy_auth; *sp; sp++) { 2167280304Sjkim int c = *sp; 2168280304Sjkim if (isascii(c) && isalpha(c)) { 2169280304Sjkim if (islower(c)) 2170280304Sjkim c = toupper(c); 2171280304Sjkim letters[c - 'A'] = 1; 2172280304Sjkim } 2173280304Sjkim } 2174160814Ssimon 2175280304Sjkim fprintf(stderr, " Initial proxy rights = "); 2176280304Sjkim for (i = 0; i < 26; i++) 2177280304Sjkim if (letters[i]) { 2178280304Sjkim fprintf(stderr, "%c", i + 'A'); 2179280304Sjkim found_any = 1; 2180280304Sjkim } 2181280304Sjkim if (!found_any) 2182280304Sjkim fprintf(stderr, "none"); 2183280304Sjkim fprintf(stderr, "\n"); 2184160814Ssimon 2185280304Sjkim X509_STORE_CTX_set_ex_data(ctx, 2186280304Sjkim get_proxy_auth_ex_data_idx(), letters); 2187280304Sjkim } 2188280304Sjkim if (cb_arg->allow_proxy_certs) { 2189280304Sjkim X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); 2190280304Sjkim } 2191160814Ssimon#ifndef OPENSSL_NO_X509_VERIFY 2192280304Sjkim ok = X509_verify_cert(ctx); 2193160814Ssimon#endif 2194160814Ssimon 2195280304Sjkim if (cb_arg->proxy_auth) { 2196280304Sjkim if (ok > 0) { 2197280304Sjkim const char *cond_end = NULL; 2198160814Ssimon 2199280304Sjkim ok = process_proxy_cond(letters, cb_arg->proxy_cond, &cond_end); 2200160814Ssimon 2201280304Sjkim if (ok < 0) 2202280304Sjkim EXIT(3); 2203280304Sjkim if (*cond_end) { 2204280304Sjkim fprintf(stderr, 2205280304Sjkim "Stopped processing condition before it's end.\n"); 2206280304Sjkim ok = 0; 2207280304Sjkim } 2208280304Sjkim if (!ok) 2209280304Sjkim fprintf(stderr, 2210280304Sjkim "Proxy rights check with condition '%s' proved invalid\n", 2211280304Sjkim cb_arg->proxy_cond); 2212280304Sjkim else 2213280304Sjkim fprintf(stderr, 2214280304Sjkim "Proxy rights check with condition '%s' proved valid\n", 2215280304Sjkim cb_arg->proxy_cond); 2216280304Sjkim } 2217280304Sjkim } 2218280304Sjkim return (ok); 2219280304Sjkim} 2220109998Smarkm 2221109998Smarkm#ifndef OPENSSL_NO_RSA 2222280304Sjkimstatic RSA *rsa_tmp = NULL; 222368651Skris 222455714Skrisstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) 2225280304Sjkim{ 2226280304Sjkim BIGNUM *bn = NULL; 2227280304Sjkim if (rsa_tmp == NULL) { 2228280304Sjkim bn = BN_new(); 2229280304Sjkim rsa_tmp = RSA_new(); 2230280304Sjkim if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) { 2231280304Sjkim BIO_printf(bio_err, "Memory error..."); 2232280304Sjkim goto end; 2233280304Sjkim } 2234280304Sjkim BIO_printf(bio_err, "Generating temp (%d bit) RSA key...", keylength); 2235280304Sjkim (void)BIO_flush(bio_err); 2236280304Sjkim if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) { 2237280304Sjkim BIO_printf(bio_err, "Error generating key."); 2238280304Sjkim RSA_free(rsa_tmp); 2239280304Sjkim rsa_tmp = NULL; 2240280304Sjkim } 2241280304Sjkim end: 2242280304Sjkim BIO_printf(bio_err, "\n"); 2243280304Sjkim (void)BIO_flush(bio_err); 2244280304Sjkim } 2245280304Sjkim if (bn) 2246280304Sjkim BN_free(bn); 2247280304Sjkim return (rsa_tmp); 2248280304Sjkim} 224968651Skris 225068651Skrisstatic void free_tmp_rsa(void) 2251280304Sjkim{ 2252280304Sjkim if (rsa_tmp != NULL) { 2253280304Sjkim RSA_free(rsa_tmp); 2254280304Sjkim rsa_tmp = NULL; 2255280304Sjkim } 2256280304Sjkim} 225755714Skris#endif 225859191Skris 2259109998Smarkm#ifndef OPENSSL_NO_DH 2260280304Sjkim/*- 2261280304Sjkim * These DH parameters have been generated as follows: 226259191Skris * $ openssl dhparam -C -noout 512 226359191Skris * $ openssl dhparam -C -noout 1024 226459191Skris * $ openssl dhparam -C -noout -dsaparam 1024 226559191Skris * (The third function has been renamed to avoid name conflicts.) 226659191Skris */ 2267109998Smarkmstatic DH *get_dh512() 2268280304Sjkim{ 2269280304Sjkim static unsigned char dh512_p[] = { 2270280304Sjkim 0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0, 2271280304Sjkim 0xC6, 2272280304Sjkim 0x1F, 0x0D, 0xAC, 0xB6, 0x25, 0x3E, 0x06, 0x39, 0xCA, 0x72, 0x04, 2273280304Sjkim 0xB0, 2274280304Sjkim 0x6E, 0xDA, 0xC0, 0x61, 0xE6, 0x7A, 0x77, 0x25, 0xE8, 0x3B, 0xB9, 2275280304Sjkim 0x5F, 2276280304Sjkim 0x9A, 0xB6, 0xB5, 0xFE, 0x99, 0x0B, 0xA1, 0x93, 0x4E, 0x35, 0x33, 2277280304Sjkim 0xB8, 2278280304Sjkim 0xE1, 0xF1, 0x13, 0x4F, 0x59, 0x1A, 0xD2, 0x57, 0xC0, 0x26, 0x21, 2279280304Sjkim 0x33, 2280280304Sjkim 0x02, 0xC5, 0xAE, 0x23, 2281280304Sjkim }; 2282280304Sjkim static unsigned char dh512_g[] = { 2283280304Sjkim 0x02, 2284280304Sjkim }; 2285280304Sjkim DH *dh; 228659191Skris 2287280304Sjkim if ((dh = DH_new()) == NULL) 2288280304Sjkim return (NULL); 2289280304Sjkim dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); 2290280304Sjkim dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); 2291280304Sjkim if ((dh->p == NULL) || (dh->g == NULL)) { 2292280304Sjkim DH_free(dh); 2293280304Sjkim return (NULL); 2294280304Sjkim } 2295280304Sjkim return (dh); 2296280304Sjkim} 229759191Skris 2298109998Smarkmstatic DH *get_dh1024() 2299280304Sjkim{ 2300280304Sjkim static unsigned char dh1024_p[] = { 2301280304Sjkim 0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 2302280304Sjkim 0x3A, 2303280304Sjkim 0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 2304280304Sjkim 0xA2, 2305280304Sjkim 0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 2306280304Sjkim 0xB0, 2307280304Sjkim 0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 2308280304Sjkim 0xC2, 2309280304Sjkim 0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 2310280304Sjkim 0x8C, 2311280304Sjkim 0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 2312280304Sjkim 0xB8, 2313280304Sjkim 0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 2314280304Sjkim 0x52, 2315280304Sjkim 0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 2316280304Sjkim 0xC1, 2317280304Sjkim 0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 2318280304Sjkim 0xB1, 2319280304Sjkim 0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 2320280304Sjkim 0xAB, 2321280304Sjkim 0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53, 2322280304Sjkim }; 2323280304Sjkim static unsigned char dh1024_g[] = { 2324280304Sjkim 0x02, 2325280304Sjkim }; 2326280304Sjkim DH *dh; 232759191Skris 2328280304Sjkim if ((dh = DH_new()) == NULL) 2329280304Sjkim return (NULL); 2330280304Sjkim dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 2331280304Sjkim dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 2332280304Sjkim if ((dh->p == NULL) || (dh->g == NULL)) { 2333280304Sjkim DH_free(dh); 2334280304Sjkim return (NULL); 2335280304Sjkim } 2336280304Sjkim return (dh); 2337280304Sjkim} 233859191Skris 2339109998Smarkmstatic DH *get_dh1024dsa() 2340280304Sjkim{ 2341280304Sjkim static unsigned char dh1024_p[] = { 2342280304Sjkim 0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 2343280304Sjkim 0x00, 2344280304Sjkim 0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 2345280304Sjkim 0x19, 2346280304Sjkim 0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 2347280304Sjkim 0xD2, 2348280304Sjkim 0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 2349280304Sjkim 0x55, 2350280304Sjkim 0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 2351280304Sjkim 0xFC, 2352280304Sjkim 0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 2353280304Sjkim 0x97, 2354280304Sjkim 0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 2355280304Sjkim 0x8D, 2356280304Sjkim 0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 2357280304Sjkim 0xBB, 2358280304Sjkim 0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 2359280304Sjkim 0xF6, 2360280304Sjkim 0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 2361280304Sjkim 0x9E, 2362280304Sjkim 0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39, 2363280304Sjkim }; 2364280304Sjkim static unsigned char dh1024_g[] = { 2365280304Sjkim 0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 2366280304Sjkim 0x05, 2367280304Sjkim 0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 2368280304Sjkim 0xF3, 2369280304Sjkim 0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 2370280304Sjkim 0xE9, 2371280304Sjkim 0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 2372280304Sjkim 0x3C, 2373280304Sjkim 0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 2374280304Sjkim 0x65, 2375280304Sjkim 0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 2376280304Sjkim 0x60, 2377280304Sjkim 0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 2378280304Sjkim 0xF6, 2379280304Sjkim 0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 2380280304Sjkim 0xA7, 2381280304Sjkim 0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 2382280304Sjkim 0xA1, 2383280304Sjkim 0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 2384280304Sjkim 0x60, 2385280304Sjkim 0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2, 2386280304Sjkim }; 2387280304Sjkim DH *dh; 238859191Skris 2389280304Sjkim if ((dh = DH_new()) == NULL) 2390280304Sjkim return (NULL); 2391280304Sjkim dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 2392280304Sjkim dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 2393280304Sjkim if ((dh->p == NULL) || (dh->g == NULL)) { 2394280304Sjkim DH_free(dh); 2395280304Sjkim return (NULL); 2396280304Sjkim } 2397280304Sjkim dh->length = 160; 2398280304Sjkim return (dh); 2399280304Sjkim} 240059191Skris#endif 2401160814Ssimon 2402238405Sjkim#ifndef OPENSSL_NO_PSK 2403238405Sjkim/* convert the PSK key (psk_key) in ascii to binary (psk) */ 2404238405Sjkimstatic int psk_key2bn(const char *pskkey, unsigned char *psk, 2405280304Sjkim unsigned int max_psk_len) 2406280304Sjkim{ 2407280304Sjkim int ret; 2408280304Sjkim BIGNUM *bn = NULL; 2409238405Sjkim 2410280304Sjkim ret = BN_hex2bn(&bn, pskkey); 2411280304Sjkim if (!ret) { 2412280304Sjkim BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", 2413280304Sjkim pskkey); 2414280304Sjkim if (bn) 2415280304Sjkim BN_free(bn); 2416280304Sjkim return 0; 2417280304Sjkim } 2418280304Sjkim if (BN_num_bytes(bn) > (int)max_psk_len) { 2419280304Sjkim BIO_printf(bio_err, 2420280304Sjkim "psk buffer of callback is too small (%d) for key (%d)\n", 2421280304Sjkim max_psk_len, BN_num_bytes(bn)); 2422280304Sjkim BN_free(bn); 2423280304Sjkim return 0; 2424280304Sjkim } 2425280304Sjkim ret = BN_bn2bin(bn, psk); 2426280304Sjkim BN_free(bn); 2427280304Sjkim return ret; 2428280304Sjkim} 2429238405Sjkim 2430280304Sjkimstatic unsigned int psk_client_callback(SSL *ssl, const char *hint, 2431280304Sjkim char *identity, 2432280304Sjkim unsigned int max_identity_len, 2433280304Sjkim unsigned char *psk, 2434280304Sjkim unsigned int max_psk_len) 2435280304Sjkim{ 2436280304Sjkim int ret; 2437280304Sjkim unsigned int psk_len = 0; 2438238405Sjkim 2439280304Sjkim ret = BIO_snprintf(identity, max_identity_len, "Client_identity"); 2440280304Sjkim if (ret < 0) 2441280304Sjkim goto out_err; 2442280304Sjkim if (debug) 2443280304Sjkim fprintf(stderr, "client: created identity '%s' len=%d\n", identity, 2444280304Sjkim ret); 2445280304Sjkim ret = psk_key2bn(psk_key, psk, max_psk_len); 2446280304Sjkim if (ret < 0) 2447280304Sjkim goto out_err; 2448280304Sjkim psk_len = ret; 2449280304Sjkim out_err: 2450280304Sjkim return psk_len; 2451280304Sjkim} 2452238405Sjkim 2453238405Sjkimstatic unsigned int psk_server_callback(SSL *ssl, const char *identity, 2454280304Sjkim unsigned char *psk, 2455280304Sjkim unsigned int max_psk_len) 2456280304Sjkim{ 2457280304Sjkim unsigned int psk_len = 0; 2458238405Sjkim 2459280304Sjkim if (strcmp(identity, "Client_identity") != 0) { 2460280304Sjkim BIO_printf(bio_err, "server: PSK error: client identity not found\n"); 2461280304Sjkim return 0; 2462280304Sjkim } 2463280304Sjkim psk_len = psk_key2bn(psk_key, psk, max_psk_len); 2464280304Sjkim return psk_len; 2465280304Sjkim} 2466238405Sjkim#endif 2467238405Sjkim 2468160814Ssimonstatic int do_test_cipherlist(void) 2469280304Sjkim{ 2470280304Sjkim int i = 0; 2471280304Sjkim const SSL_METHOD *meth; 2472280304Sjkim const SSL_CIPHER *ci, *tci = NULL; 2473160814Ssimon 2474160814Ssimon#ifndef OPENSSL_NO_SSL2 2475280304Sjkim fprintf(stderr, "testing SSLv2 cipher list order: "); 2476280304Sjkim meth = SSLv2_method(); 2477280304Sjkim while ((ci = meth->get_cipher(i++)) != NULL) { 2478280304Sjkim if (tci != NULL) 2479280304Sjkim if (ci->id >= tci->id) { 2480280304Sjkim fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2481280304Sjkim return 0; 2482280304Sjkim } 2483280304Sjkim tci = ci; 2484280304Sjkim } 2485280304Sjkim fprintf(stderr, "ok\n"); 2486160814Ssimon#endif 2487160814Ssimon#ifndef OPENSSL_NO_SSL3 2488280304Sjkim fprintf(stderr, "testing SSLv3 cipher list order: "); 2489280304Sjkim meth = SSLv3_method(); 2490280304Sjkim tci = NULL; 2491280304Sjkim while ((ci = meth->get_cipher(i++)) != NULL) { 2492280304Sjkim if (tci != NULL) 2493280304Sjkim if (ci->id >= tci->id) { 2494280304Sjkim fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2495280304Sjkim return 0; 2496280304Sjkim } 2497280304Sjkim tci = ci; 2498280304Sjkim } 2499280304Sjkim fprintf(stderr, "ok\n"); 2500160814Ssimon#endif 2501160814Ssimon#ifndef OPENSSL_NO_TLS1 2502280304Sjkim fprintf(stderr, "testing TLSv1 cipher list order: "); 2503280304Sjkim meth = TLSv1_method(); 2504280304Sjkim tci = NULL; 2505280304Sjkim while ((ci = meth->get_cipher(i++)) != NULL) { 2506280304Sjkim if (tci != NULL) 2507280304Sjkim if (ci->id >= tci->id) { 2508280304Sjkim fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2509280304Sjkim return 0; 2510280304Sjkim } 2511280304Sjkim tci = ci; 2512280304Sjkim } 2513280304Sjkim fprintf(stderr, "ok\n"); 2514160814Ssimon#endif 2515160814Ssimon 2516280304Sjkim return 1; 2517280304Sjkim} 2518