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