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