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