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 | } | ||
