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