ssltest.c revision 296465
1/* ssl/ssltest.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 *    notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in
70 *    the documentation and/or other materials provided with the
71 *    distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 *    software must display the following acknowledgment:
75 *    "This product includes software developed by the OpenSSL Project
76 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 *    endorse or promote products derived from this software without
80 *    prior written permission. For written permission, please contact
81 *    openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 *    nor may "OpenSSL" appear in their names without prior written
85 *    permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 *    acknowledgment:
89 *    "This product includes software developed by the OpenSSL Project
90 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com).  This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111/* ====================================================================
112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113 * ECC cipher suite support in OpenSSL originally developed by
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115 */
116
117/* Or gethostname won't be declared properly on Linux and GNU platforms. */
118#define _BSD_SOURCE 1
119#define _DEFAULT_SOURCE 1
120
121#include <assert.h>
122#include <errno.h>
123#include <limits.h>
124#include <stdio.h>
125#include <stdlib.h>
126#include <string.h>
127#include <time.h>
128
129#define USE_SOCKETS
130#include "e_os.h"
131
132/*
133 * Or isascii won't be declared properly on VMS (at least with DECompHP C).
134 */
135#define _XOPEN_SOURCE 500
136#include <ctype.h>
137
138#include <openssl/bio.h>
139#include <openssl/crypto.h>
140#include <openssl/evp.h>
141#include <openssl/x509.h>
142#include <openssl/x509v3.h>
143#include <openssl/ssl.h>
144#ifndef OPENSSL_NO_ENGINE
145# include <openssl/engine.h>
146#endif
147#include <openssl/err.h>
148#include <openssl/rand.h>
149#ifndef OPENSSL_NO_RSA
150# include <openssl/rsa.h>
151#endif
152#ifndef OPENSSL_NO_DSA
153# include <openssl/dsa.h>
154#endif
155#ifndef OPENSSL_NO_DH
156# include <openssl/dh.h>
157#endif
158#include <openssl/bn.h>
159
160/*
161 * Or gethostname won't be declared properly
162 * on Compaq platforms (at least with DEC C).
163 * Do not try to put it earlier, or IPv6 includes
164 * get screwed...
165 */
166#define _XOPEN_SOURCE_EXTENDED  1
167
168#ifdef OPENSSL_SYS_WINDOWS
169# include <winsock.h>
170#else
171# include OPENSSL_UNISTD
172#endif
173
174#ifdef OPENSSL_SYS_VMS
175# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
176# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
177#elif defined(OPENSSL_SYS_WINCE)
178# define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
179# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
180#elif defined(OPENSSL_SYS_NETWARE)
181# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
182# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem"
183#else
184# define TEST_SERVER_CERT "../apps/server.pem"
185# define TEST_CLIENT_CERT "../apps/client.pem"
186#endif
187
188/*
189 * There is really no standard for this, so let's assign some tentative
190 * numbers.  In any case, these numbers are only for this test
191 */
192#define COMP_RLE        255
193#define COMP_ZLIB       1
194
195static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
196#ifndef OPENSSL_NO_RSA
197static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
198static void free_tmp_rsa(void);
199#endif
200static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
201#define APP_CALLBACK_STRING "Test Callback Argument"
202struct app_verify_arg {
203    char *string;
204    int app_verify;
205    int allow_proxy_certs;
206    char *proxy_auth;
207    char *proxy_cond;
208};
209
210#ifndef OPENSSL_NO_DH
211static DH *get_dh512(void);
212static DH *get_dh1024(void);
213static DH *get_dh1024dsa(void);
214#endif
215
216static BIO *bio_err = NULL;
217static BIO *bio_stdout = NULL;
218
219static char *cipher = NULL;
220static int verbose = 0;
221static int debug = 0;
222#if 0
223/* Not used yet. */
224# ifdef FIONBIO
225static int s_nbio = 0;
226# endif
227#endif
228
229static const char rnd_seed[] =
230    "string to make the random number generator think it has entropy";
231
232int doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time,
233                 clock_t *c_time);
234int doit(SSL *s_ssl, SSL *c_ssl, long bytes);
235static int do_test_cipherlist(void);
236static void sv_usage(void)
237{
238    fprintf(stderr, "usage: ssltest [args ...]\n");
239    fprintf(stderr, "\n");
240#ifdef OPENSSL_FIPS
241    fprintf(stderr, "-F             - run test in FIPS mode\n");
242#endif
243    fprintf(stderr, " -server_auth  - check server certificate\n");
244    fprintf(stderr, " -client_auth  - do client authentication\n");
245    fprintf(stderr, " -proxy        - allow proxy certificates\n");
246    fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n");
247    fprintf(stderr,
248            " -proxy_cond <val> - experssion to test proxy policy rights\n");
249    fprintf(stderr, " -v            - more output\n");
250    fprintf(stderr, " -d            - debug output\n");
251    fprintf(stderr, " -reuse        - use session-id reuse\n");
252    fprintf(stderr, " -num <val>    - number of connections to perform\n");
253    fprintf(stderr,
254            " -bytes <val>  - number of bytes to swap between client/server\n");
255#ifndef OPENSSL_NO_DH
256    fprintf(stderr,
257            " -dhe1024      - use 1024 bit key (safe prime) for DHE\n");
258    fprintf(stderr,
259            " -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
260    fprintf(stderr, " -no_dhe       - disable DHE\n");
261#endif
262#ifndef OPENSSL_NO_ECDH
263    fprintf(stderr, " -no_ecdhe     - disable ECDHE\n");
264#endif
265#ifndef OPENSSL_NO_SSL2
266    fprintf(stderr, " -ssl2         - use SSLv2\n");
267#endif
268#ifndef OPENSSL_NO_SSL3
269    fprintf(stderr, " -ssl3         - use SSLv3\n");
270#endif
271#ifndef OPENSSL_NO_TLS1
272    fprintf(stderr, " -tls1         - use TLSv1\n");
273#endif
274    fprintf(stderr, " -CApath arg   - PEM format directory of CA's\n");
275    fprintf(stderr, " -CAfile arg   - PEM format file of CA's\n");
276    fprintf(stderr, " -cert arg     - Server certificate file\n");
277    fprintf(stderr,
278            " -key arg      - Server key file (default: same as -cert)\n");
279    fprintf(stderr, " -c_cert arg   - Client certificate file\n");
280    fprintf(stderr,
281            " -c_key arg    - Client key file (default: same as -c_cert)\n");
282    fprintf(stderr, " -cipher arg   - The cipher list\n");
283    fprintf(stderr, " -bio_pair     - Use BIO pairs\n");
284    fprintf(stderr, " -f            - Test even cases that can't work\n");
285    fprintf(stderr,
286            " -time         - measure processor time used by client and server\n");
287    fprintf(stderr, " -zlib         - use zlib compression\n");
288    fprintf(stderr, " -rle          - use rle compression\n");
289#ifndef OPENSSL_NO_ECDH
290    fprintf(stderr,
291            " -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n"
292            "                 Use \"openssl ecparam -list_curves\" for all names\n"
293            "                 (default is sect163r2).\n");
294#endif
295    fprintf(stderr,
296            " -test_cipherlist - verifies the order of the ssl cipher lists\n");
297}
298
299static void print_details(SSL *c_ssl, const char *prefix)
300{
301    SSL_CIPHER *ciph;
302    X509 *cert;
303
304    ciph = SSL_get_current_cipher(c_ssl);
305    BIO_printf(bio_stdout, "%s%s, cipher %s %s",
306               prefix,
307               SSL_get_version(c_ssl),
308               SSL_CIPHER_get_version(ciph), SSL_CIPHER_get_name(ciph));
309    cert = SSL_get_peer_certificate(c_ssl);
310    if (cert != NULL) {
311        EVP_PKEY *pkey = X509_get_pubkey(cert);
312        if (pkey != NULL) {
313            if (0) ;
314#ifndef OPENSSL_NO_RSA
315            else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
316                     && pkey->pkey.rsa->n != NULL) {
317                BIO_printf(bio_stdout, ", %d bit RSA",
318                           BN_num_bits(pkey->pkey.rsa->n));
319            }
320#endif
321#ifndef OPENSSL_NO_DSA
322            else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
323                     && pkey->pkey.dsa->p != NULL) {
324                BIO_printf(bio_stdout, ", %d bit DSA",
325                           BN_num_bits(pkey->pkey.dsa->p));
326            }
327#endif
328            EVP_PKEY_free(pkey);
329        }
330        X509_free(cert);
331    }
332    /*
333     * The SSL API does not allow us to look at temporary RSA/DH keys,
334     * otherwise we should print their lengths too
335     */
336    BIO_printf(bio_stdout, "\n");
337}
338
339static void lock_dbg_cb(int mode, int type, const char *file, int line)
340{
341    static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
342    const char *errstr = NULL;
343    int rw;
344
345    rw = mode & (CRYPTO_READ | CRYPTO_WRITE);
346    if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) {
347        errstr = "invalid mode";
348        goto err;
349    }
350
351    if (type < 0 || type >= CRYPTO_NUM_LOCKS) {
352        errstr = "type out of bounds";
353        goto err;
354    }
355
356    if (mode & CRYPTO_LOCK) {
357        if (modes[type]) {
358            errstr = "already locked";
359            /*
360             * must not happen in a single-threaded program (would deadlock)
361             */
362            goto err;
363        }
364
365        modes[type] = rw;
366    } else if (mode & CRYPTO_UNLOCK) {
367        if (!modes[type]) {
368            errstr = "not locked";
369            goto err;
370        }
371
372        if (modes[type] != rw) {
373            errstr = (rw == CRYPTO_READ) ?
374                "CRYPTO_r_unlock on write lock" :
375                "CRYPTO_w_unlock on read lock";
376        }
377
378        modes[type] = 0;
379    } else {
380        errstr = "invalid mode";
381        goto err;
382    }
383
384 err:
385    if (errstr) {
386        /* we cannot use bio_err here */
387        fprintf(stderr,
388                "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
389                errstr, mode, type, file, line);
390    }
391}
392
393int main(int argc, char *argv[])
394{
395    char *CApath = NULL, *CAfile = NULL;
396    int badop = 0;
397    int bio_pair = 0;
398    int force = 0;
399    int tls1 = 0, ssl2 = 0, ssl3 = 0, ret = 1;
400    int client_auth = 0;
401    int server_auth = 0, i;
402    struct app_verify_arg app_verify_arg =
403        { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
404    char *server_cert = TEST_SERVER_CERT;
405    char *server_key = NULL;
406    char *client_cert = TEST_CLIENT_CERT;
407    char *client_key = NULL;
408#ifndef OPENSSL_NO_ECDH
409    char *named_curve = NULL;
410#endif
411    SSL_CTX *s_ctx = NULL;
412    SSL_CTX *c_ctx = NULL;
413    SSL_METHOD *meth = NULL;
414    SSL *c_ssl, *s_ssl;
415    int number = 1, reuse = 0;
416    long bytes = 256L;
417#ifndef OPENSSL_NO_DH
418    DH *dh;
419    int dhe1024 = 1, dhe1024dsa = 0;
420#endif
421#ifndef OPENSSL_NO_ECDH
422    EC_KEY *ecdh = NULL;
423#endif
424    int no_dhe = 0;
425    int no_ecdhe = 0;
426    int print_time = 0;
427    clock_t s_time = 0, c_time = 0;
428    int comp = 0;
429#ifndef OPENSSL_NO_COMP
430    COMP_METHOD *cm = NULL;
431#endif
432    STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
433    int test_cipherlist = 0;
434#ifdef OPENSSL_FIPS
435    int fips_mode = 0;
436#endif
437
438    verbose = 0;
439    debug = 0;
440    cipher = 0;
441
442    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
443
444    CRYPTO_set_locking_callback(lock_dbg_cb);
445
446    /* enable memory leak checking unless explicitly disabled */
447    if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL)
448          && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
449        CRYPTO_malloc_debug_init();
450        CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
451    } else {
452        /* OPENSSL_DEBUG_MEMORY=off */
453        CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
454    }
455    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
456
457    RAND_seed(rnd_seed, sizeof rnd_seed);
458
459    bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
460
461    argc--;
462    argv++;
463
464    while (argc >= 1) {
465        if (!strcmp(*argv, "-F")) {
466#ifdef OPENSSL_FIPS
467            fips_mode = 1;
468#else
469            fprintf(stderr,
470                    "not compiled with FIPS support, so exitting without running.\n");
471            EXIT(0);
472#endif
473        } else if (strcmp(*argv, "-server_auth") == 0)
474            server_auth = 1;
475        else if (strcmp(*argv, "-client_auth") == 0)
476            client_auth = 1;
477        else if (strcmp(*argv, "-proxy_auth") == 0) {
478            if (--argc < 1)
479                goto bad;
480            app_verify_arg.proxy_auth = *(++argv);
481        } else if (strcmp(*argv, "-proxy_cond") == 0) {
482            if (--argc < 1)
483                goto bad;
484            app_verify_arg.proxy_cond = *(++argv);
485        } else if (strcmp(*argv, "-v") == 0)
486            verbose = 1;
487        else if (strcmp(*argv, "-d") == 0)
488            debug = 1;
489        else if (strcmp(*argv, "-reuse") == 0)
490            reuse = 1;
491        else if (strcmp(*argv, "-dhe1024") == 0) {
492#ifndef OPENSSL_NO_DH
493            dhe1024 = 1;
494#else
495            fprintf(stderr,
496                    "ignoring -dhe1024, since I'm compiled without DH\n");
497#endif
498        } else if (strcmp(*argv, "-dhe1024dsa") == 0) {
499#ifndef OPENSSL_NO_DH
500            dhe1024dsa = 1;
501#else
502            fprintf(stderr,
503                    "ignoring -dhe1024, since I'm compiled without DH\n");
504#endif
505        } else if (strcmp(*argv, "-no_dhe") == 0)
506            no_dhe = 1;
507        else if (strcmp(*argv, "-no_ecdhe") == 0)
508            no_ecdhe = 1;
509        else if (strcmp(*argv, "-ssl2") == 0)
510            ssl2 = 1;
511        else if (strcmp(*argv, "-tls1") == 0)
512            tls1 = 1;
513        else if (strcmp(*argv, "-ssl3") == 0)
514            ssl3 = 1;
515        else if (strncmp(*argv, "-num", 4) == 0) {
516            if (--argc < 1)
517                goto bad;
518            number = atoi(*(++argv));
519            if (number == 0)
520                number = 1;
521        } else if (strcmp(*argv, "-bytes") == 0) {
522            if (--argc < 1)
523                goto bad;
524            bytes = atol(*(++argv));
525            if (bytes == 0L)
526                bytes = 1L;
527            i = strlen(argv[0]);
528            if (argv[0][i - 1] == 'k')
529                bytes *= 1024L;
530            if (argv[0][i - 1] == 'm')
531                bytes *= 1024L * 1024L;
532        } else if (strcmp(*argv, "-cert") == 0) {
533            if (--argc < 1)
534                goto bad;
535            server_cert = *(++argv);
536        } else if (strcmp(*argv, "-s_cert") == 0) {
537            if (--argc < 1)
538                goto bad;
539            server_cert = *(++argv);
540        } else if (strcmp(*argv, "-key") == 0) {
541            if (--argc < 1)
542                goto bad;
543            server_key = *(++argv);
544        } else if (strcmp(*argv, "-s_key") == 0) {
545            if (--argc < 1)
546                goto bad;
547            server_key = *(++argv);
548        } else if (strcmp(*argv, "-c_cert") == 0) {
549            if (--argc < 1)
550                goto bad;
551            client_cert = *(++argv);
552        } else if (strcmp(*argv, "-c_key") == 0) {
553            if (--argc < 1)
554                goto bad;
555            client_key = *(++argv);
556        } else if (strcmp(*argv, "-cipher") == 0) {
557            if (--argc < 1)
558                goto bad;
559            cipher = *(++argv);
560        } else if (strcmp(*argv, "-CApath") == 0) {
561            if (--argc < 1)
562                goto bad;
563            CApath = *(++argv);
564        } else if (strcmp(*argv, "-CAfile") == 0) {
565            if (--argc < 1)
566                goto bad;
567            CAfile = *(++argv);
568        } else if (strcmp(*argv, "-bio_pair") == 0) {
569            bio_pair = 1;
570        } else if (strcmp(*argv, "-f") == 0) {
571            force = 1;
572        } else if (strcmp(*argv, "-time") == 0) {
573            print_time = 1;
574        } else if (strcmp(*argv, "-zlib") == 0) {
575            comp = COMP_ZLIB;
576        } else if (strcmp(*argv, "-rle") == 0) {
577            comp = COMP_RLE;
578        } else if (strcmp(*argv, "-named_curve") == 0) {
579            if (--argc < 1)
580                goto bad;
581#ifndef OPENSSL_NO_ECDH
582            named_curve = *(++argv);
583#else
584            fprintf(stderr,
585                    "ignoring -named_curve, since I'm compiled without ECDH\n");
586            ++argv;
587#endif
588        } else if (strcmp(*argv, "-app_verify") == 0) {
589            app_verify_arg.app_verify = 1;
590        } else if (strcmp(*argv, "-proxy") == 0) {
591            app_verify_arg.allow_proxy_certs = 1;
592        } else if (strcmp(*argv, "-test_cipherlist") == 0) {
593            test_cipherlist = 1;
594        } else {
595            fprintf(stderr, "unknown option %s\n", *argv);
596            badop = 1;
597            break;
598        }
599        argc--;
600        argv++;
601    }
602    if (badop) {
603 bad:
604        sv_usage();
605        goto end;
606    }
607
608    if (test_cipherlist == 1) {
609        /*
610         * ensure that the cipher list are correctly sorted and exit
611         */
612        if (do_test_cipherlist() == 0)
613            EXIT(1);
614        ret = 0;
615        goto end;
616    }
617
618    if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) {
619        fprintf(stderr, "This case cannot work.  Use -f to perform "
620                "the test anyway (and\n-d to see what happens), "
621                "or add one of -ssl2, -ssl3, -tls1, -reuse\n"
622                "to avoid protocol mismatch.\n");
623        EXIT(1);
624    }
625#ifdef OPENSSL_FIPS
626    if (fips_mode) {
627        if (!FIPS_mode_set(1)) {
628            ERR_load_crypto_strings();
629            ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
630            EXIT(1);
631        } else
632            fprintf(stderr, "*** IN FIPS MODE ***\n");
633    }
634#endif
635
636    if (print_time) {
637        if (!bio_pair) {
638            fprintf(stderr, "Using BIO pair (-bio_pair)\n");
639            bio_pair = 1;
640        }
641        if (number < 50 && !force)
642            fprintf(stderr,
643                    "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
644    }
645
646/*      if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
647
648    SSL_library_init();
649    SSL_load_error_strings();
650
651#ifndef OPENSSL_NO_COMP
652    if (comp == COMP_ZLIB)
653        cm = COMP_zlib();
654    if (comp == COMP_RLE)
655        cm = COMP_rle();
656    if (cm != NULL) {
657        if (cm->type != NID_undef) {
658            if (SSL_COMP_add_compression_method(comp, cm) != 0) {
659                fprintf(stderr, "Failed to add compression method\n");
660                ERR_print_errors_fp(stderr);
661            }
662        } else {
663            fprintf(stderr,
664                    "Warning: %s compression not supported\n",
665                    (comp == COMP_RLE ? "rle" :
666                     (comp == COMP_ZLIB ? "zlib" : "unknown")));
667            ERR_print_errors_fp(stderr);
668        }
669    }
670    ssl_comp_methods = SSL_COMP_get_compression_methods();
671    fprintf(stderr, "Available compression methods:\n");
672    {
673        int j, n = sk_SSL_COMP_num(ssl_comp_methods);
674        if (n == 0)
675            fprintf(stderr, "  NONE\n");
676        else
677            for (j = 0; j < n; j++) {
678                SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
679                fprintf(stderr, "  %d: %s\n", c->id, c->name);
680            }
681    }
682#endif
683
684#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
685    if (ssl2)
686        meth = SSLv2_method();
687    else if (tls1)
688        meth = TLSv1_method();
689    else if (ssl3)
690        meth = SSLv3_method();
691    else
692        meth = SSLv23_method();
693#else
694# ifdef OPENSSL_NO_SSL2
695    if (tls1)
696        meth = TLSv1_method();
697    else if (ssl3)
698        meth = SSLv3_method();
699    else
700        meth = SSLv23_method();
701# else
702    meth = SSLv2_method();
703# endif
704#endif
705
706    c_ctx = SSL_CTX_new(meth);
707    s_ctx = SSL_CTX_new(meth);
708    if ((c_ctx == NULL) || (s_ctx == NULL)) {
709        ERR_print_errors(bio_err);
710        goto end;
711    }
712
713    if (cipher != NULL) {
714        SSL_CTX_set_cipher_list(c_ctx, cipher);
715        SSL_CTX_set_cipher_list(s_ctx, cipher);
716    }
717#ifndef OPENSSL_NO_DH
718    if (!no_dhe) {
719        if (dhe1024dsa) {
720            /*
721             * use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks
722             */
723            SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
724            dh = get_dh1024dsa();
725        } else if (dhe1024)
726            dh = get_dh1024();
727        else
728            dh = get_dh512();
729        SSL_CTX_set_tmp_dh(s_ctx, dh);
730        DH_free(dh);
731    }
732#else
733    (void)no_dhe;
734#endif
735
736#ifndef OPENSSL_NO_ECDH
737    if (!no_ecdhe) {
738        int nid;
739
740        if (named_curve != NULL) {
741            nid = OBJ_sn2nid(named_curve);
742            if (nid == 0) {
743                BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
744                goto end;
745            }
746        } else
747            nid = NID_sect163r2;
748
749        ecdh = EC_KEY_new_by_curve_name(nid);
750        if (ecdh == NULL) {
751            BIO_printf(bio_err, "unable to create curve\n");
752            goto end;
753        }
754
755        SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
756        SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
757        EC_KEY_free(ecdh);
758    }
759#else
760    (void)no_ecdhe;
761#endif
762
763#ifndef OPENSSL_NO_RSA
764    SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb);
765#endif
766
767    if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, SSL_FILETYPE_PEM)) {
768        ERR_print_errors(bio_err);
769    } else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
770                                            (server_key ? server_key :
771                                             server_cert),
772                                            SSL_FILETYPE_PEM)) {
773        ERR_print_errors(bio_err);
774        goto end;
775    }
776
777    if (client_auth) {
778        SSL_CTX_use_certificate_file(c_ctx, client_cert, SSL_FILETYPE_PEM);
779        SSL_CTX_use_PrivateKey_file(c_ctx,
780                                    (client_key ? client_key : client_cert),
781                                    SSL_FILETYPE_PEM);
782    }
783
784    if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) ||
785        (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
786        (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) ||
787        (!SSL_CTX_set_default_verify_paths(c_ctx))) {
788        /* fprintf(stderr,"SSL_load_verify_locations\n"); */
789        ERR_print_errors(bio_err);
790        /* goto end; */
791    }
792
793    if (client_auth) {
794        BIO_printf(bio_err, "client authentication\n");
795        SSL_CTX_set_verify(s_ctx,
796                           SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
797                           verify_callback);
798        SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback,
799                                         &app_verify_arg);
800    }
801    if (server_auth) {
802        BIO_printf(bio_err, "server authentication\n");
803        SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback);
804        SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback,
805                                         &app_verify_arg);
806    }
807
808    {
809        int session_id_context = 0;
810        SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context,
811                                       sizeof session_id_context);
812    }
813
814    c_ssl = SSL_new(c_ctx);
815    s_ssl = SSL_new(s_ctx);
816
817#ifndef OPENSSL_NO_KRB5
818    if (c_ssl && c_ssl->kssl_ctx) {
819        char localhost[MAXHOSTNAMELEN + 2];
820
821        if (gethostname(localhost, sizeof localhost - 1) == 0) {
822            localhost[sizeof localhost - 1] = '\0';
823            if (strlen(localhost) == sizeof localhost - 1) {
824                BIO_printf(bio_err, "localhost name too long\n");
825                goto end;
826            }
827            kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost);
828        }
829    }
830#endif                          /* OPENSSL_NO_KRB5 */
831
832    for (i = 0; i < number; i++) {
833        if (!reuse)
834            SSL_set_session(c_ssl, NULL);
835        if (bio_pair)
836            ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, &c_time);
837        else
838            ret = doit(s_ssl, c_ssl, bytes);
839    }
840
841    if (!verbose) {
842        print_details(c_ssl, "");
843    }
844    if ((number > 1) || (bytes > 1L))
845        BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", number,
846                   bytes);
847    if (print_time) {
848#ifdef CLOCKS_PER_SEC
849        /*
850         * "To determine the time in seconds, the value returned by the clock
851         * function should be divided by the value of the macro
852         * CLOCKS_PER_SEC." -- ISO/IEC 9899
853         */
854        BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n"
855                   "Approximate total client time: %6.2f s\n",
856                   (double)s_time / CLOCKS_PER_SEC,
857                   (double)c_time / CLOCKS_PER_SEC);
858#else
859        /*
860         * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on
861         * NeXTstep/OpenStep
862         */
863        BIO_printf(bio_stdout,
864                   "Approximate total server time: %6.2f units\n"
865                   "Approximate total client time: %6.2f units\n",
866                   (double)s_time, (double)c_time);
867#endif
868    }
869
870    SSL_free(s_ssl);
871    SSL_free(c_ssl);
872
873 end:
874    if (s_ctx != NULL)
875        SSL_CTX_free(s_ctx);
876    if (c_ctx != NULL)
877        SSL_CTX_free(c_ctx);
878
879    if (bio_stdout != NULL)
880        BIO_free(bio_stdout);
881
882#ifndef OPENSSL_NO_RSA
883    free_tmp_rsa();
884#endif
885#ifndef OPENSSL_NO_ENGINE
886    ENGINE_cleanup();
887#endif
888    CRYPTO_cleanup_all_ex_data();
889    ERR_free_strings();
890    ERR_remove_state(0);
891    EVP_cleanup();
892    CRYPTO_mem_leaks(bio_err);
893    if (bio_err != NULL)
894        BIO_free(bio_err);
895    EXIT(ret);
896    return ret;
897}
898
899int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
900                 clock_t *s_time, clock_t *c_time)
901{
902    long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
903    BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
904    BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
905    int ret = 1;
906
907    size_t bufsiz = 256;        /* small buffer for testing */
908
909    if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
910        goto err;
911    if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
912        goto err;
913
914    s_ssl_bio = BIO_new(BIO_f_ssl());
915    if (!s_ssl_bio)
916        goto err;
917
918    c_ssl_bio = BIO_new(BIO_f_ssl());
919    if (!c_ssl_bio)
920        goto err;
921
922    SSL_set_connect_state(c_ssl);
923    SSL_set_bio(c_ssl, client, client);
924    (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
925
926    SSL_set_accept_state(s_ssl);
927    SSL_set_bio(s_ssl, server, server);
928    (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
929
930    do {
931        /*-
932         * c_ssl_bio:          SSL filter BIO
933         *
934         * client:             pseudo-I/O for SSL library
935         *
936         * client_io:          client's SSL communication; usually to be
937         *                     relayed over some I/O facility, but in this
938         *                     test program, we're the server, too:
939         *
940         * server_io:          server's SSL communication
941         *
942         * server:             pseudo-I/O for SSL library
943         *
944         * s_ssl_bio:          SSL filter BIO
945         *
946         * The client and the server each employ a "BIO pair":
947         * client + client_io, server + server_io.
948         * BIO pairs are symmetric.  A BIO pair behaves similar
949         * to a non-blocking socketpair (but both endpoints must
950         * be handled by the same thread).
951         * [Here we could connect client and server to the ends
952         * of a single BIO pair, but then this code would be less
953         * suitable as an example for BIO pairs in general.]
954         *
955         * Useful functions for querying the state of BIO pair endpoints:
956         *
957         * BIO_ctrl_pending(bio)              number of bytes we can read now
958         * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
959         *                                      other side's read attempt
960         * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
961         *
962         * ..._read_request is never more than ..._write_guarantee;
963         * it depends on the application which one you should use.
964         */
965
966        /*
967         * We have non-blocking behaviour throughout this test program, but
968         * can be sure that there is *some* progress in each iteration; so we
969         * don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE --
970         * we just try everything in each iteration
971         */
972
973        {
974            /* CLIENT */
975
976            MS_STATIC char cbuf[1024 * 8];
977            int i, r;
978            clock_t c_clock = clock();
979
980            memset(cbuf, 0, sizeof(cbuf));
981
982            if (debug)
983                if (SSL_in_init(c_ssl))
984                    printf("client waiting in SSL_connect - %s\n",
985                           SSL_state_string_long(c_ssl));
986
987            if (cw_num > 0) {
988                /* Write to server. */
989
990                if (cw_num > (long)sizeof cbuf)
991                    i = sizeof cbuf;
992                else
993                    i = (int)cw_num;
994                r = BIO_write(c_ssl_bio, cbuf, i);
995                if (r < 0) {
996                    if (!BIO_should_retry(c_ssl_bio)) {
997                        fprintf(stderr, "ERROR in CLIENT\n");
998                        goto err;
999                    }
1000                    /*
1001                     * BIO_should_retry(...) can just be ignored here. The
1002                     * library expects us to call BIO_write with the same
1003                     * arguments again, and that's what we will do in the
1004                     * next iteration.
1005                     */
1006                } else if (r == 0) {
1007                    fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1008                    goto err;
1009                } else {
1010                    if (debug)
1011                        printf("client wrote %d\n", r);
1012                    cw_num -= r;
1013                }
1014            }
1015
1016            if (cr_num > 0) {
1017                /* Read from server. */
1018
1019                r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
1020                if (r < 0) {
1021                    if (!BIO_should_retry(c_ssl_bio)) {
1022                        fprintf(stderr, "ERROR in CLIENT\n");
1023                        goto err;
1024                    }
1025                    /*
1026                     * Again, "BIO_should_retry" can be ignored.
1027                     */
1028                } else if (r == 0) {
1029                    fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1030                    goto err;
1031                } else {
1032                    if (debug)
1033                        printf("client read %d\n", r);
1034                    cr_num -= r;
1035                }
1036            }
1037
1038            /*
1039             * c_time and s_time increments will typically be very small
1040             * (depending on machine speed and clock tick intervals), but
1041             * sampling over a large number of connections should result in
1042             * fairly accurate figures.  We cannot guarantee a lot, however
1043             * -- if each connection lasts for exactly one clock tick, it
1044             * will be counted only for the client or only for the server or
1045             * even not at all.
1046             */
1047            *c_time += (clock() - c_clock);
1048        }
1049
1050        {
1051            /* SERVER */
1052
1053            MS_STATIC char sbuf[1024 * 8];
1054            int i, r;
1055            clock_t s_clock = clock();
1056
1057            memset(sbuf, 0, sizeof(sbuf));
1058
1059            if (debug)
1060                if (SSL_in_init(s_ssl))
1061                    printf("server waiting in SSL_accept - %s\n",
1062                           SSL_state_string_long(s_ssl));
1063
1064            if (sw_num > 0) {
1065                /* Write to client. */
1066
1067                if (sw_num > (long)sizeof sbuf)
1068                    i = sizeof sbuf;
1069                else
1070                    i = (int)sw_num;
1071                r = BIO_write(s_ssl_bio, sbuf, i);
1072                if (r < 0) {
1073                    if (!BIO_should_retry(s_ssl_bio)) {
1074                        fprintf(stderr, "ERROR in SERVER\n");
1075                        goto err;
1076                    }
1077                    /* Ignore "BIO_should_retry". */
1078                } else if (r == 0) {
1079                    fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
1080                    goto err;
1081                } else {
1082                    if (debug)
1083                        printf("server wrote %d\n", r);
1084                    sw_num -= r;
1085                }
1086            }
1087
1088            if (sr_num > 0) {
1089                /* Read from client. */
1090
1091                r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
1092                if (r < 0) {
1093                    if (!BIO_should_retry(s_ssl_bio)) {
1094                        fprintf(stderr, "ERROR in SERVER\n");
1095                        goto err;
1096                    }
1097                    /* blah, blah */
1098                } else if (r == 0) {
1099                    fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
1100                    goto err;
1101                } else {
1102                    if (debug)
1103                        printf("server read %d\n", r);
1104                    sr_num -= r;
1105                }
1106            }
1107
1108            *s_time += (clock() - s_clock);
1109        }
1110
1111        {
1112            /* "I/O" BETWEEN CLIENT AND SERVER. */
1113
1114            size_t r1, r2;
1115            BIO *io1 = server_io, *io2 = client_io;
1116            /*
1117             * we use the non-copying interface for io1 and the standard
1118             * BIO_write/BIO_read interface for io2
1119             */
1120
1121            static int prev_progress = 1;
1122            int progress = 0;
1123
1124            /* io1 to io2 */
1125            do {
1126                size_t num;
1127                int r;
1128
1129                r1 = BIO_ctrl_pending(io1);
1130                r2 = BIO_ctrl_get_write_guarantee(io2);
1131
1132                num = r1;
1133                if (r2 < num)
1134                    num = r2;
1135                if (num) {
1136                    char *dataptr;
1137
1138                    if (INT_MAX < num) /* yeah, right */
1139                        num = INT_MAX;
1140
1141                    r = BIO_nread(io1, &dataptr, (int)num);
1142                    assert(r > 0);
1143                    assert(r <= (int)num);
1144                    /*
1145                     * possibly r < num (non-contiguous data)
1146                     */
1147                    num = r;
1148                    r = BIO_write(io2, dataptr, (int)num);
1149                    if (r != (int)num) { /* can't happen */
1150                        fprintf(stderr, "ERROR: BIO_write could not write "
1151                                "BIO_ctrl_get_write_guarantee() bytes");
1152                        goto err;
1153                    }
1154                    progress = 1;
1155
1156                    if (debug)
1157                        printf((io1 == client_io) ?
1158                               "C->S relaying: %d bytes\n" :
1159                               "S->C relaying: %d bytes\n", (int)num);
1160                }
1161            }
1162            while (r1 && r2);
1163
1164            /* io2 to io1 */
1165            {
1166                size_t num;
1167                int r;
1168
1169                r1 = BIO_ctrl_pending(io2);
1170                r2 = BIO_ctrl_get_read_request(io1);
1171                /*
1172                 * here we could use ..._get_write_guarantee instead of
1173                 * ..._get_read_request, but by using the latter we test
1174                 * restartability of the SSL implementation more thoroughly
1175                 */
1176                num = r1;
1177                if (r2 < num)
1178                    num = r2;
1179                if (num) {
1180                    char *dataptr;
1181
1182                    if (INT_MAX < num)
1183                        num = INT_MAX;
1184
1185                    if (num > 1)
1186                        --num;  /* test restartability even more thoroughly */
1187
1188                    r = BIO_nwrite0(io1, &dataptr);
1189                    assert(r > 0);
1190                    if (r < (int)num)
1191                        num = r;
1192                    r = BIO_read(io2, dataptr, (int)num);
1193                    if (r != (int)num) { /* can't happen */
1194                        fprintf(stderr, "ERROR: BIO_read could not read "
1195                                "BIO_ctrl_pending() bytes");
1196                        goto err;
1197                    }
1198                    progress = 1;
1199                    r = BIO_nwrite(io1, &dataptr, (int)num);
1200                    if (r != (int)num) { /* can't happen */
1201                        fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
1202                                "BIO_nwrite0() bytes");
1203                        goto err;
1204                    }
1205
1206                    if (debug)
1207                        printf((io2 == client_io) ?
1208                               "C->S relaying: %d bytes\n" :
1209                               "S->C relaying: %d bytes\n", (int)num);
1210                }
1211            }                   /* no loop, BIO_ctrl_get_read_request now
1212                                 * returns 0 anyway */
1213
1214            if (!progress && !prev_progress)
1215                if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) {
1216                    fprintf(stderr, "ERROR: got stuck\n");
1217                    if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0) {
1218                        fprintf(stderr, "This can happen for SSL2 because "
1219                                "CLIENT-FINISHED and SERVER-VERIFY are written \n"
1220                                "concurrently ...");
1221                        if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
1222                            && strncmp("2SSV", SSL_state_string(s_ssl),
1223                                       4) == 0) {
1224                            fprintf(stderr, " ok.\n");
1225                            goto end;
1226                        }
1227                    }
1228                    fprintf(stderr, " ERROR.\n");
1229                    goto err;
1230                }
1231            prev_progress = progress;
1232        }
1233    }
1234    while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
1235
1236    if (verbose)
1237        print_details(c_ssl, "DONE via BIO pair: ");
1238 end:
1239    ret = 0;
1240
1241 err:
1242    ERR_print_errors(bio_err);
1243
1244    if (server)
1245        BIO_free(server);
1246    if (server_io)
1247        BIO_free(server_io);
1248    if (client)
1249        BIO_free(client);
1250    if (client_io)
1251        BIO_free(client_io);
1252    if (s_ssl_bio)
1253        BIO_free(s_ssl_bio);
1254    if (c_ssl_bio)
1255        BIO_free(c_ssl_bio);
1256
1257    return ret;
1258}
1259
1260#define W_READ  1
1261#define W_WRITE 2
1262#define C_DONE  1
1263#define S_DONE  2
1264
1265int doit(SSL *s_ssl, SSL *c_ssl, long count)
1266{
1267    MS_STATIC char cbuf[1024 * 8], sbuf[1024 * 8];
1268    long cw_num = count, cr_num = count;
1269    long sw_num = count, sr_num = count;
1270    int ret = 1;
1271    BIO *c_to_s = NULL;
1272    BIO *s_to_c = NULL;
1273    BIO *c_bio = NULL;
1274    BIO *s_bio = NULL;
1275    int c_r, c_w, s_r, s_w;
1276    int i, j;
1277    int done = 0;
1278    int c_write, s_write;
1279    int do_server = 0, do_client = 0;
1280
1281    memset(cbuf, 0, sizeof(cbuf));
1282    memset(sbuf, 0, sizeof(sbuf));
1283
1284    c_to_s = BIO_new(BIO_s_mem());
1285    s_to_c = BIO_new(BIO_s_mem());
1286    if ((s_to_c == NULL) || (c_to_s == NULL)) {
1287        ERR_print_errors(bio_err);
1288        goto err;
1289    }
1290
1291    c_bio = BIO_new(BIO_f_ssl());
1292    s_bio = BIO_new(BIO_f_ssl());
1293    if ((c_bio == NULL) || (s_bio == NULL)) {
1294        ERR_print_errors(bio_err);
1295        goto err;
1296    }
1297
1298    SSL_set_connect_state(c_ssl);
1299    SSL_set_bio(c_ssl, s_to_c, c_to_s);
1300    BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE);
1301
1302    SSL_set_accept_state(s_ssl);
1303    SSL_set_bio(s_ssl, c_to_s, s_to_c);
1304    BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE);
1305
1306    c_r = 0;
1307    s_r = 1;
1308    c_w = 1;
1309    s_w = 0;
1310    c_write = 1, s_write = 0;
1311
1312    /* We can always do writes */
1313    for (;;) {
1314        do_server = 0;
1315        do_client = 0;
1316
1317        i = (int)BIO_pending(s_bio);
1318        if ((i && s_r) || s_w)
1319            do_server = 1;
1320
1321        i = (int)BIO_pending(c_bio);
1322        if ((i && c_r) || c_w)
1323            do_client = 1;
1324
1325        if (do_server && debug) {
1326            if (SSL_in_init(s_ssl))
1327                printf("server waiting in SSL_accept - %s\n",
1328                       SSL_state_string_long(s_ssl));
1329/*-
1330            else if (s_write)
1331                printf("server:SSL_write()\n");
1332            else
1333                printf("server:SSL_read()\n"); */
1334        }
1335
1336        if (do_client && debug) {
1337            if (SSL_in_init(c_ssl))
1338                printf("client waiting in SSL_connect - %s\n",
1339                       SSL_state_string_long(c_ssl));
1340/*-
1341            else if (c_write)
1342                printf("client:SSL_write()\n");
1343            else
1344                printf("client:SSL_read()\n"); */
1345        }
1346
1347        if (!do_client && !do_server) {
1348            fprintf(stdout, "ERROR IN STARTUP\n");
1349            ERR_print_errors(bio_err);
1350            goto err;
1351        }
1352        if (do_client && !(done & C_DONE)) {
1353            if (c_write) {
1354                j = (cw_num > (long)sizeof(cbuf)) ?
1355                    (int)sizeof(cbuf) : (int)cw_num;
1356                i = BIO_write(c_bio, cbuf, j);
1357                if (i < 0) {
1358                    c_r = 0;
1359                    c_w = 0;
1360                    if (BIO_should_retry(c_bio)) {
1361                        if (BIO_should_read(c_bio))
1362                            c_r = 1;
1363                        if (BIO_should_write(c_bio))
1364                            c_w = 1;
1365                    } else {
1366                        fprintf(stderr, "ERROR in CLIENT\n");
1367                        ERR_print_errors(bio_err);
1368                        goto err;
1369                    }
1370                } else if (i == 0) {
1371                    fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1372                    goto err;
1373                } else {
1374                    if (debug)
1375                        printf("client wrote %d\n", i);
1376                    /* ok */
1377                    s_r = 1;
1378                    c_write = 0;
1379                    cw_num -= i;
1380                }
1381            } else {
1382                i = BIO_read(c_bio, cbuf, sizeof(cbuf));
1383                if (i < 0) {
1384                    c_r = 0;
1385                    c_w = 0;
1386                    if (BIO_should_retry(c_bio)) {
1387                        if (BIO_should_read(c_bio))
1388                            c_r = 1;
1389                        if (BIO_should_write(c_bio))
1390                            c_w = 1;
1391                    } else {
1392                        fprintf(stderr, "ERROR in CLIENT\n");
1393                        ERR_print_errors(bio_err);
1394                        goto err;
1395                    }
1396                } else if (i == 0) {
1397                    fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1398                    goto err;
1399                } else {
1400                    if (debug)
1401                        printf("client read %d\n", i);
1402                    cr_num -= i;
1403                    if (sw_num > 0) {
1404                        s_write = 1;
1405                        s_w = 1;
1406                    }
1407                    if (cr_num <= 0) {
1408                        s_write = 1;
1409                        s_w = 1;
1410                        done = S_DONE | C_DONE;
1411                    }
1412                }
1413            }
1414        }
1415
1416        if (do_server && !(done & S_DONE)) {
1417            if (!s_write) {
1418                i = BIO_read(s_bio, sbuf, sizeof(cbuf));
1419                if (i < 0) {
1420                    s_r = 0;
1421                    s_w = 0;
1422                    if (BIO_should_retry(s_bio)) {
1423                        if (BIO_should_read(s_bio))
1424                            s_r = 1;
1425                        if (BIO_should_write(s_bio))
1426                            s_w = 1;
1427                    } else {
1428                        fprintf(stderr, "ERROR in SERVER\n");
1429                        ERR_print_errors(bio_err);
1430                        goto err;
1431                    }
1432                } else if (i == 0) {
1433                    ERR_print_errors(bio_err);
1434                    fprintf(stderr,
1435                            "SSL SERVER STARTUP FAILED in SSL_read\n");
1436                    goto err;
1437                } else {
1438                    if (debug)
1439                        printf("server read %d\n", i);
1440                    sr_num -= i;
1441                    if (cw_num > 0) {
1442                        c_write = 1;
1443                        c_w = 1;
1444                    }
1445                    if (sr_num <= 0) {
1446                        s_write = 1;
1447                        s_w = 1;
1448                        c_write = 0;
1449                    }
1450                }
1451            } else {
1452                j = (sw_num > (long)sizeof(sbuf)) ?
1453                    (int)sizeof(sbuf) : (int)sw_num;
1454                i = BIO_write(s_bio, sbuf, j);
1455                if (i < 0) {
1456                    s_r = 0;
1457                    s_w = 0;
1458                    if (BIO_should_retry(s_bio)) {
1459                        if (BIO_should_read(s_bio))
1460                            s_r = 1;
1461                        if (BIO_should_write(s_bio))
1462                            s_w = 1;
1463                    } else {
1464                        fprintf(stderr, "ERROR in SERVER\n");
1465                        ERR_print_errors(bio_err);
1466                        goto err;
1467                    }
1468                } else if (i == 0) {
1469                    ERR_print_errors(bio_err);
1470                    fprintf(stderr,
1471                            "SSL SERVER STARTUP FAILED in SSL_write\n");
1472                    goto err;
1473                } else {
1474                    if (debug)
1475                        printf("server wrote %d\n", i);
1476                    sw_num -= i;
1477                    s_write = 0;
1478                    c_r = 1;
1479                    if (sw_num <= 0)
1480                        done |= S_DONE;
1481                }
1482            }
1483        }
1484
1485        if ((done & S_DONE) && (done & C_DONE))
1486            break;
1487    }
1488
1489    if (verbose)
1490        print_details(c_ssl, "DONE: ");
1491    ret = 0;
1492 err:
1493    /*
1494     * We have to set the BIO's to NULL otherwise they will be
1495     * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and again
1496     * when c_ssl is SSL_free()ed. This is a hack required because s_ssl and
1497     * c_ssl are sharing the same BIO structure and SSL_set_bio() and
1498     * SSL_free() automatically BIO_free non NULL entries. You should not
1499     * normally do this or be required to do this
1500     */
1501    if (s_ssl != NULL) {
1502        s_ssl->rbio = NULL;
1503        s_ssl->wbio = NULL;
1504    }
1505    if (c_ssl != NULL) {
1506        c_ssl->rbio = NULL;
1507        c_ssl->wbio = NULL;
1508    }
1509
1510    if (c_to_s != NULL)
1511        BIO_free(c_to_s);
1512    if (s_to_c != NULL)
1513        BIO_free(s_to_c);
1514    if (c_bio != NULL)
1515        BIO_free_all(c_bio);
1516    if (s_bio != NULL)
1517        BIO_free_all(s_bio);
1518    return (ret);
1519}
1520
1521static int get_proxy_auth_ex_data_idx(void)
1522{
1523    static volatile int idx = -1;
1524    if (idx < 0) {
1525        CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
1526        if (idx < 0) {
1527            idx = X509_STORE_CTX_get_ex_new_index(0,
1528                                                  "SSLtest for verify callback",
1529                                                  NULL, NULL, NULL);
1530        }
1531        CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
1532    }
1533    return idx;
1534}
1535
1536static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
1537{
1538    char *s, buf[256];
1539
1540    s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf,
1541                          sizeof buf);
1542    if (s != NULL) {
1543        if (ok)
1544            fprintf(stderr, "depth=%d %s\n", ctx->error_depth, buf);
1545        else {
1546            fprintf(stderr, "depth=%d error=%d %s\n",
1547                    ctx->error_depth, ctx->error, buf);
1548        }
1549    }
1550
1551    if (ok == 0) {
1552        fprintf(stderr, "Error string: %s\n",
1553                X509_verify_cert_error_string(ctx->error));
1554        switch (ctx->error) {
1555        case X509_V_ERR_CERT_NOT_YET_VALID:
1556        case X509_V_ERR_CERT_HAS_EXPIRED:
1557        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1558            fprintf(stderr, "  ... ignored.\n");
1559            ok = 1;
1560        }
1561    }
1562
1563    if (ok == 1) {
1564        X509 *xs = ctx->current_cert;
1565#if 0
1566        X509 *xi = ctx->current_issuer;
1567#endif
1568
1569        if (xs->ex_flags & EXFLAG_PROXY) {
1570            unsigned int *letters = X509_STORE_CTX_get_ex_data(ctx,
1571                                                               get_proxy_auth_ex_data_idx
1572                                                               ());
1573
1574            if (letters) {
1575                int found_any = 0;
1576                int i;
1577                PROXY_CERT_INFO_EXTENSION *pci =
1578                    X509_get_ext_d2i(xs, NID_proxyCertInfo,
1579                                     NULL, NULL);
1580
1581                switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
1582                case NID_Independent:
1583                    /*
1584                     * Completely meaningless in this program, as there's no
1585                     * way to grant explicit rights to a specific PrC.
1586                     * Basically, using id-ppl-Independent is the perfect way
1587                     * to grant no rights at all.
1588                     */
1589                    fprintf(stderr, "  Independent proxy certificate");
1590                    for (i = 0; i < 26; i++)
1591                        letters[i] = 0;
1592                    break;
1593                case NID_id_ppl_inheritAll:
1594                    /*
1595                     * This is basically a NOP, we simply let the current
1596                     * rights stand as they are.
1597                     */
1598                    fprintf(stderr, "  Proxy certificate inherits all");
1599                    break;
1600                default:
1601                    s = (char *)
1602                        pci->proxyPolicy->policy->data;
1603                    i = pci->proxyPolicy->policy->length;
1604
1605                    /*
1606                     * The algorithm works as follows: it is assumed that
1607                     * previous iterations or the initial granted rights has
1608                     * already set some elements of `letters'.  What we need
1609                     * to do is to clear those that weren't granted by the
1610                     * current PrC as well.  The easiest way to do this is to
1611                     * add 1 to all the elements whose letters are given with
1612                     * the current policy. That way, all elements that are
1613                     * set by the current policy and were already set by
1614                     * earlier policies and through the original grant of
1615                     * rights will get the value 2 or higher. The last thing
1616                     * to do is to sweep through `letters' and keep the
1617                     * elements having the value 2 as set, and clear all the
1618                     * others.
1619                     */
1620
1621                    fprintf(stderr, "  Certificate proxy rights = %*.*s", i,
1622                            i, s);
1623                    while (i-- > 0) {
1624                        int c = *s++;
1625                        if (isascii(c) && isalpha(c)) {
1626                            if (islower(c))
1627                                c = toupper(c);
1628                            letters[c - 'A']++;
1629                        }
1630                    }
1631                    for (i = 0; i < 26; i++)
1632                        if (letters[i] < 2)
1633                            letters[i] = 0;
1634                        else
1635                            letters[i] = 1;
1636                }
1637
1638                found_any = 0;
1639                fprintf(stderr, ", resulting proxy rights = ");
1640                for (i = 0; i < 26; i++)
1641                    if (letters[i]) {
1642                        fprintf(stderr, "%c", i + 'A');
1643                        found_any = 1;
1644                    }
1645                if (!found_any)
1646                    fprintf(stderr, "none");
1647                fprintf(stderr, "\n");
1648
1649                PROXY_CERT_INFO_EXTENSION_free(pci);
1650            }
1651        }
1652    }
1653
1654    return (ok);
1655}
1656
1657static void process_proxy_debug(int indent, const char *format, ...)
1658{
1659    /* That's 80 > */
1660    static const char indentation[] =
1661        ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
1662        ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
1663    char my_format[256];
1664    va_list args;
1665
1666    BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
1667                 indent, indent, indentation, format);
1668
1669    va_start(args, format);
1670    vfprintf(stderr, my_format, args);
1671    va_end(args);
1672}
1673
1674/*-
1675 * Priority levels:
1676 *  0   [!]var, ()
1677 *  1   & ^
1678 *  2   |
1679 */
1680static int process_proxy_cond_adders(unsigned int letters[26],
1681                                     const char *cond, const char **cond_end,
1682                                     int *pos, int indent);
1683static int process_proxy_cond_val(unsigned int letters[26], const char *cond,
1684                                  const char **cond_end, int *pos, int indent)
1685{
1686    int c;
1687    int ok = 1;
1688    int negate = 0;
1689
1690    while (isspace((int)*cond)) {
1691        cond++;
1692        (*pos)++;
1693    }
1694    c = *cond;
1695
1696    if (debug)
1697        process_proxy_debug(indent,
1698                            "Start process_proxy_cond_val at position %d: %s\n",
1699                            *pos, cond);
1700
1701    while (c == '!') {
1702        negate = !negate;
1703        cond++;
1704        (*pos)++;
1705        while (isspace((int)*cond)) {
1706            cond++;
1707            (*pos)++;
1708        }
1709        c = *cond;
1710    }
1711
1712    if (c == '(') {
1713        cond++;
1714        (*pos)++;
1715        ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
1716                                       indent + 1);
1717        cond = *cond_end;
1718        if (ok < 0)
1719            goto end;
1720        while (isspace((int)*cond)) {
1721            cond++;
1722            (*pos)++;
1723        }
1724        c = *cond;
1725        if (c != ')') {
1726            fprintf(stderr,
1727                    "Weird condition character in position %d: "
1728                    "%c\n", *pos, c);
1729            ok = -1;
1730            goto end;
1731        }
1732        cond++;
1733        (*pos)++;
1734    } else if (isascii(c) && isalpha(c)) {
1735        if (islower(c))
1736            c = toupper(c);
1737        ok = letters[c - 'A'];
1738        cond++;
1739        (*pos)++;
1740    } else {
1741        fprintf(stderr,
1742                "Weird condition character in position %d: " "%c\n", *pos, c);
1743        ok = -1;
1744        goto end;
1745    }
1746 end:
1747    *cond_end = cond;
1748    if (ok >= 0 && negate)
1749        ok = !ok;
1750
1751    if (debug)
1752        process_proxy_debug(indent,
1753                            "End process_proxy_cond_val at position %d: %s, returning %d\n",
1754                            *pos, cond, ok);
1755
1756    return ok;
1757}
1758
1759static int process_proxy_cond_multipliers(unsigned int letters[26],
1760                                          const char *cond,
1761                                          const char **cond_end, int *pos,
1762                                          int indent)
1763{
1764    int ok;
1765    char c;
1766
1767    if (debug)
1768        process_proxy_debug(indent,
1769                            "Start process_proxy_cond_multipliers at position %d: %s\n",
1770                            *pos, cond);
1771
1772    ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
1773    cond = *cond_end;
1774    if (ok < 0)
1775        goto end;
1776
1777    while (ok >= 0) {
1778        while (isspace((int)*cond)) {
1779            cond++;
1780            (*pos)++;
1781        }
1782        c = *cond;
1783
1784        switch (c) {
1785        case '&':
1786        case '^':
1787            {
1788                int save_ok = ok;
1789
1790                cond++;
1791                (*pos)++;
1792                ok = process_proxy_cond_val(letters,
1793                                            cond, cond_end, pos, indent + 1);
1794                cond = *cond_end;
1795                if (ok < 0)
1796                    break;
1797
1798                switch (c) {
1799                case '&':
1800                    ok &= save_ok;
1801                    break;
1802                case '^':
1803                    ok ^= save_ok;
1804                    break;
1805                default:
1806                    fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1807                            " STOPPING\n");
1808                    EXIT(1);
1809                }
1810            }
1811            break;
1812        default:
1813            goto end;
1814        }
1815    }
1816 end:
1817    if (debug)
1818        process_proxy_debug(indent,
1819                            "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
1820                            *pos, cond, ok);
1821
1822    *cond_end = cond;
1823    return ok;
1824}
1825
1826static int process_proxy_cond_adders(unsigned int letters[26],
1827                                     const char *cond, const char **cond_end,
1828                                     int *pos, int indent)
1829{
1830    int ok;
1831    char c;
1832
1833    if (debug)
1834        process_proxy_debug(indent,
1835                            "Start process_proxy_cond_adders at position %d: %s\n",
1836                            *pos, cond);
1837
1838    ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
1839                                        indent + 1);
1840    cond = *cond_end;
1841    if (ok < 0)
1842        goto end;
1843
1844    while (ok >= 0) {
1845        while (isspace((int)*cond)) {
1846            cond++;
1847            (*pos)++;
1848        }
1849        c = *cond;
1850
1851        switch (c) {
1852        case '|':
1853            {
1854                int save_ok = ok;
1855
1856                cond++;
1857                (*pos)++;
1858                ok = process_proxy_cond_multipliers(letters,
1859                                                    cond, cond_end, pos,
1860                                                    indent + 1);
1861                cond = *cond_end;
1862                if (ok < 0)
1863                    break;
1864
1865                switch (c) {
1866                case '|':
1867                    ok |= save_ok;
1868                    break;
1869                default:
1870                    fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1871                            " STOPPING\n");
1872                    EXIT(1);
1873                }
1874            }
1875            break;
1876        default:
1877            goto end;
1878        }
1879    }
1880 end:
1881    if (debug)
1882        process_proxy_debug(indent,
1883                            "End process_proxy_cond_adders at position %d: %s, returning %d\n",
1884                            *pos, cond, ok);
1885
1886    *cond_end = cond;
1887    return ok;
1888}
1889
1890static int process_proxy_cond(unsigned int letters[26],
1891                              const char *cond, const char **cond_end)
1892{
1893    int pos = 1;
1894    return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
1895}
1896
1897static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
1898{
1899    int ok = 1;
1900    struct app_verify_arg *cb_arg = arg;
1901    unsigned int letters[26];   /* only used with proxy_auth */
1902
1903    if (cb_arg->app_verify) {
1904        char *s = NULL, buf[256];
1905
1906        fprintf(stderr, "In app_verify_callback, allowing cert. ");
1907        fprintf(stderr, "Arg is: %s\n", cb_arg->string);
1908        fprintf(stderr,
1909                "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
1910                (void *)ctx, (void *)ctx->cert);
1911        if (ctx->cert)
1912            s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256);
1913        if (s != NULL) {
1914            fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf);
1915        }
1916        return (1);
1917    }
1918    if (cb_arg->proxy_auth) {
1919        int found_any = 0, i;
1920        char *sp;
1921
1922        for (i = 0; i < 26; i++)
1923            letters[i] = 0;
1924        for (sp = cb_arg->proxy_auth; *sp; sp++) {
1925            int c = *sp;
1926            if (isascii(c) && isalpha(c)) {
1927                if (islower(c))
1928                    c = toupper(c);
1929                letters[c - 'A'] = 1;
1930            }
1931        }
1932
1933        fprintf(stderr, "  Initial proxy rights = ");
1934        for (i = 0; i < 26; i++)
1935            if (letters[i]) {
1936                fprintf(stderr, "%c", i + 'A');
1937                found_any = 1;
1938            }
1939        if (!found_any)
1940            fprintf(stderr, "none");
1941        fprintf(stderr, "\n");
1942
1943        X509_STORE_CTX_set_ex_data(ctx,
1944                                   get_proxy_auth_ex_data_idx(), letters);
1945    }
1946    if (cb_arg->allow_proxy_certs) {
1947        X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
1948    }
1949#ifndef OPENSSL_NO_X509_VERIFY
1950    ok = X509_verify_cert(ctx);
1951#endif
1952
1953    if (cb_arg->proxy_auth) {
1954        if (ok > 0) {
1955            const char *cond_end = NULL;
1956
1957            ok = process_proxy_cond(letters, cb_arg->proxy_cond, &cond_end);
1958
1959            if (ok < 0)
1960                EXIT(3);
1961            if (*cond_end) {
1962                fprintf(stderr,
1963                        "Stopped processing condition before it's end.\n");
1964                ok = 0;
1965            }
1966            if (!ok)
1967                fprintf(stderr,
1968                        "Proxy rights check with condition '%s' proved invalid\n",
1969                        cb_arg->proxy_cond);
1970            else
1971                fprintf(stderr,
1972                        "Proxy rights check with condition '%s' proved valid\n",
1973                        cb_arg->proxy_cond);
1974        }
1975    }
1976    return (ok);
1977}
1978
1979#ifndef OPENSSL_NO_RSA
1980static RSA *rsa_tmp = NULL;
1981
1982static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
1983{
1984    BIGNUM *bn = NULL;
1985    if (rsa_tmp == NULL) {
1986        bn = BN_new();
1987        rsa_tmp = RSA_new();
1988        if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) {
1989            BIO_printf(bio_err, "Memory error...");
1990            goto end;
1991        }
1992        BIO_printf(bio_err, "Generating temp (%d bit) RSA key...", keylength);
1993        (void)BIO_flush(bio_err);
1994        if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
1995            BIO_printf(bio_err, "Error generating key.");
1996            RSA_free(rsa_tmp);
1997            rsa_tmp = NULL;
1998        }
1999 end:
2000        BIO_printf(bio_err, "\n");
2001        (void)BIO_flush(bio_err);
2002    }
2003    if (bn)
2004        BN_free(bn);
2005    return (rsa_tmp);
2006}
2007
2008static void free_tmp_rsa(void)
2009{
2010    if (rsa_tmp != NULL) {
2011        RSA_free(rsa_tmp);
2012        rsa_tmp = NULL;
2013    }
2014}
2015#endif
2016
2017#ifndef OPENSSL_NO_DH
2018/*-
2019 * These DH parameters have been generated as follows:
2020 *    $ openssl dhparam -C -noout 512
2021 *    $ openssl dhparam -C -noout 1024
2022 *    $ openssl dhparam -C -noout -dsaparam 1024
2023 * (The third function has been renamed to avoid name conflicts.)
2024 */
2025static DH *get_dh512()
2026{
2027    static unsigned char dh512_p[] = {
2028        0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0,
2029        0xC6,
2030        0x1F, 0x0D, 0xAC, 0xB6, 0x25, 0x3E, 0x06, 0x39, 0xCA, 0x72, 0x04,
2031        0xB0,
2032        0x6E, 0xDA, 0xC0, 0x61, 0xE6, 0x7A, 0x77, 0x25, 0xE8, 0x3B, 0xB9,
2033        0x5F,
2034        0x9A, 0xB6, 0xB5, 0xFE, 0x99, 0x0B, 0xA1, 0x93, 0x4E, 0x35, 0x33,
2035        0xB8,
2036        0xE1, 0xF1, 0x13, 0x4F, 0x59, 0x1A, 0xD2, 0x57, 0xC0, 0x26, 0x21,
2037        0x33,
2038        0x02, 0xC5, 0xAE, 0x23,
2039    };
2040    static unsigned char dh512_g[] = {
2041        0x02,
2042    };
2043    DH *dh;
2044
2045    if ((dh = DH_new()) == NULL)
2046        return (NULL);
2047    dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
2048    dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
2049    if ((dh->p == NULL) || (dh->g == NULL)) {
2050        DH_free(dh);
2051        return (NULL);
2052    }
2053    return (dh);
2054}
2055
2056static DH *get_dh1024()
2057{
2058    static unsigned char dh1024_p[] = {
2059        0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF,
2060        0x3A,
2061        0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56,
2062        0xA2,
2063        0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F,
2064        0xB0,
2065        0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87,
2066        0xC2,
2067        0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0,
2068        0x8C,
2069        0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F,
2070        0xB8,
2071        0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D,
2072        0x52,
2073        0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC,
2074        0xC1,
2075        0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB,
2076        0xB1,
2077        0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89,
2078        0xAB,
2079        0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53,
2080    };
2081    static unsigned char dh1024_g[] = {
2082        0x02,
2083    };
2084    DH *dh;
2085
2086    if ((dh = DH_new()) == NULL)
2087        return (NULL);
2088    dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
2089    dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
2090    if ((dh->p == NULL) || (dh->g == NULL)) {
2091        DH_free(dh);
2092        return (NULL);
2093    }
2094    return (dh);
2095}
2096
2097static DH *get_dh1024dsa()
2098{
2099    static unsigned char dh1024_p[] = {
2100        0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5,
2101        0x00,
2102        0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87,
2103        0x19,
2104        0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65,
2105        0xD2,
2106        0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6,
2107        0x55,
2108        0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF,
2109        0xFC,
2110        0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52,
2111        0x97,
2112        0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28,
2113        0x8D,
2114        0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD,
2115        0xBB,
2116        0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C,
2117        0xF6,
2118        0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26,
2119        0x9E,
2120        0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39,
2121    };
2122    static unsigned char dh1024_g[] = {
2123        0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80,
2124        0x05,
2125        0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03,
2126        0xF3,
2127        0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A,
2128        0xE9,
2129        0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85,
2130        0x3C,
2131        0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B,
2132        0x65,
2133        0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF,
2134        0x60,
2135        0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E,
2136        0xF6,
2137        0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB,
2138        0xA7,
2139        0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72,
2140        0xA1,
2141        0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E,
2142        0x60,
2143        0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2,
2144    };
2145    DH *dh;
2146
2147    if ((dh = DH_new()) == NULL)
2148        return (NULL);
2149    dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
2150    dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
2151    if ((dh->p == NULL) || (dh->g == NULL)) {
2152        DH_free(dh);
2153        return (NULL);
2154    }
2155    dh->length = 160;
2156    return (dh);
2157}
2158#endif
2159
2160static int do_test_cipherlist(void)
2161{
2162    int i = 0;
2163    const SSL_METHOD *meth;
2164    SSL_CIPHER *ci, *tci = NULL;
2165
2166#ifndef OPENSSL_NO_SSL2
2167    fprintf(stderr, "testing SSLv2 cipher list order: ");
2168    meth = SSLv2_method();
2169    while ((ci = meth->get_cipher(i++)) != NULL) {
2170        if (tci != NULL)
2171            if (ci->id >= tci->id) {
2172                fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
2173                return 0;
2174            }
2175        tci = ci;
2176    }
2177    fprintf(stderr, "ok\n");
2178#endif
2179#ifndef OPENSSL_NO_SSL3
2180    fprintf(stderr, "testing SSLv3 cipher list order: ");
2181    meth = SSLv3_method();
2182    tci = NULL;
2183    while ((ci = meth->get_cipher(i++)) != NULL) {
2184        if (tci != NULL)
2185            if (ci->id >= tci->id) {
2186                fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
2187                return 0;
2188            }
2189        tci = ci;
2190    }
2191    fprintf(stderr, "ok\n");
2192#endif
2193#ifndef OPENSSL_NO_TLS1
2194    fprintf(stderr, "testing TLSv1 cipher list order: ");
2195    meth = TLSv1_method();
2196    tci = NULL;
2197    while ((ci = meth->get_cipher(i++)) != NULL) {
2198        if (tci != NULL)
2199            if (ci->id >= tci->id) {
2200                fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
2201                return 0;
2202            }
2203        tci = ci;
2204    }
2205    fprintf(stderr, "ok\n");
2206#endif
2207
2208    return 1;
2209}
2210