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