e47af50a4b7ac9c0c05dcffd457c14b497f81de9
[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 500       /* Or isascii won't be declared properly on
132                                    VMS (at least with DECompHP C).  */
133 #include <ctype.h>
134
135 #include <openssl/bio.h>
136 #include <openssl/crypto.h>
137 #include <openssl/evp.h>
138 #include <openssl/x509.h>
139 #include <openssl/x509v3.h>
140 #include <openssl/ssl.h>
141 #ifndef OPENSSL_NO_ENGINE
142 #include <openssl/engine.h>
143 #endif
144 #include <openssl/err.h>
145 #include <openssl/rand.h>
146 #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         int allow_proxy_certs;
194         char *proxy_auth;
195         char *proxy_cond;
196         };
197
198 #ifndef OPENSSL_NO_DH
199 static DH *get_dh512(void);
200 static DH *get_dh1024(void);
201 static DH *get_dh1024dsa(void);
202 #endif
203
204 static BIO *bio_err=NULL;
205 static BIO *bio_stdout=NULL;
206
207 static char *cipher=NULL;
208 static int verbose=0;
209 static int debug=0;
210 #if 0
211 /* Not used yet. */
212 #ifdef FIONBIO
213 static int s_nbio=0;
214 #endif
215 #endif
216
217 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
218
219 int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time);
220 int doit(SSL *s_ssl,SSL *c_ssl,long bytes);
221 static void sv_usage(void)
222         {
223         fprintf(stderr,"usage: ssltest [args ...]\n");
224         fprintf(stderr,"\n");
225         fprintf(stderr," -server_auth  - check server certificate\n");
226         fprintf(stderr," -client_auth  - do client authentication\n");
227         fprintf(stderr," -proxy        - allow proxy certificates\n");
228         fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
229         fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
230         fprintf(stderr," -v            - more output\n");
231         fprintf(stderr," -d            - debug output\n");
232         fprintf(stderr," -reuse        - use session-id reuse\n");
233         fprintf(stderr," -num <val>    - number of connections to perform\n");
234         fprintf(stderr," -bytes <val>  - number of bytes to swap between client/server\n");
235 #ifndef OPENSSL_NO_DH
236         fprintf(stderr," -dhe1024      - use 1024 bit key (safe prime) for DHE\n");
237         fprintf(stderr," -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
238         fprintf(stderr," -no_dhe       - disable DHE\n");
239 #endif
240 #ifndef OPENSSL_NO_ECDH
241         fprintf(stderr," -no_ecdhe     - disable ECDHE\n");
242 #endif
243 #ifndef OPENSSL_NO_SSL2
244         fprintf(stderr," -ssl2         - use SSLv2\n");
245 #endif
246 #ifndef OPENSSL_NO_SSL3
247         fprintf(stderr," -ssl3         - use SSLv3\n");
248 #endif
249 #ifndef OPENSSL_NO_TLS1
250         fprintf(stderr," -tls1         - use TLSv1\n");
251 #endif
252         fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
253         fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
254         fprintf(stderr," -cert arg     - Server certificate file\n");
255         fprintf(stderr," -key arg      - Server key file (default: same as -cert)\n");
256         fprintf(stderr," -c_cert arg   - Client certificate file\n");
257         fprintf(stderr," -c_key arg    - Client key file (default: same as -c_cert)\n");
258         fprintf(stderr," -cipher arg   - The cipher list\n");
259         fprintf(stderr," -bio_pair     - Use BIO pairs\n");
260         fprintf(stderr," -f            - Test even cases that can't work\n");
261         fprintf(stderr," -time         - measure processor time used by client and server\n");
262         fprintf(stderr," -zlib         - use zlib compression\n");
263         fprintf(stderr," -rle          - use rle compression\n");
264 #ifndef OPENSSL_NO_ECDH
265         fprintf(stderr," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
266                        "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
267                        "                 (default is sect163r2).\n");
268 #endif
269         }
270
271 static void print_details(SSL *c_ssl, const char *prefix)
272         {
273         SSL_CIPHER *ciph;
274         X509 *cert;
275                 
276         ciph=SSL_get_current_cipher(c_ssl);
277         BIO_printf(bio_stdout,"%s%s, cipher %s %s",
278                 prefix,
279                 SSL_get_version(c_ssl),
280                 SSL_CIPHER_get_version(ciph),
281                 SSL_CIPHER_get_name(ciph));
282         cert=SSL_get_peer_certificate(c_ssl);
283         if (cert != NULL)
284                 {
285                 EVP_PKEY *pkey = X509_get_pubkey(cert);
286                 if (pkey != NULL)
287                         {
288                         if (0) 
289                                 ;
290 #ifndef OPENSSL_NO_RSA
291                         else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
292                                 && pkey->pkey.rsa->n != NULL)
293                                 {
294                                 BIO_printf(bio_stdout, ", %d bit RSA",
295                                         BN_num_bits(pkey->pkey.rsa->n));
296                                 }
297 #endif
298 #ifndef OPENSSL_NO_DSA
299                         else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
300                                 && pkey->pkey.dsa->p != NULL)
301                                 {
302                                 BIO_printf(bio_stdout, ", %d bit DSA",
303                                         BN_num_bits(pkey->pkey.dsa->p));
304                                 }
305 #endif
306                         EVP_PKEY_free(pkey);
307                         }
308                 X509_free(cert);
309                 }
310         /* The SSL API does not allow us to look at temporary RSA/DH keys,
311          * otherwise we should print their lengths too */
312         BIO_printf(bio_stdout,"\n");
313         }
314
315 static void lock_dbg_cb(int mode, int type, const char *file, int line)
316         {
317         static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */
318         const char *errstr = NULL;
319         int rw;
320         
321         rw = mode & (CRYPTO_READ|CRYPTO_WRITE);
322         if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE)))
323                 {
324                 errstr = "invalid mode";
325                 goto err;
326                 }
327
328         if (type < 0 || type >= CRYPTO_NUM_LOCKS)
329                 {
330                 errstr = "type out of bounds";
331                 goto err;
332                 }
333
334         if (mode & CRYPTO_LOCK)
335                 {
336                 if (modes[type])
337                         {
338                         errstr = "already locked";
339                         /* must not happen in a single-threaded program
340                          * (would deadlock) */
341                         goto err;
342                         }
343
344                 modes[type] = rw;
345                 }
346         else if (mode & CRYPTO_UNLOCK)
347                 {
348                 if (!modes[type])
349                         {
350                         errstr = "not locked";
351                         goto err;
352                         }
353                 
354                 if (modes[type] != rw)
355                         {
356                         errstr = (rw == CRYPTO_READ) ?
357                                 "CRYPTO_r_unlock on write lock" :
358                                 "CRYPTO_w_unlock on read lock";
359                         }
360
361                 modes[type] = 0;
362                 }
363         else
364                 {
365                 errstr = "invalid mode";
366                 goto err;
367                 }
368
369  err:
370         if (errstr)
371                 {
372                 /* we cannot use bio_err here */
373                 fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n",
374                         errstr, mode, type, file, line);
375                 }
376         }
377
378 int main(int argc, char *argv[])
379         {
380         char *CApath=NULL,*CAfile=NULL;
381         int badop=0;
382         int bio_pair=0;
383         int force=0;
384         int tls1=0,ssl2=0,ssl3=0,ret=1;
385         int client_auth=0;
386         int server_auth=0,i;
387         struct app_verify_arg app_verify_arg =
388                 { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
389         char *server_cert=TEST_SERVER_CERT;
390         char *server_key=NULL;
391         char *client_cert=TEST_CLIENT_CERT;
392         char *client_key=NULL;
393         char *named_curve = NULL;
394         SSL_CTX *s_ctx=NULL;
395         SSL_CTX *c_ctx=NULL;
396         SSL_METHOD *meth=NULL;
397         SSL *c_ssl,*s_ssl;
398         int number=1,reuse=0;
399         long bytes=256L;
400 #ifndef OPENSSL_NO_DH
401         DH *dh;
402         int dhe1024 = 0, dhe1024dsa = 0;
403 #endif
404 #ifndef OPENSSL_NO_ECDH
405         EC_KEY *ecdh = NULL;
406 #endif
407         int no_dhe = 0;
408         int no_ecdhe = 0;
409         int print_time = 0;
410         clock_t s_time = 0, c_time = 0;
411         int comp = 0;
412         COMP_METHOD *cm = NULL;
413         STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
414
415         verbose = 0;
416         debug = 0;
417         cipher = 0;
418
419         bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 
420
421         CRYPTO_set_locking_callback(lock_dbg_cb);
422
423         /* enable memory leak checking unless explicitly disabled */
424         if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
425                 {
426                 CRYPTO_malloc_debug_init();
427                 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
428                 }
429         else
430                 {
431                 /* OPENSSL_DEBUG_MEMORY=off */
432                 CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
433                 }
434         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
435
436         RAND_seed(rnd_seed, sizeof rnd_seed);
437
438         bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
439
440         argc--;
441         argv++;
442
443         while (argc >= 1)
444                 {
445                 if      (strcmp(*argv,"-server_auth") == 0)
446                         server_auth=1;
447                 else if (strcmp(*argv,"-client_auth") == 0)
448                         client_auth=1;
449                 else if (strcmp(*argv,"-proxy_auth") == 0)
450                         {
451                         if (--argc < 1) goto bad;
452                         app_verify_arg.proxy_auth= *(++argv);
453                         }
454                 else if (strcmp(*argv,"-proxy_cond") == 0)
455                         {
456                         if (--argc < 1) goto bad;
457                         app_verify_arg.proxy_cond= *(++argv);
458                         }
459                 else if (strcmp(*argv,"-v") == 0)
460                         verbose=1;
461                 else if (strcmp(*argv,"-d") == 0)
462                         debug=1;
463                 else if (strcmp(*argv,"-reuse") == 0)
464                         reuse=1;
465                 else if (strcmp(*argv,"-dhe1024") == 0)
466                         {
467 #ifndef OPENSSL_NO_DH
468                         dhe1024=1;
469 #else
470                         fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
471 #endif
472                         }
473                 else if (strcmp(*argv,"-dhe1024dsa") == 0)
474                         {
475 #ifndef OPENSSL_NO_DH
476                         dhe1024dsa=1;
477 #else
478                         fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
479 #endif
480                         }
481                 else if (strcmp(*argv,"-no_dhe") == 0)
482                         no_dhe=1;
483                 else if (strcmp(*argv,"-no_ecdhe") == 0)
484                         no_ecdhe=1;
485                 else if (strcmp(*argv,"-ssl2") == 0)
486                         ssl2=1;
487                 else if (strcmp(*argv,"-tls1") == 0)
488                         tls1=1;
489                 else if (strcmp(*argv,"-ssl3") == 0)
490                         ssl3=1;
491                 else if (strncmp(*argv,"-num",4) == 0)
492                         {
493                         if (--argc < 1) goto bad;
494                         number= atoi(*(++argv));
495                         if (number == 0) number=1;
496                         }
497                 else if (strcmp(*argv,"-bytes") == 0)
498                         {
499                         if (--argc < 1) goto bad;
500                         bytes= atol(*(++argv));
501                         if (bytes == 0L) bytes=1L;
502                         i=strlen(argv[0]);
503                         if (argv[0][i-1] == 'k') bytes*=1024L;
504                         if (argv[0][i-1] == 'm') bytes*=1024L*1024L;
505                         }
506                 else if (strcmp(*argv,"-cert") == 0)
507                         {
508                         if (--argc < 1) goto bad;
509                         server_cert= *(++argv);
510                         }
511                 else if (strcmp(*argv,"-s_cert") == 0)
512                         {
513                         if (--argc < 1) goto bad;
514                         server_cert= *(++argv);
515                         }
516                 else if (strcmp(*argv,"-key") == 0)
517                         {
518                         if (--argc < 1) goto bad;
519                         server_key= *(++argv);
520                         }
521                 else if (strcmp(*argv,"-s_key") == 0)
522                         {
523                         if (--argc < 1) goto bad;
524                         server_key= *(++argv);
525                         }
526                 else if (strcmp(*argv,"-c_cert") == 0)
527                         {
528                         if (--argc < 1) goto bad;
529                         client_cert= *(++argv);
530                         }
531                 else if (strcmp(*argv,"-c_key") == 0)
532                         {
533                         if (--argc < 1) goto bad;
534                         client_key= *(++argv);
535                         }
536                 else if (strcmp(*argv,"-cipher") == 0)
537                         {
538                         if (--argc < 1) goto bad;
539                         cipher= *(++argv);
540                         }
541                 else if (strcmp(*argv,"-CApath") == 0)
542                         {
543                         if (--argc < 1) goto bad;
544                         CApath= *(++argv);
545                         }
546                 else if (strcmp(*argv,"-CAfile") == 0)
547                         {
548                         if (--argc < 1) goto bad;
549                         CAfile= *(++argv);
550                         }
551                 else if (strcmp(*argv,"-bio_pair") == 0)
552                         {
553                         bio_pair = 1;
554                         }
555                 else if (strcmp(*argv,"-f") == 0)
556                         {
557                         force = 1;
558                         }
559                 else if (strcmp(*argv,"-time") == 0)
560                         {
561                         print_time = 1;
562                         }
563                 else if (strcmp(*argv,"-zlib") == 0)
564                         {
565                         comp = COMP_ZLIB;
566                         }
567                 else if (strcmp(*argv,"-rle") == 0)
568                         {
569                         comp = COMP_RLE;
570                         }
571                 else if (strcmp(*argv,"-named_curve") == 0)
572                         {
573                         if (--argc < 1) goto bad;
574 #ifndef OPENSSL_NO_ECDH         
575                         named_curve = *(++argv);
576 #else
577                         fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
578                         ++argv;
579 #endif
580                         }
581                 else if (strcmp(*argv,"-app_verify") == 0)
582                         {
583                         app_verify_arg.app_verify = 1;
584                         }
585                 else if (strcmp(*argv,"-proxy") == 0)
586                         {
587                         app_verify_arg.allow_proxy_certs = 1;
588                         }
589                 else
590                         {
591                         fprintf(stderr,"unknown option %s\n",*argv);
592                         badop=1;
593                         break;
594                         }
595                 argc--;
596                 argv++;
597                 }
598         if (badop)
599                 {
600 bad:
601                 sv_usage();
602                 goto end;
603                 }
604
605         if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
606                 {
607                 fprintf(stderr, "This case cannot work.  Use -f to perform "
608                         "the test anyway (and\n-d to see what happens), "
609                         "or add one of -ssl2, -ssl3, -tls1, -reuse\n"
610                         "to avoid protocol mismatch.\n");
611                 EXIT(1);
612                 }
613
614         if (print_time)
615                 {
616                 if (!bio_pair)
617                         {
618                         fprintf(stderr, "Using BIO pair (-bio_pair)\n");
619                         bio_pair = 1;
620                         }
621                 if (number < 50 && !force)
622                         fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
623                 }
624
625 /*      if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
626
627         SSL_library_init();
628         SSL_load_error_strings();
629
630         if (comp == COMP_ZLIB) cm = COMP_zlib();
631         if (comp == COMP_RLE) cm = COMP_rle();
632         if (cm != NULL)
633                 {
634                 if (cm->type != NID_undef)
635                         {
636                         if (SSL_COMP_add_compression_method(comp, cm) != 0)
637                                 {
638                                 fprintf(stderr,
639                                         "Failed to add compression method\n");
640                                 ERR_print_errors_fp(stderr);
641                                 }
642                         }
643                 else
644                         {
645                         fprintf(stderr,
646                                 "Warning: %s compression not supported\n",
647                                 (comp == COMP_RLE ? "rle" :
648                                         (comp == COMP_ZLIB ? "zlib" :
649                                                 "unknown")));
650                         ERR_print_errors_fp(stderr);
651                         }
652                 }
653         ssl_comp_methods = SSL_COMP_get_compression_methods();
654         fprintf(stderr, "Available compression methods:\n");
655         {
656         int j, n = sk_SSL_COMP_num(ssl_comp_methods);
657         if (n == 0)
658                 fprintf(stderr, "  NONE\n");
659         else
660                 for (j = 0; j < n; j++)
661                         {
662                         SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
663                         fprintf(stderr, "  %d: %s\n", c->id, c->name);
664                         }
665         }
666
667 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
668         if (ssl2)
669                 meth=SSLv2_method();
670         else 
671         if (tls1)
672                 meth=TLSv1_method();
673         else
674         if (ssl3)
675                 meth=SSLv3_method();
676         else
677                 meth=SSLv23_method();
678 #else
679 #ifdef OPENSSL_NO_SSL2
680         meth=SSLv3_method();
681 #else
682         meth=SSLv2_method();
683 #endif
684 #endif
685
686         c_ctx=SSL_CTX_new(meth);
687         s_ctx=SSL_CTX_new(meth);
688         if ((c_ctx == NULL) || (s_ctx == NULL))
689                 {
690                 ERR_print_errors(bio_err);
691                 goto end;
692                 }
693
694         if (cipher != NULL)
695                 {
696                 SSL_CTX_set_cipher_list(c_ctx,cipher);
697                 SSL_CTX_set_cipher_list(s_ctx,cipher);
698                 }
699
700 #ifndef OPENSSL_NO_DH
701         if (!no_dhe)
702                 {
703                 if (dhe1024dsa)
704                         {
705                         /* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
706                         SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
707                         dh=get_dh1024dsa();
708                         }
709                 else if (dhe1024)
710                         dh=get_dh1024();
711                 else
712                         dh=get_dh512();
713                 SSL_CTX_set_tmp_dh(s_ctx,dh);
714                 DH_free(dh);
715                 }
716 #else
717         (void)no_dhe;
718 #endif
719
720 #ifndef OPENSSL_NO_ECDH
721         if (!no_ecdhe)
722                 {
723                 int nid;
724
725                 if (named_curve != NULL)
726                         {
727                         nid = OBJ_sn2nid(named_curve);
728                         if (nid == 0)
729                         {
730                                 BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
731                                 goto end;
732                                 }
733                         }
734                 else
735                         nid = NID_sect163r2;
736
737                 ecdh = EC_KEY_new_by_curve_name(nid);
738                 if (ecdh == NULL)
739                         {
740                         BIO_printf(bio_err, "unable to create curve\n");
741                         goto end;
742                         }
743
744                 SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
745                 SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
746                 EC_KEY_free(ecdh);
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                         {
1610                         fprintf(stderr,"depth=%d error=%d %s\n",
1611                                 ctx->error_depth,ctx->error,buf);
1612                         }
1613                 }
1614
1615         if (ok == 0)
1616                 {
1617                 fprintf(stderr,"Error string: %s\n",
1618                         X509_verify_cert_error_string(ctx->error));
1619                 switch (ctx->error)
1620                         {
1621                 case X509_V_ERR_CERT_NOT_YET_VALID:
1622                 case X509_V_ERR_CERT_HAS_EXPIRED:
1623                 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1624                         fprintf(stderr,"  ... ignored.\n");
1625                         ok=1;
1626                         }
1627                 }
1628
1629         if (ok == 1)
1630                 {
1631                 X509 *xs = ctx->current_cert;
1632 #if 0
1633                 X509 *xi = ctx->current_issuer;
1634 #endif
1635
1636                 if (xs->ex_flags & EXFLAG_PROXY)
1637                         {
1638                         unsigned int *letters =
1639                                 X509_STORE_CTX_get_ex_data(ctx,
1640                                         get_proxy_auth_ex_data_idx());
1641
1642                         if (letters)
1643                                 {
1644                                 int found_any = 0;
1645                                 int i;
1646                                 PROXY_CERT_INFO_EXTENSION *pci =
1647                                         X509_get_ext_d2i(xs, NID_proxyCertInfo,
1648                                                 NULL, NULL);
1649
1650                                 switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage))
1651                                         {
1652                                 case NID_Independent:
1653                                         /* Completely meaningless in this
1654                                            program, as there's no way to
1655                                            grant explicit rights to a
1656                                            specific PrC.  Basically, using
1657                                            id-ppl-Independent is the perfect
1658                                            way to grant no rights at all. */
1659                                         fprintf(stderr, "  Independent proxy certificate");
1660                                         for (i = 0; i < 26; i++)
1661                                                 letters[i] = 0;
1662                                         break;
1663                                 case NID_id_ppl_inheritAll:
1664                                         /* This is basically a NOP, we
1665                                            simply let the current rights
1666                                            stand as they are. */
1667                                         fprintf(stderr, "  Proxy certificate inherits all");
1668                                         break;
1669                                 default:
1670                                         s = (char *)
1671                                                 pci->proxyPolicy->policy->data;
1672                                         i = pci->proxyPolicy->policy->length;
1673
1674                                         /* The algorithm works as follows:
1675                                            it is assumed that previous
1676                                            iterations or the initial granted
1677                                            rights has already set some elements
1678                                            of `letters'.  What we need to do is
1679                                            to clear those that weren't granted
1680                                            by the current PrC as well.  The
1681                                            easiest way to do this is to add 1
1682                                            to all the elements whose letters
1683                                            are given with the current policy.
1684                                            That way, all elements that are set
1685                                            by the current policy and were
1686                                            already set by earlier policies and
1687                                            through the original grant of rights
1688                                            will get the value 2 or higher.
1689                                            The last thing to do is to sweep
1690                                            through `letters' and keep the
1691                                            elements having the value 2 as set,
1692                                            and clear all the others. */
1693
1694                                         fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
1695                                         while(i-- > 0)
1696                                                 {
1697                                                 char c = *s++;
1698                                                 if (isascii(c) && isalpha(c))
1699                                                         {
1700                                                         if (islower(c))
1701                                                                 c = toupper(c);
1702                                                         letters[c - 'A']++;
1703                                                         }
1704                                                 }
1705                                         for (i = 0; i < 26; i++)
1706                                                 if (letters[i] < 2)
1707                                                         letters[i] = 0;
1708                                                 else
1709                                                         letters[i] = 1;
1710                                         }
1711
1712                                 found_any = 0;
1713                                 fprintf(stderr,
1714                                         ", resulting proxy rights = ");
1715                                 for(i = 0; i < 26; i++)
1716                                         if (letters[i])
1717                                                 {
1718                                                 fprintf(stderr, "%c", i + 'A');
1719                                                 found_any = 1;
1720                                                 }
1721                                 if (!found_any)
1722                                         fprintf(stderr, "none");
1723                                 fprintf(stderr, "\n");
1724
1725                                 PROXY_CERT_INFO_EXTENSION_free(pci);
1726                                 }
1727                         }
1728                 }
1729
1730         return(ok);
1731         }
1732
1733 static void process_proxy_debug(int indent, const char *format, ...)
1734         {
1735         static const char indentation[] =
1736                 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
1737                 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
1738         char my_format[256];
1739         va_list args;
1740
1741         BIO_snprintf(my_format, sizeof(my_format), "%*.*s %s",
1742                 indent, indent, indentation, format);
1743
1744         va_start(args, format);
1745         vfprintf(stderr, my_format, args);
1746         va_end(args);
1747         }
1748 /* Priority levels:
1749    0    [!]var, ()
1750    1    & ^
1751    2    |
1752 */
1753 static int process_proxy_cond_adders(unsigned int letters[26],
1754         const char *cond, const char **cond_end, int *pos, int indent);
1755 static int process_proxy_cond_val(unsigned int letters[26],
1756         const char *cond, const char **cond_end, int *pos, int indent)
1757         {
1758         char c;
1759         int ok = 1;
1760         int negate = 0;
1761
1762         while(isspace(*cond))
1763                 {
1764                 cond++; (*pos)++;
1765                 }
1766         c = *cond;
1767
1768         if (debug)
1769                 process_proxy_debug(indent,
1770                         "Start process_proxy_cond_val at position %d: %s\n",
1771                         *pos, cond);
1772
1773         while(c == '!')
1774                 {
1775                 negate = !negate;
1776                 cond++; (*pos)++;
1777                 while(isspace(*cond))
1778                         {
1779                         cond++; (*pos)++;
1780                         }
1781                 c = *cond;
1782                 }
1783
1784         if (c == '(')
1785                 {
1786                 cond++; (*pos)++;
1787                 ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
1788                         indent + 1);
1789                 cond = *cond_end;
1790                 if (ok < 0)
1791                         goto end;
1792                 while(isspace(*cond))
1793                         {
1794                         cond++; (*pos)++;
1795                         }
1796                 c = *cond;
1797                 if (c != ')')
1798                         {
1799                         fprintf(stderr,
1800                                 "Weird condition character in position %d: "
1801                                 "%c\n", *pos, c);
1802                         ok = -1;
1803                         goto end;
1804                         }
1805                 cond++; (*pos)++;
1806                 }
1807         else if (isascii(c) && isalpha(c))
1808                 {
1809                 if (islower(c))
1810                         c = toupper(c);
1811                 ok = letters[c - 'A'];
1812                 cond++; (*pos)++;
1813                 }
1814         else
1815                 {
1816                 fprintf(stderr,
1817                         "Weird condition character in position %d: "
1818                         "%c\n", *pos, c);
1819                 ok = -1;
1820                 goto end;
1821                 }
1822  end:
1823         *cond_end = cond;
1824         if (ok >= 0 && negate)
1825                 ok = !ok;
1826
1827         if (debug)
1828                 process_proxy_debug(indent,
1829                         "End process_proxy_cond_val at position %d: %s, returning %d\n",
1830                         *pos, cond, ok);
1831
1832         return ok;
1833         }
1834 static int process_proxy_cond_multipliers(unsigned int letters[26],
1835         const char *cond, const char **cond_end, int *pos, int indent)
1836         {
1837         int ok;
1838         char c;
1839
1840         if (debug)
1841                 process_proxy_debug(indent,
1842                         "Start process_proxy_cond_multipliers at position %d: %s\n",
1843                         *pos, cond);
1844
1845         ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
1846         cond = *cond_end;
1847         if (ok < 0)
1848                 goto end;
1849
1850         while(ok >= 0)
1851                 {
1852                 while(isspace(*cond))
1853                         {
1854                         cond++; (*pos)++;
1855                         }
1856                 c = *cond;
1857
1858                 switch(c)
1859                         {
1860                 case '&':
1861                 case '^':
1862                         {
1863                         int save_ok = ok;
1864
1865                         cond++; (*pos)++;
1866                         ok = process_proxy_cond_val(letters,
1867                                 cond, cond_end, pos, indent + 1);
1868                         cond = *cond_end;
1869                         if (ok < 0)
1870                                 break;
1871
1872                         switch(c)
1873                                 {
1874                         case '&':
1875                                 ok &= save_ok;
1876                                 break;
1877                         case '^':
1878                                 ok ^= save_ok;
1879                                 break;
1880                         default:
1881                                 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1882                                         " STOPPING\n");
1883                                 EXIT(1);
1884                                 }
1885                         }
1886                         break;
1887                 default:
1888                         goto end;
1889                         }
1890                 }
1891  end:
1892         if (debug)
1893                 process_proxy_debug(indent,
1894                         "End process_proxy_cond_multipliers at position %d: %s, returning %d\n",
1895                         *pos, cond, ok);
1896
1897         *cond_end = cond;
1898         return ok;
1899         }
1900 static int process_proxy_cond_adders(unsigned int letters[26],
1901         const char *cond, const char **cond_end, int *pos, int indent)
1902         {
1903         int ok;
1904         char c;
1905
1906         if (debug)
1907                 process_proxy_debug(indent,
1908                         "Start process_proxy_cond_adders at position %d: %s\n",
1909                         *pos, cond);
1910
1911         ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
1912                 indent + 1);
1913         cond = *cond_end;
1914         if (ok < 0)
1915                 goto end;
1916
1917         while(ok >= 0)
1918                 {
1919                 while(isspace(*cond))
1920                         {
1921                         cond++; (*pos)++;
1922                         }
1923                 c = *cond;
1924
1925                 switch(c)
1926                         {
1927                 case '|':
1928                         {
1929                         int save_ok = ok;
1930
1931                         cond++; (*pos)++;
1932                         ok = process_proxy_cond_multipliers(letters,
1933                                 cond, cond_end, pos, indent + 1);
1934                         cond = *cond_end;
1935                         if (ok < 0)
1936                                 break;
1937
1938                         switch(c)
1939                                 {
1940                         case '|':
1941                                 ok |= save_ok;
1942                                 break;
1943                         default:
1944                                 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1945                                         " STOPPING\n");
1946                                 EXIT(1);
1947                                 }
1948                         }
1949                         break;
1950                 default:
1951                         goto end;
1952                         }
1953                 }
1954  end:
1955         if (debug)
1956                 process_proxy_debug(indent,
1957                         "End process_proxy_cond_adders at position %d: %s, returning %d\n",
1958                         *pos, cond, ok);
1959
1960         *cond_end = cond;
1961         return ok;
1962         }
1963
1964 static int process_proxy_cond(unsigned int letters[26],
1965         const char *cond, const char **cond_end)
1966         {
1967         int pos = 1;
1968         return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
1969         }
1970
1971 static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
1972         {
1973         int ok=1;
1974         struct app_verify_arg *cb_arg = arg;
1975         unsigned int letters[26]; /* only used with proxy_auth */
1976
1977         if (cb_arg->app_verify)
1978                 {
1979                 char *s = NULL,buf[256];
1980
1981                 fprintf(stderr, "In app_verify_callback, allowing cert. ");
1982                 fprintf(stderr, "Arg is: %s\n", cb_arg->string);
1983                 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
1984                         (void *)ctx, (void *)ctx->cert);
1985                 if (ctx->cert)
1986                         s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
1987                 if (s != NULL)
1988                         {
1989                         fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
1990                         }
1991                 return(1);
1992                 }
1993         if (cb_arg->proxy_auth)
1994                 {
1995                 int found_any = 0, i;
1996                 char *sp;
1997
1998                 for(i = 0; i < 26; i++)
1999                         letters[i] = 0;
2000                 for(sp = cb_arg->proxy_auth; *sp; sp++)
2001                         {
2002                         char c = *sp;
2003                         if (isascii(c) && isalpha(c))
2004                                 {
2005                                 if (islower(c))
2006                                         c = toupper(c);
2007                                 letters[c - 'A'] = 1;
2008                                 }
2009                         }
2010
2011                 fprintf(stderr,
2012                         "  Initial proxy rights = ");
2013                 for(i = 0; i < 26; i++)
2014                         if (letters[i])
2015                                 {
2016                                 fprintf(stderr, "%c", i + 'A');
2017                                 found_any = 1;
2018                                 }
2019                 if (!found_any)
2020                         fprintf(stderr, "none");
2021                 fprintf(stderr, "\n");
2022
2023                 X509_STORE_CTX_set_ex_data(ctx,
2024                         get_proxy_auth_ex_data_idx(),letters);
2025                 }
2026         if (cb_arg->allow_proxy_certs)
2027                 {
2028                 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
2029                 }
2030
2031 #ifndef OPENSSL_NO_X509_VERIFY
2032 # ifdef OPENSSL_FIPS
2033         if(s->version == TLS1_VERSION)
2034                 FIPS_allow_md5(1);
2035 # endif
2036         ok = X509_verify_cert(ctx);
2037 # ifdef OPENSSL_FIPS
2038         if(s->version == TLS1_VERSION)
2039                 FIPS_allow_md5(0);
2040 # endif
2041 #endif
2042
2043         if (cb_arg->proxy_auth)
2044                 {
2045                 if (ok)
2046                         {
2047                         const char *cond_end = NULL;
2048
2049                         ok = process_proxy_cond(letters,
2050                                 cb_arg->proxy_cond, &cond_end);
2051
2052                         if (ok < 0)
2053                                 EXIT(3);
2054                         if (*cond_end)
2055                                 {
2056                                 fprintf(stderr, "Stopped processing condition before it's end.\n");
2057                                 ok = 0;
2058                                 }
2059                         if (!ok)
2060                                 fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
2061                                         cb_arg->proxy_cond);
2062                         else
2063                                 fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
2064                                         cb_arg->proxy_cond);
2065                         }
2066                 }
2067         return(ok);
2068         }
2069
2070 #ifndef OPENSSL_NO_RSA
2071 static RSA *rsa_tmp=NULL;
2072
2073 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
2074         {
2075         BIGNUM *bn = NULL;
2076         if (rsa_tmp == NULL)
2077                 {
2078                 bn = BN_new();
2079                 rsa_tmp = RSA_new();
2080                 if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
2081                         {
2082                         BIO_printf(bio_err, "Memory error...");
2083                         goto end;
2084                         }
2085                 BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
2086                 (void)BIO_flush(bio_err);
2087                 if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
2088                         {
2089                         BIO_printf(bio_err, "Error generating key.");
2090                         RSA_free(rsa_tmp);
2091                         rsa_tmp = NULL;
2092                         }
2093 end:
2094                 BIO_printf(bio_err,"\n");
2095                 (void)BIO_flush(bio_err);
2096                 }
2097         if(bn) BN_free(bn);
2098         return(rsa_tmp);
2099         }
2100
2101 static void free_tmp_rsa(void)
2102         {
2103         if (rsa_tmp != NULL)
2104                 {
2105                 RSA_free(rsa_tmp);
2106                 rsa_tmp = NULL;
2107                 }
2108         }
2109 #endif
2110
2111 #ifndef OPENSSL_NO_DH
2112 /* These DH parameters have been generated as follows:
2113  *    $ openssl dhparam -C -noout 512
2114  *    $ openssl dhparam -C -noout 1024
2115  *    $ openssl dhparam -C -noout -dsaparam 1024
2116  * (The third function has been renamed to avoid name conflicts.)
2117  */
2118 static DH *get_dh512()
2119         {
2120         static unsigned char dh512_p[]={
2121                 0xCB,0xC8,0xE1,0x86,0xD0,0x1F,0x94,0x17,0xA6,0x99,0xF0,0xC6,
2122                 0x1F,0x0D,0xAC,0xB6,0x25,0x3E,0x06,0x39,0xCA,0x72,0x04,0xB0,
2123                 0x6E,0xDA,0xC0,0x61,0xE6,0x7A,0x77,0x25,0xE8,0x3B,0xB9,0x5F,
2124                 0x9A,0xB6,0xB5,0xFE,0x99,0x0B,0xA1,0x93,0x4E,0x35,0x33,0xB8,
2125                 0xE1,0xF1,0x13,0x4F,0x59,0x1A,0xD2,0x57,0xC0,0x26,0x21,0x33,
2126                 0x02,0xC5,0xAE,0x23,
2127                 };
2128         static unsigned char dh512_g[]={
2129                 0x02,
2130                 };
2131         DH *dh;
2132
2133         if ((dh=DH_new()) == NULL) return(NULL);
2134         dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
2135         dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
2136         if ((dh->p == NULL) || (dh->g == NULL))
2137                 { DH_free(dh); return(NULL); }
2138         return(dh);
2139         }
2140
2141 static DH *get_dh1024()
2142         {
2143         static unsigned char dh1024_p[]={
2144                 0xF8,0x81,0x89,0x7D,0x14,0x24,0xC5,0xD1,0xE6,0xF7,0xBF,0x3A,
2145                 0xE4,0x90,0xF4,0xFC,0x73,0xFB,0x34,0xB5,0xFA,0x4C,0x56,0xA2,
2146                 0xEA,0xA7,0xE9,0xC0,0xC0,0xCE,0x89,0xE1,0xFA,0x63,0x3F,0xB0,
2147                 0x6B,0x32,0x66,0xF1,0xD1,0x7B,0xB0,0x00,0x8F,0xCA,0x87,0xC2,
2148                 0xAE,0x98,0x89,0x26,0x17,0xC2,0x05,0xD2,0xEC,0x08,0xD0,0x8C,
2149                 0xFF,0x17,0x52,0x8C,0xC5,0x07,0x93,0x03,0xB1,0xF6,0x2F,0xB8,
2150                 0x1C,0x52,0x47,0x27,0x1B,0xDB,0xD1,0x8D,0x9D,0x69,0x1D,0x52,
2151                 0x4B,0x32,0x81,0xAA,0x7F,0x00,0xC8,0xDC,0xE6,0xD9,0xCC,0xC1,
2152                 0x11,0x2D,0x37,0x34,0x6C,0xEA,0x02,0x97,0x4B,0x0E,0xBB,0xB1,
2153                 0x71,0x33,0x09,0x15,0xFD,0xDD,0x23,0x87,0x07,0x5E,0x89,0xAB,
2154                 0x6B,0x7C,0x5F,0xEC,0xA6,0x24,0xDC,0x53,
2155                 };
2156         static unsigned char dh1024_g[]={
2157                 0x02,
2158                 };
2159         DH *dh;
2160
2161         if ((dh=DH_new()) == NULL) return(NULL);
2162         dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
2163         dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
2164         if ((dh->p == NULL) || (dh->g == NULL))
2165                 { DH_free(dh); return(NULL); }
2166         return(dh);
2167         }
2168
2169 static DH *get_dh1024dsa()
2170         {
2171         static unsigned char dh1024_p[]={
2172                 0xC8,0x00,0xF7,0x08,0x07,0x89,0x4D,0x90,0x53,0xF3,0xD5,0x00,
2173                 0x21,0x1B,0xF7,0x31,0xA6,0xA2,0xDA,0x23,0x9A,0xC7,0x87,0x19,
2174                 0x3B,0x47,0xB6,0x8C,0x04,0x6F,0xFF,0xC6,0x9B,0xB8,0x65,0xD2,
2175                 0xC2,0x5F,0x31,0x83,0x4A,0xA7,0x5F,0x2F,0x88,0x38,0xB6,0x55,
2176                 0xCF,0xD9,0x87,0x6D,0x6F,0x9F,0xDA,0xAC,0xA6,0x48,0xAF,0xFC,
2177                 0x33,0x84,0x37,0x5B,0x82,0x4A,0x31,0x5D,0xE7,0xBD,0x52,0x97,
2178                 0xA1,0x77,0xBF,0x10,0x9E,0x37,0xEA,0x64,0xFA,0xCA,0x28,0x8D,
2179                 0x9D,0x3B,0xD2,0x6E,0x09,0x5C,0x68,0xC7,0x45,0x90,0xFD,0xBB,
2180                 0x70,0xC9,0x3A,0xBB,0xDF,0xD4,0x21,0x0F,0xC4,0x6A,0x3C,0xF6,
2181                 0x61,0xCF,0x3F,0xD6,0x13,0xF1,0x5F,0xBC,0xCF,0xBC,0x26,0x9E,
2182                 0xBC,0x0B,0xBD,0xAB,0x5D,0xC9,0x54,0x39,
2183                 };
2184         static unsigned char dh1024_g[]={
2185                 0x3B,0x40,0x86,0xE7,0xF3,0x6C,0xDE,0x67,0x1C,0xCC,0x80,0x05,
2186                 0x5A,0xDF,0xFE,0xBD,0x20,0x27,0x74,0x6C,0x24,0xC9,0x03,0xF3,
2187                 0xE1,0x8D,0xC3,0x7D,0x98,0x27,0x40,0x08,0xB8,0x8C,0x6A,0xE9,
2188                 0xBB,0x1A,0x3A,0xD6,0x86,0x83,0x5E,0x72,0x41,0xCE,0x85,0x3C,
2189                 0xD2,0xB3,0xFC,0x13,0xCE,0x37,0x81,0x9E,0x4C,0x1C,0x7B,0x65,
2190                 0xD3,0xE6,0xA6,0x00,0xF5,0x5A,0x95,0x43,0x5E,0x81,0xCF,0x60,
2191                 0xA2,0x23,0xFC,0x36,0xA7,0x5D,0x7A,0x4C,0x06,0x91,0x6E,0xF6,
2192                 0x57,0xEE,0x36,0xCB,0x06,0xEA,0xF5,0x3D,0x95,0x49,0xCB,0xA7,
2193                 0xDD,0x81,0xDF,0x80,0x09,0x4A,0x97,0x4D,0xA8,0x22,0x72,0xA1,
2194                 0x7F,0xC4,0x70,0x56,0x70,0xE8,0x20,0x10,0x18,0x8F,0x2E,0x60,
2195                 0x07,0xE7,0x68,0x1A,0x82,0x5D,0x32,0xA2,
2196                 };
2197         DH *dh;
2198
2199         if ((dh=DH_new()) == NULL) return(NULL);
2200         dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
2201         dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
2202         if ((dh->p == NULL) || (dh->g == NULL))
2203                 { DH_free(dh); return(NULL); }
2204         dh->length = 160;
2205         return(dh);
2206         }
2207 #endif