]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - crypto/openssl/ssl/ssltest.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 c_want,s_want;
1355         int i,j;
1356         int done=0;
1357         int c_write,s_write;
1358         int do_server=0,do_client=0;
1359
1360         memset(cbuf,0,sizeof(cbuf));
1361         memset(sbuf,0,sizeof(sbuf));
1362
1363         c_to_s=BIO_new(BIO_s_mem());
1364         s_to_c=BIO_new(BIO_s_mem());
1365         if ((s_to_c == NULL) || (c_to_s == NULL))
1366                 {
1367                 ERR_print_errors(bio_err);
1368                 goto err;
1369                 }
1370
1371         c_bio=BIO_new(BIO_f_ssl());
1372         s_bio=BIO_new(BIO_f_ssl());
1373         if ((c_bio == NULL) || (s_bio == NULL))
1374                 {
1375                 ERR_print_errors(bio_err);
1376                 goto err;
1377                 }
1378
1379         SSL_set_connect_state(c_ssl);
1380         SSL_set_bio(c_ssl,s_to_c,c_to_s);
1381         BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
1382
1383         SSL_set_accept_state(s_ssl);
1384         SSL_set_bio(s_ssl,c_to_s,s_to_c);
1385         BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
1386
1387         c_r=0; s_r=1;
1388         c_w=1; s_w=0;
1389         c_want=W_WRITE;
1390         s_want=0;
1391         c_write=1,s_write=0;
1392
1393         /* We can always do writes */
1394         for (;;)
1395                 {
1396                 do_server=0;
1397                 do_client=0;
1398
1399                 i=(int)BIO_pending(s_bio);
1400                 if ((i && s_r) || s_w) do_server=1;
1401
1402                 i=(int)BIO_pending(c_bio);
1403                 if ((i && c_r) || c_w) do_client=1;
1404
1405                 if (do_server && debug)
1406                         {
1407                         if (SSL_in_init(s_ssl))
1408                                 printf("server waiting in SSL_accept - %s\n",
1409                                         SSL_state_string_long(s_ssl));
1410 /*                      else if (s_write)
1411                                 printf("server:SSL_write()\n");
1412                         else
1413                                 printf("server:SSL_read()\n"); */
1414                         }
1415
1416                 if (do_client && debug)
1417                         {
1418                         if (SSL_in_init(c_ssl))
1419                                 printf("client waiting in SSL_connect - %s\n",
1420                                         SSL_state_string_long(c_ssl));
1421 /*                      else if (c_write)
1422                                 printf("client:SSL_write()\n");
1423                         else
1424                                 printf("client:SSL_read()\n"); */
1425                         }
1426
1427                 if (!do_client && !do_server)
1428                         {
1429                         fprintf(stdout,"ERROR IN STARTUP\n");
1430                         ERR_print_errors(bio_err);
1431                         break;
1432                         }
1433                 if (do_client && !(done & C_DONE))
1434                         {
1435                         if (c_write)
1436                                 {
1437                                 j = (cw_num > (long)sizeof(cbuf)) ?
1438                                         (int)sizeof(cbuf) : (int)cw_num;
1439                                 i=BIO_write(c_bio,cbuf,j);
1440                                 if (i < 0)
1441                                         {
1442                                         c_r=0;
1443                                         c_w=0;
1444                                         if (BIO_should_retry(c_bio))
1445                                                 {
1446                                                 if (BIO_should_read(c_bio))
1447                                                         c_r=1;
1448                                                 if (BIO_should_write(c_bio))
1449                                                         c_w=1;
1450                                                 }
1451                                         else
1452                                                 {
1453                                                 fprintf(stderr,"ERROR in CLIENT\n");
1454                                                 ERR_print_errors(bio_err);
1455                                                 goto err;
1456                                                 }
1457                                         }
1458                                 else if (i == 0)
1459                                         {
1460                                         fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
1461                                         goto err;
1462                                         }
1463                                 else
1464                                         {
1465                                         if (debug)
1466                                                 printf("client wrote %d\n",i);
1467                                         /* ok */
1468                                         s_r=1;
1469                                         c_write=0;
1470                                         cw_num-=i;
1471                                         }
1472                                 }
1473                         else
1474                                 {
1475                                 i=BIO_read(c_bio,cbuf,sizeof(cbuf));
1476                                 if (i < 0)
1477                                         {
1478                                         c_r=0;
1479                                         c_w=0;
1480                                         if (BIO_should_retry(c_bio))
1481                                                 {
1482                                                 if (BIO_should_read(c_bio))
1483                                                         c_r=1;
1484                                                 if (BIO_should_write(c_bio))
1485                                                         c_w=1;
1486                                                 }
1487                                         else
1488                                                 {
1489                                                 fprintf(stderr,"ERROR in CLIENT\n");
1490                                                 ERR_print_errors(bio_err);
1491                                                 goto err;
1492                                                 }
1493                                         }
1494                                 else if (i == 0)
1495                                         {
1496                                         fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
1497                                         goto err;
1498                                         }
1499                                 else
1500                                         {
1501                                         if (debug)
1502                                                 printf("client read %d\n",i);
1503                                         cr_num-=i;
1504                                         if (sw_num > 0)
1505                                                 {
1506                                                 s_write=1;
1507                                                 s_w=1;
1508                                                 }
1509                                         if (cr_num <= 0)
1510                                                 {
1511                                                 s_write=1;
1512                                                 s_w=1;
1513                                                 done=S_DONE|C_DONE;
1514                                                 }
1515                                         }
1516                                 }
1517                         }
1518
1519                 if (do_server && !(done & S_DONE))
1520                         {
1521                         if (!s_write)
1522                                 {
1523                                 i=BIO_read(s_bio,sbuf,sizeof(cbuf));
1524                                 if (i < 0)
1525                                         {
1526                                         s_r=0;
1527                                         s_w=0;
1528                                         if (BIO_should_retry(s_bio))
1529                                                 {
1530                                                 if (BIO_should_read(s_bio))
1531                                                         s_r=1;
1532                                                 if (BIO_should_write(s_bio))
1533                                                         s_w=1;
1534                                                 }
1535                                         else
1536                                                 {
1537                                                 fprintf(stderr,"ERROR in SERVER\n");
1538                                                 ERR_print_errors(bio_err);
1539                                                 goto err;
1540                                                 }
1541                                         }
1542                                 else if (i == 0)
1543                                         {
1544                                         ERR_print_errors(bio_err);
1545                                         fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
1546                                         goto err;
1547                                         }
1548                                 else
1549                                         {
1550                                         if (debug)
1551                                                 printf("server read %d\n",i);
1552                                         sr_num-=i;
1553                                         if (cw_num > 0)
1554                                                 {
1555                                                 c_write=1;
1556                                                 c_w=1;
1557                                                 }
1558                                         if (sr_num <= 0)
1559                                                 {
1560                                                 s_write=1;
1561                                                 s_w=1;
1562                                                 c_write=0;
1563                                                 }
1564                                         }
1565                                 }
1566                         else
1567                                 {
1568                                 j = (sw_num > (long)sizeof(sbuf)) ?
1569                                         (int)sizeof(sbuf) : (int)sw_num;
1570                                 i=BIO_write(s_bio,sbuf,j);
1571                                 if (i < 0)
1572                                         {
1573                                         s_r=0;
1574                                         s_w=0;
1575                                         if (BIO_should_retry(s_bio))
1576                                                 {
1577                                                 if (BIO_should_read(s_bio))
1578                                                         s_r=1;
1579                                                 if (BIO_should_write(s_bio))
1580                                                         s_w=1;
1581                                                 }
1582                                         else
1583                                                 {
1584                                                 fprintf(stderr,"ERROR in SERVER\n");
1585                                                 ERR_print_errors(bio_err);
1586                                                 goto err;
1587                                                 }
1588                                         }
1589                                 else if (i == 0)
1590                                         {
1591                                         ERR_print_errors(bio_err);
1592                                         fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
1593                                         goto err;
1594                                         }
1595                                 else
1596                                         {
1597                                         if (debug)
1598                                                 printf("server wrote %d\n",i);
1599                                         sw_num-=i;
1600                                         s_write=0;
1601                                         c_r=1;
1602                                         if (sw_num <= 0)
1603                                                 done|=S_DONE;
1604                                         }
1605                                 }
1606                         }
1607
1608                 if ((done & S_DONE) && (done & C_DONE)) break;
1609                 }
1610
1611         if (verbose)
1612                 print_details(c_ssl, "DONE: ");
1613         ret=0;
1614 err:
1615         /* We have to set the BIO's to NULL otherwise they will be
1616          * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and
1617          * again when c_ssl is SSL_free()ed.
1618          * This is a hack required because s_ssl and c_ssl are sharing the same
1619          * BIO structure and SSL_set_bio() and SSL_free() automatically
1620          * BIO_free non NULL entries.
1621          * You should not normally do this or be required to do this */
1622         if (s_ssl != NULL)
1623                 {
1624                 s_ssl->rbio=NULL;
1625                 s_ssl->wbio=NULL;
1626                 }
1627         if (c_ssl != NULL)
1628                 {
1629                 c_ssl->rbio=NULL;
1630                 c_ssl->wbio=NULL;
1631                 }
1632
1633         if (c_to_s != NULL) BIO_free(c_to_s);
1634         if (s_to_c != NULL) BIO_free(s_to_c);
1635         if (c_bio != NULL) BIO_free_all(c_bio);
1636         if (s_bio != NULL) BIO_free_all(s_bio);
1637         return(ret);
1638         }
1639
1640 static int get_proxy_auth_ex_data_idx(void)
1641         {
1642         static volatile int idx = -1;
1643         if (idx < 0)
1644                 {
1645                 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
1646                 if (idx < 0)
1647                         {
1648                         idx = X509_STORE_CTX_get_ex_new_index(0,
1649                                 "SSLtest for verify callback", NULL,NULL,NULL);
1650                         }
1651                 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
1652                 }
1653         return idx;
1654         }
1655
1656 static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
1657         {
1658         char *s,buf[256];
1659
1660         s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
1661                             sizeof buf);
1662         if (s != NULL)
1663                 {
1664                 if (ok)
1665                         fprintf(stderr,"depth=%d %s\n",
1666                                 ctx->error_depth,buf);
1667                 else
1668                         {
1669                         fprintf(stderr,"depth=%d error=%d %s\n",
1670                                 ctx->error_depth,ctx->error,buf);
1671                         }
1672                 }
1673
1674         if (ok == 0)
1675                 {
1676                 fprintf(stderr,"Error string: %s\n",
1677                         X509_verify_cert_error_string(ctx->error));
1678                 switch (ctx->error)
1679                         {
1680                 case X509_V_ERR_CERT_NOT_YET_VALID:
1681                 case X509_V_ERR_CERT_HAS_EXPIRED:
1682                 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1683                         fprintf(stderr,"  ... ignored.\n");
1684                         ok=1;
1685                         }
1686                 }
1687
1688         if (ok == 1)
1689                 {
1690                 X509 *xs = ctx->current_cert;
1691 #if 0
1692                 X509 *xi = ctx->current_issuer;
1693 #endif
1694
1695                 if (xs->ex_flags & EXFLAG_PROXY)
1696                         {
1697                         unsigned int *letters =
1698                                 X509_STORE_CTX_get_ex_data(ctx,
1699                                         get_proxy_auth_ex_data_idx());
1700
1701                         if (letters)
1702                                 {
1703                                 int found_any = 0;
1704                                 int i;
1705                                 PROXY_CERT_INFO_EXTENSION *pci =
1706                                         X509_get_ext_d2i(xs, NID_proxyCertInfo,
1707                                                 NULL, NULL);
1708
1709                                 switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
1710                                         {
1711                                 case NID_Independent:
1712                                         /* Completely meaningless in this
1713                                            program, as there's no way to
1714                                            grant explicit rights to a
1715                                            specific PrC.  Basically, using
1716                                            id-ppl-Independent is the perfect
1717                                            way to grant no rights at all. */
1718                                         fprintf(stderr, "  Independent proxy certificate");
1719                                         for (i = 0; i < 26; i++)
1720                                                 letters[i] = 0;
1721                                         break;
1722                                 case NID_id_ppl_inheritAll:
1723                                         /* This is basically a NOP, we
1724                                            simply let the current rights
1725                                            stand as they are. */
1726                                         fprintf(stderr, "  Proxy certificate inherits all");
1727                                         break;
1728                                 default:
1729                                         s = (char *)
1730                                                 pci->proxyPolicy->policy->data;
1731                                         i = pci->proxyPolicy->policy->length;
1732
1733                                         /* The algorithm works as follows:
1734                                            it is assumed that previous
1735                                            iterations or the initial granted
1736                                            rights has already set some elements
1737                                            of `letters'.  What we need to do is
1738                                            to clear those that weren't granted
1739                                            by the current PrC as well.  The
1740                                            easiest way to do this is to add 1
1741                                            to all the elements whose letters
1742                                            are given with the current policy.
1743                                            That way, all elements that are set
1744                                            by the current policy and were
1745                                            already set by earlier policies and
1746                                            through the original grant of rights
1747                                            will get the value 2 or higher.
1748                                            The last thing to do is to sweep
1749                                            through `letters' and keep the
1750                                            elements having the value 2 as set,
1751                                            and clear all the others. */
1752
1753                                         fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
1754                                         while(i-- > 0)
1755                                                 {
1756                                                 int c = *s++;
1757                                                 if (isascii(c) && isalpha(c))
1758                                                         {
1759                                                         if (islower(c))
1760                                                                 c = toupper(c);
1761                                                         letters[c - 'A']++;
1762                                                         }
1763                                                 }
1764                                         for (i = 0; i < 26; i++)
1765                                                 if (letters[i] < 2)
1766                                                         letters[i] = 0;
1767                                                 else
1768                                                         letters[i] = 1;
1769                                         }
1770
1771                                 found_any = 0;
1772                                 fprintf(stderr,
1773                                         ", resulting proxy rights = ");
1774                                 for(i = 0; i < 26; i++)
1775                                         if (letters[i])
1776                                                 {
1777                                                 fprintf(stderr, "%c", i + 'A');
1778                                                 found_any = 1;
1779                                                 }
1780                                 if (!found_any)
1781                                         fprintf(stderr, "none");
1782                                 fprintf(stderr, "\n");
1783
1784                                 PROXY_CERT_INFO_EXTENSION_free(pci);
1785                                 }
1786                         }
1787                 }
1788
1789         return(ok);
1790         }
1791
1792 static void process_proxy_debug(int indent, const char *format, ...)
1793         {
1794         static const char indentation[] =
1795                 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
1796                 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
1797         char my_format[256];
1798         va_list args;
1799
1800         BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
1801                 indent, indent, indentation, format);
1802
1803         va_start(args, format);
1804         vfprintf(stderr, my_format, args);
1805         va_end(args);
1806         }
1807 /* Priority levels:
1808    0    [!]var, ()
1809    1    & ^
1810    2    |
1811 */
1812 static int process_proxy_cond_adders(unsigned int letters[26],
1813         const char *cond, const char **cond_end, int *pos, int indent);
1814 static int process_proxy_cond_val(unsigned int letters[26],
1815         const char *cond, const char **cond_end, int *pos, int indent)
1816         {
1817         int c;
1818         int ok = 1;
1819         int negate = 0;
1820
1821         while(isspace((int)*cond))
1822                 {
1823                 cond++; (*pos)++;
1824                 }
1825         c = *cond;
1826
1827         if (debug)
1828                 process_proxy_debug(indent,
1829                         "Start process_proxy_cond_val at position %d: %s\n",
1830                         *pos, cond);
1831
1832         while(c == '!')
1833                 {
1834                 negate = !negate;
1835                 cond++; (*pos)++;
1836                 while(isspace((int)*cond))
1837                         {
1838                         cond++; (*pos)++;
1839                         }
1840                 c = *cond;
1841                 }
1842
1843         if (c == '(')
1844                 {
1845                 cond++; (*pos)++;
1846                 ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
1847                         indent + 1);
1848                 cond = *cond_end;
1849                 if (ok < 0)
1850                         goto end;
1851                 while(isspace((int)*cond))
1852                         {
1853                         cond++; (*pos)++;
1854                         }
1855                 c = *cond;
1856                 if (c != ')')
1857                         {
1858                         fprintf(stderr,
1859                                 "Weird condition character in position %d: "
1860                                 "%c\n", *pos, c);
1861                         ok = -1;
1862                         goto end;
1863                         }
1864                 cond++; (*pos)++;
1865                 }
1866         else if (isascii(c) && isalpha(c))
1867                 {
1868                 if (islower(c))
1869                         c = toupper(c);
1870                 ok = letters[c - 'A'];
1871                 cond++; (*pos)++;
1872                 }
1873         else
1874                 {
1875                 fprintf(stderr,
1876                         "Weird condition character in position %d: "
1877                         "%c\n", *pos, c);
1878                 ok = -1;
1879                 goto end;
1880                 }
1881  end:
1882         *cond_end = cond;
1883         if (ok >= 0 && negate)
1884                 ok = !ok;
1885
1886         if (debug)
1887                 process_proxy_debug(indent,
1888                         "End process_proxy_cond_val at position %d: %s, returning %d\n",
1889                         *pos, cond, ok);
1890
1891         return ok;
1892         }
1893 static int process_proxy_cond_multipliers(unsigned int letters[26],
1894         const char *cond, const char **cond_end, int *pos, int indent)
1895         {
1896         int ok;
1897         char c;
1898
1899         if (debug)
1900                 process_proxy_debug(indent,
1901                         "Start process_proxy_cond_multipliers at position %d: %s\n",
1902                         *pos, cond);
1903
1904         ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
1905         cond = *cond_end;
1906         if (ok < 0)
1907                 goto end;
1908
1909         while(ok >= 0)
1910                 {
1911                 while(isspace((int)*cond))
1912                         {
1913                         cond++; (*pos)++;
1914                         }
1915                 c = *cond;
1916
1917                 switch(c)
1918                         {
1919                 case '&':
1920                 case '^':
1921                         {
1922                         int save_ok = ok;
1923
1924                         cond++; (*pos)++;
1925                         ok = process_proxy_cond_val(letters,
1926                                 cond, cond_end, pos, indent + 1);
1927                         cond = *cond_end;
1928                         if (ok < 0)
1929                                 break;
1930
1931                         switch(c)
1932                                 {
1933                         case '&':
1934                                 ok &= save_ok;
1935                                 break;
1936                         case '^':
1937                                 ok ^= save_ok;
1938                                 break;
1939                         default:
1940                                 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1941                                         " STOPPING\n");
1942                                 EXIT(1);
1943                                 }
1944                         }
1945                         break;
1946                 default:
1947                         goto end;
1948                         }
1949                 }
1950  end:
1951         if (debug)
1952                 process_proxy_debug(indent,
1953                         "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
1954                         *pos, cond, ok);
1955
1956         *cond_end = cond;
1957         return ok;
1958         }
1959 static int process_proxy_cond_adders(unsigned int letters[26],
1960         const char *cond, const char **cond_end, int *pos, int indent)
1961         {
1962         int ok;
1963         char c;
1964
1965         if (debug)
1966                 process_proxy_debug(indent,
1967                         "Start process_proxy_cond_adders at position %d: %s\n",
1968                         *pos, cond);
1969
1970         ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
1971                 indent + 1);
1972         cond = *cond_end;
1973         if (ok < 0)
1974                 goto end;
1975
1976         while(ok >= 0)
1977                 {
1978                 while(isspace((int)*cond))
1979                         {
1980                         cond++; (*pos)++;
1981                         }
1982                 c = *cond;
1983
1984                 switch(c)
1985                         {
1986                 case '|':
1987                         {
1988                         int save_ok = ok;
1989
1990                         cond++; (*pos)++;
1991                         ok = process_proxy_cond_multipliers(letters,
1992                                 cond, cond_end, pos, indent + 1);
1993                         cond = *cond_end;
1994                         if (ok < 0)
1995                                 break;
1996
1997                         switch(c)
1998                                 {
1999                         case '|':
2000                                 ok |= save_ok;
2001                                 break;
2002                         default:
2003                                 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
2004                                         " STOPPING\n");
2005                                 EXIT(1);
2006                                 }
2007                         }
2008                         break;
2009                 default:
2010                         goto end;
2011                         }
2012                 }
2013  end:
2014         if (debug)
2015                 process_proxy_debug(indent,
2016                         "End process_proxy_cond_adders at position %d: %s, returning %d\n",
2017                         *pos, cond, ok);
2018
2019         *cond_end = cond;
2020         return ok;
2021         }
2022
2023 static int process_proxy_cond(unsigned int letters[26],
2024         const char *cond, const char **cond_end)
2025         {
2026         int pos = 1;
2027         return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
2028         }
2029
2030 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
2031         {
2032         int ok=1;
2033         struct app_verify_arg *cb_arg = arg;
2034         unsigned int letters[26]; /* only used with proxy_auth */
2035
2036         if (cb_arg->app_verify)
2037                 {
2038                 char *s = NULL,buf[256];
2039
2040                 fprintf(stderr, "In app_verify_callback, allowing cert. ");
2041                 fprintf(stderr, "Arg is: %s\n", cb_arg->string);
2042                 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
2043                         (void *)ctx, (void *)ctx->cert);
2044                 if (ctx->cert)
2045                         s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
2046                 if (s != NULL)
2047                         {
2048                         fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
2049                         }
2050                 return(1);
2051                 }
2052         if (cb_arg->proxy_auth)
2053                 {
2054                 int found_any = 0, i;
2055                 char *sp;
2056
2057                 for(i = 0; i < 26; i++)
2058                         letters[i] = 0;
2059                 for(sp = cb_arg->proxy_auth; *sp; sp++)
2060                         {
2061                         int c = *sp;
2062                         if (isascii(c) && isalpha(c))
2063                                 {
2064                                 if (islower(c))
2065                                         c = toupper(c);
2066                                 letters[c - 'A'] = 1;
2067                                 }
2068                         }
2069
2070                 fprintf(stderr,
2071                         "  Initial proxy rights = ");
2072                 for(i = 0; i < 26; i++)
2073                         if (letters[i])
2074                                 {
2075                                 fprintf(stderr, "%c", i + 'A');
2076                                 found_any = 1;
2077                                 }
2078                 if (!found_any)
2079                         fprintf(stderr, "none");
2080                 fprintf(stderr, "\n");
2081
2082                 X509_STORE_CTX_set_ex_data(ctx,
2083                         get_proxy_auth_ex_data_idx(),letters);
2084                 }
2085         if (cb_arg->allow_proxy_certs)
2086                 {
2087                 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
2088                 }
2089
2090 #ifndef OPENSSL_NO_X509_VERIFY
2091         ok = X509_verify_cert(ctx);
2092 #endif
2093
2094         if (cb_arg->proxy_auth)
2095                 {
2096                 if (ok > 0)
2097                         {
2098                         const char *cond_end = NULL;
2099
2100                         ok = process_proxy_cond(letters,
2101                                 cb_arg->proxy_cond, &cond_end);
2102
2103                         if (ok < 0)
2104                                 EXIT(3);
2105                         if (*cond_end)
2106                                 {
2107                                 fprintf(stderr, "Stopped processing condition before it's end.\n");
2108                                 ok = 0;
2109                                 }
2110                         if (!ok)
2111                                 fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
2112                                         cb_arg->proxy_cond);
2113                         else
2114                                 fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
2115                                         cb_arg->proxy_cond);
2116                         }
2117                 }
2118         return(ok);
2119         }
2120
2121 #ifndef OPENSSL_NO_RSA
2122 static RSA *rsa_tmp=NULL;
2123
2124 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
2125         {
2126         BIGNUM *bn = NULL;
2127         if (rsa_tmp == NULL)
2128                 {
2129                 bn = BN_new();
2130                 rsa_tmp = RSA_new();
2131                 if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
2132                         {
2133                         BIO_printf(bio_err, "Memory error...");
2134                         goto end;
2135                         }
2136                 BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
2137                 (void)BIO_flush(bio_err);
2138                 if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
2139                         {
2140                         BIO_printf(bio_err, "Error generating key.");
2141                         RSA_free(rsa_tmp);
2142                         rsa_tmp = NULL;
2143                         }
2144 end:
2145                 BIO_printf(bio_err,"\n");
2146                 (void)BIO_flush(bio_err);
2147                 }
2148         if(bn) BN_free(bn);
2149         return(rsa_tmp);
2150         }
2151
2152 static void free_tmp_rsa(void)
2153         {
2154         if (rsa_tmp != NULL)
2155                 {
2156                 RSA_free(rsa_tmp);
2157                 rsa_tmp = NULL;
2158                 }
2159         }
2160 #endif
2161
2162 #ifndef OPENSSL_NO_DH
2163 /* These DH parameters have been generated as follows:
2164  *    $ openssl dhparam -C -noout 512
2165  *    $ openssl dhparam -C -noout 1024
2166  *    $ openssl dhparam -C -noout -dsaparam 1024
2167  * (The third function has been renamed to avoid name conflicts.)
2168  */
2169 static DH *get_dh512()
2170         {
2171         static unsigned char dh512_p[]={
2172                 0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
2173                 0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
2174                 0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
2175                 0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
2176                 0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
2177                 0x02,0xC5,0xAE,0x23,
2178                 };
2179         static unsigned char dh512_g[]={
2180                 0x02,
2181                 };
2182         DH *dh;
2183
2184         if ((dh=DH_new()) == NULL) return(NULL);
2185         dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
2186         dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
2187         if ((dh->p == NULL) || (dh->g == NULL))
2188                 { DH_free(dh); return(NULL); }
2189         return(dh);
2190         }
2191
2192 static DH *get_dh1024()
2193         {
2194         static unsigned char dh1024_p[]={
2195                 0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
2196                 0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
2197                 0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
2198                 0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
2199                 0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
2200                 0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
2201                 0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
2202                 0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
2203                 0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
2204                 0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
2205                 0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
2206                 };
2207         static unsigned char dh1024_g[]={
2208                 0x02,
2209                 };
2210         DH *dh;
2211
2212         if ((dh=DH_new()) == NULL) return(NULL);
2213         dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
2214         dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
2215         if ((dh->p == NULL) || (dh->g == NULL))
2216                 { DH_free(dh); return(NULL); }
2217         return(dh);
2218         }
2219
2220 static DH *get_dh1024dsa()
2221         {
2222         static unsigned char dh1024_p[]={
2223                 0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
2224                 0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
2225                 0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
2226                 0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
2227                 0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
2228                 0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
2229                 0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
2230                 0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
2231                 0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
2232                 0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
2233                 0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
2234                 };
2235         static unsigned char dh1024_g[]={
2236                 0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
2237                 0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
2238                 0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
2239                 0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
2240                 0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
2241                 0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
2242                 0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
2243                 0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
2244                 0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
2245                 0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
2246                 0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
2247                 };
2248         DH *dh;
2249
2250         if ((dh=DH_new()) == NULL) return(NULL);
2251         dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
2252         dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
2253         if ((dh->p == NULL) || (dh->g == NULL))
2254                 { DH_free(dh); return(NULL); }
2255         dh->length = 160;
2256         return(dh);
2257         }
2258 #endif
2259
2260 static int do_test_cipherlist(void)
2261         {
2262         int i = 0;
2263         const SSL_METHOD *meth;
2264         SSL_CIPHER *ci, *tci = NULL;
2265
2266 #ifndef OPENSSL_NO_SSL2
2267         fprintf(stderr, "testing SSLv2 cipher list order: ");
2268         meth = SSLv2_method();
2269         while ((ci = meth->get_cipher(i++)) != NULL)
2270                 {
2271                 if (tci != NULL)
2272                         if (ci->id >= tci->id)
2273                                 {
2274                                 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
2275                                 return 0;
2276                                 }
2277                 tci = ci;
2278                 }
2279         fprintf(stderr, "ok\n");
2280 #endif
2281 #ifndef OPENSSL_NO_SSL3
2282         fprintf(stderr, "testing SSLv3 cipher list order: ");
2283         meth = SSLv3_method();
2284         tci = NULL;
2285         while ((ci = meth->get_cipher(i++)) != NULL)
2286                 {
2287                 if (tci != NULL)
2288                         if (ci->id >= tci->id)
2289                                 {
2290                                 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
2291                                 return 0;
2292                                 }
2293                 tci = ci;
2294                 }
2295         fprintf(stderr, "ok\n");
2296 #endif
2297 #ifndef OPENSSL_NO_TLS1
2298         fprintf(stderr, "testing TLSv1 cipher list order: ");
2299         meth = TLSv1_method();
2300         tci = NULL;
2301         while ((ci = meth->get_cipher(i++)) != NULL)
2302                 {
2303                 if (tci != NULL)
2304                         if (ci->id >= tci->id)
2305                                 {
2306                                 fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
2307                                 return 0;
2308                                 }
2309                 tci = ci;
2310                 }
2311         fprintf(stderr, "ok\n");
2312 #endif
2313
2314         return 1;
2315         }