make
[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         }
897
898 int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
899         clock_t *s_time, clock_t *c_time)
900         {
901         long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
902         BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
903         BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
904         int ret = 1;
905         
906         size_t bufsiz = 256; /* small buffer for testing */
907
908         if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
909                 goto err;
910         if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
911                 goto err;
912         
913         s_ssl_bio = BIO_new(BIO_f_ssl());
914         if (!s_ssl_bio)
915                 goto err;
916
917         c_ssl_bio = BIO_new(BIO_f_ssl());
918         if (!c_ssl_bio)
919                 goto err;
920
921         SSL_set_connect_state(c_ssl);
922         SSL_set_bio(c_ssl, client, client);
923         (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
924
925         SSL_set_accept_state(s_ssl);
926         SSL_set_bio(s_ssl, server, server);
927         (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
928
929         do
930                 {
931                 /* c_ssl_bio:          SSL filter BIO
932                  *
933                  * client:             pseudo-I/O for SSL library
934                  *
935                  * client_io:          client's SSL communication; usually to be
936                  *                     relayed over some I/O facility, but in this
937                  *                     test program, we're the server, too:
938                  *
939                  * server_io:          server's SSL communication
940                  *
941                  * server:             pseudo-I/O for SSL library
942                  *
943                  * s_ssl_bio:          SSL filter BIO
944                  *
945                  * The client and the server each employ a "BIO pair":
946                  * client + client_io, server + server_io.
947                  * BIO pairs are symmetric.  A BIO pair behaves similar
948                  * to a non-blocking socketpair (but both endpoints must
949                  * be handled by the same thread).
950                  * [Here we could connect client and server to the ends
951                  * of a single BIO pair, but then this code would be less
952                  * suitable as an example for BIO pairs in general.]
953                  *
954                  * Useful functions for querying the state of BIO pair endpoints:
955                  *
956                  * BIO_ctrl_pending(bio)              number of bytes we can read now
957                  * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
958                  *                                      other side's read attempt
959                  * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
960                  *
961                  * ..._read_request is never more than ..._write_guarantee;
962                  * it depends on the application which one you should use.
963                  */
964
965                 /* We have non-blocking behaviour throughout this test program, but
966                  * can be sure that there is *some* progress in each iteration; so
967                  * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
968                  * -- we just try everything in each iteration
969                  */
970
971                         {
972                         /* CLIENT */
973                 
974                         MS_STATIC char cbuf[1024*8];
975                         int i, r;
976                         clock_t c_clock = clock();
977
978                         memset(cbuf, 0, sizeof(cbuf));
979
980                         if (debug)
981                                 if (SSL_in_init(c_ssl))
982                                         printf("client waiting in SSL_connect - %s\n",
983                                                 SSL_state_string_long(c_ssl));
984
985                         if (cw_num > 0)
986                                 {
987                                 /* Write to server. */
988                                 
989                                 if (cw_num > (long)sizeof cbuf)
990                                         i = sizeof cbuf;
991                                 else
992                                         i = (int)cw_num;
993                                 r = BIO_write(c_ssl_bio, cbuf, i);
994                                 if (r < 0)
995                                         {
996                                         if (!BIO_should_retry(c_ssl_bio))
997                                                 {
998                                                 fprintf(stderr,"ERROR in CLIENT\n");
999                                                 goto err;
1000                                                 }
1001                                         /* BIO_should_retry(...) can just be ignored here.
1002                                          * The library expects us to call BIO_write with
1003                                          * the same arguments again, and that's what we will
1004                                          * do in the next iteration. */
1005                                         }
1006                                 else if (r == 0)
1007                                         {
1008                                         fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
1009                                         goto err;
1010                                         }
1011                                 else
1012                                         {
1013                                         if (debug)
1014                                                 printf("client wrote %d\n", r);
1015                                         cw_num -= r;                            
1016                                         }
1017                                 }
1018
1019                         if (cr_num > 0)
1020                                 {
1021                                 /* Read from server. */
1022
1023                                 r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
1024                                 if (r < 0)
1025                                         {
1026                                         if (!BIO_should_retry(c_ssl_bio))
1027                                                 {
1028                                                 fprintf(stderr,"ERROR in CLIENT\n");
1029                                                 goto err;
1030                                                 }
1031                                         /* Again, "BIO_should_retry" can be ignored. */
1032                                         }
1033                                 else if (r == 0)
1034                                         {
1035                                         fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
1036                                         goto err;
1037                                         }
1038                                 else
1039                                         {
1040                                         if (debug)
1041                                                 printf("client read %d\n", r);
1042                                         cr_num -= r;
1043                                         }
1044                                 }
1045
1046                         /* c_time and s_time increments will typically be very small
1047                          * (depending on machine speed and clock tick intervals),
1048                          * but sampling over a large number of connections should
1049                          * result in fairly accurate figures.  We cannot guarantee
1050                          * a lot, however -- if each connection lasts for exactly
1051                          * one clock tick, it will be counted only for the client
1052                          * or only for the server or even not at all.
1053                          */
1054                         *c_time += (clock() - c_clock);
1055                         }
1056
1057                         {
1058                         /* SERVER */
1059                 
1060                         MS_STATIC char sbuf[1024*8];
1061                         int i, r;
1062                         clock_t s_clock = clock();
1063
1064                         memset(sbuf, 0, sizeof(sbuf));
1065
1066                         if (debug)
1067                                 if (SSL_in_init(s_ssl))
1068                                         printf("server waiting in SSL_accept - %s\n",
1069                                                 SSL_state_string_long(s_ssl));
1070
1071                         if (sw_num > 0)
1072                                 {
1073                                 /* Write to client. */
1074                                 
1075                                 if (sw_num > (long)sizeof sbuf)
1076                                         i = sizeof sbuf;
1077                                 else
1078                                         i = (int)sw_num;
1079                                 r = BIO_write(s_ssl_bio, sbuf, i);
1080                                 if (r < 0)
1081                                         {
1082                                         if (!BIO_should_retry(s_ssl_bio))
1083                                                 {
1084                                                 fprintf(stderr,"ERROR in SERVER\n");
1085                                                 goto err;
1086                                                 }
1087                                         /* Ignore "BIO_should_retry". */
1088                                         }
1089                                 else if (r == 0)
1090                                         {
1091                                         fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
1092                                         goto err;
1093                                         }
1094                                 else
1095                                         {
1096                                         if (debug)
1097                                                 printf("server wrote %d\n", r);
1098                                         sw_num -= r;                            
1099                                         }
1100                                 }
1101
1102                         if (sr_num > 0)
1103                                 {
1104                                 /* Read from client. */
1105
1106                                 r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
1107                                 if (r < 0)
1108                                         {
1109                                         if (!BIO_should_retry(s_ssl_bio))
1110                                                 {
1111                                                 fprintf(stderr,"ERROR in SERVER\n");
1112                                                 goto err;
1113                                                 }
1114                                         /* blah, blah */
1115                                         }
1116                                 else if (r == 0)
1117                                         {
1118                                         fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
1119                                         goto err;
1120                                         }
1121                                 else
1122                                         {
1123                                         if (debug)
1124                                                 printf("server read %d\n", r);
1125                                         sr_num -= r;
1126                                         }
1127                                 }
1128
1129                         *s_time += (clock() - s_clock);
1130                         }
1131                         
1132                         {
1133                         /* "I/O" BETWEEN CLIENT AND SERVER. */
1134
1135                         size_t r1, r2;
1136                         BIO *io1 = server_io, *io2 = client_io;
1137                         /* we use the non-copying interface for io1
1138                          * and the standard BIO_write/BIO_read interface for io2
1139                          */
1140                         
1141                         static int prev_progress = 1;
1142                         int progress = 0;
1143                         
1144                         /* io1 to io2 */
1145                         do
1146                                 {
1147                                 size_t num;
1148                                 int r;
1149
1150                                 r1 = BIO_ctrl_pending(io1);
1151                                 r2 = BIO_ctrl_get_write_guarantee(io2);
1152
1153                                 num = r1;
1154                                 if (r2 < num)
1155                                         num = r2;
1156                                 if (num)
1157                                         {
1158                                         char *dataptr;
1159
1160                                         if (INT_MAX < num) /* yeah, right */
1161                                                 num = INT_MAX;
1162                                         
1163                                         r = BIO_nread(io1, &dataptr, (int)num);
1164                                         assert(r > 0);
1165                                         assert(r <= (int)num);
1166                                         /* possibly r < num (non-contiguous data) */
1167                                         num = r;
1168                                         r = BIO_write(io2, dataptr, (int)num);
1169                                         if (r != (int)num) /* can't happen */
1170                                                 {
1171                                                 fprintf(stderr, "ERROR: BIO_write could not write "
1172                                                         "BIO_ctrl_get_write_guarantee() bytes");
1173                                                 goto err;
1174                                                 }
1175                                         progress = 1;
1176
1177                                         if (debug)
1178                                                 printf((io1 == client_io) ?
1179                                                         "C->S relaying: %d bytes\n" :
1180                                                         "S->C relaying: %d bytes\n",
1181                                                         (int)num);
1182                                         }
1183                                 }
1184                         while (r1 && r2);
1185
1186                         /* io2 to io1 */
1187                         {
1188                                 size_t num;
1189                                 int r;
1190
1191                                 r1 = BIO_ctrl_pending(io2);
1192                                 r2 = BIO_ctrl_get_read_request(io1);
1193                                 /* here we could use ..._get_write_guarantee instead of
1194                                  * ..._get_read_request, but by using the latter
1195                                  * we test restartability of the SSL implementation
1196                                  * more thoroughly */
1197                                 num = r1;
1198                                 if (r2 < num)
1199                                         num = r2;
1200                                 if (num)
1201                                         {
1202                                         char *dataptr;
1203                                         
1204                                         if (INT_MAX < num)
1205                                                 num = INT_MAX;
1206
1207                                         if (num > 1)
1208                                                 --num; /* test restartability even more thoroughly */
1209                                         
1210                                         r = BIO_nwrite0(io1, &dataptr);
1211                                         assert(r > 0);
1212                                         if (r < (int)num)
1213                                                 num = r;
1214                                         r = BIO_read(io2, dataptr, (int)num);
1215                                         if (r != (int)num) /* can't happen */
1216                                                 {
1217                                                 fprintf(stderr, "ERROR: BIO_read could not read "
1218                                                         "BIO_ctrl_pending() bytes");
1219                                                 goto err;
1220                                                 }
1221                                         progress = 1;
1222                                         r = BIO_nwrite(io1, &dataptr, (int)num);
1223                                         if (r != (int)num) /* can't happen */
1224                                                 {
1225                                                 fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
1226                                                         "BIO_nwrite0() bytes");
1227                                                 goto err;
1228                                                 }
1229                                         
1230                                         if (debug)
1231                                                 printf((io2 == client_io) ?
1232                                                         "C->S relaying: %d bytes\n" :
1233                                                         "S->C relaying: %d bytes\n",
1234                                                         (int)num);
1235                                         }
1236                         } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
1237
1238                         if (!progress && !prev_progress)
1239                                 if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
1240                                         {
1241                                         fprintf(stderr, "ERROR: got stuck\n");
1242                                         if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)
1243                                                 {
1244                                                 fprintf(stderr, "This can happen for SSL2 because "
1245                                                         "CLIENT-FINISHED and SERVER-VERIFY are written \n"
1246                                                         "concurrently ...");
1247                                                 if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
1248                                                         && strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)
1249                                                         {
1250                                                         fprintf(stderr, " ok.\n");
1251                                                         goto end;
1252                                                         }
1253                                                 }
1254                                         fprintf(stderr, " ERROR.\n");
1255                                         goto err;
1256                                         }
1257                         prev_progress = progress;
1258                         }
1259                 }
1260         while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
1261
1262         if (verbose)
1263                 print_details(c_ssl, "DONE via BIO pair: ");
1264 end:
1265         ret = 0;
1266
1267  err:
1268         ERR_print_errors(bio_err);
1269         
1270         if (server)
1271                 BIO_free(server);
1272         if (server_io)
1273                 BIO_free(server_io);
1274         if (client)
1275                 BIO_free(client);
1276         if (client_io)
1277                 BIO_free(client_io);
1278         if (s_ssl_bio)
1279                 BIO_free(s_ssl_bio);
1280         if (c_ssl_bio)
1281                 BIO_free(c_ssl_bio);
1282
1283         return ret;
1284         }
1285
1286
1287 #define W_READ  1
1288 #define W_WRITE 2
1289 #define C_DONE  1
1290 #define S_DONE  2
1291
1292 int doit(SSL *s_ssl, SSL *c_ssl, long count)
1293         {
1294         MS_STATIC char cbuf[1024*8],sbuf[1024*8];
1295         long cw_num=count,cr_num=count;
1296         long sw_num=count,sr_num=count;
1297         int ret=1;
1298         BIO *c_to_s=NULL;
1299         BIO *s_to_c=NULL;
1300         BIO *c_bio=NULL;
1301         BIO *s_bio=NULL;
1302         int c_r,c_w,s_r,s_w;
1303         int c_want,s_want;
1304         int i,j;
1305         int done=0;
1306         int c_write,s_write;
1307         int do_server=0,do_client=0;
1308
1309         memset(cbuf,0,sizeof(cbuf));
1310         memset(sbuf,0,sizeof(sbuf));
1311
1312         c_to_s=BIO_new(BIO_s_mem());
1313         s_to_c=BIO_new(BIO_s_mem());
1314         if ((s_to_c == NULL) || (c_to_s == NULL))
1315                 {
1316                 ERR_print_errors(bio_err);
1317                 goto err;
1318                 }
1319
1320         c_bio=BIO_new(BIO_f_ssl());
1321         s_bio=BIO_new(BIO_f_ssl());
1322         if ((c_bio == NULL) || (s_bio == NULL))
1323                 {
1324                 ERR_print_errors(bio_err);
1325                 goto err;
1326                 }
1327
1328         SSL_set_connect_state(c_ssl);
1329         SSL_set_bio(c_ssl,s_to_c,c_to_s);
1330         BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
1331
1332         SSL_set_accept_state(s_ssl);
1333         SSL_set_bio(s_ssl,c_to_s,s_to_c);
1334         BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
1335
1336         c_r=0; s_r=1;
1337         c_w=1; s_w=0;
1338         c_want=W_WRITE;
1339         s_want=0;
1340         c_write=1,s_write=0;
1341
1342         /* We can always do writes */
1343         for (;;)
1344                 {
1345                 do_server=0;
1346                 do_client=0;
1347
1348                 i=(int)BIO_pending(s_bio);
1349                 if ((i && s_r) || s_w) do_server=1;
1350
1351                 i=(int)BIO_pending(c_bio);
1352                 if ((i && c_r) || c_w) do_client=1;
1353
1354                 if (do_server && debug)
1355                         {
1356                         if (SSL_in_init(s_ssl))
1357                                 printf("server waiting in SSL_accept - %s\n",
1358                                         SSL_state_string_long(s_ssl));
1359 /*                      else if (s_write)
1360                                 printf("server:SSL_write()\n");
1361                         else
1362                                 printf("server:SSL_read()\n"); */
1363                         }
1364
1365                 if (do_client && debug)
1366                         {
1367                         if (SSL_in_init(c_ssl))
1368                                 printf("client waiting in SSL_connect - %s\n",
1369                                         SSL_state_string_long(c_ssl));
1370 /*                      else if (c_write)
1371                                 printf("client:SSL_write()\n");
1372                         else
1373                                 printf("client:SSL_read()\n"); */
1374                         }
1375
1376                 if (!do_client && !do_server)
1377                         {
1378                         fprintf(stdout,"ERROR IN STARTUP\n");
1379                         ERR_print_errors(bio_err);
1380                         break;
1381                         }
1382                 if (do_client && !(done & C_DONE))
1383                         {
1384                         if (c_write)
1385                                 {
1386                                 j = (cw_num > (long)sizeof(cbuf)) ?
1387                                         (int)sizeof(cbuf) : (int)cw_num;
1388                                 i=BIO_write(c_bio,cbuf,j);
1389                                 if (i < 0)
1390                                         {
1391                                         c_r=0;
1392                                         c_w=0;
1393                                         if (BIO_should_retry(c_bio))
1394                                                 {
1395                                                 if (BIO_should_read(c_bio))
1396                                                         c_r=1;
1397                                                 if (BIO_should_write(c_bio))
1398                                                         c_w=1;
1399                                                 }
1400                                         else
1401                                                 {
1402                                                 fprintf(stderr,"ERROR in CLIENT\n");
1403                                                 ERR_print_errors(bio_err);
1404                                                 goto err;
1405                                                 }
1406                                         }
1407                                 else if (i == 0)
1408                                         {
1409                                         fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
1410                                         goto err;
1411                                         }
1412                                 else
1413                                         {
1414                                         if (debug)
1415                                                 printf("client wrote %d\n",i);
1416                                         /* ok */
1417                                         s_r=1;
1418                                         c_write=0;
1419                                         cw_num-=i;
1420                                         }
1421                                 }
1422                         else
1423                                 {
1424                                 i=BIO_read(c_bio,cbuf,sizeof(cbuf));
1425                                 if (i < 0)
1426                                         {
1427                                         c_r=0;
1428                                         c_w=0;
1429                                         if (BIO_should_retry(c_bio))
1430                                                 {
1431                                                 if (BIO_should_read(c_bio))
1432                                                         c_r=1;
1433                                                 if (BIO_should_write(c_bio))
1434                                                         c_w=1;
1435                                                 }
1436                                         else
1437                                                 {
1438                                                 fprintf(stderr,"ERROR in CLIENT\n");
1439                                                 ERR_print_errors(bio_err);
1440                                                 goto err;
1441                                                 }
1442                                         }
1443                                 else if (i == 0)
1444                                         {
1445                                         fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
1446                                         goto err;
1447                                         }
1448                                 else
1449                                         {
1450                                         if (debug)
1451                                                 printf("client read %d\n",i);
1452                                         cr_num-=i;
1453                                         if (sw_num > 0)
1454                                                 {
1455                                                 s_write=1;
1456                                                 s_w=1;
1457                                                 }
1458                                         if (cr_num <= 0)
1459                                                 {
1460                                                 s_write=1;
1461                                                 s_w=1;
1462                                                 done=S_DONE|C_DONE;
1463                                                 }
1464                                         }
1465                                 }
1466                         }
1467
1468                 if (do_server && !(done & S_DONE))
1469                         {
1470                         if (!s_write)
1471                                 {
1472                                 i=BIO_read(s_bio,sbuf,sizeof(cbuf));
1473                                 if (i < 0)
1474                                         {
1475                                         s_r=0;
1476                                         s_w=0;
1477                                         if (BIO_should_retry(s_bio))
1478                                                 {
1479                                                 if (BIO_should_read(s_bio))
1480                                                         s_r=1;
1481                                                 if (BIO_should_write(s_bio))
1482                                                         s_w=1;
1483                                                 }
1484                                         else
1485                                                 {
1486                                                 fprintf(stderr,"ERROR in SERVER\n");
1487                                                 ERR_print_errors(bio_err);
1488                                                 goto err;
1489                                                 }
1490                                         }
1491                                 else if (i == 0)
1492                                         {
1493                                         ERR_print_errors(bio_err);
1494                                         fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
1495                                         goto err;
1496                                         }
1497                                 else
1498                                         {
1499                                         if (debug)
1500                                                 printf("server read %d\n",i);
1501                                         sr_num-=i;
1502                                         if (cw_num > 0)
1503                                                 {
1504                                                 c_write=1;
1505                                                 c_w=1;
1506                                                 }
1507                                         if (sr_num <= 0)
1508                                                 {
1509                                                 s_write=1;
1510                                                 s_w=1;
1511                                                 c_write=0;
1512                                                 }
1513                                         }
1514                                 }
1515                         else
1516                                 {
1517                                 j = (sw_num > (long)sizeof(sbuf)) ?
1518                                         (int)sizeof(sbuf) : (int)sw_num;
1519                                 i=BIO_write(s_bio,sbuf,j);
1520                                 if (i < 0)
1521                                         {
1522                                         s_r=0;
1523                                         s_w=0;
1524                                         if (BIO_should_retry(s_bio))
1525                                                 {
1526                                                 if (BIO_should_read(s_bio))
1527                                                         s_r=1;
1528                                                 if (BIO_should_write(s_bio))
1529                                                         s_w=1;
1530                                                 }
1531                                         else
1532                                                 {
1533                                                 fprintf(stderr,"ERROR in SERVER\n");
1534                                                 ERR_print_errors(bio_err);
1535                                                 goto err;
1536                                                 }
1537                                         }
1538                                 else if (i == 0)
1539                                         {
1540                                         ERR_print_errors(bio_err);
1541                                         fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
1542                                         goto err;
1543                                         }
1544                                 else
1545                                         {
1546                                         if (debug)
1547                                                 printf("server wrote %d\n",i);
1548                                         sw_num-=i;
1549                                         s_write=0;
1550                                         c_r=1;
1551                                         if (sw_num <= 0)
1552                                                 done|=S_DONE;
1553                                         }
1554                                 }
1555                         }
1556
1557                 if ((done & S_DONE) && (done & C_DONE)) break;
1558                 }
1559
1560         if (verbose)
1561                 print_details(c_ssl, "DONE: ");
1562         ret=0;
1563 err:
1564         /* We have to set the BIO's to NULL otherwise they will be
1565          * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and
1566          * again when c_ssl is SSL_free()ed.
1567          * This is a hack required because s_ssl and c_ssl are sharing the same
1568          * BIO structure and SSL_set_bio() and SSL_free() automatically
1569          * BIO_free non NULL entries.
1570          * You should not normally do this or be required to do this */
1571         if (s_ssl != NULL)
1572                 {
1573                 s_ssl->rbio=NULL;
1574                 s_ssl->wbio=NULL;
1575                 }
1576         if (c_ssl != NULL)
1577                 {
1578                 c_ssl->rbio=NULL;
1579                 c_ssl->wbio=NULL;
1580                 }
1581
1582         if (c_to_s != NULL) BIO_free(c_to_s);
1583         if (s_to_c != NULL) BIO_free(s_to_c);
1584         if (c_bio != NULL) BIO_free_all(c_bio);
1585         if (s_bio != NULL) BIO_free_all(s_bio);
1586         return(ret);
1587         }
1588
1589 static int get_proxy_auth_ex_data_idx(void)
1590         {
1591         static volatile int idx = -1;
1592         if (idx < 0)
1593                 {
1594                 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
1595                 if (idx < 0)
1596                         {
1597                         idx = X509_STORE_CTX_get_ex_new_index(0,
1598                                 "SSLtest for verify callback", NULL,NULL,NULL);
1599                         }
1600                 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
1601                 }
1602         return idx;
1603         }
1604
1605 static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
1606         {
1607         char *s,buf[256];
1608
1609         s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
1610                             sizeof buf);
1611         if (s != NULL)
1612                 {
1613                 if (ok)
1614                         fprintf(stderr,"depth=%d %s\n",
1615                                 ctx->error_depth,buf);
1616                 else
1617                         {
1618                         fprintf(stderr,"depth=%d error=%d %s\n",
1619                                 ctx->error_depth,ctx->error,buf);
1620                         }
1621                 }
1622
1623         if (ok == 0)
1624                 {
1625                 fprintf(stderr,"Error string: %s\n",
1626                         X509_verify_cert_error_string(ctx->error));
1627                 switch (ctx->error)
1628                         {
1629                 case X509_V_ERR_CERT_NOT_YET_VALID:
1630                 case X509_V_ERR_CERT_HAS_EXPIRED:
1631                 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1632                         fprintf(stderr,"  ... ignored.\n");
1633                         ok=1;
1634                         }
1635                 }
1636
1637         if (ok == 1)
1638                 {
1639                 X509 *xs = ctx->current_cert;
1640 #if 0
1641                 X509 *xi = ctx->current_issuer;
1642 #endif
1643
1644                 if (xs->ex_flags & EXFLAG_PROXY)
1645                         {
1646                         unsigned int *letters =
1647                                 X509_STORE_CTX_get_ex_data(ctx,
1648                                         get_proxy_auth_ex_data_idx());
1649
1650                         if (letters)
1651                                 {
1652                                 int found_any = 0;
1653                                 int i;
1654                                 PROXY_CERT_INFO_EXTENSION *pci =
1655                                         X509_get_ext_d2i(xs, NID_proxyCertInfo,
1656                                                 NULL, NULL);
1657
1658                                 switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
1659                                         {
1660                                 case NID_Independent:
1661                                         /* Completely meaningless in this
1662                                            program, as there's no way to
1663                                            grant explicit rights to a
1664                                            specific PrC.  Basically, using
1665                                            id-ppl-Independent is the perfect
1666                                            way to grant no rights at all. */
1667                                         fprintf(stderr, "  Independent proxy certificate");
1668                                         for (i = 0; i < 26; i++)
1669                                                 letters[i] = 0;
1670                                         break;
1671                                 case NID_id_ppl_inheritAll:
1672                                         /* This is basically a NOP, we
1673                                            simply let the current rights
1674                                            stand as they are. */
1675                                         fprintf(stderr, "  Proxy certificate inherits all");
1676                                         break;
1677                                 default:
1678                                         s = (char *)
1679                                                 pci->proxyPolicy->policy->data;
1680                                         i = pci->proxyPolicy->policy->length;
1681
1682                                         /* The algorithm works as follows:
1683                                            it is assumed that previous
1684                                            iterations or the initial granted
1685                                            rights has already set some elements
1686                                            of `letters'.  What we need to do is
1687                                            to clear those that weren't granted
1688                                            by the current PrC as well.  The
1689                                            easiest way to do this is to add 1
1690                                            to all the elements whose letters
1691                                            are given with the current policy.
1692                                            That way, all elements that are set
1693                                            by the current policy and were
1694                                            already set by earlier policies and
1695                                            through the original grant of rights
1696                                            will get the value 2 or higher.
1697                                            The last thing to do is to sweep
1698                                            through `letters' and keep the
1699                                            elements having the value 2 as set,
1700                                            and clear all the others. */
1701
1702                                         fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
1703                                         while(i-- > 0)
1704                                                 {
1705                                                 int c = *s++;
1706                                                 if (isascii(c) && isalpha(c))
1707                                                         {
1708                                                         if (islower(c))
1709                                                                 c = toupper(c);
1710                                                         letters[c - 'A']++;
1711                                                         }
1712                                                 }
1713                                         for (i = 0; i < 26; i++)
1714                                                 if (letters[i] < 2)
1715                                                         letters[i] = 0;
1716                                                 else
1717                                                         letters[i] = 1;
1718                                         }
1719
1720                                 found_any = 0;
1721                                 fprintf(stderr,
1722                                         ", resulting proxy rights = ");
1723                                 for(i = 0; i < 26; i++)
1724                                         if (letters[i])
1725                                                 {
1726                                                 fprintf(stderr, "%c", i + 'A');
1727                                                 found_any = 1;
1728                                                 }
1729                                 if (!found_any)
1730                                         fprintf(stderr, "none");
1731                                 fprintf(stderr, "\n");
1732
1733                                 PROXY_CERT_INFO_EXTENSION_free(pci);
1734                                 }
1735                         }
1736                 }
1737
1738         return(ok);
1739         }
1740
1741 static void process_proxy_debug(int indent, const char *format, ...)
1742         {
1743         static const char indentation[] =
1744                 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
1745                 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
1746         char my_format[256];
1747         va_list args;
1748
1749         BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
1750                 indent, indent, indentation, format);
1751
1752         va_start(args, format);
1753         vfprintf(stderr, my_format, args);
1754         va_end(args);
1755         }
1756 /* Priority levels:
1757    0    [!]var, ()
1758    1    & ^
1759    2    |
1760 */
1761 static int process_proxy_cond_adders(unsigned int letters[26],
1762         const char *cond, const char **cond_end, int *pos, int indent);
1763 static int process_proxy_cond_val(unsigned int letters[26],
1764         const char *cond, const char **cond_end, int *pos, int indent)
1765         {
1766         int c;
1767         int ok = 1;
1768         int negate = 0;
1769
1770         while(isspace((int)*cond))
1771                 {
1772                 cond++; (*pos)++;
1773                 }
1774         c = *cond;
1775
1776         if (debug)
1777                 process_proxy_debug(indent,
1778                         "Start process_proxy_cond_val at position %d: %s\n",
1779                         *pos, cond);
1780
1781         while(c == '!')
1782                 {
1783                 negate = !negate;
1784                 cond++; (*pos)++;
1785                 while(isspace((int)*cond))
1786                         {
1787                         cond++; (*pos)++;
1788                         }
1789                 c = *cond;
1790                 }
1791
1792         if (c == '(')
1793                 {
1794                 cond++; (*pos)++;
1795                 ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
1796                         indent + 1);
1797                 cond = *cond_end;
1798                 if (ok < 0)
1799                         goto end;
1800                 while(isspace((int)*cond))
1801                         {
1802                         cond++; (*pos)++;
1803                         }
1804                 c = *cond;
1805                 if (c != ')')
1806                         {
1807                         fprintf(stderr,
1808                                 "Weird condition character in position %d: "
1809                                 "%c\n", *pos, c);
1810                         ok = -1;
1811                         goto end;
1812                         }
1813                 cond++; (*pos)++;
1814                 }
1815         else if (isascii(c) && isalpha(c))
1816                 {
1817                 if (islower(c))
1818                         c = toupper(c);
1819                 ok = letters[c - 'A'];
1820                 cond++; (*pos)++;
1821                 }
1822         else
1823                 {
1824                 fprintf(stderr,
1825                         "Weird condition character in position %d: "
1826                         "%c\n", *pos, c);
1827                 ok = -1;
1828                 goto end;
1829                 }
1830  end:
1831         *cond_end = cond;
1832         if (ok >= 0 && negate)
1833                 ok = !ok;
1834
1835         if (debug)
1836                 process_proxy_debug(indent,
1837                         "End process_proxy_cond_val at position %d: %s, returning %d\n",
1838                         *pos, cond, ok);
1839
1840         return ok;
1841         }
1842 static int process_proxy_cond_multipliers(unsigned int letters[26],
1843         const char *cond, const char **cond_end, int *pos, int indent)
1844         {
1845         int ok;
1846         char c;
1847
1848         if (debug)
1849                 process_proxy_debug(indent,
1850                         "Start process_proxy_cond_multipliers at position %d: %s\n",
1851                         *pos, cond);
1852
1853         ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
1854         cond = *cond_end;
1855         if (ok < 0)
1856                 goto end;
1857
1858         while(ok >= 0)
1859                 {
1860                 while(isspace((int)*cond))
1861                         {
1862                         cond++; (*pos)++;
1863                         }
1864                 c = *cond;
1865
1866                 switch(c)
1867                         {
1868                 case '&':
1869                 case '^':
1870                         {
1871                         int save_ok = ok;
1872
1873                         cond++; (*pos)++;
1874                         ok = process_proxy_cond_val(letters,
1875                                 cond, cond_end, pos, indent + 1);
1876                         cond = *cond_end;
1877                         if (ok < 0)
1878                                 break;
1879
1880                         switch(c)
1881                                 {
1882                         case '&':
1883                                 ok &= save_ok;
1884                                 break;
1885                         case '^':
1886                                 ok ^= save_ok;
1887                                 break;
1888                         default:
1889                                 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1890                                         " STOPPING\n");
1891                                 EXIT(1);
1892                                 }
1893                         }
1894                         break;
1895                 default:
1896                         goto end;
1897                         }
1898                 }
1899  end:
1900         if (debug)
1901                 process_proxy_debug(indent,
1902                         "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
1903                         *pos, cond, ok);
1904
1905         *cond_end = cond;
1906         return ok;
1907         }
1908 static int process_proxy_cond_adders(unsigned int letters[26],
1909         const char *cond, const char **cond_end, int *pos, int indent)
1910         {
1911         int ok;
1912         char c;
1913
1914         if (debug)
1915                 process_proxy_debug(indent,
1916                         "Start process_proxy_cond_adders at position %d: %s\n",
1917                         *pos, cond);
1918
1919         ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
1920                 indent + 1);
1921         cond = *cond_end;
1922         if (ok < 0)
1923                 goto end;
1924
1925         while(ok >= 0)
1926                 {
1927                 while(isspace((int)*cond))
1928                         {
1929                         cond++; (*pos)++;
1930                         }
1931                 c = *cond;
1932
1933                 switch(c)
1934                         {
1935                 case '|':
1936                         {
1937                         int save_ok = ok;
1938
1939                         cond++; (*pos)++;
1940                         ok = process_proxy_cond_multipliers(letters,
1941                                 cond, cond_end, pos, indent + 1);
1942                         cond = *cond_end;
1943                         if (ok < 0)
1944                                 break;
1945
1946                         switch(c)
1947                                 {
1948                         case '|':
1949                                 ok |= save_ok;
1950                                 break;
1951                         default:
1952                                 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1953                                         " STOPPING\n");
1954                                 EXIT(1);
1955                                 }
1956                         }
1957                         break;
1958                 default:
1959                         goto end;
1960                         }
1961                 }
1962  end:
1963         if (debug)
1964                 process_proxy_debug(indent,
1965                         "End process_proxy_cond_adders at position %d: %s, returning %d\n",
1966                         *pos, cond, ok);
1967
1968         *cond_end = cond;
1969         return ok;
1970         }
1971
1972 static int process_proxy_cond(unsigned int letters[26],
1973         const char *cond, const char **cond_end)
1974         {
1975         int pos = 1;
1976         return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
1977         }
1978
1979 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
1980         {
1981         int ok=1;
1982         struct app_verify_arg *cb_arg = arg;
1983         unsigned int letters[26]; /* only used with proxy_auth */
1984
1985         if (cb_arg->app_verify)
1986                 {
1987                 char *s = NULL,buf[256];
1988
1989                 fprintf(stderr, "In app_verify_callback, allowing cert. ");
1990                 fprintf(stderr, "Arg is: %s\n", cb_arg->string);
1991                 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
1992                         (void *)ctx, (void *)ctx->cert);
1993                 if (ctx->cert)
1994                         s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
1995                 if (s != NULL)
1996                         {
1997                         fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
1998                         }
1999                 return(1);
2000                 }
2001         if (cb_arg->proxy_auth)
2002                 {
2003                 int found_any = 0, i;
2004                 char *sp;
2005
2006                 for(i = 0; i < 26; i++)
2007                         letters[i] = 0;
2008                 for(sp = cb_arg->proxy_auth; *sp; sp++)
2009                         {
2010                         int c = *sp;
2011                         if (isascii(c) && isalpha(c))
2012                                 {
2013                                 if (islower(c))
2014                                         c = toupper(c);
2015                                 letters[c - 'A'] = 1;
2016                                 }
2017                         }
2018
2019                 fprintf(stderr,
2020                         "  Initial proxy rights = ");
2021                 for(i = 0; i < 26; i++)
2022                         if (letters[i])
2023                                 {
2024                                 fprintf(stderr, "%c", i + 'A');
2025                                 found_any = 1;
2026                                 }
2027                 if (!found_any)
2028                         fprintf(stderr, "none");
2029                 fprintf(stderr, "\n");
2030
2031                 X509_STORE_CTX_set_ex_data(ctx,
2032                         get_proxy_auth_ex_data_idx(),letters);
2033                 }
2034         if (cb_arg->allow_proxy_certs)
2035                 {
2036                 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
2037                 }
2038
2039 #ifndef OPENSSL_NO_X509_VERIFY
2040 # ifdef OPENSSL_FIPS
2041         if(s->version == TLS1_VERSION)
2042                 FIPS_allow_md5(1);
2043 # endif
2044         ok = X509_verify_cert(ctx);
2045 # ifdef OPENSSL_FIPS
2046         if(s->version == TLS1_VERSION)
2047                 FIPS_allow_md5(0);
2048 # endif
2049 #endif
2050
2051         if (cb_arg->proxy_auth)
2052                 {
2053                 if (ok)
2054                         {
2055                         const char *cond_end = NULL;
2056
2057                         ok = process_proxy_cond(letters,
2058                                 cb_arg->proxy_cond, &cond_end);
2059
2060                         if (ok < 0)
2061                                 EXIT(3);
2062                         if (*cond_end)
2063                                 {
2064                                 fprintf(stderr, "Stopped processing condition before it's end.\n");
2065                                 ok = 0;
2066                                 }
2067                         if (!ok)
2068                                 fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
2069                                         cb_arg->proxy_cond);
2070                         else
2071                                 fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
2072                                         cb_arg->proxy_cond);
2073                         }
2074                 }
2075         return(ok);
2076         }
2077
2078 #ifndef OPENSSL_NO_RSA
2079 static RSA *rsa_tmp=NULL;
2080
2081 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
2082         {
2083         BIGNUM *bn = NULL;
2084         if (rsa_tmp == NULL)
2085                 {
2086                 bn = BN_new();
2087                 rsa_tmp = RSA_new();
2088                 if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
2089                         {
2090                         BIO_printf(bio_err, "Memory error...");
2091                         goto end;
2092                         }
2093                 BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
2094                 (void)BIO_flush(bio_err);
2095                 if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
2096                         {
2097                         BIO_printf(bio_err, "Error generating key.");
2098                         RSA_free(rsa_tmp);
2099                         rsa_tmp = NULL;
2100                         }
2101 end:
2102                 BIO_printf(bio_err,"\n");
2103                 (void)BIO_flush(bio_err);
2104                 }
2105         if(bn) BN_free(bn);
2106         return(rsa_tmp);
2107         }
2108
2109 static void free_tmp_rsa(void)
2110         {
2111         if (rsa_tmp != NULL)
2112                 {
2113                 RSA_free(rsa_tmp);
2114                 rsa_tmp = NULL;
2115                 }
2116         }
2117 #endif
2118
2119 #ifndef OPENSSL_NO_DH
2120 /* These DH parameters have been generated as follows:
2121  *    $ openssl dhparam -C -noout 512
2122  *    $ openssl dhparam -C -noout 1024
2123  *    $ openssl dhparam -C -noout -dsaparam 1024
2124  * (The third function has been renamed to avoid name conflicts.)
2125  */
2126 static DH *get_dh512()
2127         {
2128         static unsigned char dh512_p[]={
2129                 0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
2130                 0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
2131                 0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
2132                 0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
2133                 0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
2134                 0x02,0xC5,0xAE,0x23,
2135                 };
2136         static unsigned char dh512_g[]={
2137                 0x02,
2138                 };
2139         DH *dh;
2140
2141         if ((dh=DH_new()) == NULL) return(NULL);
2142         dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
2143         dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
2144         if ((dh->p == NULL) || (dh->g == NULL))
2145                 { DH_free(dh); return(NULL); }
2146         return(dh);
2147         }
2148
2149 static DH *get_dh1024()
2150         {
2151         static unsigned char dh1024_p[]={
2152                 0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
2153                 0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
2154                 0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
2155                 0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
2156                 0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
2157                 0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
2158                 0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
2159                 0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
2160                 0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
2161                 0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
2162                 0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
2163                 };
2164         static unsigned char dh1024_g[]={
2165                 0x02,
2166                 };
2167         DH *dh;
2168
2169         if ((dh=DH_new()) == NULL) return(NULL);
2170         dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
2171         dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
2172         if ((dh->p == NULL) || (dh->g == NULL))
2173                 { DH_free(dh); return(NULL); }
2174         return(dh);
2175         }
2176
2177 static DH *get_dh1024dsa()
2178         {
2179         static unsigned char dh1024_p[]={
2180                 0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
2181                 0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
2182                 0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
2183                 0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
2184                 0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
2185                 0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
2186                 0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
2187                 0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
2188                 0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
2189                 0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
2190                 0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
2191                 };
2192         static unsigned char dh1024_g[]={
2193                 0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
2194                 0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
2195                 0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
2196                 0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
2197                 0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
2198                 0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
2199                 0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
2200                 0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
2201                 0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
2202                 0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
2203                 0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
2204                 };
2205         DH *dh;
2206
2207         if ((dh=DH_new()) == NULL) return(NULL);
2208         dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
2209         dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
2210         if ((dh->p == NULL) || (dh->g == NULL))
2211                 { DH_free(dh); return(NULL); }
2212         dh->length = 160;
2213         return(dh);
2214         }
2215 #endif