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