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