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