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