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