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