]> git.ipfire.org Git - thirdparty/openssl.git/blame - ssl/ssltest.c
pariscid.pl: OPENSSL_cleanse to compile on PA-RISC 2.0W and to accept zero
[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 */
ddac1974
NL
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 */
d02b48c6 142
4fbe40c5 143#define _BSD_SOURCE 1 /* Or gethostname won't be declared properly
37289744 144 on Linux and GNU platforms. */
37289744 145
ce1ec9c3
DSH
146#define _XOPEN_SOURCE 500 /* Or isascii won't be declared properly on
147 VMS (at least with DECompHP C). */
148
6f7af152
BM
149#include <assert.h>
150#include <errno.h>
151#include <limits.h>
d02b48c6
RE
152#include <stdio.h>
153#include <stdlib.h>
154#include <string.h>
563f1503 155#include <time.h>
17e3dd1c 156
e7a28569 157#define USE_SOCKETS
41d2a336 158#include "e_os.h"
17e3dd1c 159
a963395a
RL
160#include <ctype.h>
161
ec577822
BM
162#include <openssl/bio.h>
163#include <openssl/crypto.h>
563f1503 164#include <openssl/evp.h>
ec577822 165#include <openssl/x509.h>
a7201e9a 166#include <openssl/x509v3.h>
ec577822 167#include <openssl/ssl.h>
0b13e9f0 168#ifndef OPENSSL_NO_ENGINE
b8e2f83a 169#include <openssl/engine.h>
0b13e9f0 170#endif
ec577822 171#include <openssl/err.h>
b9d82f47 172#include <openssl/rand.h>
3eeaab4b 173#ifndef OPENSSL_NO_RSA
60a938c6 174#include <openssl/rsa.h>
3eeaab4b
NL
175#endif
176#ifndef OPENSSL_NO_DSA
60a938c6 177#include <openssl/dsa.h>
3eeaab4b
NL
178#endif
179#ifndef OPENSSL_NO_DH
60a938c6 180#include <openssl/dh.h>
3eeaab4b 181#endif
d095b68d 182#include <openssl/bn.h>
09867a47
RL
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
bc36ee62 190#ifdef OPENSSL_SYS_WINDOWS
f9b3bff6 191#include <winsock.h>
37289744
RL
192#else
193#include OPENSSL_UNISTD
d02b48c6
RE
194#endif
195
bc36ee62 196#ifdef OPENSSL_SYS_VMS
7d7d2cbc
UM
197# define TEST_SERVER_CERT "SYS$DISK:[-.APPS]SERVER.PEM"
198# define TEST_CLIENT_CERT "SYS$DISK:[-.APPS]CLIENT.PEM"
0bf23d9b
RL
199#elif defined(OPENSSL_SYS_WINCE)
200# define TEST_SERVER_CERT "\\OpenSSL\\server.pem"
201# define TEST_CLIENT_CERT "\\OpenSSL\\client.pem"
4d8743f4
RL
202#elif defined(OPENSSL_SYS_NETWARE)
203# define TEST_SERVER_CERT "\\openssl\\apps\\server.pem"
204# define TEST_CLIENT_CERT "\\openssl\\apps\\client.pem"
7d7d2cbc
UM
205#else
206# define TEST_SERVER_CERT "../apps/server.pem"
207# define TEST_CLIENT_CERT "../apps/client.pem"
208#endif
d02b48c6 209
23f80f46
RL
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 */
82423549
RL
212#define COMP_RLE 255
213#define COMP_ZLIB 1
23f80f46 214
396f6314 215static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
bc36ee62 216#ifndef OPENSSL_NO_RSA
df63a389 217static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
46b3bd54 218static void free_tmp_rsa(void);
79df9d62 219#endif
023ec151 220static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
a7201e9a
RL
221#define APP_CALLBACK_STRING "Test Callback Argument"
222struct app_verify_arg
223 {
224 char *string;
225 int app_verify;
d9bfe4f9 226 int allow_proxy_certs;
a7201e9a
RL
227 char *proxy_auth;
228 char *proxy_cond;
229 };
023ec151 230
bc36ee62 231#ifndef OPENSSL_NO_DH
d02b48c6 232static DH *get_dh512(void);
e4589582
BM
233static DH *get_dh1024(void);
234static DH *get_dh1024dsa(void);
53002dc6
BM
235#endif
236
ddac1974
NL
237
238static char *psk_key=NULL; /* by default PSK is not used */
239#ifndef OPENSSL_NO_PSK
240static 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);
243static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
244 unsigned int max_psk_len);
245#endif
246
396f6314
BM
247static BIO *bio_err=NULL;
248static BIO *bio_stdout=NULL;
d02b48c6
RE
249
250static char *cipher=NULL;
79875776
BM
251static int verbose=0;
252static int debug=0;
d58d092b
BM
253#if 0
254/* Not used yet. */
d02b48c6
RE
255#ifdef FIONBIO
256static int s_nbio=0;
257#endif
d58d092b 258#endif
d02b48c6 259
b9d82f47 260static const char rnd_seed[] = "string to make the random number generator think it has entropy";
d02b48c6 261
563f1503 262int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time);
58964a49 263int doit(SSL *s_ssl,SSL *c_ssl,long bytes);
6e119bb0 264static int do_test_cipherlist(void);
6b691a5c 265static void sv_usage(void)
d02b48c6
RE
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");
d9bfe4f9 271 fprintf(stderr," -proxy - allow proxy certificates\n");
a7201e9a
RL
272 fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
273 fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
d02b48c6 274 fprintf(stderr," -v - more output\n");
58964a49
RE
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");
bc36ee62 279#ifndef OPENSSL_NO_DH
e4589582
BM
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");
77fa04a9
BM
282 fprintf(stderr," -no_dhe - disable DHE\n");
283#endif
ea262260
BM
284#ifndef OPENSSL_NO_ECDH
285 fprintf(stderr," -no_ecdhe - disable ECDHE\n");
286#endif
ddac1974
NL
287#ifndef OPENSSL_NO_PSK
288 fprintf(stderr," -psk arg - PSK in hex (without 0x)\n");
289#endif
bc36ee62 290#ifndef OPENSSL_NO_SSL2
d02b48c6
RE
291 fprintf(stderr," -ssl2 - use SSLv2\n");
292#endif
bc36ee62 293#ifndef OPENSSL_NO_SSL3
d02b48c6 294 fprintf(stderr," -ssl3 - use SSLv3\n");
58964a49 295#endif
bc36ee62 296#ifndef OPENSSL_NO_TLS1
58964a49 297 fprintf(stderr," -tls1 - use TLSv1\n");
d02b48c6
RE
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");
7d2509b6
BM
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");
58964a49 305 fprintf(stderr," -cipher arg - The cipher list\n");
95d29597
BM
306 fprintf(stderr," -bio_pair - Use BIO pairs\n");
307 fprintf(stderr," -f - Test even cases that can't work\n");
563f1503 308 fprintf(stderr," -time - measure processor time used by client and server\n");
23f80f46 309 fprintf(stderr," -zlib - use zlib compression\n");
ea262260
BM
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
6e119bb0 316 fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
563f1503
BM
317 }
318
319static void print_details(SSL *c_ssl, const char *prefix)
320 {
babb3798 321 const SSL_CIPHER *ciph;
563f1503
BM
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 ;
bc36ee62 338#ifndef OPENSSL_NO_RSA
563f1503
BM
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
bc36ee62 346#ifndef OPENSSL_NO_DSA
563f1503
BM
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");
d02b48c6
RE
361 }
362
3ac82faa
BM
363static 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
563c05e2 376 if (type < 0 || type >= CRYPTO_NUM_LOCKS)
3ac82faa
BM
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
761772d7
BM
426#ifdef TLSEXT_TYPE_opaque_prf_input
427struct cb_info_st { void *input; size_t len; int ret; };
428struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */
429struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */
430struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */
431struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */
432
433int 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
6e119bb0 445
6b691a5c 446int main(int argc, char *argv[])
d02b48c6
RE
447 {
448 char *CApath=NULL,*CAfile=NULL;
449 int badop=0;
95d29597
BM
450 int bio_pair=0;
451 int force=0;
58964a49 452 int tls1=0,ssl2=0,ssl3=0,ret=1;
d02b48c6 453 int client_auth=0;
58964a49 454 int server_auth=0,i;
a7201e9a 455 struct app_verify_arg app_verify_arg =
d9bfe4f9 456 { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
d02b48c6 457 char *server_cert=TEST_SERVER_CERT;
65b002f3 458 char *server_key=NULL;
d02b48c6 459 char *client_cert=TEST_CLIENT_CERT;
65b002f3 460 char *client_key=NULL;
3eeaab4b 461#ifndef OPENSSL_NO_ECDH
ea262260 462 char *named_curve = NULL;
3eeaab4b 463#endif
d02b48c6
RE
464 SSL_CTX *s_ctx=NULL;
465 SSL_CTX *c_ctx=NULL;
4ebb342f 466 const SSL_METHOD *meth=NULL;
58964a49
RE
467 SSL *c_ssl,*s_ssl;
468 int number=1,reuse=0;
82423549 469 long bytes=256L;
bc36ee62 470#ifndef OPENSSL_NO_DH
d02b48c6 471 DH *dh;
e4589582 472 int dhe1024 = 0, dhe1024dsa = 0;
ea262260
BM
473#endif
474#ifndef OPENSSL_NO_ECDH
475 EC_KEY *ecdh = NULL;
58964a49 476#endif
e4589582 477 int no_dhe = 0;
ea262260 478 int no_ecdhe = 0;
ddac1974 479 int no_psk = 0;
563f1503
BM
480 int print_time = 0;
481 clock_t s_time = 0, c_time = 0;
23f80f46 482 int comp = 0;
09b6c2ef 483#ifndef OPENSSL_NO_COMP
8df788c9 484 COMP_METHOD *cm = NULL;
09b6c2ef 485#endif
82423549 486 STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
6e119bb0 487 int test_cipherlist = 0;
563f1503 488
79875776
BM
489 verbose = 0;
490 debug = 0;
491 cipher = 0;
1e3a9b65 492
e9680894 493 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);
1e3a9b65 494
3ac82faa
BM
495 CRYPTO_set_locking_callback(lock_dbg_cb);
496
10654d3a
BM
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();
384eff87
BM
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);
10654d3a 507 }
79875776 508 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
d02b48c6 509
b9d82f47
UM
510 RAND_seed(rnd_seed, sizeof rnd_seed);
511
e9680894 512 bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
d02b48c6 513
d02b48c6
RE
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;
a7201e9a
RL
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 }
d02b48c6
RE
533 else if (strcmp(*argv,"-v") == 0)
534 verbose=1;
58964a49
RE
535 else if (strcmp(*argv,"-d") == 0)
536 debug=1;
537 else if (strcmp(*argv,"-reuse") == 0)
538 reuse=1;
48c843c3 539 else if (strcmp(*argv,"-dhe1024") == 0)
90f5a2b6
RL
540 {
541#ifndef OPENSSL_NO_DH
48c843c3 542 dhe1024=1;
90f5a2b6 543#else
ba5ba549 544 fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
90f5a2b6
RL
545#endif
546 }
e4589582 547 else if (strcmp(*argv,"-dhe1024dsa") == 0)
90f5a2b6
RL
548 {
549#ifndef OPENSSL_NO_DH
e4589582 550 dhe1024dsa=1;
90f5a2b6 551#else
ba5ba549 552 fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
e4589582 553#endif
90f5a2b6 554 }
77fa04a9
BM
555 else if (strcmp(*argv,"-no_dhe") == 0)
556 no_dhe=1;
ea262260
BM
557 else if (strcmp(*argv,"-no_ecdhe") == 0)
558 no_ecdhe=1;
ddac1974
NL
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 }
d02b48c6
RE
573 else if (strcmp(*argv,"-ssl2") == 0)
574 ssl2=1;
58964a49
RE
575 else if (strcmp(*argv,"-tls1") == 0)
576 tls1=1;
d02b48c6
RE
577 else if (strcmp(*argv,"-ssl3") == 0)
578 ssl3=1;
58964a49
RE
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 }
d02b48c6
RE
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 }
65b002f3
BM
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 }
d02b48c6
RE
614 else if (strcmp(*argv,"-c_cert") == 0)
615 {
616 if (--argc < 1) goto bad;
617 client_cert= *(++argv);
618 }
65b002f3
BM
619 else if (strcmp(*argv,"-c_key") == 0)
620 {
621 if (--argc < 1) goto bad;
622 client_key= *(++argv);
623 }
d02b48c6
RE
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 }
95d29597
BM
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 }
563f1503
BM
647 else if (strcmp(*argv,"-time") == 0)
648 {
649 print_time = 1;
650 }
23f80f46
RL
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 }
ea262260
BM
659 else if (strcmp(*argv,"-named_curve") == 0)
660 {
661 if (--argc < 1) goto bad;
90f5a2b6 662#ifndef OPENSSL_NO_ECDH
ea262260 663 named_curve = *(++argv);
90f5a2b6 664#else
5e3247d8 665 fprintf(stderr,"ignoring -named_curve, since I'm compiled without ECDH\n");
90f5a2b6 666 ++argv;
ea262260 667#endif
90f5a2b6 668 }
023ec151
BM
669 else if (strcmp(*argv,"-app_verify") == 0)
670 {
a7201e9a 671 app_verify_arg.app_verify = 1;
023ec151 672 }
d9bfe4f9
RL
673 else if (strcmp(*argv,"-proxy") == 0)
674 {
675 app_verify_arg.allow_proxy_certs = 1;
676 }
6e119bb0
NL
677 else if (strcmp(*argv,"-test_cipherlist") == 0)
678 {
679 test_cipherlist = 1;
680 }
d02b48c6
RE
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 {
692bad:
693 sv_usage();
694 goto end;
695 }
696
6e119bb0
NL
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
95d29597
BM
706 if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
707 {
563f1503
BM
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");
55f78baf 712 EXIT(1);
95d29597
BM
713 }
714
563f1503
BM
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
d02b48c6
RE
726/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
727
413c4f45 728 SSL_library_init();
d02b48c6
RE
729 SSL_load_error_strings();
730
09b6c2ef 731#ifndef OPENSSL_NO_COMP
bd68b6b1
RL
732 if (comp == COMP_ZLIB) cm = COMP_zlib();
733 if (comp == COMP_RLE) cm = COMP_rle();
734 if (cm != NULL)
23f80f46 735 {
23f80f46 736 if (cm->type != NID_undef)
f82ab534
RL
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 }
23f80f46 745 else
4751717c 746 {
bd68b6b1
RL
747 fprintf(stderr,
748 "Warning: %s compression not supported\n",
749 (comp == COMP_RLE ? "rle" :
750 (comp == COMP_ZLIB ? "zlib" :
751 "unknown")));
4751717c
RL
752 ERR_print_errors_fp(stderr);
753 }
23f80f46 754 }
82423549
RL
755 ssl_comp_methods = SSL_COMP_get_compression_methods();
756 fprintf(stderr, "Available compression methods:\n");
757 {
a08ced78 758 int j, n = sk_SSL_COMP_num(ssl_comp_methods);
82423549
RL
759 if (n == 0)
760 fprintf(stderr, " NONE\n");
761 else
a08ced78 762 for (j = 0; j < n; j++)
82423549 763 {
a08ced78 764 SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
82423549
RL
765 fprintf(stderr, " %d: %s\n", c->id, c->name);
766 }
767 }
231b98a5 768#endif
23f80f46 769
bc36ee62 770#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
d02b48c6
RE
771 if (ssl2)
772 meth=SSLv2_method();
773 else
58964a49
RE
774 if (tls1)
775 meth=TLSv1_method();
776 else
d02b48c6
RE
777 if (ssl3)
778 meth=SSLv3_method();
779 else
780 meth=SSLv23_method();
781#else
bc36ee62 782#ifdef OPENSSL_NO_SSL2
d02b48c6
RE
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
bc36ee62 803#ifndef OPENSSL_NO_DH
77fa04a9 804 if (!no_dhe)
48c843c3 805 {
e4589582 806 if (dhe1024dsa)
48c843c3 807 {
e4589582 808 /* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
77fa04a9 809 SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
e4589582 810 dh=get_dh1024dsa();
48c843c3 811 }
e4589582
BM
812 else if (dhe1024)
813 dh=get_dh1024();
77fa04a9 814 else
77fa04a9
BM
815 dh=get_dh512();
816 SSL_CTX_set_tmp_dh(s_ctx,dh);
817 DH_free(dh);
818 }
e4589582
BM
819#else
820 (void)no_dhe;
58964a49
RE
821#endif
822
ea262260
BM
823#ifndef OPENSSL_NO_ECDH
824 if (!no_ecdhe)
825 {
9dd84053
NL
826 int nid;
827
828 if (named_curve != NULL)
ea262260 829 {
9dd84053
NL
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;
ea262260 835 }
9dd84053
NL
836 }
837 else
838 nid = NID_sect163r2;
ea262260 839
9dd84053
NL
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;
ea262260 845 }
9dd84053
NL
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);
ea262260
BM
850 }
851#else
852 (void)no_ecdhe;
853#endif
854
bc36ee62 855#ifndef OPENSSL_NO_RSA
58964a49 856 SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
d02b48c6
RE
857#endif
858
761772d7
BM
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
d02b48c6
RE
866 if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
867 {
868 ERR_print_errors(bio_err);
869 }
65b002f3
BM
870 else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
871 (server_key?server_key:server_cert), SSL_FILETYPE_PEM))
d02b48c6
RE
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);
65b002f3
BM
881 SSL_CTX_use_PrivateKey_file(c_ctx,
882 (client_key?client_key:client_cert),
d02b48c6
RE
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 {
58964a49 891 /* fprintf(stderr,"SSL_load_verify_locations\n"); */
d02b48c6 892 ERR_print_errors(bio_err);
58964a49 893 /* goto end; */
d02b48c6
RE
894 }
895
896 if (client_auth)
897 {
53002dc6 898 BIO_printf(bio_err,"client authentication\n");
d02b48c6
RE
899 SSL_CTX_set_verify(s_ctx,
900 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
901 verify_callback);
a7201e9a 902 SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, &app_verify_arg);
d02b48c6
RE
903 }
904 if (server_auth)
905 {
53002dc6 906 BIO_printf(bio_err,"server authentication\n");
d02b48c6
RE
907 SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
908 verify_callback);
a7201e9a 909 SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, &app_verify_arg);
d02b48c6 910 }
b1fe6ca1
BM
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 }
d02b48c6 916
ddac1974
NL
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
58964a49
RE
942 c_ssl=SSL_new(c_ctx);
943 s_ssl=SSL_new(s_ctx);
944
bc36ee62 945#ifndef OPENSSL_NO_KRB5
f9b3bff6
RL
946 if (c_ssl && c_ssl->kssl_ctx)
947 {
54a656ef 948 char localhost[MAXHOSTNAMELEN+2];
f9b3bff6 949
54a656ef 950 if (gethostname(localhost, sizeof localhost-1) == 0)
f9b3bff6 951 {
54a656ef
BL
952 localhost[sizeof localhost-1]='\0';
953 if(strlen(localhost) == sizeof localhost-1)
954 {
955 BIO_printf(bio_err,"localhost name too long\n");
31be2daa 956 goto end;
54a656ef 957 }
f9b3bff6
RL
958 kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
959 localhost);
960 }
961 }
bc36ee62 962#endif /* OPENSSL_NO_KRB5 */
f9b3bff6 963
58964a49
RE
964 for (i=0; i<number; i++)
965 {
966 if (!reuse) SSL_set_session(c_ssl,NULL);
95d29597 967 if (bio_pair)
563f1503 968 ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time);
95d29597
BM
969 else
970 ret=doit(s_ssl,c_ssl,bytes);
58964a49
RE
971 }
972
973 if (!verbose)
974 {
563f1503 975 print_details(c_ssl, "");
58964a49
RE
976 }
977 if ((number > 1) || (bytes > 1L))
53002dc6 978 BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes);
563f1503
BM
979 if (print_time)
980 {
617d71bc
BM
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 */
563f1503
BM
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);
617d71bc
BM
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
563f1503 999 }
58964a49
RE
1000
1001 SSL_free(s_ssl);
1002 SSL_free(c_ssl);
1003
d02b48c6
RE
1004end:
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
bc36ee62 1010#ifndef OPENSSL_NO_RSA
46b3bd54
BM
1011 free_tmp_rsa();
1012#endif
0b13e9f0 1013#ifndef OPENSSL_NO_ENGINE
b8e2f83a 1014 ENGINE_cleanup();
0b13e9f0 1015#endif
79aa04ef 1016 CRYPTO_cleanup_all_ex_data();
dfeab068 1017 ERR_free_strings();
4c329696 1018 ERR_remove_thread_state(NULL);
d02b48c6
RE
1019 EVP_cleanup();
1020 CRYPTO_mem_leaks(bio_err);
79875776 1021 if (bio_err != NULL) BIO_free(bio_err);
d02b48c6 1022 EXIT(ret);
19bd66fe 1023 return ret;
d02b48c6
RE
1024 }
1025
563f1503
BM
1026int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
1027 clock_t *s_time, clock_t *c_time)
95d29597
BM
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;
95d29597
BM
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).
7eea36bb
BM
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.]
95d29597
BM
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
f50c0497 1085 * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil
95d29597 1086 * other side's read attempt
657e60fa 1087 * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now
95d29597
BM
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;
563f1503 1104 clock_t c_clock = clock();
95d29597 1105
896e4fef
BM
1106 memset(cbuf, 0, sizeof(cbuf));
1107
95d29597
BM
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);
29159a42 1122 if (r < 0)
95d29597
BM
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 }
563f1503
BM
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);
95d29597
BM
1183 }
1184
1185 {
1186 /* SERVER */
1187
1188 MS_STATIC char sbuf[1024*8];
1189 int i, r;
563f1503 1190 clock_t s_clock = clock();
95d29597 1191
896e4fef
BM
1192 memset(sbuf, 0, sizeof(sbuf));
1193
95d29597
BM
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);
29159a42 1208 if (r < 0)
95d29597
BM
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 }
563f1503
BM
1256
1257 *s_time += (clock() - s_clock);
95d29597
BM
1258 }
1259
1260 {
1261 /* "I/O" BETWEEN CLIENT AND SERVER. */
1262
95d29597 1263 size_t r1, r2;
6f7af152
BM
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
95d29597
BM
1269 static int prev_progress = 1;
1270 int progress = 0;
1271
6f7af152 1272 /* io1 to io2 */
95d29597
BM
1273 do
1274 {
6f7af152 1275 size_t num;
b52f3818 1276 int r;
6f7af152
BM
1277
1278 r1 = BIO_ctrl_pending(io1);
1279 r2 = BIO_ctrl_get_write_guarantee(io2);
95d29597
BM
1280
1281 num = r1;
1282 if (r2 < num)
1283 num = r2;
1284 if (num)
1285 {
6f7af152
BM
1286 char *dataptr;
1287
95d29597
BM
1288 if (INT_MAX < num) /* yeah, right */
1289 num = INT_MAX;
1290
6f7af152
BM
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);
95d29597
BM
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)
6f7af152
BM
1306 printf((io1 == client_io) ?
1307 "C->S relaying: %d bytes\n" :
1308 "S->C relaying: %d bytes\n",
1309 (int)num);
95d29597
BM
1310 }
1311 }
1312 while (r1 && r2);
1313
6f7af152
BM
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 */
95d29597
BM
1325 num = r1;
1326 if (r2 < num)
1327 num = r2;
1328 if (num)
1329 {
6f7af152
BM
1330 char *dataptr;
1331
95d29597
BM
1332 if (INT_MAX < num)
1333 num = INT_MAX;
6f7af152
BM
1334
1335 if (num > 1)
cb0369d8 1336 --num; /* test restartability even more thoroughly */
95d29597 1337
234c7376 1338 r = BIO_nwrite0(io1, &dataptr);
6f7af152 1339 assert(r > 0);
cc129755 1340 if (r < (int)num)
234c7376 1341 num = r;
6f7af152 1342 r = BIO_read(io2, dataptr, (int)num);
95d29597
BM
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 }
95d29597 1349 progress = 1;
234c7376
BM
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 }
6f7af152 1357
95d29597 1358 if (debug)
6f7af152
BM
1359 printf((io2 == client_io) ?
1360 "C->S relaying: %d bytes\n" :
1361 "S->C relaying: %d bytes\n",
1362 (int)num);
95d29597 1363 }
6f7af152 1364 } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
95d29597
BM
1365
1366 if (!progress && !prev_progress)
1367 if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
95d29597
BM
1368 {
1369 fprintf(stderr, "ERROR: got stuck\n");
d7fcc7f6
BM
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");
95d29597
BM
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
95d29597 1390 if (verbose)
563f1503
BM
1391 print_details(c_ssl, "DONE via BIO pair: ");
1392end:
95d29597
BM
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
d02b48c6
RE
1415#define W_READ 1
1416#define W_WRITE 2
1417#define C_DONE 1
1418#define S_DONE 2
1419
6b691a5c 1420int doit(SSL *s_ssl, SSL *c_ssl, long count)
d02b48c6 1421 {
58964a49
RE
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;
d02b48c6 1425 int ret=1;
d02b48c6
RE
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;
58964a49 1432 int i,j;
d02b48c6
RE
1433 int done=0;
1434 int c_write,s_write;
1435 int do_server=0,do_client=0;
d02b48c6 1436
896e4fef
BM
1437 memset(cbuf,0,sizeof(cbuf));
1438 memset(sbuf,0,sizeof(sbuf));
1439
d02b48c6
RE
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);
58964a49 1458 BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);
d02b48c6
RE
1459
1460 SSL_set_accept_state(s_ssl);
1461 SSL_set_bio(s_ssl,c_to_s,s_to_c);
58964a49 1462 BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);
d02b48c6
RE
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
58964a49 1482 if (do_server && debug)
d02b48c6
RE
1483 {
1484 if (SSL_in_init(s_ssl))
1485 printf("server waiting in SSL_accept - %s\n",
1486 SSL_state_string_long(s_ssl));
58964a49 1487/* else if (s_write)
d02b48c6 1488 printf("server:SSL_write()\n");
58964a49
RE
1489 else
1490 printf("server:SSL_read()\n"); */
d02b48c6
RE
1491 }
1492
58964a49 1493 if (do_client && debug)
d02b48c6
RE
1494 {
1495 if (SSL_in_init(c_ssl))
1496 printf("client waiting in SSL_connect - %s\n",
1497 SSL_state_string_long(c_ssl));
58964a49 1498/* else if (c_write)
d02b48c6
RE
1499 printf("client:SSL_write()\n");
1500 else
58964a49 1501 printf("client:SSL_read()\n"); */
d02b48c6
RE
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 {
27545970
GT
1514 j = (cw_num > (long)sizeof(cbuf)) ?
1515 (int)sizeof(cbuf) : (int)cw_num;
58964a49 1516 i=BIO_write(c_bio,cbuf,j);
d02b48c6
RE
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 {
58964a49
RE
1542 if (debug)
1543 printf("client wrote %d\n",i);
d02b48c6 1544 /* ok */
58964a49 1545 s_r=1;
d02b48c6 1546 c_write=0;
58964a49 1547 cw_num-=i;
d02b48c6
RE
1548 }
1549 }
1550 else
1551 {
58964a49 1552 i=BIO_read(c_bio,cbuf,sizeof(cbuf));
d02b48c6
RE
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 {
58964a49
RE
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 }
d02b48c6
RE
1592 }
1593 }
1594 }
1595
1596 if (do_server && !(done & S_DONE))
1597 {
1598 if (!s_write)
1599 {
58964a49 1600 i=BIO_read(s_bio,sbuf,sizeof(cbuf));
d02b48c6
RE
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 {
58964a49
RE
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 }
d02b48c6
RE
1641 }
1642 }
1643 else
1644 {
27545970
GT
1645 j = (sw_num > (long)sizeof(sbuf)) ?
1646 (int)sizeof(sbuf) : (int)sw_num;
58964a49 1647 i=BIO_write(s_bio,sbuf,j);
d02b48c6
RE
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 {
58964a49
RE
1674 if (debug)
1675 printf("server wrote %d\n",i);
1676 sw_num-=i;
d02b48c6 1677 s_write=0;
58964a49
RE
1678 c_r=1;
1679 if (sw_num <= 0)
1680 done|=S_DONE;
d02b48c6
RE
1681 }
1682 }
1683 }
1684
1685 if ((done & S_DONE) && (done & C_DONE)) break;
1686 }
1687
58964a49 1688 if (verbose)
563f1503 1689 print_details(c_ssl, "DONE: ");
d02b48c6
RE
1690 ret=0;
1691err:
1692 /* We have to set the BIO's to NULL otherwise they will be
26a3a48d 1693 * OPENSSL_free()ed twice. Once when th s_ssl is SSL_free()ed and
d02b48c6
RE
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);
58964a49
RE
1712 if (c_bio != NULL) BIO_free_all(c_bio);
1713 if (s_bio != NULL) BIO_free_all(s_bio);
d02b48c6
RE
1714 return(ret);
1715 }
1716
a7201e9a
RL
1717static 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
396f6314 1733static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
d02b48c6
RE
1734 {
1735 char *s,buf[256];
1736
54a656ef
BL
1737 s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),buf,
1738 sizeof buf);
d02b48c6
RE
1739 if (s != NULL)
1740 {
1741 if (ok)
a7201e9a
RL
1742 fprintf(stderr,"depth=%d %s\n",
1743 ctx->error_depth,buf);
d02b48c6 1744 else
d9bfe4f9 1745 {
d02b48c6
RE
1746 fprintf(stderr,"depth=%d error=%d %s\n",
1747 ctx->error_depth,ctx->error,buf);
d9bfe4f9 1748 }
d02b48c6
RE
1749 }
1750
1751 if (ok == 0)
1752 {
d9bfe4f9
RL
1753 fprintf(stderr,"Error string: %s\n",
1754 X509_verify_cert_error_string(ctx->error));
d02b48c6
RE
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:
d9bfe4f9 1760 fprintf(stderr," ... ignored.\n");
d02b48c6
RE
1761 ok=1;
1762 }
1763 }
1764
a7201e9a
RL
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 {
a51a9726 1833 int c = *s++;
a7201e9a
RL
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
d02b48c6
RE
1866 return(ok);
1867 }
1868
a7201e9a
RL
1869static 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*/
1889static int process_proxy_cond_adders(unsigned int letters[26],
1890 const char *cond, const char **cond_end, int *pos, int indent);
1891static int process_proxy_cond_val(unsigned int letters[26],
1892 const char *cond, const char **cond_end, int *pos, int indent)
1893 {
a51a9726 1894 int c;
a7201e9a
RL
1895 int ok = 1;
1896 int negate = 0;
1897
a51a9726 1898 while(isspace((int)*cond))
a7201e9a
RL
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)++;
a51a9726 1913 while(isspace((int)*cond))
a7201e9a
RL
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;
a51a9726 1928 while(isspace((int)*cond))
a7201e9a
RL
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 }
1970static 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 {
a51a9726 1988 while(isspace((int)*cond))
a7201e9a
RL
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 }
2036static 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 {
a51a9726 2055 while(isspace((int)*cond))
a7201e9a
RL
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
2100static 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
023ec151
BM
2107static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
2108 {
023ec151 2109 int ok=1;
a7201e9a
RL
2110 struct app_verify_arg *cb_arg = arg;
2111 unsigned int letters[26]; /* only used with proxy_auth */
023ec151 2112
a7201e9a 2113 if (cb_arg->app_verify)
023ec151 2114 {
a7201e9a
RL
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);
35e8510e 2119 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
f795123c 2120 (void *)ctx, (void *)ctx->cert);
a7201e9a
RL
2121 if (ctx->cert)
2122 s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
2123 if (s != NULL)
2124 {
023ec151 2125 fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
a7201e9a
RL
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 {
a51a9726 2138 int c = *sp;
a7201e9a
RL
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);
023ec151 2161 }
d9bfe4f9
RL
2162 if (cb_arg->allow_proxy_certs)
2163 {
2164 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
2165 }
023ec151 2166
a7201e9a
RL
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 {
bab53405 2181 if (ok > 0)
a7201e9a
RL
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 }
023ec151
BM
2203 return(ok);
2204 }
2205
bc36ee62 2206#ifndef OPENSSL_NO_RSA
46b3bd54
BM
2207static RSA *rsa_tmp=NULL;
2208
df63a389 2209static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
58964a49 2210 {
bcfea9fb 2211 BIGNUM *bn = NULL;
58964a49
RE
2212 if (rsa_tmp == NULL)
2213 {
bcfea9fb 2214 bn = BN_new();
e9224c71 2215 rsa_tmp = RSA_new();
bcfea9fb 2216 if(!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4))
e9224c71
GT
2217 {
2218 BIO_printf(bio_err, "Memory error...");
2219 goto end;
2220 }
60e31c3a 2221 BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
d58d092b 2222 (void)BIO_flush(bio_err);
bcfea9fb 2223 if(!RSA_generate_key_ex(rsa_tmp,keylength,bn,NULL))
e9224c71 2224 {
3ae70939 2225 BIO_printf(bio_err, "Error generating key.");
e9224c71
GT
2226 RSA_free(rsa_tmp);
2227 rsa_tmp = NULL;
2228 }
2229end:
58964a49 2230 BIO_printf(bio_err,"\n");
d58d092b 2231 (void)BIO_flush(bio_err);
58964a49 2232 }
bcfea9fb 2233 if(bn) BN_free(bn);
58964a49
RE
2234 return(rsa_tmp);
2235 }
46b3bd54
BM
2236
2237static void free_tmp_rsa(void)
2238 {
2239 if (rsa_tmp != NULL)
2240 {
2241 RSA_free(rsa_tmp);
2242 rsa_tmp = NULL;
2243 }
2244 }
79df9d62 2245#endif
53002dc6 2246
bc36ee62 2247#ifndef OPENSSL_NO_DH
e4589582
BM
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 */
f3f316f1 2254static DH *get_dh512()
e4589582
BM
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
f3f316f1 2277static DH *get_dh1024()
53002dc6 2278 {
e4589582
BM
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 }
53002dc6 2304
f3f316f1 2305static DH *get_dh1024dsa()
e4589582
BM
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;
53002dc6 2334
e4589582
BM
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);
53002dc6 2342 }
f71165b5 2343#endif
6e119bb0 2344
ddac1974
NL
2345#ifndef OPENSSL_NO_PSK
2346/* convert the PSK key (psk_key) in ascii to binary (psk) */
2347static 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
2373static 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
e9680894 2380 ret = BIO_snprintf(identity, max_identity_len, "Client_identity");
ddac1974
NL
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;
2389out_err:
2390 return psk_len;
2391 }
2392
2393static 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
6e119bb0
NL
2408static int do_test_cipherlist(void)
2409 {
2410 int i = 0;
2411 const SSL_METHOD *meth;
babb3798 2412 const SSL_CIPHER *ci, *tci = NULL;
6e119bb0 2413
00fe865d 2414#ifndef OPENSSL_NO_SSL2
6e119bb0
NL
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");
00fe865d
NL
2428#endif
2429#ifndef OPENSSL_NO_SSL3
6e119bb0
NL
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");
00fe865d
NL
2444#endif
2445#ifndef OPENSSL_NO_TLS1
6e119bb0
NL
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");
00fe865d 2460#endif
6e119bb0
NL
2461
2462 return 1;
2463 }