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. 8296341Sdelphij * 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). 15296341Sdelphij * 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. 22296341Sdelphij * 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 :-). 37296341Sdelphij * 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)" 40296341Sdelphij * 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. 52296341Sdelphij * 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 66296341Sdelphij * 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. 113296341Sdelphij * 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 143296341Sdelphij/* Or gethostname won't be declared properly on Linux and GNU platforms. */ 144296341Sdelphij#define _BSD_SOURCE 1 145109998Smarkm 14659191Skris#include <assert.h> 14759191Skris#include <errno.h> 14859191Skris#include <limits.h> 14955714Skris#include <stdio.h> 15055714Skris#include <stdlib.h> 15155714Skris#include <string.h> 15259191Skris#include <time.h> 15355714Skris 154109998Smarkm#define USE_SOCKETS 155109998Smarkm#include "e_os.h" 15655714Skris 157238405Sjkim#ifdef OPENSSL_SYS_VMS 158296341Sdelphij/* 159296341Sdelphij * Or isascii won't be declared properly on VMS (at least with DECompHP C). 160296341Sdelphij */ 161296341Sdelphij# define _XOPEN_SOURCE 500 162238405Sjkim#endif 163238405Sjkim 164160814Ssimon#include <ctype.h> 165160814Ssimon 16655714Skris#include <openssl/bio.h> 16755714Skris#include <openssl/crypto.h> 16859191Skris#include <openssl/evp.h> 16955714Skris#include <openssl/x509.h> 170160814Ssimon#include <openssl/x509v3.h> 17155714Skris#include <openssl/ssl.h> 172111147Snectar#ifndef OPENSSL_NO_ENGINE 173296341Sdelphij# include <openssl/engine.h> 174111147Snectar#endif 17555714Skris#include <openssl/err.h> 17659191Skris#include <openssl/rand.h> 177160814Ssimon#ifndef OPENSSL_NO_RSA 178296341Sdelphij# include <openssl/rsa.h> 179160814Ssimon#endif 180160814Ssimon#ifndef OPENSSL_NO_DSA 181296341Sdelphij# include <openssl/dsa.h> 182160814Ssimon#endif 183160814Ssimon#ifndef OPENSSL_NO_DH 184296341Sdelphij# include <openssl/dh.h> 185160814Ssimon#endif 186238405Sjkim#ifndef OPENSSL_NO_SRP 187296341Sdelphij# include <openssl/srp.h> 188238405Sjkim#endif 189160814Ssimon#include <openssl/bn.h> 190109998Smarkm 191296341Sdelphij/* 192296341Sdelphij * Or gethostname won't be declared properly 193296341Sdelphij * on Compaq platforms (at least with DEC C). 194296341Sdelphij * Do not try to put it earlier, or IPv6 includes 195296341Sdelphij * get screwed... 196296341Sdelphij */ 197296341Sdelphij#define _XOPEN_SOURCE_EXTENDED 1 198109998Smarkm 199109998Smarkm#ifdef OPENSSL_SYS_WINDOWS 200296341Sdelphij# include <winsock.h> 201109998Smarkm#else 202296341Sdelphij# include OPENSSL_UNISTD 20355714Skris#endif 20455714Skris 205109998Smarkm#ifdef OPENSSL_SYS_VMS 206296341Sdelphij# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM" 207296341Sdelphij# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM" 208109998Smarkm#elif defined(OPENSSL_SYS_WINCE) 209296341Sdelphij# define TEST_SERVER_CERT "\\OpenSSL\\server.pem" 210296341Sdelphij# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem" 211160814Ssimon#elif defined(OPENSSL_SYS_NETWARE) 212296341Sdelphij# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem" 213296341Sdelphij# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem" 21455714Skris#else 215296341Sdelphij# define TEST_SERVER_CERT "../apps/server.pem" 216296341Sdelphij# define TEST_CLIENT_CERT "../apps/client.pem" 21755714Skris#endif 21855714Skris 219296341Sdelphij/* 220296341Sdelphij * There is really no standard for this, so let's assign some tentative 221296341Sdelphij * numbers. In any case, these numbers are only for this test 222296341Sdelphij */ 223296341Sdelphij#define COMP_RLE 255 224296341Sdelphij#define COMP_ZLIB 1 225109998Smarkm 22659191Skrisstatic int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); 227109998Smarkm#ifndef OPENSSL_NO_RSA 228296341Sdelphijstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); 22968651Skrisstatic void free_tmp_rsa(void); 23055714Skris#endif 231109998Smarkmstatic int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg); 232160814Ssimon#define APP_CALLBACK_STRING "Test Callback Argument" 233296341Sdelphijstruct app_verify_arg { 234296341Sdelphij char *string; 235296341Sdelphij int app_verify; 236296341Sdelphij int allow_proxy_certs; 237296341Sdelphij char *proxy_auth; 238296341Sdelphij char *proxy_cond; 239296341Sdelphij}; 240109998Smarkm 241109998Smarkm#ifndef OPENSSL_NO_DH 24255714Skrisstatic DH *get_dh512(void); 24359191Skrisstatic DH *get_dh1024(void); 24459191Skrisstatic DH *get_dh1024dsa(void); 24555714Skris#endif 24655714Skris 247296341Sdelphijstatic char *psk_key = NULL; /* by default PSK is not used */ 248238405Sjkim#ifndef OPENSSL_NO_PSK 249296341Sdelphijstatic unsigned int psk_client_callback(SSL *ssl, const char *hint, 250296341Sdelphij char *identity, 251296341Sdelphij unsigned int max_identity_len, 252296341Sdelphij unsigned char *psk, 253296341Sdelphij unsigned int max_psk_len); 254296341Sdelphijstatic unsigned int psk_server_callback(SSL *ssl, const char *identity, 255296341Sdelphij unsigned char *psk, 256296341Sdelphij unsigned int max_psk_len); 257238405Sjkim#endif 258238405Sjkim 259238405Sjkim#ifndef OPENSSL_NO_SRP 260238405Sjkim/* SRP client */ 261238405Sjkim/* This is a context that we pass to all callbacks */ 262296341Sdelphijtypedef struct srp_client_arg_st { 263296341Sdelphij char *srppassin; 264296341Sdelphij char *srplogin; 265296341Sdelphij} SRP_CLIENT_ARG; 266238405Sjkim 267296341Sdelphij# define PWD_STRLEN 1024 268238405Sjkim 269296341Sdelphijstatic char *MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg) 270296341Sdelphij{ 271296341Sdelphij SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; 272296341Sdelphij return BUF_strdup((char *)srp_client_arg->srppassin); 273296341Sdelphij} 274238405Sjkim 275238405Sjkim/* SRP server */ 276238405Sjkim/* This is a context that we pass to SRP server callbacks */ 277296341Sdelphijtypedef struct srp_server_arg_st { 278296341Sdelphij char *expected_user; 279296341Sdelphij char *pass; 280296341Sdelphij} SRP_SERVER_ARG; 281238405Sjkim 282238405Sjkimstatic int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) 283296341Sdelphij{ 284296341Sdelphij SRP_SERVER_ARG *p = (SRP_SERVER_ARG *)arg; 285238405Sjkim 286296341Sdelphij if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0) { 287296341Sdelphij fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s)); 288296341Sdelphij return SSL3_AL_FATAL; 289296341Sdelphij } 290296341Sdelphij if (SSL_set_srp_server_param_pw(s, p->expected_user, p->pass, "1024") < 0) { 291296341Sdelphij *ad = SSL_AD_INTERNAL_ERROR; 292296341Sdelphij return SSL3_AL_FATAL; 293296341Sdelphij } 294296341Sdelphij return SSL_ERROR_NONE; 295296341Sdelphij} 296238405Sjkim#endif 297238405Sjkim 298296341Sdelphijstatic BIO *bio_err = NULL; 299296341Sdelphijstatic BIO *bio_stdout = NULL; 30059191Skris 301296341Sdelphijstatic char *cipher = NULL; 302296341Sdelphijstatic int verbose = 0; 303296341Sdelphijstatic int debug = 0; 30455714Skris#if 0 30555714Skris/* Not used yet. */ 306296341Sdelphij# ifdef FIONBIO 307296341Sdelphijstatic int s_nbio = 0; 308296341Sdelphij# endif 30955714Skris#endif 31055714Skris 311296341Sdelphijstatic const char rnd_seed[] = 312296341Sdelphij "string to make the random number generator think it has entropy"; 31355714Skris 314296341Sdelphijint doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time, 315296341Sdelphij clock_t *c_time); 316296341Sdelphijint doit(SSL *s_ssl, SSL *c_ssl, long bytes); 317160814Ssimonstatic int do_test_cipherlist(void); 31855714Skrisstatic void sv_usage(void) 319296341Sdelphij{ 320296341Sdelphij fprintf(stderr, "usage: ssltest [args ...]\n"); 321296341Sdelphij fprintf(stderr, "\n"); 322194206Ssimon#ifdef OPENSSL_FIPS 323296341Sdelphij fprintf(stderr, "-F - run test in FIPS mode\n"); 324194206Ssimon#endif 325296341Sdelphij fprintf(stderr, " -server_auth - check server certificate\n"); 326296341Sdelphij fprintf(stderr, " -client_auth - do client authentication\n"); 327296341Sdelphij fprintf(stderr, " -proxy - allow proxy certificates\n"); 328296341Sdelphij fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n"); 329296341Sdelphij fprintf(stderr, 330296341Sdelphij " -proxy_cond <val> - experssion to test proxy policy rights\n"); 331296341Sdelphij fprintf(stderr, " -v - more output\n"); 332296341Sdelphij fprintf(stderr, " -d - debug output\n"); 333296341Sdelphij fprintf(stderr, " -reuse - use session-id reuse\n"); 334296341Sdelphij fprintf(stderr, " -num <val> - number of connections to perform\n"); 335296341Sdelphij fprintf(stderr, 336296341Sdelphij " -bytes <val> - number of bytes to swap between client/server\n"); 337109998Smarkm#ifndef OPENSSL_NO_DH 338296341Sdelphij fprintf(stderr, 339296341Sdelphij " -dhe512 - use 512 bit key for DHE (to test failure)\n"); 340296341Sdelphij fprintf(stderr, 341296341Sdelphij " -dhe1024 - use 1024 bit key (safe prime) for DHE (default, no-op)\n"); 342296341Sdelphij fprintf(stderr, 343296341Sdelphij " -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); 344296341Sdelphij fprintf(stderr, " -no_dhe - disable DHE\n"); 34555714Skris#endif 346160814Ssimon#ifndef OPENSSL_NO_ECDH 347296341Sdelphij fprintf(stderr, " -no_ecdhe - disable ECDHE\n"); 348160814Ssimon#endif 349238405Sjkim#ifndef OPENSSL_NO_PSK 350296341Sdelphij fprintf(stderr, " -psk arg - PSK in hex (without 0x)\n"); 351238405Sjkim#endif 352238405Sjkim#ifndef OPENSSL_NO_SRP 353296341Sdelphij fprintf(stderr, " -srpuser user - SRP username to use\n"); 354296341Sdelphij fprintf(stderr, " -srppass arg - password for 'user'\n"); 355238405Sjkim#endif 356109998Smarkm#ifndef OPENSSL_NO_SSL2 357296341Sdelphij fprintf(stderr, " -ssl2 - use SSLv2\n"); 35855714Skris#endif 359279264Sdelphij#ifndef OPENSSL_NO_SSL3_METHOD 360296341Sdelphij fprintf(stderr, " -ssl3 - use SSLv3\n"); 36155714Skris#endif 362109998Smarkm#ifndef OPENSSL_NO_TLS1 363296341Sdelphij fprintf(stderr, " -tls1 - use TLSv1\n"); 36455714Skris#endif 365296341Sdelphij fprintf(stderr, " -CApath arg - PEM format directory of CA's\n"); 366296341Sdelphij fprintf(stderr, " -CAfile arg - PEM format file of CA's\n"); 367296341Sdelphij fprintf(stderr, " -cert arg - Server certificate file\n"); 368296341Sdelphij fprintf(stderr, 369296341Sdelphij " -key arg - Server key file (default: same as -cert)\n"); 370296341Sdelphij fprintf(stderr, " -c_cert arg - Client certificate file\n"); 371296341Sdelphij fprintf(stderr, 372296341Sdelphij " -c_key arg - Client key file (default: same as -c_cert)\n"); 373296341Sdelphij fprintf(stderr, " -cipher arg - The cipher list\n"); 374296341Sdelphij fprintf(stderr, " -bio_pair - Use BIO pairs\n"); 375296341Sdelphij fprintf(stderr, " -f - Test even cases that can't work\n"); 376296341Sdelphij fprintf(stderr, 377296341Sdelphij " -time - measure processor time used by client and server\n"); 378296341Sdelphij fprintf(stderr, " -zlib - use zlib compression\n"); 379296341Sdelphij fprintf(stderr, " -rle - use rle compression\n"); 380160814Ssimon#ifndef OPENSSL_NO_ECDH 381296341Sdelphij fprintf(stderr, 382296341Sdelphij " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" 383296341Sdelphij " Use \"openssl ecparam -list_curves\" for all names\n" 384296341Sdelphij " (default is sect163r2).\n"); 385160814Ssimon#endif 386296341Sdelphij fprintf(stderr, 387296341Sdelphij " -test_cipherlist - Verifies the order of the ssl cipher lists.\n" 388296341Sdelphij " When this option is requested, the cipherlist\n" 389296341Sdelphij " tests are run instead of handshake tests.\n"); 390296341Sdelphij} 39155714Skris 39259191Skrisstatic void print_details(SSL *c_ssl, const char *prefix) 393296341Sdelphij{ 394296341Sdelphij const SSL_CIPHER *ciph; 395296341Sdelphij X509 *cert; 396296341Sdelphij 397296341Sdelphij ciph = SSL_get_current_cipher(c_ssl); 398296341Sdelphij BIO_printf(bio_stdout, "%s%s, cipher %s %s", 399296341Sdelphij prefix, 400296341Sdelphij SSL_get_version(c_ssl), 401296341Sdelphij SSL_CIPHER_get_version(ciph), SSL_CIPHER_get_name(ciph)); 402296341Sdelphij cert = SSL_get_peer_certificate(c_ssl); 403296341Sdelphij if (cert != NULL) { 404296341Sdelphij EVP_PKEY *pkey = X509_get_pubkey(cert); 405296341Sdelphij if (pkey != NULL) { 406296341Sdelphij if (0) ; 407109998Smarkm#ifndef OPENSSL_NO_RSA 408296341Sdelphij else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL 409296341Sdelphij && pkey->pkey.rsa->n != NULL) { 410296341Sdelphij BIO_printf(bio_stdout, ", %d bit RSA", 411296341Sdelphij BN_num_bits(pkey->pkey.rsa->n)); 412296341Sdelphij } 41359191Skris#endif 414109998Smarkm#ifndef OPENSSL_NO_DSA 415296341Sdelphij else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL 416296341Sdelphij && pkey->pkey.dsa->p != NULL) { 417296341Sdelphij BIO_printf(bio_stdout, ", %d bit DSA", 418296341Sdelphij BN_num_bits(pkey->pkey.dsa->p)); 419296341Sdelphij } 42059191Skris#endif 421296341Sdelphij EVP_PKEY_free(pkey); 422296341Sdelphij } 423296341Sdelphij X509_free(cert); 424296341Sdelphij } 425296341Sdelphij /* 426296341Sdelphij * The SSL API does not allow us to look at temporary RSA/DH keys, 427296341Sdelphij * otherwise we should print their lengths too 428296341Sdelphij */ 429296341Sdelphij BIO_printf(bio_stdout, "\n"); 430296341Sdelphij} 43159191Skris 432109998Smarkmstatic void lock_dbg_cb(int mode, int type, const char *file, int line) 433296341Sdelphij{ 434296341Sdelphij static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ 435296341Sdelphij const char *errstr = NULL; 436296341Sdelphij int rw; 437109998Smarkm 438296341Sdelphij rw = mode & (CRYPTO_READ | CRYPTO_WRITE); 439296341Sdelphij if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) { 440296341Sdelphij errstr = "invalid mode"; 441296341Sdelphij goto err; 442296341Sdelphij } 443109998Smarkm 444296341Sdelphij if (type < 0 || type >= CRYPTO_NUM_LOCKS) { 445296341Sdelphij errstr = "type out of bounds"; 446296341Sdelphij goto err; 447296341Sdelphij } 448109998Smarkm 449296341Sdelphij if (mode & CRYPTO_LOCK) { 450296341Sdelphij if (modes[type]) { 451296341Sdelphij errstr = "already locked"; 452296341Sdelphij /* 453296341Sdelphij * must not happen in a single-threaded program (would deadlock) 454296341Sdelphij */ 455296341Sdelphij goto err; 456296341Sdelphij } 457109998Smarkm 458296341Sdelphij modes[type] = rw; 459296341Sdelphij } else if (mode & CRYPTO_UNLOCK) { 460296341Sdelphij if (!modes[type]) { 461296341Sdelphij errstr = "not locked"; 462296341Sdelphij goto err; 463296341Sdelphij } 464109998Smarkm 465296341Sdelphij if (modes[type] != rw) { 466296341Sdelphij errstr = (rw == CRYPTO_READ) ? 467296341Sdelphij "CRYPTO_r_unlock on write lock" : 468296341Sdelphij "CRYPTO_w_unlock on read lock"; 469296341Sdelphij } 470296341Sdelphij 471296341Sdelphij modes[type] = 0; 472296341Sdelphij } else { 473296341Sdelphij errstr = "invalid mode"; 474296341Sdelphij goto err; 475296341Sdelphij } 476296341Sdelphij 477109998Smarkm err: 478296341Sdelphij if (errstr) { 479296341Sdelphij /* we cannot use bio_err here */ 480296341Sdelphij fprintf(stderr, 481296341Sdelphij "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", 482296341Sdelphij errstr, mode, type, file, line); 483296341Sdelphij } 484296341Sdelphij} 485109998Smarkm 486238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 487296341Sdelphijstruct cb_info_st { 488296341Sdelphij void *input; 489296341Sdelphij size_t len; 490296341Sdelphij int ret; 491296341Sdelphij}; 492238405Sjkimstruct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */ 493238405Sjkimstruct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */ 494238405Sjkimstruct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */ 495238405Sjkimstruct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */ 496160814Ssimon 497238405Sjkimint opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_) 498296341Sdelphij{ 499296341Sdelphij struct cb_info_st *arg = arg_; 500238405Sjkim 501296341Sdelphij if (arg == NULL) 502296341Sdelphij return 1; 503296341Sdelphij 504296341Sdelphij if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len)) 505296341Sdelphij return 0; 506296341Sdelphij return arg->ret; 507296341Sdelphij} 508238405Sjkim#endif 509238405Sjkim 51055714Skrisint main(int argc, char *argv[]) 511296341Sdelphij{ 512296341Sdelphij char *CApath = NULL, *CAfile = NULL; 513296341Sdelphij int badop = 0; 514296341Sdelphij int bio_pair = 0; 515296341Sdelphij int force = 0; 516296341Sdelphij int tls1 = 0, ssl2 = 0, ssl3 = 0, ret = 1; 517296341Sdelphij int client_auth = 0; 518296341Sdelphij int server_auth = 0, i; 519296341Sdelphij struct app_verify_arg app_verify_arg = 520296341Sdelphij { APP_CALLBACK_STRING, 0, 0, NULL, NULL }; 521296341Sdelphij char *server_cert = TEST_SERVER_CERT; 522296341Sdelphij char *server_key = NULL; 523296341Sdelphij char *client_cert = TEST_CLIENT_CERT; 524296341Sdelphij char *client_key = NULL; 525160814Ssimon#ifndef OPENSSL_NO_ECDH 526296341Sdelphij char *named_curve = NULL; 527160814Ssimon#endif 528296341Sdelphij SSL_CTX *s_ctx = NULL; 529296341Sdelphij SSL_CTX *c_ctx = NULL; 530296341Sdelphij const SSL_METHOD *meth = NULL; 531296341Sdelphij SSL *c_ssl, *s_ssl; 532296341Sdelphij int number = 1, reuse = 0; 533296341Sdelphij long bytes = 256L; 534109998Smarkm#ifndef OPENSSL_NO_DH 535296341Sdelphij DH *dh; 536296341Sdelphij int dhe512 = 0, dhe1024dsa = 0; 53755714Skris#endif 538160814Ssimon#ifndef OPENSSL_NO_ECDH 539296341Sdelphij EC_KEY *ecdh = NULL; 540160814Ssimon#endif 541238405Sjkim#ifndef OPENSSL_NO_SRP 542296341Sdelphij /* client */ 543296341Sdelphij SRP_CLIENT_ARG srp_client_arg = { NULL, NULL }; 544296341Sdelphij /* server */ 545296341Sdelphij SRP_SERVER_ARG srp_server_arg = { NULL, NULL }; 546238405Sjkim#endif 547296341Sdelphij int no_dhe = 0; 548296341Sdelphij int no_ecdhe = 0; 549296341Sdelphij int no_psk = 0; 550296341Sdelphij int print_time = 0; 551296341Sdelphij clock_t s_time = 0, c_time = 0; 552296341Sdelphij int comp = 0; 553160814Ssimon#ifndef OPENSSL_NO_COMP 554296341Sdelphij COMP_METHOD *cm = NULL; 555296341Sdelphij STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; 556142425Snectar#endif 557296341Sdelphij int test_cipherlist = 0; 558194206Ssimon#ifdef OPENSSL_FIPS 559296341Sdelphij int fips_mode = 0; 560194206Ssimon#endif 561296341Sdelphij int no_protocol = 0; 56255714Skris 563296341Sdelphij verbose = 0; 564296341Sdelphij debug = 0; 565296341Sdelphij cipher = 0; 566109998Smarkm 567296341Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); 568109998Smarkm 569296341Sdelphij CRYPTO_set_locking_callback(lock_dbg_cb); 570109998Smarkm 571296341Sdelphij /* enable memory leak checking unless explicitly disabled */ 572296341Sdelphij if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) 573296341Sdelphij && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { 574296341Sdelphij CRYPTO_malloc_debug_init(); 575296341Sdelphij CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); 576296341Sdelphij } else { 577296341Sdelphij /* OPENSSL_DEBUG_MEMORY=off */ 578296341Sdelphij CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); 579296341Sdelphij } 580296341Sdelphij CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 58159191Skris 582296341Sdelphij RAND_seed(rnd_seed, sizeof rnd_seed); 58359191Skris 584296341Sdelphij bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); 58555714Skris 586296341Sdelphij argc--; 587296341Sdelphij argv++; 58855714Skris 589296341Sdelphij while (argc >= 1) { 590296341Sdelphij if (!strcmp(*argv, "-F")) { 591194206Ssimon#ifdef OPENSSL_FIPS 592296341Sdelphij fips_mode = 1; 593194206Ssimon#else 594296341Sdelphij fprintf(stderr, 595296341Sdelphij "not compiled with FIPS support, so exitting without running.\n"); 596296341Sdelphij EXIT(0); 597194206Ssimon#endif 598296341Sdelphij } else if (strcmp(*argv, "-server_auth") == 0) 599296341Sdelphij server_auth = 1; 600296341Sdelphij else if (strcmp(*argv, "-client_auth") == 0) 601296341Sdelphij client_auth = 1; 602296341Sdelphij else if (strcmp(*argv, "-proxy_auth") == 0) { 603296341Sdelphij if (--argc < 1) 604296341Sdelphij goto bad; 605296341Sdelphij app_verify_arg.proxy_auth = *(++argv); 606296341Sdelphij } else if (strcmp(*argv, "-proxy_cond") == 0) { 607296341Sdelphij if (--argc < 1) 608296341Sdelphij goto bad; 609296341Sdelphij app_verify_arg.proxy_cond = *(++argv); 610296341Sdelphij } else if (strcmp(*argv, "-v") == 0) 611296341Sdelphij verbose = 1; 612296341Sdelphij else if (strcmp(*argv, "-d") == 0) 613296341Sdelphij debug = 1; 614296341Sdelphij else if (strcmp(*argv, "-reuse") == 0) 615296341Sdelphij reuse = 1; 616296341Sdelphij else if (strcmp(*argv, "-dhe512") == 0) { 617109998Smarkm#ifndef OPENSSL_NO_DH 618296341Sdelphij dhe512 = 1; 619109998Smarkm#else 620296341Sdelphij fprintf(stderr, 621296341Sdelphij "ignoring -dhe512, since I'm compiled without DH\n"); 622109998Smarkm#endif 623296341Sdelphij } else if (strcmp(*argv, "-dhe1024dsa") == 0) { 624109998Smarkm#ifndef OPENSSL_NO_DH 625296341Sdelphij dhe1024dsa = 1; 626109998Smarkm#else 627296341Sdelphij fprintf(stderr, 628296341Sdelphij "ignoring -dhe1024dsa, since I'm compiled without DH\n"); 62959191Skris#endif 630296341Sdelphij } else if (strcmp(*argv, "-no_dhe") == 0) 631296341Sdelphij no_dhe = 1; 632296341Sdelphij else if (strcmp(*argv, "-no_ecdhe") == 0) 633296341Sdelphij no_ecdhe = 1; 634296341Sdelphij else if (strcmp(*argv, "-psk") == 0) { 635296341Sdelphij if (--argc < 1) 636296341Sdelphij goto bad; 637296341Sdelphij psk_key = *(++argv); 638238405Sjkim#ifndef OPENSSL_NO_PSK 639296341Sdelphij if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key)) { 640296341Sdelphij BIO_printf(bio_err, "Not a hex number '%s'\n", *argv); 641296341Sdelphij goto bad; 642296341Sdelphij } 643238405Sjkim#else 644296341Sdelphij no_psk = 1; 645238405Sjkim#endif 646296341Sdelphij } 647238405Sjkim#ifndef OPENSSL_NO_SRP 648296341Sdelphij else if (strcmp(*argv, "-srpuser") == 0) { 649296341Sdelphij if (--argc < 1) 650296341Sdelphij goto bad; 651296341Sdelphij srp_server_arg.expected_user = srp_client_arg.srplogin = 652296341Sdelphij *(++argv); 653296341Sdelphij tls1 = 1; 654296341Sdelphij } else if (strcmp(*argv, "-srppass") == 0) { 655296341Sdelphij if (--argc < 1) 656296341Sdelphij goto bad; 657296341Sdelphij srp_server_arg.pass = srp_client_arg.srppassin = *(++argv); 658296341Sdelphij tls1 = 1; 659296341Sdelphij } 660238405Sjkim#endif 661296341Sdelphij else if (strcmp(*argv, "-ssl2") == 0) { 662279264Sdelphij#ifdef OPENSSL_NO_SSL2 663296341Sdelphij no_protocol = 1; 664279264Sdelphij#endif 665296341Sdelphij ssl2 = 1; 666296341Sdelphij } else if (strcmp(*argv, "-tls1") == 0) { 667279264Sdelphij#ifdef OPENSSL_NO_TLS1 668296341Sdelphij no_protocol = 1; 669279264Sdelphij#endif 670296341Sdelphij tls1 = 1; 671296341Sdelphij } else if (strcmp(*argv, "-ssl3") == 0) { 672279264Sdelphij#ifdef OPENSSL_NO_SSL3_METHOD 673296341Sdelphij no_protocol = 1; 674279264Sdelphij#endif 675296341Sdelphij ssl3 = 1; 676296341Sdelphij } else if (strncmp(*argv, "-num", 4) == 0) { 677296341Sdelphij if (--argc < 1) 678296341Sdelphij goto bad; 679296341Sdelphij number = atoi(*(++argv)); 680296341Sdelphij if (number == 0) 681296341Sdelphij number = 1; 682296341Sdelphij } else if (strcmp(*argv, "-bytes") == 0) { 683296341Sdelphij if (--argc < 1) 684296341Sdelphij goto bad; 685296341Sdelphij bytes = atol(*(++argv)); 686296341Sdelphij if (bytes == 0L) 687296341Sdelphij bytes = 1L; 688296341Sdelphij i = strlen(argv[0]); 689296341Sdelphij if (argv[0][i - 1] == 'k') 690296341Sdelphij bytes *= 1024L; 691296341Sdelphij if (argv[0][i - 1] == 'm') 692296341Sdelphij bytes *= 1024L * 1024L; 693296341Sdelphij } else if (strcmp(*argv, "-cert") == 0) { 694296341Sdelphij if (--argc < 1) 695296341Sdelphij goto bad; 696296341Sdelphij server_cert = *(++argv); 697296341Sdelphij } else if (strcmp(*argv, "-s_cert") == 0) { 698296341Sdelphij if (--argc < 1) 699296341Sdelphij goto bad; 700296341Sdelphij server_cert = *(++argv); 701296341Sdelphij } else if (strcmp(*argv, "-key") == 0) { 702296341Sdelphij if (--argc < 1) 703296341Sdelphij goto bad; 704296341Sdelphij server_key = *(++argv); 705296341Sdelphij } else if (strcmp(*argv, "-s_key") == 0) { 706296341Sdelphij if (--argc < 1) 707296341Sdelphij goto bad; 708296341Sdelphij server_key = *(++argv); 709296341Sdelphij } else if (strcmp(*argv, "-c_cert") == 0) { 710296341Sdelphij if (--argc < 1) 711296341Sdelphij goto bad; 712296341Sdelphij client_cert = *(++argv); 713296341Sdelphij } else if (strcmp(*argv, "-c_key") == 0) { 714296341Sdelphij if (--argc < 1) 715296341Sdelphij goto bad; 716296341Sdelphij client_key = *(++argv); 717296341Sdelphij } else if (strcmp(*argv, "-cipher") == 0) { 718296341Sdelphij if (--argc < 1) 719296341Sdelphij goto bad; 720296341Sdelphij cipher = *(++argv); 721296341Sdelphij } else if (strcmp(*argv, "-CApath") == 0) { 722296341Sdelphij if (--argc < 1) 723296341Sdelphij goto bad; 724296341Sdelphij CApath = *(++argv); 725296341Sdelphij } else if (strcmp(*argv, "-CAfile") == 0) { 726296341Sdelphij if (--argc < 1) 727296341Sdelphij goto bad; 728296341Sdelphij CAfile = *(++argv); 729296341Sdelphij } else if (strcmp(*argv, "-bio_pair") == 0) { 730296341Sdelphij bio_pair = 1; 731296341Sdelphij } else if (strcmp(*argv, "-f") == 0) { 732296341Sdelphij force = 1; 733296341Sdelphij } else if (strcmp(*argv, "-time") == 0) { 734296341Sdelphij print_time = 1; 735296341Sdelphij } else if (strcmp(*argv, "-zlib") == 0) { 736296341Sdelphij comp = COMP_ZLIB; 737296341Sdelphij } else if (strcmp(*argv, "-rle") == 0) { 738296341Sdelphij comp = COMP_RLE; 739296341Sdelphij } else if (strcmp(*argv, "-named_curve") == 0) { 740296341Sdelphij if (--argc < 1) 741296341Sdelphij goto bad; 742296341Sdelphij#ifndef OPENSSL_NO_ECDH 743296341Sdelphij named_curve = *(++argv); 744160814Ssimon#else 745296341Sdelphij fprintf(stderr, 746296341Sdelphij "ignoring -named_curve, since I'm compiled without ECDH\n"); 747296341Sdelphij ++argv; 748160814Ssimon#endif 749296341Sdelphij } else if (strcmp(*argv, "-app_verify") == 0) { 750296341Sdelphij app_verify_arg.app_verify = 1; 751296341Sdelphij } else if (strcmp(*argv, "-proxy") == 0) { 752296341Sdelphij app_verify_arg.allow_proxy_certs = 1; 753296341Sdelphij } else if (strcmp(*argv, "-test_cipherlist") == 0) { 754296341Sdelphij test_cipherlist = 1; 755296341Sdelphij } else { 756296341Sdelphij fprintf(stderr, "unknown option %s\n", *argv); 757296341Sdelphij badop = 1; 758296341Sdelphij break; 759296341Sdelphij } 760296341Sdelphij argc--; 761296341Sdelphij argv++; 762296341Sdelphij } 763296341Sdelphij if (badop) { 764296341Sdelphij bad: 765296341Sdelphij sv_usage(); 766296341Sdelphij goto end; 767296341Sdelphij } 76855714Skris 769296341Sdelphij /* 770296341Sdelphij * test_cipherlist prevails over protocol switch: we test the cipherlist 771296341Sdelphij * for all enabled protocols. 772296341Sdelphij */ 773296341Sdelphij if (test_cipherlist == 1) { 774296341Sdelphij /* 775296341Sdelphij * ensure that the cipher list are correctly sorted and exit 776296341Sdelphij */ 777296341Sdelphij fprintf(stdout, "Testing cipherlist order only. Ignoring all " 778296341Sdelphij "other options.\n"); 779296341Sdelphij if (do_test_cipherlist() == 0) 780296341Sdelphij EXIT(1); 781296341Sdelphij ret = 0; 782296341Sdelphij goto end; 783296341Sdelphij } 784142425Snectar 785296341Sdelphij if (ssl2 + ssl3 + tls1 > 1) { 786296341Sdelphij fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should " 787296341Sdelphij "be requested.\n"); 788296341Sdelphij EXIT(1); 789296341Sdelphij } 790279264Sdelphij 791296341Sdelphij /* 792296341Sdelphij * Testing was requested for a compiled-out protocol (e.g. SSLv2). 793296341Sdelphij * Ideally, we would error out, but the generic test wrapper can't know 794296341Sdelphij * when to expect failure. So we do nothing and return success. 795296341Sdelphij */ 796296341Sdelphij if (no_protocol) { 797296341Sdelphij fprintf(stderr, "Testing was requested for a disabled protocol. " 798296341Sdelphij "Skipping tests.\n"); 799296341Sdelphij ret = 0; 800296341Sdelphij goto end; 801296341Sdelphij } 802279264Sdelphij 803296341Sdelphij if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) { 804296341Sdelphij fprintf(stderr, "This case cannot work. Use -f to perform " 805296341Sdelphij "the test anyway (and\n-d to see what happens), " 806296341Sdelphij "or add one of -ssl2, -ssl3, -tls1, -reuse\n" 807296341Sdelphij "to avoid protocol mismatch.\n"); 808296341Sdelphij EXIT(1); 809296341Sdelphij } 810194206Ssimon#ifdef OPENSSL_FIPS 811296341Sdelphij if (fips_mode) { 812296341Sdelphij if (!FIPS_mode_set(1)) { 813296341Sdelphij ERR_load_crypto_strings(); 814296341Sdelphij ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE)); 815296341Sdelphij EXIT(1); 816296341Sdelphij } else 817296341Sdelphij fprintf(stderr, "*** IN FIPS MODE ***\n"); 818296341Sdelphij } 819194206Ssimon#endif 820194206Ssimon 821296341Sdelphij if (print_time) { 822296341Sdelphij if (!bio_pair) { 823296341Sdelphij fprintf(stderr, "Using BIO pair (-bio_pair)\n"); 824296341Sdelphij bio_pair = 1; 825296341Sdelphij } 826296341Sdelphij if (number < 50 && !force) 827296341Sdelphij fprintf(stderr, 828296341Sdelphij "Warning: For accurate timings, use more connections (e.g. -num 1000)\n"); 829296341Sdelphij } 83059191Skris 831296341Sdelphij/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */ 83255714Skris 833296341Sdelphij SSL_library_init(); 834296341Sdelphij SSL_load_error_strings(); 83555714Skris 836160814Ssimon#ifndef OPENSSL_NO_COMP 837296341Sdelphij if (comp == COMP_ZLIB) 838296341Sdelphij cm = COMP_zlib(); 839296341Sdelphij if (comp == COMP_RLE) 840296341Sdelphij cm = COMP_rle(); 841296341Sdelphij if (cm != NULL) { 842296341Sdelphij if (cm->type != NID_undef) { 843296341Sdelphij if (SSL_COMP_add_compression_method(comp, cm) != 0) { 844296341Sdelphij fprintf(stderr, "Failed to add compression method\n"); 845296341Sdelphij ERR_print_errors_fp(stderr); 846296341Sdelphij } 847296341Sdelphij } else { 848296341Sdelphij fprintf(stderr, 849296341Sdelphij "Warning: %s compression not supported\n", 850296341Sdelphij (comp == COMP_RLE ? "rle" : 851296341Sdelphij (comp == COMP_ZLIB ? "zlib" : "unknown"))); 852296341Sdelphij ERR_print_errors_fp(stderr); 853296341Sdelphij } 854296341Sdelphij } 855296341Sdelphij ssl_comp_methods = SSL_COMP_get_compression_methods(); 856296341Sdelphij fprintf(stderr, "Available compression methods:\n"); 857296341Sdelphij { 858296341Sdelphij int j, n = sk_SSL_COMP_num(ssl_comp_methods); 859296341Sdelphij if (n == 0) 860296341Sdelphij fprintf(stderr, " NONE\n"); 861296341Sdelphij else 862296341Sdelphij for (j = 0; j < n; j++) { 863296341Sdelphij SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j); 864296341Sdelphij fprintf(stderr, " %d: %s\n", c->id, c->name); 865296341Sdelphij } 866296341Sdelphij } 867160814Ssimon#endif 868109998Smarkm 869296341Sdelphij /* 870296341Sdelphij * At this point, ssl2/ssl3/tls1 is only set if the protocol is 871296341Sdelphij * available. (Otherwise we exit early.) However the compiler doesn't 872296341Sdelphij * know this, so we ifdef. 873296341Sdelphij */ 874279264Sdelphij#ifndef OPENSSL_NO_SSL2 875296341Sdelphij if (ssl2) 876296341Sdelphij meth = SSLv2_method(); 877296341Sdelphij else 878279264Sdelphij#endif 879279264Sdelphij#ifndef OPENSSL_NO_SSL3 880296341Sdelphij if (ssl3) 881296341Sdelphij meth = SSLv3_method(); 882296341Sdelphij else 883279264Sdelphij#endif 884279264Sdelphij#ifndef OPENSSL_NO_TLS1 885296341Sdelphij if (tls1) 886296341Sdelphij meth = TLSv1_method(); 887296341Sdelphij else 88855714Skris#endif 889296341Sdelphij meth = SSLv23_method(); 89055714Skris 891296341Sdelphij c_ctx = SSL_CTX_new(meth); 892296341Sdelphij s_ctx = SSL_CTX_new(meth); 893296341Sdelphij if ((c_ctx == NULL) || (s_ctx == NULL)) { 894296341Sdelphij ERR_print_errors(bio_err); 895296341Sdelphij goto end; 896296341Sdelphij } 89755714Skris 898296341Sdelphij if (cipher != NULL) { 899296341Sdelphij SSL_CTX_set_cipher_list(c_ctx, cipher); 900296341Sdelphij SSL_CTX_set_cipher_list(s_ctx, cipher); 901296341Sdelphij } 902109998Smarkm#ifndef OPENSSL_NO_DH 903296341Sdelphij if (!no_dhe) { 904296341Sdelphij if (dhe1024dsa) { 905296341Sdelphij /* 906296341Sdelphij * use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks 907296341Sdelphij */ 908296341Sdelphij SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); 909296341Sdelphij dh = get_dh1024dsa(); 910296341Sdelphij } else if (dhe512) 911296341Sdelphij dh = get_dh512(); 912296341Sdelphij else 913296341Sdelphij dh = get_dh1024(); 914296341Sdelphij SSL_CTX_set_tmp_dh(s_ctx, dh); 915296341Sdelphij DH_free(dh); 916296341Sdelphij } 91759191Skris#else 918296341Sdelphij (void)no_dhe; 91955714Skris#endif 92055714Skris 921160814Ssimon#ifndef OPENSSL_NO_ECDH 922296341Sdelphij if (!no_ecdhe) { 923296341Sdelphij int nid; 924160814Ssimon 925296341Sdelphij if (named_curve != NULL) { 926296341Sdelphij nid = OBJ_sn2nid(named_curve); 927296341Sdelphij if (nid == 0) { 928296341Sdelphij BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); 929296341Sdelphij goto end; 930296341Sdelphij } 931296341Sdelphij } else 932296341Sdelphij# ifdef OPENSSL_NO_EC2M 933296341Sdelphij nid = NID_X9_62_prime256v1; 934296341Sdelphij# else 935296341Sdelphij nid = NID_sect163r2; 936296341Sdelphij# endif 937160814Ssimon 938296341Sdelphij ecdh = EC_KEY_new_by_curve_name(nid); 939296341Sdelphij if (ecdh == NULL) { 940296341Sdelphij BIO_printf(bio_err, "unable to create curve\n"); 941296341Sdelphij goto end; 942296341Sdelphij } 943160814Ssimon 944296341Sdelphij SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); 945296341Sdelphij SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); 946296341Sdelphij EC_KEY_free(ecdh); 947296341Sdelphij } 948160814Ssimon#else 949296341Sdelphij (void)no_ecdhe; 950160814Ssimon#endif 951160814Ssimon 952109998Smarkm#ifndef OPENSSL_NO_RSA 953296341Sdelphij SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb); 95455714Skris#endif 95555714Skris 956238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 957296341Sdelphij SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb); 958296341Sdelphij SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb); 959296341Sdelphij /* or &co2 or NULL */ 960296341Sdelphij SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); 961296341Sdelphij /* or &so2 or NULL */ 962296341Sdelphij SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); 963238405Sjkim#endif 964238405Sjkim 965296341Sdelphij if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, SSL_FILETYPE_PEM)) { 966296341Sdelphij ERR_print_errors(bio_err); 967296341Sdelphij } else if (!SSL_CTX_use_PrivateKey_file(s_ctx, 968296341Sdelphij (server_key ? server_key : 969296341Sdelphij server_cert), 970296341Sdelphij SSL_FILETYPE_PEM)) { 971296341Sdelphij ERR_print_errors(bio_err); 972296341Sdelphij goto end; 973296341Sdelphij } 97455714Skris 975296341Sdelphij if (client_auth) { 976296341Sdelphij SSL_CTX_use_certificate_file(c_ctx, client_cert, SSL_FILETYPE_PEM); 977296341Sdelphij SSL_CTX_use_PrivateKey_file(c_ctx, 978296341Sdelphij (client_key ? client_key : client_cert), 979296341Sdelphij SSL_FILETYPE_PEM); 980296341Sdelphij } 98155714Skris 982296341Sdelphij if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || 983296341Sdelphij (!SSL_CTX_set_default_verify_paths(s_ctx)) || 984296341Sdelphij (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || 985296341Sdelphij (!SSL_CTX_set_default_verify_paths(c_ctx))) { 986296341Sdelphij /* fprintf(stderr,"SSL_load_verify_locations\n"); */ 987296341Sdelphij ERR_print_errors(bio_err); 988296341Sdelphij /* goto end; */ 989296341Sdelphij } 99055714Skris 991296341Sdelphij if (client_auth) { 992296341Sdelphij BIO_printf(bio_err, "client authentication\n"); 993296341Sdelphij SSL_CTX_set_verify(s_ctx, 994296341Sdelphij SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 995296341Sdelphij verify_callback); 996296341Sdelphij SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, 997296341Sdelphij &app_verify_arg); 998296341Sdelphij } 999296341Sdelphij if (server_auth) { 1000296341Sdelphij BIO_printf(bio_err, "server authentication\n"); 1001296341Sdelphij SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); 1002296341Sdelphij SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, 1003296341Sdelphij &app_verify_arg); 1004296341Sdelphij } 100555714Skris 1006296341Sdelphij { 1007296341Sdelphij int session_id_context = 0; 1008296341Sdelphij SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, 1009296341Sdelphij sizeof session_id_context); 1010296341Sdelphij } 1011296341Sdelphij 1012296341Sdelphij /* Use PSK only if PSK key is given */ 1013296341Sdelphij if (psk_key != NULL) { 1014296341Sdelphij /* 1015296341Sdelphij * no_psk is used to avoid putting psk command to openssl tool 1016296341Sdelphij */ 1017296341Sdelphij if (no_psk) { 1018296341Sdelphij /* 1019296341Sdelphij * if PSK is not compiled in and psk key is given, do nothing and 1020296341Sdelphij * exit successfully 1021296341Sdelphij */ 1022296341Sdelphij ret = 0; 1023296341Sdelphij goto end; 1024296341Sdelphij } 1025238405Sjkim#ifndef OPENSSL_NO_PSK 1026296341Sdelphij SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback); 1027296341Sdelphij SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback); 1028296341Sdelphij if (debug) 1029296341Sdelphij BIO_printf(bio_err, "setting PSK identity hint to s_ctx\n"); 1030296341Sdelphij if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint")) { 1031296341Sdelphij BIO_printf(bio_err, "error setting PSK identity hint to s_ctx\n"); 1032296341Sdelphij ERR_print_errors(bio_err); 1033296341Sdelphij goto end; 1034296341Sdelphij } 1035238405Sjkim#endif 1036296341Sdelphij } 1037238405Sjkim#ifndef OPENSSL_NO_SRP 1038296341Sdelphij if (srp_client_arg.srplogin) { 1039296341Sdelphij if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin)) { 1040296341Sdelphij BIO_printf(bio_err, "Unable to set SRP username\n"); 1041296341Sdelphij goto end; 1042296341Sdelphij } 1043296341Sdelphij SSL_CTX_set_srp_cb_arg(c_ctx, &srp_client_arg); 1044296341Sdelphij SSL_CTX_set_srp_client_pwd_callback(c_ctx, 1045296341Sdelphij ssl_give_srp_client_pwd_cb); 1046296341Sdelphij /* 1047296341Sdelphij * SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength); 1048296341Sdelphij */ 1049296341Sdelphij } 1050238405Sjkim 1051296341Sdelphij if (srp_server_arg.expected_user != NULL) { 1052296341Sdelphij SSL_CTX_set_verify(s_ctx, SSL_VERIFY_NONE, verify_callback); 1053296341Sdelphij SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); 1054296341Sdelphij SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); 1055296341Sdelphij } 1056238405Sjkim#endif 1057238405Sjkim 1058296341Sdelphij c_ssl = SSL_new(c_ctx); 1059296341Sdelphij s_ssl = SSL_new(s_ctx); 106055714Skris 1061109998Smarkm#ifndef OPENSSL_NO_KRB5 1062296341Sdelphij if (c_ssl && c_ssl->kssl_ctx) { 1063296341Sdelphij char localhost[MAXHOSTNAMELEN + 2]; 1064109998Smarkm 1065296341Sdelphij if (gethostname(localhost, sizeof localhost - 1) == 0) { 1066296341Sdelphij localhost[sizeof localhost - 1] = '\0'; 1067296341Sdelphij if (strlen(localhost) == sizeof localhost - 1) { 1068296341Sdelphij BIO_printf(bio_err, "localhost name too long\n"); 1069296341Sdelphij goto end; 1070296341Sdelphij } 1071296341Sdelphij kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost); 1072296341Sdelphij } 1073296341Sdelphij } 1074296341Sdelphij#endif /* OPENSSL_NO_KRB5 */ 1075109998Smarkm 1076296341Sdelphij for (i = 0; i < number; i++) { 1077296341Sdelphij if (!reuse) 1078296341Sdelphij SSL_set_session(c_ssl, NULL); 1079296341Sdelphij if (bio_pair) 1080296341Sdelphij ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time); 1081296341Sdelphij else 1082296341Sdelphij ret = doit(s_ssl, c_ssl, bytes); 1083296341Sdelphij } 108455714Skris 1085296341Sdelphij if (!verbose) { 1086296341Sdelphij print_details(c_ssl, ""); 1087296341Sdelphij } 1088296341Sdelphij if ((number > 1) || (bytes > 1L)) 1089296341Sdelphij BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", number, 1090296341Sdelphij bytes); 1091296341Sdelphij if (print_time) { 109259191Skris#ifdef CLOCKS_PER_SEC 1093296341Sdelphij /* 1094296341Sdelphij * "To determine the time in seconds, the value returned by the clock 1095296341Sdelphij * function should be divided by the value of the macro 1096296341Sdelphij * CLOCKS_PER_SEC." -- ISO/IEC 9899 1097296341Sdelphij */ 1098296341Sdelphij BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n" 1099296341Sdelphij "Approximate total client time: %6.2f s\n", 1100296341Sdelphij (double)s_time / CLOCKS_PER_SEC, 1101296341Sdelphij (double)c_time / CLOCKS_PER_SEC); 110259191Skris#else 1103296341Sdelphij /* 1104296341Sdelphij * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on 1105296341Sdelphij * NeXTstep/OpenStep 1106296341Sdelphij */ 1107296341Sdelphij BIO_printf(bio_stdout, 1108296341Sdelphij "Approximate total server time: %6.2f units\n" 1109296341Sdelphij "Approximate total client time: %6.2f units\n", 1110296341Sdelphij (double)s_time, (double)c_time); 111159191Skris#endif 1112296341Sdelphij } 111355714Skris 1114296341Sdelphij SSL_free(s_ssl); 1115296341Sdelphij SSL_free(c_ssl); 111655714Skris 1117296341Sdelphij end: 1118296341Sdelphij if (s_ctx != NULL) 1119296341Sdelphij SSL_CTX_free(s_ctx); 1120296341Sdelphij if (c_ctx != NULL) 1121296341Sdelphij SSL_CTX_free(c_ctx); 112255714Skris 1123296341Sdelphij if (bio_stdout != NULL) 1124296341Sdelphij BIO_free(bio_stdout); 112555714Skris 1126109998Smarkm#ifndef OPENSSL_NO_RSA 1127296341Sdelphij free_tmp_rsa(); 112868651Skris#endif 1129111147Snectar#ifndef OPENSSL_NO_ENGINE 1130296341Sdelphij ENGINE_cleanup(); 1131111147Snectar#endif 1132296341Sdelphij CRYPTO_cleanup_all_ex_data(); 1133296341Sdelphij ERR_free_strings(); 1134296341Sdelphij ERR_remove_thread_state(NULL); 1135296341Sdelphij EVP_cleanup(); 1136296341Sdelphij CRYPTO_mem_leaks(bio_err); 1137296341Sdelphij if (bio_err != NULL) 1138296341Sdelphij BIO_free(bio_err); 1139296341Sdelphij EXIT(ret); 1140296341Sdelphij return ret; 1141296341Sdelphij} 114255714Skris 114359191Skrisint doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, 1144296341Sdelphij clock_t *s_time, clock_t *c_time) 1145296341Sdelphij{ 1146296341Sdelphij long cw_num = count, cr_num = count, sw_num = count, sr_num = count; 1147296341Sdelphij BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; 1148296341Sdelphij BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL; 1149296341Sdelphij int ret = 1; 115055714Skris 1151296341Sdelphij size_t bufsiz = 256; /* small buffer for testing */ 115255714Skris 1153296341Sdelphij if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz)) 1154296341Sdelphij goto err; 1155296341Sdelphij if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz)) 1156296341Sdelphij goto err; 115755714Skris 1158296341Sdelphij s_ssl_bio = BIO_new(BIO_f_ssl()); 1159296341Sdelphij if (!s_ssl_bio) 1160296341Sdelphij goto err; 116155714Skris 1162296341Sdelphij c_ssl_bio = BIO_new(BIO_f_ssl()); 1163296341Sdelphij if (!c_ssl_bio) 1164296341Sdelphij goto err; 116555714Skris 1166296341Sdelphij SSL_set_connect_state(c_ssl); 1167296341Sdelphij SSL_set_bio(c_ssl, client, client); 1168296341Sdelphij (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE); 116955714Skris 1170296341Sdelphij SSL_set_accept_state(s_ssl); 1171296341Sdelphij SSL_set_bio(s_ssl, server, server); 1172296341Sdelphij (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE); 117355714Skris 1174296341Sdelphij do { 1175296341Sdelphij /*- 1176296341Sdelphij * c_ssl_bio: SSL filter BIO 1177296341Sdelphij * 1178296341Sdelphij * client: pseudo-I/O for SSL library 1179296341Sdelphij * 1180296341Sdelphij * client_io: client's SSL communication; usually to be 1181296341Sdelphij * relayed over some I/O facility, but in this 1182296341Sdelphij * test program, we're the server, too: 1183296341Sdelphij * 1184296341Sdelphij * server_io: server's SSL communication 1185296341Sdelphij * 1186296341Sdelphij * server: pseudo-I/O for SSL library 1187296341Sdelphij * 1188296341Sdelphij * s_ssl_bio: SSL filter BIO 1189296341Sdelphij * 1190296341Sdelphij * The client and the server each employ a "BIO pair": 1191296341Sdelphij * client + client_io, server + server_io. 1192296341Sdelphij * BIO pairs are symmetric. A BIO pair behaves similar 1193296341Sdelphij * to a non-blocking socketpair (but both endpoints must 1194296341Sdelphij * be handled by the same thread). 1195296341Sdelphij * [Here we could connect client and server to the ends 1196296341Sdelphij * of a single BIO pair, but then this code would be less 1197296341Sdelphij * suitable as an example for BIO pairs in general.] 1198296341Sdelphij * 1199296341Sdelphij * Useful functions for querying the state of BIO pair endpoints: 1200296341Sdelphij * 1201296341Sdelphij * BIO_ctrl_pending(bio) number of bytes we can read now 1202296341Sdelphij * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil 1203296341Sdelphij * other side's read attempt 1204296341Sdelphij * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now 1205296341Sdelphij * 1206296341Sdelphij * ..._read_request is never more than ..._write_guarantee; 1207296341Sdelphij * it depends on the application which one you should use. 1208296341Sdelphij */ 120955714Skris 1210296341Sdelphij /* 1211296341Sdelphij * We have non-blocking behaviour throughout this test program, but 1212296341Sdelphij * can be sure that there is *some* progress in each iteration; so we 1213296341Sdelphij * don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE -- 1214296341Sdelphij * we just try everything in each iteration 1215296341Sdelphij */ 1216109998Smarkm 1217296341Sdelphij { 1218296341Sdelphij /* CLIENT */ 121955714Skris 1220296341Sdelphij MS_STATIC char cbuf[1024 * 8]; 1221296341Sdelphij int i, r; 1222296341Sdelphij clock_t c_clock = clock(); 122355714Skris 1224296341Sdelphij memset(cbuf, 0, sizeof(cbuf)); 122555714Skris 1226296341Sdelphij if (debug) 1227296341Sdelphij if (SSL_in_init(c_ssl)) 1228296341Sdelphij printf("client waiting in SSL_connect - %s\n", 1229296341Sdelphij SSL_state_string_long(c_ssl)); 123059191Skris 1231296341Sdelphij if (cw_num > 0) { 1232296341Sdelphij /* Write to server. */ 123355714Skris 1234296341Sdelphij if (cw_num > (long)sizeof cbuf) 1235296341Sdelphij i = sizeof cbuf; 1236296341Sdelphij else 1237296341Sdelphij i = (int)cw_num; 1238296341Sdelphij r = BIO_write(c_ssl_bio, cbuf, i); 1239296341Sdelphij if (r < 0) { 1240296341Sdelphij if (!BIO_should_retry(c_ssl_bio)) { 1241296341Sdelphij fprintf(stderr, "ERROR in CLIENT\n"); 1242296341Sdelphij goto err; 1243296341Sdelphij } 1244296341Sdelphij /* 1245296341Sdelphij * BIO_should_retry(...) can just be ignored here. The 1246296341Sdelphij * library expects us to call BIO_write with the same 1247296341Sdelphij * arguments again, and that's what we will do in the 1248296341Sdelphij * next iteration. 1249296341Sdelphij */ 1250296341Sdelphij } else if (r == 0) { 1251296341Sdelphij fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1252296341Sdelphij goto err; 1253296341Sdelphij } else { 1254296341Sdelphij if (debug) 1255296341Sdelphij printf("client wrote %d\n", r); 1256296341Sdelphij cw_num -= r; 1257296341Sdelphij } 1258296341Sdelphij } 125955714Skris 1260296341Sdelphij if (cr_num > 0) { 1261296341Sdelphij /* Read from server. */ 1262109998Smarkm 1263296341Sdelphij r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf)); 1264296341Sdelphij if (r < 0) { 1265296341Sdelphij if (!BIO_should_retry(c_ssl_bio)) { 1266296341Sdelphij fprintf(stderr, "ERROR in CLIENT\n"); 1267296341Sdelphij goto err; 1268296341Sdelphij } 1269296341Sdelphij /* 1270296341Sdelphij * Again, "BIO_should_retry" can be ignored. 1271296341Sdelphij */ 1272296341Sdelphij } else if (r == 0) { 1273296341Sdelphij fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1274296341Sdelphij goto err; 1275296341Sdelphij } else { 1276296341Sdelphij if (debug) 1277296341Sdelphij printf("client read %d\n", r); 1278296341Sdelphij cr_num -= r; 1279296341Sdelphij } 1280296341Sdelphij } 128155714Skris 1282296341Sdelphij /* 1283296341Sdelphij * c_time and s_time increments will typically be very small 1284296341Sdelphij * (depending on machine speed and clock tick intervals), but 1285296341Sdelphij * sampling over a large number of connections should result in 1286296341Sdelphij * fairly accurate figures. We cannot guarantee a lot, however 1287296341Sdelphij * -- if each connection lasts for exactly one clock tick, it 1288296341Sdelphij * will be counted only for the client or only for the server or 1289296341Sdelphij * even not at all. 1290296341Sdelphij */ 1291296341Sdelphij *c_time += (clock() - c_clock); 1292296341Sdelphij } 129355714Skris 1294296341Sdelphij { 1295296341Sdelphij /* SERVER */ 129655714Skris 1297296341Sdelphij MS_STATIC char sbuf[1024 * 8]; 1298296341Sdelphij int i, r; 1299296341Sdelphij clock_t s_clock = clock(); 130059191Skris 1301296341Sdelphij memset(sbuf, 0, sizeof(sbuf)); 130255714Skris 1303296341Sdelphij if (debug) 1304296341Sdelphij if (SSL_in_init(s_ssl)) 1305296341Sdelphij printf("server waiting in SSL_accept - %s\n", 1306296341Sdelphij SSL_state_string_long(s_ssl)); 130755714Skris 1308296341Sdelphij if (sw_num > 0) { 1309296341Sdelphij /* Write to client. */ 131059191Skris 1311296341Sdelphij if (sw_num > (long)sizeof sbuf) 1312296341Sdelphij i = sizeof sbuf; 1313296341Sdelphij else 1314296341Sdelphij i = (int)sw_num; 1315296341Sdelphij r = BIO_write(s_ssl_bio, sbuf, i); 1316296341Sdelphij if (r < 0) { 1317296341Sdelphij if (!BIO_should_retry(s_ssl_bio)) { 1318296341Sdelphij fprintf(stderr, "ERROR in SERVER\n"); 1319296341Sdelphij goto err; 1320296341Sdelphij } 1321296341Sdelphij /* Ignore "BIO_should_retry". */ 1322296341Sdelphij } else if (r == 0) { 1323296341Sdelphij fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 1324296341Sdelphij goto err; 1325296341Sdelphij } else { 1326296341Sdelphij if (debug) 1327296341Sdelphij printf("server wrote %d\n", r); 1328296341Sdelphij sw_num -= r; 1329296341Sdelphij } 1330296341Sdelphij } 133159191Skris 1332296341Sdelphij if (sr_num > 0) { 1333296341Sdelphij /* Read from client. */ 133455714Skris 1335296341Sdelphij r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf)); 1336296341Sdelphij if (r < 0) { 1337296341Sdelphij if (!BIO_should_retry(s_ssl_bio)) { 1338296341Sdelphij fprintf(stderr, "ERROR in SERVER\n"); 1339296341Sdelphij goto err; 1340296341Sdelphij } 1341296341Sdelphij /* blah, blah */ 1342296341Sdelphij } else if (r == 0) { 1343296341Sdelphij fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 1344296341Sdelphij goto err; 1345296341Sdelphij } else { 1346296341Sdelphij if (debug) 1347296341Sdelphij printf("server read %d\n", r); 1348296341Sdelphij sr_num -= r; 1349296341Sdelphij } 1350296341Sdelphij } 135155714Skris 1352296341Sdelphij *s_time += (clock() - s_clock); 1353296341Sdelphij } 135455714Skris 1355296341Sdelphij { 1356296341Sdelphij /* "I/O" BETWEEN CLIENT AND SERVER. */ 135759191Skris 1358296341Sdelphij size_t r1, r2; 1359296341Sdelphij BIO *io1 = server_io, *io2 = client_io; 1360296341Sdelphij /* 1361296341Sdelphij * we use the non-copying interface for io1 and the standard 1362296341Sdelphij * BIO_write/BIO_read interface for io2 1363296341Sdelphij */ 136455714Skris 1365296341Sdelphij static int prev_progress = 1; 1366296341Sdelphij int progress = 0; 136755714Skris 1368296341Sdelphij /* io1 to io2 */ 1369296341Sdelphij do { 1370296341Sdelphij size_t num; 1371296341Sdelphij int r; 137255714Skris 1373296341Sdelphij r1 = BIO_ctrl_pending(io1); 1374296341Sdelphij r2 = BIO_ctrl_get_write_guarantee(io2); 1375296341Sdelphij 1376296341Sdelphij num = r1; 1377296341Sdelphij if (r2 < num) 1378296341Sdelphij num = r2; 1379296341Sdelphij if (num) { 1380296341Sdelphij char *dataptr; 1381296341Sdelphij 1382296341Sdelphij if (INT_MAX < num) /* yeah, right */ 1383296341Sdelphij num = INT_MAX; 1384296341Sdelphij 1385296341Sdelphij r = BIO_nread(io1, &dataptr, (int)num); 1386296341Sdelphij assert(r > 0); 1387296341Sdelphij assert(r <= (int)num); 1388296341Sdelphij /* 1389296341Sdelphij * possibly r < num (non-contiguous data) 1390296341Sdelphij */ 1391296341Sdelphij num = r; 1392296341Sdelphij r = BIO_write(io2, dataptr, (int)num); 1393296341Sdelphij if (r != (int)num) { /* can't happen */ 1394296341Sdelphij fprintf(stderr, "ERROR: BIO_write could not write " 1395296341Sdelphij "BIO_ctrl_get_write_guarantee() bytes"); 1396296341Sdelphij goto err; 1397296341Sdelphij } 1398296341Sdelphij progress = 1; 1399296341Sdelphij 1400296341Sdelphij if (debug) 1401296341Sdelphij printf((io1 == client_io) ? 1402296341Sdelphij "C->S relaying: %d bytes\n" : 1403296341Sdelphij "S->C relaying: %d bytes\n", (int)num); 1404296341Sdelphij } 1405296341Sdelphij } 1406296341Sdelphij while (r1 && r2); 1407296341Sdelphij 1408296341Sdelphij /* io2 to io1 */ 1409296341Sdelphij { 1410296341Sdelphij size_t num; 1411296341Sdelphij int r; 1412296341Sdelphij 1413296341Sdelphij r1 = BIO_ctrl_pending(io2); 1414296341Sdelphij r2 = BIO_ctrl_get_read_request(io1); 1415296341Sdelphij /* 1416296341Sdelphij * here we could use ..._get_write_guarantee instead of 1417296341Sdelphij * ..._get_read_request, but by using the latter we test 1418296341Sdelphij * restartability of the SSL implementation more thoroughly 1419296341Sdelphij */ 1420296341Sdelphij num = r1; 1421296341Sdelphij if (r2 < num) 1422296341Sdelphij num = r2; 1423296341Sdelphij if (num) { 1424296341Sdelphij char *dataptr; 1425296341Sdelphij 1426296341Sdelphij if (INT_MAX < num) 1427296341Sdelphij num = INT_MAX; 1428296341Sdelphij 1429296341Sdelphij if (num > 1) 1430296341Sdelphij --num; /* test restartability even more thoroughly */ 1431296341Sdelphij 1432296341Sdelphij r = BIO_nwrite0(io1, &dataptr); 1433296341Sdelphij assert(r > 0); 1434296341Sdelphij if (r < (int)num) 1435296341Sdelphij num = r; 1436296341Sdelphij r = BIO_read(io2, dataptr, (int)num); 1437296341Sdelphij if (r != (int)num) { /* can't happen */ 1438296341Sdelphij fprintf(stderr, "ERROR: BIO_read could not read " 1439296341Sdelphij "BIO_ctrl_pending() bytes"); 1440296341Sdelphij goto err; 1441296341Sdelphij } 1442296341Sdelphij progress = 1; 1443296341Sdelphij r = BIO_nwrite(io1, &dataptr, (int)num); 1444296341Sdelphij if (r != (int)num) { /* can't happen */ 1445296341Sdelphij fprintf(stderr, "ERROR: BIO_nwrite() did not accept " 1446296341Sdelphij "BIO_nwrite0() bytes"); 1447296341Sdelphij goto err; 1448296341Sdelphij } 1449296341Sdelphij 1450296341Sdelphij if (debug) 1451296341Sdelphij printf((io2 == client_io) ? 1452296341Sdelphij "C->S relaying: %d bytes\n" : 1453296341Sdelphij "S->C relaying: %d bytes\n", (int)num); 1454296341Sdelphij } 1455296341Sdelphij } /* no loop, BIO_ctrl_get_read_request now 1456296341Sdelphij * returns 0 anyway */ 1457296341Sdelphij 1458296341Sdelphij if (!progress && !prev_progress) 1459296341Sdelphij if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) { 1460296341Sdelphij fprintf(stderr, "ERROR: got stuck\n"); 1461296341Sdelphij if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0) { 1462296341Sdelphij fprintf(stderr, "This can happen for SSL2 because " 1463296341Sdelphij "CLIENT-FINISHED and SERVER-VERIFY are written \n" 1464296341Sdelphij "concurrently ..."); 1465296341Sdelphij if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0 1466296341Sdelphij && strncmp("2SSV", SSL_state_string(s_ssl), 1467296341Sdelphij 4) == 0) { 1468296341Sdelphij fprintf(stderr, " ok.\n"); 1469296341Sdelphij goto end; 1470296341Sdelphij } 1471296341Sdelphij } 1472296341Sdelphij fprintf(stderr, " ERROR.\n"); 1473296341Sdelphij goto err; 1474296341Sdelphij } 1475296341Sdelphij prev_progress = progress; 1476296341Sdelphij } 1477296341Sdelphij } 1478296341Sdelphij while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); 1479296341Sdelphij 1480296341Sdelphij if (verbose) 1481296341Sdelphij print_details(c_ssl, "DONE via BIO pair: "); 1482296341Sdelphij end: 1483296341Sdelphij ret = 0; 1484296341Sdelphij 148555714Skris err: 1486296341Sdelphij ERR_print_errors(bio_err); 148755714Skris 1488296341Sdelphij if (server) 1489296341Sdelphij BIO_free(server); 1490296341Sdelphij if (server_io) 1491296341Sdelphij BIO_free(server_io); 1492296341Sdelphij if (client) 1493296341Sdelphij BIO_free(client); 1494296341Sdelphij if (client_io) 1495296341Sdelphij BIO_free(client_io); 1496296341Sdelphij if (s_ssl_bio) 1497296341Sdelphij BIO_free(s_ssl_bio); 1498296341Sdelphij if (c_ssl_bio) 1499296341Sdelphij BIO_free(c_ssl_bio); 150055714Skris 1501296341Sdelphij return ret; 1502296341Sdelphij} 150355714Skris 1504296341Sdelphij#define W_READ 1 1505296341Sdelphij#define W_WRITE 2 1506296341Sdelphij#define C_DONE 1 1507296341Sdelphij#define S_DONE 2 150855714Skris 150955714Skrisint doit(SSL *s_ssl, SSL *c_ssl, long count) 1510296341Sdelphij{ 1511296341Sdelphij MS_STATIC char cbuf[1024 * 8], sbuf[1024 * 8]; 1512296341Sdelphij long cw_num = count, cr_num = count; 1513296341Sdelphij long sw_num = count, sr_num = count; 1514296341Sdelphij int ret = 1; 1515296341Sdelphij BIO *c_to_s = NULL; 1516296341Sdelphij BIO *s_to_c = NULL; 1517296341Sdelphij BIO *c_bio = NULL; 1518296341Sdelphij BIO *s_bio = NULL; 1519296341Sdelphij int c_r, c_w, s_r, s_w; 1520296341Sdelphij int i, j; 1521296341Sdelphij int done = 0; 1522296341Sdelphij int c_write, s_write; 1523296341Sdelphij int do_server = 0, do_client = 0; 152455714Skris 1525296341Sdelphij memset(cbuf, 0, sizeof(cbuf)); 1526296341Sdelphij memset(sbuf, 0, sizeof(sbuf)); 1527109998Smarkm 1528296341Sdelphij c_to_s = BIO_new(BIO_s_mem()); 1529296341Sdelphij s_to_c = BIO_new(BIO_s_mem()); 1530296341Sdelphij if ((s_to_c == NULL) || (c_to_s == NULL)) { 1531296341Sdelphij ERR_print_errors(bio_err); 1532296341Sdelphij goto err; 1533296341Sdelphij } 153455714Skris 1535296341Sdelphij c_bio = BIO_new(BIO_f_ssl()); 1536296341Sdelphij s_bio = BIO_new(BIO_f_ssl()); 1537296341Sdelphij if ((c_bio == NULL) || (s_bio == NULL)) { 1538296341Sdelphij ERR_print_errors(bio_err); 1539296341Sdelphij goto err; 1540296341Sdelphij } 154155714Skris 1542296341Sdelphij SSL_set_connect_state(c_ssl); 1543296341Sdelphij SSL_set_bio(c_ssl, s_to_c, c_to_s); 1544296341Sdelphij BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE); 154555714Skris 1546296341Sdelphij SSL_set_accept_state(s_ssl); 1547296341Sdelphij SSL_set_bio(s_ssl, c_to_s, s_to_c); 1548296341Sdelphij BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE); 154955714Skris 1550296341Sdelphij c_r = 0; 1551296341Sdelphij s_r = 1; 1552296341Sdelphij c_w = 1; 1553296341Sdelphij s_w = 0; 1554296341Sdelphij c_write = 1, s_write = 0; 155555714Skris 1556296341Sdelphij /* We can always do writes */ 1557296341Sdelphij for (;;) { 1558296341Sdelphij do_server = 0; 1559296341Sdelphij do_client = 0; 156055714Skris 1561296341Sdelphij i = (int)BIO_pending(s_bio); 1562296341Sdelphij if ((i && s_r) || s_w) 1563296341Sdelphij do_server = 1; 156455714Skris 1565296341Sdelphij i = (int)BIO_pending(c_bio); 1566296341Sdelphij if ((i && c_r) || c_w) 1567296341Sdelphij do_client = 1; 156855714Skris 1569296341Sdelphij if (do_server && debug) { 1570296341Sdelphij if (SSL_in_init(s_ssl)) 1571296341Sdelphij printf("server waiting in SSL_accept - %s\n", 1572296341Sdelphij SSL_state_string_long(s_ssl)); 1573296341Sdelphij/*- 1574296341Sdelphij else if (s_write) 1575296341Sdelphij printf("server:SSL_write()\n"); 1576296341Sdelphij else 1577296341Sdelphij printf("server:SSL_read()\n"); */ 1578296341Sdelphij } 157955714Skris 1580296341Sdelphij if (do_client && debug) { 1581296341Sdelphij if (SSL_in_init(c_ssl)) 1582296341Sdelphij printf("client waiting in SSL_connect - %s\n", 1583296341Sdelphij SSL_state_string_long(c_ssl)); 1584296341Sdelphij/*- 1585296341Sdelphij else if (c_write) 1586296341Sdelphij printf("client:SSL_write()\n"); 1587296341Sdelphij else 1588296341Sdelphij printf("client:SSL_read()\n"); */ 1589296341Sdelphij } 159055714Skris 1591296341Sdelphij if (!do_client && !do_server) { 1592296341Sdelphij fprintf(stdout, "ERROR IN STARTUP\n"); 1593296341Sdelphij ERR_print_errors(bio_err); 1594296341Sdelphij goto err; 1595296341Sdelphij } 1596296341Sdelphij if (do_client && !(done & C_DONE)) { 1597296341Sdelphij if (c_write) { 1598296341Sdelphij j = (cw_num > (long)sizeof(cbuf)) ? 1599296341Sdelphij (int)sizeof(cbuf) : (int)cw_num; 1600296341Sdelphij i = BIO_write(c_bio, cbuf, j); 1601296341Sdelphij if (i < 0) { 1602296341Sdelphij c_r = 0; 1603296341Sdelphij c_w = 0; 1604296341Sdelphij if (BIO_should_retry(c_bio)) { 1605296341Sdelphij if (BIO_should_read(c_bio)) 1606296341Sdelphij c_r = 1; 1607296341Sdelphij if (BIO_should_write(c_bio)) 1608296341Sdelphij c_w = 1; 1609296341Sdelphij } else { 1610296341Sdelphij fprintf(stderr, "ERROR in CLIENT\n"); 1611296341Sdelphij ERR_print_errors(bio_err); 1612296341Sdelphij goto err; 1613296341Sdelphij } 1614296341Sdelphij } else if (i == 0) { 1615296341Sdelphij fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1616296341Sdelphij goto err; 1617296341Sdelphij } else { 1618296341Sdelphij if (debug) 1619296341Sdelphij printf("client wrote %d\n", i); 1620296341Sdelphij /* ok */ 1621296341Sdelphij s_r = 1; 1622296341Sdelphij c_write = 0; 1623296341Sdelphij cw_num -= i; 1624296341Sdelphij } 1625296341Sdelphij } else { 1626296341Sdelphij i = BIO_read(c_bio, cbuf, sizeof(cbuf)); 1627296341Sdelphij if (i < 0) { 1628296341Sdelphij c_r = 0; 1629296341Sdelphij c_w = 0; 1630296341Sdelphij if (BIO_should_retry(c_bio)) { 1631296341Sdelphij if (BIO_should_read(c_bio)) 1632296341Sdelphij c_r = 1; 1633296341Sdelphij if (BIO_should_write(c_bio)) 1634296341Sdelphij c_w = 1; 1635296341Sdelphij } else { 1636296341Sdelphij fprintf(stderr, "ERROR in CLIENT\n"); 1637296341Sdelphij ERR_print_errors(bio_err); 1638296341Sdelphij goto err; 1639296341Sdelphij } 1640296341Sdelphij } else if (i == 0) { 1641296341Sdelphij fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1642296341Sdelphij goto err; 1643296341Sdelphij } else { 1644296341Sdelphij if (debug) 1645296341Sdelphij printf("client read %d\n", i); 1646296341Sdelphij cr_num -= i; 1647296341Sdelphij if (sw_num > 0) { 1648296341Sdelphij s_write = 1; 1649296341Sdelphij s_w = 1; 1650296341Sdelphij } 1651296341Sdelphij if (cr_num <= 0) { 1652296341Sdelphij s_write = 1; 1653296341Sdelphij s_w = 1; 1654296341Sdelphij done = S_DONE | C_DONE; 1655296341Sdelphij } 1656296341Sdelphij } 1657296341Sdelphij } 1658296341Sdelphij } 165955714Skris 1660296341Sdelphij if (do_server && !(done & S_DONE)) { 1661296341Sdelphij if (!s_write) { 1662296341Sdelphij i = BIO_read(s_bio, sbuf, sizeof(cbuf)); 1663296341Sdelphij if (i < 0) { 1664296341Sdelphij s_r = 0; 1665296341Sdelphij s_w = 0; 1666296341Sdelphij if (BIO_should_retry(s_bio)) { 1667296341Sdelphij if (BIO_should_read(s_bio)) 1668296341Sdelphij s_r = 1; 1669296341Sdelphij if (BIO_should_write(s_bio)) 1670296341Sdelphij s_w = 1; 1671296341Sdelphij } else { 1672296341Sdelphij fprintf(stderr, "ERROR in SERVER\n"); 1673296341Sdelphij ERR_print_errors(bio_err); 1674296341Sdelphij goto err; 1675296341Sdelphij } 1676296341Sdelphij } else if (i == 0) { 1677296341Sdelphij ERR_print_errors(bio_err); 1678296341Sdelphij fprintf(stderr, 1679296341Sdelphij "SSL SERVER STARTUP FAILED in SSL_read\n"); 1680296341Sdelphij goto err; 1681296341Sdelphij } else { 1682296341Sdelphij if (debug) 1683296341Sdelphij printf("server read %d\n", i); 1684296341Sdelphij sr_num -= i; 1685296341Sdelphij if (cw_num > 0) { 1686296341Sdelphij c_write = 1; 1687296341Sdelphij c_w = 1; 1688296341Sdelphij } 1689296341Sdelphij if (sr_num <= 0) { 1690296341Sdelphij s_write = 1; 1691296341Sdelphij s_w = 1; 1692296341Sdelphij c_write = 0; 1693296341Sdelphij } 1694296341Sdelphij } 1695296341Sdelphij } else { 1696296341Sdelphij j = (sw_num > (long)sizeof(sbuf)) ? 1697296341Sdelphij (int)sizeof(sbuf) : (int)sw_num; 1698296341Sdelphij i = BIO_write(s_bio, sbuf, j); 1699296341Sdelphij if (i < 0) { 1700296341Sdelphij s_r = 0; 1701296341Sdelphij s_w = 0; 1702296341Sdelphij if (BIO_should_retry(s_bio)) { 1703296341Sdelphij if (BIO_should_read(s_bio)) 1704296341Sdelphij s_r = 1; 1705296341Sdelphij if (BIO_should_write(s_bio)) 1706296341Sdelphij s_w = 1; 1707296341Sdelphij } else { 1708296341Sdelphij fprintf(stderr, "ERROR in SERVER\n"); 1709296341Sdelphij ERR_print_errors(bio_err); 1710296341Sdelphij goto err; 1711296341Sdelphij } 1712296341Sdelphij } else if (i == 0) { 1713296341Sdelphij ERR_print_errors(bio_err); 1714296341Sdelphij fprintf(stderr, 1715296341Sdelphij "SSL SERVER STARTUP FAILED in SSL_write\n"); 1716296341Sdelphij goto err; 1717296341Sdelphij } else { 1718296341Sdelphij if (debug) 1719296341Sdelphij printf("server wrote %d\n", i); 1720296341Sdelphij sw_num -= i; 1721296341Sdelphij s_write = 0; 1722296341Sdelphij c_r = 1; 1723296341Sdelphij if (sw_num <= 0) 1724296341Sdelphij done |= S_DONE; 1725296341Sdelphij } 1726296341Sdelphij } 1727296341Sdelphij } 172855714Skris 1729296341Sdelphij if ((done & S_DONE) && (done & C_DONE)) 1730296341Sdelphij break; 1731296341Sdelphij } 173255714Skris 1733296341Sdelphij if (verbose) 1734296341Sdelphij print_details(c_ssl, "DONE: "); 1735296341Sdelphij ret = 0; 1736296341Sdelphij err: 1737296341Sdelphij /* 1738296341Sdelphij * We have to set the BIO's to NULL otherwise they will be 1739296341Sdelphij * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and again 1740296341Sdelphij * when c_ssl is SSL_free()ed. This is a hack required because s_ssl and 1741296341Sdelphij * c_ssl are sharing the same BIO structure and SSL_set_bio() and 1742296341Sdelphij * SSL_free() automatically BIO_free non NULL entries. You should not 1743296341Sdelphij * normally do this or be required to do this 1744296341Sdelphij */ 1745296341Sdelphij if (s_ssl != NULL) { 1746296341Sdelphij s_ssl->rbio = NULL; 1747296341Sdelphij s_ssl->wbio = NULL; 1748296341Sdelphij } 1749296341Sdelphij if (c_ssl != NULL) { 1750296341Sdelphij c_ssl->rbio = NULL; 1751296341Sdelphij c_ssl->wbio = NULL; 1752296341Sdelphij } 175355714Skris 1754296341Sdelphij if (c_to_s != NULL) 1755296341Sdelphij BIO_free(c_to_s); 1756296341Sdelphij if (s_to_c != NULL) 1757296341Sdelphij BIO_free(s_to_c); 1758296341Sdelphij if (c_bio != NULL) 1759296341Sdelphij BIO_free_all(c_bio); 1760296341Sdelphij if (s_bio != NULL) 1761296341Sdelphij BIO_free_all(s_bio); 1762296341Sdelphij return (ret); 1763296341Sdelphij} 176455714Skris 1765160814Ssimonstatic int get_proxy_auth_ex_data_idx(void) 1766296341Sdelphij{ 1767296341Sdelphij static volatile int idx = -1; 1768296341Sdelphij if (idx < 0) { 1769296341Sdelphij CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 1770296341Sdelphij if (idx < 0) { 1771296341Sdelphij idx = X509_STORE_CTX_get_ex_new_index(0, 1772296341Sdelphij "SSLtest for verify callback", 1773296341Sdelphij NULL, NULL, NULL); 1774296341Sdelphij } 1775296341Sdelphij CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 1776296341Sdelphij } 1777296341Sdelphij return idx; 1778296341Sdelphij} 1779160814Ssimon 178059191Skrisstatic int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 1781296341Sdelphij{ 1782296341Sdelphij char *s, buf[256]; 178355714Skris 1784296341Sdelphij s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, 1785296341Sdelphij sizeof buf); 1786296341Sdelphij if (s != NULL) { 1787296341Sdelphij if (ok) 1788296341Sdelphij fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf); 1789296341Sdelphij else { 1790296341Sdelphij fprintf(stderr, "depth=%d error=%d %s\n", 1791296341Sdelphij ctx->error_depth, ctx->error, buf); 1792296341Sdelphij } 1793296341Sdelphij } 179455714Skris 1795296341Sdelphij if (ok == 0) { 1796296341Sdelphij fprintf(stderr, "Error string: %s\n", 1797296341Sdelphij X509_verify_cert_error_string(ctx->error)); 1798296341Sdelphij switch (ctx->error) { 1799296341Sdelphij case X509_V_ERR_CERT_NOT_YET_VALID: 1800296341Sdelphij case X509_V_ERR_CERT_HAS_EXPIRED: 1801296341Sdelphij case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1802296341Sdelphij fprintf(stderr, " ... ignored.\n"); 1803296341Sdelphij ok = 1; 1804296341Sdelphij } 1805296341Sdelphij } 180655714Skris 1807296341Sdelphij if (ok == 1) { 1808296341Sdelphij X509 *xs = ctx->current_cert; 1809160814Ssimon#if 0 1810296341Sdelphij X509 *xi = ctx->current_issuer; 1811160814Ssimon#endif 1812160814Ssimon 1813296341Sdelphij if (xs->ex_flags & EXFLAG_PROXY) { 1814296341Sdelphij unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx, 1815296341Sdelphij get_proxy_auth_ex_data_idx 1816296341Sdelphij ()); 1817160814Ssimon 1818296341Sdelphij if (letters) { 1819296341Sdelphij int found_any = 0; 1820296341Sdelphij int i; 1821296341Sdelphij PROXY_CERT_INFO_EXTENSION *pci = 1822296341Sdelphij X509_get_ext_d2i(xs, NID_proxyCertInfo, 1823296341Sdelphij NULL, NULL); 1824160814Ssimon 1825296341Sdelphij switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { 1826296341Sdelphij case NID_Independent: 1827296341Sdelphij /* 1828296341Sdelphij * Completely meaningless in this program, as there's no 1829296341Sdelphij * way to grant explicit rights to a specific PrC. 1830296341Sdelphij * Basically, using id-ppl-Independent is the perfect way 1831296341Sdelphij * to grant no rights at all. 1832296341Sdelphij */ 1833296341Sdelphij fprintf(stderr, " Independent proxy certificate"); 1834296341Sdelphij for (i = 0; i < 26; i++) 1835296341Sdelphij letters[i] = 0; 1836296341Sdelphij break; 1837296341Sdelphij case NID_id_ppl_inheritAll: 1838296341Sdelphij /* 1839296341Sdelphij * This is basically a NOP, we simply let the current 1840296341Sdelphij * rights stand as they are. 1841296341Sdelphij */ 1842296341Sdelphij fprintf(stderr, " Proxy certificate inherits all"); 1843296341Sdelphij break; 1844296341Sdelphij default: 1845296341Sdelphij s = (char *) 1846296341Sdelphij pci->proxyPolicy->policy->data; 1847296341Sdelphij i = pci->proxyPolicy->policy->length; 1848160814Ssimon 1849296341Sdelphij /* 1850296341Sdelphij * The algorithm works as follows: it is assumed that 1851296341Sdelphij * previous iterations or the initial granted rights has 1852296341Sdelphij * already set some elements of `letters'. What we need 1853296341Sdelphij * to do is to clear those that weren't granted by the 1854296341Sdelphij * current PrC as well. The easiest way to do this is to 1855296341Sdelphij * add 1 to all the elements whose letters are given with 1856296341Sdelphij * the current policy. That way, all elements that are 1857296341Sdelphij * set by the current policy and were already set by 1858296341Sdelphij * earlier policies and through the original grant of 1859296341Sdelphij * rights will get the value 2 or higher. The last thing 1860296341Sdelphij * to do is to sweep through `letters' and keep the 1861296341Sdelphij * elements having the value 2 as set, and clear all the 1862296341Sdelphij * others. 1863296341Sdelphij */ 1864160814Ssimon 1865296341Sdelphij fprintf(stderr, " Certificate proxy rights = %*.*s", i, 1866296341Sdelphij i, s); 1867296341Sdelphij while (i-- > 0) { 1868296341Sdelphij int c = *s++; 1869296341Sdelphij if (isascii(c) && isalpha(c)) { 1870296341Sdelphij if (islower(c)) 1871296341Sdelphij c = toupper(c); 1872296341Sdelphij letters[c - 'A']++; 1873296341Sdelphij } 1874296341Sdelphij } 1875296341Sdelphij for (i = 0; i < 26; i++) 1876296341Sdelphij if (letters[i] < 2) 1877296341Sdelphij letters[i] = 0; 1878296341Sdelphij else 1879296341Sdelphij letters[i] = 1; 1880296341Sdelphij } 1881160814Ssimon 1882296341Sdelphij found_any = 0; 1883296341Sdelphij fprintf(stderr, ", resulting proxy rights = "); 1884296341Sdelphij for (i = 0; i < 26; i++) 1885296341Sdelphij if (letters[i]) { 1886296341Sdelphij fprintf(stderr, "%c", i + 'A'); 1887296341Sdelphij found_any = 1; 1888296341Sdelphij } 1889296341Sdelphij if (!found_any) 1890296341Sdelphij fprintf(stderr, "none"); 1891296341Sdelphij fprintf(stderr, "\n"); 1892160814Ssimon 1893296341Sdelphij PROXY_CERT_INFO_EXTENSION_free(pci); 1894296341Sdelphij } 1895296341Sdelphij } 1896296341Sdelphij } 1897160814Ssimon 1898296341Sdelphij return (ok); 1899296341Sdelphij} 190055714Skris 1901160814Ssimonstatic void process_proxy_debug(int indent, const char *format, ...) 1902296341Sdelphij{ 1903296341Sdelphij /* That's 80 > */ 1904296341Sdelphij static const char indentation[] = 1905296341Sdelphij ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 1906296341Sdelphij ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; 1907296341Sdelphij char my_format[256]; 1908296341Sdelphij va_list args; 1909160814Ssimon 1910296341Sdelphij BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s", 1911296341Sdelphij indent, indent, indentation, format); 1912160814Ssimon 1913296341Sdelphij va_start(args, format); 1914296341Sdelphij vfprintf(stderr, my_format, args); 1915296341Sdelphij va_end(args); 1916296341Sdelphij} 1917296341Sdelphij 1918296341Sdelphij/*- 1919296341Sdelphij * Priority levels: 1920296341Sdelphij * 0 [!]var, () 1921296341Sdelphij * 1 & ^ 1922296341Sdelphij * 2 | 1923296341Sdelphij */ 1924160814Ssimonstatic int process_proxy_cond_adders(unsigned int letters[26], 1925296341Sdelphij const char *cond, const char **cond_end, 1926296341Sdelphij int *pos, int indent); 1927296341Sdelphijstatic int process_proxy_cond_val(unsigned int letters[26], const char *cond, 1928296341Sdelphij const char **cond_end, int *pos, int indent) 1929296341Sdelphij{ 1930296341Sdelphij int c; 1931296341Sdelphij int ok = 1; 1932296341Sdelphij int negate = 0; 1933160814Ssimon 1934296341Sdelphij while (isspace((int)*cond)) { 1935296341Sdelphij cond++; 1936296341Sdelphij (*pos)++; 1937296341Sdelphij } 1938296341Sdelphij c = *cond; 1939160814Ssimon 1940296341Sdelphij if (debug) 1941296341Sdelphij process_proxy_debug(indent, 1942296341Sdelphij "Start process_proxy_cond_val at position %d: %s\n", 1943296341Sdelphij *pos, cond); 1944160814Ssimon 1945296341Sdelphij while (c == '!') { 1946296341Sdelphij negate = !negate; 1947296341Sdelphij cond++; 1948296341Sdelphij (*pos)++; 1949296341Sdelphij while (isspace((int)*cond)) { 1950296341Sdelphij cond++; 1951296341Sdelphij (*pos)++; 1952296341Sdelphij } 1953296341Sdelphij c = *cond; 1954296341Sdelphij } 1955160814Ssimon 1956296341Sdelphij if (c == '(') { 1957296341Sdelphij cond++; 1958296341Sdelphij (*pos)++; 1959296341Sdelphij ok = process_proxy_cond_adders(letters, cond, cond_end, pos, 1960296341Sdelphij indent + 1); 1961296341Sdelphij cond = *cond_end; 1962296341Sdelphij if (ok < 0) 1963296341Sdelphij goto end; 1964296341Sdelphij while (isspace((int)*cond)) { 1965296341Sdelphij cond++; 1966296341Sdelphij (*pos)++; 1967296341Sdelphij } 1968296341Sdelphij c = *cond; 1969296341Sdelphij if (c != ')') { 1970296341Sdelphij fprintf(stderr, 1971296341Sdelphij "Weird condition character in position %d: " 1972296341Sdelphij "%c\n", *pos, c); 1973296341Sdelphij ok = -1; 1974296341Sdelphij goto end; 1975296341Sdelphij } 1976296341Sdelphij cond++; 1977296341Sdelphij (*pos)++; 1978296341Sdelphij } else if (isascii(c) && isalpha(c)) { 1979296341Sdelphij if (islower(c)) 1980296341Sdelphij c = toupper(c); 1981296341Sdelphij ok = letters[c - 'A']; 1982296341Sdelphij cond++; 1983296341Sdelphij (*pos)++; 1984296341Sdelphij } else { 1985296341Sdelphij fprintf(stderr, 1986296341Sdelphij "Weird condition character in position %d: " "%c\n", *pos, c); 1987296341Sdelphij ok = -1; 1988296341Sdelphij goto end; 1989296341Sdelphij } 1990160814Ssimon end: 1991296341Sdelphij *cond_end = cond; 1992296341Sdelphij if (ok >= 0 && negate) 1993296341Sdelphij ok = !ok; 1994160814Ssimon 1995296341Sdelphij if (debug) 1996296341Sdelphij process_proxy_debug(indent, 1997296341Sdelphij "End process_proxy_cond_val at position %d: %s, returning %d\n", 1998296341Sdelphij *pos, cond, ok); 1999160814Ssimon 2000296341Sdelphij return ok; 2001296341Sdelphij} 2002296341Sdelphij 2003160814Ssimonstatic int process_proxy_cond_multipliers(unsigned int letters[26], 2004296341Sdelphij const char *cond, 2005296341Sdelphij const char **cond_end, int *pos, 2006296341Sdelphij int indent) 2007296341Sdelphij{ 2008296341Sdelphij int ok; 2009296341Sdelphij char c; 2010160814Ssimon 2011296341Sdelphij if (debug) 2012296341Sdelphij process_proxy_debug(indent, 2013296341Sdelphij "Start process_proxy_cond_multipliers at position %d: %s\n", 2014296341Sdelphij *pos, cond); 2015160814Ssimon 2016296341Sdelphij ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1); 2017296341Sdelphij cond = *cond_end; 2018296341Sdelphij if (ok < 0) 2019296341Sdelphij goto end; 2020160814Ssimon 2021296341Sdelphij while (ok >= 0) { 2022296341Sdelphij while (isspace((int)*cond)) { 2023296341Sdelphij cond++; 2024296341Sdelphij (*pos)++; 2025296341Sdelphij } 2026296341Sdelphij c = *cond; 2027160814Ssimon 2028296341Sdelphij switch (c) { 2029296341Sdelphij case '&': 2030296341Sdelphij case '^': 2031296341Sdelphij { 2032296341Sdelphij int save_ok = ok; 2033160814Ssimon 2034296341Sdelphij cond++; 2035296341Sdelphij (*pos)++; 2036296341Sdelphij ok = process_proxy_cond_val(letters, 2037296341Sdelphij cond, cond_end, pos, indent + 1); 2038296341Sdelphij cond = *cond_end; 2039296341Sdelphij if (ok < 0) 2040296341Sdelphij break; 2041160814Ssimon 2042296341Sdelphij switch (c) { 2043296341Sdelphij case '&': 2044296341Sdelphij ok &= save_ok; 2045296341Sdelphij break; 2046296341Sdelphij case '^': 2047296341Sdelphij ok ^= save_ok; 2048296341Sdelphij break; 2049296341Sdelphij default: 2050296341Sdelphij fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 2051296341Sdelphij " STOPPING\n"); 2052296341Sdelphij EXIT(1); 2053296341Sdelphij } 2054296341Sdelphij } 2055296341Sdelphij break; 2056296341Sdelphij default: 2057296341Sdelphij goto end; 2058296341Sdelphij } 2059296341Sdelphij } 2060160814Ssimon end: 2061296341Sdelphij if (debug) 2062296341Sdelphij process_proxy_debug(indent, 2063296341Sdelphij "End process_proxy_cond_multipliers at position %d: %s, returning %d\n", 2064296341Sdelphij *pos, cond, ok); 2065160814Ssimon 2066296341Sdelphij *cond_end = cond; 2067296341Sdelphij return ok; 2068296341Sdelphij} 2069296341Sdelphij 2070160814Ssimonstatic int process_proxy_cond_adders(unsigned int letters[26], 2071296341Sdelphij const char *cond, const char **cond_end, 2072296341Sdelphij int *pos, int indent) 2073296341Sdelphij{ 2074296341Sdelphij int ok; 2075296341Sdelphij char c; 2076160814Ssimon 2077296341Sdelphij if (debug) 2078296341Sdelphij process_proxy_debug(indent, 2079296341Sdelphij "Start process_proxy_cond_adders at position %d: %s\n", 2080296341Sdelphij *pos, cond); 2081160814Ssimon 2082296341Sdelphij ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos, 2083296341Sdelphij indent + 1); 2084296341Sdelphij cond = *cond_end; 2085296341Sdelphij if (ok < 0) 2086296341Sdelphij goto end; 2087160814Ssimon 2088296341Sdelphij while (ok >= 0) { 2089296341Sdelphij while (isspace((int)*cond)) { 2090296341Sdelphij cond++; 2091296341Sdelphij (*pos)++; 2092296341Sdelphij } 2093296341Sdelphij c = *cond; 2094160814Ssimon 2095296341Sdelphij switch (c) { 2096296341Sdelphij case '|': 2097296341Sdelphij { 2098296341Sdelphij int save_ok = ok; 2099160814Ssimon 2100296341Sdelphij cond++; 2101296341Sdelphij (*pos)++; 2102296341Sdelphij ok = process_proxy_cond_multipliers(letters, 2103296341Sdelphij cond, cond_end, pos, 2104296341Sdelphij indent + 1); 2105296341Sdelphij cond = *cond_end; 2106296341Sdelphij if (ok < 0) 2107296341Sdelphij break; 2108160814Ssimon 2109296341Sdelphij switch (c) { 2110296341Sdelphij case '|': 2111296341Sdelphij ok |= save_ok; 2112296341Sdelphij break; 2113296341Sdelphij default: 2114296341Sdelphij fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 2115296341Sdelphij " STOPPING\n"); 2116296341Sdelphij EXIT(1); 2117296341Sdelphij } 2118296341Sdelphij } 2119296341Sdelphij break; 2120296341Sdelphij default: 2121296341Sdelphij goto end; 2122296341Sdelphij } 2123296341Sdelphij } 2124160814Ssimon end: 2125296341Sdelphij if (debug) 2126296341Sdelphij process_proxy_debug(indent, 2127296341Sdelphij "End process_proxy_cond_adders at position %d: %s, returning %d\n", 2128296341Sdelphij *pos, cond, ok); 2129160814Ssimon 2130296341Sdelphij *cond_end = cond; 2131296341Sdelphij return ok; 2132296341Sdelphij} 2133160814Ssimon 2134160814Ssimonstatic int process_proxy_cond(unsigned int letters[26], 2135296341Sdelphij const char *cond, const char **cond_end) 2136296341Sdelphij{ 2137296341Sdelphij int pos = 1; 2138296341Sdelphij return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1); 2139296341Sdelphij} 2140160814Ssimon 2141109998Smarkmstatic int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) 2142296341Sdelphij{ 2143296341Sdelphij int ok = 1; 2144296341Sdelphij struct app_verify_arg *cb_arg = arg; 2145296341Sdelphij unsigned int letters[26]; /* only used with proxy_auth */ 2146109998Smarkm 2147296341Sdelphij if (cb_arg->app_verify) { 2148296341Sdelphij char *s = NULL, buf[256]; 2149160814Ssimon 2150296341Sdelphij fprintf(stderr, "In app_verify_callback, allowing cert. "); 2151296341Sdelphij fprintf(stderr, "Arg is: %s\n", cb_arg->string); 2152296341Sdelphij fprintf(stderr, 2153296341Sdelphij "Finished printing do we have a context? 0x%p a cert? 0x%p\n", 2154296341Sdelphij (void *)ctx, (void *)ctx->cert); 2155296341Sdelphij if (ctx->cert) 2156296341Sdelphij s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256); 2157296341Sdelphij if (s != NULL) { 2158296341Sdelphij fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf); 2159296341Sdelphij } 2160296341Sdelphij return (1); 2161296341Sdelphij } 2162296341Sdelphij if (cb_arg->proxy_auth) { 2163296341Sdelphij int found_any = 0, i; 2164296341Sdelphij char *sp; 2165109998Smarkm 2166296341Sdelphij for (i = 0; i < 26; i++) 2167296341Sdelphij letters[i] = 0; 2168296341Sdelphij for (sp = cb_arg->proxy_auth; *sp; sp++) { 2169296341Sdelphij int c = *sp; 2170296341Sdelphij if (isascii(c) && isalpha(c)) { 2171296341Sdelphij if (islower(c)) 2172296341Sdelphij c = toupper(c); 2173296341Sdelphij letters[c - 'A'] = 1; 2174296341Sdelphij } 2175296341Sdelphij } 2176160814Ssimon 2177296341Sdelphij fprintf(stderr, " Initial proxy rights = "); 2178296341Sdelphij for (i = 0; i < 26; i++) 2179296341Sdelphij if (letters[i]) { 2180296341Sdelphij fprintf(stderr, "%c", i + 'A'); 2181296341Sdelphij found_any = 1; 2182296341Sdelphij } 2183296341Sdelphij if (!found_any) 2184296341Sdelphij fprintf(stderr, "none"); 2185296341Sdelphij fprintf(stderr, "\n"); 2186160814Ssimon 2187296341Sdelphij X509_STORE_CTX_set_ex_data(ctx, 2188296341Sdelphij get_proxy_auth_ex_data_idx(), letters); 2189296341Sdelphij } 2190296341Sdelphij if (cb_arg->allow_proxy_certs) { 2191296341Sdelphij X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); 2192296341Sdelphij } 2193160814Ssimon#ifndef OPENSSL_NO_X509_VERIFY 2194296341Sdelphij ok = X509_verify_cert(ctx); 2195160814Ssimon#endif 2196160814Ssimon 2197296341Sdelphij if (cb_arg->proxy_auth) { 2198296341Sdelphij if (ok > 0) { 2199296341Sdelphij const char *cond_end = NULL; 2200160814Ssimon 2201296341Sdelphij ok = process_proxy_cond(letters, cb_arg->proxy_cond, &cond_end); 2202160814Ssimon 2203296341Sdelphij if (ok < 0) 2204296341Sdelphij EXIT(3); 2205296341Sdelphij if (*cond_end) { 2206296341Sdelphij fprintf(stderr, 2207296341Sdelphij "Stopped processing condition before it's end.\n"); 2208296341Sdelphij ok = 0; 2209296341Sdelphij } 2210296341Sdelphij if (!ok) 2211296341Sdelphij fprintf(stderr, 2212296341Sdelphij "Proxy rights check with condition '%s' proved invalid\n", 2213296341Sdelphij cb_arg->proxy_cond); 2214296341Sdelphij else 2215296341Sdelphij fprintf(stderr, 2216296341Sdelphij "Proxy rights check with condition '%s' proved valid\n", 2217296341Sdelphij cb_arg->proxy_cond); 2218296341Sdelphij } 2219296341Sdelphij } 2220296341Sdelphij return (ok); 2221296341Sdelphij} 2222109998Smarkm 2223109998Smarkm#ifndef OPENSSL_NO_RSA 2224296341Sdelphijstatic RSA *rsa_tmp = NULL; 222568651Skris 222655714Skrisstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) 2227296341Sdelphij{ 2228296341Sdelphij BIGNUM *bn = NULL; 2229296341Sdelphij if (rsa_tmp == NULL) { 2230296341Sdelphij bn = BN_new(); 2231296341Sdelphij rsa_tmp = RSA_new(); 2232296341Sdelphij if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) { 2233296341Sdelphij BIO_printf(bio_err, "Memory error..."); 2234296341Sdelphij goto end; 2235296341Sdelphij } 2236296341Sdelphij BIO_printf(bio_err, "Generating temp (%d bit) RSA key...", keylength); 2237296341Sdelphij (void)BIO_flush(bio_err); 2238296341Sdelphij if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) { 2239296341Sdelphij BIO_printf(bio_err, "Error generating key."); 2240296341Sdelphij RSA_free(rsa_tmp); 2241296341Sdelphij rsa_tmp = NULL; 2242296341Sdelphij } 2243296341Sdelphij end: 2244296341Sdelphij BIO_printf(bio_err, "\n"); 2245296341Sdelphij (void)BIO_flush(bio_err); 2246296341Sdelphij } 2247296341Sdelphij if (bn) 2248296341Sdelphij BN_free(bn); 2249296341Sdelphij return (rsa_tmp); 2250296341Sdelphij} 225168651Skris 225268651Skrisstatic void free_tmp_rsa(void) 2253296341Sdelphij{ 2254296341Sdelphij if (rsa_tmp != NULL) { 2255296341Sdelphij RSA_free(rsa_tmp); 2256296341Sdelphij rsa_tmp = NULL; 2257296341Sdelphij } 2258296341Sdelphij} 225955714Skris#endif 226059191Skris 2261109998Smarkm#ifndef OPENSSL_NO_DH 2262296341Sdelphij/*- 2263296341Sdelphij * These DH parameters have been generated as follows: 226459191Skris * $ openssl dhparam -C -noout 512 226559191Skris * $ openssl dhparam -C -noout 1024 226659191Skris * $ openssl dhparam -C -noout -dsaparam 1024 226759191Skris * (The third function has been renamed to avoid name conflicts.) 226859191Skris */ 2269109998Smarkmstatic DH *get_dh512() 2270296341Sdelphij{ 2271296341Sdelphij static unsigned char dh512_p[] = { 2272296341Sdelphij 0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0, 2273296341Sdelphij 0xC6, 2274296341Sdelphij 0x1F, 0x0D, 0xAC, 0xB6, 0x25, 0x3E, 0x06, 0x39, 0xCA, 0x72, 0x04, 2275296341Sdelphij 0xB0, 2276296341Sdelphij 0x6E, 0xDA, 0xC0, 0x61, 0xE6, 0x7A, 0x77, 0x25, 0xE8, 0x3B, 0xB9, 2277296341Sdelphij 0x5F, 2278296341Sdelphij 0x9A, 0xB6, 0xB5, 0xFE, 0x99, 0x0B, 0xA1, 0x93, 0x4E, 0x35, 0x33, 2279296341Sdelphij 0xB8, 2280296341Sdelphij 0xE1, 0xF1, 0x13, 0x4F, 0x59, 0x1A, 0xD2, 0x57, 0xC0, 0x26, 0x21, 2281296341Sdelphij 0x33, 2282296341Sdelphij 0x02, 0xC5, 0xAE, 0x23, 2283296341Sdelphij }; 2284296341Sdelphij static unsigned char dh512_g[] = { 2285296341Sdelphij 0x02, 2286296341Sdelphij }; 2287296341Sdelphij DH *dh; 228859191Skris 2289296341Sdelphij if ((dh = DH_new()) == NULL) 2290296341Sdelphij return (NULL); 2291296341Sdelphij dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); 2292296341Sdelphij dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); 2293296341Sdelphij if ((dh->p == NULL) || (dh->g == NULL)) { 2294296341Sdelphij DH_free(dh); 2295296341Sdelphij return (NULL); 2296296341Sdelphij } 2297296341Sdelphij return (dh); 2298296341Sdelphij} 229959191Skris 2300109998Smarkmstatic DH *get_dh1024() 2301296341Sdelphij{ 2302296341Sdelphij static unsigned char dh1024_p[] = { 2303296341Sdelphij 0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 2304296341Sdelphij 0x3A, 2305296341Sdelphij 0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 2306296341Sdelphij 0xA2, 2307296341Sdelphij 0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 2308296341Sdelphij 0xB0, 2309296341Sdelphij 0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 2310296341Sdelphij 0xC2, 2311296341Sdelphij 0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 2312296341Sdelphij 0x8C, 2313296341Sdelphij 0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 2314296341Sdelphij 0xB8, 2315296341Sdelphij 0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 2316296341Sdelphij 0x52, 2317296341Sdelphij 0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 2318296341Sdelphij 0xC1, 2319296341Sdelphij 0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 2320296341Sdelphij 0xB1, 2321296341Sdelphij 0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 2322296341Sdelphij 0xAB, 2323296341Sdelphij 0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53, 2324296341Sdelphij }; 2325296341Sdelphij static unsigned char dh1024_g[] = { 2326296341Sdelphij 0x02, 2327296341Sdelphij }; 2328296341Sdelphij DH *dh; 232959191Skris 2330296341Sdelphij if ((dh = DH_new()) == NULL) 2331296341Sdelphij return (NULL); 2332296341Sdelphij dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 2333296341Sdelphij dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 2334296341Sdelphij if ((dh->p == NULL) || (dh->g == NULL)) { 2335296341Sdelphij DH_free(dh); 2336296341Sdelphij return (NULL); 2337296341Sdelphij } 2338296341Sdelphij return (dh); 2339296341Sdelphij} 234059191Skris 2341109998Smarkmstatic DH *get_dh1024dsa() 2342296341Sdelphij{ 2343296341Sdelphij static unsigned char dh1024_p[] = { 2344296341Sdelphij 0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 2345296341Sdelphij 0x00, 2346296341Sdelphij 0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 2347296341Sdelphij 0x19, 2348296341Sdelphij 0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 2349296341Sdelphij 0xD2, 2350296341Sdelphij 0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 2351296341Sdelphij 0x55, 2352296341Sdelphij 0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 2353296341Sdelphij 0xFC, 2354296341Sdelphij 0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 2355296341Sdelphij 0x97, 2356296341Sdelphij 0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 2357296341Sdelphij 0x8D, 2358296341Sdelphij 0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 2359296341Sdelphij 0xBB, 2360296341Sdelphij 0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 2361296341Sdelphij 0xF6, 2362296341Sdelphij 0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 2363296341Sdelphij 0x9E, 2364296341Sdelphij 0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39, 2365296341Sdelphij }; 2366296341Sdelphij static unsigned char dh1024_g[] = { 2367296341Sdelphij 0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 2368296341Sdelphij 0x05, 2369296341Sdelphij 0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 2370296341Sdelphij 0xF3, 2371296341Sdelphij 0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 2372296341Sdelphij 0xE9, 2373296341Sdelphij 0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 2374296341Sdelphij 0x3C, 2375296341Sdelphij 0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 2376296341Sdelphij 0x65, 2377296341Sdelphij 0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 2378296341Sdelphij 0x60, 2379296341Sdelphij 0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 2380296341Sdelphij 0xF6, 2381296341Sdelphij 0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 2382296341Sdelphij 0xA7, 2383296341Sdelphij 0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 2384296341Sdelphij 0xA1, 2385296341Sdelphij 0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 2386296341Sdelphij 0x60, 2387296341Sdelphij 0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2, 2388296341Sdelphij }; 2389296341Sdelphij DH *dh; 239059191Skris 2391296341Sdelphij if ((dh = DH_new()) == NULL) 2392296341Sdelphij return (NULL); 2393296341Sdelphij dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 2394296341Sdelphij dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 2395296341Sdelphij if ((dh->p == NULL) || (dh->g == NULL)) { 2396296341Sdelphij DH_free(dh); 2397296341Sdelphij return (NULL); 2398296341Sdelphij } 2399296341Sdelphij dh->length = 160; 2400296341Sdelphij return (dh); 2401296341Sdelphij} 240259191Skris#endif 2403160814Ssimon 2404238405Sjkim#ifndef OPENSSL_NO_PSK 2405238405Sjkim/* convert the PSK key (psk_key) in ascii to binary (psk) */ 2406238405Sjkimstatic int psk_key2bn(const char *pskkey, unsigned char *psk, 2407296341Sdelphij unsigned int max_psk_len) 2408296341Sdelphij{ 2409296341Sdelphij int ret; 2410296341Sdelphij BIGNUM *bn = NULL; 2411238405Sjkim 2412296341Sdelphij ret = BN_hex2bn(&bn, pskkey); 2413296341Sdelphij if (!ret) { 2414296341Sdelphij BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n", 2415296341Sdelphij pskkey); 2416296341Sdelphij if (bn) 2417296341Sdelphij BN_free(bn); 2418296341Sdelphij return 0; 2419296341Sdelphij } 2420296341Sdelphij if (BN_num_bytes(bn) > (int)max_psk_len) { 2421296341Sdelphij BIO_printf(bio_err, 2422296341Sdelphij "psk buffer of callback is too small (%d) for key (%d)\n", 2423296341Sdelphij max_psk_len, BN_num_bytes(bn)); 2424296341Sdelphij BN_free(bn); 2425296341Sdelphij return 0; 2426296341Sdelphij } 2427296341Sdelphij ret = BN_bn2bin(bn, psk); 2428296341Sdelphij BN_free(bn); 2429296341Sdelphij return ret; 2430296341Sdelphij} 2431238405Sjkim 2432296341Sdelphijstatic unsigned int psk_client_callback(SSL *ssl, const char *hint, 2433296341Sdelphij char *identity, 2434296341Sdelphij unsigned int max_identity_len, 2435296341Sdelphij unsigned char *psk, 2436296341Sdelphij unsigned int max_psk_len) 2437296341Sdelphij{ 2438296341Sdelphij int ret; 2439296341Sdelphij unsigned int psk_len = 0; 2440238405Sjkim 2441296341Sdelphij ret = BIO_snprintf(identity, max_identity_len, "Client_identity"); 2442296341Sdelphij if (ret < 0) 2443296341Sdelphij goto out_err; 2444296341Sdelphij if (debug) 2445296341Sdelphij fprintf(stderr, "client: created identity '%s' len=%d\n", identity, 2446296341Sdelphij ret); 2447296341Sdelphij ret = psk_key2bn(psk_key, psk, max_psk_len); 2448296341Sdelphij if (ret < 0) 2449296341Sdelphij goto out_err; 2450296341Sdelphij psk_len = ret; 2451296341Sdelphij out_err: 2452296341Sdelphij return psk_len; 2453296341Sdelphij} 2454238405Sjkim 2455238405Sjkimstatic unsigned int psk_server_callback(SSL *ssl, const char *identity, 2456296341Sdelphij unsigned char *psk, 2457296341Sdelphij unsigned int max_psk_len) 2458296341Sdelphij{ 2459296341Sdelphij unsigned int psk_len = 0; 2460238405Sjkim 2461296341Sdelphij if (strcmp(identity, "Client_identity") != 0) { 2462296341Sdelphij BIO_printf(bio_err, "server: PSK error: client identity not found\n"); 2463296341Sdelphij return 0; 2464296341Sdelphij } 2465296341Sdelphij psk_len = psk_key2bn(psk_key, psk, max_psk_len); 2466296341Sdelphij return psk_len; 2467296341Sdelphij} 2468238405Sjkim#endif 2469238405Sjkim 2470160814Ssimonstatic int do_test_cipherlist(void) 2471296341Sdelphij{ 2472296341Sdelphij int i = 0; 2473296341Sdelphij const SSL_METHOD *meth; 2474296341Sdelphij const SSL_CIPHER *ci, *tci = NULL; 2475160814Ssimon 2476160814Ssimon#ifndef OPENSSL_NO_SSL2 2477296341Sdelphij fprintf(stderr, "testing SSLv2 cipher list order: "); 2478296341Sdelphij meth = SSLv2_method(); 2479296341Sdelphij while ((ci = meth->get_cipher(i++)) != NULL) { 2480296341Sdelphij if (tci != NULL) 2481296341Sdelphij if (ci->id >= tci->id) { 2482296341Sdelphij fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2483296341Sdelphij return 0; 2484296341Sdelphij } 2485296341Sdelphij tci = ci; 2486296341Sdelphij } 2487296341Sdelphij fprintf(stderr, "ok\n"); 2488160814Ssimon#endif 2489160814Ssimon#ifndef OPENSSL_NO_SSL3 2490296341Sdelphij fprintf(stderr, "testing SSLv3 cipher list order: "); 2491296341Sdelphij meth = SSLv3_method(); 2492296341Sdelphij tci = NULL; 2493296341Sdelphij while ((ci = meth->get_cipher(i++)) != NULL) { 2494296341Sdelphij if (tci != NULL) 2495296341Sdelphij if (ci->id >= tci->id) { 2496296341Sdelphij fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2497296341Sdelphij return 0; 2498296341Sdelphij } 2499296341Sdelphij tci = ci; 2500296341Sdelphij } 2501296341Sdelphij fprintf(stderr, "ok\n"); 2502160814Ssimon#endif 2503160814Ssimon#ifndef OPENSSL_NO_TLS1 2504296341Sdelphij fprintf(stderr, "testing TLSv1 cipher list order: "); 2505296341Sdelphij meth = TLSv1_method(); 2506296341Sdelphij tci = NULL; 2507296341Sdelphij while ((ci = meth->get_cipher(i++)) != NULL) { 2508296341Sdelphij if (tci != NULL) 2509296341Sdelphij if (ci->id >= tci->id) { 2510296341Sdelphij fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); 2511296341Sdelphij return 0; 2512296341Sdelphij } 2513296341Sdelphij tci = ci; 2514296341Sdelphij } 2515296341Sdelphij fprintf(stderr, "ok\n"); 2516160814Ssimon#endif 2517160814Ssimon 2518296341Sdelphij return 1; 2519296341Sdelphij} 2520