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 145291721Sjkim#define _DEFAULT_SOURCE 1 146109998Smarkm 14759191Skris#include <assert.h> 14859191Skris#include <errno.h> 14959191Skris#include <limits.h> 15055714Skris#include <stdio.h> 15155714Skris#include <stdlib.h> 15255714Skris#include <string.h> 15359191Skris#include <time.h> 15455714Skris 155109998Smarkm#define USE_SOCKETS 156109998Smarkm#include "e_os.h" 15755714Skris 158238405Sjkim#ifdef OPENSSL_SYS_VMS 159280304Sjkim/* 160280304Sjkim * Or isascii won't be declared properly on VMS (at least with DECompHP C). 161280304Sjkim */ 162280304Sjkim# define _XOPEN_SOURCE 500 163238405Sjkim#endif 164238405Sjkim 165160814Ssimon#include <ctype.h> 166160814Ssimon 16755714Skris#include <openssl/bio.h> 16855714Skris#include <openssl/crypto.h> 16959191Skris#include <openssl/evp.h> 17055714Skris#include <openssl/x509.h> 171160814Ssimon#include <openssl/x509v3.h> 17255714Skris#include <openssl/ssl.h> 173111147Snectar#ifndef OPENSSL_NO_ENGINE 174280304Sjkim# include <openssl/engine.h> 175111147Snectar#endif 17655714Skris#include <openssl/err.h> 17759191Skris#include <openssl/rand.h> 178160814Ssimon#ifndef OPENSSL_NO_RSA 179280304Sjkim# include <openssl/rsa.h> 180160814Ssimon#endif 181160814Ssimon#ifndef OPENSSL_NO_DSA 182280304Sjkim# include <openssl/dsa.h> 183160814Ssimon#endif 184160814Ssimon#ifndef OPENSSL_NO_DH 185280304Sjkim# include <openssl/dh.h> 186160814Ssimon#endif 187238405Sjkim#ifndef OPENSSL_NO_SRP 188280304Sjkim# include <openssl/srp.h> 189238405Sjkim#endif 190160814Ssimon#include <openssl/bn.h> 191109998Smarkm 192280304Sjkim/* 193280304Sjkim * Or gethostname won't be declared properly 194280304Sjkim * on Compaq platforms (at least with DEC C). 195280304Sjkim * Do not try to put it earlier, or IPv6 includes 196280304Sjkim * get screwed... 197280304Sjkim */ 198280304Sjkim#define _XOPEN_SOURCE_EXTENDED 1 199109998Smarkm 200109998Smarkm#ifdef OPENSSL_SYS_WINDOWS 201280304Sjkim# include <winsock.h> 202109998Smarkm#else 203280304Sjkim# include OPENSSL_UNISTD 20455714Skris#endif 20555714Skris 206109998Smarkm#ifdef OPENSSL_SYS_VMS 207280304Sjkim# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM" 208280304Sjkim# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM" 209109998Smarkm#elif defined(OPENSSL_SYS_WINCE) 210280304Sjkim# define TEST_SERVER_CERT "\\OpenSSL\\server.pem" 211280304Sjkim# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem" 212160814Ssimon#elif defined(OPENSSL_SYS_NETWARE) 213280304Sjkim# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem" 214280304Sjkim# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem" 21555714Skris#else 216280304Sjkim# define TEST_SERVER_CERT "../apps/server.pem" 217280304Sjkim# define TEST_CLIENT_CERT "../apps/client.pem" 21855714Skris#endif 21955714Skris 220280304Sjkim/* 221280304Sjkim * There is really no standard for this, so let's assign some tentative 222280304Sjkim * numbers. In any case, these numbers are only for this test 223280304Sjkim */ 224280304Sjkim#define COMP_RLE 255 225280304Sjkim#define COMP_ZLIB 1 226109998Smarkm 22759191Skrisstatic int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); 228109998Smarkm#ifndef OPENSSL_NO_RSA 229280304Sjkimstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); 23068651Skrisstatic void free_tmp_rsa(void); 23155714Skris#endif 232109998Smarkmstatic int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg); 233160814Ssimon#define APP_CALLBACK_STRING "Test Callback Argument" 234280304Sjkimstruct app_verify_arg { 235280304Sjkim char *string; 236280304Sjkim int app_verify; 237280304Sjkim int allow_proxy_certs; 238280304Sjkim char *proxy_auth; 239280304Sjkim char *proxy_cond; 240280304Sjkim}; 241109998Smarkm 242109998Smarkm#ifndef OPENSSL_NO_DH 24355714Skrisstatic DH *get_dh512(void); 24459191Skrisstatic DH *get_dh1024(void); 24559191Skrisstatic DH *get_dh1024dsa(void); 24655714Skris#endif 24755714Skris 248280304Sjkimstatic char *psk_key = NULL; /* by default PSK is not used */ 249238405Sjkim#ifndef OPENSSL_NO_PSK 250280304Sjkimstatic unsigned int psk_client_callback(SSL *ssl, const char *hint, 251280304Sjkim char *identity, 252280304Sjkim unsigned int max_identity_len, 253280304Sjkim unsigned char *psk, 254280304Sjkim unsigned int max_psk_len); 255280304Sjkimstatic unsigned int psk_server_callback(SSL *ssl, const char *identity, 256280304Sjkim unsigned char *psk, 257280304Sjkim unsigned int max_psk_len); 258238405Sjkim#endif 259238405Sjkim 260238405Sjkim#ifndef OPENSSL_NO_SRP 261238405Sjkim/* SRP client */ 262238405Sjkim/* This is a context that we pass to all callbacks */ 263280304Sjkimtypedef struct srp_client_arg_st { 264280304Sjkim char *srppassin; 265280304Sjkim char *srplogin; 266280304Sjkim} SRP_CLIENT_ARG; 267238405Sjkim 268280304Sjkim# define PWD_STRLEN 1024 269238405Sjkim 270280304Sjkimstatic char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg) 271280304Sjkim{ 272280304Sjkim SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; 273280304Sjkim return BUF_strdup((char *)srp_client_arg->srppassin); 274280304Sjkim} 275238405Sjkim 276238405Sjkim/* SRP server */ 277238405Sjkim/* This is a context that we pass to SRP server callbacks */ 278280304Sjkimtypedef struct srp_server_arg_st { 279280304Sjkim char *expected_user; 280280304Sjkim char *pass; 281280304Sjkim} SRP_SERVER_ARG; 282238405Sjkim 283238405Sjkimstatic int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) 284280304Sjkim{ 285280304Sjkim SRP_SERVER_ARG *p = (SRP_SERVER_ARG *)arg; 286238405Sjkim 287280304Sjkim if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0) { 288280304Sjkim fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s)); 289280304Sjkim return SSL3_AL_FATAL; 290280304Sjkim } 291280304Sjkim if (SSL_set_srp_server_param_pw(s, p->expected_user, p->pass, "1024") < 0) { 292280304Sjkim *ad = SSL_AD_INTERNAL_ERROR; 293280304Sjkim return SSL3_AL_FATAL; 294280304Sjkim } 295280304Sjkim return SSL_ERROR_NONE; 296280304Sjkim} 297238405Sjkim#endif 298238405Sjkim 299280304Sjkimstatic BIO *bio_err = NULL; 300280304Sjkimstatic BIO *bio_stdout = NULL; 30159191Skris 302280304Sjkimstatic char *cipher = NULL; 303280304Sjkimstatic int verbose = 0; 304280304Sjkimstatic int debug = 0; 30555714Skris#if 0 30655714Skris/* Not used yet. */ 307280304Sjkim# ifdef FIONBIO 308280304Sjkimstatic int s_nbio = 0; 309280304Sjkim# endif 31055714Skris#endif 31155714Skris 312280304Sjkimstatic const char rnd_seed[] = 313280304Sjkim "string to make the random number generator think it has entropy"; 31455714Skris 315280304Sjkimint doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time, 316280304Sjkim clock_t *c_time); 317280304Sjkimint doit(SSL *s_ssl, SSL *c_ssl, long bytes); 318160814Ssimonstatic int do_test_cipherlist(void); 31955714Skrisstatic void sv_usage(void) 320280304Sjkim{ 321280304Sjkim fprintf(stderr, "usage: ssltest [args ...]\n"); 322280304Sjkim fprintf(stderr, "\n"); 323194206Ssimon#ifdef OPENSSL_FIPS 324280304Sjkim fprintf(stderr, "-F - run test in FIPS mode\n"); 325194206Ssimon#endif 326280304Sjkim fprintf(stderr, " -server_auth - check server certificate\n"); 327280304Sjkim fprintf(stderr, " -client_auth - do client authentication\n"); 328280304Sjkim fprintf(stderr, " -proxy - allow proxy certificates\n"); 329280304Sjkim fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n"); 330280304Sjkim fprintf(stderr, 331280304Sjkim " -proxy_cond <val> - experssion to test proxy policy rights\n"); 332280304Sjkim fprintf(stderr, " -v - more output\n"); 333280304Sjkim fprintf(stderr, " -d - debug output\n"); 334280304Sjkim fprintf(stderr, " -reuse - use session-id reuse\n"); 335280304Sjkim fprintf(stderr, " -num <val> - number of connections to perform\n"); 336280304Sjkim fprintf(stderr, 337280304Sjkim " -bytes <val> - number of bytes to swap between client/server\n"); 338109998Smarkm#ifndef OPENSSL_NO_DH 339280304Sjkim fprintf(stderr, 340284285Sjkim " -dhe512 - use 512 bit key for DHE (to test failure)\n"); 341280304Sjkim fprintf(stderr, 342284285Sjkim " -dhe1024 - use 1024 bit key (safe prime) for DHE (default, no-op)\n"); 343284285Sjkim fprintf(stderr, 344280304Sjkim " -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); 345280304Sjkim fprintf(stderr, " -no_dhe - disable DHE\n"); 34655714Skris#endif 347160814Ssimon#ifndef OPENSSL_NO_ECDH 348280304Sjkim fprintf(stderr, " -no_ecdhe - disable ECDHE\n"); 349160814Ssimon#endif 350238405Sjkim#ifndef OPENSSL_NO_PSK 351280304Sjkim fprintf(stderr, " -psk arg - PSK in hex (without 0x)\n"); 352238405Sjkim#endif 353238405Sjkim#ifndef OPENSSL_NO_SRP 354280304Sjkim fprintf(stderr, " -srpuser user - SRP username to use\n"); 355280304Sjkim fprintf(stderr, " -srppass arg - password for 'user'\n"); 356238405Sjkim#endif 357109998Smarkm#ifndef OPENSSL_NO_SSL2 358280304Sjkim fprintf(stderr, " -ssl2 - use SSLv2\n"); 35955714Skris#endif 360276864Sjkim#ifndef OPENSSL_NO_SSL3_METHOD 361280304Sjkim fprintf(stderr, " -ssl3 - use SSLv3\n"); 36255714Skris#endif 363109998Smarkm#ifndef OPENSSL_NO_TLS1 364280304Sjkim fprintf(stderr, " -tls1 - use TLSv1\n"); 36555714Skris#endif 366280304Sjkim fprintf(stderr, " -CApath arg - PEM format directory of CA's\n"); 367280304Sjkim fprintf(stderr, " -CAfile arg - PEM format file of CA's\n"); 368280304Sjkim fprintf(stderr, " -cert arg - Server certificate file\n"); 369280304Sjkim fprintf(stderr, 370280304Sjkim " -key arg - Server key file (default: same as -cert)\n"); 371280304Sjkim fprintf(stderr, " -c_cert arg - Client certificate file\n"); 372280304Sjkim fprintf(stderr, 373280304Sjkim " -c_key arg - Client key file (default: same as -c_cert)\n"); 374280304Sjkim fprintf(stderr, " -cipher arg - The cipher list\n"); 375280304Sjkim fprintf(stderr, " -bio_pair - Use BIO pairs\n"); 376280304Sjkim fprintf(stderr, " -f - Test even cases that can't work\n"); 377280304Sjkim fprintf(stderr, 378280304Sjkim " -time - measure processor time used by client and server\n"); 379280304Sjkim fprintf(stderr, " -zlib - use zlib compression\n"); 380280304Sjkim fprintf(stderr, " -rle - use rle compression\n"); 381160814Ssimon#ifndef OPENSSL_NO_ECDH 382280304Sjkim fprintf(stderr, 383280304Sjkim " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" 384280304Sjkim " Use \"openssl ecparam -list_curves\" for all names\n" 385280304Sjkim " (default is sect163r2).\n"); 386160814Ssimon#endif 387280304Sjkim fprintf(stderr, 388280304Sjkim " -test_cipherlist - Verifies the order of the ssl cipher lists.\n" 389280304Sjkim " When this option is requested, the cipherlist\n" 390280304Sjkim " tests are run instead of handshake tests.\n"); 391280304Sjkim} 39255714Skris 39359191Skrisstatic void print_details(SSL *c_ssl, const char *prefix) 394280304Sjkim{ 395280304Sjkim const SSL_CIPHER *ciph; 396280304Sjkim X509 *cert; 397280304Sjkim 398280304Sjkim ciph = SSL_get_current_cipher(c_ssl); 399280304Sjkim BIO_printf(bio_stdout, "%s%s, cipher %s %s", 400280304Sjkim prefix, 401280304Sjkim SSL_get_version(c_ssl), 402280304Sjkim SSL_CIPHER_get_version(ciph), SSL_CIPHER_get_name(ciph)); 403280304Sjkim cert = SSL_get_peer_certificate(c_ssl); 404280304Sjkim if (cert != NULL) { 405280304Sjkim EVP_PKEY *pkey = X509_get_pubkey(cert); 406280304Sjkim if (pkey != NULL) { 407280304Sjkim if (0) ; 408109998Smarkm#ifndef OPENSSL_NO_RSA 409280304Sjkim else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL 410280304Sjkim && pkey->pkey.rsa->n != NULL) { 411280304Sjkim BIO_printf(bio_stdout, ", %d bit RSA", 412280304Sjkim BN_num_bits(pkey->pkey.rsa->n)); 413280304Sjkim } 41459191Skris#endif 415109998Smarkm#ifndef OPENSSL_NO_DSA 416280304Sjkim else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL 417280304Sjkim && pkey->pkey.dsa->p != NULL) { 418280304Sjkim BIO_printf(bio_stdout, ", %d bit DSA", 419280304Sjkim BN_num_bits(pkey->pkey.dsa->p)); 420280304Sjkim } 42159191Skris#endif 422280304Sjkim EVP_PKEY_free(pkey); 423280304Sjkim } 424280304Sjkim X509_free(cert); 425280304Sjkim } 426280304Sjkim /* 427280304Sjkim * The SSL API does not allow us to look at temporary RSA/DH keys, 428280304Sjkim * otherwise we should print their lengths too 429280304Sjkim */ 430280304Sjkim BIO_printf(bio_stdout, "\n"); 431280304Sjkim} 43259191Skris 433109998Smarkmstatic void lock_dbg_cb(int mode, int type, const char *file, int line) 434280304Sjkim{ 435280304Sjkim static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ 436280304Sjkim const char *errstr = NULL; 437280304Sjkim int rw; 438109998Smarkm 439280304Sjkim rw = mode & (CRYPTO_READ | CRYPTO_WRITE); 440280304Sjkim if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { 441280304Sjkim errstr = "invalid mode"; 442280304Sjkim goto err; 443280304Sjkim } 444109998Smarkm 445280304Sjkim if (type < 0 || type >= CRYPTO_NUM_LOCKS) { 446280304Sjkim errstr = "type out of bounds"; 447280304Sjkim goto err; 448280304Sjkim } 449109998Smarkm 450280304Sjkim if (mode & CRYPTO_LOCK) { 451280304Sjkim if (modes[type]) { 452280304Sjkim errstr = "already locked"; 453280304Sjkim /* 454280304Sjkim * must not happen in a single-threaded program (would deadlock) 455280304Sjkim */ 456280304Sjkim goto err; 457280304Sjkim } 458109998Smarkm 459280304Sjkim modes[type] = rw; 460280304Sjkim } else if (mode & CRYPTO_UNLOCK) { 461280304Sjkim if (!modes[type]) { 462280304Sjkim errstr = "not locked"; 463280304Sjkim goto err; 464280304Sjkim } 465109998Smarkm 466280304Sjkim if (modes[type] != rw) { 467280304Sjkim errstr = (rw == CRYPTO_READ) ? 468280304Sjkim "CRYPTO_r_unlock on write lock" : 469280304Sjkim "CRYPTO_w_unlock on read lock"; 470280304Sjkim } 471280304Sjkim 472280304Sjkim modes[type] = 0; 473280304Sjkim } else { 474280304Sjkim errstr = "invalid mode"; 475280304Sjkim goto err; 476280304Sjkim } 477280304Sjkim 478109998Smarkm err: 479280304Sjkim if (errstr) { 480280304Sjkim /* we cannot use bio_err here */ 481280304Sjkim fprintf(stderr, 482280304Sjkim "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", 483280304Sjkim errstr, mode, type, file, line); 484280304Sjkim } 485280304Sjkim} 486109998Smarkm 487238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 488280304Sjkimstruct cb_info_st { 489280304Sjkim void *input; 490280304Sjkim size_t len; 491280304Sjkim int ret; 492280304Sjkim}; 493238405Sjkimstruct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */ 494238405Sjkimstruct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */ 495238405Sjkimstruct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */ 496238405Sjkimstruct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */ 497160814Ssimon 498238405Sjkimint opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_) 499280304Sjkim{ 500280304Sjkim struct cb_info_st *arg = arg_; 501238405Sjkim 502280304Sjkim if (arg == NULL) 503280304Sjkim return 1; 504280304Sjkim 505280304Sjkim if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len)) 506280304Sjkim return 0; 507280304Sjkim return arg->ret; 508280304Sjkim} 509238405Sjkim#endif 510238405Sjkim 51155714Skrisint main(int argc, char *argv[]) 512280304Sjkim{ 513280304Sjkim char *CApath = NULL, *CAfile = NULL; 514280304Sjkim int badop = 0; 515280304Sjkim int bio_pair = 0; 516280304Sjkim int force = 0; 517280304Sjkim int tls1 = 0, ssl2 = 0, ssl3 = 0, ret = 1; 518280304Sjkim int client_auth = 0; 519280304Sjkim int server_auth = 0, i; 520280304Sjkim struct app_verify_arg app_verify_arg = 521280304Sjkim { APP_CALLBACK_STRING, 0, 0, NULL, NULL }; 522280304Sjkim char *server_cert = TEST_SERVER_CERT; 523280304Sjkim char *server_key = NULL; 524280304Sjkim char *client_cert = TEST_CLIENT_CERT; 525280304Sjkim char *client_key = NULL; 526160814Ssimon#ifndef OPENSSL_NO_ECDH 527280304Sjkim char *named_curve = NULL; 528160814Ssimon#endif 529280304Sjkim SSL_CTX *s_ctx = NULL; 530280304Sjkim SSL_CTX *c_ctx = NULL; 531280304Sjkim const SSL_METHOD *meth = NULL; 532280304Sjkim SSL *c_ssl, *s_ssl; 533280304Sjkim int number = 1, reuse = 0; 534280304Sjkim long bytes = 256L; 535109998Smarkm#ifndef OPENSSL_NO_DH 536280304Sjkim DH *dh; 537284285Sjkim int dhe512 = 0, dhe1024dsa = 0; 53855714Skris#endif 539160814Ssimon#ifndef OPENSSL_NO_ECDH 540280304Sjkim EC_KEY *ecdh = NULL; 541160814Ssimon#endif 542238405Sjkim#ifndef OPENSSL_NO_SRP 543280304Sjkim /* client */ 544280304Sjkim SRP_CLIENT_ARG srp_client_arg = { NULL, NULL }; 545280304Sjkim /* server */ 546280304Sjkim SRP_SERVER_ARG srp_server_arg = { NULL, NULL }; 547238405Sjkim#endif 548280304Sjkim int no_dhe = 0; 549280304Sjkim int no_ecdhe = 0; 550280304Sjkim int no_psk = 0; 551280304Sjkim int print_time = 0; 552280304Sjkim clock_t s_time = 0, c_time = 0; 553280304Sjkim int comp = 0; 554160814Ssimon#ifndef OPENSSL_NO_COMP 555280304Sjkim COMP_METHOD *cm = NULL; 556280304Sjkim STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; 557142425Snectar#endif 558280304Sjkim int test_cipherlist = 0; 559194206Ssimon#ifdef OPENSSL_FIPS 560280304Sjkim int fips_mode = 0; 561194206Ssimon#endif 562280304Sjkim int no_protocol = 0; 56355714Skris 564280304Sjkim verbose = 0; 565280304Sjkim debug = 0; 566280304Sjkim cipher = 0; 567109998Smarkm 568280304Sjkim bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 569109998Smarkm 570280304Sjkim CRYPTO_set_locking_callback(lock_dbg_cb); 571109998Smarkm 572280304Sjkim /* enable memory leak checking unless explicitly disabled */ 573280304Sjkim if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) 574280304Sjkim && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 575280304Sjkim CRYPTO_malloc_debug_init(); 576280304Sjkim CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 577280304Sjkim } else { 578280304Sjkim /* OPENSSL_DEBUG_MEMORY=off */ 579280304Sjkim CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 580280304Sjkim } 581280304Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 58259191Skris 583280304Sjkim RAND_seed(rnd_seed, sizeof rnd_seed); 58459191Skris 585280304Sjkim bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); 58655714Skris 587280304Sjkim argc--; 588280304Sjkim argv++; 58955714Skris 590280304Sjkim while (argc >= 1) { 591280304Sjkim if (!strcmp(*argv, "-F")) { 592194206Ssimon#ifdef OPENSSL_FIPS 593280304Sjkim fips_mode = 1; 594194206Ssimon#else 595280304Sjkim fprintf(stderr, 596280304Sjkim "not compiled with FIPS support, so exitting without running.\n"); 597280304Sjkim EXIT(0); 598194206Ssimon#endif 599280304Sjkim } else if (strcmp(*argv, "-server_auth") == 0) 600280304Sjkim server_auth = 1; 601280304Sjkim else if (strcmp(*argv, "-client_auth") == 0) 602280304Sjkim client_auth = 1; 603280304Sjkim else if (strcmp(*argv, "-proxy_auth") == 0) { 604280304Sjkim if (--argc < 1) 605280304Sjkim goto bad; 606280304Sjkim app_verify_arg.proxy_auth = *(++argv); 607280304Sjkim } else if (strcmp(*argv, "-proxy_cond") == 0) { 608280304Sjkim if (--argc < 1) 609280304Sjkim goto bad; 610280304Sjkim app_verify_arg.proxy_cond = *(++argv); 611280304Sjkim } else if (strcmp(*argv, "-v") == 0) 612280304Sjkim verbose = 1; 613280304Sjkim else if (strcmp(*argv, "-d") == 0) 614280304Sjkim debug = 1; 615280304Sjkim else if (strcmp(*argv, "-reuse") == 0) 616280304Sjkim reuse = 1; 617284285Sjkim else if (strcmp(*argv, "-dhe512") == 0) { 618109998Smarkm#ifndef OPENSSL_NO_DH 619284285Sjkim dhe512 = 1; 620109998Smarkm#else 621280304Sjkim fprintf(stderr, 622284285Sjkim "ignoring -dhe512, since I'm compiled without DH\n"); 623109998Smarkm#endif 624280304Sjkim } else if (strcmp(*argv, "-dhe1024dsa") == 0) { 625109998Smarkm#ifndef OPENSSL_NO_DH 626280304Sjkim dhe1024dsa = 1; 627109998Smarkm#else 628280304Sjkim fprintf(stderr, 629284285Sjkim "ignoring -dhe1024dsa, since I'm compiled without DH\n"); 63059191Skris#endif 631280304Sjkim } else if (strcmp(*argv, "-no_dhe") == 0) 632280304Sjkim no_dhe = 1; 633280304Sjkim else if (strcmp(*argv, "-no_ecdhe") == 0) 634280304Sjkim no_ecdhe = 1; 635280304Sjkim else if (strcmp(*argv, "-psk") == 0) { 636280304Sjkim if (--argc < 1) 637280304Sjkim goto bad; 638280304Sjkim psk_key = *(++argv); 639238405Sjkim#ifndef OPENSSL_NO_PSK 640280304Sjkim if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key)) { 641280304Sjkim BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); 642280304Sjkim goto bad; 643280304Sjkim } 644238405Sjkim#else 645280304Sjkim no_psk = 1; 646238405Sjkim#endif 647280304Sjkim } 648238405Sjkim#ifndef OPENSSL_NO_SRP 649280304Sjkim else if (strcmp(*argv, "-srpuser") == 0) { 650280304Sjkim if (--argc < 1) 651280304Sjkim goto bad; 652280304Sjkim srp_server_arg.expected_user = srp_client_arg.srplogin = 653280304Sjkim *(++argv); 654280304Sjkim tls1 = 1; 655280304Sjkim } else if (strcmp(*argv, "-srppass") == 0) { 656280304Sjkim if (--argc < 1) 657280304Sjkim goto bad; 658280304Sjkim srp_server_arg.pass = srp_client_arg.srppassin = *(++argv); 659280304Sjkim tls1 = 1; 660280304Sjkim } 661238405Sjkim#endif 662280304Sjkim else if (strcmp(*argv, "-ssl2") == 0) { 663276864Sjkim#ifdef OPENSSL_NO_SSL2 664280304Sjkim no_protocol = 1; 665276864Sjkim#endif 666280304Sjkim ssl2 = 1; 667280304Sjkim } else if (strcmp(*argv, "-tls1") == 0) { 668276864Sjkim#ifdef OPENSSL_NO_TLS1 669280304Sjkim no_protocol = 1; 670276864Sjkim#endif 671280304Sjkim tls1 = 1; 672280304Sjkim } else if (strcmp(*argv, "-ssl3") == 0) { 673276864Sjkim#ifdef OPENSSL_NO_SSL3_METHOD 674280304Sjkim no_protocol = 1; 675276864Sjkim#endif 676280304Sjkim ssl3 = 1; 677280304Sjkim } else if (strncmp(*argv, "-num", 4) == 0) { 678280304Sjkim if (--argc < 1) 679280304Sjkim goto bad; 680280304Sjkim number = atoi(*(++argv)); 681280304Sjkim if (number == 0) 682280304Sjkim number = 1; 683280304Sjkim } else if (strcmp(*argv, "-bytes") == 0) { 684280304Sjkim if (--argc < 1) 685280304Sjkim goto bad; 686280304Sjkim bytes = atol(*(++argv)); 687280304Sjkim if (bytes == 0L) 688280304Sjkim bytes = 1L; 689280304Sjkim i = strlen(argv[0]); 690280304Sjkim if (argv[0][i - 1] == 'k') 691280304Sjkim bytes *= 1024L; 692280304Sjkim if (argv[0][i - 1] == 'm') 693280304Sjkim bytes *= 1024L * 1024L; 694280304Sjkim } else if (strcmp(*argv, "-cert") == 0) { 695280304Sjkim if (--argc < 1) 696280304Sjkim goto bad; 697280304Sjkim server_cert = *(++argv); 698280304Sjkim } else if (strcmp(*argv, "-s_cert") == 0) { 699280304Sjkim if (--argc < 1) 700280304Sjkim goto bad; 701280304Sjkim server_cert = *(++argv); 702280304Sjkim } else if (strcmp(*argv, "-key") == 0) { 703280304Sjkim if (--argc < 1) 704280304Sjkim goto bad; 705280304Sjkim server_key = *(++argv); 706280304Sjkim } else if (strcmp(*argv, "-s_key") == 0) { 707280304Sjkim if (--argc < 1) 708280304Sjkim goto bad; 709280304Sjkim server_key = *(++argv); 710280304Sjkim } else if (strcmp(*argv, "-c_cert") == 0) { 711280304Sjkim if (--argc < 1) 712280304Sjkim goto bad; 713280304Sjkim client_cert = *(++argv); 714280304Sjkim } else if (strcmp(*argv, "-c_key") == 0) { 715280304Sjkim if (--argc < 1) 716280304Sjkim goto bad; 717280304Sjkim client_key = *(++argv); 718280304Sjkim } else if (strcmp(*argv, "-cipher") == 0) { 719280304Sjkim if (--argc < 1) 720280304Sjkim goto bad; 721280304Sjkim cipher = *(++argv); 722280304Sjkim } else if (strcmp(*argv, "-CApath") == 0) { 723280304Sjkim if (--argc < 1) 724280304Sjkim goto bad; 725280304Sjkim CApath = *(++argv); 726280304Sjkim } else if (strcmp(*argv, "-CAfile") == 0) { 727280304Sjkim if (--argc < 1) 728280304Sjkim goto bad; 729280304Sjkim CAfile = *(++argv); 730280304Sjkim } else if (strcmp(*argv, "-bio_pair") == 0) { 731280304Sjkim bio_pair = 1; 732280304Sjkim } else if (strcmp(*argv, "-f") == 0) { 733280304Sjkim force = 1; 734280304Sjkim } else if (strcmp(*argv, "-time") == 0) { 735280304Sjkim print_time = 1; 736280304Sjkim } else if (strcmp(*argv, "-zlib") == 0) { 737280304Sjkim comp = COMP_ZLIB; 738280304Sjkim } else if (strcmp(*argv, "-rle") == 0) { 739280304Sjkim comp = COMP_RLE; 740280304Sjkim } else if (strcmp(*argv, "-named_curve") == 0) { 741280304Sjkim if (--argc < 1) 742280304Sjkim goto bad; 743280304Sjkim#ifndef OPENSSL_NO_ECDH 744280304Sjkim named_curve = *(++argv); 745160814Ssimon#else 746280304Sjkim fprintf(stderr, 747280304Sjkim "ignoring -named_curve, since I'm compiled without ECDH\n"); 748280304Sjkim ++argv; 749160814Ssimon#endif 750280304Sjkim } else if (strcmp(*argv, "-app_verify") == 0) { 751280304Sjkim app_verify_arg.app_verify = 1; 752280304Sjkim } else if (strcmp(*argv, "-proxy") == 0) { 753280304Sjkim app_verify_arg.allow_proxy_certs = 1; 754280304Sjkim } else if (strcmp(*argv, "-test_cipherlist") == 0) { 755280304Sjkim test_cipherlist = 1; 756280304Sjkim } else { 757280304Sjkim fprintf(stderr, "unknown option %s\n", *argv); 758280304Sjkim badop = 1; 759280304Sjkim break; 760280304Sjkim } 761280304Sjkim argc--; 762280304Sjkim argv++; 763280304Sjkim } 764280304Sjkim if (badop) { 765280304Sjkim bad: 766280304Sjkim sv_usage(); 767280304Sjkim goto end; 768280304Sjkim } 76955714Skris 770280304Sjkim /* 771280304Sjkim * test_cipherlist prevails over protocol switch: we test the cipherlist 772280304Sjkim * for all enabled protocols. 773280304Sjkim */ 774280304Sjkim if (test_cipherlist == 1) { 775280304Sjkim /* 776280304Sjkim * ensure that the cipher list are correctly sorted and exit 777280304Sjkim */ 778280304Sjkim fprintf(stdout, "Testing cipherlist order only. Ignoring all " 779280304Sjkim "other options.\n"); 780280304Sjkim if (do_test_cipherlist() == 0) 781280304Sjkim EXIT(1); 782280304Sjkim ret = 0; 783280304Sjkim goto end; 784280304Sjkim } 785142425Snectar 786280304Sjkim if (ssl2 + ssl3 + tls1 > 1) { 787280304Sjkim fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should " 788280304Sjkim "be requested.\n"); 789280304Sjkim EXIT(1); 790280304Sjkim } 791276864Sjkim 792280304Sjkim /* 793280304Sjkim * Testing was requested for a compiled-out protocol (e.g. SSLv2). 794280304Sjkim * Ideally, we would error out, but the generic test wrapper can't know 795280304Sjkim * when to expect failure. So we do nothing and return success. 796280304Sjkim */ 797280304Sjkim if (no_protocol) { 798280304Sjkim fprintf(stderr, "Testing was requested for a disabled protocol. " 799280304Sjkim "Skipping tests.\n"); 800280304Sjkim ret = 0; 801280304Sjkim goto end; 802280304Sjkim } 803276864Sjkim 804280304Sjkim if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) { 805280304Sjkim fprintf(stderr, "This case cannot work. Use -f to perform " 806280304Sjkim "the test anyway (and\n-d to see what happens), " 807280304Sjkim "or add one of -ssl2, -ssl3, -tls1, -reuse\n" 808280304Sjkim "to avoid protocol mismatch.\n"); 809280304Sjkim EXIT(1); 810280304Sjkim } 811194206Ssimon#ifdef OPENSSL_FIPS 812280304Sjkim if (fips_mode) { 813280304Sjkim if (!FIPS_mode_set(1)) { 814280304Sjkim ERR_load_crypto_strings(); 815280304Sjkim ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE)); 816280304Sjkim EXIT(1); 817280304Sjkim } else 818280304Sjkim fprintf(stderr, "*** IN FIPS MODE ***\n"); 819280304Sjkim } 820194206Ssimon#endif 821194206Ssimon 822280304Sjkim if (print_time) { 823280304Sjkim if (!bio_pair) { 824280304Sjkim fprintf(stderr, "Using BIO pair (-bio_pair)\n"); 825280304Sjkim bio_pair = 1; 826280304Sjkim } 827280304Sjkim if (number < 50 && !force) 828280304Sjkim fprintf(stderr, 829280304Sjkim "Warning: For accurate timings, use more connections (e.g. -num 1000)\n"); 830280304Sjkim } 83159191Skris 832280304Sjkim/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */ 83355714Skris 834280304Sjkim SSL_library_init(); 835280304Sjkim SSL_load_error_strings(); 83655714Skris 837160814Ssimon#ifndef OPENSSL_NO_COMP 838280304Sjkim if (comp == COMP_ZLIB) 839280304Sjkim cm = COMP_zlib(); 840280304Sjkim if (comp == COMP_RLE) 841280304Sjkim cm = COMP_rle(); 842280304Sjkim if (cm != NULL) { 843280304Sjkim if (cm->type != NID_undef) { 844280304Sjkim if (SSL_COMP_add_compression_method(comp, cm) != 0) { 845280304Sjkim fprintf(stderr, "Failed to add compression method\n"); 846280304Sjkim ERR_print_errors_fp(stderr); 847280304Sjkim } 848280304Sjkim } else { 849280304Sjkim fprintf(stderr, 850280304Sjkim "Warning: %s compression not supported\n", 851280304Sjkim (comp == COMP_RLE ? "rle" : 852280304Sjkim (comp == COMP_ZLIB ? "zlib" : "unknown"))); 853280304Sjkim ERR_print_errors_fp(stderr); 854280304Sjkim } 855280304Sjkim } 856280304Sjkim ssl_comp_methods = SSL_COMP_get_compression_methods(); 857280304Sjkim fprintf(stderr, "Available compression methods:\n"); 858280304Sjkim { 859280304Sjkim int j, n = sk_SSL_COMP_num(ssl_comp_methods); 860280304Sjkim if (n == 0) 861280304Sjkim fprintf(stderr, " NONE\n"); 862280304Sjkim else 863280304Sjkim for (j = 0; j < n; j++) { 864280304Sjkim SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); 865280304Sjkim fprintf(stderr, " %d: %s\n", c->id, c->name); 866280304Sjkim } 867280304Sjkim } 868160814Ssimon#endif 869109998Smarkm 870280304Sjkim /* 871280304Sjkim * At this point, ssl2/ssl3/tls1 is only set if the protocol is 872280304Sjkim * available. (Otherwise we exit early.) However the compiler doesn't 873280304Sjkim * know this, so we ifdef. 874280304Sjkim */ 875276864Sjkim#ifndef OPENSSL_NO_SSL2 876280304Sjkim if (ssl2) 877280304Sjkim meth = SSLv2_method(); 878280304Sjkim else 879276864Sjkim#endif 880276864Sjkim#ifndef OPENSSL_NO_SSL3 881280304Sjkim if (ssl3) 882280304Sjkim meth = SSLv3_method(); 883280304Sjkim else 884276864Sjkim#endif 885276864Sjkim#ifndef OPENSSL_NO_TLS1 886280304Sjkim if (tls1) 887280304Sjkim meth = TLSv1_method(); 888280304Sjkim else 88955714Skris#endif 890280304Sjkim meth = SSLv23_method(); 89155714Skris 892280304Sjkim c_ctx = SSL_CTX_new(meth); 893280304Sjkim s_ctx = SSL_CTX_new(meth); 894280304Sjkim if ((c_ctx == NULL) || (s_ctx == NULL)) { 895280304Sjkim ERR_print_errors(bio_err); 896280304Sjkim goto end; 897280304Sjkim } 89855714Skris 899280304Sjkim if (cipher != NULL) { 900280304Sjkim SSL_CTX_set_cipher_list(c_ctx, cipher); 901280304Sjkim SSL_CTX_set_cipher_list(s_ctx, cipher); 902280304Sjkim } 903109998Smarkm#ifndef OPENSSL_NO_DH 904280304Sjkim if (!no_dhe) { 905280304Sjkim if (dhe1024dsa) { 906280304Sjkim /* 907280304Sjkim * use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks 908280304Sjkim */ 909280304Sjkim SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); 910280304Sjkim dh = get_dh1024dsa(); 911284285Sjkim } else if (dhe512) 912284285Sjkim dh = get_dh512(); 913284285Sjkim else 914280304Sjkim dh = get_dh1024(); 915280304Sjkim SSL_CTX_set_tmp_dh(s_ctx, dh); 916280304Sjkim DH_free(dh); 917280304Sjkim } 91859191Skris#else 919280304Sjkim (void)no_dhe; 92055714Skris#endif 92155714Skris 922160814Ssimon#ifndef OPENSSL_NO_ECDH 923280304Sjkim if (!no_ecdhe) { 924280304Sjkim int nid; 925160814Ssimon 926280304Sjkim if (named_curve != NULL) { 927280304Sjkim nid = OBJ_sn2nid(named_curve); 928280304Sjkim if (nid == 0) { 929280304Sjkim BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); 930280304Sjkim goto end; 931280304Sjkim } 932280304Sjkim } else 933280304Sjkim# ifdef OPENSSL_NO_EC2M 934280304Sjkim nid = NID_X9_62_prime256v1; 935280304Sjkim# else 936280304Sjkim nid = NID_sect163r2; 937280304Sjkim# endif 938160814Ssimon 939280304Sjkim ecdh = EC_KEY_new_by_curve_name(nid); 940280304Sjkim if (ecdh == NULL) { 941280304Sjkim BIO_printf(bio_err, "unable to create curve\n"); 942280304Sjkim goto end; 943280304Sjkim } 944160814Ssimon 945280304Sjkim SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); 946280304Sjkim SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); 947280304Sjkim EC_KEY_free(ecdh); 948280304Sjkim } 949160814Ssimon#else 950280304Sjkim (void)no_ecdhe; 951160814Ssimon#endif 952160814Ssimon 953109998Smarkm#ifndef OPENSSL_NO_RSA 954280304Sjkim SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb); 95555714Skris#endif 95655714Skris 957238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 958280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb); 959280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb); 960280304Sjkim /* or &co2 or NULL */ 961280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); 962280304Sjkim /* or &so2 or NULL */ 963280304Sjkim SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); 964238405Sjkim#endif 965238405Sjkim 966280304Sjkim if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, SSL_FILETYPE_PEM)) { 967280304Sjkim ERR_print_errors(bio_err); 968280304Sjkim } else if (!SSL_CTX_use_PrivateKey_file(s_ctx, 969280304Sjkim (server_key ? server_key : 970280304Sjkim server_cert), 971280304Sjkim SSL_FILETYPE_PEM)) { 972280304Sjkim ERR_print_errors(bio_err); 973280304Sjkim goto end; 974280304Sjkim } 97555714Skris 976280304Sjkim if (client_auth) { 977280304Sjkim SSL_CTX_use_certificate_file(c_ctx, client_cert, SSL_FILETYPE_PEM); 978280304Sjkim SSL_CTX_use_PrivateKey_file(c_ctx, 979280304Sjkim (client_key ? client_key : client_cert), 980280304Sjkim SSL_FILETYPE_PEM); 981280304Sjkim } 98255714Skris 983280304Sjkim if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || 984280304Sjkim (!SSL_CTX_set_default_verify_paths(s_ctx)) || 985280304Sjkim (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || 986280304Sjkim (!SSL_CTX_set_default_verify_paths(c_ctx))) { 987280304Sjkim /* fprintf(stderr,"SSL_load_verify_locations\n"); */ 988280304Sjkim ERR_print_errors(bio_err); 989280304Sjkim /* goto end; */ 990280304Sjkim } 99155714Skris 992280304Sjkim if (client_auth) { 993280304Sjkim BIO_printf(bio_err, "client authentication\n"); 994280304Sjkim SSL_CTX_set_verify(s_ctx, 995280304Sjkim SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 996280304Sjkim verify_callback); 997280304Sjkim SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, 998280304Sjkim &app_verify_arg); 999280304Sjkim } 1000280304Sjkim if (server_auth) { 1001280304Sjkim BIO_printf(bio_err, "server authentication\n"); 1002280304Sjkim SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); 1003280304Sjkim SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, 1004280304Sjkim &app_verify_arg); 1005280304Sjkim } 100655714Skris 1007280304Sjkim { 1008280304Sjkim int session_id_context = 0; 1009280304Sjkim SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, 1010280304Sjkim sizeof session_id_context); 1011280304Sjkim } 1012280304Sjkim 1013280304Sjkim /* Use PSK only if PSK key is given */ 1014280304Sjkim if (psk_key != NULL) { 1015280304Sjkim /* 1016280304Sjkim * no_psk is used to avoid putting psk command to openssl tool 1017280304Sjkim */ 1018280304Sjkim if (no_psk) { 1019280304Sjkim /* 1020280304Sjkim * if PSK is not compiled in and psk key is given, do nothing and 1021280304Sjkim * exit successfully 1022280304Sjkim */ 1023280304Sjkim ret = 0; 1024280304Sjkim goto end; 1025280304Sjkim } 1026238405Sjkim#ifndef OPENSSL_NO_PSK 1027280304Sjkim SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback); 1028280304Sjkim SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback); 1029280304Sjkim if (debug) 1030280304Sjkim BIO_printf(bio_err, "setting PSK identity hint to s_ctx\n"); 1031280304Sjkim if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint")) { 1032280304Sjkim BIO_printf(bio_err, "error setting PSK identity hint to s_ctx\n"); 1033280304Sjkim ERR_print_errors(bio_err); 1034280304Sjkim goto end; 1035280304Sjkim } 1036238405Sjkim#endif 1037280304Sjkim } 1038238405Sjkim#ifndef OPENSSL_NO_SRP 1039280304Sjkim if (srp_client_arg.srplogin) { 1040280304Sjkim if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin)) { 1041280304Sjkim BIO_printf(bio_err, "Unable to set SRP username\n"); 1042280304Sjkim goto end; 1043280304Sjkim } 1044280304Sjkim SSL_CTX_set_srp_cb_arg(c_ctx, &srp_client_arg); 1045280304Sjkim SSL_CTX_set_srp_client_pwd_callback(c_ctx, 1046280304Sjkim ssl_give_srp_client_pwd_cb); 1047280304Sjkim /* 1048280304Sjkim * SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength); 1049280304Sjkim */ 1050280304Sjkim } 1051238405Sjkim 1052280304Sjkim if (srp_server_arg.expected_user != NULL) { 1053280304Sjkim SSL_CTX_set_verify(s_ctx, SSL_VERIFY_NONE, verify_callback); 1054280304Sjkim SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); 1055280304Sjkim SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); 1056280304Sjkim } 1057238405Sjkim#endif 1058238405Sjkim 1059280304Sjkim c_ssl = SSL_new(c_ctx); 1060280304Sjkim s_ssl = SSL_new(s_ctx); 106155714Skris 1062109998Smarkm#ifndef OPENSSL_NO_KRB5 1063280304Sjkim if (c_ssl && c_ssl->kssl_ctx) { 1064280304Sjkim char localhost[MAXHOSTNAMELEN + 2]; 1065109998Smarkm 1066280304Sjkim if (gethostname(localhost, sizeof localhost - 1) == 0) { 1067280304Sjkim localhost[sizeof localhost - 1] = '\0'; 1068280304Sjkim if (strlen(localhost) == sizeof localhost - 1) { 1069280304Sjkim BIO_printf(bio_err, "localhost name too long\n"); 1070280304Sjkim goto end; 1071280304Sjkim } 1072280304Sjkim kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost); 1073280304Sjkim } 1074280304Sjkim } 1075280304Sjkim#endif /* OPENSSL_NO_KRB5 */ 1076109998Smarkm 1077280304Sjkim for (i = 0; i < number; i++) { 1078280304Sjkim if (!reuse) 1079280304Sjkim SSL_set_session(c_ssl, NULL); 1080280304Sjkim if (bio_pair) 1081280304Sjkim ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time); 1082280304Sjkim else 1083280304Sjkim ret = doit(s_ssl, c_ssl, bytes); 1084280304Sjkim } 108555714Skris 1086280304Sjkim if (!verbose) { 1087280304Sjkim print_details(c_ssl, ""); 1088280304Sjkim } 1089280304Sjkim if ((number > 1) || (bytes > 1L)) 1090280304Sjkim BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", number, 1091280304Sjkim bytes); 1092280304Sjkim if (print_time) { 109359191Skris#ifdef CLOCKS_PER_SEC 1094280304Sjkim /* 1095280304Sjkim * "To determine the time in seconds, the value returned by the clock 1096280304Sjkim * function should be divided by the value of the macro 1097280304Sjkim * CLOCKS_PER_SEC." -- ISO/IEC 9899 1098280304Sjkim */ 1099280304Sjkim BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n" 1100280304Sjkim "Approximate total client time: %6.2f s\n", 1101280304Sjkim (double)s_time / CLOCKS_PER_SEC, 1102280304Sjkim (double)c_time / CLOCKS_PER_SEC); 110359191Skris#else 1104280304Sjkim /* 1105280304Sjkim * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on 1106280304Sjkim * NeXTstep/OpenStep 1107280304Sjkim */ 1108280304Sjkim BIO_printf(bio_stdout, 1109280304Sjkim "Approximate total server time: %6.2f units\n" 1110280304Sjkim "Approximate total client time: %6.2f units\n", 1111280304Sjkim (double)s_time, (double)c_time); 111259191Skris#endif 1113280304Sjkim } 111455714Skris 1115280304Sjkim SSL_free(s_ssl); 1116280304Sjkim SSL_free(c_ssl); 111755714Skris 1118280304Sjkim end: 1119280304Sjkim if (s_ctx != NULL) 1120280304Sjkim SSL_CTX_free(s_ctx); 1121280304Sjkim if (c_ctx != NULL) 1122280304Sjkim SSL_CTX_free(c_ctx); 112355714Skris 1124280304Sjkim if (bio_stdout != NULL) 1125280304Sjkim BIO_free(bio_stdout); 112655714Skris 1127109998Smarkm#ifndef OPENSSL_NO_RSA 1128280304Sjkim free_tmp_rsa(); 112968651Skris#endif 1130111147Snectar#ifndef OPENSSL_NO_ENGINE 1131280304Sjkim ENGINE_cleanup(); 1132111147Snectar#endif 1133280304Sjkim CRYPTO_cleanup_all_ex_data(); 1134280304Sjkim ERR_free_strings(); 1135280304Sjkim ERR_remove_thread_state(NULL); 1136280304Sjkim EVP_cleanup(); 1137280304Sjkim CRYPTO_mem_leaks(bio_err); 1138280304Sjkim if (bio_err != NULL) 1139280304Sjkim BIO_free(bio_err); 1140280304Sjkim EXIT(ret); 1141280304Sjkim return ret; 1142280304Sjkim} 114355714Skris 114459191Skrisint doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, 1145280304Sjkim clock_t *s_time, clock_t *c_time) 1146280304Sjkim{ 1147280304Sjkim long cw_num = count, cr_num = count, sw_num = count, sr_num = count; 1148280304Sjkim BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; 1149280304Sjkim BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL; 1150280304Sjkim int ret = 1; 115155714Skris 1152280304Sjkim size_t bufsiz = 256; /* small buffer for testing */ 115355714Skris 1154280304Sjkim if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz)) 1155280304Sjkim goto err; 1156280304Sjkim if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz)) 1157280304Sjkim goto err; 115855714Skris 1159280304Sjkim s_ssl_bio = BIO_new(BIO_f_ssl()); 1160280304Sjkim if (!s_ssl_bio) 1161280304Sjkim goto err; 116255714Skris 1163280304Sjkim c_ssl_bio = BIO_new(BIO_f_ssl()); 1164280304Sjkim if (!c_ssl_bio) 1165280304Sjkim goto err; 116655714Skris 1167280304Sjkim SSL_set_connect_state(c_ssl); 1168280304Sjkim SSL_set_bio(c_ssl, client, client); 1169280304Sjkim (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE); 117055714Skris 1171280304Sjkim SSL_set_accept_state(s_ssl); 1172280304Sjkim SSL_set_bio(s_ssl, server, server); 1173280304Sjkim (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE); 117455714Skris 1175280304Sjkim do { 1176280304Sjkim /*- 1177280304Sjkim * c_ssl_bio: SSL filter BIO 1178280304Sjkim * 1179280304Sjkim * client: pseudo-I/O for SSL library 1180280304Sjkim * 1181280304Sjkim * client_io: client's SSL communication; usually to be 1182280304Sjkim * relayed over some I/O facility, but in this 1183280304Sjkim * test program, we're the server, too: 1184280304Sjkim * 1185280304Sjkim * server_io: server's SSL communication 1186280304Sjkim * 1187280304Sjkim * server: pseudo-I/O for SSL library 1188280304Sjkim * 1189280304Sjkim * s_ssl_bio: SSL filter BIO 1190280304Sjkim * 1191280304Sjkim * The client and the server each employ a "BIO pair": 1192280304Sjkim * client + client_io, server + server_io. 1193280304Sjkim * BIO pairs are symmetric. A BIO pair behaves similar 1194280304Sjkim * to a non-blocking socketpair (but both endpoints must 1195280304Sjkim * be handled by the same thread). 1196280304Sjkim * [Here we could connect client and server to the ends 1197280304Sjkim * of a single BIO pair, but then this code would be less 1198280304Sjkim * suitable as an example for BIO pairs in general.] 1199280304Sjkim * 1200280304Sjkim * Useful functions for querying the state of BIO pair endpoints: 1201280304Sjkim * 1202280304Sjkim * BIO_ctrl_pending(bio) number of bytes we can read now 1203280304Sjkim * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil 1204280304Sjkim * other side's read attempt 1205280304Sjkim * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now 1206280304Sjkim * 1207280304Sjkim * ..._read_request is never more than ..._write_guarantee; 1208280304Sjkim * it depends on the application which one you should use. 1209280304Sjkim */ 121055714Skris 1211280304Sjkim /* 1212280304Sjkim * We have non-blocking behaviour throughout this test program, but 1213280304Sjkim * can be sure that there is *some* progress in each iteration; so we 1214280304Sjkim * don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE -- 1215280304Sjkim * we just try everything in each iteration 1216280304Sjkim */ 1217109998Smarkm 1218280304Sjkim { 1219280304Sjkim /* CLIENT */ 122055714Skris 1221280304Sjkim MS_STATIC char cbuf[1024 * 8]; 1222280304Sjkim int i, r; 1223280304Sjkim clock_t c_clock = clock(); 122455714Skris 1225280304Sjkim memset(cbuf, 0, sizeof(cbuf)); 122655714Skris 1227280304Sjkim if (debug) 1228280304Sjkim if (SSL_in_init(c_ssl)) 1229280304Sjkim printf("client waiting in SSL_connect - %s\n", 1230280304Sjkim SSL_state_string_long(c_ssl)); 123159191Skris 1232280304Sjkim if (cw_num > 0) { 1233280304Sjkim /* Write to server. */ 123455714Skris 1235280304Sjkim if (cw_num > (long)sizeof cbuf) 1236280304Sjkim i = sizeof cbuf; 1237280304Sjkim else 1238280304Sjkim i = (int)cw_num; 1239280304Sjkim r = BIO_write(c_ssl_bio, cbuf, i); 1240280304Sjkim if (r < 0) { 1241280304Sjkim if (!BIO_should_retry(c_ssl_bio)) { 1242280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1243280304Sjkim goto err; 1244280304Sjkim } 1245280304Sjkim /* 1246280304Sjkim * BIO_should_retry(...) can just be ignored here. The 1247280304Sjkim * library expects us to call BIO_write with the same 1248280304Sjkim * arguments again, and that's what we will do in the 1249280304Sjkim * next iteration. 1250280304Sjkim */ 1251280304Sjkim } else if (r == 0) { 1252280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1253280304Sjkim goto err; 1254280304Sjkim } else { 1255280304Sjkim if (debug) 1256280304Sjkim printf("client wrote %d\n", r); 1257280304Sjkim cw_num -= r; 1258280304Sjkim } 1259280304Sjkim } 126055714Skris 1261280304Sjkim if (cr_num > 0) { 1262280304Sjkim /* Read from server. */ 1263109998Smarkm 1264280304Sjkim r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf)); 1265280304Sjkim if (r < 0) { 1266280304Sjkim if (!BIO_should_retry(c_ssl_bio)) { 1267280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1268280304Sjkim goto err; 1269280304Sjkim } 1270280304Sjkim /* 1271280304Sjkim * Again, "BIO_should_retry" can be ignored. 1272280304Sjkim */ 1273280304Sjkim } else if (r == 0) { 1274280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1275280304Sjkim goto err; 1276280304Sjkim } else { 1277280304Sjkim if (debug) 1278280304Sjkim printf("client read %d\n", r); 1279280304Sjkim cr_num -= r; 1280280304Sjkim } 1281280304Sjkim } 128255714Skris 1283280304Sjkim /* 1284280304Sjkim * c_time and s_time increments will typically be very small 1285280304Sjkim * (depending on machine speed and clock tick intervals), but 1286280304Sjkim * sampling over a large number of connections should result in 1287280304Sjkim * fairly accurate figures. We cannot guarantee a lot, however 1288280304Sjkim * -- if each connection lasts for exactly one clock tick, it 1289280304Sjkim * will be counted only for the client or only for the server or 1290280304Sjkim * even not at all. 1291280304Sjkim */ 1292280304Sjkim *c_time += (clock() - c_clock); 1293280304Sjkim } 129455714Skris 1295280304Sjkim { 1296280304Sjkim /* SERVER */ 129755714Skris 1298280304Sjkim MS_STATIC char sbuf[1024 * 8]; 1299280304Sjkim int i, r; 1300280304Sjkim clock_t s_clock = clock(); 130159191Skris 1302280304Sjkim memset(sbuf, 0, sizeof(sbuf)); 130355714Skris 1304280304Sjkim if (debug) 1305280304Sjkim if (SSL_in_init(s_ssl)) 1306280304Sjkim printf("server waiting in SSL_accept - %s\n", 1307280304Sjkim SSL_state_string_long(s_ssl)); 130855714Skris 1309280304Sjkim if (sw_num > 0) { 1310280304Sjkim /* Write to client. */ 131159191Skris 1312280304Sjkim if (sw_num > (long)sizeof sbuf) 1313280304Sjkim i = sizeof sbuf; 1314280304Sjkim else 1315280304Sjkim i = (int)sw_num; 1316280304Sjkim r = BIO_write(s_ssl_bio, sbuf, i); 1317280304Sjkim if (r < 0) { 1318280304Sjkim if (!BIO_should_retry(s_ssl_bio)) { 1319280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1320280304Sjkim goto err; 1321280304Sjkim } 1322280304Sjkim /* Ignore "BIO_should_retry". */ 1323280304Sjkim } else if (r == 0) { 1324280304Sjkim fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 1325280304Sjkim goto err; 1326280304Sjkim } else { 1327280304Sjkim if (debug) 1328280304Sjkim printf("server wrote %d\n", r); 1329280304Sjkim sw_num -= r; 1330280304Sjkim } 1331280304Sjkim } 133259191Skris 1333280304Sjkim if (sr_num > 0) { 1334280304Sjkim /* Read from client. */ 133555714Skris 1336280304Sjkim r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf)); 1337280304Sjkim if (r < 0) { 1338280304Sjkim if (!BIO_should_retry(s_ssl_bio)) { 1339280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1340280304Sjkim goto err; 1341280304Sjkim } 1342280304Sjkim /* blah, blah */ 1343280304Sjkim } else if (r == 0) { 1344280304Sjkim fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 1345280304Sjkim goto err; 1346280304Sjkim } else { 1347280304Sjkim if (debug) 1348280304Sjkim printf("server read %d\n", r); 1349280304Sjkim sr_num -= r; 1350280304Sjkim } 1351280304Sjkim } 135255714Skris 1353280304Sjkim *s_time += (clock() - s_clock); 1354280304Sjkim } 135555714Skris 1356280304Sjkim { 1357280304Sjkim /* "I/O" BETWEEN CLIENT AND SERVER. */ 135859191Skris 1359280304Sjkim size_t r1, r2; 1360280304Sjkim BIO *io1 = server_io, *io2 = client_io; 1361280304Sjkim /* 1362280304Sjkim * we use the non-copying interface for io1 and the standard 1363280304Sjkim * BIO_write/BIO_read interface for io2 1364280304Sjkim */ 136555714Skris 1366280304Sjkim static int prev_progress = 1; 1367280304Sjkim int progress = 0; 136855714Skris 1369280304Sjkim /* io1 to io2 */ 1370280304Sjkim do { 1371280304Sjkim size_t num; 1372280304Sjkim int r; 137355714Skris 1374280304Sjkim r1 = BIO_ctrl_pending(io1); 1375280304Sjkim r2 = BIO_ctrl_get_write_guarantee(io2); 1376280304Sjkim 1377280304Sjkim num = r1; 1378280304Sjkim if (r2 < num) 1379280304Sjkim num = r2; 1380280304Sjkim if (num) { 1381280304Sjkim char *dataptr; 1382280304Sjkim 1383280304Sjkim if (INT_MAX < num) /* yeah, right */ 1384280304Sjkim num = INT_MAX; 1385280304Sjkim 1386280304Sjkim r = BIO_nread(io1, &dataptr, (int)num); 1387280304Sjkim assert(r > 0); 1388280304Sjkim assert(r <= (int)num); 1389280304Sjkim /* 1390280304Sjkim * possibly r < num (non-contiguous data) 1391280304Sjkim */ 1392280304Sjkim num = r; 1393280304Sjkim r = BIO_write(io2, dataptr, (int)num); 1394280304Sjkim if (r != (int)num) { /* can't happen */ 1395280304Sjkim fprintf(stderr, "ERROR: BIO_write could not write " 1396280304Sjkim "BIO_ctrl_get_write_guarantee() bytes"); 1397280304Sjkim goto err; 1398280304Sjkim } 1399280304Sjkim progress = 1; 1400280304Sjkim 1401280304Sjkim if (debug) 1402280304Sjkim printf((io1 == client_io) ? 1403280304Sjkim "C->S relaying: %d bytes\n" : 1404280304Sjkim "S->C relaying: %d bytes\n", (int)num); 1405280304Sjkim } 1406280304Sjkim } 1407280304Sjkim while (r1 && r2); 1408280304Sjkim 1409280304Sjkim /* io2 to io1 */ 1410280304Sjkim { 1411280304Sjkim size_t num; 1412280304Sjkim int r; 1413280304Sjkim 1414280304Sjkim r1 = BIO_ctrl_pending(io2); 1415280304Sjkim r2 = BIO_ctrl_get_read_request(io1); 1416280304Sjkim /* 1417280304Sjkim * here we could use ..._get_write_guarantee instead of 1418280304Sjkim * ..._get_read_request, but by using the latter we test 1419280304Sjkim * restartability of the SSL implementation more thoroughly 1420280304Sjkim */ 1421280304Sjkim num = r1; 1422280304Sjkim if (r2 < num) 1423280304Sjkim num = r2; 1424280304Sjkim if (num) { 1425280304Sjkim char *dataptr; 1426280304Sjkim 1427280304Sjkim if (INT_MAX < num) 1428280304Sjkim num = INT_MAX; 1429280304Sjkim 1430280304Sjkim if (num > 1) 1431280304Sjkim --num; /* test restartability even more thoroughly */ 1432280304Sjkim 1433280304Sjkim r = BIO_nwrite0(io1, &dataptr); 1434280304Sjkim assert(r > 0); 1435280304Sjkim if (r < (int)num) 1436280304Sjkim num = r; 1437280304Sjkim r = BIO_read(io2, dataptr, (int)num); 1438280304Sjkim if (r != (int)num) { /* can't happen */ 1439280304Sjkim fprintf(stderr, "ERROR: BIO_read could not read " 1440280304Sjkim "BIO_ctrl_pending() bytes"); 1441280304Sjkim goto err; 1442280304Sjkim } 1443280304Sjkim progress = 1; 1444280304Sjkim r = BIO_nwrite(io1, &dataptr, (int)num); 1445280304Sjkim if (r != (int)num) { /* can't happen */ 1446280304Sjkim fprintf(stderr, "ERROR: BIO_nwrite() did not accept " 1447280304Sjkim "BIO_nwrite0() bytes"); 1448280304Sjkim goto err; 1449280304Sjkim } 1450280304Sjkim 1451280304Sjkim if (debug) 1452280304Sjkim printf((io2 == client_io) ? 1453280304Sjkim "C->S relaying: %d bytes\n" : 1454280304Sjkim "S->C relaying: %d bytes\n", (int)num); 1455280304Sjkim } 1456280304Sjkim } /* no loop, BIO_ctrl_get_read_request now 1457280304Sjkim * returns 0 anyway */ 1458280304Sjkim 1459280304Sjkim if (!progress && !prev_progress) 1460280304Sjkim if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) { 1461280304Sjkim fprintf(stderr, "ERROR: got stuck\n"); 1462280304Sjkim if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0) { 1463280304Sjkim fprintf(stderr, "This can happen for SSL2 because " 1464280304Sjkim "CLIENT-FINISHED and SERVER-VERIFY are written \n" 1465280304Sjkim "concurrently ..."); 1466280304Sjkim if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0 1467280304Sjkim && strncmp("2SSV", SSL_state_string(s_ssl), 1468280304Sjkim 4) == 0) { 1469280304Sjkim fprintf(stderr, " ok.\n"); 1470280304Sjkim goto end; 1471280304Sjkim } 1472280304Sjkim } 1473280304Sjkim fprintf(stderr, " ERROR.\n"); 1474280304Sjkim goto err; 1475280304Sjkim } 1476280304Sjkim prev_progress = progress; 1477280304Sjkim } 1478280304Sjkim } 1479280304Sjkim while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); 1480280304Sjkim 1481280304Sjkim if (verbose) 1482280304Sjkim print_details(c_ssl, "DONE via BIO pair: "); 1483280304Sjkim end: 1484280304Sjkim ret = 0; 1485280304Sjkim 148655714Skris err: 1487280304Sjkim ERR_print_errors(bio_err); 148855714Skris 1489280304Sjkim if (server) 1490280304Sjkim BIO_free(server); 1491280304Sjkim if (server_io) 1492280304Sjkim BIO_free(server_io); 1493280304Sjkim if (client) 1494280304Sjkim BIO_free(client); 1495280304Sjkim if (client_io) 1496280304Sjkim BIO_free(client_io); 1497280304Sjkim if (s_ssl_bio) 1498280304Sjkim BIO_free(s_ssl_bio); 1499280304Sjkim if (c_ssl_bio) 1500280304Sjkim BIO_free(c_ssl_bio); 150155714Skris 1502280304Sjkim return ret; 1503280304Sjkim} 150455714Skris 1505280304Sjkim#define W_READ 1 1506280304Sjkim#define W_WRITE 2 1507280304Sjkim#define C_DONE 1 1508280304Sjkim#define S_DONE 2 150955714Skris 151055714Skrisint doit(SSL *s_ssl, SSL *c_ssl, long count) 1511280304Sjkim{ 1512280304Sjkim MS_STATIC char cbuf[1024 * 8], sbuf[1024 * 8]; 1513280304Sjkim long cw_num = count, cr_num = count; 1514280304Sjkim long sw_num = count, sr_num = count; 1515280304Sjkim int ret = 1; 1516280304Sjkim BIO *c_to_s = NULL; 1517280304Sjkim BIO *s_to_c = NULL; 1518280304Sjkim BIO *c_bio = NULL; 1519280304Sjkim BIO *s_bio = NULL; 1520280304Sjkim int c_r, c_w, s_r, s_w; 1521280304Sjkim int i, j; 1522280304Sjkim int done = 0; 1523280304Sjkim int c_write, s_write; 1524280304Sjkim int do_server = 0, do_client = 0; 152555714Skris 1526280304Sjkim memset(cbuf, 0, sizeof(cbuf)); 1527280304Sjkim memset(sbuf, 0, sizeof(sbuf)); 1528109998Smarkm 1529280304Sjkim c_to_s = BIO_new(BIO_s_mem()); 1530280304Sjkim s_to_c = BIO_new(BIO_s_mem()); 1531280304Sjkim if ((s_to_c == NULL) || (c_to_s == NULL)) { 1532280304Sjkim ERR_print_errors(bio_err); 1533280304Sjkim goto err; 1534280304Sjkim } 153555714Skris 1536280304Sjkim c_bio = BIO_new(BIO_f_ssl()); 1537280304Sjkim s_bio = BIO_new(BIO_f_ssl()); 1538280304Sjkim if ((c_bio == NULL) || (s_bio == NULL)) { 1539280304Sjkim ERR_print_errors(bio_err); 1540280304Sjkim goto err; 1541280304Sjkim } 154255714Skris 1543280304Sjkim SSL_set_connect_state(c_ssl); 1544280304Sjkim SSL_set_bio(c_ssl, s_to_c, c_to_s); 1545280304Sjkim BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE); 154655714Skris 1547280304Sjkim SSL_set_accept_state(s_ssl); 1548280304Sjkim SSL_set_bio(s_ssl, c_to_s, s_to_c); 1549280304Sjkim BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE); 155055714Skris 1551280304Sjkim c_r = 0; 1552280304Sjkim s_r = 1; 1553280304Sjkim c_w = 1; 1554280304Sjkim s_w = 0; 1555280304Sjkim c_write = 1, s_write = 0; 155655714Skris 1557280304Sjkim /* We can always do writes */ 1558280304Sjkim for (;;) { 1559280304Sjkim do_server = 0; 1560280304Sjkim do_client = 0; 156155714Skris 1562280304Sjkim i = (int)BIO_pending(s_bio); 1563280304Sjkim if ((i && s_r) || s_w) 1564280304Sjkim do_server = 1; 156555714Skris 1566280304Sjkim i = (int)BIO_pending(c_bio); 1567280304Sjkim if ((i && c_r) || c_w) 1568280304Sjkim do_client = 1; 156955714Skris 1570280304Sjkim if (do_server && debug) { 1571280304Sjkim if (SSL_in_init(s_ssl)) 1572280304Sjkim printf("server waiting in SSL_accept - %s\n", 1573280304Sjkim SSL_state_string_long(s_ssl)); 1574280304Sjkim/*- 1575280304Sjkim else if (s_write) 1576280304Sjkim printf("server:SSL_write()\n"); 1577280304Sjkim else 1578280304Sjkim printf("server:SSL_read()\n"); */ 1579280304Sjkim } 158055714Skris 1581280304Sjkim if (do_client && debug) { 1582280304Sjkim if (SSL_in_init(c_ssl)) 1583280304Sjkim printf("client waiting in SSL_connect - %s\n", 1584280304Sjkim SSL_state_string_long(c_ssl)); 1585280304Sjkim/*- 1586280304Sjkim else if (c_write) 1587280304Sjkim printf("client:SSL_write()\n"); 1588280304Sjkim else 1589280304Sjkim printf("client:SSL_read()\n"); */ 1590280304Sjkim } 159155714Skris 1592280304Sjkim if (!do_client && !do_server) { 1593280304Sjkim fprintf(stdout, "ERROR IN STARTUP\n"); 1594280304Sjkim ERR_print_errors(bio_err); 1595280304Sjkim goto err; 1596280304Sjkim } 1597280304Sjkim if (do_client && !(done & C_DONE)) { 1598280304Sjkim if (c_write) { 1599280304Sjkim j = (cw_num > (long)sizeof(cbuf)) ? 1600280304Sjkim (int)sizeof(cbuf) : (int)cw_num; 1601280304Sjkim i = BIO_write(c_bio, cbuf, j); 1602280304Sjkim if (i < 0) { 1603280304Sjkim c_r = 0; 1604280304Sjkim c_w = 0; 1605280304Sjkim if (BIO_should_retry(c_bio)) { 1606280304Sjkim if (BIO_should_read(c_bio)) 1607280304Sjkim c_r = 1; 1608280304Sjkim if (BIO_should_write(c_bio)) 1609280304Sjkim c_w = 1; 1610280304Sjkim } else { 1611280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1612280304Sjkim ERR_print_errors(bio_err); 1613280304Sjkim goto err; 1614280304Sjkim } 1615280304Sjkim } else if (i == 0) { 1616280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1617280304Sjkim goto err; 1618280304Sjkim } else { 1619280304Sjkim if (debug) 1620280304Sjkim printf("client wrote %d\n", i); 1621280304Sjkim /* ok */ 1622280304Sjkim s_r = 1; 1623280304Sjkim c_write = 0; 1624280304Sjkim cw_num -= i; 1625280304Sjkim } 1626280304Sjkim } else { 1627280304Sjkim i = BIO_read(c_bio, cbuf, sizeof(cbuf)); 1628280304Sjkim if (i < 0) { 1629280304Sjkim c_r = 0; 1630280304Sjkim c_w = 0; 1631280304Sjkim if (BIO_should_retry(c_bio)) { 1632280304Sjkim if (BIO_should_read(c_bio)) 1633280304Sjkim c_r = 1; 1634280304Sjkim if (BIO_should_write(c_bio)) 1635280304Sjkim c_w = 1; 1636280304Sjkim } else { 1637280304Sjkim fprintf(stderr, "ERROR in CLIENT\n"); 1638280304Sjkim ERR_print_errors(bio_err); 1639280304Sjkim goto err; 1640280304Sjkim } 1641280304Sjkim } else if (i == 0) { 1642280304Sjkim fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1643280304Sjkim goto err; 1644280304Sjkim } else { 1645280304Sjkim if (debug) 1646280304Sjkim printf("client read %d\n", i); 1647280304Sjkim cr_num -= i; 1648280304Sjkim if (sw_num > 0) { 1649280304Sjkim s_write = 1; 1650280304Sjkim s_w = 1; 1651280304Sjkim } 1652280304Sjkim if (cr_num <= 0) { 1653280304Sjkim s_write = 1; 1654280304Sjkim s_w = 1; 1655280304Sjkim done = S_DONE | C_DONE; 1656280304Sjkim } 1657280304Sjkim } 1658280304Sjkim } 1659280304Sjkim } 166055714Skris 1661280304Sjkim if (do_server && !(done & S_DONE)) { 1662280304Sjkim if (!s_write) { 1663280304Sjkim i = BIO_read(s_bio, sbuf, sizeof(cbuf)); 1664280304Sjkim if (i < 0) { 1665280304Sjkim s_r = 0; 1666280304Sjkim s_w = 0; 1667280304Sjkim if (BIO_should_retry(s_bio)) { 1668280304Sjkim if (BIO_should_read(s_bio)) 1669280304Sjkim s_r = 1; 1670280304Sjkim if (BIO_should_write(s_bio)) 1671280304Sjkim s_w = 1; 1672280304Sjkim } else { 1673280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1674280304Sjkim ERR_print_errors(bio_err); 1675280304Sjkim goto err; 1676280304Sjkim } 1677280304Sjkim } else if (i == 0) { 1678280304Sjkim ERR_print_errors(bio_err); 1679280304Sjkim fprintf(stderr, 1680280304Sjkim "SSL SERVER STARTUP FAILED in SSL_read\n"); 1681280304Sjkim goto err; 1682280304Sjkim } else { 1683280304Sjkim if (debug) 1684280304Sjkim printf("server read %d\n", i); 1685280304Sjkim sr_num -= i; 1686280304Sjkim if (cw_num > 0) { 1687280304Sjkim c_write = 1; 1688280304Sjkim c_w = 1; 1689280304Sjkim } 1690280304Sjkim if (sr_num <= 0) { 1691280304Sjkim s_write = 1; 1692280304Sjkim s_w = 1; 1693280304Sjkim c_write = 0; 1694280304Sjkim } 1695280304Sjkim } 1696280304Sjkim } else { 1697280304Sjkim j = (sw_num > (long)sizeof(sbuf)) ? 1698280304Sjkim (int)sizeof(sbuf) : (int)sw_num; 1699280304Sjkim i = BIO_write(s_bio, sbuf, j); 1700280304Sjkim if (i < 0) { 1701280304Sjkim s_r = 0; 1702280304Sjkim s_w = 0; 1703280304Sjkim if (BIO_should_retry(s_bio)) { 1704280304Sjkim if (BIO_should_read(s_bio)) 1705280304Sjkim s_r = 1; 1706280304Sjkim if (BIO_should_write(s_bio)) 1707280304Sjkim s_w = 1; 1708280304Sjkim } else { 1709280304Sjkim fprintf(stderr, "ERROR in SERVER\n"); 1710280304Sjkim ERR_print_errors(bio_err); 1711280304Sjkim goto err; 1712280304Sjkim } 1713280304Sjkim } else if (i == 0) { 1714280304Sjkim ERR_print_errors(bio_err); 1715280304Sjkim fprintf(stderr, 1716280304Sjkim "SSL SERVER STARTUP FAILED in SSL_write\n"); 1717280304Sjkim goto err; 1718280304Sjkim } else { 1719280304Sjkim if (debug) 1720280304Sjkim printf("server wrote %d\n", i); 1721280304Sjkim sw_num -= i; 1722280304Sjkim s_write = 0; 1723280304Sjkim c_r = 1; 1724280304Sjkim if (sw_num <= 0) 1725280304Sjkim done |= S_DONE; 1726280304Sjkim } 1727280304Sjkim } 1728280304Sjkim } 172955714Skris 1730280304Sjkim if ((done & S_DONE) && (done & C_DONE)) 1731280304Sjkim break; 1732280304Sjkim } 173355714Skris 1734280304Sjkim if (verbose) 1735280304Sjkim print_details(c_ssl, "DONE: "); 1736280304Sjkim ret = 0; 1737280304Sjkim err: 1738280304Sjkim /* 1739280304Sjkim * We have to set the BIO's to NULL otherwise they will be 1740280304Sjkim * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and again 1741280304Sjkim * when c_ssl is SSL_free()ed. This is a hack required because s_ssl and 1742280304Sjkim * c_ssl are sharing the same BIO structure and SSL_set_bio() and 1743280304Sjkim * SSL_free() automatically BIO_free non NULL entries. You should not 1744280304Sjkim * normally do this or be required to do this 1745280304Sjkim */ 1746280304Sjkim if (s_ssl != NULL) { 1747280304Sjkim s_ssl->rbio = NULL; 1748280304Sjkim s_ssl->wbio = NULL; 1749280304Sjkim } 1750280304Sjkim if (c_ssl != NULL) { 1751280304Sjkim c_ssl->rbio = NULL; 1752280304Sjkim c_ssl->wbio = NULL; 1753280304Sjkim } 175455714Skris 1755280304Sjkim if (c_to_s != NULL) 1756280304Sjkim BIO_free(c_to_s); 1757280304Sjkim if (s_to_c != NULL) 1758280304Sjkim BIO_free(s_to_c); 1759280304Sjkim if (c_bio != NULL) 1760280304Sjkim BIO_free_all(c_bio); 1761280304Sjkim if (s_bio != NULL) 1762280304Sjkim BIO_free_all(s_bio); 1763280304Sjkim return (ret); 1764280304Sjkim} 176555714Skris 1766160814Ssimonstatic int get_proxy_auth_ex_data_idx(void) 1767280304Sjkim{ 1768280304Sjkim static volatile int idx = -1; 1769280304Sjkim if (idx < 0) { 1770280304Sjkim CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 1771280304Sjkim if (idx < 0) { 1772280304Sjkim idx = X509_STORE_CTX_get_ex_new_index(0, 1773280304Sjkim "SSLtest for verify callback", 1774280304Sjkim NULL, NULL, NULL); 1775280304Sjkim } 1776280304Sjkim CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 1777280304Sjkim } 1778280304Sjkim return idx; 1779280304Sjkim} 1780160814Ssimon 178159191Skrisstatic int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 1782280304Sjkim{ 1783280304Sjkim char *s, buf[256]; 178455714Skris 1785280304Sjkim s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, 1786280304Sjkim sizeof buf); 1787280304Sjkim if (s != NULL) { 1788280304Sjkim if (ok) 1789280304Sjkim fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf); 1790280304Sjkim else { 1791280304Sjkim fprintf(stderr, "depth=%d error=%d %s\n", 1792280304Sjkim ctx->error_depth, ctx->error, buf); 1793280304Sjkim } 1794280304Sjkim } 179555714Skris 1796280304Sjkim if (ok == 0) { 1797280304Sjkim fprintf(stderr, "Error string: %s\n", 1798280304Sjkim X509_verify_cert_error_string(ctx->error)); 1799280304Sjkim switch (ctx->error) { 1800280304Sjkim case X509_V_ERR_CERT_NOT_YET_VALID: 1801280304Sjkim case X509_V_ERR_CERT_HAS_EXPIRED: 1802280304Sjkim case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1803280304Sjkim fprintf(stderr, " ... ignored.\n"); 1804280304Sjkim ok = 1; 1805280304Sjkim } 1806280304Sjkim } 180755714Skris 1808280304Sjkim if (ok == 1) { 1809280304Sjkim X509 *xs = ctx->current_cert; 1810160814Ssimon#if 0 1811280304Sjkim X509 *xi = ctx->current_issuer; 1812160814Ssimon#endif 1813160814Ssimon 1814280304Sjkim if (xs->ex_flags & EXFLAG_PROXY) { 1815280304Sjkim unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx, 1816280304Sjkim get_proxy_auth_ex_data_idx 1817280304Sjkim ()); 1818160814Ssimon 1819280304Sjkim if (letters) { 1820280304Sjkim int found_any = 0; 1821280304Sjkim int i; 1822280304Sjkim PROXY_CERT_INFO_EXTENSION *pci = 1823280304Sjkim X509_get_ext_d2i(xs, NID_proxyCertInfo, 1824280304Sjkim NULL, NULL); 1825160814Ssimon 1826280304Sjkim switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { 1827280304Sjkim case NID_Independent: 1828280304Sjkim /* 1829280304Sjkim * Completely meaningless in this program, as there's no 1830280304Sjkim * way to grant explicit rights to a specific PrC. 1831280304Sjkim * Basically, using id-ppl-Independent is the perfect way 1832280304Sjkim * to grant no rights at all. 1833280304Sjkim */ 1834280304Sjkim fprintf(stderr, " Independent proxy certificate"); 1835280304Sjkim for (i = 0; i < 26; i++) 1836280304Sjkim letters[i] = 0; 1837280304Sjkim break; 1838280304Sjkim case NID_id_ppl_inheritAll: 1839280304Sjkim /* 1840280304Sjkim * This is basically a NOP, we simply let the current 1841280304Sjkim * rights stand as they are. 1842280304Sjkim */ 1843280304Sjkim fprintf(stderr, " Proxy certificate inherits all"); 1844280304Sjkim break; 1845280304Sjkim default: 1846280304Sjkim s = (char *) 1847280304Sjkim pci->proxyPolicy->policy->data; 1848280304Sjkim i = pci->proxyPolicy->policy->length; 1849160814Ssimon 1850280304Sjkim /* 1851280304Sjkim * The algorithm works as follows: it is assumed that 1852280304Sjkim * previous iterations or the initial granted rights has 1853280304Sjkim * already set some elements of `letters'. What we need 1854280304Sjkim * to do is to clear those that weren't granted by the 1855280304Sjkim * current PrC as well. The easiest way to do this is to 1856280304Sjkim * add 1 to all the elements whose letters are given with 1857280304Sjkim * the current policy. That way, all elements that are 1858280304Sjkim * set by the current policy and were already set by 1859280304Sjkim * earlier policies and through the original grant of 1860280304Sjkim * rights will get the value 2 or higher. The last thing 1861280304Sjkim * to do is to sweep through `letters' and keep the 1862280304Sjkim * elements having the value 2 as set, and clear all the 1863280304Sjkim * others. 1864280304Sjkim */ 1865160814Ssimon 1866280304Sjkim fprintf(stderr, " Certificate proxy rights = %*.*s", i, 1867280304Sjkim i, s); 1868280304Sjkim while (i-- > 0) { 1869280304Sjkim int c = *s++; 1870280304Sjkim if (isascii(c) && isalpha(c)) { 1871280304Sjkim if (islower(c)) 1872280304Sjkim c = toupper(c); 1873280304Sjkim letters[c - 'A']++; 1874280304Sjkim } 1875280304Sjkim } 1876280304Sjkim for (i = 0; i < 26; i++) 1877280304Sjkim if (letters[i] < 2) 1878280304Sjkim letters[i] = 0; 1879280304Sjkim else 1880280304Sjkim letters[i] = 1; 1881280304Sjkim } 1882160814Ssimon 1883280304Sjkim found_any = 0; 1884280304Sjkim fprintf(stderr, ", resulting proxy rights = "); 1885280304Sjkim for (i = 0; i < 26; i++) 1886280304Sjkim if (letters[i]) { 1887280304Sjkim fprintf(stderr, "%c", i + 'A'); 1888280304Sjkim found_any = 1; 1889280304Sjkim } 1890280304Sjkim if (!found_any) 1891280304Sjkim fprintf(stderr, "none"); 1892280304Sjkim fprintf(stderr, "\n"); 1893160814Ssimon 1894280304Sjkim PROXY_CERT_INFO_EXTENSION_free(pci); 1895280304Sjkim } 1896280304Sjkim } 1897280304Sjkim } 1898160814Ssimon 1899280304Sjkim return (ok); 1900280304Sjkim} 190155714Skris 1902160814Ssimonstatic void process_proxy_debug(int indent, const char *format, ...) 1903280304Sjkim{ 1904280304Sjkim /* That's 80 > */ 1905280304Sjkim static const char indentation[] = 1906280304Sjkim ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 1907280304Sjkim ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; 1908280304Sjkim char my_format[256]; 1909280304Sjkim va_list args; 1910160814Ssimon 1911280304Sjkim BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s", 1912280304Sjkim indent, indent, indentation, format); 1913160814Ssimon 1914280304Sjkim va_start(args, format); 1915280304Sjkim vfprintf(stderr, my_format, args); 1916280304Sjkim va_end(args); 1917280304Sjkim} 1918280304Sjkim 1919280304Sjkim/*- 1920280304Sjkim * Priority levels: 1921280304Sjkim * 0 [!]var, () 1922280304Sjkim * 1 & ^ 1923280304Sjkim * 2 | 1924280304Sjkim */ 1925160814Ssimonstatic int process_proxy_cond_adders(unsigned int letters[26], 1926280304Sjkim const char *cond, const char **cond_end, 1927280304Sjkim int *pos, int indent); 1928280304Sjkimstatic int process_proxy_cond_val(unsigned int letters[26], const char *cond, 1929280304Sjkim const char **cond_end, int *pos, int indent) 1930280304Sjkim{ 1931280304Sjkim int c; 1932280304Sjkim int ok = 1; 1933280304Sjkim int negate = 0; 1934160814Ssimon 1935280304Sjkim while (isspace((int)*cond)) { 1936280304Sjkim cond++; 1937280304Sjkim (*pos)++; 1938280304Sjkim } 1939280304Sjkim c = *cond; 1940160814Ssimon 1941280304Sjkim if (debug) 1942280304Sjkim process_proxy_debug(indent, 1943280304Sjkim "Start process_proxy_cond_val at position %d: %s\n", 1944280304Sjkim *pos, cond); 1945160814Ssimon 1946280304Sjkim while (c == '!') { 1947280304Sjkim negate = !negate; 1948280304Sjkim cond++; 1949280304Sjkim (*pos)++; 1950280304Sjkim while (isspace((int)*cond)) { 1951280304Sjkim cond++; 1952280304Sjkim (*pos)++; 1953280304Sjkim } 1954280304Sjkim c = *cond; 1955280304Sjkim } 1956160814Ssimon 1957280304Sjkim if (c == '(') { 1958280304Sjkim cond++; 1959280304Sjkim (*pos)++; 1960280304Sjkim ok = process_proxy_cond_adders(letters, cond, cond_end, pos, 1961280304Sjkim indent + 1); 1962280304Sjkim cond = *cond_end; 1963280304Sjkim if (ok < 0) 1964280304Sjkim goto end; 1965280304Sjkim while (isspace((int)*cond)) { 1966280304Sjkim cond++; 1967280304Sjkim (*pos)++; 1968280304Sjkim } 1969280304Sjkim c = *cond; 1970280304Sjkim if (c != ')') { 1971280304Sjkim fprintf(stderr, 1972280304Sjkim "Weird condition character in position %d: " 1973280304Sjkim "%c\n", *pos, c); 1974280304Sjkim ok = -1; 1975280304Sjkim goto end; 1976280304Sjkim } 1977280304Sjkim cond++; 1978280304Sjkim (*pos)++; 1979280304Sjkim } else if (isascii(c) && isalpha(c)) { 1980280304Sjkim if (islower(c)) 1981280304Sjkim c = toupper(c); 1982280304Sjkim ok = letters[c - 'A']; 1983280304Sjkim cond++; 1984280304Sjkim (*pos)++; 1985280304Sjkim } else { 1986280304Sjkim fprintf(stderr, 1987280304Sjkim "Weird condition character in position %d: " "%c\n", *pos, c); 1988280304Sjkim ok = -1; 1989280304Sjkim goto end; 1990280304Sjkim } 1991160814Ssimon end: 1992280304Sjkim *cond_end = cond; 1993280304Sjkim if (ok >= 0 && negate) 1994280304Sjkim ok = !ok; 1995160814Ssimon 1996280304Sjkim if (debug) 1997280304Sjkim process_proxy_debug(indent, 1998280304Sjkim "End process_proxy_cond_val at position %d: %s, returning %d\n", 1999280304Sjkim *pos, cond, ok); 2000160814Ssimon 2001280304Sjkim return ok; 2002280304Sjkim} 2003280304Sjkim 2004160814Ssimonstatic int process_proxy_cond_multipliers(unsigned int letters[26], 2005280304Sjkim const char *cond, 2006280304Sjkim const char **cond_end, int *pos, 2007280304Sjkim int indent) 2008280304Sjkim{ 2009280304Sjkim int ok; 2010280304Sjkim char c; 2011160814Ssimon 2012280304Sjkim if (debug) 2013280304Sjkim process_proxy_debug(indent, 2014280304Sjkim "Start process_proxy_cond_multipliers at position %d: %s\n", 2015280304Sjkim *pos, cond); 2016160814Ssimon 2017280304Sjkim ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1); 2018280304Sjkim cond = *cond_end; 2019280304Sjkim if (ok < 0) 2020280304Sjkim goto end; 2021160814Ssimon 2022280304Sjkim while (ok >= 0) { 2023280304Sjkim while (isspace((int)*cond)) { 2024280304Sjkim cond++; 2025280304Sjkim (*pos)++; 2026280304Sjkim } 2027280304Sjkim c = *cond; 2028160814Ssimon 2029280304Sjkim switch (c) { 2030280304Sjkim case '&': 2031280304Sjkim case '^': 2032280304Sjkim { 2033280304Sjkim int save_ok = ok; 2034160814Ssimon 2035280304Sjkim cond++; 2036280304Sjkim (*pos)++; 2037280304Sjkim ok = process_proxy_cond_val(letters, 2038280304Sjkim cond, cond_end, pos, indent + 1); 2039280304Sjkim cond = *cond_end; 2040280304Sjkim if (ok < 0) 2041280304Sjkim break; 2042160814Ssimon 2043280304Sjkim switch (c) { 2044280304Sjkim case '&': 2045280304Sjkim ok &= save_ok; 2046280304Sjkim break; 2047280304Sjkim case '^': 2048280304Sjkim ok ^= save_ok; 2049280304Sjkim break; 2050280304Sjkim default: 2051280304Sjkim fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 2052280304Sjkim " STOPPING\n"); 2053280304Sjkim EXIT(1); 2054280304Sjkim } 2055280304Sjkim } 2056280304Sjkim break; 2057280304Sjkim default: 2058280304Sjkim goto end; 2059280304Sjkim } 2060280304Sjkim } 2061160814Ssimon end: 2062280304Sjkim if (debug) 2063280304Sjkim process_proxy_debug(indent, 2064280304Sjkim "End process_proxy_cond_multipliers at position %d: %s, returning %d\n", 2065280304Sjkim *pos, cond, ok); 2066160814Ssimon 2067280304Sjkim *cond_end = cond; 2068280304Sjkim return ok; 2069280304Sjkim} 2070280304Sjkim 2071160814Ssimonstatic int process_proxy_cond_adders(unsigned int letters[26], 2072280304Sjkim const char *cond, const char **cond_end, 2073280304Sjkim int *pos, int indent) 2074280304Sjkim{ 2075280304Sjkim int ok; 2076280304Sjkim char c; 2077160814Ssimon 2078280304Sjkim if (debug) 2079280304Sjkim process_proxy_debug(indent, 2080280304Sjkim "Start process_proxy_cond_adders at position %d: %s\n", 2081280304Sjkim *pos, cond); 2082160814Ssimon 2083280304Sjkim ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos, 2084280304Sjkim indent + 1); 2085280304Sjkim cond = *cond_end; 2086280304Sjkim if (ok < 0) 2087280304Sjkim goto end; 2088160814Ssimon 2089280304Sjkim while (ok >= 0) { 2090280304Sjkim while (isspace((int)*cond)) { 2091280304Sjkim cond++; 2092280304Sjkim (*pos)++; 2093280304Sjkim } 2094280304Sjkim c = *cond; 2095160814Ssimon 2096280304Sjkim switch (c) { 2097280304Sjkim case '|': 2098280304Sjkim { 2099280304Sjkim int save_ok = ok; 2100160814Ssimon 2101280304Sjkim cond++; 2102280304Sjkim (*pos)++; 2103280304Sjkim ok = process_proxy_cond_multipliers(letters, 2104280304Sjkim cond, cond_end, pos, 2105280304Sjkim indent + 1); 2106280304Sjkim cond = *cond_end; 2107280304Sjkim if (ok < 0) 2108280304Sjkim break; 2109160814Ssimon 2110280304Sjkim switch (c) { 2111280304Sjkim case '|': 2112280304Sjkim ok |= save_ok; 2113280304Sjkim break; 2114280304Sjkim default: 2115280304Sjkim fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 2116280304Sjkim " STOPPING\n"); 2117280304Sjkim EXIT(1); 2118280304Sjkim } 2119280304Sjkim } 2120280304Sjkim break; 2121280304Sjkim default: 2122280304Sjkim goto end; 2123280304Sjkim } 2124280304Sjkim } 2125160814Ssimon end: 2126280304Sjkim if (debug) 2127280304Sjkim process_proxy_debug(indent, 2128280304Sjkim "End process_proxy_cond_adders at position %d: %s, returning %d\n", 2129280304Sjkim *pos, cond, ok); 2130160814Ssimon 2131280304Sjkim *cond_end = cond; 2132280304Sjkim return ok; 2133280304Sjkim} 2134160814Ssimon 2135160814Ssimonstatic int process_proxy_cond(unsigned int letters[26], 2136280304Sjkim const char *cond, const char **cond_end) 2137280304Sjkim{ 2138280304Sjkim int pos = 1; 2139280304Sjkim return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1); 2140280304Sjkim} 2141160814Ssimon 2142109998Smarkmstatic int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) 2143280304Sjkim{ 2144280304Sjkim int ok = 1; 2145280304Sjkim struct app_verify_arg *cb_arg = arg; 2146280304Sjkim unsigned int letters[26]; /* only used with proxy_auth */ 2147109998Smarkm 2148280304Sjkim if (cb_arg->app_verify) { 2149280304Sjkim char *s = NULL, buf[256]; 2150160814Ssimon 2151280304Sjkim fprintf(stderr, "In app_verify_callback, allowing cert. "); 2152280304Sjkim fprintf(stderr, "Arg is: %s\n", cb_arg->string); 2153280304Sjkim fprintf(stderr, 2154280304Sjkim "Finished printing do we have a context? 0x%p a cert? 0x%p\n", 2155280304Sjkim (void *)ctx, (void *)ctx->cert); 2156280304Sjkim if (ctx->cert) 2157280304Sjkim s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256); 2158280304Sjkim if (s != NULL) { 2159280304Sjkim fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf); 2160280304Sjkim } 2161280304Sjkim return (1); 2162280304Sjkim } 2163280304Sjkim if (cb_arg->proxy_auth) { 2164280304Sjkim int found_any = 0, i; 2165280304Sjkim char *sp; 2166109998Smarkm 2167280304Sjkim for (i = 0; i < 26; i++) 2168280304Sjkim letters[i] = 0; 2169280304Sjkim for (sp = cb_arg->proxy_auth; *sp; sp++) { 2170280304Sjkim int c = *sp; 2171280304Sjkim if (isascii(c) && isalpha(c)) { 2172280304Sjkim if (islower(c)) 2173280304Sjkim c = toupper(c); 2174280304Sjkim letters[c - 'A'] = 1; 2175280304Sjkim } 2176280304Sjkim } 2177160814Ssimon 2178280304Sjkim fprintf(stderr, " Initial proxy rights = "); 2179280304Sjkim for (i = 0; i < 26; i++) 2180280304Sjkim if (letters[i]) { 2181280304Sjkim fprintf(stderr, "%c", i + 'A'); 2182280304Sjkim found_any = 1; 2183280304Sjkim } 2184280304Sjkim if (!found_any) 2185280304Sjkim fprintf(stderr, "none"); 2186280304Sjkim fprintf(stderr, "\n"); 2187160814Ssimon 2188280304Sjkim X509_STORE_CTX_set_ex_data(ctx, 2189280304Sjkim get_proxy_auth_ex_data_idx(), letters); 2190280304Sjkim } 2191280304Sjkim if (cb_arg->allow_proxy_certs) { 2192280304Sjkim X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); 2193280304Sjkim } 2194160814Ssimon#ifndef OPENSSL_NO_X509_VERIFY 2195280304Sjkim ok = X509_verify_cert(ctx); 2196160814Ssimon#endif 2197160814Ssimon 2198280304Sjkim if (cb_arg->proxy_auth) { 2199280304Sjkim if (ok > 0) { 2200280304Sjkim const char *cond_end = NULL; 2201160814Ssimon 2202280304Sjkim ok = process_proxy_cond(letters, cb_arg->proxy_cond, &cond_end); 2203160814Ssimon 2204280304Sjkim if (ok < 0) 2205280304Sjkim EXIT(3); 2206280304Sjkim if (*cond_end) { 2207280304Sjkim fprintf(stderr, 2208280304Sjkim "Stopped processing condition before it's end.\n"); 2209280304Sjkim ok = 0; 2210280304Sjkim } 2211280304Sjkim if (!ok) 2212280304Sjkim fprintf(stderr, 2213280304Sjkim "Proxy rights check with condition '%s' proved invalid\n", 2214280304Sjkim cb_arg->proxy_cond); 2215280304Sjkim else 2216280304Sjkim fprintf(stderr, 2217280304Sjkim "Proxy rights check with condition '%s' proved valid\n", 2218280304Sjkim cb_arg->proxy_cond); 2219280304Sjkim } 2220280304Sjkim } 2221280304Sjkim return (ok); 2222280304Sjkim} 2223109998Smarkm 2224109998Smarkm#ifndef OPENSSL_NO_RSA 2225280304Sjkimstatic RSA *rsa_tmp = NULL; 222668651Skris 222755714Skrisstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) 2228280304Sjkim{ 2229280304Sjkim BIGNUM *bn = NULL; 2230280304Sjkim if (rsa_tmp == NULL) { 2231280304Sjkim bn = BN_new(); 2232280304Sjkim rsa_tmp = RSA_new(); 2233280304Sjkim if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) { 2234280304Sjkim BIO_printf(bio_err, "Memory error..."); 2235280304Sjkim goto end; 2236280304Sjkim } 2237280304Sjkim BIO_printf(bio_err, "Generating temp (%d bit) RSA key...", keylength); 2238280304Sjkim (void)BIO_flush(bio_err); 2239280304Sjkim if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) { 2240280304Sjkim BIO_printf(bio_err, "Error generating key."); 2241280304Sjkim RSA_free(rsa_tmp); 2242280304Sjkim rsa_tmp = NULL; 2243280304Sjkim } 2244280304Sjkim end: 2245280304Sjkim BIO_printf(bio_err, "\n"); 2246280304Sjkim (void)BIO_flush(bio_err); 2247280304Sjkim } 2248280304Sjkim if (bn) 2249280304Sjkim BN_free(bn); 2250280304Sjkim return (rsa_tmp); 2251280304Sjkim} 225268651Skris 225368651Skrisstatic void free_tmp_rsa(void) 2254280304Sjkim{ 2255280304Sjkim if (rsa_tmp != NULL) { 2256280304Sjkim RSA_free(rsa_tmp); 2257280304Sjkim rsa_tmp = NULL; 2258280304Sjkim } 2259280304Sjkim} 226055714Skris#endif 226159191Skris 2262109998Smarkm#ifndef OPENSSL_NO_DH 2263280304Sjkim/*- 2264280304Sjkim * These DH parameters have been generated as follows: 226559191Skris * $ openssl dhparam -C -noout 512 226659191Skris * $ openssl dhparam -C -noout 1024 226759191Skris * $ openssl dhparam -C -noout -dsaparam 1024 226859191Skris * (The third function has been renamed to avoid name conflicts.) 226959191Skris */ 2270109998Smarkmstatic DH *get_dh512() 2271280304Sjkim{ 2272280304Sjkim static unsigned char dh512_p[] = { 2273280304Sjkim 0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0, 2274280304Sjkim 0xC6, 2275280304Sjkim 0x1F, 0x0D, 0xAC, 0xB6, 0x25, 0x3E, 0x06, 0x39, 0xCA, 0x72, 0x04, 2276280304Sjkim 0xB0, 2277280304Sjkim 0x6E, 0xDA, 0xC0, 0x61, 0xE6, 0x7A, 0x77, 0x25, 0xE8, 0x3B, 0xB9, 2278280304Sjkim 0x5F, 2279280304Sjkim 0x9A, 0xB6, 0xB5, 0xFE, 0x99, 0x0B, 0xA1, 0x93, 0x4E, 0x35, 0x33, 2280280304Sjkim 0xB8, 2281280304Sjkim 0xE1, 0xF1, 0x13, 0x4F, 0x59, 0x1A, 0xD2, 0x57, 0xC0, 0x26, 0x21, 2282280304Sjkim 0x33, 2283280304Sjkim 0x02, 0xC5, 0xAE, 0x23, 2284280304Sjkim }; 2285280304Sjkim static unsigned char dh512_g[] = { 2286280304Sjkim 0x02, 2287280304Sjkim }; 2288280304Sjkim DH *dh; 228959191Skris 2290280304Sjkim if ((dh = DH_new()) == NULL) 2291280304Sjkim return (NULL); 2292280304Sjkim dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); 2293280304Sjkim dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); 2294280304Sjkim if ((dh->p == NULL) || (dh->g == NULL)) { 2295280304Sjkim DH_free(dh); 2296280304Sjkim return (NULL); 2297280304Sjkim } 2298280304Sjkim return (dh); 2299280304Sjkim} 230059191Skris 2301109998Smarkmstatic DH *get_dh1024() 2302280304Sjkim{ 2303280304Sjkim static unsigned char dh1024_p[] = { 2304280304Sjkim 0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 2305280304Sjkim 0x3A, 2306280304Sjkim 0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 2307280304Sjkim 0xA2, 2308280304Sjkim 0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 2309280304Sjkim 0xB0, 2310280304Sjkim 0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 2311280304Sjkim 0xC2, 2312280304Sjkim 0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 2313280304Sjkim 0x8C, 2314280304Sjkim 0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 2315280304Sjkim 0xB8, 2316280304Sjkim 0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 2317280304Sjkim 0x52, 2318280304Sjkim 0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 2319280304Sjkim 0xC1, 2320280304Sjkim 0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 2321280304Sjkim 0xB1, 2322280304Sjkim 0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 2323280304Sjkim 0xAB, 2324280304Sjkim 0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53, 2325280304Sjkim }; 2326280304Sjkim static unsigned char dh1024_g[] = { 2327280304Sjkim 0x02, 2328280304Sjkim }; 2329280304Sjkim DH *dh; 233059191Skris 2331280304Sjkim if ((dh = DH_new()) == NULL) 2332280304Sjkim return (NULL); 2333280304Sjkim dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 2334280304Sjkim dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 2335280304Sjkim if ((dh->p == NULL) || (dh->g == NULL)) { 2336280304Sjkim DH_free(dh); 2337280304Sjkim return (NULL); 2338280304Sjkim } 2339280304Sjkim return (dh); 2340280304Sjkim} 234159191Skris 2342109998Smarkmstatic DH *get_dh1024dsa() 2343280304Sjkim{ 2344280304Sjkim static unsigned char dh1024_p[] = { 2345280304Sjkim 0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 2346280304Sjkim 0x00, 2347280304Sjkim 0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 2348280304Sjkim 0x19, 2349280304Sjkim 0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 2350280304Sjkim 0xD2, 2351280304Sjkim 0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 2352280304Sjkim 0x55, 2353280304Sjkim 0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 2354280304Sjkim 0xFC, 2355280304Sjkim 0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 2356280304Sjkim 0x97, 2357280304Sjkim 0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 2358280304Sjkim 0x8D, 2359280304Sjkim 0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 2360280304Sjkim 0xBB, 2361280304Sjkim 0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 2362280304Sjkim 0xF6, 2363280304Sjkim 0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 2364280304Sjkim 0x9E, 2365280304Sjkim 0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39, 2366280304Sjkim }; 2367280304Sjkim static unsigned char dh1024_g[] = { 2368280304Sjkim 0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 2369280304Sjkim 0x05, 2370280304Sjkim 0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 2371280304Sjkim 0xF3, 2372280304Sjkim 0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 2373280304Sjkim 0xE9, 2374280304Sjkim 0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 2375280304Sjkim 0x3C, 2376280304Sjkim 0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 2377280304Sjkim 0x65, 2378280304Sjkim 0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 2379280304Sjkim 0x60, 2380280304Sjkim 0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 2381280304Sjkim 0xF6, 2382280304Sjkim 0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 2383280304Sjkim 0xA7, 2384280304Sjkim 0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 2385280304Sjkim 0xA1, 2386280304Sjkim 0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 2387280304Sjkim 0x60, 2388280304Sjkim 0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2, 2389280304Sjkim }; 2390280304Sjkim DH *dh; 239159191Skris 2392280304Sjkim if ((dh = DH_new()) == NULL) 2393280304Sjkim return (NULL); 2394280304Sjkim dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 2395280304Sjkim dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 2396280304Sjkim if ((dh->p == NULL) || (dh->g == NULL)) { 2397280304Sjkim DH_free(dh); 2398280304Sjkim return (NULL); 2399280304Sjkim } 2400280304Sjkim dh->length = 160; 2401280304Sjkim return (dh); 2402280304Sjkim} 240359191Skris#endif 2404160814Ssimon 2405238405Sjkim#ifndef OPENSSL_NO_PSK 2406238405Sjkim/* convert the PSK key (psk_key) in ascii to binary (psk) */ 2407238405Sjkimstatic int psk_key2bn(const char *pskkey, unsigned char *psk, 2408280304Sjkim unsigned int max_psk_len) 2409280304Sjkim{ 2410280304Sjkim int ret; 2411280304Sjkim BIGNUM *bn = NULL; 2412238405Sjkim 2413280304Sjkim ret = BN_hex2bn(&bn, pskkey); 2414280304Sjkim if (!ret) { 2415280304Sjkim BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", 2416280304Sjkim pskkey); 2417280304Sjkim if (bn) 2418280304Sjkim BN_free(bn); 2419280304Sjkim return 0; 2420280304Sjkim } 2421280304Sjkim if (BN_num_bytes(bn) > (int)max_psk_len) { 2422280304Sjkim BIO_printf(bio_err, 2423280304Sjkim "psk buffer of callback is too small (%d) for key (%d)\n", 2424280304Sjkim max_psk_len, BN_num_bytes(bn)); 2425280304Sjkim BN_free(bn); 2426280304Sjkim return 0; 2427280304Sjkim } 2428280304Sjkim ret = BN_bn2bin(bn, psk); 2429280304Sjkim BN_free(bn); 2430280304Sjkim return ret; 2431280304Sjkim} 2432238405Sjkim 2433280304Sjkimstatic unsigned int psk_client_callback(SSL *ssl, const char *hint, 2434280304Sjkim char *identity, 2435280304Sjkim unsigned int max_identity_len, 2436280304Sjkim unsigned char *psk, 2437280304Sjkim unsigned int max_psk_len) 2438280304Sjkim{ 2439280304Sjkim int ret; 2440280304Sjkim unsigned int psk_len = 0; 2441238405Sjkim 2442280304Sjkim ret = BIO_snprintf(identity, max_identity_len, "Client_identity"); 2443280304Sjkim if (ret < 0) 2444280304Sjkim goto out_err; 2445280304Sjkim if (debug) 2446280304Sjkim fprintf(stderr, "client: created identity '%s' len=%d\n", identity, 2447280304Sjkim ret); 2448280304Sjkim ret = psk_key2bn(psk_key, psk, max_psk_len); 2449280304Sjkim if (ret < 0) 2450280304Sjkim goto out_err; 2451280304Sjkim psk_len = ret; 2452280304Sjkim out_err: 2453280304Sjkim return psk_len; 2454280304Sjkim} 2455238405Sjkim 2456238405Sjkimstatic unsigned int psk_server_callback(SSL *ssl, const char *identity, 2457280304Sjkim unsigned char *psk, 2458280304Sjkim unsigned int max_psk_len) 2459280304Sjkim{ 2460280304Sjkim unsigned int psk_len = 0; 2461238405Sjkim 2462280304Sjkim if (strcmp(identity, "Client_identity") != 0) { 2463280304Sjkim BIO_printf(bio_err, "server: PSK error: client identity not found\n"); 2464280304Sjkim return 0; 2465280304Sjkim } 2466280304Sjkim psk_len = psk_key2bn(psk_key, psk, max_psk_len); 2467280304Sjkim return psk_len; 2468280304Sjkim} 2469238405Sjkim#endif 2470238405Sjkim 2471160814Ssimonstatic int do_test_cipherlist(void) 2472280304Sjkim{ 2473280304Sjkim int i = 0; 2474280304Sjkim const SSL_METHOD *meth; 2475280304Sjkim const SSL_CIPHER *ci, *tci = NULL; 2476160814Ssimon 2477160814Ssimon#ifndef OPENSSL_NO_SSL2 2478280304Sjkim fprintf(stderr, "testing SSLv2 cipher list order: "); 2479280304Sjkim meth = SSLv2_method(); 2480280304Sjkim while ((ci = meth->get_cipher(i++)) != NULL) { 2481280304Sjkim if (tci != NULL) 2482280304Sjkim if (ci->id >= tci->id) { 2483280304Sjkim fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2484280304Sjkim return 0; 2485280304Sjkim } 2486280304Sjkim tci = ci; 2487280304Sjkim } 2488280304Sjkim fprintf(stderr, "ok\n"); 2489160814Ssimon#endif 2490160814Ssimon#ifndef OPENSSL_NO_SSL3 2491280304Sjkim fprintf(stderr, "testing SSLv3 cipher list order: "); 2492280304Sjkim meth = SSLv3_method(); 2493280304Sjkim tci = NULL; 2494280304Sjkim while ((ci = meth->get_cipher(i++)) != NULL) { 2495280304Sjkim if (tci != NULL) 2496280304Sjkim if (ci->id >= tci->id) { 2497280304Sjkim fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2498280304Sjkim return 0; 2499280304Sjkim } 2500280304Sjkim tci = ci; 2501280304Sjkim } 2502280304Sjkim fprintf(stderr, "ok\n"); 2503160814Ssimon#endif 2504160814Ssimon#ifndef OPENSSL_NO_TLS1 2505280304Sjkim fprintf(stderr, "testing TLSv1 cipher list order: "); 2506280304Sjkim meth = TLSv1_method(); 2507280304Sjkim tci = NULL; 2508280304Sjkim while ((ci = meth->get_cipher(i++)) != NULL) { 2509280304Sjkim if (tci != NULL) 2510280304Sjkim if (ci->id >= tci->id) { 2511280304Sjkim fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2512280304Sjkim return 0; 2513280304Sjkim } 2514280304Sjkim tci = ci; 2515280304Sjkim } 2516280304Sjkim fprintf(stderr, "ok\n"); 2517160814Ssimon#endif 2518160814Ssimon 2519280304Sjkim return 1; 2520280304Sjkim} 2521