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