xref: /openbsd/regress/lib/libssl/ssl/ssltest.c (revision 319de9d2)
1*319de9d2Stb /*	$OpenBSD: ssltest.c,v 1.45 2024/03/01 03:45:16 tb Exp $ */
2e90e4cafSjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3e90e4cafSjsing  * All rights reserved.
4e90e4cafSjsing  *
5e90e4cafSjsing  * This package is an SSL implementation written
6e90e4cafSjsing  * by Eric Young (eay@cryptsoft.com).
7e90e4cafSjsing  * The implementation was written so as to conform with Netscapes SSL.
8e90e4cafSjsing  *
9e90e4cafSjsing  * This library is free for commercial and non-commercial use as long as
10e90e4cafSjsing  * the following conditions are aheared to.  The following conditions
11e90e4cafSjsing  * apply to all code found in this distribution, be it the RC4, RSA,
12e90e4cafSjsing  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13e90e4cafSjsing  * included with this distribution is covered by the same copyright terms
14e90e4cafSjsing  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15e90e4cafSjsing  *
16e90e4cafSjsing  * Copyright remains Eric Young's, and as such any Copyright notices in
17e90e4cafSjsing  * the code are not to be removed.
18e90e4cafSjsing  * If this package is used in a product, Eric Young should be given attribution
19e90e4cafSjsing  * as the author of the parts of the library used.
20e90e4cafSjsing  * This can be in the form of a textual message at program startup or
21e90e4cafSjsing  * in documentation (online or textual) provided with the package.
22e90e4cafSjsing  *
23e90e4cafSjsing  * Redistribution and use in source and binary forms, with or without
24e90e4cafSjsing  * modification, are permitted provided that the following conditions
25e90e4cafSjsing  * are met:
26e90e4cafSjsing  * 1. Redistributions of source code must retain the copyright
27e90e4cafSjsing  *    notice, this list of conditions and the following disclaimer.
28e90e4cafSjsing  * 2. Redistributions in binary form must reproduce the above copyright
29e90e4cafSjsing  *    notice, this list of conditions and the following disclaimer in the
30e90e4cafSjsing  *    documentation and/or other materials provided with the distribution.
31e90e4cafSjsing  * 3. All advertising materials mentioning features or use of this software
32e90e4cafSjsing  *    must display the following acknowledgement:
33e90e4cafSjsing  *    "This product includes cryptographic software written by
34e90e4cafSjsing  *     Eric Young (eay@cryptsoft.com)"
35e90e4cafSjsing  *    The word 'cryptographic' can be left out if the rouines from the library
36e90e4cafSjsing  *    being used are not cryptographic related :-).
37e90e4cafSjsing  * 4. If you include any Windows specific code (or a derivative thereof) from
38e90e4cafSjsing  *    the apps directory (application code) you must include an acknowledgement:
39e90e4cafSjsing  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40e90e4cafSjsing  *
41e90e4cafSjsing  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42e90e4cafSjsing  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43e90e4cafSjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44e90e4cafSjsing  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45e90e4cafSjsing  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46e90e4cafSjsing  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47e90e4cafSjsing  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48e90e4cafSjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49e90e4cafSjsing  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50e90e4cafSjsing  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51e90e4cafSjsing  * SUCH DAMAGE.
52e90e4cafSjsing  *
53e90e4cafSjsing  * The licence and distribution terms for any publically available version or
54e90e4cafSjsing  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55e90e4cafSjsing  * copied and put under another distribution licence
56e90e4cafSjsing  * [including the GNU Public Licence.]
57e90e4cafSjsing  */
58e90e4cafSjsing /* ====================================================================
59e90e4cafSjsing  * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
60e90e4cafSjsing  *
61e90e4cafSjsing  * Redistribution and use in source and binary forms, with or without
62e90e4cafSjsing  * modification, are permitted provided that the following conditions
63e90e4cafSjsing  * are met:
64e90e4cafSjsing  *
65e90e4cafSjsing  * 1. Redistributions of source code must retain the above copyright
66e90e4cafSjsing  *    notice, this list of conditions and the following disclaimer.
67e90e4cafSjsing  *
68e90e4cafSjsing  * 2. Redistributions in binary form must reproduce the above copyright
69e90e4cafSjsing  *    notice, this list of conditions and the following disclaimer in
70e90e4cafSjsing  *    the documentation and/or other materials provided with the
71e90e4cafSjsing  *    distribution.
72e90e4cafSjsing  *
73e90e4cafSjsing  * 3. All advertising materials mentioning features or use of this
74e90e4cafSjsing  *    software must display the following acknowledgment:
75e90e4cafSjsing  *    "This product includes software developed by the OpenSSL Project
76e90e4cafSjsing  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77e90e4cafSjsing  *
78e90e4cafSjsing  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79e90e4cafSjsing  *    endorse or promote products derived from this software without
80e90e4cafSjsing  *    prior written permission. For written permission, please contact
81e90e4cafSjsing  *    openssl-core@openssl.org.
82e90e4cafSjsing  *
83e90e4cafSjsing  * 5. Products derived from this software may not be called "OpenSSL"
84e90e4cafSjsing  *    nor may "OpenSSL" appear in their names without prior written
85e90e4cafSjsing  *    permission of the OpenSSL Project.
86e90e4cafSjsing  *
87e90e4cafSjsing  * 6. Redistributions of any form whatsoever must retain the following
88e90e4cafSjsing  *    acknowledgment:
89e90e4cafSjsing  *    "This product includes software developed by the OpenSSL Project
90e90e4cafSjsing  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91e90e4cafSjsing  *
92e90e4cafSjsing  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93e90e4cafSjsing  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94e90e4cafSjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95e90e4cafSjsing  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96e90e4cafSjsing  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97e90e4cafSjsing  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98e90e4cafSjsing  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99e90e4cafSjsing  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100e90e4cafSjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101e90e4cafSjsing  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102e90e4cafSjsing  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103e90e4cafSjsing  * OF THE POSSIBILITY OF SUCH DAMAGE.
104e90e4cafSjsing  * ====================================================================
105e90e4cafSjsing  *
106e90e4cafSjsing  * This product includes cryptographic software written by Eric Young
107e90e4cafSjsing  * (eay@cryptsoft.com).  This product includes software written by Tim
108e90e4cafSjsing  * Hudson (tjh@cryptsoft.com).
109e90e4cafSjsing  *
110e90e4cafSjsing  */
111e90e4cafSjsing /* ====================================================================
112e90e4cafSjsing  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113e90e4cafSjsing  * ECC cipher suite support in OpenSSL originally developed by
114e90e4cafSjsing  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115e90e4cafSjsing  */
116e90e4cafSjsing /* ====================================================================
117e90e4cafSjsing  * Copyright 2005 Nokia. All rights reserved.
118e90e4cafSjsing  *
119e90e4cafSjsing  * The portions of the attached software ("Contribution") is developed by
120e90e4cafSjsing  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
121e90e4cafSjsing  * license.
122e90e4cafSjsing  *
123e90e4cafSjsing  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
124e90e4cafSjsing  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
125e90e4cafSjsing  * support (see RFC 4279) to OpenSSL.
126e90e4cafSjsing  *
127e90e4cafSjsing  * No patent licenses or other rights except those expressly stated in
128e90e4cafSjsing  * the OpenSSL open source license shall be deemed granted or received
129e90e4cafSjsing  * expressly, by implication, estoppel, or otherwise.
130e90e4cafSjsing  *
131e90e4cafSjsing  * No assurances are provided by Nokia that the Contribution does not
132e90e4cafSjsing  * infringe the patent or other intellectual property rights of any third
133e90e4cafSjsing  * party or that the license provides you with all the necessary rights
134e90e4cafSjsing  * to make use of the Contribution.
135e90e4cafSjsing  *
136e90e4cafSjsing  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
137e90e4cafSjsing  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
138e90e4cafSjsing  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
139e90e4cafSjsing  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
140e90e4cafSjsing  * OTHERWISE.
141e90e4cafSjsing  */
142e90e4cafSjsing 
1432287d13aStb /* XXX - USE_BIOPAIR code needs updating for BIO_n{read,write}{,0} removal. */
1442287d13aStb /* #define USE_BIOPAIR */
1452287d13aStb 
146e90e4cafSjsing #define _BSD_SOURCE 1		/* Or gethostname won't be declared properly
147e90e4cafSjsing 				   on Linux and GNU platforms. */
148e90e4cafSjsing #include <sys/types.h>
149e90e4cafSjsing #include <sys/socket.h>
150e90e4cafSjsing 
151e90e4cafSjsing #include <netinet/in.h>
152e90e4cafSjsing 
153e90e4cafSjsing #include <assert.h>
154e90e4cafSjsing #include <errno.h>
155e90e4cafSjsing #include <limits.h>
156e90e4cafSjsing #include <netdb.h>
157e90e4cafSjsing #include <stdio.h>
158e90e4cafSjsing #include <stdlib.h>
159e90e4cafSjsing #include <string.h>
160e90e4cafSjsing #include <time.h>
161e90e4cafSjsing #include <unistd.h>
162e90e4cafSjsing 
163e90e4cafSjsing #include <openssl/opensslconf.h>
164e90e4cafSjsing #include <openssl/bio.h>
165e90e4cafSjsing #include <openssl/crypto.h>
166e90e4cafSjsing #include <openssl/evp.h>
167e90e4cafSjsing #include <openssl/x509.h>
168e90e4cafSjsing #include <openssl/x509v3.h>
169e90e4cafSjsing #include <openssl/ssl.h>
170e90e4cafSjsing #include <openssl/err.h>
171e90e4cafSjsing #include <openssl/rand.h>
172e90e4cafSjsing #include <openssl/rsa.h>
173e90e4cafSjsing #include <openssl/dsa.h>
174e90e4cafSjsing #include <openssl/dh.h>
175e90e4cafSjsing #include <openssl/bn.h>
176e90e4cafSjsing 
177c9675a23Stb #include "ssl_local.h"
178b3b86eecSjsing 
179e90e4cafSjsing #define TEST_SERVER_CERT "../apps/server.pem"
180e90e4cafSjsing #define TEST_CLIENT_CERT "../apps/client.pem"
181e90e4cafSjsing 
182e90e4cafSjsing static int verify_callback(int ok, X509_STORE_CTX *ctx);
183e90e4cafSjsing static int app_verify_callback(X509_STORE_CTX *ctx, void *arg);
184e90e4cafSjsing 
185e90e4cafSjsing static DH *get_dh1024(void);
186e90e4cafSjsing static DH *get_dh1024dsa(void);
187e90e4cafSjsing 
188e90e4cafSjsing static BIO *bio_err = NULL;
189e90e4cafSjsing static BIO *bio_stdout = NULL;
190e90e4cafSjsing 
19100422117Sjsing static const char *alpn_client;
19200422117Sjsing static const char *alpn_server;
19300422117Sjsing static const char *alpn_expected;
19400422117Sjsing static unsigned char *alpn_selected;
19500422117Sjsing 
19600422117Sjsing /*
19700422117Sjsing  * next_protos_parse parses a comma separated list of strings into a string
19800422117Sjsing  * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
19900422117Sjsing  *   outlen: (output) set to the length of the resulting buffer on success.
20000422117Sjsing  *   err: (maybe NULL) on failure, an error message line is written to this BIO.
20100422117Sjsing  *   in: a NUL terminated string like "abc,def,ghi"
20200422117Sjsing  *
20300422117Sjsing  *   returns: a malloced buffer or NULL on failure.
20400422117Sjsing  */
20500422117Sjsing static unsigned char *
next_protos_parse(unsigned short * outlen,const char * in)20600422117Sjsing next_protos_parse(unsigned short *outlen, const char *in)
20700422117Sjsing {
20800422117Sjsing 	size_t i, len, start = 0;
20900422117Sjsing 	unsigned char *out;
21000422117Sjsing 
21100422117Sjsing 	len = strlen(in);
21200422117Sjsing 	if (len >= 65535)
21300422117Sjsing 		return (NULL);
21400422117Sjsing 
21500422117Sjsing 	if ((out = malloc(strlen(in) + 1)) == NULL)
21600422117Sjsing 		return (NULL);
21700422117Sjsing 
21800422117Sjsing 	for (i = 0; i <= len; ++i) {
21900422117Sjsing 		if (i == len || in[i] == ',') {
22000422117Sjsing 			if (i - start > 255) {
22100422117Sjsing 				free(out);
22200422117Sjsing 				return (NULL);
22300422117Sjsing 			}
22400422117Sjsing 			out[start] = i - start;
22500422117Sjsing 			start = i + 1;
22600422117Sjsing 		} else
22700422117Sjsing 			out[i+1] = in[i];
22800422117Sjsing 	}
22900422117Sjsing 	*outlen = len + 1;
23000422117Sjsing 	return (out);
23100422117Sjsing }
23200422117Sjsing 
23300422117Sjsing static int
cb_server_alpn(SSL * s,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)23400422117Sjsing cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen,
23500422117Sjsing     const unsigned char *in, unsigned int inlen, void *arg)
23600422117Sjsing {
23700422117Sjsing 	unsigned char *protos;
23800422117Sjsing 	unsigned short protos_len;
23900422117Sjsing 
24000422117Sjsing 	if ((protos = next_protos_parse(&protos_len, alpn_server)) == NULL) {
24100422117Sjsing 		fprintf(stderr,
24200422117Sjsing 		    "failed to parser ALPN server protocol string: %s\n",
24300422117Sjsing 		    alpn_server);
24400422117Sjsing 		abort();
24500422117Sjsing 	}
24600422117Sjsing 
24700422117Sjsing 	if (SSL_select_next_proto((unsigned char **)out, outlen, protos,
24800422117Sjsing 	    protos_len, in, inlen) != OPENSSL_NPN_NEGOTIATED) {
24900422117Sjsing 		free(protos);
25000422117Sjsing 		return (SSL_TLSEXT_ERR_NOACK);
25100422117Sjsing 	}
25200422117Sjsing 
25300422117Sjsing 	/*
25400422117Sjsing 	 * Make a copy of the selected protocol which will be freed in
25500422117Sjsing 	 * verify_alpn.
25600422117Sjsing 	 */
257df6ddd9bStb 	free(alpn_selected);
25800422117Sjsing 	if ((alpn_selected = malloc(*outlen)) == NULL) {
25900422117Sjsing 		fprintf(stderr, "malloc failed\n");
26000422117Sjsing 		abort();
26100422117Sjsing 	}
26200422117Sjsing 	memcpy(alpn_selected, *out, *outlen);
26300422117Sjsing 	*out = alpn_selected;
26400422117Sjsing 	free(protos);
26500422117Sjsing 
26600422117Sjsing 	return (SSL_TLSEXT_ERR_OK);
26700422117Sjsing }
26800422117Sjsing 
26900422117Sjsing static int
verify_alpn(SSL * client,SSL * server)27000422117Sjsing verify_alpn(SSL *client, SSL *server)
27100422117Sjsing {
27200422117Sjsing 	const unsigned char *client_proto, *server_proto;
27300422117Sjsing 	unsigned int client_proto_len = 0, server_proto_len = 0;
27400422117Sjsing 
27500422117Sjsing 	SSL_get0_alpn_selected(client, &client_proto, &client_proto_len);
27600422117Sjsing 	SSL_get0_alpn_selected(server, &server_proto, &server_proto_len);
27700422117Sjsing 
27800422117Sjsing 	free(alpn_selected);
27900422117Sjsing 	alpn_selected = NULL;
28000422117Sjsing 
2813220613cStb 	if (client_proto_len != server_proto_len || (client_proto_len > 0 &&
2823220613cStb 	    memcmp(client_proto, server_proto, client_proto_len) != 0)) {
28300422117Sjsing 		BIO_printf(bio_stdout, "ALPN selected protocols differ!\n");
28400422117Sjsing 		goto err;
28500422117Sjsing 	}
28600422117Sjsing 
28700422117Sjsing 	if (client_proto_len > 0 && alpn_expected == NULL) {
28800422117Sjsing 		BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n");
28900422117Sjsing 		goto err;
29000422117Sjsing 	}
29100422117Sjsing 
29200422117Sjsing 	if (alpn_expected != NULL &&
29300422117Sjsing 	    (client_proto_len != strlen(alpn_expected) ||
29400422117Sjsing 	     memcmp(client_proto, alpn_expected, client_proto_len) != 0)) {
29500422117Sjsing 		BIO_printf(bio_stdout, "ALPN selected protocols not equal to "
29600422117Sjsing 		    "expected protocol: %s\n", alpn_expected);
29700422117Sjsing 		goto err;
29800422117Sjsing 	}
29900422117Sjsing 
30000422117Sjsing 	return (0);
30100422117Sjsing 
30200422117Sjsing err:
30300422117Sjsing 	BIO_printf(bio_stdout, "ALPN results: client: '");
30400422117Sjsing 	BIO_write(bio_stdout, client_proto, client_proto_len);
30500422117Sjsing 	BIO_printf(bio_stdout, "', server: '");
30600422117Sjsing 	BIO_write(bio_stdout, server_proto, server_proto_len);
30700422117Sjsing 	BIO_printf(bio_stdout, "'\n");
30800422117Sjsing 	BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n",
30900422117Sjsing 	    alpn_client, alpn_server);
31000422117Sjsing 
31100422117Sjsing 	return (-1);
31200422117Sjsing }
31300422117Sjsing 
314e90e4cafSjsing static char *cipher = NULL;
315e90e4cafSjsing static int verbose = 0;
316e90e4cafSjsing static int debug = 0;
317e90e4cafSjsing 
3181b38a69bSjsing int doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time,
3191b38a69bSjsing     clock_t *c_time);
320e90e4cafSjsing int doit(SSL *s_ssl, SSL *c_ssl, long bytes);
321bb4517aeSjsing 
322e90e4cafSjsing static void
sv_usage(void)323e90e4cafSjsing sv_usage(void)
324e90e4cafSjsing {
325e90e4cafSjsing 	fprintf(stderr, "usage: ssltest [args ...]\n");
326e90e4cafSjsing 	fprintf(stderr, "\n");
327e90e4cafSjsing 	fprintf(stderr, " -server_auth  - check server certificate\n");
328e90e4cafSjsing 	fprintf(stderr, " -client_auth  - do client authentication\n");
329e90e4cafSjsing 	fprintf(stderr, " -proxy        - allow proxy certificates\n");
330e90e4cafSjsing 	fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n");
331e90e4cafSjsing 	fprintf(stderr, " -proxy_cond <val> - experssion to test proxy policy rights\n");
332e90e4cafSjsing 	fprintf(stderr, " -v            - more output\n");
333e90e4cafSjsing 	fprintf(stderr, " -d            - debug output\n");
334e90e4cafSjsing 	fprintf(stderr, " -reuse        - use session-id reuse\n");
335e90e4cafSjsing 	fprintf(stderr, " -num <val>    - number of connections to perform\n");
336e90e4cafSjsing 	fprintf(stderr, " -bytes <val>  - number of bytes to swap between client/server\n");
337e90e4cafSjsing 	fprintf(stderr, " -dhe1024dsa   - use 1024 bit key (with 160-bit subprime) for DHE\n");
338e90e4cafSjsing 	fprintf(stderr, " -no_dhe       - disable DHE\n");
339e90e4cafSjsing 	fprintf(stderr, " -no_ecdhe     - disable ECDHE\n");
340521ba2f2Sbeck 	fprintf(stderr, " -dtls1_2      - use DTLSv1.2\n");
341e90e4cafSjsing 	fprintf(stderr, " -tls1         - use TLSv1\n");
34217e2d200Sjsing 	fprintf(stderr, " -tls1_2       - use TLSv1.2\n");
343e90e4cafSjsing 	fprintf(stderr, " -CApath arg   - PEM format directory of CA's\n");
344e90e4cafSjsing 	fprintf(stderr, " -CAfile arg   - PEM format file of CA's\n");
345e90e4cafSjsing 	fprintf(stderr, " -cert arg     - Server certificate file\n");
346e90e4cafSjsing 	fprintf(stderr, " -key arg      - Server key file (default: same as -cert)\n");
347e90e4cafSjsing 	fprintf(stderr, " -c_cert arg   - Client certificate file\n");
348e90e4cafSjsing 	fprintf(stderr, " -c_key arg    - Client key file (default: same as -c_cert)\n");
349e90e4cafSjsing 	fprintf(stderr, " -cipher arg   - The cipher list\n");
350e90e4cafSjsing 	fprintf(stderr, " -bio_pair     - Use BIO pairs\n");
351e90e4cafSjsing 	fprintf(stderr, " -f            - Test even cases that can't work\n");
352e90e4cafSjsing 	fprintf(stderr, " -time         - measure processor time used by client and server\n");
353e90e4cafSjsing 	fprintf(stderr, " -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
354e90e4cafSjsing 	               "                 Use \"openssl ecparam -list_curves\" for all names\n"  \
355e90e4cafSjsing 	               "                 (default is sect163r2).\n");
35600422117Sjsing 	fprintf(stderr, " -alpn_client <string> - have client side offer ALPN\n");
35700422117Sjsing 	fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n");
35800422117Sjsing 	fprintf(stderr, " -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
359e90e4cafSjsing }
360e90e4cafSjsing 
361e90e4cafSjsing static void
print_details(SSL * c_ssl,const char * prefix)362e90e4cafSjsing print_details(SSL *c_ssl, const char *prefix)
363e90e4cafSjsing {
364e90e4cafSjsing 	const SSL_CIPHER *ciph;
36578191710Stb 	X509 *cert = NULL;
36678191710Stb 	EVP_PKEY *pkey;
367e90e4cafSjsing 
368e90e4cafSjsing 	ciph = SSL_get_current_cipher(c_ssl);
369e90e4cafSjsing 	BIO_printf(bio_stdout, "%s%s, cipher %s %s",
3701b38a69bSjsing 	    prefix, SSL_get_version(c_ssl), SSL_CIPHER_get_version(ciph),
371e90e4cafSjsing 	    SSL_CIPHER_get_name(ciph));
37278191710Stb 
37378191710Stb 	if ((cert = SSL_get_peer_certificate(c_ssl)) == NULL)
37478191710Stb 		goto out;
37578191710Stb 	if ((pkey = X509_get0_pubkey(cert)) == NULL)
37678191710Stb 		goto out;
37778191710Stb 	if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
37878191710Stb 		RSA *rsa;
37978191710Stb 
38078191710Stb 		if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL)
38178191710Stb 			goto out;
38278191710Stb 
38378191710Stb 		BIO_printf(bio_stdout, ", %d bit RSA", RSA_bits(rsa));
38478191710Stb 	} else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) {
38578191710Stb 		DSA *dsa;
38678191710Stb 		const BIGNUM *p;
38778191710Stb 
38878191710Stb 		if ((dsa = EVP_PKEY_get0_DSA(pkey)) == NULL)
38978191710Stb 			goto out;
39078191710Stb 
39178191710Stb 		DSA_get0_pqg(dsa, &p, NULL, NULL);
39278191710Stb 
39378191710Stb 		BIO_printf(bio_stdout, ", %d bit DSA", BN_num_bits(p));
394e90e4cafSjsing 	}
39578191710Stb 
39678191710Stb  out:
39778191710Stb 	/*
39878191710Stb 	 * The SSL API does not allow us to look at temporary RSA/DH keys,
39978191710Stb 	 * otherwise we should print their lengths too
40078191710Stb 	 */
401e90e4cafSjsing 	BIO_printf(bio_stdout, "\n");
40278191710Stb 
40378191710Stb 	X509_free(cert);
404e90e4cafSjsing }
405e90e4cafSjsing 
406e90e4cafSjsing int
main(int argc,char * argv[])407e90e4cafSjsing main(int argc, char *argv[])
408e90e4cafSjsing {
409e90e4cafSjsing 	char *CApath = NULL, *CAfile = NULL;
410e90e4cafSjsing 	int badop = 0;
411e90e4cafSjsing 	int bio_pair = 0;
412e90e4cafSjsing 	int force = 0;
413521ba2f2Sbeck 	int tls1 = 0, tls1_2 = 0, dtls1_2 = 0, ret = 1;
414e90e4cafSjsing 	int client_auth = 0;
415e90e4cafSjsing 	int server_auth = 0, i;
416664ea9f8Stb 	char *app_verify_arg = "Test Callback Argument";
417e90e4cafSjsing 	char *server_cert = TEST_SERVER_CERT;
418e90e4cafSjsing 	char *server_key = NULL;
419e90e4cafSjsing 	char *client_cert = TEST_CLIENT_CERT;
420e90e4cafSjsing 	char *client_key = NULL;
421e90e4cafSjsing 	char *named_curve = NULL;
422e90e4cafSjsing 	SSL_CTX *s_ctx = NULL;
423e90e4cafSjsing 	SSL_CTX *c_ctx = NULL;
424e90e4cafSjsing 	const SSL_METHOD *meth = NULL;
425e90e4cafSjsing 	SSL *c_ssl, *s_ssl;
426e90e4cafSjsing 	int number = 1, reuse = 0;
427517f1d0fStb 	int seclevel = 0;
428e90e4cafSjsing 	long bytes = 256L;
429e90e4cafSjsing 	DH *dh;
430855052a0Smiod 	int dhe1024dsa = 0;
431e90e4cafSjsing 	EC_KEY *ecdh = NULL;
432e90e4cafSjsing 	int no_dhe = 0;
433e90e4cafSjsing 	int no_ecdhe = 0;
434e90e4cafSjsing 	int print_time = 0;
435e90e4cafSjsing 	clock_t s_time = 0, c_time = 0;
436e90e4cafSjsing 
437e90e4cafSjsing 	verbose = 0;
438e90e4cafSjsing 	debug = 0;
439e90e4cafSjsing 	cipher = 0;
440e90e4cafSjsing 
441e90e4cafSjsing 	bio_err = BIO_new_fp(stderr, BIO_NOCLOSE|BIO_FP_TEXT);
442e90e4cafSjsing 
443e90e4cafSjsing 	bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE|BIO_FP_TEXT);
444e90e4cafSjsing 
445e90e4cafSjsing 	argc--;
446e90e4cafSjsing 	argv++;
447e90e4cafSjsing 
448e90e4cafSjsing 	while (argc >= 1) {
449e90e4cafSjsing 		if (!strcmp(*argv, "-F")) {
450e4c7564cStb 			fprintf(stderr, "not compiled with FIPS support, so exiting without running.\n");
451e90e4cafSjsing 			exit(0);
452e90e4cafSjsing 		} else if (strcmp(*argv, "-server_auth") == 0)
453e90e4cafSjsing 			server_auth = 1;
454e90e4cafSjsing 		else if (strcmp(*argv, "-client_auth") == 0)
455e90e4cafSjsing 			client_auth = 1;
456664ea9f8Stb 		else if (strcmp(*argv, "-v") == 0)
457e90e4cafSjsing 			verbose = 1;
458e90e4cafSjsing 		else if (strcmp(*argv, "-d") == 0)
459e90e4cafSjsing 			debug = 1;
460e90e4cafSjsing 		else if (strcmp(*argv, "-reuse") == 0)
461e90e4cafSjsing 			reuse = 1;
462855052a0Smiod 		else if (strcmp(*argv, "-dhe1024dsa") == 0) {
463e90e4cafSjsing 			dhe1024dsa = 1;
464e90e4cafSjsing 		} else if (strcmp(*argv, "-no_dhe") == 0)
465e90e4cafSjsing 			no_dhe = 1;
466e90e4cafSjsing 		else if (strcmp(*argv, "-no_ecdhe") == 0)
467e90e4cafSjsing 			no_ecdhe = 1;
468521ba2f2Sbeck 		else if (strcmp(*argv, "-dtls1_2") == 0)
469521ba2f2Sbeck 			dtls1_2 = 1;
470c419fba1Sjsing 		else if (strcmp(*argv, "-tls1") == 0)
471c419fba1Sjsing 			tls1 = 1;
47217e2d200Sjsing 		else if (strcmp(*argv, "-tls1_2") == 0)
47317e2d200Sjsing 			tls1_2 = 1;
474e90e4cafSjsing 		else if (strncmp(*argv, "-num", 4) == 0) {
475e90e4cafSjsing 			if (--argc < 1)
476e90e4cafSjsing 				goto bad;
477e90e4cafSjsing 			number = atoi(*(++argv));
478e90e4cafSjsing 			if (number == 0)
479e90e4cafSjsing 				number = 1;
480517f1d0fStb 		} else if (strncmp(*argv, "-seclevel", 9) == 0) {
481517f1d0fStb 			if (--argc < 1)
482517f1d0fStb 				goto bad;
483517f1d0fStb 			seclevel = atoi(*(++argv));
484e90e4cafSjsing 		} else if (strcmp(*argv, "-bytes") == 0) {
485e90e4cafSjsing 			if (--argc < 1)
486e90e4cafSjsing 				goto bad;
487e90e4cafSjsing 			bytes = atol(*(++argv));
488e90e4cafSjsing 			if (bytes == 0L)
489e90e4cafSjsing 				bytes = 1L;
490e90e4cafSjsing 			i = strlen(argv[0]);
491e90e4cafSjsing 			if (argv[0][i - 1] == 'k')
492e90e4cafSjsing 				bytes*=1024L;
493e90e4cafSjsing 			if (argv[0][i - 1] == 'm')
494e90e4cafSjsing 				bytes*=1024L*1024L;
495e90e4cafSjsing 		} else if (strcmp(*argv, "-cert") == 0) {
496e90e4cafSjsing 			if (--argc < 1)
497e90e4cafSjsing 				goto bad;
498e90e4cafSjsing 			server_cert= *(++argv);
499e90e4cafSjsing 		} else if (strcmp(*argv, "-s_cert") == 0) {
500e90e4cafSjsing 			if (--argc < 1)
501e90e4cafSjsing 				goto bad;
502e90e4cafSjsing 			server_cert= *(++argv);
503e90e4cafSjsing 		} else if (strcmp(*argv, "-key") == 0) {
504e90e4cafSjsing 			if (--argc < 1)
505e90e4cafSjsing 				goto bad;
506e90e4cafSjsing 			server_key= *(++argv);
507e90e4cafSjsing 		} else if (strcmp(*argv, "-s_key") == 0) {
508e90e4cafSjsing 			if (--argc < 1)
509e90e4cafSjsing 				goto bad;
510e90e4cafSjsing 			server_key= *(++argv);
511e90e4cafSjsing 		} else if (strcmp(*argv, "-c_cert") == 0) {
512e90e4cafSjsing 			if (--argc < 1)
513e90e4cafSjsing 				goto bad;
514e90e4cafSjsing 			client_cert= *(++argv);
515e90e4cafSjsing 		} else if (strcmp(*argv, "-c_key") == 0) {
516e90e4cafSjsing 			if (--argc < 1)
517e90e4cafSjsing 				goto bad;
518e90e4cafSjsing 			client_key= *(++argv);
519e90e4cafSjsing 		} else if (strcmp(*argv, "-cipher") == 0) {
520e90e4cafSjsing 			if (--argc < 1)
521e90e4cafSjsing 				goto bad;
522e90e4cafSjsing 			cipher= *(++argv);
523e90e4cafSjsing 		} else if (strcmp(*argv, "-CApath") == 0) {
524e90e4cafSjsing 			if (--argc < 1)
525e90e4cafSjsing 				goto bad;
526e90e4cafSjsing 			CApath= *(++argv);
527e90e4cafSjsing 		} else if (strcmp(*argv, "-CAfile") == 0) {
528e90e4cafSjsing 			if (--argc < 1)
529e90e4cafSjsing 				goto bad;
530e90e4cafSjsing 			CAfile= *(++argv);
531e90e4cafSjsing 		} else if (strcmp(*argv, "-bio_pair") == 0) {
532e90e4cafSjsing 			bio_pair = 1;
533e90e4cafSjsing 		} else if (strcmp(*argv, "-f") == 0) {
534e90e4cafSjsing 			force = 1;
535e90e4cafSjsing 		} else if (strcmp(*argv, "-time") == 0) {
536e90e4cafSjsing 			print_time = 1;
537e90e4cafSjsing 		} else if (strcmp(*argv, "-named_curve") == 0) {
538e90e4cafSjsing 			if (--argc < 1)
539e90e4cafSjsing 				goto bad;
540e90e4cafSjsing 			named_curve = *(++argv);
541e90e4cafSjsing 		} else if (strcmp(*argv, "-app_verify") == 0) {
542664ea9f8Stb 			;
54306acd9fcSjsing 		} else if (strcmp(*argv, "-alpn_client") == 0) {
54400422117Sjsing 			if (--argc < 1)
54500422117Sjsing 				goto bad;
54600422117Sjsing 			alpn_client = *(++argv);
54700422117Sjsing 		} else if (strcmp(*argv, "-alpn_server") == 0) {
54800422117Sjsing 			if (--argc < 1)
54900422117Sjsing 				goto bad;
55000422117Sjsing 			alpn_server = *(++argv);
55100422117Sjsing 		} else if (strcmp(*argv, "-alpn_expected") == 0) {
55200422117Sjsing 			if (--argc < 1)
55300422117Sjsing 				goto bad;
55400422117Sjsing 			alpn_expected = *(++argv);
55500422117Sjsing 		} else {
556e90e4cafSjsing 			fprintf(stderr, "unknown option %s\n", *argv);
557e90e4cafSjsing 			badop = 1;
558e90e4cafSjsing 			break;
559e90e4cafSjsing 		}
560e90e4cafSjsing 		argc--;
561e90e4cafSjsing 		argv++;
562e90e4cafSjsing 	}
563e90e4cafSjsing 	if (badop) {
564e90e4cafSjsing bad:
565e90e4cafSjsing 		sv_usage();
566e90e4cafSjsing 		goto end;
567e90e4cafSjsing 	}
568e90e4cafSjsing 
569521ba2f2Sbeck 	if (!dtls1_2 && !tls1 && !tls1_2 && number > 1 && !reuse && !force) {
570e90e4cafSjsing 		fprintf(stderr,
571e90e4cafSjsing 		    "This case cannot work.  Use -f to perform "
572e90e4cafSjsing 		    "the test anyway (and\n-d to see what happens), "
57317e2d200Sjsing 		    "or add one of -dtls1, -tls1, -tls1_2, -reuse\n"
574e90e4cafSjsing 		    "to avoid protocol mismatch.\n");
575e90e4cafSjsing 		exit(1);
576e90e4cafSjsing 	}
577e90e4cafSjsing 
578e90e4cafSjsing 	if (print_time) {
579e90e4cafSjsing 		if (!bio_pair) {
580e90e4cafSjsing 			fprintf(stderr, "Using BIO pair (-bio_pair)\n");
581e90e4cafSjsing 			bio_pair = 1;
582e90e4cafSjsing 		}
583e90e4cafSjsing 		if (number < 50 && !force)
584e90e4cafSjsing 			fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
585e90e4cafSjsing 	}
586e90e4cafSjsing 
587e90e4cafSjsing /*	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */
588e90e4cafSjsing 
589e90e4cafSjsing 	SSL_library_init();
590e90e4cafSjsing 	SSL_load_error_strings();
591e90e4cafSjsing 
592521ba2f2Sbeck 	if (dtls1_2)
593521ba2f2Sbeck 		meth = DTLSv1_2_method();
594c419fba1Sjsing 	else if (tls1)
595e90e4cafSjsing 		meth = TLSv1_method();
59617e2d200Sjsing 	else if (tls1_2)
59717e2d200Sjsing 		meth = TLSv1_2_method();
598e90e4cafSjsing 	else
59917e2d200Sjsing 		meth = TLS_method();
600e90e4cafSjsing 
601e90e4cafSjsing 	c_ctx = SSL_CTX_new(meth);
602e90e4cafSjsing 	s_ctx = SSL_CTX_new(meth);
603e90e4cafSjsing 	if ((c_ctx == NULL) || (s_ctx == NULL)) {
604e90e4cafSjsing 		ERR_print_errors(bio_err);
605e90e4cafSjsing 		goto end;
606e90e4cafSjsing 	}
607e90e4cafSjsing 
608517f1d0fStb 	SSL_CTX_set_security_level(c_ctx, seclevel);
609517f1d0fStb 	SSL_CTX_set_security_level(s_ctx, seclevel);
610517f1d0fStb 
611e90e4cafSjsing 	if (cipher != NULL) {
612e90e4cafSjsing 		SSL_CTX_set_cipher_list(c_ctx, cipher);
613e90e4cafSjsing 		SSL_CTX_set_cipher_list(s_ctx, cipher);
614e90e4cafSjsing 	}
615e90e4cafSjsing 
616e90e4cafSjsing 	if (!no_dhe) {
617e90e4cafSjsing 		if (dhe1024dsa) {
618e90e4cafSjsing 			/* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
619e90e4cafSjsing 			SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
620e90e4cafSjsing 			dh = get_dh1024dsa();
621855052a0Smiod 		} else
622e90e4cafSjsing 			dh = get_dh1024();
623e90e4cafSjsing 		SSL_CTX_set_tmp_dh(s_ctx, dh);
624e90e4cafSjsing 		DH_free(dh);
625e90e4cafSjsing 	}
626e90e4cafSjsing 
627e90e4cafSjsing 	if (!no_ecdhe) {
628e90e4cafSjsing 		int nid;
629e90e4cafSjsing 
630e90e4cafSjsing 		if (named_curve != NULL) {
631e90e4cafSjsing 			nid = OBJ_sn2nid(named_curve);
632e90e4cafSjsing 			if (nid == 0) {
633e90e4cafSjsing 				BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
634e90e4cafSjsing 				goto end;
635e90e4cafSjsing 			}
636e90e4cafSjsing 		} else
637e90e4cafSjsing 			nid = NID_X9_62_prime256v1;
638e90e4cafSjsing 
639e90e4cafSjsing 		ecdh = EC_KEY_new_by_curve_name(nid);
640e90e4cafSjsing 		if (ecdh == NULL) {
641e90e4cafSjsing 			BIO_printf(bio_err, "unable to create curve\n");
642e90e4cafSjsing 			goto end;
643e90e4cafSjsing 		}
644e90e4cafSjsing 
645e90e4cafSjsing 		SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
646e90e4cafSjsing 		SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
647e90e4cafSjsing 		EC_KEY_free(ecdh);
648e90e4cafSjsing 	}
649e90e4cafSjsing 
65057499507Stb 	if (!SSL_CTX_use_certificate_chain_file(s_ctx, server_cert)) {
651e90e4cafSjsing 		ERR_print_errors(bio_err);
652e90e4cafSjsing 	} else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
653e90e4cafSjsing 	    (server_key ? server_key : server_cert), SSL_FILETYPE_PEM)) {
654e90e4cafSjsing 		ERR_print_errors(bio_err);
655e90e4cafSjsing 		goto end;
656e90e4cafSjsing 	}
657e90e4cafSjsing 
658e90e4cafSjsing 	if (client_auth) {
65957499507Stb 		SSL_CTX_use_certificate_chain_file(c_ctx, client_cert);
660e90e4cafSjsing 		SSL_CTX_use_PrivateKey_file(c_ctx,
661e90e4cafSjsing 		    (client_key ? client_key : client_cert),
662e90e4cafSjsing 		    SSL_FILETYPE_PEM);
663e90e4cafSjsing 	}
664e90e4cafSjsing 
665e90e4cafSjsing 	if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) ||
666e90e4cafSjsing 	    (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
667e90e4cafSjsing 	    (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) ||
668e90e4cafSjsing 	    (!SSL_CTX_set_default_verify_paths(c_ctx))) {
669e90e4cafSjsing 		/* fprintf(stderr,"SSL_load_verify_locations\n"); */
670e90e4cafSjsing 		ERR_print_errors(bio_err);
671e90e4cafSjsing 		/* goto end; */
672e90e4cafSjsing 	}
673e90e4cafSjsing 
674e90e4cafSjsing 	if (client_auth) {
675e90e4cafSjsing 		BIO_printf(bio_err, "client authentication\n");
676e90e4cafSjsing 		SSL_CTX_set_verify(s_ctx,
677e90e4cafSjsing 		    SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
678e90e4cafSjsing 		    verify_callback);
6791b38a69bSjsing 		SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback,
680664ea9f8Stb 		    app_verify_arg);
681e90e4cafSjsing 	}
682e90e4cafSjsing 	if (server_auth) {
683e90e4cafSjsing 		BIO_printf(bio_err, "server authentication\n");
684e90e4cafSjsing 		SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER,
685e90e4cafSjsing 		    verify_callback);
6861b38a69bSjsing 		SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback,
687664ea9f8Stb 		    app_verify_arg);
688e90e4cafSjsing 	}
689e90e4cafSjsing 
690e90e4cafSjsing 	{
691e90e4cafSjsing 		int session_id_context = 0;
6921b38a69bSjsing 		SSL_CTX_set_session_id_context(s_ctx,
6931b38a69bSjsing 		    (void *)&session_id_context, sizeof(session_id_context));
694e90e4cafSjsing 	}
695e90e4cafSjsing 
69600422117Sjsing 	if (alpn_server != NULL)
69700422117Sjsing 		SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL);
69800422117Sjsing 
69900422117Sjsing 	if (alpn_client != NULL) {
70000422117Sjsing 		unsigned short alpn_len;
70100422117Sjsing 		unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client);
70200422117Sjsing 
70300422117Sjsing 		if (alpn == NULL) {
70400422117Sjsing 			BIO_printf(bio_err, "Error parsing -alpn_client argument\n");
70500422117Sjsing 			goto end;
70600422117Sjsing 		}
70700422117Sjsing 		SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len);
70800422117Sjsing 		free(alpn);
70900422117Sjsing 	}
71000422117Sjsing 
711e90e4cafSjsing 	c_ssl = SSL_new(c_ctx);
712e90e4cafSjsing 	s_ssl = SSL_new(s_ctx);
713e90e4cafSjsing 
714e90e4cafSjsing 	for (i = 0; i < number; i++) {
715e90e4cafSjsing 		if (!reuse)
716e90e4cafSjsing 			SSL_set_session(c_ssl, NULL);
7172287d13aStb #ifdef USE_BIOPAIR
718e90e4cafSjsing 		if (bio_pair)
7191b38a69bSjsing 			ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time,
7201b38a69bSjsing 			    &c_time);
721e90e4cafSjsing 		else
7222287d13aStb #endif
723e90e4cafSjsing 			ret = doit(s_ssl, c_ssl, bytes);
724e90e4cafSjsing 	}
725e90e4cafSjsing 
726e90e4cafSjsing 	if (!verbose) {
727e90e4cafSjsing 		print_details(c_ssl, "");
728e90e4cafSjsing 	}
729e90e4cafSjsing 	if ((number > 1) || (bytes > 1L))
7301b38a69bSjsing 		BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",
7311b38a69bSjsing 		    number, bytes);
732e90e4cafSjsing 	if (print_time) {
733e90e4cafSjsing #ifdef CLOCKS_PER_SEC
734e90e4cafSjsing 		/* "To determine the time in seconds, the value returned
735e90e4cafSjsing 		 * by the clock function should be divided by the value
736e90e4cafSjsing 		 * of the macro CLOCKS_PER_SEC."
737e90e4cafSjsing 		 *                                       -- ISO/IEC 9899 */
7381b38a69bSjsing 		BIO_printf(bio_stdout,
7391b38a69bSjsing 		    "Approximate total server time: %6.2f s\n"
740e90e4cafSjsing 		    "Approximate total client time: %6.2f s\n",
741e90e4cafSjsing 		    (double)s_time/CLOCKS_PER_SEC,
742e90e4cafSjsing 		    (double)c_time/CLOCKS_PER_SEC);
743e90e4cafSjsing #else
744e90e4cafSjsing 		/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
745e90e4cafSjsing 		 *                            -- cc on NeXTstep/OpenStep */
746e90e4cafSjsing 		BIO_printf(bio_stdout,
747e90e4cafSjsing 		    "Approximate total server time: %6.2f units\n"
748e90e4cafSjsing 		    "Approximate total client time: %6.2f units\n",
749e90e4cafSjsing 		    (double)s_time,
750e90e4cafSjsing 		    (double)c_time);
751e90e4cafSjsing #endif
752e90e4cafSjsing 	}
753e90e4cafSjsing 
754e90e4cafSjsing 	SSL_free(s_ssl);
755e90e4cafSjsing 	SSL_free(c_ssl);
756e90e4cafSjsing 
757e90e4cafSjsing end:
758e90e4cafSjsing 	SSL_CTX_free(s_ctx);
759e90e4cafSjsing 	SSL_CTX_free(c_ctx);
760e90e4cafSjsing 	BIO_free(bio_stdout);
761e90e4cafSjsing 
762e90e4cafSjsing 	CRYPTO_cleanup_all_ex_data();
763e90e4cafSjsing 	ERR_free_strings();
764e90e4cafSjsing 	ERR_remove_thread_state(NULL);
765e90e4cafSjsing 	EVP_cleanup();
766e90e4cafSjsing 	BIO_free(bio_err);
7677503bb1fSjsing 
768e90e4cafSjsing 	exit(ret);
769e90e4cafSjsing 	return ret;
770e90e4cafSjsing }
771e90e4cafSjsing 
7722287d13aStb #if USE_BIOPAIR
773e90e4cafSjsing int
doit_biopair(SSL * s_ssl,SSL * c_ssl,long count,clock_t * s_time,clock_t * c_time)774e90e4cafSjsing doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time,
775e90e4cafSjsing     clock_t *c_time)
776e90e4cafSjsing {
777e90e4cafSjsing 	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
778e90e4cafSjsing 	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
7791b38a69bSjsing 	BIO *server = NULL, *server_io = NULL;
7801b38a69bSjsing 	BIO *client = NULL, *client_io = NULL;
781e90e4cafSjsing 	int ret = 1;
782e90e4cafSjsing 
783e90e4cafSjsing 	size_t bufsiz = 256; /* small buffer for testing */
784e90e4cafSjsing 
785e90e4cafSjsing 	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
786e90e4cafSjsing 		goto err;
787e90e4cafSjsing 	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
788e90e4cafSjsing 		goto err;
789e90e4cafSjsing 
790e90e4cafSjsing 	s_ssl_bio = BIO_new(BIO_f_ssl());
791e90e4cafSjsing 	if (!s_ssl_bio)
792e90e4cafSjsing 		goto err;
793e90e4cafSjsing 
794e90e4cafSjsing 	c_ssl_bio = BIO_new(BIO_f_ssl());
795e90e4cafSjsing 	if (!c_ssl_bio)
796e90e4cafSjsing 		goto err;
797e90e4cafSjsing 
798e90e4cafSjsing 	SSL_set_connect_state(c_ssl);
799e90e4cafSjsing 	SSL_set_bio(c_ssl, client, client);
800e90e4cafSjsing 	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);
801e90e4cafSjsing 
802e90e4cafSjsing 	SSL_set_accept_state(s_ssl);
803e90e4cafSjsing 	SSL_set_bio(s_ssl, server, server);
804e90e4cafSjsing 	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);
805e90e4cafSjsing 
806e90e4cafSjsing 	do {
807e90e4cafSjsing 		/* c_ssl_bio:          SSL filter BIO
808e90e4cafSjsing 		 *
809e90e4cafSjsing 		 * client:             pseudo-I/O for SSL library
810e90e4cafSjsing 		 *
811e90e4cafSjsing 		 * client_io:          client's SSL communication; usually to be
812e90e4cafSjsing 		 *                     relayed over some I/O facility, but in this
813e90e4cafSjsing 		 *                     test program, we're the server, too:
814e90e4cafSjsing 		 *
815e90e4cafSjsing 		 * server_io:          server's SSL communication
816e90e4cafSjsing 		 *
817e90e4cafSjsing 		 * server:             pseudo-I/O for SSL library
818e90e4cafSjsing 		 *
819e90e4cafSjsing 		 * s_ssl_bio:          SSL filter BIO
820e90e4cafSjsing 		 *
821e90e4cafSjsing 		 * The client and the server each employ a "BIO pair":
822e90e4cafSjsing 		 * client + client_io, server + server_io.
823e90e4cafSjsing 		 * BIO pairs are symmetric.  A BIO pair behaves similar
824e90e4cafSjsing 		 * to a non-blocking socketpair (but both endpoints must
825e90e4cafSjsing 		 * be handled by the same thread).
826e90e4cafSjsing 		 * [Here we could connect client and server to the ends
827e90e4cafSjsing 		 * of a single BIO pair, but then this code would be less
828e90e4cafSjsing 		 * suitable as an example for BIO pairs in general.]
829e90e4cafSjsing 		 *
830e90e4cafSjsing 		 * Useful functions for querying the state of BIO pair endpoints:
831e90e4cafSjsing 		 *
832e90e4cafSjsing 		 * BIO_ctrl_pending(bio)              number of bytes we can read now
833e90e4cafSjsing 		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
834e90e4cafSjsing 		 *                                      other side's read attempt
835e90e4cafSjsing 		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
836e90e4cafSjsing 		 *
837e90e4cafSjsing 		 * ..._read_request is never more than ..._write_guarantee;
838e90e4cafSjsing 		 * it depends on the application which one you should use.
839e90e4cafSjsing 		 */
840e90e4cafSjsing 
841e90e4cafSjsing 		/* We have non-blocking behaviour throughout this test program, but
842e90e4cafSjsing 		 * can be sure that there is *some* progress in each iteration; so
843e90e4cafSjsing 		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
844e90e4cafSjsing 		 * -- we just try everything in each iteration
845e90e4cafSjsing 		 */
846e90e4cafSjsing 
847e90e4cafSjsing 		{
848e90e4cafSjsing 			/* CLIENT */
849e90e4cafSjsing 
850e90e4cafSjsing 			char cbuf[1024*8];
851e90e4cafSjsing 			int i, r;
852e90e4cafSjsing 			clock_t c_clock = clock();
853e90e4cafSjsing 
854e90e4cafSjsing 			memset(cbuf, 0, sizeof(cbuf));
855e90e4cafSjsing 
856e90e4cafSjsing 			if (debug)
857e90e4cafSjsing 				if (SSL_in_init(c_ssl))
858e90e4cafSjsing 					printf("client waiting in SSL_connect - %s\n",
859e90e4cafSjsing 					    SSL_state_string_long(c_ssl));
860e90e4cafSjsing 
861e90e4cafSjsing 			if (cw_num > 0) {
862e90e4cafSjsing 				/* Write to server. */
863e90e4cafSjsing 
864e90e4cafSjsing 				if (cw_num > (long)sizeof cbuf)
865e90e4cafSjsing 					i = sizeof cbuf;
866e90e4cafSjsing 				else
867e90e4cafSjsing 					i = (int)cw_num;
868e90e4cafSjsing 				r = BIO_write(c_ssl_bio, cbuf, i);
869e90e4cafSjsing 				if (r < 0) {
870e90e4cafSjsing 					if (!BIO_should_retry(c_ssl_bio)) {
871e90e4cafSjsing 						fprintf(stderr, "ERROR in CLIENT\n");
872e90e4cafSjsing 						goto err;
873e90e4cafSjsing 					}
874e90e4cafSjsing 					/* BIO_should_retry(...) can just be ignored here.
875e90e4cafSjsing 					 * The library expects us to call BIO_write with
876e90e4cafSjsing 					 * the same arguments again, and that's what we will
877e90e4cafSjsing 					 * do in the next iteration. */
878e90e4cafSjsing 				} else if (r == 0) {
879e90e4cafSjsing 					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
880e90e4cafSjsing 					goto err;
881e90e4cafSjsing 				} else {
882e90e4cafSjsing 					if (debug)
883e90e4cafSjsing 						printf("client wrote %d\n", r);
884e90e4cafSjsing 					cw_num -= r;
885e90e4cafSjsing 
886e90e4cafSjsing 				}
887e90e4cafSjsing 			}
888e90e4cafSjsing 
889e90e4cafSjsing 			if (cr_num > 0) {
890e90e4cafSjsing 				/* Read from server. */
891e90e4cafSjsing 
892e90e4cafSjsing 				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
893e90e4cafSjsing 				if (r < 0) {
894e90e4cafSjsing 					if (!BIO_should_retry(c_ssl_bio)) {
895e90e4cafSjsing 						fprintf(stderr, "ERROR in CLIENT\n");
896e90e4cafSjsing 						goto err;
897e90e4cafSjsing 					}
898e90e4cafSjsing 					/* Again, "BIO_should_retry" can be ignored. */
899e90e4cafSjsing 				} else if (r == 0) {
900e90e4cafSjsing 					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
901e90e4cafSjsing 					goto err;
902e90e4cafSjsing 				} else {
903e90e4cafSjsing 					if (debug)
904e90e4cafSjsing 						printf("client read %d\n", r);
905e90e4cafSjsing 					cr_num -= r;
906e90e4cafSjsing 				}
907e90e4cafSjsing 			}
908e90e4cafSjsing 
909e90e4cafSjsing 			/* c_time and s_time increments will typically be very small
910e90e4cafSjsing 			 * (depending on machine speed and clock tick intervals),
911e90e4cafSjsing 			 * but sampling over a large number of connections should
912e90e4cafSjsing 			 * result in fairly accurate figures.  We cannot guarantee
913e90e4cafSjsing 			 * a lot, however -- if each connection lasts for exactly
914e90e4cafSjsing 			 * one clock tick, it will be counted only for the client
915e90e4cafSjsing 			 * or only for the server or even not at all.
916e90e4cafSjsing 			 */
917e90e4cafSjsing 			*c_time += (clock() - c_clock);
918e90e4cafSjsing 		}
919e90e4cafSjsing 
920e90e4cafSjsing 		{
921e90e4cafSjsing 			/* SERVER */
922e90e4cafSjsing 
923e90e4cafSjsing 			char sbuf[1024*8];
924e90e4cafSjsing 			int i, r;
925e90e4cafSjsing 			clock_t s_clock = clock();
926e90e4cafSjsing 
927e90e4cafSjsing 			memset(sbuf, 0, sizeof(sbuf));
928e90e4cafSjsing 
929e90e4cafSjsing 			if (debug)
930e90e4cafSjsing 				if (SSL_in_init(s_ssl))
931e90e4cafSjsing 					printf("server waiting in SSL_accept - %s\n",
932e90e4cafSjsing 					    SSL_state_string_long(s_ssl));
933e90e4cafSjsing 
934e90e4cafSjsing 			if (sw_num > 0) {
935e90e4cafSjsing 				/* Write to client. */
936e90e4cafSjsing 
937e90e4cafSjsing 				if (sw_num > (long)sizeof sbuf)
938e90e4cafSjsing 					i = sizeof sbuf;
939e90e4cafSjsing 				else
940e90e4cafSjsing 					i = (int)sw_num;
941e90e4cafSjsing 				r = BIO_write(s_ssl_bio, sbuf, i);
942e90e4cafSjsing 				if (r < 0) {
943e90e4cafSjsing 					if (!BIO_should_retry(s_ssl_bio)) {
944e90e4cafSjsing 						fprintf(stderr, "ERROR in SERVER\n");
945e90e4cafSjsing 						goto err;
946e90e4cafSjsing 					}
947e90e4cafSjsing 					/* Ignore "BIO_should_retry". */
948e90e4cafSjsing 				} else if (r == 0) {
949e90e4cafSjsing 					fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
950e90e4cafSjsing 					goto err;
951e90e4cafSjsing 				} else {
952e90e4cafSjsing 					if (debug)
953e90e4cafSjsing 						printf("server wrote %d\n", r);
954e90e4cafSjsing 					sw_num -= r;
955e90e4cafSjsing 
956e90e4cafSjsing 				}
957e90e4cafSjsing 			}
958e90e4cafSjsing 
959e90e4cafSjsing 			if (sr_num > 0) {
960e90e4cafSjsing 				/* Read from client. */
961e90e4cafSjsing 
962e90e4cafSjsing 				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
963e90e4cafSjsing 				if (r < 0) {
964e90e4cafSjsing 					if (!BIO_should_retry(s_ssl_bio)) {
965e90e4cafSjsing 						fprintf(stderr, "ERROR in SERVER\n");
966e90e4cafSjsing 						goto err;
967e90e4cafSjsing 					}
968e90e4cafSjsing 					/* blah, blah */
969e90e4cafSjsing 				} else if (r == 0) {
970e90e4cafSjsing 					fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
971e90e4cafSjsing 					goto err;
972e90e4cafSjsing 				} else {
973e90e4cafSjsing 					if (debug)
974e90e4cafSjsing 						printf("server read %d\n", r);
975e90e4cafSjsing 					sr_num -= r;
976e90e4cafSjsing 				}
977e90e4cafSjsing 			}
978e90e4cafSjsing 
979e90e4cafSjsing 			*s_time += (clock() - s_clock);
980e90e4cafSjsing 		}
981e90e4cafSjsing 
982e90e4cafSjsing 		{
983e90e4cafSjsing 			/* "I/O" BETWEEN CLIENT AND SERVER. */
984e90e4cafSjsing 
985e90e4cafSjsing 			size_t r1, r2;
986e90e4cafSjsing 			BIO *io1 = server_io, *io2 = client_io;
987e90e4cafSjsing 			/* we use the non-copying interface for io1
988e90e4cafSjsing 			 * and the standard BIO_write/BIO_read interface for io2
989e90e4cafSjsing 			 */
990e90e4cafSjsing 
991e90e4cafSjsing 			static int prev_progress = 1;
992e90e4cafSjsing 			int progress = 0;
993e90e4cafSjsing 
994e90e4cafSjsing 			/* io1 to io2 */
9951b38a69bSjsing 			do {
996e90e4cafSjsing 				size_t num;
997e90e4cafSjsing 				int r;
998e90e4cafSjsing 
999e90e4cafSjsing 				r1 = BIO_ctrl_pending(io1);
1000e90e4cafSjsing 				r2 = BIO_ctrl_get_write_guarantee(io2);
1001e90e4cafSjsing 
1002e90e4cafSjsing 				num = r1;
1003e90e4cafSjsing 				if (r2 < num)
1004e90e4cafSjsing 					num = r2;
1005e90e4cafSjsing 				if (num) {
1006e90e4cafSjsing 					char *dataptr;
1007e90e4cafSjsing 
1008e90e4cafSjsing 					if (INT_MAX < num) /* yeah, right */
1009e90e4cafSjsing 						num = INT_MAX;
1010e90e4cafSjsing 
1011e90e4cafSjsing 					r = BIO_nread(io1, &dataptr, (int)num);
1012e90e4cafSjsing 					assert(r > 0);
1013e90e4cafSjsing 					assert(r <= (int)num);
1014e90e4cafSjsing 					/* possibly r < num (non-contiguous data) */
1015e90e4cafSjsing 					num = r;
1016e90e4cafSjsing 					r = BIO_write(io2, dataptr, (int)num);
1017e90e4cafSjsing 					if (r != (int)num) /* can't happen */
1018e90e4cafSjsing 					{
1019e90e4cafSjsing 						fprintf(stderr, "ERROR: BIO_write could not write "
1020e90e4cafSjsing 						    "BIO_ctrl_get_write_guarantee() bytes");
1021e90e4cafSjsing 						goto err;
1022e90e4cafSjsing 					}
1023e90e4cafSjsing 					progress = 1;
1024e90e4cafSjsing 
1025e90e4cafSjsing 					if (debug)
1026e90e4cafSjsing 						printf((io1 == client_io) ?
1027e90e4cafSjsing 						    "C->S relaying: %d bytes\n" :
1028e90e4cafSjsing 						    "S->C relaying: %d bytes\n",
1029e90e4cafSjsing 						    (int)num);
1030e90e4cafSjsing 				}
1031e90e4cafSjsing 			} while (r1 && r2);
1032e90e4cafSjsing 
1033e90e4cafSjsing 			/* io2 to io1 */
1034e90e4cafSjsing 			{
1035e90e4cafSjsing 				size_t num;
1036e90e4cafSjsing 				int r;
1037e90e4cafSjsing 
1038e90e4cafSjsing 				r1 = BIO_ctrl_pending(io2);
1039e90e4cafSjsing 				r2 = BIO_ctrl_get_read_request(io1);
1040e90e4cafSjsing 				/* here we could use ..._get_write_guarantee instead of
1041e90e4cafSjsing 				 * ..._get_read_request, but by using the latter
1042e90e4cafSjsing 				 * we test restartability of the SSL implementation
1043e90e4cafSjsing 				 * more thoroughly */
1044e90e4cafSjsing 				num = r1;
1045e90e4cafSjsing 				if (r2 < num)
1046e90e4cafSjsing 					num = r2;
1047e90e4cafSjsing 				if (num) {
1048e90e4cafSjsing 					char *dataptr;
1049e90e4cafSjsing 
1050e90e4cafSjsing 					if (INT_MAX < num)
1051e90e4cafSjsing 						num = INT_MAX;
1052e90e4cafSjsing 
1053e90e4cafSjsing 					if (num > 1)
1054e90e4cafSjsing 						--num; /* test restartability even more thoroughly */
1055e90e4cafSjsing 
1056e90e4cafSjsing 					r = BIO_nwrite0(io1, &dataptr);
1057e90e4cafSjsing 					assert(r > 0);
1058e90e4cafSjsing 					if (r < (int)num)
1059e90e4cafSjsing 						num = r;
1060e90e4cafSjsing 					r = BIO_read(io2, dataptr, (int)num);
1061e90e4cafSjsing 					if (r != (int)num) /* can't happen */
1062e90e4cafSjsing 					{
1063e90e4cafSjsing 						fprintf(stderr, "ERROR: BIO_read could not read "
1064e90e4cafSjsing 						    "BIO_ctrl_pending() bytes");
1065e90e4cafSjsing 						goto err;
1066e90e4cafSjsing 					}
1067e90e4cafSjsing 					progress = 1;
1068e90e4cafSjsing 					r = BIO_nwrite(io1, &dataptr, (int)num);
1069e90e4cafSjsing 					if (r != (int)num) /* can't happen */
1070e90e4cafSjsing 					{
1071e90e4cafSjsing 						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
1072e90e4cafSjsing 						    "BIO_nwrite0() bytes");
1073e90e4cafSjsing 						goto err;
1074e90e4cafSjsing 					}
1075e90e4cafSjsing 
1076e90e4cafSjsing 					if (debug)
1077e90e4cafSjsing 						printf((io2 == client_io) ?
1078e90e4cafSjsing 						    "C->S relaying: %d bytes\n" :
1079e90e4cafSjsing 						    "S->C relaying: %d bytes\n",
1080e90e4cafSjsing 						    (int)num);
1081e90e4cafSjsing 				}
1082e90e4cafSjsing 			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */
1083e90e4cafSjsing 
1084154f950aSjsing 			if (!progress && !prev_progress) {
1085e90e4cafSjsing 				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) {
1086e90e4cafSjsing 					fprintf(stderr, "ERROR: got stuck\n");
1087e90e4cafSjsing 					goto err;
1088e90e4cafSjsing 				}
1089154f950aSjsing 			}
1090e90e4cafSjsing 			prev_progress = progress;
1091e90e4cafSjsing 		}
1092e90e4cafSjsing 	} while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);
1093e90e4cafSjsing 
1094e90e4cafSjsing 	if (verbose)
1095e90e4cafSjsing 		print_details(c_ssl, "DONE via BIO pair: ");
10962011c60cSjsing 
109700422117Sjsing 	if (verify_alpn(c_ssl, s_ssl) < 0) {
109800422117Sjsing 		ret = 1;
109900422117Sjsing 		goto err;
110000422117Sjsing 	}
11012011c60cSjsing 
1102e90e4cafSjsing 	ret = 0;
1103e90e4cafSjsing 
1104e90e4cafSjsing err:
1105e90e4cafSjsing 	ERR_print_errors(bio_err);
1106e90e4cafSjsing 
1107e90e4cafSjsing 	BIO_free(server);
1108e90e4cafSjsing 	BIO_free(server_io);
1109e90e4cafSjsing 	BIO_free(client);
1110e90e4cafSjsing 	BIO_free(client_io);
1111e90e4cafSjsing 	BIO_free(s_ssl_bio);
1112e90e4cafSjsing 	BIO_free(c_ssl_bio);
1113e90e4cafSjsing 
1114e90e4cafSjsing 	return ret;
1115e90e4cafSjsing }
11162287d13aStb #endif
1117e90e4cafSjsing 
1118e90e4cafSjsing 
1119e90e4cafSjsing #define W_READ	1
1120e90e4cafSjsing #define W_WRITE	2
1121e90e4cafSjsing #define C_DONE	1
1122e90e4cafSjsing #define S_DONE	2
1123e90e4cafSjsing 
1124e90e4cafSjsing int
doit(SSL * s_ssl,SSL * c_ssl,long count)1125e90e4cafSjsing doit(SSL *s_ssl, SSL *c_ssl, long count)
1126e90e4cafSjsing {
1127e90e4cafSjsing 	char cbuf[1024*8], sbuf[1024*8];
1128e90e4cafSjsing 	long cw_num = count, cr_num = count;
1129e90e4cafSjsing 	long sw_num = count, sr_num = count;
1130e90e4cafSjsing 	int ret = 1;
1131e90e4cafSjsing 	BIO *c_to_s = NULL;
1132e90e4cafSjsing 	BIO *s_to_c = NULL;
1133e90e4cafSjsing 	BIO *c_bio = NULL;
1134e90e4cafSjsing 	BIO *s_bio = NULL;
1135e90e4cafSjsing 	int c_r, c_w, s_r, s_w;
1136e90e4cafSjsing 	int i, j;
1137e90e4cafSjsing 	int done = 0;
1138e90e4cafSjsing 	int c_write, s_write;
1139e90e4cafSjsing 	int do_server = 0, do_client = 0;
1140e90e4cafSjsing 
1141e90e4cafSjsing 	memset(cbuf, 0, sizeof(cbuf));
1142e90e4cafSjsing 	memset(sbuf, 0, sizeof(sbuf));
1143e90e4cafSjsing 
1144e90e4cafSjsing 	c_to_s = BIO_new(BIO_s_mem());
1145e90e4cafSjsing 	s_to_c = BIO_new(BIO_s_mem());
1146e90e4cafSjsing 	if ((s_to_c == NULL) || (c_to_s == NULL)) {
1147e90e4cafSjsing 		ERR_print_errors(bio_err);
1148e90e4cafSjsing 		goto err;
1149e90e4cafSjsing 	}
1150e90e4cafSjsing 
1151e90e4cafSjsing 	c_bio = BIO_new(BIO_f_ssl());
1152e90e4cafSjsing 	s_bio = BIO_new(BIO_f_ssl());
1153e90e4cafSjsing 	if ((c_bio == NULL) || (s_bio == NULL)) {
1154e90e4cafSjsing 		ERR_print_errors(bio_err);
1155e90e4cafSjsing 		goto err;
1156e90e4cafSjsing 	}
1157e90e4cafSjsing 
1158e90e4cafSjsing 	SSL_set_connect_state(c_ssl);
1159e90e4cafSjsing 	SSL_set_bio(c_ssl, s_to_c, c_to_s);
1160e90e4cafSjsing 	BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE);
1161e90e4cafSjsing 
1162e90e4cafSjsing 	SSL_set_accept_state(s_ssl);
1163e90e4cafSjsing 	SSL_set_bio(s_ssl, c_to_s, s_to_c);
1164e90e4cafSjsing 	BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE);
1165e90e4cafSjsing 
1166e90e4cafSjsing 	c_r = 0;
1167e90e4cafSjsing 	s_r = 1;
1168e90e4cafSjsing 	c_w = 1;
1169e90e4cafSjsing 	s_w = 0;
1170e90e4cafSjsing 	c_write = 1, s_write = 0;
1171e90e4cafSjsing 
1172e90e4cafSjsing 	/* We can always do writes */
1173e90e4cafSjsing 	for (;;) {
1174e90e4cafSjsing 		do_server = 0;
1175e90e4cafSjsing 		do_client = 0;
1176e90e4cafSjsing 
1177e90e4cafSjsing 		i = (int)BIO_pending(s_bio);
1178e90e4cafSjsing 		if ((i && s_r) || s_w)
1179e90e4cafSjsing 			do_server = 1;
1180e90e4cafSjsing 
1181e90e4cafSjsing 		i = (int)BIO_pending(c_bio);
1182e90e4cafSjsing 		if ((i && c_r) || c_w)
1183e90e4cafSjsing 			do_client = 1;
1184e90e4cafSjsing 
1185e90e4cafSjsing 		if (do_server && debug) {
1186e90e4cafSjsing 			if (SSL_in_init(s_ssl))
1187e90e4cafSjsing 				printf("server waiting in SSL_accept - %s\n",
1188e90e4cafSjsing 				    SSL_state_string_long(s_ssl));
1189e90e4cafSjsing 		}
1190e90e4cafSjsing 
1191e90e4cafSjsing 		if (do_client && debug) {
1192e90e4cafSjsing 			if (SSL_in_init(c_ssl))
1193e90e4cafSjsing 				printf("client waiting in SSL_connect - %s\n",
1194e90e4cafSjsing 				    SSL_state_string_long(c_ssl));
1195e90e4cafSjsing 		}
1196e90e4cafSjsing 
1197e90e4cafSjsing 		if (!do_client && !do_server) {
1198b963adf1Sjsing 			fprintf(stdout, "ERROR in STARTUP\n");
1199e90e4cafSjsing 			ERR_print_errors(bio_err);
1200b963adf1Sjsing 			goto err;
1201e90e4cafSjsing 		}
120293b15c7eSjsing 
1203e90e4cafSjsing 		if (do_client && !(done & C_DONE)) {
1204e90e4cafSjsing 			if (c_write) {
1205e90e4cafSjsing 				j = (cw_num > (long)sizeof(cbuf)) ?
1206e90e4cafSjsing 				    (int)sizeof(cbuf) : (int)cw_num;
1207e90e4cafSjsing 				i = BIO_write(c_bio, cbuf, j);
1208e90e4cafSjsing 				if (i < 0) {
1209e90e4cafSjsing 					c_r = 0;
1210e90e4cafSjsing 					c_w = 0;
1211e90e4cafSjsing 					if (BIO_should_retry(c_bio)) {
1212e90e4cafSjsing 						if (BIO_should_read(c_bio))
1213e90e4cafSjsing 							c_r = 1;
1214e90e4cafSjsing 						if (BIO_should_write(c_bio))
1215e90e4cafSjsing 							c_w = 1;
1216e90e4cafSjsing 					} else {
1217e90e4cafSjsing 						fprintf(stderr, "ERROR in CLIENT\n");
1218e90e4cafSjsing 						ERR_print_errors(bio_err);
1219e90e4cafSjsing 						goto err;
1220e90e4cafSjsing 					}
1221e90e4cafSjsing 				} else if (i == 0) {
1222e90e4cafSjsing 					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1223e90e4cafSjsing 					goto err;
1224e90e4cafSjsing 				} else {
1225e90e4cafSjsing 					if (debug)
1226e90e4cafSjsing 						printf("client wrote %d\n", i);
1227e90e4cafSjsing 					/* ok */
1228e90e4cafSjsing 					s_r = 1;
1229e90e4cafSjsing 					c_write = 0;
1230e90e4cafSjsing 					cw_num -= i;
1231e90e4cafSjsing 				}
1232e90e4cafSjsing 			} else {
1233e90e4cafSjsing 				i = BIO_read(c_bio, cbuf, sizeof(cbuf));
1234e90e4cafSjsing 				if (i < 0) {
1235e90e4cafSjsing 					c_r = 0;
1236e90e4cafSjsing 					c_w = 0;
1237e90e4cafSjsing 					if (BIO_should_retry(c_bio)) {
1238e90e4cafSjsing 						if (BIO_should_read(c_bio))
1239e90e4cafSjsing 							c_r = 1;
1240e90e4cafSjsing 						if (BIO_should_write(c_bio))
1241e90e4cafSjsing 							c_w = 1;
1242e90e4cafSjsing 					} else {
1243e90e4cafSjsing 						fprintf(stderr, "ERROR in CLIENT\n");
1244e90e4cafSjsing 						ERR_print_errors(bio_err);
1245e90e4cafSjsing 						goto err;
1246e90e4cafSjsing 					}
1247e90e4cafSjsing 				} else if (i == 0) {
1248e90e4cafSjsing 					fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
1249e90e4cafSjsing 					goto err;
1250e90e4cafSjsing 				} else {
1251e90e4cafSjsing 					if (debug)
1252e90e4cafSjsing 						printf("client read %d\n", i);
1253e90e4cafSjsing 					cr_num -= i;
1254e90e4cafSjsing 					if (sw_num > 0) {
1255e90e4cafSjsing 						s_write = 1;
1256e90e4cafSjsing 						s_w = 1;
1257e90e4cafSjsing 					}
1258e90e4cafSjsing 					if (cr_num <= 0) {
1259e90e4cafSjsing 						s_write = 1;
1260e90e4cafSjsing 						s_w = 1;
1261e90e4cafSjsing 						done = S_DONE|C_DONE;
1262e90e4cafSjsing 					}
1263e90e4cafSjsing 				}
1264e90e4cafSjsing 			}
1265e90e4cafSjsing 		}
1266e90e4cafSjsing 
1267e90e4cafSjsing 		if (do_server && !(done & S_DONE)) {
1268e90e4cafSjsing 			if (!s_write) {
1269e90e4cafSjsing 				i = BIO_read(s_bio, sbuf, sizeof(cbuf));
1270e90e4cafSjsing 				if (i < 0) {
1271e90e4cafSjsing 					s_r = 0;
1272e90e4cafSjsing 					s_w = 0;
1273e90e4cafSjsing 					if (BIO_should_retry(s_bio)) {
1274e90e4cafSjsing 						if (BIO_should_read(s_bio))
1275e90e4cafSjsing 							s_r = 1;
1276e90e4cafSjsing 						if (BIO_should_write(s_bio))
1277e90e4cafSjsing 							s_w = 1;
1278e90e4cafSjsing 					} else {
1279e90e4cafSjsing 						fprintf(stderr, "ERROR in SERVER\n");
1280e90e4cafSjsing 						ERR_print_errors(bio_err);
1281e90e4cafSjsing 						goto err;
1282e90e4cafSjsing 					}
1283e90e4cafSjsing 				} else if (i == 0) {
1284e90e4cafSjsing 					ERR_print_errors(bio_err);
1285e90e4cafSjsing 					fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_read\n");
1286e90e4cafSjsing 					goto err;
1287e90e4cafSjsing 				} else {
1288e90e4cafSjsing 					if (debug)
1289e90e4cafSjsing 						printf("server read %d\n", i);
1290e90e4cafSjsing 					sr_num -= i;
1291e90e4cafSjsing 					if (cw_num > 0) {
1292e90e4cafSjsing 						c_write = 1;
1293e90e4cafSjsing 						c_w = 1;
1294e90e4cafSjsing 					}
1295e90e4cafSjsing 					if (sr_num <= 0) {
1296e90e4cafSjsing 						s_write = 1;
1297e90e4cafSjsing 						s_w = 1;
1298e90e4cafSjsing 						c_write = 0;
1299e90e4cafSjsing 					}
1300e90e4cafSjsing 				}
1301e90e4cafSjsing 			} else {
1302e90e4cafSjsing 				j = (sw_num > (long)sizeof(sbuf)) ?
1303e90e4cafSjsing 				    (int)sizeof(sbuf) : (int)sw_num;
1304e90e4cafSjsing 				i = BIO_write(s_bio, sbuf, j);
1305e90e4cafSjsing 				if (i < 0) {
1306e90e4cafSjsing 					s_r = 0;
1307e90e4cafSjsing 					s_w = 0;
1308e90e4cafSjsing 					if (BIO_should_retry(s_bio)) {
1309e90e4cafSjsing 						if (BIO_should_read(s_bio))
1310e90e4cafSjsing 							s_r = 1;
1311e90e4cafSjsing 						if (BIO_should_write(s_bio))
1312e90e4cafSjsing 							s_w = 1;
1313e90e4cafSjsing 					} else {
1314e90e4cafSjsing 						fprintf(stderr, "ERROR in SERVER\n");
1315e90e4cafSjsing 						ERR_print_errors(bio_err);
1316e90e4cafSjsing 						goto err;
1317e90e4cafSjsing 					}
1318e90e4cafSjsing 				} else if (i == 0) {
1319e90e4cafSjsing 					ERR_print_errors(bio_err);
1320e90e4cafSjsing 					fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_write\n");
1321e90e4cafSjsing 					goto err;
1322e90e4cafSjsing 				} else {
1323e90e4cafSjsing 					if (debug)
1324e90e4cafSjsing 						printf("server wrote %d\n", i);
1325e90e4cafSjsing 					sw_num -= i;
1326e90e4cafSjsing 					s_write = 0;
1327e90e4cafSjsing 					c_r = 1;
1328e90e4cafSjsing 					if (sw_num <= 0)
1329e90e4cafSjsing 						done |= S_DONE;
1330e90e4cafSjsing 				}
1331e90e4cafSjsing 			}
1332e90e4cafSjsing 		}
1333e90e4cafSjsing 
13341b38a69bSjsing 		if ((done & S_DONE) && (done & C_DONE))
13351b38a69bSjsing 			break;
1336e90e4cafSjsing 	}
1337e90e4cafSjsing 
1338e90e4cafSjsing 	if (verbose)
1339e90e4cafSjsing 		print_details(c_ssl, "DONE: ");
13402011c60cSjsing 
134100422117Sjsing 	if (verify_alpn(c_ssl, s_ssl) < 0) {
134200422117Sjsing 		ret = 1;
134300422117Sjsing 		goto err;
134400422117Sjsing 	}
13452011c60cSjsing 
1346e90e4cafSjsing 	ret = 0;
1347e90e4cafSjsing err:
1348e90e4cafSjsing 	/* We have to set the BIO's to NULL otherwise they will be
1349e90e4cafSjsing 	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
1350e90e4cafSjsing 	 * again when c_ssl is SSL_free()ed.
1351e90e4cafSjsing 	 * This is a hack required because s_ssl and c_ssl are sharing the same
1352e90e4cafSjsing 	 * BIO structure and SSL_set_bio() and SSL_free() automatically
1353e90e4cafSjsing 	 * BIO_free non NULL entries.
1354e90e4cafSjsing 	 * You should not normally do this or be required to do this */
1355e90e4cafSjsing 	if (s_ssl != NULL) {
1356e90e4cafSjsing 		s_ssl->rbio = NULL;
1357e90e4cafSjsing 		s_ssl->wbio = NULL;
1358e90e4cafSjsing 	}
1359e90e4cafSjsing 	if (c_ssl != NULL) {
1360e90e4cafSjsing 		c_ssl->rbio = NULL;
1361e90e4cafSjsing 		c_ssl->wbio = NULL;
1362e90e4cafSjsing 	}
1363e90e4cafSjsing 
1364e90e4cafSjsing 	BIO_free(c_to_s);
1365e90e4cafSjsing 	BIO_free(s_to_c);
1366e90e4cafSjsing 	BIO_free_all(c_bio);
1367e90e4cafSjsing 	BIO_free_all(s_bio);
13687503bb1fSjsing 
1369e90e4cafSjsing 	return (ret);
1370e90e4cafSjsing }
1371e90e4cafSjsing 
1372e90e4cafSjsing static int
verify_callback(int ok,X509_STORE_CTX * ctx)1373e90e4cafSjsing verify_callback(int ok, X509_STORE_CTX *ctx)
1374e90e4cafSjsing {
1375f70a35c1Stb 	X509 *xs;
1376e90e4cafSjsing 	char *s, buf[256];
1377f70a35c1Stb 	int error, error_depth;
1378e90e4cafSjsing 
1379f70a35c1Stb 	xs = X509_STORE_CTX_get_current_cert(ctx);
1380f70a35c1Stb 	s = X509_NAME_oneline(X509_get_subject_name(xs), buf, sizeof buf);
1381f70a35c1Stb 	error = X509_STORE_CTX_get_error(ctx);
1382f70a35c1Stb 	error_depth = X509_STORE_CTX_get_error_depth(ctx);
1383e90e4cafSjsing 	if (s != NULL) {
1384e90e4cafSjsing 		if (ok)
1385f70a35c1Stb 			fprintf(stderr, "depth=%d %s\n", error_depth, buf);
1386e90e4cafSjsing 		else {
1387f70a35c1Stb 			fprintf(stderr, "depth=%d error=%d %s\n", error_depth,
1388f70a35c1Stb 			    error, buf);
1389e90e4cafSjsing 		}
1390e90e4cafSjsing 	}
1391e90e4cafSjsing 
1392e90e4cafSjsing 	if (ok == 0) {
1393e90e4cafSjsing 		fprintf(stderr, "Error string: %s\n",
1394f70a35c1Stb 		    X509_verify_cert_error_string(error));
1395f70a35c1Stb 		switch (error) {
1396e90e4cafSjsing 		case X509_V_ERR_CERT_NOT_YET_VALID:
1397e90e4cafSjsing 		case X509_V_ERR_CERT_HAS_EXPIRED:
1398e90e4cafSjsing 		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1399e90e4cafSjsing 			fprintf(stderr, "  ... ignored.\n");
1400e90e4cafSjsing 			ok = 1;
1401e90e4cafSjsing 		}
1402e90e4cafSjsing 	}
1403e90e4cafSjsing 
1404e90e4cafSjsing 	return (ok);
1405e90e4cafSjsing }
1406e90e4cafSjsing 
1407e90e4cafSjsing static int
app_verify_callback(X509_STORE_CTX * ctx,void * arg)1408e90e4cafSjsing app_verify_callback(X509_STORE_CTX *ctx, void *arg)
1409e90e4cafSjsing {
1410f70a35c1Stb 	X509 *xs;
1411e90e4cafSjsing 	char *s = NULL, buf[256];
1412664ea9f8Stb 	const char *cb_arg = arg;
1413e90e4cafSjsing 
1414f70a35c1Stb 	xs = X509_STORE_CTX_get0_cert(ctx);
1415e90e4cafSjsing 	fprintf(stderr, "In app_verify_callback, allowing cert. ");
1416664ea9f8Stb 	fprintf(stderr, "Arg is: %s\n", cb_arg);
1417e90e4cafSjsing 	fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n",
1418f70a35c1Stb 	    (void *)ctx, (void *)xs);
1419f70a35c1Stb 	if (xs)
1420f70a35c1Stb 		s = X509_NAME_oneline(X509_get_subject_name(xs), buf, 256);
1421e90e4cafSjsing 	if (s != NULL) {
1422f70a35c1Stb 		fprintf(stderr, "cert depth=%d %s\n",
1423f70a35c1Stb 		    X509_STORE_CTX_get_error_depth(ctx), buf);
1424e90e4cafSjsing 	}
1425e90e4cafSjsing 
1426664ea9f8Stb 	return 1;
1427e90e4cafSjsing }
1428e90e4cafSjsing 
1429e90e4cafSjsing /* These DH parameters have been generated as follows:
1430e90e4cafSjsing  *    $ openssl dhparam -C -noout 1024
1431e90e4cafSjsing  *    $ openssl dhparam -C -noout -dsaparam 1024
1432855052a0Smiod  * (The second function has been renamed to avoid name conflicts.)
1433e90e4cafSjsing  */
1434e90e4cafSjsing static DH *
get_dh1024(void)1435039f14fdSanton get_dh1024(void)
1436e90e4cafSjsing {
1437e90e4cafSjsing 	static unsigned char dh1024_p[] = {
1438e90e4cafSjsing 		0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 0x3A,
1439e90e4cafSjsing 		0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 0xA2,
1440e90e4cafSjsing 		0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 0xB0,
1441e90e4cafSjsing 		0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 0xC2,
1442e90e4cafSjsing 		0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 0x8C,
1443e90e4cafSjsing 		0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 0xB8,
1444e90e4cafSjsing 		0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 0x52,
1445e90e4cafSjsing 		0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 0xC1,
1446e90e4cafSjsing 		0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 0xB1,
1447e90e4cafSjsing 		0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 0xAB,
1448e90e4cafSjsing 		0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53,
1449e90e4cafSjsing 	};
1450e90e4cafSjsing 	static unsigned char dh1024_g[] = {
1451e90e4cafSjsing 		0x02,
1452e90e4cafSjsing 	};
1453e90e4cafSjsing 	DH *dh;
1454dd8e321aStb 	BIGNUM *dh_p = NULL, *dh_g = NULL;
1455e90e4cafSjsing 
14561b38a69bSjsing 	if ((dh = DH_new()) == NULL)
1457dd8e321aStb 		return NULL;
1458dd8e321aStb 
1459dd8e321aStb 	dh_p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
1460dd8e321aStb 	dh_g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
1461dd8e321aStb 	if (dh_p == NULL || dh_g == NULL)
1462dd8e321aStb 		goto err;
1463dd8e321aStb 
1464dd8e321aStb 	if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
1465dd8e321aStb 		goto err;
1466dd8e321aStb 
1467dd8e321aStb 	return dh;
1468dd8e321aStb 
1469dd8e321aStb  err:
1470dd8e321aStb 	BN_free(dh_p);
1471dd8e321aStb 	BN_free(dh_g);
1472e90e4cafSjsing 	DH_free(dh);
1473dd8e321aStb 	return NULL;
1474e90e4cafSjsing }
1475e90e4cafSjsing 
1476e90e4cafSjsing static DH *
get_dh1024dsa(void)1477039f14fdSanton get_dh1024dsa(void)
1478e90e4cafSjsing {
1479e90e4cafSjsing 	static unsigned char dh1024_p[] = {
1480e90e4cafSjsing 		0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 0x00,
1481e90e4cafSjsing 		0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 0x19,
1482e90e4cafSjsing 		0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 0xD2,
1483e90e4cafSjsing 		0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 0x55,
1484e90e4cafSjsing 		0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 0xFC,
1485e90e4cafSjsing 		0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 0x97,
1486e90e4cafSjsing 		0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 0x8D,
1487e90e4cafSjsing 		0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 0xBB,
1488e90e4cafSjsing 		0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 0xF6,
1489e90e4cafSjsing 		0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 0x9E,
1490e90e4cafSjsing 		0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39,
1491e90e4cafSjsing 	};
1492e90e4cafSjsing 	static unsigned char dh1024_g[] = {
1493e90e4cafSjsing 		0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 0x05,
1494e90e4cafSjsing 		0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 0xF3,
1495e90e4cafSjsing 		0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 0xE9,
1496e90e4cafSjsing 		0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 0x3C,
1497e90e4cafSjsing 		0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 0x65,
1498e90e4cafSjsing 		0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 0x60,
1499e90e4cafSjsing 		0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 0xF6,
1500e90e4cafSjsing 		0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 0xA7,
1501e90e4cafSjsing 		0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 0xA1,
1502e90e4cafSjsing 		0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 0x60,
1503e90e4cafSjsing 		0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2,
1504e90e4cafSjsing 	};
1505e90e4cafSjsing 	DH *dh;
1506dd8e321aStb 	BIGNUM *dh_p = NULL, *dh_g = NULL;
1507e90e4cafSjsing 
15081b38a69bSjsing 	if ((dh = DH_new()) == NULL)
1509dd8e321aStb 		return NULL;
1510dd8e321aStb 
1511dd8e321aStb 	dh_p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
1512dd8e321aStb 	dh_g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
1513dd8e321aStb 	if (dh_p == NULL || dh_g == NULL)
1514dd8e321aStb 		goto err;
1515dd8e321aStb 
1516dd8e321aStb 	if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
1517dd8e321aStb 		goto err;
1518dd8e321aStb 
1519dd8e321aStb 	DH_set_length(dh, 160);
1520dd8e321aStb 
1521dd8e321aStb 	return dh;
1522dd8e321aStb 
1523dd8e321aStb  err:
1524dd8e321aStb 	BN_free(dh_p);
1525dd8e321aStb 	BN_free(dh_g);
1526e90e4cafSjsing 	DH_free(dh);
1527dd8e321aStb 	return NULL;
1528e90e4cafSjsing }
1529