ssltest.c revision 1.29
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/socket.h>
147
148#include <netinet/in.h>
149
150#include <assert.h>
151#include <errno.h>
152#include <limits.h>
153#include <netdb.h>
154#include <stdio.h>
155#include <stdlib.h>
156#include <string.h>
157#include <time.h>
158#include <unistd.h>
159
160#include <ctype.h>
161
162#include <openssl/opensslconf.h>
163#include <openssl/bio.h>
164#include <openssl/crypto.h>
165#include <openssl/evp.h>
166#include <openssl/x509.h>
167#include <openssl/x509v3.h>
168#include <openssl/ssl.h>
169#ifndef OPENSSL_NO_ENGINE
170#include <openssl/engine.h>
171#endif
172#include <openssl/err.h>
173#include <openssl/rand.h>
174#include <openssl/rsa.h>
175#include <openssl/dsa.h>
176#include <openssl/dh.h>
177#include <openssl/bn.h>
178
179#define TEST_SERVER_CERT "../apps/server.pem"
180#define TEST_CLIENT_CERT "../apps/client.pem"
181
182static int verify_callback(int ok, X509_STORE_CTX *ctx);
183static int app_verify_callback(X509_STORE_CTX *ctx, void *arg);
184#define APP_CALLBACK_STRING "Test Callback Argument"
185struct app_verify_arg {
186	char *string;
187	int app_verify;
188	int allow_proxy_certs;
189	char *proxy_auth;
190	char *proxy_cond;
191};
192
193static DH *get_dh1024(void);
194static DH *get_dh1024dsa(void);
195
196static BIO *bio_err = NULL;
197static BIO *bio_stdout = NULL;
198
199static const char *alpn_client;
200static const char *alpn_server;
201static const char *alpn_expected;
202static unsigned char *alpn_selected;
203
204/*
205 * next_protos_parse parses a comma separated list of strings into a string
206 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
207 *   outlen: (output) set to the length of the resulting buffer on success.
208 *   err: (maybe NULL) on failure, an error message line is written to this BIO.
209 *   in: a NUL terminated string like "abc,def,ghi"
210 *
211 *   returns: a malloced buffer or NULL on failure.
212 */
213static unsigned char *
214next_protos_parse(unsigned short *outlen, const char *in)
215{
216	size_t i, len, start = 0;
217	unsigned char *out;
218
219	len = strlen(in);
220	if (len >= 65535)
221		return (NULL);
222
223	if ((out = malloc(strlen(in) + 1)) == NULL)
224		return (NULL);
225
226	for (i = 0; i <= len; ++i) {
227		if (i == len || in[i] == ',') {
228			if (i - start > 255) {
229				free(out);
230				return (NULL);
231			}
232			out[start] = i - start;
233			start = i + 1;
234		} else
235			out[i+1] = in[i];
236	}
237	*outlen = len + 1;
238	return (out);
239}
240
241static int
242cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen,
243    const unsigned char *in, unsigned int inlen, void *arg)
244{
245	unsigned char *protos;
246	unsigned short protos_len;
247
248	if ((protos = next_protos_parse(&protos_len, alpn_server)) == NULL) {
249		fprintf(stderr,
250		    "failed to parser ALPN server protocol string: %s\n",
251		    alpn_server);
252		abort();
253	}
254
255	if (SSL_select_next_proto((unsigned char **)out, outlen, protos,
256	    protos_len, in, inlen) != OPENSSL_NPN_NEGOTIATED) {
257		free(protos);
258		return (SSL_TLSEXT_ERR_NOACK);
259	}
260
261	/*
262	 * Make a copy of the selected protocol which will be freed in
263	 * verify_alpn.
264	 */
265	if ((alpn_selected = malloc(*outlen)) == NULL) {
266		fprintf(stderr, "malloc failed\n");
267		abort();
268	}
269	memcpy(alpn_selected, *out, *outlen);
270	*out = alpn_selected;
271	free(protos);
272
273	return (SSL_TLSEXT_ERR_OK);
274}
275
276static int
277verify_alpn(SSL *client, SSL *server)
278{
279	const unsigned char *client_proto, *server_proto;
280	unsigned int client_proto_len = 0, server_proto_len = 0;
281
282	SSL_get0_alpn_selected(client, &client_proto, &client_proto_len);
283	SSL_get0_alpn_selected(server, &server_proto, &server_proto_len);
284
285	free(alpn_selected);
286	alpn_selected = NULL;
287
288	if (client_proto_len != server_proto_len ||
289	    memcmp(client_proto, server_proto, client_proto_len) != 0) {
290		BIO_printf(bio_stdout, "ALPN selected protocols differ!\n");
291		goto err;
292	}
293
294	if (client_proto_len > 0 && alpn_expected == NULL) {
295		BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n");
296		goto err;
297	}
298
299	if (alpn_expected != NULL &&
300	    (client_proto_len != strlen(alpn_expected) ||
301	     memcmp(client_proto, alpn_expected, client_proto_len) != 0)) {
302		BIO_printf(bio_stdout, "ALPN selected protocols not equal to "
303		    "expected protocol: %s\n", alpn_expected);
304		goto err;
305	}
306
307	return (0);
308
309err:
310	BIO_printf(bio_stdout, "ALPN results: client: '");
311	BIO_write(bio_stdout, client_proto, client_proto_len);
312	BIO_printf(bio_stdout, "', server: '");
313	BIO_write(bio_stdout, server_proto, server_proto_len);
314	BIO_printf(bio_stdout, "'\n");
315	BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n",
316	    alpn_client, alpn_server);
317
318	return (-1);
319}
320
321static char *cipher = NULL;
322static int verbose = 0;
323static int debug = 0;
324
325int doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time,
326    clock_t *c_time);
327int doit(SSL *s_ssl, SSL *c_ssl, long bytes);
328
329static void
330sv_usage(void)
331{
332	fprintf(stderr, "usage: ssltest [args ...]\n");
333	fprintf(stderr, "\n");
334	fprintf(stderr, " -server_auth  - check server certificate\n");
335	fprintf(stderr, " -client_auth  - do client authentication\n");
336	fprintf(stderr, " -proxy        - allow proxy certificates\n");
337	fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n");
338	fprintf(stderr, " -proxy_cond <val> - experssion to test proxy policy rights\n");
339	fprintf(stderr, " -v            - more output\n");
340	fprintf(stderr, " -d            - debug output\n");
341	fprintf(stderr, " -reuse        - use session-id reuse\n");
342	fprintf(stderr, " -num <val>    - number of connections to perform\n");
343	fprintf(stderr, " -bytes <val>  - number of bytes to swap between client/server\n");
344	fprintf(stderr, " -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
345	fprintf(stderr, " -no_dhe       - disable DHE\n");
346	fprintf(stderr, " -no_ecdhe     - disable ECDHE\n");
347	fprintf(stderr, " -dtls1        - use DTLSv1\n");
348	fprintf(stderr, " -tls1         - use TLSv1\n");
349	fprintf(stderr, " -tls1_2       - use TLSv1.2\n");
350	fprintf(stderr, " -CApath arg   - PEM format directory of CA's\n");
351	fprintf(stderr, " -CAfile arg   - PEM format file of CA's\n");
352	fprintf(stderr, " -cert arg     - Server certificate file\n");
353	fprintf(stderr, " -key arg      - Server key file (default: same as -cert)\n");
354	fprintf(stderr, " -c_cert arg   - Client certificate file\n");
355	fprintf(stderr, " -c_key arg    - Client key file (default: same as -c_cert)\n");
356	fprintf(stderr, " -cipher arg   - The cipher list\n");
357	fprintf(stderr, " -bio_pair     - Use BIO pairs\n");
358	fprintf(stderr, " -f            - Test even cases that can't work\n");
359	fprintf(stderr, " -time         - measure processor time used by client and server\n");
360	fprintf(stderr, " -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
361	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
362	               "                 (default is sect163r2).\n");
363	fprintf(stderr, " -alpn_client <string> - have client side offer ALPN\n");
364	fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n");
365	fprintf(stderr, " -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
366}
367
368static void
369print_details(SSL *c_ssl, const char *prefix)
370{
371	const SSL_CIPHER *ciph;
372	X509 *cert;
373
374	ciph = SSL_get_current_cipher(c_ssl);
375	BIO_printf(bio_stdout, "%s%s, cipher %s %s",
376	    prefix, SSL_get_version(c_ssl), SSL_CIPHER_get_version(ciph),
377	    SSL_CIPHER_get_name(ciph));
378	cert = SSL_get_peer_certificate(c_ssl);
379	if (cert != NULL) {
380		EVP_PKEY *pkey = X509_get_pubkey(cert);
381		if (pkey != NULL) {
382			if (pkey->type == EVP_PKEY_RSA &&
383			    pkey->pkey.rsa != NULL &&
384			    pkey->pkey.rsa->n != NULL) {
385				BIO_printf(bio_stdout, ", %d bit RSA",
386				    BN_num_bits(pkey->pkey.rsa->n));
387			} else if (pkey->type == EVP_PKEY_DSA &&
388			    pkey->pkey.dsa != NULL &&
389			    pkey->pkey.dsa->p != NULL) {
390				BIO_printf(bio_stdout, ", %d bit DSA",
391				    BN_num_bits(pkey->pkey.dsa->p));
392			}
393			EVP_PKEY_free(pkey);
394		}
395		X509_free(cert);
396	}
397	/* The SSL API does not allow us to look at temporary RSA/DH keys,
398	 * otherwise we should print their lengths too */
399	BIO_printf(bio_stdout, "\n");
400}
401
402int
403main(int argc, char *argv[])
404{
405	char *CApath = NULL, *CAfile = NULL;
406	int badop = 0;
407	int bio_pair = 0;
408	int force = 0;
409	int tls1 = 0, tls1_2 = 0, dtls1 = 0, ret = 1;
410	int client_auth = 0;
411	int server_auth = 0, i;
412	struct app_verify_arg app_verify_arg =
413	    { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
414	char *server_cert = TEST_SERVER_CERT;
415	char *server_key = NULL;
416	char *client_cert = TEST_CLIENT_CERT;
417	char *client_key = NULL;
418	char *named_curve = NULL;
419	SSL_CTX *s_ctx = NULL;
420	SSL_CTX *c_ctx = NULL;
421	const SSL_METHOD *meth = NULL;
422	SSL *c_ssl, *s_ssl;
423	int number = 1, reuse = 0;
424	long bytes = 256L;
425	DH *dh;
426	int dhe1024dsa = 0;
427	EC_KEY *ecdh = NULL;
428	int no_dhe = 0;
429	int no_ecdhe = 0;
430	int print_time = 0;
431	clock_t s_time = 0, c_time = 0;
432
433	verbose = 0;
434	debug = 0;
435	cipher = 0;
436
437	bio_err = BIO_new_fp(stderr, BIO_NOCLOSE|BIO_FP_TEXT);
438
439	bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE|BIO_FP_TEXT);
440
441	argc--;
442	argv++;
443
444	while (argc >= 1) {
445		if (!strcmp(*argv, "-F")) {
446			fprintf(stderr, "not compiled with FIPS support, so exiting without running.\n");
447			exit(0);
448		} else if (strcmp(*argv, "-server_auth") == 0)
449			server_auth = 1;
450		else if (strcmp(*argv, "-client_auth") == 0)
451			client_auth = 1;
452		else if (strcmp(*argv, "-proxy_auth") == 0) {
453			if (--argc < 1)
454				goto bad;
455			app_verify_arg.proxy_auth= *(++argv);
456		} else if (strcmp(*argv, "-proxy_cond") == 0) {
457			if (--argc < 1)
458				goto bad;
459			app_verify_arg.proxy_cond= *(++argv);
460		} else if (strcmp(*argv, "-v") == 0)
461			verbose = 1;
462		else if (strcmp(*argv, "-d") == 0)
463			debug = 1;
464		else if (strcmp(*argv, "-reuse") == 0)
465			reuse = 1;
466		else if (strcmp(*argv, "-dhe1024dsa") == 0) {
467			dhe1024dsa = 1;
468		} else if (strcmp(*argv, "-no_dhe") == 0)
469			no_dhe = 1;
470		else if (strcmp(*argv, "-no_ecdhe") == 0)
471			no_ecdhe = 1;
472		else if (strcmp(*argv, "-dtls1") == 0)
473			dtls1 = 1;
474		else if (strcmp(*argv, "-tls1") == 0)
475			tls1 = 1;
476		else if (strcmp(*argv, "-tls1_2") == 0)
477			tls1_2 = 1;
478		else if (strncmp(*argv, "-num", 4) == 0) {
479			if (--argc < 1)
480				goto bad;
481			number = atoi(*(++argv));
482			if (number == 0)
483				number = 1;
484		} else if (strcmp(*argv, "-bytes") == 0) {
485			if (--argc < 1)
486				goto bad;
487			bytes = atol(*(++argv));
488			if (bytes == 0L)
489				bytes = 1L;
490			i = strlen(argv[0]);
491			if (argv[0][i - 1] == 'k')
492				bytes*=1024L;
493			if (argv[0][i - 1] == 'm')
494				bytes*=1024L*1024L;
495		} else if (strcmp(*argv, "-cert") == 0) {
496			if (--argc < 1)
497				goto bad;
498			server_cert= *(++argv);
499		} else if (strcmp(*argv, "-s_cert") == 0) {
500			if (--argc < 1)
501				goto bad;
502			server_cert= *(++argv);
503		} else if (strcmp(*argv, "-key") == 0) {
504			if (--argc < 1)
505				goto bad;
506			server_key= *(++argv);
507		} else if (strcmp(*argv, "-s_key") == 0) {
508			if (--argc < 1)
509				goto bad;
510			server_key= *(++argv);
511		} else if (strcmp(*argv, "-c_cert") == 0) {
512			if (--argc < 1)
513				goto bad;
514			client_cert= *(++argv);
515		} else if (strcmp(*argv, "-c_key") == 0) {
516			if (--argc < 1)
517				goto bad;
518			client_key= *(++argv);
519		} else if (strcmp(*argv, "-cipher") == 0) {
520			if (--argc < 1)
521				goto bad;
522			cipher= *(++argv);
523		} else if (strcmp(*argv, "-CApath") == 0) {
524			if (--argc < 1)
525				goto bad;
526			CApath= *(++argv);
527		} else if (strcmp(*argv, "-CAfile") == 0) {
528			if (--argc < 1)
529				goto bad;
530			CAfile= *(++argv);
531		} else if (strcmp(*argv, "-bio_pair") == 0) {
532			bio_pair = 1;
533		} else if (strcmp(*argv, "-f") == 0) {
534			force = 1;
535		} else if (strcmp(*argv, "-time") == 0) {
536			print_time = 1;
537		} else if (strcmp(*argv, "-named_curve") == 0) {
538			if (--argc < 1)
539				goto bad;
540			named_curve = *(++argv);
541		} else if (strcmp(*argv, "-app_verify") == 0) {
542			app_verify_arg.app_verify = 1;
543		} else if (strcmp(*argv, "-proxy") == 0) {
544			app_verify_arg.allow_proxy_certs = 1;
545		} else if (strcmp(*argv, "-alpn_client") == 0) {
546			if (--argc < 1)
547				goto bad;
548			alpn_client = *(++argv);
549		} else if (strcmp(*argv, "-alpn_server") == 0) {
550			if (--argc < 1)
551				goto bad;
552			alpn_server = *(++argv);
553		} else if (strcmp(*argv, "-alpn_expected") == 0) {
554			if (--argc < 1)
555				goto bad;
556			alpn_expected = *(++argv);
557		} else {
558			fprintf(stderr, "unknown option %s\n", *argv);
559			badop = 1;
560			break;
561		}
562		argc--;
563		argv++;
564	}
565	if (badop) {
566bad:
567		sv_usage();
568		goto end;
569	}
570
571	if (!dtls1 && !tls1 && !tls1_2 && number > 1 && !reuse && !force) {
572		fprintf(stderr,
573		    "This case cannot work.  Use -f to perform "
574		    "the test anyway (and\n-d to see what happens), "
575		    "or add one of -dtls1, -tls1, -tls1_2, -reuse\n"
576		    "to avoid protocol mismatch.\n");
577		exit(1);
578	}
579
580	if (print_time) {
581		if (!bio_pair) {
582			fprintf(stderr, "Using BIO pair (-bio_pair)\n");
583			bio_pair = 1;
584		}
585		if (number < 50 && !force)
586			fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
587	}
588
589/*	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
590
591	SSL_library_init();
592	SSL_load_error_strings();
593
594	if (dtls1)
595		meth = DTLSv1_method();
596	else if (tls1)
597		meth = TLSv1_method();
598	else if (tls1_2)
599		meth = TLSv1_2_method();
600	else
601		meth = TLS_method();
602
603	c_ctx = SSL_CTX_new(meth);
604	s_ctx = SSL_CTX_new(meth);
605	if ((c_ctx == NULL) || (s_ctx == NULL)) {
606		ERR_print_errors(bio_err);
607		goto end;
608	}
609
610	if (cipher != NULL) {
611		SSL_CTX_set_cipher_list(c_ctx, cipher);
612		SSL_CTX_set_cipher_list(s_ctx, cipher);
613	}
614
615	if (!no_dhe) {
616		if (dhe1024dsa) {
617			/* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
618			SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
619			dh = get_dh1024dsa();
620		} else
621			dh = get_dh1024();
622		SSL_CTX_set_tmp_dh(s_ctx, dh);
623		DH_free(dh);
624	}
625
626	if (!no_ecdhe) {
627		int nid;
628
629		if (named_curve != NULL) {
630			nid = OBJ_sn2nid(named_curve);
631			if (nid == 0) {
632				BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
633				goto end;
634			}
635		} else
636			nid = NID_X9_62_prime256v1;
637
638		ecdh = EC_KEY_new_by_curve_name(nid);
639		if (ecdh == NULL) {
640			BIO_printf(bio_err, "unable to create curve\n");
641			goto end;
642		}
643
644		SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
645		SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
646		EC_KEY_free(ecdh);
647	}
648
649	if (!SSL_CTX_use_certificate_file(s_ctx, server_cert,
650	    SSL_FILETYPE_PEM)) {
651		ERR_print_errors(bio_err);
652	} else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
653	    (server_key ? server_key : server_cert), SSL_FILETYPE_PEM)) {
654		ERR_print_errors(bio_err);
655		goto end;
656	}
657
658	if (client_auth) {
659		SSL_CTX_use_certificate_file(c_ctx, client_cert,
660		    SSL_FILETYPE_PEM);
661		SSL_CTX_use_PrivateKey_file(c_ctx,
662		    (client_key ? client_key : client_cert),
663		    SSL_FILETYPE_PEM);
664	}
665
666	if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) ||
667	    (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
668	    (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) ||
669	    (!SSL_CTX_set_default_verify_paths(c_ctx))) {
670		/* fprintf(stderr,"SSL_load_verify_locations\n"); */
671		ERR_print_errors(bio_err);
672		/* goto end; */
673	}
674
675	if (client_auth) {
676		BIO_printf(bio_err, "client authentication\n");
677		SSL_CTX_set_verify(s_ctx,
678		    SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
679		    verify_callback);
680		SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback,
681		    &app_verify_arg);
682	}
683	if (server_auth) {
684		BIO_printf(bio_err, "server authentication\n");
685		SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER,
686		    verify_callback);
687		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback,
688		    &app_verify_arg);
689	}
690
691	{
692		int session_id_context = 0;
693		SSL_CTX_set_session_id_context(s_ctx,
694		    (void *)&session_id_context, sizeof(session_id_context));
695	}
696
697	if (alpn_server != NULL)
698		SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL);
699
700	if (alpn_client != NULL) {
701		unsigned short alpn_len;
702		unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client);
703
704		if (alpn == NULL) {
705			BIO_printf(bio_err, "Error parsing -alpn_client argument\n");
706			goto end;
707		}
708		SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len);
709		free(alpn);
710	}
711
712	c_ssl = SSL_new(c_ctx);
713	s_ssl = SSL_new(s_ctx);
714
715	for (i = 0; i < number; i++) {
716		if (!reuse)
717			SSL_set_session(c_ssl, NULL);
718		if (bio_pair)
719			ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time,
720			    &c_time);
721		else
722			ret = doit(s_ssl, c_ssl, bytes);
723	}
724
725	if (!verbose) {
726		print_details(c_ssl, "");
727	}
728	if ((number > 1) || (bytes > 1L))
729		BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",
730		    number, bytes);
731	if (print_time) {
732#ifdef CLOCKS_PER_SEC
733		/* "To determine the time in seconds, the value returned
734		 * by the clock function should be divided by the value
735		 * of the macro CLOCKS_PER_SEC."
736		 *                                       -- ISO/IEC 9899 */
737		BIO_printf(bio_stdout,
738		    "Approximate total server time: %6.2f s\n"
739		    "Approximate total client time: %6.2f s\n",
740		    (double)s_time/CLOCKS_PER_SEC,
741		    (double)c_time/CLOCKS_PER_SEC);
742#else
743		/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
744		 *                            -- cc on NeXTstep/OpenStep */
745		BIO_printf(bio_stdout,
746		    "Approximate total server time: %6.2f units\n"
747		    "Approximate total client time: %6.2f units\n",
748		    (double)s_time,
749		    (double)c_time);
750#endif
751	}
752
753	SSL_free(s_ssl);
754	SSL_free(c_ssl);
755
756end:
757	SSL_CTX_free(s_ctx);
758	SSL_CTX_free(c_ctx);
759	BIO_free(bio_stdout);
760
761#ifndef OPENSSL_NO_ENGINE
762	ENGINE_cleanup();
763#endif
764	CRYPTO_cleanup_all_ex_data();
765	ERR_free_strings();
766	ERR_remove_thread_state(NULL);
767	EVP_cleanup();
768	CRYPTO_mem_leaks(bio_err);
769	BIO_free(bio_err);
770
771	exit(ret);
772	return ret;
773}
774
775int
776doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time,
777    clock_t *c_time)
778{
779	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
780	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
781	BIO *server = NULL, *server_io = NULL;
782	BIO *client = NULL, *client_io = NULL;
783	int ret = 1;
784
785	size_t bufsiz = 256; /* small buffer for testing */
786
787	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
788		goto err;
789	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
790		goto err;
791
792	s_ssl_bio = BIO_new(BIO_f_ssl());
793	if (!s_ssl_bio)
794		goto err;
795
796	c_ssl_bio = BIO_new(BIO_f_ssl());
797	if (!c_ssl_bio)
798		goto err;
799
800	SSL_set_connect_state(c_ssl);
801	SSL_set_bio(c_ssl, client, client);
802	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
803
804	SSL_set_accept_state(s_ssl);
805	SSL_set_bio(s_ssl, server, server);
806	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
807
808	do {
809		/* c_ssl_bio:          SSL filter BIO
810		 *
811		 * client:             pseudo-I/O for SSL library
812		 *
813		 * client_io:          client's SSL communication; usually to be
814		 *                     relayed over some I/O facility, but in this
815		 *                     test program, we're the server, too:
816		 *
817		 * server_io:          server's SSL communication
818		 *
819		 * server:             pseudo-I/O for SSL library
820		 *
821		 * s_ssl_bio:          SSL filter BIO
822		 *
823		 * The client and the server each employ a "BIO pair":
824		 * client + client_io, server + server_io.
825		 * BIO pairs are symmetric.  A BIO pair behaves similar
826		 * to a non-blocking socketpair (but both endpoints must
827		 * be handled by the same thread).
828		 * [Here we could connect client and server to the ends
829		 * of a single BIO pair, but then this code would be less
830		 * suitable as an example for BIO pairs in general.]
831		 *
832		 * Useful functions for querying the state of BIO pair endpoints:
833		 *
834		 * BIO_ctrl_pending(bio)              number of bytes we can read now
835		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
836		 *                                      other side's read attempt
837		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
838		 *
839		 * ..._read_request is never more than ..._write_guarantee;
840		 * it depends on the application which one you should use.
841		 */
842
843		/* We have non-blocking behaviour throughout this test program, but
844		 * can be sure that there is *some* progress in each iteration; so
845		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
846		 * -- we just try everything in each iteration
847		 */
848
849		{
850			/* CLIENT */
851
852			char cbuf[1024*8];
853			int i, r;
854			clock_t c_clock = clock();
855
856			memset(cbuf, 0, sizeof(cbuf));
857
858			if (debug)
859				if (SSL_in_init(c_ssl))
860					printf("client waiting in SSL_connect - %s\n",
861					    SSL_state_string_long(c_ssl));
862
863			if (cw_num > 0) {
864				/* Write to server. */
865
866				if (cw_num > (long)sizeof cbuf)
867					i = sizeof cbuf;
868				else
869					i = (int)cw_num;
870				r = BIO_write(c_ssl_bio, cbuf, i);
871				if (r < 0) {
872					if (!BIO_should_retry(c_ssl_bio)) {
873						fprintf(stderr, "ERROR in CLIENT\n");
874						goto err;
875					}
876					/* BIO_should_retry(...) can just be ignored here.
877					 * The library expects us to call BIO_write with
878					 * the same arguments again, and that's what we will
879					 * do in the next iteration. */
880				} else if (r == 0) {
881					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
882					goto err;
883				} else {
884					if (debug)
885						printf("client wrote %d\n", r);
886					cw_num -= r;
887
888				}
889			}
890
891			if (cr_num > 0) {
892				/* Read from server. */
893
894				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
895				if (r < 0) {
896					if (!BIO_should_retry(c_ssl_bio)) {
897						fprintf(stderr, "ERROR in CLIENT\n");
898						goto err;
899					}
900					/* Again, "BIO_should_retry" can be ignored. */
901				} else if (r == 0) {
902					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
903					goto err;
904				} else {
905					if (debug)
906						printf("client read %d\n", r);
907					cr_num -= r;
908				}
909			}
910
911			/* c_time and s_time increments will typically be very small
912			 * (depending on machine speed and clock tick intervals),
913			 * but sampling over a large number of connections should
914			 * result in fairly accurate figures.  We cannot guarantee
915			 * a lot, however -- if each connection lasts for exactly
916			 * one clock tick, it will be counted only for the client
917			 * or only for the server or even not at all.
918			 */
919			*c_time += (clock() - c_clock);
920		}
921
922		{
923			/* SERVER */
924
925			char sbuf[1024*8];
926			int i, r;
927			clock_t s_clock = clock();
928
929			memset(sbuf, 0, sizeof(sbuf));
930
931			if (debug)
932				if (SSL_in_init(s_ssl))
933					printf("server waiting in SSL_accept - %s\n",
934					    SSL_state_string_long(s_ssl));
935
936			if (sw_num > 0) {
937				/* Write to client. */
938
939				if (sw_num > (long)sizeof sbuf)
940					i = sizeof sbuf;
941				else
942					i = (int)sw_num;
943				r = BIO_write(s_ssl_bio, sbuf, i);
944				if (r < 0) {
945					if (!BIO_should_retry(s_ssl_bio)) {
946						fprintf(stderr, "ERROR in SERVER\n");
947						goto err;
948					}
949					/* Ignore "BIO_should_retry". */
950				} else if (r == 0) {
951					fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
952					goto err;
953				} else {
954					if (debug)
955						printf("server wrote %d\n", r);
956					sw_num -= r;
957
958				}
959			}
960
961			if (sr_num > 0) {
962				/* Read from client. */
963
964				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
965				if (r < 0) {
966					if (!BIO_should_retry(s_ssl_bio)) {
967						fprintf(stderr, "ERROR in SERVER\n");
968						goto err;
969					}
970					/* blah, blah */
971				} else if (r == 0) {
972					fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
973					goto err;
974				} else {
975					if (debug)
976						printf("server read %d\n", r);
977					sr_num -= r;
978				}
979			}
980
981			*s_time += (clock() - s_clock);
982		}
983
984		{
985			/* "I/O" BETWEEN CLIENT AND SERVER. */
986
987			size_t r1, r2;
988			BIO *io1 = server_io, *io2 = client_io;
989			/* we use the non-copying interface for io1
990			 * and the standard BIO_write/BIO_read interface for io2
991			 */
992
993			static int prev_progress = 1;
994			int progress = 0;
995
996			/* io1 to io2 */
997			do {
998				size_t num;
999				int r;
1000
1001				r1 = BIO_ctrl_pending(io1);
1002				r2 = BIO_ctrl_get_write_guarantee(io2);
1003
1004				num = r1;
1005				if (r2 < num)
1006					num = r2;
1007				if (num) {
1008					char *dataptr;
1009
1010					if (INT_MAX < num) /* yeah, right */
1011						num = INT_MAX;
1012
1013					r = BIO_nread(io1, &dataptr, (int)num);
1014					assert(r > 0);
1015					assert(r <= (int)num);
1016					/* possibly r < num (non-contiguous data) */
1017					num = r;
1018					r = BIO_write(io2, dataptr, (int)num);
1019					if (r != (int)num) /* can't happen */
1020					{
1021						fprintf(stderr, "ERROR: BIO_write could not write "
1022						    "BIO_ctrl_get_write_guarantee() bytes");
1023						goto err;
1024					}
1025					progress = 1;
1026
1027					if (debug)
1028						printf((io1 == client_io) ?
1029						    "C->S relaying: %d bytes\n" :
1030						    "S->C relaying: %d bytes\n",
1031						    (int)num);
1032				}
1033			} while (r1 && r2);
1034
1035			/* io2 to io1 */
1036			{
1037				size_t num;
1038				int r;
1039
1040				r1 = BIO_ctrl_pending(io2);
1041				r2 = BIO_ctrl_get_read_request(io1);
1042				/* here we could use ..._get_write_guarantee instead of
1043				 * ..._get_read_request, but by using the latter
1044				 * we test restartability of the SSL implementation
1045				 * more thoroughly */
1046				num = r1;
1047				if (r2 < num)
1048					num = r2;
1049				if (num) {
1050					char *dataptr;
1051
1052					if (INT_MAX < num)
1053						num = INT_MAX;
1054
1055					if (num > 1)
1056						--num; /* test restartability even more thoroughly */
1057
1058					r = BIO_nwrite0(io1, &dataptr);
1059					assert(r > 0);
1060					if (r < (int)num)
1061						num = r;
1062					r = BIO_read(io2, dataptr, (int)num);
1063					if (r != (int)num) /* can't happen */
1064					{
1065						fprintf(stderr, "ERROR: BIO_read could not read "
1066						    "BIO_ctrl_pending() bytes");
1067						goto err;
1068					}
1069					progress = 1;
1070					r = BIO_nwrite(io1, &dataptr, (int)num);
1071					if (r != (int)num) /* can't happen */
1072					{
1073						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
1074						    "BIO_nwrite0() bytes");
1075						goto err;
1076					}
1077
1078					if (debug)
1079						printf((io2 == client_io) ?
1080						    "C->S relaying: %d bytes\n" :
1081						    "S->C relaying: %d bytes\n",
1082						    (int)num);
1083				}
1084			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
1085
1086			if (!progress && !prev_progress) {
1087				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) {
1088					fprintf(stderr, "ERROR: got stuck\n");
1089					goto err;
1090				}
1091			}
1092			prev_progress = progress;
1093		}
1094	} while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
1095
1096	if (verbose)
1097		print_details(c_ssl, "DONE via BIO pair: ");
1098
1099	if (verify_alpn(c_ssl, s_ssl) < 0) {
1100		ret = 1;
1101		goto err;
1102	}
1103
1104	ret = 0;
1105
1106err:
1107	ERR_print_errors(bio_err);
1108
1109	BIO_free(server);
1110	BIO_free(server_io);
1111	BIO_free(client);
1112	BIO_free(client_io);
1113	BIO_free(s_ssl_bio);
1114	BIO_free(c_ssl_bio);
1115
1116	return ret;
1117}
1118
1119
1120#define W_READ	1
1121#define W_WRITE	2
1122#define C_DONE	1
1123#define S_DONE	2
1124
1125int
1126doit(SSL *s_ssl, SSL *c_ssl, long count)
1127{
1128	char cbuf[1024*8], sbuf[1024*8];
1129	long cw_num = count, cr_num = count;
1130	long sw_num = count, sr_num = count;
1131	int ret = 1;
1132	BIO *c_to_s = NULL;
1133	BIO *s_to_c = NULL;
1134	BIO *c_bio = NULL;
1135	BIO *s_bio = NULL;
1136	int c_r, c_w, s_r, s_w;
1137	int i, j;
1138	int done = 0;
1139	int c_write, s_write;
1140	int do_server = 0, do_client = 0;
1141
1142	memset(cbuf, 0, sizeof(cbuf));
1143	memset(sbuf, 0, sizeof(sbuf));
1144
1145	c_to_s = BIO_new(BIO_s_mem());
1146	s_to_c = BIO_new(BIO_s_mem());
1147	if ((s_to_c == NULL) || (c_to_s == NULL)) {
1148		ERR_print_errors(bio_err);
1149		goto err;
1150	}
1151
1152	c_bio = BIO_new(BIO_f_ssl());
1153	s_bio = BIO_new(BIO_f_ssl());
1154	if ((c_bio == NULL) || (s_bio == NULL)) {
1155		ERR_print_errors(bio_err);
1156		goto err;
1157	}
1158
1159	SSL_set_connect_state(c_ssl);
1160	SSL_set_bio(c_ssl, s_to_c, c_to_s);
1161	BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE);
1162
1163	SSL_set_accept_state(s_ssl);
1164	SSL_set_bio(s_ssl, c_to_s, s_to_c);
1165	BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE);
1166
1167	c_r = 0;
1168	s_r = 1;
1169	c_w = 1;
1170	s_w = 0;
1171	c_write = 1, s_write = 0;
1172
1173	/* We can always do writes */
1174	for (;;) {
1175		do_server = 0;
1176		do_client = 0;
1177
1178		i = (int)BIO_pending(s_bio);
1179		if ((i && s_r) || s_w)
1180			do_server = 1;
1181
1182		i = (int)BIO_pending(c_bio);
1183		if ((i && c_r) || c_w)
1184			do_client = 1;
1185
1186		if (do_server && debug) {
1187			if (SSL_in_init(s_ssl))
1188				printf("server waiting in SSL_accept - %s\n",
1189				    SSL_state_string_long(s_ssl));
1190		}
1191
1192		if (do_client && debug) {
1193			if (SSL_in_init(c_ssl))
1194				printf("client waiting in SSL_connect - %s\n",
1195				    SSL_state_string_long(c_ssl));
1196		}
1197
1198		if (!do_client && !do_server) {
1199			fprintf(stdout, "ERROR in STARTUP\n");
1200			ERR_print_errors(bio_err);
1201			goto err;
1202		}
1203
1204		if (do_client && !(done & C_DONE)) {
1205			if (c_write) {
1206				j = (cw_num > (long)sizeof(cbuf)) ?
1207				    (int)sizeof(cbuf) : (int)cw_num;
1208				i = BIO_write(c_bio, cbuf, j);
1209				if (i < 0) {
1210					c_r = 0;
1211					c_w = 0;
1212					if (BIO_should_retry(c_bio)) {
1213						if (BIO_should_read(c_bio))
1214							c_r = 1;
1215						if (BIO_should_write(c_bio))
1216							c_w = 1;
1217					} else {
1218						fprintf(stderr, "ERROR in CLIENT\n");
1219						ERR_print_errors(bio_err);
1220						goto err;
1221					}
1222				} else if (i == 0) {
1223					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1224					goto err;
1225				} else {
1226					if (debug)
1227						printf("client wrote %d\n", i);
1228					/* ok */
1229					s_r = 1;
1230					c_write = 0;
1231					cw_num -= i;
1232				}
1233			} else {
1234				i = BIO_read(c_bio, cbuf, sizeof(cbuf));
1235				if (i < 0) {
1236					c_r = 0;
1237					c_w = 0;
1238					if (BIO_should_retry(c_bio)) {
1239						if (BIO_should_read(c_bio))
1240							c_r = 1;
1241						if (BIO_should_write(c_bio))
1242							c_w = 1;
1243					} else {
1244						fprintf(stderr, "ERROR in CLIENT\n");
1245						ERR_print_errors(bio_err);
1246						goto err;
1247					}
1248				} else if (i == 0) {
1249					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1250					goto err;
1251				} else {
1252					if (debug)
1253						printf("client read %d\n", i);
1254					cr_num -= i;
1255					if (sw_num > 0) {
1256						s_write = 1;
1257						s_w = 1;
1258					}
1259					if (cr_num <= 0) {
1260						s_write = 1;
1261						s_w = 1;
1262						done = S_DONE|C_DONE;
1263					}
1264				}
1265			}
1266		}
1267
1268		if (do_server && !(done & S_DONE)) {
1269			if (!s_write) {
1270				i = BIO_read(s_bio, sbuf, sizeof(cbuf));
1271				if (i < 0) {
1272					s_r = 0;
1273					s_w = 0;
1274					if (BIO_should_retry(s_bio)) {
1275						if (BIO_should_read(s_bio))
1276							s_r = 1;
1277						if (BIO_should_write(s_bio))
1278							s_w = 1;
1279					} else {
1280						fprintf(stderr, "ERROR in SERVER\n");
1281						ERR_print_errors(bio_err);
1282						goto err;
1283					}
1284				} else if (i == 0) {
1285					ERR_print_errors(bio_err);
1286					fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_read\n");
1287					goto err;
1288				} else {
1289					if (debug)
1290						printf("server read %d\n", i);
1291					sr_num -= i;
1292					if (cw_num > 0) {
1293						c_write = 1;
1294						c_w = 1;
1295					}
1296					if (sr_num <= 0) {
1297						s_write = 1;
1298						s_w = 1;
1299						c_write = 0;
1300					}
1301				}
1302			} else {
1303				j = (sw_num > (long)sizeof(sbuf)) ?
1304				    (int)sizeof(sbuf) : (int)sw_num;
1305				i = BIO_write(s_bio, sbuf, j);
1306				if (i < 0) {
1307					s_r = 0;
1308					s_w = 0;
1309					if (BIO_should_retry(s_bio)) {
1310						if (BIO_should_read(s_bio))
1311							s_r = 1;
1312						if (BIO_should_write(s_bio))
1313							s_w = 1;
1314					} else {
1315						fprintf(stderr, "ERROR in SERVER\n");
1316						ERR_print_errors(bio_err);
1317						goto err;
1318					}
1319				} else if (i == 0) {
1320					ERR_print_errors(bio_err);
1321					fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_write\n");
1322					goto err;
1323				} else {
1324					if (debug)
1325						printf("server wrote %d\n", i);
1326					sw_num -= i;
1327					s_write = 0;
1328					c_r = 1;
1329					if (sw_num <= 0)
1330						done |= S_DONE;
1331				}
1332			}
1333		}
1334
1335		if ((done & S_DONE) && (done & C_DONE))
1336			break;
1337	}
1338
1339	if (verbose)
1340		print_details(c_ssl, "DONE: ");
1341
1342	if (verify_alpn(c_ssl, s_ssl) < 0) {
1343		ret = 1;
1344		goto err;
1345	}
1346
1347	ret = 0;
1348err:
1349	/* We have to set the BIO's to NULL otherwise they will be
1350	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
1351	 * again when c_ssl is SSL_free()ed.
1352	 * This is a hack required because s_ssl and c_ssl are sharing the same
1353	 * BIO structure and SSL_set_bio() and SSL_free() automatically
1354	 * BIO_free non NULL entries.
1355	 * You should not normally do this or be required to do this */
1356	if (s_ssl != NULL) {
1357		s_ssl->rbio = NULL;
1358		s_ssl->wbio = NULL;
1359	}
1360	if (c_ssl != NULL) {
1361		c_ssl->rbio = NULL;
1362		c_ssl->wbio = NULL;
1363	}
1364
1365	BIO_free(c_to_s);
1366	BIO_free(s_to_c);
1367	BIO_free_all(c_bio);
1368	BIO_free_all(s_bio);
1369
1370	return (ret);
1371}
1372
1373static int
1374get_proxy_auth_ex_data_idx(void)
1375{
1376	static volatile int idx = -1;
1377	if (idx < 0) {
1378		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
1379		if (idx < 0) {
1380			idx = X509_STORE_CTX_get_ex_new_index(0,
1381			    "SSLtest for verify callback", NULL, NULL, NULL);
1382		}
1383		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
1384	}
1385	return idx;
1386}
1387
1388static int
1389verify_callback(int ok, X509_STORE_CTX *ctx)
1390{
1391	char *s, buf[256];
1392
1393	s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf,
1394	    sizeof buf);
1395	if (s != NULL) {
1396		if (ok)
1397			fprintf(stderr, "depth=%d %s\n",
1398			    ctx->error_depth, buf);
1399		else {
1400			fprintf(stderr, "depth=%d error=%d %s\n",
1401			    ctx->error_depth, ctx->error, buf);
1402		}
1403	}
1404
1405	if (ok == 0) {
1406		fprintf(stderr, "Error string: %s\n",
1407		    X509_verify_cert_error_string(ctx->error));
1408		switch (ctx->error) {
1409		case X509_V_ERR_CERT_NOT_YET_VALID:
1410		case X509_V_ERR_CERT_HAS_EXPIRED:
1411		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1412			fprintf(stderr, "  ... ignored.\n");
1413			ok = 1;
1414		}
1415	}
1416
1417	if (ok == 1) {
1418		X509 *xs = ctx->current_cert;
1419#if 0
1420		X509 *xi = ctx->current_issuer;
1421#endif
1422
1423		if (xs->ex_flags & EXFLAG_PROXY) {
1424			unsigned int *letters =
1425			    X509_STORE_CTX_get_ex_data(ctx,
1426			    get_proxy_auth_ex_data_idx());
1427
1428			if (letters) {
1429				int found_any = 0;
1430				int i;
1431				PROXY_CERT_INFO_EXTENSION *pci =
1432				    X509_get_ext_d2i(xs, NID_proxyCertInfo,
1433				    NULL, NULL);
1434
1435				switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) {
1436				case NID_Independent:
1437					/* Completely meaningless in this
1438					   program, as there's no way to
1439					   grant explicit rights to a
1440					   specific PrC.  Basically, using
1441					   id-ppl-Independent is the perfect
1442					   way to grant no rights at all. */
1443					fprintf(stderr, "  Independent proxy certificate");
1444					for (i = 0; i < 26; i++)
1445						letters[i] = 0;
1446					break;
1447				case NID_id_ppl_inheritAll:
1448					/* This is basically a NOP, we
1449					   simply let the current rights
1450					   stand as they are. */
1451					fprintf(stderr, "  Proxy certificate inherits all");
1452					break;
1453				default:
1454					s = (char *)
1455					pci->proxyPolicy->policy->data;
1456					i = pci->proxyPolicy->policy->length;
1457
1458					/* The algorithm works as follows:
1459					   it is assumed that previous
1460					   iterations or the initial granted
1461					   rights has already set some elements
1462					   of `letters'.  What we need to do is
1463					   to clear those that weren't granted
1464					   by the current PrC as well.  The
1465					   easiest way to do this is to add 1
1466					   to all the elements whose letters
1467					   are given with the current policy.
1468					   That way, all elements that are set
1469					   by the current policy and were
1470					   already set by earlier policies and
1471					   through the original grant of rights
1472					   will get the value 2 or higher.
1473					   The last thing to do is to sweep
1474					   through `letters' and keep the
1475					   elements having the value 2 as set,
1476					   and clear all the others. */
1477
1478					fprintf(stderr, "  Certificate proxy rights = %*.*s", i, i, s);
1479					while (i-- > 0) {
1480						int c = *s++;
1481						if (isascii(c) && isalpha(c)) {
1482							if (islower(c))
1483								c = toupper(c);
1484							letters[c - 'A']++;
1485						}
1486					}
1487					for (i = 0; i < 26; i++)
1488						if (letters[i] < 2)
1489							letters[i] = 0;
1490					else
1491						letters[i] = 1;
1492				}
1493
1494				found_any = 0;
1495				fprintf(stderr, ", resulting proxy rights = ");
1496				for (i = 0; i < 26; i++)
1497					if (letters[i]) {
1498					fprintf(stderr, "%c", i + 'A');
1499					found_any = 1;
1500				}
1501				if (!found_any)
1502					fprintf(stderr, "none");
1503				fprintf(stderr, "\n");
1504
1505				PROXY_CERT_INFO_EXTENSION_free(pci);
1506			}
1507		}
1508	}
1509
1510	return (ok);
1511}
1512
1513static void
1514process_proxy_debug(int indent, const char *format, ...)
1515{
1516	static const char indentation[] =
1517	    ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
1518	    ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */
1519	char my_format[256];
1520	va_list args;
1521
1522	(void) snprintf(my_format, sizeof(my_format), "%*.*s %s",
1523	    indent, indent, indentation, format);
1524
1525	va_start(args, format);
1526	vfprintf(stderr, my_format, args);
1527	va_end(args);
1528}
1529/* Priority levels:
1530   0	[!]var, ()
1531   1	& ^
1532   2	|
1533*/
1534static int process_proxy_cond_adders(unsigned int letters[26],
1535    const char *cond, const char **cond_end, int *pos, int indent);
1536
1537static int
1538process_proxy_cond_val(unsigned int letters[26], const char *cond,
1539    const char **cond_end, int *pos, int indent)
1540{
1541	int c;
1542	int ok = 1;
1543	int negate = 0;
1544
1545	while (isspace((int)*cond)) {
1546		cond++;
1547		(*pos)++;
1548	}
1549	c = *cond;
1550
1551	if (debug)
1552		process_proxy_debug(indent,
1553		    "Start process_proxy_cond_val at position %d: %s\n",
1554		    *pos, cond);
1555
1556	while (c == '!') {
1557		negate = !negate;
1558		cond++;
1559		(*pos)++;
1560		while (isspace((int)*cond)) {
1561			cond++;
1562			(*pos)++;
1563		}
1564		c = *cond;
1565	}
1566
1567	if (c == '(') {
1568		cond++;
1569		(*pos)++;
1570		ok = process_proxy_cond_adders(letters, cond, cond_end, pos,
1571		    indent + 1);
1572		cond = *cond_end;
1573		if (ok < 0)
1574			goto end;
1575		while (isspace((int)*cond)) {
1576			cond++;
1577			(*pos)++;
1578		}
1579		c = *cond;
1580		if (c != ')') {
1581			fprintf(stderr,
1582			    "Weird condition character in position %d: "
1583			    "%c\n", *pos, c);
1584			ok = -1;
1585			goto end;
1586		}
1587		cond++;
1588		(*pos)++;
1589	} else if (isascii(c) && isalpha(c)) {
1590		if (islower(c))
1591			c = toupper(c);
1592		ok = letters[c - 'A'];
1593		cond++;
1594		(*pos)++;
1595	} else {
1596		fprintf(stderr,
1597		    "Weird condition character in position %d: "
1598		    "%c\n", *pos, c);
1599		ok = -1;
1600		goto end;
1601	}
1602end:
1603	*cond_end = cond;
1604	if (ok >= 0 && negate)
1605		ok = !ok;
1606
1607	if (debug)
1608		process_proxy_debug(indent,
1609		    "End process_proxy_cond_val at position %d: %s, returning %d\n",
1610		    *pos, cond, ok);
1611
1612	return ok;
1613}
1614
1615static int
1616process_proxy_cond_multipliers(unsigned int letters[26], const char *cond,
1617    const char **cond_end, int *pos, int indent)
1618{
1619	int ok;
1620	char c;
1621
1622	if (debug)
1623		process_proxy_debug(indent,
1624		    "Start process_proxy_cond_multipliers at position %d: %s\n",
1625		    *pos, cond);
1626
1627	ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1);
1628	cond = *cond_end;
1629	if (ok < 0)
1630		goto end;
1631
1632	while (ok >= 0) {
1633		while (isspace((int)*cond)) {
1634			cond++;
1635			(*pos)++;
1636		}
1637		c = *cond;
1638
1639		switch (c) {
1640		case '&':
1641		case '^':
1642			{
1643				int save_ok = ok;
1644
1645				cond++;
1646				(*pos)++;
1647				ok = process_proxy_cond_val(letters,
1648				    cond, cond_end, pos, indent + 1);
1649				cond = *cond_end;
1650				if (ok < 0)
1651					break;
1652
1653				switch (c) {
1654				case '&':
1655					ok &= save_ok;
1656					break;
1657				case '^':
1658					ok ^= save_ok;
1659					break;
1660				default:
1661					fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1662					    " STOPPING\n");
1663					exit(1);
1664				}
1665			}
1666			break;
1667		default:
1668			goto end;
1669		}
1670	}
1671end:
1672	if (debug)
1673		process_proxy_debug(indent,
1674		    "End process_proxy_cond_multipliers at position %d: %s, "
1675		    "returning %d\n",
1676		    *pos, cond, ok);
1677
1678	*cond_end = cond;
1679	return ok;
1680}
1681
1682static int
1683process_proxy_cond_adders(unsigned int letters[26], const char *cond,
1684    const char **cond_end, int *pos, int indent)
1685{
1686	int ok;
1687	char c;
1688
1689	if (debug)
1690		process_proxy_debug(indent,
1691		    "Start process_proxy_cond_adders at position %d: %s\n",
1692		    *pos, cond);
1693
1694	ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos,
1695	    indent + 1);
1696	cond = *cond_end;
1697	if (ok < 0)
1698		goto end;
1699
1700	while (ok >= 0) {
1701		while (isspace((int)*cond)) {
1702			cond++;
1703			(*pos)++;
1704		}
1705		c = *cond;
1706
1707		switch (c) {
1708		case '|':
1709			{
1710				int save_ok = ok;
1711
1712				cond++;
1713				(*pos)++;
1714				ok = process_proxy_cond_multipliers(letters,
1715				    cond, cond_end, pos, indent + 1);
1716				cond = *cond_end;
1717				if (ok < 0)
1718					break;
1719
1720				switch (c) {
1721				case '|':
1722					ok |= save_ok;
1723					break;
1724				default:
1725					fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!"
1726					    " STOPPING\n");
1727					exit(1);
1728				}
1729			}
1730			break;
1731		default:
1732			goto end;
1733		}
1734	}
1735end:
1736	if (debug)
1737		process_proxy_debug(indent,
1738		    "End process_proxy_cond_adders at position %d: %s, returning %d\n",
1739		    *pos, cond, ok);
1740
1741	*cond_end = cond;
1742	return ok;
1743}
1744
1745static int
1746process_proxy_cond(unsigned int letters[26], const char *cond,
1747    const char **cond_end)
1748{
1749	int pos = 1;
1750	return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1);
1751}
1752
1753static int
1754app_verify_callback(X509_STORE_CTX *ctx, void *arg)
1755{
1756	int ok = 1;
1757	struct app_verify_arg *cb_arg = arg;
1758	unsigned int letters[26]; /* only used with proxy_auth */
1759
1760	if (cb_arg->app_verify) {
1761		char *s = NULL, buf[256];
1762
1763		fprintf(stderr, "In app_verify_callback, allowing cert. ");
1764		fprintf(stderr, "Arg is: %s\n", cb_arg->string);
1765		fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
1766		    (void *)ctx, (void *)ctx->cert);
1767		if (ctx->cert)
1768			s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256);
1769		if (s != NULL) {
1770			fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf);
1771		}
1772		return (1);
1773	}
1774	if (cb_arg->proxy_auth) {
1775		int found_any = 0, i;
1776		char *sp;
1777
1778		for (i = 0; i < 26; i++)
1779			letters[i] = 0;
1780		for (sp = cb_arg->proxy_auth; *sp; sp++) {
1781			int c = *sp;
1782			if (isascii(c) && isalpha(c)) {
1783				if (islower(c))
1784					c = toupper(c);
1785				letters[c - 'A'] = 1;
1786			}
1787		}
1788
1789		fprintf(stderr, "  Initial proxy rights = ");
1790		for (i = 0; i < 26; i++)
1791			if (letters[i]) {
1792			fprintf(stderr, "%c", i + 'A');
1793			found_any = 1;
1794		}
1795		if (!found_any)
1796			fprintf(stderr, "none");
1797		fprintf(stderr, "\n");
1798
1799		X509_STORE_CTX_set_ex_data(ctx,
1800		    get_proxy_auth_ex_data_idx(), letters);
1801	}
1802	if (cb_arg->allow_proxy_certs) {
1803		X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
1804	}
1805
1806	ok = X509_verify_cert(ctx);
1807
1808	if (cb_arg->proxy_auth) {
1809		if (ok > 0) {
1810			const char *cond_end = NULL;
1811
1812			ok = process_proxy_cond(letters,
1813			    cb_arg->proxy_cond, &cond_end);
1814
1815			if (ok < 0)
1816				exit(3);
1817			if (*cond_end) {
1818				fprintf(stderr, "Stopped processing condition before it's end.\n");
1819				ok = 0;
1820			}
1821			if (!ok)
1822				fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n",
1823				    cb_arg->proxy_cond);
1824			else
1825				fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n",
1826				    cb_arg->proxy_cond);
1827		}
1828	}
1829	return (ok);
1830}
1831
1832/* These DH parameters have been generated as follows:
1833 *    $ openssl dhparam -C -noout 1024
1834 *    $ openssl dhparam -C -noout -dsaparam 1024
1835 * (The second function has been renamed to avoid name conflicts.)
1836 */
1837static DH *
1838get_dh1024()
1839{
1840	static unsigned char dh1024_p[] = {
1841		0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 0x3A,
1842		0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 0xA2,
1843		0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 0xB0,
1844		0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 0xC2,
1845		0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 0x8C,
1846		0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 0xB8,
1847		0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 0x52,
1848		0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 0xC1,
1849		0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 0xB1,
1850		0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 0xAB,
1851		0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53,
1852	};
1853	static unsigned char dh1024_g[] = {
1854		0x02,
1855	};
1856	DH *dh;
1857
1858	if ((dh = DH_new()) == NULL)
1859		return (NULL);
1860	dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
1861	dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
1862	if ((dh->p == NULL) || (dh->g == NULL)) {
1863		DH_free(dh);
1864		return (NULL);
1865	}
1866	return (dh);
1867}
1868
1869static DH *
1870get_dh1024dsa()
1871{
1872	static unsigned char dh1024_p[] = {
1873		0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 0x00,
1874		0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 0x19,
1875		0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 0xD2,
1876		0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 0x55,
1877		0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 0xFC,
1878		0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 0x97,
1879		0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 0x8D,
1880		0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 0xBB,
1881		0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 0xF6,
1882		0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 0x9E,
1883		0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39,
1884	};
1885	static unsigned char dh1024_g[] = {
1886		0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 0x05,
1887		0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 0xF3,
1888		0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 0xE9,
1889		0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 0x3C,
1890		0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 0x65,
1891		0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 0x60,
1892		0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 0xF6,
1893		0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 0xA7,
1894		0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 0xA1,
1895		0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 0x60,
1896		0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2,
1897	};
1898	DH *dh;
1899
1900	if ((dh = DH_new()) == NULL)
1901		return (NULL);
1902	dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
1903	dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
1904	if ((dh->p == NULL) || (dh->g == NULL)) {
1905		DH_free(dh);
1906		return (NULL);
1907	}
1908	dh->length = 160;
1909	return (dh);
1910}
1911