diff options
Diffstat (limited to 'src/usr.bin/openssl/s_server.c')
-rw-r--r-- | src/usr.bin/openssl/s_server.c | 2154 |
1 files changed, 2154 insertions, 0 deletions
diff --git a/src/usr.bin/openssl/s_server.c b/src/usr.bin/openssl/s_server.c new file mode 100644 index 0000000000..7fa875c661 --- /dev/null +++ b/src/usr.bin/openssl/s_server.c | |||
@@ -0,0 +1,2154 @@ | |||
1 | /* $OpenBSD: s_server.c,v 1.1 2014/08/26 17:47:25 jsing Exp $ */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | /* ==================================================================== | ||
59 | * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. | ||
60 | * | ||
61 | * Redistribution and use in source and binary forms, with or without | ||
62 | * modification, are permitted provided that the following conditions | ||
63 | * are met: | ||
64 | * | ||
65 | * 1. Redistributions of source code must retain the above copyright | ||
66 | * notice, this list of conditions and the following disclaimer. | ||
67 | * | ||
68 | * 2. Redistributions in binary form must reproduce the above copyright | ||
69 | * notice, this list of conditions and the following disclaimer in | ||
70 | * the documentation and/or other materials provided with the | ||
71 | * distribution. | ||
72 | * | ||
73 | * 3. All advertising materials mentioning features or use of this | ||
74 | * software must display the following acknowledgment: | ||
75 | * "This product includes software developed by the OpenSSL Project | ||
76 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
77 | * | ||
78 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
79 | * endorse or promote products derived from this software without | ||
80 | * prior written permission. For written permission, please contact | ||
81 | * openssl-core@openssl.org. | ||
82 | * | ||
83 | * 5. Products derived from this software may not be called "OpenSSL" | ||
84 | * nor may "OpenSSL" appear in their names without prior written | ||
85 | * permission of the OpenSSL Project. | ||
86 | * | ||
87 | * 6. Redistributions of any form whatsoever must retain the following | ||
88 | * acknowledgment: | ||
89 | * "This product includes software developed by the OpenSSL Project | ||
90 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
91 | * | ||
92 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
93 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
94 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
95 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
96 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
97 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
98 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
99 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
100 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
101 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
102 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
103 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
104 | * ==================================================================== | ||
105 | * | ||
106 | * This product includes cryptographic software written by Eric Young | ||
107 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
108 | * Hudson (tjh@cryptsoft.com). | ||
109 | * | ||
110 | */ | ||
111 | /* ==================================================================== | ||
112 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
113 | * ECC cipher suite support in OpenSSL originally developed by | ||
114 | * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. | ||
115 | */ | ||
116 | /* ==================================================================== | ||
117 | * Copyright 2005 Nokia. All rights reserved. | ||
118 | * | ||
119 | * The portions of the attached software ("Contribution") is developed by | ||
120 | * Nokia Corporation and is licensed pursuant to the OpenSSL open source | ||
121 | * license. | ||
122 | * | ||
123 | * The Contribution, originally written by Mika Kousa and Pasi Eronen of | ||
124 | * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites | ||
125 | * support (see RFC 4279) to OpenSSL. | ||
126 | * | ||
127 | * No patent licenses or other rights except those expressly stated in | ||
128 | * the OpenSSL open source license shall be deemed granted or received | ||
129 | * expressly, by implication, estoppel, or otherwise. | ||
130 | * | ||
131 | * No assurances are provided by Nokia that the Contribution does not | ||
132 | * infringe the patent or other intellectual property rights of any third | ||
133 | * party or that the license provides you with all the necessary rights | ||
134 | * to make use of the Contribution. | ||
135 | * | ||
136 | * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN | ||
137 | * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA | ||
138 | * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY | ||
139 | * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR | ||
140 | * OTHERWISE. | ||
141 | */ | ||
142 | |||
143 | /* Until the key-gen callbacks are modified to use newer prototypes, we allow | ||
144 | * deprecated functions for openssl-internal code */ | ||
145 | #ifdef OPENSSL_NO_DEPRECATED | ||
146 | #undef OPENSSL_NO_DEPRECATED | ||
147 | #endif | ||
148 | |||
149 | #include <sys/types.h> | ||
150 | #include <sys/ioctl.h> | ||
151 | #include <sys/select.h> | ||
152 | #include <sys/socket.h> | ||
153 | |||
154 | #include <assert.h> | ||
155 | #include <ctype.h> | ||
156 | #include <stdio.h> | ||
157 | #include <stdlib.h> | ||
158 | #include <limits.h> | ||
159 | #include <string.h> | ||
160 | #include <unistd.h> | ||
161 | |||
162 | #include "apps.h" | ||
163 | |||
164 | #include <openssl/bn.h> | ||
165 | #include <openssl/err.h> | ||
166 | #include <openssl/lhash.h> | ||
167 | #include <openssl/ocsp.h> | ||
168 | #include <openssl/pem.h> | ||
169 | #include <openssl/rand.h> | ||
170 | #include <openssl/ssl.h> | ||
171 | #include <openssl/x509.h> | ||
172 | |||
173 | #ifndef OPENSSL_NO_DH | ||
174 | #include <openssl/dh.h> | ||
175 | #endif | ||
176 | |||
177 | #include <openssl/rsa.h> | ||
178 | |||
179 | #include "s_apps.h" | ||
180 | #include "timeouts.h" | ||
181 | |||
182 | static RSA *tmp_rsa_cb(SSL * s, int is_export, int keylength); | ||
183 | static int sv_body(char *hostname, int s, unsigned char *context); | ||
184 | static int www_body(char *hostname, int s, unsigned char *context); | ||
185 | static void close_accept_socket(void); | ||
186 | static void sv_usage(void); | ||
187 | static int init_ssl_connection(SSL * s); | ||
188 | static void print_stats(BIO * bp, SSL_CTX * ctx); | ||
189 | static int | ||
190 | generate_session_id(const SSL * ssl, unsigned char *id, | ||
191 | unsigned int *id_len); | ||
192 | #ifndef OPENSSL_NO_DH | ||
193 | static DH *load_dh_param(const char *dhfile); | ||
194 | static DH *get_dh512(void); | ||
195 | #endif | ||
196 | |||
197 | static void s_server_init(void); | ||
198 | |||
199 | #ifndef OPENSSL_NO_DH | ||
200 | static unsigned char dh512_p[] = { | ||
201 | 0xDA, 0x58, 0x3C, 0x16, 0xD9, 0x85, 0x22, 0x89, 0xD0, 0xE4, 0xAF, 0x75, | ||
202 | 0x6F, 0x4C, 0xCA, 0x92, 0xDD, 0x4B, 0xE5, 0x33, 0xB8, 0x04, 0xFB, 0x0F, | ||
203 | 0xED, 0x94, 0xEF, 0x9C, 0x8A, 0x44, 0x03, 0xED, 0x57, 0x46, 0x50, 0xD3, | ||
204 | 0x69, 0x99, 0xDB, 0x29, 0xD7, 0x76, 0x27, 0x6B, 0xA2, 0xD3, 0xD4, 0x12, | ||
205 | 0xE2, 0x18, 0xF4, 0xDD, 0x1E, 0x08, 0x4C, 0xF6, 0xD8, 0x00, 0x3E, 0x7C, | ||
206 | 0x47, 0x74, 0xE8, 0x33, | ||
207 | }; | ||
208 | static unsigned char dh512_g[] = { | ||
209 | 0x02, | ||
210 | }; | ||
211 | |||
212 | static DH * | ||
213 | get_dh512(void) | ||
214 | { | ||
215 | DH *dh = NULL; | ||
216 | |||
217 | if ((dh = DH_new()) == NULL) | ||
218 | return (NULL); | ||
219 | dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); | ||
220 | dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); | ||
221 | if ((dh->p == NULL) || (dh->g == NULL)) | ||
222 | return (NULL); | ||
223 | return (dh); | ||
224 | } | ||
225 | #endif | ||
226 | |||
227 | |||
228 | /* static int load_CA(SSL_CTX *ctx, char *file);*/ | ||
229 | |||
230 | #define BUFSIZZ 16*1024 | ||
231 | static int bufsize = BUFSIZZ; | ||
232 | static int accept_socket = -1; | ||
233 | |||
234 | #define TEST_CERT "server.pem" | ||
235 | #ifndef OPENSSL_NO_TLSEXT | ||
236 | #define TEST_CERT2 "server2.pem" | ||
237 | #endif | ||
238 | |||
239 | extern int verify_depth, verify_return_error; | ||
240 | |||
241 | static char *cipher = NULL; | ||
242 | static int s_server_verify = SSL_VERIFY_NONE; | ||
243 | static int s_server_session_id_context = 1; /* anything will do */ | ||
244 | static const char *s_cert_file = TEST_CERT, *s_key_file = NULL; | ||
245 | #ifndef OPENSSL_NO_TLSEXT | ||
246 | static const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL; | ||
247 | #endif | ||
248 | static char *s_dcert_file = NULL, *s_dkey_file = NULL; | ||
249 | static int s_nbio = 0; | ||
250 | static int s_nbio_test = 0; | ||
251 | int s_crlf = 0; | ||
252 | static SSL_CTX *ctx = NULL; | ||
253 | #ifndef OPENSSL_NO_TLSEXT | ||
254 | static SSL_CTX *ctx2 = NULL; | ||
255 | #endif | ||
256 | static int www = 0; | ||
257 | |||
258 | static BIO *bio_s_out = NULL; | ||
259 | static int s_debug = 0; | ||
260 | #ifndef OPENSSL_NO_TLSEXT | ||
261 | static int s_tlsextdebug = 0; | ||
262 | static int s_tlsextstatus = 0; | ||
263 | static int cert_status_cb(SSL * s, void *arg); | ||
264 | #endif | ||
265 | static int s_msg = 0; | ||
266 | static int s_quiet = 0; | ||
267 | |||
268 | static char *keymatexportlabel = NULL; | ||
269 | static int keymatexportlen = 20; | ||
270 | |||
271 | static int hack = 0; | ||
272 | #ifndef OPENSSL_NO_ENGINE | ||
273 | static char *engine_id = NULL; | ||
274 | #endif | ||
275 | static const char *session_id_prefix = NULL; | ||
276 | |||
277 | static int enable_timeouts = 0; | ||
278 | static long socket_mtu; | ||
279 | #ifndef OPENSSL_NO_DTLS1 | ||
280 | static int cert_chain = 0; | ||
281 | #endif | ||
282 | |||
283 | |||
284 | |||
285 | |||
286 | static void | ||
287 | s_server_init(void) | ||
288 | { | ||
289 | accept_socket = -1; | ||
290 | cipher = NULL; | ||
291 | s_server_verify = SSL_VERIFY_NONE; | ||
292 | s_dcert_file = NULL; | ||
293 | s_dkey_file = NULL; | ||
294 | s_cert_file = TEST_CERT; | ||
295 | s_key_file = NULL; | ||
296 | #ifndef OPENSSL_NO_TLSEXT | ||
297 | s_cert_file2 = TEST_CERT2; | ||
298 | s_key_file2 = NULL; | ||
299 | ctx2 = NULL; | ||
300 | #endif | ||
301 | s_nbio = 0; | ||
302 | s_nbio_test = 0; | ||
303 | ctx = NULL; | ||
304 | www = 0; | ||
305 | |||
306 | bio_s_out = NULL; | ||
307 | s_debug = 0; | ||
308 | s_msg = 0; | ||
309 | s_quiet = 0; | ||
310 | hack = 0; | ||
311 | #ifndef OPENSSL_NO_ENGINE | ||
312 | engine_id = NULL; | ||
313 | #endif | ||
314 | } | ||
315 | |||
316 | static void | ||
317 | sv_usage(void) | ||
318 | { | ||
319 | BIO_printf(bio_err, "usage: s_server [args ...]\n"); | ||
320 | BIO_printf(bio_err, "\n"); | ||
321 | BIO_printf(bio_err, " -accept arg - port to accept on (default is %d)\n", PORT); | ||
322 | BIO_printf(bio_err, " -context arg - set session ID context\n"); | ||
323 | BIO_printf(bio_err, " -verify arg - turn on peer certificate verification\n"); | ||
324 | BIO_printf(bio_err, " -Verify arg - turn on peer certificate verification, must have a cert.\n"); | ||
325 | BIO_printf(bio_err, " -cert arg - certificate file to use\n"); | ||
326 | BIO_printf(bio_err, " (default is %s)\n", TEST_CERT); | ||
327 | BIO_printf(bio_err, " -crl_check - check the peer certificate has not been revoked by its CA.\n" \ | ||
328 | " The CRL(s) are appended to the certificate file\n"); | ||
329 | BIO_printf(bio_err, " -crl_check_all - check the peer certificate has not been revoked by its CA\n" \ | ||
330 | " or any other CRL in the CA chain. CRL(s) are appended to the\n" \ | ||
331 | " the certificate file.\n"); | ||
332 | BIO_printf(bio_err, " -certform arg - certificate format (PEM or DER) PEM default\n"); | ||
333 | BIO_printf(bio_err, " -key arg - Private Key file to use, in cert file if\n"); | ||
334 | BIO_printf(bio_err, " not specified (default is %s)\n", TEST_CERT); | ||
335 | BIO_printf(bio_err, " -keyform arg - key format (PEM, DER or ENGINE) PEM default\n"); | ||
336 | BIO_printf(bio_err, " -pass arg - private key file pass phrase source\n"); | ||
337 | BIO_printf(bio_err, " -dcert arg - second certificate file to use (usually for DSA)\n"); | ||
338 | BIO_printf(bio_err, " -dcertform x - second certificate format (PEM or DER) PEM default\n"); | ||
339 | BIO_printf(bio_err, " -dkey arg - second private key file to use (usually for DSA)\n"); | ||
340 | BIO_printf(bio_err, " -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n"); | ||
341 | BIO_printf(bio_err, " -dpass arg - second private key file pass phrase source\n"); | ||
342 | BIO_printf(bio_err, " -dhparam arg - DH parameter file to use, in cert file if not specified\n"); | ||
343 | BIO_printf(bio_err, " or a default set of parameters is used\n"); | ||
344 | BIO_printf(bio_err, " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ | ||
345 | " Use \"openssl ecparam -list_curves\" for all names\n" \ | ||
346 | " (default is nistp256).\n"); | ||
347 | BIO_printf(bio_err, " -nbio - Run with non-blocking IO\n"); | ||
348 | BIO_printf(bio_err, " -nbio_test - test with the non-blocking test bio\n"); | ||
349 | BIO_printf(bio_err, " -crlf - convert LF from terminal into CRLF\n"); | ||
350 | BIO_printf(bio_err, " -debug - Print more output\n"); | ||
351 | BIO_printf(bio_err, " -msg - Show protocol messages\n"); | ||
352 | BIO_printf(bio_err, " -state - Print the SSL states\n"); | ||
353 | BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); | ||
354 | BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); | ||
355 | BIO_printf(bio_err, " -nocert - Don't use any certificates (Anon-DH)\n"); | ||
356 | BIO_printf(bio_err, " -cipher arg - play with 'openssl ciphers' to see what goes here\n"); | ||
357 | BIO_printf(bio_err, " -serverpref - Use server's cipher preferences\n"); | ||
358 | BIO_printf(bio_err, " -quiet - Inhibit printing of session and certificate information\n"); | ||
359 | BIO_printf(bio_err, " -no_tmp_rsa - Do not generate a tmp RSA key\n"); | ||
360 | BIO_printf(bio_err, " -ssl3 - Just talk SSLv3\n"); | ||
361 | BIO_printf(bio_err, " -tls1_2 - Just talk TLSv1.2\n"); | ||
362 | BIO_printf(bio_err, " -tls1_1 - Just talk TLSv1.1\n"); | ||
363 | BIO_printf(bio_err, " -tls1 - Just talk TLSv1\n"); | ||
364 | BIO_printf(bio_err, " -dtls1 - Just talk DTLSv1\n"); | ||
365 | BIO_printf(bio_err, " -timeout - Enable timeouts\n"); | ||
366 | BIO_printf(bio_err, " -mtu - Set link layer MTU\n"); | ||
367 | BIO_printf(bio_err, " -chain - Read a certificate chain\n"); | ||
368 | BIO_printf(bio_err, " -no_ssl2 - Just disable SSLv2\n"); | ||
369 | BIO_printf(bio_err, " -no_ssl3 - Just disable SSLv3\n"); | ||
370 | BIO_printf(bio_err, " -no_tls1 - Just disable TLSv1\n"); | ||
371 | BIO_printf(bio_err, " -no_tls1_1 - Just disable TLSv1.1\n"); | ||
372 | BIO_printf(bio_err, " -no_tls1_2 - Just disable TLSv1.2\n"); | ||
373 | #ifndef OPENSSL_NO_DH | ||
374 | BIO_printf(bio_err, " -no_dhe - Disable ephemeral DH\n"); | ||
375 | #endif | ||
376 | BIO_printf(bio_err, " -no_ecdhe - Disable ephemeral ECDH\n"); | ||
377 | BIO_printf(bio_err, " -bugs - Turn on SSL bug compatibility\n"); | ||
378 | BIO_printf(bio_err, " -www - Respond to a 'GET /' with a status page\n"); | ||
379 | BIO_printf(bio_err, " -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); | ||
380 | BIO_printf(bio_err, " -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); | ||
381 | BIO_printf(bio_err, " with the assumption it contains a complete HTTP response.\n"); | ||
382 | #ifndef OPENSSL_NO_ENGINE | ||
383 | BIO_printf(bio_err, " -engine id - Initialise and use the specified engine\n"); | ||
384 | #endif | ||
385 | BIO_printf(bio_err, " -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); | ||
386 | #ifndef OPENSSL_NO_TLSEXT | ||
387 | BIO_printf(bio_err, " -servername host - servername for HostName TLS extension\n"); | ||
388 | BIO_printf(bio_err, " -servername_fatal - on mismatch send fatal alert (default warning alert)\n"); | ||
389 | BIO_printf(bio_err, " -cert2 arg - certificate file to use for servername\n"); | ||
390 | BIO_printf(bio_err, " (default is %s)\n", TEST_CERT2); | ||
391 | BIO_printf(bio_err, " -key2 arg - Private Key file to use for servername, in cert file if\n"); | ||
392 | BIO_printf(bio_err, " not specified (default is %s)\n", TEST_CERT2); | ||
393 | BIO_printf(bio_err, " -tlsextdebug - hex dump of all TLS extensions received\n"); | ||
394 | BIO_printf(bio_err, " -no_ticket - disable use of RFC4507bis session tickets\n"); | ||
395 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
396 | BIO_printf(bio_err, " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n"); | ||
397 | #endif | ||
398 | #ifndef OPENSSL_NO_SRTP | ||
399 | BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); | ||
400 | #endif | ||
401 | #endif | ||
402 | BIO_printf(bio_err, " -keymatexport label - Export keying material using label\n"); | ||
403 | BIO_printf(bio_err, " -keymatexportlen len - Export len bytes of keying material (default 20)\n"); | ||
404 | } | ||
405 | |||
406 | static int local_argc = 0; | ||
407 | static char **local_argv; | ||
408 | |||
409 | #ifndef OPENSSL_NO_TLSEXT | ||
410 | |||
411 | /* This is a context that we pass to callbacks */ | ||
412 | typedef struct tlsextctx_st { | ||
413 | char *servername; | ||
414 | BIO *biodebug; | ||
415 | int extension_error; | ||
416 | } tlsextctx; | ||
417 | |||
418 | |||
419 | static int | ||
420 | ssl_servername_cb(SSL * s, int *ad, void *arg) | ||
421 | { | ||
422 | tlsextctx *p = (tlsextctx *) arg; | ||
423 | const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); | ||
424 | if (servername && p->biodebug) | ||
425 | BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", servername); | ||
426 | |||
427 | if (!p->servername) | ||
428 | return SSL_TLSEXT_ERR_NOACK; | ||
429 | |||
430 | if (servername) { | ||
431 | if (strcmp(servername, p->servername)) | ||
432 | return p->extension_error; | ||
433 | if (ctx2) { | ||
434 | BIO_printf(p->biodebug, "Switching server context.\n"); | ||
435 | SSL_set_SSL_CTX(s, ctx2); | ||
436 | } | ||
437 | } | ||
438 | return SSL_TLSEXT_ERR_OK; | ||
439 | } | ||
440 | |||
441 | /* Structure passed to cert status callback */ | ||
442 | |||
443 | typedef struct tlsextstatusctx_st { | ||
444 | /* Default responder to use */ | ||
445 | char *host, *path, *port; | ||
446 | int use_ssl; | ||
447 | int timeout; | ||
448 | BIO *err; | ||
449 | int verbose; | ||
450 | } tlsextstatusctx; | ||
451 | |||
452 | static tlsextstatusctx tlscstatp = {NULL, NULL, NULL, 0, -1, NULL, 0}; | ||
453 | |||
454 | /* Certificate Status callback. This is called when a client includes a | ||
455 | * certificate status request extension. | ||
456 | * | ||
457 | * This is a simplified version. It examines certificates each time and | ||
458 | * makes one OCSP responder query for each request. | ||
459 | * | ||
460 | * A full version would store details such as the OCSP certificate IDs and | ||
461 | * minimise the number of OCSP responses by caching them until they were | ||
462 | * considered "expired". | ||
463 | */ | ||
464 | |||
465 | static int | ||
466 | cert_status_cb(SSL * s, void *arg) | ||
467 | { | ||
468 | tlsextstatusctx *srctx = arg; | ||
469 | BIO *err = srctx->err; | ||
470 | char *host, *port, *path; | ||
471 | int use_ssl; | ||
472 | unsigned char *rspder = NULL; | ||
473 | int rspderlen; | ||
474 | STACK_OF(OPENSSL_STRING) * aia = NULL; | ||
475 | X509 *x = NULL; | ||
476 | X509_STORE_CTX inctx; | ||
477 | X509_OBJECT obj; | ||
478 | OCSP_REQUEST *req = NULL; | ||
479 | OCSP_RESPONSE *resp = NULL; | ||
480 | OCSP_CERTID *id = NULL; | ||
481 | STACK_OF(X509_EXTENSION) * exts; | ||
482 | int ret = SSL_TLSEXT_ERR_NOACK; | ||
483 | int i; | ||
484 | |||
485 | if (srctx->verbose) | ||
486 | BIO_puts(err, "cert_status: callback called\n"); | ||
487 | /* Build up OCSP query from server certificate */ | ||
488 | x = SSL_get_certificate(s); | ||
489 | aia = X509_get1_ocsp(x); | ||
490 | if (aia) { | ||
491 | if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), | ||
492 | &host, &port, &path, &use_ssl)) { | ||
493 | BIO_puts(err, "cert_status: can't parse AIA URL\n"); | ||
494 | goto err; | ||
495 | } | ||
496 | if (srctx->verbose) | ||
497 | BIO_printf(err, "cert_status: AIA URL: %s\n", | ||
498 | sk_OPENSSL_STRING_value(aia, 0)); | ||
499 | } else { | ||
500 | if (!srctx->host) { | ||
501 | BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n"); | ||
502 | goto done; | ||
503 | } | ||
504 | host = srctx->host; | ||
505 | path = srctx->path; | ||
506 | port = srctx->port; | ||
507 | use_ssl = srctx->use_ssl; | ||
508 | } | ||
509 | |||
510 | if (!X509_STORE_CTX_init(&inctx, | ||
511 | SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)), | ||
512 | NULL, NULL)) | ||
513 | goto err; | ||
514 | if (X509_STORE_get_by_subject(&inctx, X509_LU_X509, | ||
515 | X509_get_issuer_name(x), &obj) <= 0) { | ||
516 | BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n"); | ||
517 | X509_STORE_CTX_cleanup(&inctx); | ||
518 | goto done; | ||
519 | } | ||
520 | req = OCSP_REQUEST_new(); | ||
521 | if (!req) | ||
522 | goto err; | ||
523 | id = OCSP_cert_to_id(NULL, x, obj.data.x509); | ||
524 | X509_free(obj.data.x509); | ||
525 | X509_STORE_CTX_cleanup(&inctx); | ||
526 | if (!id) | ||
527 | goto err; | ||
528 | if (!OCSP_request_add0_id(req, id)) | ||
529 | goto err; | ||
530 | id = NULL; | ||
531 | /* Add any extensions to the request */ | ||
532 | SSL_get_tlsext_status_exts(s, &exts); | ||
533 | for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { | ||
534 | X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); | ||
535 | if (!OCSP_REQUEST_add_ext(req, ext, -1)) | ||
536 | goto err; | ||
537 | } | ||
538 | resp = process_responder(err, req, host, path, port, use_ssl, NULL, | ||
539 | srctx->timeout); | ||
540 | if (!resp) { | ||
541 | BIO_puts(err, "cert_status: error querying responder\n"); | ||
542 | goto done; | ||
543 | } | ||
544 | rspderlen = i2d_OCSP_RESPONSE(resp, &rspder); | ||
545 | if (rspderlen <= 0) | ||
546 | goto err; | ||
547 | SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen); | ||
548 | if (srctx->verbose) { | ||
549 | BIO_puts(err, "cert_status: ocsp response sent:\n"); | ||
550 | OCSP_RESPONSE_print(err, resp, 2); | ||
551 | } | ||
552 | ret = SSL_TLSEXT_ERR_OK; | ||
553 | done: | ||
554 | if (ret != SSL_TLSEXT_ERR_OK) | ||
555 | ERR_print_errors(err); | ||
556 | if (aia) { | ||
557 | free(host); | ||
558 | free(path); | ||
559 | free(port); | ||
560 | X509_email_free(aia); | ||
561 | } | ||
562 | if (id) | ||
563 | OCSP_CERTID_free(id); | ||
564 | if (req) | ||
565 | OCSP_REQUEST_free(req); | ||
566 | if (resp) | ||
567 | OCSP_RESPONSE_free(resp); | ||
568 | return ret; | ||
569 | err: | ||
570 | ret = SSL_TLSEXT_ERR_ALERT_FATAL; | ||
571 | goto done; | ||
572 | } | ||
573 | |||
574 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
575 | /* This is the context that we pass to next_proto_cb */ | ||
576 | typedef struct tlsextnextprotoctx_st { | ||
577 | unsigned char *data; | ||
578 | unsigned int len; | ||
579 | } tlsextnextprotoctx; | ||
580 | |||
581 | static int | ||
582 | next_proto_cb(SSL * s, const unsigned char **data, unsigned int *len, void *arg) | ||
583 | { | ||
584 | tlsextnextprotoctx *next_proto = arg; | ||
585 | |||
586 | *data = next_proto->data; | ||
587 | *len = next_proto->len; | ||
588 | |||
589 | return SSL_TLSEXT_ERR_OK; | ||
590 | } | ||
591 | #endif /* ndef OPENSSL_NO_NEXTPROTONEG */ | ||
592 | |||
593 | |||
594 | #endif | ||
595 | |||
596 | int s_server_main(int, char **); | ||
597 | |||
598 | #ifndef OPENSSL_NO_SRTP | ||
599 | static char *srtp_profiles = NULL; | ||
600 | #endif | ||
601 | |||
602 | int | ||
603 | s_server_main(int argc, char *argv[]) | ||
604 | { | ||
605 | X509_VERIFY_PARAM *vpm = NULL; | ||
606 | int badarg = 0; | ||
607 | short port = PORT; | ||
608 | char *CApath = NULL, *CAfile = NULL; | ||
609 | unsigned char *context = NULL; | ||
610 | char *dhfile = NULL; | ||
611 | char *named_curve = NULL; | ||
612 | int badop = 0, bugs = 0; | ||
613 | int ret = 1; | ||
614 | int off = 0; | ||
615 | int no_tmp_rsa = 0, no_dhe = 0, no_ecdhe = 0, nocert = 0; | ||
616 | int state = 0; | ||
617 | const SSL_METHOD *meth = NULL; | ||
618 | int socket_type = SOCK_STREAM; | ||
619 | ENGINE *e = NULL; | ||
620 | int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM; | ||
621 | char *passarg = NULL, *pass = NULL; | ||
622 | char *dpassarg = NULL, *dpass = NULL; | ||
623 | int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; | ||
624 | X509 *s_cert = NULL, *s_dcert = NULL; | ||
625 | EVP_PKEY *s_key = NULL, *s_dkey = NULL; | ||
626 | int no_cache = 0; | ||
627 | const char *errstr = NULL; | ||
628 | #ifndef OPENSSL_NO_TLSEXT | ||
629 | EVP_PKEY *s_key2 = NULL; | ||
630 | X509 *s_cert2 = NULL; | ||
631 | tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; | ||
632 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
633 | const char *next_proto_neg_in = NULL; | ||
634 | tlsextnextprotoctx next_proto; | ||
635 | #endif | ||
636 | #endif | ||
637 | meth = SSLv23_server_method(); | ||
638 | |||
639 | local_argc = argc; | ||
640 | local_argv = argv; | ||
641 | |||
642 | s_server_init(); | ||
643 | |||
644 | verify_depth = 0; | ||
645 | s_nbio = 0; | ||
646 | s_nbio_test = 0; | ||
647 | |||
648 | argc--; | ||
649 | argv++; | ||
650 | |||
651 | while (argc >= 1) { | ||
652 | if ((strcmp(*argv, "-port") == 0) || | ||
653 | (strcmp(*argv, "-accept") == 0)) { | ||
654 | if (--argc < 1) | ||
655 | goto bad; | ||
656 | if (!extract_port(*(++argv), &port)) | ||
657 | goto bad; | ||
658 | } else if (strcmp(*argv, "-verify") == 0) { | ||
659 | s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; | ||
660 | if (--argc < 1) | ||
661 | goto bad; | ||
662 | verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr); | ||
663 | if (errstr) | ||
664 | goto bad; | ||
665 | BIO_printf(bio_err, "verify depth is %d\n", verify_depth); | ||
666 | } else if (strcmp(*argv, "-Verify") == 0) { | ||
667 | s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | | ||
668 | SSL_VERIFY_CLIENT_ONCE; | ||
669 | if (--argc < 1) | ||
670 | goto bad; | ||
671 | verify_depth = strtonum(*(++argv), 0, INT_MAX, &errstr); | ||
672 | if (errstr) | ||
673 | goto bad; | ||
674 | BIO_printf(bio_err, "verify depth is %d, must return a certificate\n", verify_depth); | ||
675 | } else if (strcmp(*argv, "-context") == 0) { | ||
676 | if (--argc < 1) | ||
677 | goto bad; | ||
678 | context = (unsigned char *) *(++argv); | ||
679 | } else if (strcmp(*argv, "-cert") == 0) { | ||
680 | if (--argc < 1) | ||
681 | goto bad; | ||
682 | s_cert_file = *(++argv); | ||
683 | } else if (strcmp(*argv, "-certform") == 0) { | ||
684 | if (--argc < 1) | ||
685 | goto bad; | ||
686 | s_cert_format = str2fmt(*(++argv)); | ||
687 | } else if (strcmp(*argv, "-key") == 0) { | ||
688 | if (--argc < 1) | ||
689 | goto bad; | ||
690 | s_key_file = *(++argv); | ||
691 | } else if (strcmp(*argv, "-keyform") == 0) { | ||
692 | if (--argc < 1) | ||
693 | goto bad; | ||
694 | s_key_format = str2fmt(*(++argv)); | ||
695 | } else if (strcmp(*argv, "-pass") == 0) { | ||
696 | if (--argc < 1) | ||
697 | goto bad; | ||
698 | passarg = *(++argv); | ||
699 | } else if (strcmp(*argv, "-dhparam") == 0) { | ||
700 | if (--argc < 1) | ||
701 | goto bad; | ||
702 | dhfile = *(++argv); | ||
703 | } | ||
704 | else if (strcmp(*argv, "-named_curve") == 0) { | ||
705 | if (--argc < 1) | ||
706 | goto bad; | ||
707 | named_curve = *(++argv); | ||
708 | } | ||
709 | else if (strcmp(*argv, "-dcertform") == 0) { | ||
710 | if (--argc < 1) | ||
711 | goto bad; | ||
712 | s_dcert_format = str2fmt(*(++argv)); | ||
713 | } else if (strcmp(*argv, "-dcert") == 0) { | ||
714 | if (--argc < 1) | ||
715 | goto bad; | ||
716 | s_dcert_file = *(++argv); | ||
717 | } else if (strcmp(*argv, "-dkeyform") == 0) { | ||
718 | if (--argc < 1) | ||
719 | goto bad; | ||
720 | s_dkey_format = str2fmt(*(++argv)); | ||
721 | } else if (strcmp(*argv, "-dpass") == 0) { | ||
722 | if (--argc < 1) | ||
723 | goto bad; | ||
724 | dpassarg = *(++argv); | ||
725 | } else if (strcmp(*argv, "-dkey") == 0) { | ||
726 | if (--argc < 1) | ||
727 | goto bad; | ||
728 | s_dkey_file = *(++argv); | ||
729 | } else if (strcmp(*argv, "-nocert") == 0) { | ||
730 | nocert = 1; | ||
731 | } else if (strcmp(*argv, "-CApath") == 0) { | ||
732 | if (--argc < 1) | ||
733 | goto bad; | ||
734 | CApath = *(++argv); | ||
735 | } else if (strcmp(*argv, "-no_cache") == 0) | ||
736 | no_cache = 1; | ||
737 | else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) { | ||
738 | if (badarg) | ||
739 | goto bad; | ||
740 | continue; | ||
741 | } else if (strcmp(*argv, "-verify_return_error") == 0) | ||
742 | verify_return_error = 1; | ||
743 | else if (strcmp(*argv, "-serverpref") == 0) { | ||
744 | off |= SSL_OP_CIPHER_SERVER_PREFERENCE; | ||
745 | } else if (strcmp(*argv, "-legacy_renegotiation") == 0) | ||
746 | ; /* no-op */ | ||
747 | else if (strcmp(*argv, "-cipher") == 0) { | ||
748 | if (--argc < 1) | ||
749 | goto bad; | ||
750 | cipher = *(++argv); | ||
751 | } else if (strcmp(*argv, "-CAfile") == 0) { | ||
752 | if (--argc < 1) | ||
753 | goto bad; | ||
754 | CAfile = *(++argv); | ||
755 | } | ||
756 | else if (strcmp(*argv, "-nbio") == 0) { | ||
757 | s_nbio = 1; | ||
758 | } | ||
759 | else if (strcmp(*argv, "-nbio_test") == 0) { | ||
760 | s_nbio = 1; | ||
761 | s_nbio_test = 1; | ||
762 | } else if (strcmp(*argv, "-debug") == 0) { | ||
763 | s_debug = 1; | ||
764 | } | ||
765 | #ifndef OPENSSL_NO_TLSEXT | ||
766 | else if (strcmp(*argv, "-tlsextdebug") == 0) | ||
767 | s_tlsextdebug = 1; | ||
768 | else if (strcmp(*argv, "-status") == 0) | ||
769 | s_tlsextstatus = 1; | ||
770 | else if (strcmp(*argv, "-status_verbose") == 0) { | ||
771 | s_tlsextstatus = 1; | ||
772 | tlscstatp.verbose = 1; | ||
773 | } else if (!strcmp(*argv, "-status_timeout")) { | ||
774 | s_tlsextstatus = 1; | ||
775 | if (--argc < 1) | ||
776 | goto bad; | ||
777 | tlscstatp.timeout = strtonum(*(++argv), 0, INT_MAX, &errstr); | ||
778 | if (errstr) | ||
779 | goto bad; | ||
780 | } else if (!strcmp(*argv, "-status_url")) { | ||
781 | s_tlsextstatus = 1; | ||
782 | if (--argc < 1) | ||
783 | goto bad; | ||
784 | if (!OCSP_parse_url(*(++argv), | ||
785 | &tlscstatp.host, | ||
786 | &tlscstatp.port, | ||
787 | &tlscstatp.path, | ||
788 | &tlscstatp.use_ssl)) { | ||
789 | BIO_printf(bio_err, "Error parsing URL\n"); | ||
790 | goto bad; | ||
791 | } | ||
792 | } | ||
793 | #endif | ||
794 | else if (strcmp(*argv, "-msg") == 0) { | ||
795 | s_msg = 1; | ||
796 | } else if (strcmp(*argv, "-hack") == 0) { | ||
797 | hack = 1; | ||
798 | } else if (strcmp(*argv, "-state") == 0) { | ||
799 | state = 1; | ||
800 | } else if (strcmp(*argv, "-crlf") == 0) { | ||
801 | s_crlf = 1; | ||
802 | } else if (strcmp(*argv, "-quiet") == 0) { | ||
803 | s_quiet = 1; | ||
804 | } else if (strcmp(*argv, "-bugs") == 0) { | ||
805 | bugs = 1; | ||
806 | } else if (strcmp(*argv, "-no_tmp_rsa") == 0) { | ||
807 | no_tmp_rsa = 1; | ||
808 | } else if (strcmp(*argv, "-no_dhe") == 0) { | ||
809 | no_dhe = 1; | ||
810 | } else if (strcmp(*argv, "-no_ecdhe") == 0) { | ||
811 | no_ecdhe = 1; | ||
812 | } | ||
813 | else if (strcmp(*argv, "-www") == 0) { | ||
814 | www = 1; | ||
815 | } else if (strcmp(*argv, "-WWW") == 0) { | ||
816 | www = 2; | ||
817 | } else if (strcmp(*argv, "-HTTP") == 0) { | ||
818 | www = 3; | ||
819 | } else if (strcmp(*argv, "-no_ssl2") == 0) { | ||
820 | off |= SSL_OP_NO_SSLv2; | ||
821 | } else if (strcmp(*argv, "-no_ssl3") == 0) { | ||
822 | off |= SSL_OP_NO_SSLv3; | ||
823 | } else if (strcmp(*argv, "-no_tls1") == 0) { | ||
824 | off |= SSL_OP_NO_TLSv1; | ||
825 | } else if (strcmp(*argv, "-no_tls1_1") == 0) { | ||
826 | off |= SSL_OP_NO_TLSv1_1; | ||
827 | } else if (strcmp(*argv, "-no_tls1_2") == 0) { | ||
828 | off |= SSL_OP_NO_TLSv1_2; | ||
829 | } else if (strcmp(*argv, "-no_comp") == 0) { | ||
830 | off |= SSL_OP_NO_COMPRESSION; | ||
831 | } | ||
832 | #ifndef OPENSSL_NO_TLSEXT | ||
833 | else if (strcmp(*argv, "-no_ticket") == 0) { | ||
834 | off |= SSL_OP_NO_TICKET; | ||
835 | } | ||
836 | #endif | ||
837 | else if (strcmp(*argv, "-ssl3") == 0) { | ||
838 | meth = SSLv3_server_method(); | ||
839 | } else if (strcmp(*argv, "-tls1") == 0) { | ||
840 | meth = TLSv1_server_method(); | ||
841 | } else if (strcmp(*argv, "-tls1_1") == 0) { | ||
842 | meth = TLSv1_1_server_method(); | ||
843 | } else if (strcmp(*argv, "-tls1_2") == 0) { | ||
844 | meth = TLSv1_2_server_method(); | ||
845 | } | ||
846 | #ifndef OPENSSL_NO_DTLS1 | ||
847 | else if (strcmp(*argv, "-dtls1") == 0) { | ||
848 | meth = DTLSv1_server_method(); | ||
849 | socket_type = SOCK_DGRAM; | ||
850 | } else if (strcmp(*argv, "-timeout") == 0) | ||
851 | enable_timeouts = 1; | ||
852 | else if (strcmp(*argv, "-mtu") == 0) { | ||
853 | if (--argc < 1) | ||
854 | goto bad; | ||
855 | socket_mtu = strtonum(*(++argv), 0, LONG_MAX, &errstr); | ||
856 | if (errstr) | ||
857 | goto bad; | ||
858 | } else if (strcmp(*argv, "-chain") == 0) | ||
859 | cert_chain = 1; | ||
860 | #endif | ||
861 | else if (strcmp(*argv, "-id_prefix") == 0) { | ||
862 | if (--argc < 1) | ||
863 | goto bad; | ||
864 | session_id_prefix = *(++argv); | ||
865 | } | ||
866 | #ifndef OPENSSL_NO_ENGINE | ||
867 | else if (strcmp(*argv, "-engine") == 0) { | ||
868 | if (--argc < 1) | ||
869 | goto bad; | ||
870 | engine_id = *(++argv); | ||
871 | } | ||
872 | #endif | ||
873 | #ifndef OPENSSL_NO_TLSEXT | ||
874 | else if (strcmp(*argv, "-servername") == 0) { | ||
875 | if (--argc < 1) | ||
876 | goto bad; | ||
877 | tlsextcbp.servername = *(++argv); | ||
878 | } else if (strcmp(*argv, "-servername_fatal") == 0) { | ||
879 | tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; | ||
880 | } else if (strcmp(*argv, "-cert2") == 0) { | ||
881 | if (--argc < 1) | ||
882 | goto bad; | ||
883 | s_cert_file2 = *(++argv); | ||
884 | } else if (strcmp(*argv, "-key2") == 0) { | ||
885 | if (--argc < 1) | ||
886 | goto bad; | ||
887 | s_key_file2 = *(++argv); | ||
888 | } | ||
889 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
890 | else if (strcmp(*argv, "-nextprotoneg") == 0) { | ||
891 | if (--argc < 1) | ||
892 | goto bad; | ||
893 | next_proto_neg_in = *(++argv); | ||
894 | } | ||
895 | #endif | ||
896 | #endif | ||
897 | #ifndef OPENSSL_NO_SRTP | ||
898 | else if (strcmp(*argv, "-use_srtp") == 0) { | ||
899 | if (--argc < 1) | ||
900 | goto bad; | ||
901 | srtp_profiles = *(++argv); | ||
902 | } | ||
903 | #endif | ||
904 | else if (strcmp(*argv, "-keymatexport") == 0) { | ||
905 | if (--argc < 1) | ||
906 | goto bad; | ||
907 | keymatexportlabel = *(++argv); | ||
908 | } else if (strcmp(*argv, "-keymatexportlen") == 0) { | ||
909 | if (--argc < 1) | ||
910 | goto bad; | ||
911 | keymatexportlen = strtonum(*(++argv), 1, INT_MAX, &errstr); | ||
912 | if (errstr) | ||
913 | goto bad; | ||
914 | } else { | ||
915 | BIO_printf(bio_err, "unknown option %s\n", *argv); | ||
916 | badop = 1; | ||
917 | break; | ||
918 | } | ||
919 | argc--; | ||
920 | argv++; | ||
921 | } | ||
922 | if (badop) { | ||
923 | bad: | ||
924 | if (errstr) | ||
925 | BIO_printf(bio_err, "invalid argument %s: %s\n", | ||
926 | *argv, errstr); | ||
927 | else | ||
928 | sv_usage(); | ||
929 | goto end; | ||
930 | } | ||
931 | |||
932 | #ifndef OPENSSL_NO_ENGINE | ||
933 | e = setup_engine(bio_err, engine_id, 1); | ||
934 | #endif | ||
935 | |||
936 | if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) { | ||
937 | BIO_printf(bio_err, "Error getting password\n"); | ||
938 | goto end; | ||
939 | } | ||
940 | if (s_key_file == NULL) | ||
941 | s_key_file = s_cert_file; | ||
942 | #ifndef OPENSSL_NO_TLSEXT | ||
943 | if (s_key_file2 == NULL) | ||
944 | s_key_file2 = s_cert_file2; | ||
945 | #endif | ||
946 | |||
947 | if (nocert == 0) { | ||
948 | s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e, | ||
949 | "server certificate private key file"); | ||
950 | if (!s_key) { | ||
951 | ERR_print_errors(bio_err); | ||
952 | goto end; | ||
953 | } | ||
954 | s_cert = load_cert(bio_err, s_cert_file, s_cert_format, | ||
955 | NULL, e, "server certificate file"); | ||
956 | |||
957 | if (!s_cert) { | ||
958 | ERR_print_errors(bio_err); | ||
959 | goto end; | ||
960 | } | ||
961 | #ifndef OPENSSL_NO_TLSEXT | ||
962 | if (tlsextcbp.servername) { | ||
963 | s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e, | ||
964 | "second server certificate private key file"); | ||
965 | if (!s_key2) { | ||
966 | ERR_print_errors(bio_err); | ||
967 | goto end; | ||
968 | } | ||
969 | s_cert2 = load_cert(bio_err, s_cert_file2, s_cert_format, | ||
970 | NULL, e, "second server certificate file"); | ||
971 | |||
972 | if (!s_cert2) { | ||
973 | ERR_print_errors(bio_err); | ||
974 | goto end; | ||
975 | } | ||
976 | } | ||
977 | #endif | ||
978 | } | ||
979 | #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) | ||
980 | if (next_proto_neg_in) { | ||
981 | unsigned short len; | ||
982 | next_proto.data = next_protos_parse(&len, next_proto_neg_in); | ||
983 | if (next_proto.data == NULL) | ||
984 | goto end; | ||
985 | next_proto.len = len; | ||
986 | } else { | ||
987 | next_proto.data = NULL; | ||
988 | } | ||
989 | #endif | ||
990 | |||
991 | |||
992 | if (s_dcert_file) { | ||
993 | |||
994 | if (s_dkey_file == NULL) | ||
995 | s_dkey_file = s_dcert_file; | ||
996 | |||
997 | s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format, | ||
998 | 0, dpass, e, | ||
999 | "second certificate private key file"); | ||
1000 | if (!s_dkey) { | ||
1001 | ERR_print_errors(bio_err); | ||
1002 | goto end; | ||
1003 | } | ||
1004 | s_dcert = load_cert(bio_err, s_dcert_file, s_dcert_format, | ||
1005 | NULL, e, "second server certificate file"); | ||
1006 | |||
1007 | if (!s_dcert) { | ||
1008 | ERR_print_errors(bio_err); | ||
1009 | goto end; | ||
1010 | } | ||
1011 | } | ||
1012 | if (bio_s_out == NULL) { | ||
1013 | if (s_quiet && !s_debug && !s_msg) { | ||
1014 | bio_s_out = BIO_new(BIO_s_null()); | ||
1015 | } else { | ||
1016 | if (bio_s_out == NULL) | ||
1017 | bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE); | ||
1018 | } | ||
1019 | } | ||
1020 | if (nocert) | ||
1021 | { | ||
1022 | s_cert_file = NULL; | ||
1023 | s_key_file = NULL; | ||
1024 | s_dcert_file = NULL; | ||
1025 | s_dkey_file = NULL; | ||
1026 | #ifndef OPENSSL_NO_TLSEXT | ||
1027 | s_cert_file2 = NULL; | ||
1028 | s_key_file2 = NULL; | ||
1029 | #endif | ||
1030 | } | ||
1031 | ctx = SSL_CTX_new(meth); | ||
1032 | if (ctx == NULL) { | ||
1033 | ERR_print_errors(bio_err); | ||
1034 | goto end; | ||
1035 | } | ||
1036 | if (session_id_prefix) { | ||
1037 | if (strlen(session_id_prefix) >= 32) | ||
1038 | BIO_printf(bio_err, | ||
1039 | "warning: id_prefix is too long, only one new session will be possible\n"); | ||
1040 | else if (strlen(session_id_prefix) >= 16) | ||
1041 | BIO_printf(bio_err, | ||
1042 | "warning: id_prefix is too long if you use SSLv2\n"); | ||
1043 | if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) { | ||
1044 | BIO_printf(bio_err, "error setting 'id_prefix'\n"); | ||
1045 | ERR_print_errors(bio_err); | ||
1046 | goto end; | ||
1047 | } | ||
1048 | BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); | ||
1049 | } | ||
1050 | SSL_CTX_set_quiet_shutdown(ctx, 1); | ||
1051 | if (bugs) | ||
1052 | SSL_CTX_set_options(ctx, SSL_OP_ALL); | ||
1053 | if (hack) | ||
1054 | SSL_CTX_set_options(ctx, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); | ||
1055 | SSL_CTX_set_options(ctx, off); | ||
1056 | /* | ||
1057 | * DTLS: partial reads end up discarding unread UDP bytes :-( Setting | ||
1058 | * read ahead solves this problem. | ||
1059 | */ | ||
1060 | if (socket_type == SOCK_DGRAM) | ||
1061 | SSL_CTX_set_read_ahead(ctx, 1); | ||
1062 | |||
1063 | if (state) | ||
1064 | SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); | ||
1065 | if (no_cache) | ||
1066 | SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); | ||
1067 | else | ||
1068 | SSL_CTX_sess_set_cache_size(ctx, 128); | ||
1069 | |||
1070 | #ifndef OPENSSL_NO_SRTP | ||
1071 | if (srtp_profiles != NULL) | ||
1072 | SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles); | ||
1073 | #endif | ||
1074 | |||
1075 | |||
1076 | if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) || | ||
1077 | (!SSL_CTX_set_default_verify_paths(ctx))) { | ||
1078 | /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ | ||
1079 | ERR_print_errors(bio_err); | ||
1080 | /* goto end; */ | ||
1081 | } | ||
1082 | if (vpm) | ||
1083 | SSL_CTX_set1_param(ctx, vpm); | ||
1084 | |||
1085 | #ifndef OPENSSL_NO_TLSEXT | ||
1086 | if (s_cert2) { | ||
1087 | ctx2 = SSL_CTX_new(meth); | ||
1088 | if (ctx2 == NULL) { | ||
1089 | ERR_print_errors(bio_err); | ||
1090 | goto end; | ||
1091 | } | ||
1092 | } | ||
1093 | if (ctx2) { | ||
1094 | BIO_printf(bio_s_out, "Setting secondary ctx parameters\n"); | ||
1095 | |||
1096 | if (session_id_prefix) { | ||
1097 | if (strlen(session_id_prefix) >= 32) | ||
1098 | BIO_printf(bio_err, | ||
1099 | "warning: id_prefix is too long, only one new session will be possible\n"); | ||
1100 | else if (strlen(session_id_prefix) >= 16) | ||
1101 | BIO_printf(bio_err, | ||
1102 | "warning: id_prefix is too long if you use SSLv2\n"); | ||
1103 | if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) { | ||
1104 | BIO_printf(bio_err, "error setting 'id_prefix'\n"); | ||
1105 | ERR_print_errors(bio_err); | ||
1106 | goto end; | ||
1107 | } | ||
1108 | BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix); | ||
1109 | } | ||
1110 | SSL_CTX_set_quiet_shutdown(ctx2, 1); | ||
1111 | if (bugs) | ||
1112 | SSL_CTX_set_options(ctx2, SSL_OP_ALL); | ||
1113 | if (hack) | ||
1114 | SSL_CTX_set_options(ctx2, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); | ||
1115 | SSL_CTX_set_options(ctx2, off); | ||
1116 | /* | ||
1117 | * DTLS: partial reads end up discarding unread UDP bytes :-( | ||
1118 | * Setting read ahead solves this problem. | ||
1119 | */ | ||
1120 | if (socket_type == SOCK_DGRAM) | ||
1121 | SSL_CTX_set_read_ahead(ctx2, 1); | ||
1122 | |||
1123 | if (state) | ||
1124 | SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback); | ||
1125 | |||
1126 | if (no_cache) | ||
1127 | SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF); | ||
1128 | else | ||
1129 | SSL_CTX_sess_set_cache_size(ctx2, 128); | ||
1130 | |||
1131 | if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) || | ||
1132 | (!SSL_CTX_set_default_verify_paths(ctx2))) { | ||
1133 | ERR_print_errors(bio_err); | ||
1134 | } | ||
1135 | if (vpm) | ||
1136 | SSL_CTX_set1_param(ctx2, vpm); | ||
1137 | } | ||
1138 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
1139 | if (next_proto.data) | ||
1140 | SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto); | ||
1141 | #endif | ||
1142 | #endif | ||
1143 | |||
1144 | #ifndef OPENSSL_NO_DH | ||
1145 | if (!no_dhe) { | ||
1146 | DH *dh = NULL; | ||
1147 | |||
1148 | if (dhfile) | ||
1149 | dh = load_dh_param(dhfile); | ||
1150 | else if (s_cert_file) | ||
1151 | dh = load_dh_param(s_cert_file); | ||
1152 | |||
1153 | if (dh != NULL) { | ||
1154 | BIO_printf(bio_s_out, "Setting temp DH parameters\n"); | ||
1155 | } else { | ||
1156 | BIO_printf(bio_s_out, "Using default temp DH parameters\n"); | ||
1157 | dh = get_dh512(); | ||
1158 | } | ||
1159 | (void) BIO_flush(bio_s_out); | ||
1160 | |||
1161 | SSL_CTX_set_tmp_dh(ctx, dh); | ||
1162 | #ifndef OPENSSL_NO_TLSEXT | ||
1163 | if (ctx2) { | ||
1164 | if (!dhfile) { | ||
1165 | DH *dh2 = load_dh_param(s_cert_file2); | ||
1166 | if (dh2 != NULL) { | ||
1167 | BIO_printf(bio_s_out, "Setting temp DH parameters\n"); | ||
1168 | (void) BIO_flush(bio_s_out); | ||
1169 | |||
1170 | DH_free(dh); | ||
1171 | dh = dh2; | ||
1172 | } | ||
1173 | } | ||
1174 | SSL_CTX_set_tmp_dh(ctx2, dh); | ||
1175 | } | ||
1176 | #endif | ||
1177 | DH_free(dh); | ||
1178 | } | ||
1179 | #endif | ||
1180 | |||
1181 | if (!no_ecdhe) { | ||
1182 | EC_KEY *ecdh = NULL; | ||
1183 | |||
1184 | if (named_curve) { | ||
1185 | int nid = OBJ_sn2nid(named_curve); | ||
1186 | |||
1187 | if (nid == 0) { | ||
1188 | BIO_printf(bio_err, "unknown curve name (%s)\n", | ||
1189 | named_curve); | ||
1190 | goto end; | ||
1191 | } | ||
1192 | ecdh = EC_KEY_new_by_curve_name(nid); | ||
1193 | if (ecdh == NULL) { | ||
1194 | BIO_printf(bio_err, "unable to create curve (%s)\n", | ||
1195 | named_curve); | ||
1196 | goto end; | ||
1197 | } | ||
1198 | } | ||
1199 | if (ecdh != NULL) { | ||
1200 | BIO_printf(bio_s_out, "Setting temp ECDH parameters\n"); | ||
1201 | } else { | ||
1202 | BIO_printf(bio_s_out, "Using default temp ECDH parameters\n"); | ||
1203 | ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); | ||
1204 | if (ecdh == NULL) { | ||
1205 | BIO_printf(bio_err, "unable to create curve (nistp256)\n"); | ||
1206 | goto end; | ||
1207 | } | ||
1208 | } | ||
1209 | (void) BIO_flush(bio_s_out); | ||
1210 | |||
1211 | SSL_CTX_set_tmp_ecdh(ctx, ecdh); | ||
1212 | #ifndef OPENSSL_NO_TLSEXT | ||
1213 | if (ctx2) | ||
1214 | SSL_CTX_set_tmp_ecdh(ctx2, ecdh); | ||
1215 | #endif | ||
1216 | EC_KEY_free(ecdh); | ||
1217 | } | ||
1218 | |||
1219 | if (!set_cert_key_stuff(ctx, s_cert, s_key)) | ||
1220 | goto end; | ||
1221 | #ifndef OPENSSL_NO_TLSEXT | ||
1222 | if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2)) | ||
1223 | goto end; | ||
1224 | #endif | ||
1225 | if (s_dcert != NULL) { | ||
1226 | if (!set_cert_key_stuff(ctx, s_dcert, s_dkey)) | ||
1227 | goto end; | ||
1228 | } | ||
1229 | if (!no_tmp_rsa) { | ||
1230 | SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb); | ||
1231 | #ifndef OPENSSL_NO_TLSEXT | ||
1232 | if (ctx2) | ||
1233 | SSL_CTX_set_tmp_rsa_callback(ctx2, tmp_rsa_cb); | ||
1234 | #endif | ||
1235 | } | ||
1236 | |||
1237 | |||
1238 | if (cipher != NULL) { | ||
1239 | if (!SSL_CTX_set_cipher_list(ctx, cipher)) { | ||
1240 | BIO_printf(bio_err, "error setting cipher list\n"); | ||
1241 | ERR_print_errors(bio_err); | ||
1242 | goto end; | ||
1243 | } | ||
1244 | #ifndef OPENSSL_NO_TLSEXT | ||
1245 | if (ctx2 && !SSL_CTX_set_cipher_list(ctx2, cipher)) { | ||
1246 | BIO_printf(bio_err, "error setting cipher list\n"); | ||
1247 | ERR_print_errors(bio_err); | ||
1248 | goto end; | ||
1249 | } | ||
1250 | #endif | ||
1251 | } | ||
1252 | SSL_CTX_set_verify(ctx, s_server_verify, verify_callback); | ||
1253 | SSL_CTX_set_session_id_context(ctx, (void *) &s_server_session_id_context, | ||
1254 | sizeof s_server_session_id_context); | ||
1255 | |||
1256 | /* Set DTLS cookie generation and verification callbacks */ | ||
1257 | SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback); | ||
1258 | SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback); | ||
1259 | |||
1260 | #ifndef OPENSSL_NO_TLSEXT | ||
1261 | if (ctx2) { | ||
1262 | SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback); | ||
1263 | SSL_CTX_set_session_id_context(ctx2, (void *) &s_server_session_id_context, | ||
1264 | sizeof s_server_session_id_context); | ||
1265 | |||
1266 | tlsextcbp.biodebug = bio_s_out; | ||
1267 | SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb); | ||
1268 | SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp); | ||
1269 | SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); | ||
1270 | SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); | ||
1271 | } | ||
1272 | #endif | ||
1273 | |||
1274 | if (CAfile != NULL) { | ||
1275 | SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile)); | ||
1276 | #ifndef OPENSSL_NO_TLSEXT | ||
1277 | if (ctx2) | ||
1278 | SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile)); | ||
1279 | #endif | ||
1280 | } | ||
1281 | BIO_printf(bio_s_out, "ACCEPT\n"); | ||
1282 | (void) BIO_flush(bio_s_out); | ||
1283 | if (www) | ||
1284 | do_server(port, socket_type, &accept_socket, www_body, context); | ||
1285 | else | ||
1286 | do_server(port, socket_type, &accept_socket, sv_body, context); | ||
1287 | print_stats(bio_s_out, ctx); | ||
1288 | ret = 0; | ||
1289 | end: | ||
1290 | if (ctx != NULL) | ||
1291 | SSL_CTX_free(ctx); | ||
1292 | if (s_cert) | ||
1293 | X509_free(s_cert); | ||
1294 | if (s_dcert) | ||
1295 | X509_free(s_dcert); | ||
1296 | if (s_key) | ||
1297 | EVP_PKEY_free(s_key); | ||
1298 | if (s_dkey) | ||
1299 | EVP_PKEY_free(s_dkey); | ||
1300 | free(pass); | ||
1301 | free(dpass); | ||
1302 | if (vpm) | ||
1303 | X509_VERIFY_PARAM_free(vpm); | ||
1304 | #ifndef OPENSSL_NO_TLSEXT | ||
1305 | free(tlscstatp.host); | ||
1306 | free(tlscstatp.port); | ||
1307 | free(tlscstatp.path); | ||
1308 | if (ctx2 != NULL) | ||
1309 | SSL_CTX_free(ctx2); | ||
1310 | if (s_cert2) | ||
1311 | X509_free(s_cert2); | ||
1312 | if (s_key2) | ||
1313 | EVP_PKEY_free(s_key2); | ||
1314 | #endif | ||
1315 | if (bio_s_out != NULL) { | ||
1316 | BIO_free(bio_s_out); | ||
1317 | bio_s_out = NULL; | ||
1318 | } | ||
1319 | |||
1320 | return (ret); | ||
1321 | } | ||
1322 | |||
1323 | static void | ||
1324 | print_stats(BIO * bio, SSL_CTX * ssl_ctx) | ||
1325 | { | ||
1326 | BIO_printf(bio, "%4ld items in the session cache\n", | ||
1327 | SSL_CTX_sess_number(ssl_ctx)); | ||
1328 | BIO_printf(bio, "%4ld client connects (SSL_connect())\n", | ||
1329 | SSL_CTX_sess_connect(ssl_ctx)); | ||
1330 | BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n", | ||
1331 | SSL_CTX_sess_connect_renegotiate(ssl_ctx)); | ||
1332 | BIO_printf(bio, "%4ld client connects that finished\n", | ||
1333 | SSL_CTX_sess_connect_good(ssl_ctx)); | ||
1334 | BIO_printf(bio, "%4ld server accepts (SSL_accept())\n", | ||
1335 | SSL_CTX_sess_accept(ssl_ctx)); | ||
1336 | BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n", | ||
1337 | SSL_CTX_sess_accept_renegotiate(ssl_ctx)); | ||
1338 | BIO_printf(bio, "%4ld server accepts that finished\n", | ||
1339 | SSL_CTX_sess_accept_good(ssl_ctx)); | ||
1340 | BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx)); | ||
1341 | BIO_printf(bio, "%4ld session cache misses\n", SSL_CTX_sess_misses(ssl_ctx)); | ||
1342 | BIO_printf(bio, "%4ld session cache timeouts\n", SSL_CTX_sess_timeouts(ssl_ctx)); | ||
1343 | BIO_printf(bio, "%4ld callback cache hits\n", SSL_CTX_sess_cb_hits(ssl_ctx)); | ||
1344 | BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n", | ||
1345 | SSL_CTX_sess_cache_full(ssl_ctx), | ||
1346 | SSL_CTX_sess_get_cache_size(ssl_ctx)); | ||
1347 | } | ||
1348 | |||
1349 | static int | ||
1350 | sv_body(char *hostname, int s, unsigned char *context) | ||
1351 | { | ||
1352 | char *buf = NULL; | ||
1353 | fd_set readfds; | ||
1354 | int ret = 1, width; | ||
1355 | int k, i; | ||
1356 | unsigned long l; | ||
1357 | SSL *con = NULL; | ||
1358 | BIO *sbio; | ||
1359 | struct timeval timeout; | ||
1360 | struct timeval *timeoutp; | ||
1361 | |||
1362 | if ((buf = malloc(bufsize)) == NULL) { | ||
1363 | BIO_printf(bio_err, "out of memory\n"); | ||
1364 | goto err; | ||
1365 | } | ||
1366 | if (s_nbio) { | ||
1367 | unsigned long sl = 1; | ||
1368 | |||
1369 | if (!s_quiet) | ||
1370 | BIO_printf(bio_err, "turning on non blocking io\n"); | ||
1371 | if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0) | ||
1372 | ERR_print_errors(bio_err); | ||
1373 | } | ||
1374 | |||
1375 | if (con == NULL) { | ||
1376 | con = SSL_new(ctx); | ||
1377 | #ifndef OPENSSL_NO_TLSEXT | ||
1378 | if (s_tlsextdebug) { | ||
1379 | SSL_set_tlsext_debug_callback(con, tlsext_cb); | ||
1380 | SSL_set_tlsext_debug_arg(con, bio_s_out); | ||
1381 | } | ||
1382 | if (s_tlsextstatus) { | ||
1383 | SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb); | ||
1384 | tlscstatp.err = bio_err; | ||
1385 | SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp); | ||
1386 | } | ||
1387 | #endif | ||
1388 | if (context) | ||
1389 | SSL_set_session_id_context(con, context, | ||
1390 | strlen((char *) context)); | ||
1391 | } | ||
1392 | SSL_clear(con); | ||
1393 | |||
1394 | if (SSL_version(con) == DTLS1_VERSION) { | ||
1395 | |||
1396 | sbio = BIO_new_dgram(s, BIO_NOCLOSE); | ||
1397 | |||
1398 | if (enable_timeouts) { | ||
1399 | timeout.tv_sec = 0; | ||
1400 | timeout.tv_usec = DGRAM_RCV_TIMEOUT; | ||
1401 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); | ||
1402 | |||
1403 | timeout.tv_sec = 0; | ||
1404 | timeout.tv_usec = DGRAM_SND_TIMEOUT; | ||
1405 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); | ||
1406 | } | ||
1407 | if (socket_mtu > 28) { | ||
1408 | SSL_set_options(con, SSL_OP_NO_QUERY_MTU); | ||
1409 | SSL_set_mtu(con, socket_mtu - 28); | ||
1410 | } else | ||
1411 | /* want to do MTU discovery */ | ||
1412 | BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); | ||
1413 | |||
1414 | /* turn on cookie exchange */ | ||
1415 | SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE); | ||
1416 | } else | ||
1417 | sbio = BIO_new_socket(s, BIO_NOCLOSE); | ||
1418 | |||
1419 | if (s_nbio_test) { | ||
1420 | BIO *test; | ||
1421 | |||
1422 | test = BIO_new(BIO_f_nbio_test()); | ||
1423 | sbio = BIO_push(test, sbio); | ||
1424 | } | ||
1425 | |||
1426 | SSL_set_bio(con, sbio, sbio); | ||
1427 | SSL_set_accept_state(con); | ||
1428 | /* SSL_set_fd(con,s); */ | ||
1429 | |||
1430 | if (s_debug) { | ||
1431 | SSL_set_debug(con, 1); | ||
1432 | BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); | ||
1433 | BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); | ||
1434 | } | ||
1435 | if (s_msg) { | ||
1436 | SSL_set_msg_callback(con, msg_cb); | ||
1437 | SSL_set_msg_callback_arg(con, bio_s_out); | ||
1438 | } | ||
1439 | #ifndef OPENSSL_NO_TLSEXT | ||
1440 | if (s_tlsextdebug) { | ||
1441 | SSL_set_tlsext_debug_callback(con, tlsext_cb); | ||
1442 | SSL_set_tlsext_debug_arg(con, bio_s_out); | ||
1443 | } | ||
1444 | #endif | ||
1445 | |||
1446 | width = s + 1; | ||
1447 | for (;;) { | ||
1448 | int read_from_terminal; | ||
1449 | int read_from_sslcon; | ||
1450 | |||
1451 | read_from_terminal = 0; | ||
1452 | read_from_sslcon = SSL_pending(con); | ||
1453 | |||
1454 | if (!read_from_sslcon) { | ||
1455 | FD_ZERO(&readfds); | ||
1456 | FD_SET(fileno(stdin), &readfds); | ||
1457 | FD_SET(s, &readfds); | ||
1458 | if ((SSL_version(con) == DTLS1_VERSION) && | ||
1459 | DTLSv1_get_timeout(con, &timeout)) | ||
1460 | timeoutp = &timeout; | ||
1461 | else | ||
1462 | timeoutp = NULL; | ||
1463 | |||
1464 | i = select(width, &readfds, NULL, NULL, timeoutp); | ||
1465 | |||
1466 | if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) { | ||
1467 | BIO_printf(bio_err, "TIMEOUT occured\n"); | ||
1468 | } | ||
1469 | if (i <= 0) | ||
1470 | continue; | ||
1471 | if (FD_ISSET(fileno(stdin), &readfds)) | ||
1472 | read_from_terminal = 1; | ||
1473 | if (FD_ISSET(s, &readfds)) | ||
1474 | read_from_sslcon = 1; | ||
1475 | } | ||
1476 | if (read_from_terminal) { | ||
1477 | if (s_crlf) { | ||
1478 | int j, lf_num; | ||
1479 | |||
1480 | i = read(fileno(stdin), buf, bufsize / 2); | ||
1481 | lf_num = 0; | ||
1482 | /* both loops are skipped when i <= 0 */ | ||
1483 | for (j = 0; j < i; j++) | ||
1484 | if (buf[j] == '\n') | ||
1485 | lf_num++; | ||
1486 | for (j = i - 1; j >= 0; j--) { | ||
1487 | buf[j + lf_num] = buf[j]; | ||
1488 | if (buf[j] == '\n') { | ||
1489 | lf_num--; | ||
1490 | i++; | ||
1491 | buf[j + lf_num] = '\r'; | ||
1492 | } | ||
1493 | } | ||
1494 | assert(lf_num == 0); | ||
1495 | } else | ||
1496 | i = read(fileno(stdin), buf, bufsize); | ||
1497 | if (!s_quiet) { | ||
1498 | if ((i <= 0) || (buf[0] == 'Q')) { | ||
1499 | BIO_printf(bio_s_out, "DONE\n"); | ||
1500 | shutdown(s, SHUT_RD); | ||
1501 | close(s); | ||
1502 | close_accept_socket(); | ||
1503 | ret = -11; | ||
1504 | goto err; | ||
1505 | } | ||
1506 | if ((i <= 0) || (buf[0] == 'q')) { | ||
1507 | BIO_printf(bio_s_out, "DONE\n"); | ||
1508 | if (SSL_version(con) != DTLS1_VERSION) { | ||
1509 | shutdown(s, SHUT_RD); | ||
1510 | close(s); | ||
1511 | } | ||
1512 | /* | ||
1513 | * close_accept_socket(); ret= -11; | ||
1514 | */ | ||
1515 | goto err; | ||
1516 | } | ||
1517 | if ((buf[0] == 'r') && | ||
1518 | ((buf[1] == '\n') || (buf[1] == '\r'))) { | ||
1519 | SSL_renegotiate(con); | ||
1520 | i = SSL_do_handshake(con); | ||
1521 | printf("SSL_do_handshake -> %d\n", i); | ||
1522 | i = 0; /* 13; */ | ||
1523 | continue; | ||
1524 | /* | ||
1525 | * strcpy(buf,"server side | ||
1526 | * RE-NEGOTIATE\n"); | ||
1527 | */ | ||
1528 | } | ||
1529 | if ((buf[0] == 'R') && | ||
1530 | ((buf[1] == '\n') || (buf[1] == '\r'))) { | ||
1531 | SSL_set_verify(con, | ||
1532 | SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); | ||
1533 | SSL_renegotiate(con); | ||
1534 | i = SSL_do_handshake(con); | ||
1535 | printf("SSL_do_handshake -> %d\n", i); | ||
1536 | i = 0; /* 13; */ | ||
1537 | continue; | ||
1538 | /* | ||
1539 | * strcpy(buf,"server side | ||
1540 | * RE-NEGOTIATE asking for client | ||
1541 | * cert\n"); | ||
1542 | */ | ||
1543 | } | ||
1544 | if (buf[0] == 'P') { | ||
1545 | static const char *str = "Lets print some clear text\n"; | ||
1546 | BIO_write(SSL_get_wbio(con), str, strlen(str)); | ||
1547 | } | ||
1548 | if (buf[0] == 'S') { | ||
1549 | print_stats(bio_s_out, SSL_get_SSL_CTX(con)); | ||
1550 | } | ||
1551 | } | ||
1552 | l = k = 0; | ||
1553 | for (;;) { | ||
1554 | /* should do a select for the write */ | ||
1555 | #ifdef RENEG | ||
1556 | { | ||
1557 | static count = 0; | ||
1558 | if (++count == 100) { | ||
1559 | count = 0; | ||
1560 | SSL_renegotiate(con); | ||
1561 | } | ||
1562 | } | ||
1563 | #endif | ||
1564 | k = SSL_write(con, &(buf[l]), (unsigned int) i); | ||
1565 | switch (SSL_get_error(con, k)) { | ||
1566 | case SSL_ERROR_NONE: | ||
1567 | break; | ||
1568 | case SSL_ERROR_WANT_WRITE: | ||
1569 | case SSL_ERROR_WANT_READ: | ||
1570 | case SSL_ERROR_WANT_X509_LOOKUP: | ||
1571 | BIO_printf(bio_s_out, "Write BLOCK\n"); | ||
1572 | break; | ||
1573 | case SSL_ERROR_SYSCALL: | ||
1574 | case SSL_ERROR_SSL: | ||
1575 | BIO_printf(bio_s_out, "ERROR\n"); | ||
1576 | ERR_print_errors(bio_err); | ||
1577 | ret = 1; | ||
1578 | goto err; | ||
1579 | /* break; */ | ||
1580 | case SSL_ERROR_ZERO_RETURN: | ||
1581 | BIO_printf(bio_s_out, "DONE\n"); | ||
1582 | ret = 1; | ||
1583 | goto err; | ||
1584 | } | ||
1585 | l += k; | ||
1586 | i -= k; | ||
1587 | if (i <= 0) | ||
1588 | break; | ||
1589 | } | ||
1590 | } | ||
1591 | if (read_from_sslcon) { | ||
1592 | if (!SSL_is_init_finished(con)) { | ||
1593 | i = init_ssl_connection(con); | ||
1594 | |||
1595 | if (i < 0) { | ||
1596 | ret = 0; | ||
1597 | goto err; | ||
1598 | } else if (i == 0) { | ||
1599 | ret = 1; | ||
1600 | goto err; | ||
1601 | } | ||
1602 | } else { | ||
1603 | again: | ||
1604 | i = SSL_read(con, (char *) buf, bufsize); | ||
1605 | switch (SSL_get_error(con, i)) { | ||
1606 | case SSL_ERROR_NONE: { | ||
1607 | int len, n; | ||
1608 | for (len = 0; len < i;) { | ||
1609 | do { | ||
1610 | n = write(fileno(stdout), buf + len, i - len); | ||
1611 | } while (n == -1 && errno == EINTR); | ||
1612 | |||
1613 | if (n < 0) { | ||
1614 | BIO_printf(bio_s_out, "ERROR\n"); | ||
1615 | goto err; | ||
1616 | } | ||
1617 | len += n; | ||
1618 | } | ||
1619 | } | ||
1620 | if (SSL_pending(con)) | ||
1621 | goto again; | ||
1622 | break; | ||
1623 | case SSL_ERROR_WANT_WRITE: | ||
1624 | case SSL_ERROR_WANT_READ: | ||
1625 | BIO_printf(bio_s_out, "Read BLOCK\n"); | ||
1626 | break; | ||
1627 | case SSL_ERROR_SYSCALL: | ||
1628 | case SSL_ERROR_SSL: | ||
1629 | BIO_printf(bio_s_out, "ERROR\n"); | ||
1630 | ERR_print_errors(bio_err); | ||
1631 | ret = 1; | ||
1632 | goto err; | ||
1633 | case SSL_ERROR_ZERO_RETURN: | ||
1634 | BIO_printf(bio_s_out, "DONE\n"); | ||
1635 | ret = 1; | ||
1636 | goto err; | ||
1637 | } | ||
1638 | } | ||
1639 | } | ||
1640 | } | ||
1641 | err: | ||
1642 | if (con != NULL) { | ||
1643 | BIO_printf(bio_s_out, "shutting down SSL\n"); | ||
1644 | SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); | ||
1645 | SSL_free(con); | ||
1646 | } | ||
1647 | BIO_printf(bio_s_out, "CONNECTION CLOSED\n"); | ||
1648 | if (buf != NULL) { | ||
1649 | OPENSSL_cleanse(buf, bufsize); | ||
1650 | free(buf); | ||
1651 | } | ||
1652 | if (ret >= 0) | ||
1653 | BIO_printf(bio_s_out, "ACCEPT\n"); | ||
1654 | return (ret); | ||
1655 | } | ||
1656 | |||
1657 | static void | ||
1658 | close_accept_socket(void) | ||
1659 | { | ||
1660 | BIO_printf(bio_err, "shutdown accept socket\n"); | ||
1661 | if (accept_socket >= 0) { | ||
1662 | shutdown(accept_socket, SHUT_RDWR); | ||
1663 | close(accept_socket); | ||
1664 | } | ||
1665 | } | ||
1666 | |||
1667 | static int | ||
1668 | init_ssl_connection(SSL * con) | ||
1669 | { | ||
1670 | int i; | ||
1671 | const char *str; | ||
1672 | X509 *peer; | ||
1673 | long verify_error; | ||
1674 | char buf[BUFSIZ]; | ||
1675 | #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) | ||
1676 | const unsigned char *next_proto_neg; | ||
1677 | unsigned next_proto_neg_len; | ||
1678 | #endif | ||
1679 | unsigned char *exportedkeymat; | ||
1680 | |||
1681 | |||
1682 | i = SSL_accept(con); | ||
1683 | if (i <= 0) { | ||
1684 | if (BIO_sock_should_retry(i)) { | ||
1685 | BIO_printf(bio_s_out, "DELAY\n"); | ||
1686 | return (1); | ||
1687 | } | ||
1688 | BIO_printf(bio_err, "ERROR\n"); | ||
1689 | verify_error = SSL_get_verify_result(con); | ||
1690 | if (verify_error != X509_V_OK) { | ||
1691 | BIO_printf(bio_err, "verify error:%s\n", | ||
1692 | X509_verify_cert_error_string(verify_error)); | ||
1693 | } else | ||
1694 | ERR_print_errors(bio_err); | ||
1695 | return (0); | ||
1696 | } | ||
1697 | PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con)); | ||
1698 | |||
1699 | peer = SSL_get_peer_certificate(con); | ||
1700 | if (peer != NULL) { | ||
1701 | BIO_printf(bio_s_out, "Client certificate\n"); | ||
1702 | PEM_write_bio_X509(bio_s_out, peer); | ||
1703 | X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf); | ||
1704 | BIO_printf(bio_s_out, "subject=%s\n", buf); | ||
1705 | X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf); | ||
1706 | BIO_printf(bio_s_out, "issuer=%s\n", buf); | ||
1707 | X509_free(peer); | ||
1708 | } | ||
1709 | if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) | ||
1710 | BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf); | ||
1711 | str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); | ||
1712 | BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); | ||
1713 | |||
1714 | #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) | ||
1715 | SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); | ||
1716 | if (next_proto_neg) { | ||
1717 | BIO_printf(bio_s_out, "NEXTPROTO is "); | ||
1718 | BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len); | ||
1719 | BIO_printf(bio_s_out, "\n"); | ||
1720 | } | ||
1721 | #endif | ||
1722 | #ifndef OPENSSL_NO_SRTP | ||
1723 | { | ||
1724 | SRTP_PROTECTION_PROFILE *srtp_profile | ||
1725 | = SSL_get_selected_srtp_profile(con); | ||
1726 | |||
1727 | if (srtp_profile) | ||
1728 | BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n", | ||
1729 | srtp_profile->name); | ||
1730 | } | ||
1731 | #endif | ||
1732 | if (SSL_cache_hit(con)) | ||
1733 | BIO_printf(bio_s_out, "Reused session-id\n"); | ||
1734 | if (SSL_ctrl(con, SSL_CTRL_GET_FLAGS, 0, NULL) & | ||
1735 | TLS1_FLAGS_TLS_PADDING_BUG) | ||
1736 | BIO_printf(bio_s_out, | ||
1737 | "Peer has incorrect TLSv1 block padding\n"); | ||
1738 | BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n", | ||
1739 | SSL_get_secure_renegotiation_support(con) ? "" : " NOT"); | ||
1740 | if (keymatexportlabel != NULL) { | ||
1741 | BIO_printf(bio_s_out, "Keying material exporter:\n"); | ||
1742 | BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel); | ||
1743 | BIO_printf(bio_s_out, " Length: %i bytes\n", | ||
1744 | keymatexportlen); | ||
1745 | exportedkeymat = malloc(keymatexportlen); | ||
1746 | if (exportedkeymat != NULL) { | ||
1747 | if (!SSL_export_keying_material(con, exportedkeymat, | ||
1748 | keymatexportlen, | ||
1749 | keymatexportlabel, | ||
1750 | strlen(keymatexportlabel), | ||
1751 | NULL, 0, 0)) { | ||
1752 | BIO_printf(bio_s_out, " Error\n"); | ||
1753 | } else { | ||
1754 | BIO_printf(bio_s_out, " Keying material: "); | ||
1755 | for (i = 0; i < keymatexportlen; i++) | ||
1756 | BIO_printf(bio_s_out, "%02X", | ||
1757 | exportedkeymat[i]); | ||
1758 | BIO_printf(bio_s_out, "\n"); | ||
1759 | } | ||
1760 | free(exportedkeymat); | ||
1761 | } | ||
1762 | } | ||
1763 | return (1); | ||
1764 | } | ||
1765 | |||
1766 | #ifndef OPENSSL_NO_DH | ||
1767 | static DH * | ||
1768 | load_dh_param(const char *dhfile) | ||
1769 | { | ||
1770 | DH *ret = NULL; | ||
1771 | BIO *bio; | ||
1772 | |||
1773 | if ((bio = BIO_new_file(dhfile, "r")) == NULL) | ||
1774 | goto err; | ||
1775 | ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); | ||
1776 | err: | ||
1777 | BIO_free(bio); | ||
1778 | return (ret); | ||
1779 | } | ||
1780 | #endif | ||
1781 | |||
1782 | static int | ||
1783 | www_body(char *hostname, int s, unsigned char *context) | ||
1784 | { | ||
1785 | char *buf = NULL; | ||
1786 | int ret = 1; | ||
1787 | int i, j, k, dot; | ||
1788 | SSL *con; | ||
1789 | const SSL_CIPHER *c; | ||
1790 | BIO *io, *ssl_bio, *sbio; | ||
1791 | |||
1792 | buf = malloc(bufsize); | ||
1793 | if (buf == NULL) | ||
1794 | return (0); | ||
1795 | io = BIO_new(BIO_f_buffer()); | ||
1796 | ssl_bio = BIO_new(BIO_f_ssl()); | ||
1797 | if ((io == NULL) || (ssl_bio == NULL)) | ||
1798 | goto err; | ||
1799 | |||
1800 | if (s_nbio) { | ||
1801 | unsigned long sl = 1; | ||
1802 | |||
1803 | if (!s_quiet) | ||
1804 | BIO_printf(bio_err, "turning on non blocking io\n"); | ||
1805 | if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0) | ||
1806 | ERR_print_errors(bio_err); | ||
1807 | } | ||
1808 | |||
1809 | /* lets make the output buffer a reasonable size */ | ||
1810 | if (!BIO_set_write_buffer_size(io, bufsize)) | ||
1811 | goto err; | ||
1812 | |||
1813 | if ((con = SSL_new(ctx)) == NULL) | ||
1814 | goto err; | ||
1815 | #ifndef OPENSSL_NO_TLSEXT | ||
1816 | if (s_tlsextdebug) { | ||
1817 | SSL_set_tlsext_debug_callback(con, tlsext_cb); | ||
1818 | SSL_set_tlsext_debug_arg(con, bio_s_out); | ||
1819 | } | ||
1820 | #endif | ||
1821 | if (context) | ||
1822 | SSL_set_session_id_context(con, context, | ||
1823 | strlen((char *) context)); | ||
1824 | |||
1825 | sbio = BIO_new_socket(s, BIO_NOCLOSE); | ||
1826 | if (s_nbio_test) { | ||
1827 | BIO *test; | ||
1828 | |||
1829 | test = BIO_new(BIO_f_nbio_test()); | ||
1830 | sbio = BIO_push(test, sbio); | ||
1831 | } | ||
1832 | SSL_set_bio(con, sbio, sbio); | ||
1833 | SSL_set_accept_state(con); | ||
1834 | |||
1835 | /* SSL_set_fd(con,s); */ | ||
1836 | BIO_set_ssl(ssl_bio, con, BIO_CLOSE); | ||
1837 | BIO_push(io, ssl_bio); | ||
1838 | |||
1839 | if (s_debug) { | ||
1840 | SSL_set_debug(con, 1); | ||
1841 | BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); | ||
1842 | BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out); | ||
1843 | } | ||
1844 | if (s_msg) { | ||
1845 | SSL_set_msg_callback(con, msg_cb); | ||
1846 | SSL_set_msg_callback_arg(con, bio_s_out); | ||
1847 | } | ||
1848 | for (;;) { | ||
1849 | if (hack) { | ||
1850 | i = SSL_accept(con); | ||
1851 | switch (SSL_get_error(con, i)) { | ||
1852 | case SSL_ERROR_NONE: | ||
1853 | break; | ||
1854 | case SSL_ERROR_WANT_WRITE: | ||
1855 | case SSL_ERROR_WANT_READ: | ||
1856 | case SSL_ERROR_WANT_X509_LOOKUP: | ||
1857 | continue; | ||
1858 | case SSL_ERROR_SYSCALL: | ||
1859 | case SSL_ERROR_SSL: | ||
1860 | case SSL_ERROR_ZERO_RETURN: | ||
1861 | ret = 1; | ||
1862 | goto err; | ||
1863 | /* break; */ | ||
1864 | } | ||
1865 | |||
1866 | SSL_renegotiate(con); | ||
1867 | SSL_write(con, NULL, 0); | ||
1868 | } | ||
1869 | i = BIO_gets(io, buf, bufsize - 1); | ||
1870 | if (i < 0) { /* error */ | ||
1871 | if (!BIO_should_retry(io)) { | ||
1872 | if (!s_quiet) | ||
1873 | ERR_print_errors(bio_err); | ||
1874 | goto err; | ||
1875 | } else { | ||
1876 | BIO_printf(bio_s_out, "read R BLOCK\n"); | ||
1877 | sleep(1); | ||
1878 | continue; | ||
1879 | } | ||
1880 | } else if (i == 0) { /* end of input */ | ||
1881 | ret = 1; | ||
1882 | goto end; | ||
1883 | } | ||
1884 | /* else we have data */ | ||
1885 | if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) || | ||
1886 | ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) { | ||
1887 | char *p; | ||
1888 | X509 *peer; | ||
1889 | STACK_OF(SSL_CIPHER) * sk; | ||
1890 | static const char *space = " "; | ||
1891 | |||
1892 | BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); | ||
1893 | BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n"); | ||
1894 | BIO_puts(io, "<pre>\n"); | ||
1895 | /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ | ||
1896 | BIO_puts(io, "\n"); | ||
1897 | for (i = 0; i < local_argc; i++) { | ||
1898 | BIO_puts(io, local_argv[i]); | ||
1899 | BIO_write(io, " ", 1); | ||
1900 | } | ||
1901 | BIO_puts(io, "\n"); | ||
1902 | |||
1903 | BIO_printf(io, | ||
1904 | "Secure Renegotiation IS%s supported\n", | ||
1905 | SSL_get_secure_renegotiation_support(con) ? | ||
1906 | "" : " NOT"); | ||
1907 | |||
1908 | /* | ||
1909 | * The following is evil and should not really be | ||
1910 | * done | ||
1911 | */ | ||
1912 | BIO_printf(io, "Ciphers supported in s_server binary\n"); | ||
1913 | sk = SSL_get_ciphers(con); | ||
1914 | j = sk_SSL_CIPHER_num(sk); | ||
1915 | for (i = 0; i < j; i++) { | ||
1916 | c = sk_SSL_CIPHER_value(sk, i); | ||
1917 | BIO_printf(io, "%-11s:%-25s", | ||
1918 | SSL_CIPHER_get_version(c), | ||
1919 | SSL_CIPHER_get_name(c)); | ||
1920 | if ((((i + 1) % 2) == 0) && (i + 1 != j)) | ||
1921 | BIO_puts(io, "\n"); | ||
1922 | } | ||
1923 | BIO_puts(io, "\n"); | ||
1924 | p = SSL_get_shared_ciphers(con, buf, bufsize); | ||
1925 | if (p != NULL) { | ||
1926 | BIO_printf(io, "---\nCiphers common between both SSL end points:\n"); | ||
1927 | j = i = 0; | ||
1928 | while (*p) { | ||
1929 | if (*p == ':') { | ||
1930 | BIO_write(io, space, 26 - j); | ||
1931 | i++; | ||
1932 | j = 0; | ||
1933 | BIO_write(io, ((i % 3) ? " " : "\n"), 1); | ||
1934 | } else { | ||
1935 | BIO_write(io, p, 1); | ||
1936 | j++; | ||
1937 | } | ||
1938 | p++; | ||
1939 | } | ||
1940 | BIO_puts(io, "\n"); | ||
1941 | } | ||
1942 | BIO_printf(io, (SSL_cache_hit(con) | ||
1943 | ? "---\nReused, " | ||
1944 | : "---\nNew, ")); | ||
1945 | c = SSL_get_current_cipher(con); | ||
1946 | BIO_printf(io, "%s, Cipher is %s\n", | ||
1947 | SSL_CIPHER_get_version(c), | ||
1948 | SSL_CIPHER_get_name(c)); | ||
1949 | SSL_SESSION_print(io, SSL_get_session(con)); | ||
1950 | BIO_printf(io, "---\n"); | ||
1951 | print_stats(io, SSL_get_SSL_CTX(con)); | ||
1952 | BIO_printf(io, "---\n"); | ||
1953 | peer = SSL_get_peer_certificate(con); | ||
1954 | if (peer != NULL) { | ||
1955 | BIO_printf(io, "Client certificate\n"); | ||
1956 | X509_print(io, peer); | ||
1957 | PEM_write_bio_X509(io, peer); | ||
1958 | } else | ||
1959 | BIO_puts(io, "no client certificate available\n"); | ||
1960 | BIO_puts(io, "</BODY></HTML>\r\n\r\n"); | ||
1961 | break; | ||
1962 | } else if ((www == 2 || www == 3) | ||
1963 | && (strncmp("GET /", buf, 5) == 0)) { | ||
1964 | BIO *file; | ||
1965 | char *p, *e; | ||
1966 | static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; | ||
1967 | |||
1968 | /* skip the '/' */ | ||
1969 | p = &(buf[5]); | ||
1970 | |||
1971 | dot = 1; | ||
1972 | for (e = p; *e != '\0'; e++) { | ||
1973 | if (e[0] == ' ') | ||
1974 | break; | ||
1975 | |||
1976 | switch (dot) { | ||
1977 | case 1: | ||
1978 | dot = (e[0] == '.') ? 2 : 0; | ||
1979 | break; | ||
1980 | case 2: | ||
1981 | dot = (e[0] == '.') ? 3 : 0; | ||
1982 | break; | ||
1983 | case 3: | ||
1984 | dot = (e[0] == '/') ? -1 : 0; | ||
1985 | break; | ||
1986 | } | ||
1987 | if (dot == 0) | ||
1988 | dot = (e[0] == '/') ? 1 : 0; | ||
1989 | } | ||
1990 | dot = (dot == 3) || (dot == -1); /* filename contains | ||
1991 | * ".." component */ | ||
1992 | |||
1993 | if (*e == '\0') { | ||
1994 | BIO_puts(io, text); | ||
1995 | BIO_printf(io, "'%s' is an invalid file name\r\n", p); | ||
1996 | break; | ||
1997 | } | ||
1998 | *e = '\0'; | ||
1999 | |||
2000 | if (dot) { | ||
2001 | BIO_puts(io, text); | ||
2002 | BIO_printf(io, "'%s' contains '..' reference\r\n", p); | ||
2003 | break; | ||
2004 | } | ||
2005 | if (*p == '/') { | ||
2006 | BIO_puts(io, text); | ||
2007 | BIO_printf(io, "'%s' is an invalid path\r\n", p); | ||
2008 | break; | ||
2009 | } | ||
2010 | /* if a directory, do the index thang */ | ||
2011 | if (app_isdir(p) > 0) { | ||
2012 | BIO_puts(io, text); | ||
2013 | BIO_printf(io, "'%s' is a directory\r\n", p); | ||
2014 | break; | ||
2015 | } | ||
2016 | if ((file = BIO_new_file(p, "r")) == NULL) { | ||
2017 | BIO_puts(io, text); | ||
2018 | BIO_printf(io, "Error opening '%s'\r\n", p); | ||
2019 | ERR_print_errors(io); | ||
2020 | break; | ||
2021 | } | ||
2022 | if (!s_quiet) | ||
2023 | BIO_printf(bio_err, "FILE:%s\n", p); | ||
2024 | |||
2025 | if (www == 2) { | ||
2026 | i = strlen(p); | ||
2027 | if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) || | ||
2028 | ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) || | ||
2029 | ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0))) | ||
2030 | BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); | ||
2031 | else | ||
2032 | BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); | ||
2033 | } | ||
2034 | /* send the file */ | ||
2035 | for (;;) { | ||
2036 | i = BIO_read(file, buf, bufsize); | ||
2037 | if (i <= 0) | ||
2038 | break; | ||
2039 | |||
2040 | #ifdef RENEG | ||
2041 | total_bytes += i; | ||
2042 | fprintf(stderr, "%d\n", i); | ||
2043 | if (total_bytes > 3 * 1024) { | ||
2044 | total_bytes = 0; | ||
2045 | fprintf(stderr, "RENEGOTIATE\n"); | ||
2046 | SSL_renegotiate(con); | ||
2047 | } | ||
2048 | #endif | ||
2049 | |||
2050 | for (j = 0; j < i;) { | ||
2051 | #ifdef RENEG | ||
2052 | { | ||
2053 | static count = 0; | ||
2054 | if (++count == 13) { | ||
2055 | SSL_renegotiate(con); | ||
2056 | } | ||
2057 | } | ||
2058 | #endif | ||
2059 | k = BIO_write(io, &(buf[j]), i - j); | ||
2060 | if (k <= 0) { | ||
2061 | if (!BIO_should_retry(io)) | ||
2062 | goto write_error; | ||
2063 | else { | ||
2064 | BIO_printf(bio_s_out, "rwrite W BLOCK\n"); | ||
2065 | } | ||
2066 | } else { | ||
2067 | j += k; | ||
2068 | } | ||
2069 | } | ||
2070 | } | ||
2071 | write_error: | ||
2072 | BIO_free(file); | ||
2073 | break; | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | for (;;) { | ||
2078 | i = (int) BIO_flush(io); | ||
2079 | if (i <= 0) { | ||
2080 | if (!BIO_should_retry(io)) | ||
2081 | break; | ||
2082 | } else | ||
2083 | break; | ||
2084 | } | ||
2085 | end: | ||
2086 | /* make sure we re-use sessions */ | ||
2087 | SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); | ||
2088 | |||
2089 | err: | ||
2090 | |||
2091 | if (ret >= 0) | ||
2092 | BIO_printf(bio_s_out, "ACCEPT\n"); | ||
2093 | |||
2094 | if (buf != NULL) | ||
2095 | free(buf); | ||
2096 | if (io != NULL) | ||
2097 | BIO_free_all(io); | ||
2098 | /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/ | ||
2099 | return (ret); | ||
2100 | } | ||
2101 | |||
2102 | static RSA * | ||
2103 | tmp_rsa_cb(SSL * s, int is_export, int keylength) | ||
2104 | { | ||
2105 | BIGNUM *bn = NULL; | ||
2106 | static RSA *rsa_tmp = NULL; | ||
2107 | |||
2108 | if (!rsa_tmp && ((bn = BN_new()) == NULL)) | ||
2109 | BIO_printf(bio_err, "Allocation error in generating RSA key\n"); | ||
2110 | if (!rsa_tmp && bn) { | ||
2111 | if (!s_quiet) { | ||
2112 | BIO_printf(bio_err, "Generating temp (%d bit) RSA key...", keylength); | ||
2113 | (void) BIO_flush(bio_err); | ||
2114 | } | ||
2115 | if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) || | ||
2116 | !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) { | ||
2117 | if (rsa_tmp) | ||
2118 | RSA_free(rsa_tmp); | ||
2119 | rsa_tmp = NULL; | ||
2120 | } | ||
2121 | if (!s_quiet) { | ||
2122 | BIO_printf(bio_err, "\n"); | ||
2123 | (void) BIO_flush(bio_err); | ||
2124 | } | ||
2125 | BN_free(bn); | ||
2126 | } | ||
2127 | return (rsa_tmp); | ||
2128 | } | ||
2129 | |||
2130 | #define MAX_SESSION_ID_ATTEMPTS 10 | ||
2131 | static int | ||
2132 | generate_session_id(const SSL * ssl, unsigned char *id, | ||
2133 | unsigned int *id_len) | ||
2134 | { | ||
2135 | unsigned int count = 0; | ||
2136 | do { | ||
2137 | RAND_pseudo_bytes(id, *id_len); | ||
2138 | /* | ||
2139 | * Prefix the session_id with the required prefix. NB: If our | ||
2140 | * prefix is too long, clip it - but there will be worse | ||
2141 | * effects anyway, eg. the server could only possibly create | ||
2142 | * 1 session ID (ie. the prefix!) so all future session | ||
2143 | * negotiations will fail due to conflicts. | ||
2144 | */ | ||
2145 | memcpy(id, session_id_prefix, | ||
2146 | (strlen(session_id_prefix) < *id_len) ? | ||
2147 | strlen(session_id_prefix) : *id_len); | ||
2148 | } | ||
2149 | while (SSL_has_matching_session_id(ssl, id, *id_len) && | ||
2150 | (++count < MAX_SESSION_ID_ATTEMPTS)); | ||
2151 | if (count >= MAX_SESSION_ID_ATTEMPTS) | ||
2152 | return 0; | ||
2153 | return 1; | ||
2154 | } | ||