xref: /minix3/crypto/external/bsd/openssl/dist/ssl/ssltest.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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