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