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