Annotation of src/usr.bin/openssl/s_server.c, Revision 1.46
1.46 ! jsing 1: /* $OpenBSD: s_server.c,v 1.45 2021/03/17 18:08:32 jsing Exp $ */
1.1 jsing 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/socket.h>
151:
152: #include <assert.h>
153: #include <ctype.h>
154: #include <stdio.h>
155: #include <stdlib.h>
156: #include <limits.h>
157: #include <string.h>
158: #include <unistd.h>
1.7 deraadt 159: #include <poll.h>
1.1 jsing 160:
161: #include "apps.h"
162:
163: #include <openssl/bn.h>
164: #include <openssl/err.h>
165: #include <openssl/lhash.h>
166: #include <openssl/ocsp.h>
167: #include <openssl/pem.h>
168: #include <openssl/ssl.h>
169: #include <openssl/x509.h>
170:
171: #ifndef OPENSSL_NO_DH
172: #include <openssl/dh.h>
173: #endif
174:
175: #include <openssl/rsa.h>
176:
177: #include "s_apps.h"
178: #include "timeouts.h"
179:
1.42 inoguchi 180: static void s_server_init(void);
181: static void sv_usage(void);
182: static void print_stats(BIO *bp, SSL_CTX *ctx);
1.1 jsing 183: static int sv_body(char *hostname, int s, unsigned char *context);
184: static void close_accept_socket(void);
1.41 inoguchi 185: static int init_ssl_connection(SSL *s);
1.1 jsing 186: #ifndef OPENSSL_NO_DH
187: static DH *load_dh_param(const char *dhfile);
188: #endif
1.42 inoguchi 189: static int www_body(char *hostname, int s, unsigned char *context);
190: static int generate_session_id(const SSL *ssl, unsigned char *id,
191: unsigned int *id_len);
192: static int ssl_servername_cb(SSL *s, int *ad, void *arg);
193: static int cert_status_cb(SSL * s, void *arg);
194: static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
195: const unsigned char *in, unsigned int inlen, void *arg);
1.1 jsing 196: /* static int load_CA(SSL_CTX *ctx, char *file);*/
197:
198: #define BUFSIZZ 16*1024
199: static int bufsize = BUFSIZZ;
200: static int accept_socket = -1;
201:
202: #define TEST_CERT "server.pem"
203: #define TEST_CERT2 "server2.pem"
204:
205: static int s_server_session_id_context = 1; /* anything will do */
206: static SSL_CTX *ctx = NULL;
207: static SSL_CTX *ctx2 = NULL;
208: static BIO *bio_s_out = NULL;
1.42 inoguchi 209:
210: static int local_argc = 0;
211: static char **local_argv;
1.1 jsing 212:
1.39 inoguchi 213: /* This is a context that we pass to callbacks */
214: typedef struct tlsextctx_st {
215: char *servername;
216: BIO *biodebug;
217: int extension_error;
218: } tlsextctx;
1.1 jsing 219:
1.39 inoguchi 220: /* Structure passed to cert status callback */
221: typedef struct tlsextstatusctx_st {
222: /* Default responder to use */
223: char *host, *path, *port;
224: int use_ssl;
225: int timeout;
226: BIO *err;
227: int verbose;
228: } tlsextstatusctx;
229:
1.42 inoguchi 230: /* This the context that we pass to alpn_cb */
231: typedef struct tlsextalpnctx_st {
232: unsigned char *data;
233: unsigned short len;
234: } tlsextalpnctx;
235:
1.39 inoguchi 236: static struct {
237: char *alpn_in;
238: char *npn_in; /* Ignored. */
239: int bugs;
240: char *CAfile;
241: char *CApath;
1.45 jsing 242: #ifndef OPENSSL_NO_DTLS
1.39 inoguchi 243: int cert_chain;
244: #endif
1.40 inoguchi 245: char *cert_file;
246: char *cert_file2;
247: int cert_format;
1.39 inoguchi 248: char *cipher;
249: unsigned char *context;
1.40 inoguchi 250: int crlf;
251: char *dcert_file;
252: int dcert_format;
253: int debug;
1.39 inoguchi 254: char *dhfile;
1.40 inoguchi 255: char *dkey_file;
256: int dkey_format;
1.39 inoguchi 257: char *dpassarg;
258: int enable_timeouts;
259: const char *errstr;
260: char *groups_in;
1.40 inoguchi 261: char *key_file;
262: char *key_file2;
263: int key_format;
1.39 inoguchi 264: char *keymatexportlabel;
265: int keymatexportlen;
266: uint16_t max_version;
267: uint16_t min_version;
268: const SSL_METHOD *meth;
1.40 inoguchi 269: int msg;
1.39 inoguchi 270: char *named_curve;
1.40 inoguchi 271: int nbio;
272: int nbio_test;
1.39 inoguchi 273: int no_cache;
274: int nocert;
275: int no_dhe;
276: int no_ecdhe;
277: int no_tmp_rsa; /* No-op. */
278: int off;
279: char *passarg;
280: short port;
1.40 inoguchi 281: int quiet;
282: int server_verify;
1.39 inoguchi 283: char *session_id_prefix;
284: long socket_mtu;
285: int socket_type;
286: #ifndef OPENSSL_NO_SRTP
287: char *srtp_profiles;
288: #endif
289: int state;
290: tlsextstatusctx tlscstatp;
291: tlsextctx tlsextcbp;
1.40 inoguchi 292: int tlsextdebug;
293: int tlsextstatus;
1.39 inoguchi 294: X509_VERIFY_PARAM *vpm;
295: int www;
296: } s_server_config;
297:
298: static int
299: s_server_opt_context(char *arg)
300: {
301: s_server_config.context = (unsigned char *) arg;
302: return (0);
303: }
304:
305: static int
306: s_server_opt_keymatexportlen(char *arg)
307: {
308: s_server_config.keymatexportlen = strtonum(arg, 1, INT_MAX,
309: &s_server_config.errstr);
310: if (s_server_config.errstr != NULL) {
311: BIO_printf(bio_err, "invalid argument %s: %s\n",
312: arg, s_server_config.errstr);
313: return (1);
314: }
315: return (0);
316: }
1.1 jsing 317:
1.45 jsing 318: #ifndef OPENSSL_NO_DTLS
1.39 inoguchi 319: static int
320: s_server_opt_mtu(char *arg)
321: {
322: s_server_config.socket_mtu = strtonum(arg, 0, LONG_MAX,
323: &s_server_config.errstr);
324: if (s_server_config.errstr != NULL) {
325: BIO_printf(bio_err, "invalid argument %s: %s\n",
326: arg, s_server_config.errstr);
327: return (1);
328: }
329: return (0);
330: }
1.45 jsing 331: #endif
1.39 inoguchi 332:
1.45 jsing 333: #ifndef OPENSSL_NO_DTLS
1.39 inoguchi 334: static int
1.45 jsing 335: s_server_opt_protocol_version_dtls(void)
1.39 inoguchi 336: {
337: s_server_config.meth = DTLS_server_method();
338: s_server_config.socket_type = SOCK_DGRAM;
339: return (0);
340: }
1.1 jsing 341: #endif
342:
1.45 jsing 343: #ifndef OPENSSL_NO_DTLS1
344: static int
345: s_server_opt_protocol_version_dtls1(void)
346: {
347: s_server_config.meth = DTLS_server_method();
348: s_server_config.min_version = DTLS1_VERSION;
349: s_server_config.max_version = DTLS1_VERSION;
350: s_server_config.socket_type = SOCK_DGRAM;
351: return (0);
352: }
353: #endif
354:
355: #ifndef OPENSSL_NO_DTLS1_2
356: static int
357: s_server_opt_protocol_version_dtls1_2(void)
358: {
359: s_server_config.meth = DTLS_server_method();
360: s_server_config.min_version = DTLS1_2_VERSION;
361: s_server_config.max_version = DTLS1_2_VERSION;
362: s_server_config.socket_type = SOCK_DGRAM;
363: return (0);
364: }
365: #endif
366:
1.39 inoguchi 367: static int
1.46 ! jsing 368: s_server_opt_protocol_version_tls1(void)
1.39 inoguchi 369: {
370: s_server_config.min_version = TLS1_VERSION;
371: s_server_config.max_version = TLS1_VERSION;
372: return (0);
373: }
374:
375: static int
1.46 ! jsing 376: s_server_opt_protocol_version_tls1_1(void)
1.39 inoguchi 377: {
378: s_server_config.min_version = TLS1_1_VERSION;
379: s_server_config.max_version = TLS1_1_VERSION;
380: return (0);
381: }
382:
383: static int
1.46 ! jsing 384: s_server_opt_protocol_version_tls1_2(void)
1.39 inoguchi 385: {
386: s_server_config.min_version = TLS1_2_VERSION;
387: s_server_config.max_version = TLS1_2_VERSION;
388: return (0);
389: }
390:
391: static int
1.46 ! jsing 392: s_server_opt_protocol_version_tls1_3(void)
1.39 inoguchi 393: {
394: s_server_config.min_version = TLS1_3_VERSION;
395: s_server_config.max_version = TLS1_3_VERSION;
396: return (0);
397: }
398:
399: static int
400: s_server_opt_nbio_test(void)
401: {
1.40 inoguchi 402: s_server_config.nbio = 1;
403: s_server_config.nbio_test = 1;
1.39 inoguchi 404: return (0);
405: }
406:
407: static int
408: s_server_opt_port(char *arg)
409: {
410: if (!extract_port(arg, &s_server_config.port))
411: return (1);
412: return (0);
413: }
414:
415: static int
416: s_server_opt_status_timeout(char *arg)
417: {
1.40 inoguchi 418: s_server_config.tlsextstatus = 1;
1.39 inoguchi 419: s_server_config.tlscstatp.timeout = strtonum(arg, 0, INT_MAX,
420: &s_server_config.errstr);
421: if (s_server_config.errstr != NULL) {
422: BIO_printf(bio_err, "invalid argument %s: %s\n",
423: arg, s_server_config.errstr);
424: return (1);
425: }
426: return (0);
427: }
428:
429: static int
430: s_server_opt_status_url(char *arg)
431: {
1.40 inoguchi 432: s_server_config.tlsextstatus = 1;
1.39 inoguchi 433: if (!OCSP_parse_url(arg, &s_server_config.tlscstatp.host,
434: &s_server_config.tlscstatp.port, &s_server_config.tlscstatp.path,
435: &s_server_config.tlscstatp.use_ssl)) {
436: BIO_printf(bio_err, "Error parsing URL\n");
437: return (1);
438: }
439: return (0);
440: }
441:
442: static int
443: s_server_opt_status_verbose(void)
444: {
1.40 inoguchi 445: s_server_config.tlsextstatus = 1;
1.39 inoguchi 446: s_server_config.tlscstatp.verbose = 1;
447: return (0);
448: }
449:
450: static int
451: s_server_opt_verify(char *arg)
452: {
1.40 inoguchi 453: s_server_config.server_verify = SSL_VERIFY_PEER |
1.39 inoguchi 454: SSL_VERIFY_CLIENT_ONCE;
455: verify_depth = strtonum(arg, 0, INT_MAX, &s_server_config.errstr);
456: if (s_server_config.errstr != NULL) {
457: BIO_printf(bio_err, "invalid argument %s: %s\n",
458: arg, s_server_config.errstr);
459: return (1);
460: }
461: BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
462: return (0);
463: }
464:
465: static int
466: s_server_opt_verify_fail(char *arg)
467: {
1.40 inoguchi 468: s_server_config.server_verify = SSL_VERIFY_PEER |
1.39 inoguchi 469: SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
470: verify_depth = strtonum(arg, 0, INT_MAX, &s_server_config.errstr);
471: if (s_server_config.errstr != NULL) {
472: BIO_printf(bio_err, "invalid argument %s: %s\n",
473: arg, s_server_config.errstr);
474: return (1);
475: }
476: BIO_printf(bio_err, "verify depth is %d, must return a certificate\n",
477: verify_depth);
478: return (0);
479: }
480:
481: static int
482: s_server_opt_verify_param(int argc, char **argv, int *argsused)
483: {
484: char **pargs = argv;
485: int pargc = argc;
486: int badarg = 0;
1.1 jsing 487:
1.39 inoguchi 488: if (!args_verify(&pargs, &pargc, &badarg, bio_err,
489: &s_server_config.vpm)) {
490: BIO_printf(bio_err, "unknown option %s\n", *argv);
491: return (1);
492: }
493: if (badarg)
494: return (1);
495:
496: *argsused = argc - pargc;
497: return (0);
498: }
1.1 jsing 499:
1.39 inoguchi 500: static const struct option s_server_options[] = {
1.44 tb 501: {
502: .name = "4",
503: .type = OPTION_DISCARD,
504: },
505: {
506: .name = "6",
507: .type = OPTION_DISCARD,
508: },
1.39 inoguchi 509: {
510: .name = "accept",
511: .argname = "port",
512: .desc = "Port to accept on (default is 4433)",
513: .type = OPTION_ARG_FUNC,
514: .opt.argfunc = s_server_opt_port,
515: },
516: {
517: .name = "alpn",
518: .argname = "protocols",
519: .desc = "Set the advertised protocols for the ALPN extension"
520: " (comma-separated list)",
521: .type = OPTION_ARG,
522: .opt.arg = &s_server_config.alpn_in,
523: },
524: {
525: .name = "bugs",
526: .desc = "Turn on SSL bug compatibility",
527: .type = OPTION_FLAG,
528: .opt.flag = &s_server_config.bugs,
529: },
530: {
531: .name = "CAfile",
532: .argname = "file",
533: .desc = "PEM format file of CA certificates",
534: .type = OPTION_ARG,
535: .opt.arg = &s_server_config.CAfile,
536: },
537: {
538: .name = "CApath",
539: .argname = "directory",
540: .desc = "PEM format directory of CA certificates",
541: .type = OPTION_ARG,
542: .opt.arg = &s_server_config.CApath,
543: },
544: {
545: .name = "cert",
546: .argname = "file",
547: .desc = "Certificate file to use\n"
548: "(default is " TEST_CERT ")",
549: .type = OPTION_ARG,
1.40 inoguchi 550: .opt.arg = &s_server_config.cert_file,
1.39 inoguchi 551: },
552: {
553: .name = "cert2",
554: .argname = "file",
555: .desc = "Certificate file to use for servername\n"
556: "(default is " TEST_CERT2 ")",
557: .type = OPTION_ARG,
1.40 inoguchi 558: .opt.arg = &s_server_config.cert_file2,
1.39 inoguchi 559: },
560: {
561: .name = "certform",
562: .argname = "fmt",
563: .desc = "Certificate format (PEM or DER) PEM default",
564: .type = OPTION_ARG_FORMAT,
1.40 inoguchi 565: .opt.value = &s_server_config.cert_format,
1.39 inoguchi 566: },
1.45 jsing 567: #ifndef OPENSSL_NO_DTLS
1.39 inoguchi 568: {
569: .name = "chain",
570: .type = OPTION_FLAG,
571: .opt.flag = &s_server_config.cert_chain,
572: },
573: #endif
574: {
575: .name = "cipher",
576: .argname = "list",
577: .desc = "List of ciphers to enable (see `openssl ciphers`)",
578: .type = OPTION_ARG,
579: .opt.arg = &s_server_config.cipher,
580: },
581: {
582: .name = "context",
583: .argname = "id",
584: .desc = "Set session ID context",
585: .type = OPTION_ARG_FUNC,
586: .opt.argfunc = s_server_opt_context,
587: },
588: {
589: .name = "crlf",
590: .desc = "Convert LF from terminal into CRLF",
591: .type = OPTION_FLAG,
1.40 inoguchi 592: .opt.flag = &s_server_config.crlf,
1.39 inoguchi 593: },
594: {
595: .name = "dcert",
596: .argname = "file",
597: .desc = "Second certificate file to use (usually for DSA)",
598: .type = OPTION_ARG,
1.40 inoguchi 599: .opt.arg = &s_server_config.dcert_file,
1.39 inoguchi 600: },
601: {
602: .name = "dcertform",
603: .argname = "fmt",
604: .desc = "Second certificate format (PEM or DER) PEM default",
605: .type = OPTION_ARG_FORMAT,
1.40 inoguchi 606: .opt.value = &s_server_config.dcert_format,
1.39 inoguchi 607: },
608: {
609: .name = "debug",
610: .desc = "Print more output",
611: .type = OPTION_FLAG,
1.40 inoguchi 612: .opt.flag = &s_server_config.debug,
1.39 inoguchi 613: },
614: {
615: .name = "dhparam",
616: .argname = "file",
617: .desc = "DH parameter file to use, in cert file if not specified",
618: .type = OPTION_ARG,
619: .opt.arg = &s_server_config.dhfile,
620: },
621: {
622: .name = "dkey",
623: .argname = "file",
624: .desc = "Second private key file to use (usually for DSA)",
625: .type = OPTION_ARG,
1.40 inoguchi 626: .opt.arg = &s_server_config.dkey_file,
1.39 inoguchi 627: },
628: {
629: .name = "dkeyform",
630: .argname = "fmt",
631: .desc = "Second key format (PEM or DER) PEM default",
632: .type = OPTION_ARG_FORMAT,
1.40 inoguchi 633: .opt.value = &s_server_config.dkey_format,
1.39 inoguchi 634: },
635: {
636: .name = "dpass",
637: .argname = "arg",
638: .desc = "Second private key file pass phrase source",
639: .type = OPTION_ARG,
640: .opt.arg = &s_server_config.dpassarg,
641: },
1.45 jsing 642: #ifndef OPENSSL_NO_DTLS
643: {
644: .name = "dtls",
645: .desc = "Use any version of DTLS",
646: .type = OPTION_FUNC,
647: .opt.func = s_server_opt_protocol_version_dtls,
648: },
649: #endif
1.39 inoguchi 650: #ifndef OPENSSL_NO_DTLS1
651: {
652: .name = "dtls1",
1.45 jsing 653: .desc = "Just use DTLSv1",
1.39 inoguchi 654: .type = OPTION_FUNC,
1.45 jsing 655: .opt.func = s_server_opt_protocol_version_dtls1,
656: },
657: #endif
658: #ifndef OPENSSL_NO_DTLS1_2
659: {
660: .name = "dtls1_2",
661: .desc = "Just use DTLSv1.2",
662: .type = OPTION_FUNC,
663: .opt.func = s_server_opt_protocol_version_dtls1_2,
1.39 inoguchi 664: },
665: #endif
666: {
667: .name = "groups",
668: .argname = "list",
669: .desc = "Specify EC groups (colon-separated list)",
670: .type = OPTION_ARG,
671: .opt.arg = &s_server_config.groups_in,
672: },
673: {
674: .name = "HTTP",
675: .desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>",
676: .type = OPTION_VALUE,
677: .opt.value = &s_server_config.www,
678: .value = 3,
679: },
680: {
681: .name = "id_prefix",
682: .argname = "arg",
683: .desc = "Generate SSL/TLS session IDs prefixed by 'arg'",
684: .type = OPTION_ARG,
685: .opt.arg = &s_server_config.session_id_prefix,
686: },
687: {
688: .name = "key",
689: .argname = "file",
690: .desc = "Private Key file to use, in cert file if\n"
691: "not specified (default is " TEST_CERT ")",
692: .type = OPTION_ARG,
1.40 inoguchi 693: .opt.arg = &s_server_config.key_file,
1.39 inoguchi 694: },
695: {
696: .name = "key2",
697: .argname = "file",
698: .desc = "Private Key file to use for servername, in cert file if\n"
699: "not specified (default is " TEST_CERT2 ")",
700: .type = OPTION_ARG,
1.40 inoguchi 701: .opt.arg = &s_server_config.key_file2,
1.39 inoguchi 702: },
703: {
704: .name = "keyform",
705: .argname = "fmt",
706: .desc = "Key format (PEM or DER) PEM default",
707: .type = OPTION_ARG_FORMAT,
1.40 inoguchi 708: .opt.value = &s_server_config.key_format,
1.39 inoguchi 709: },
710: {
711: .name = "keymatexport",
712: .argname = "label",
713: .desc = "Export keying material using label",
714: .type = OPTION_ARG,
715: .opt.arg = &s_server_config.keymatexportlabel,
716: },
717: {
718: .name = "keymatexportlen",
719: .argname = "len",
720: .desc = "Export len bytes of keying material (default 20)",
721: .type = OPTION_ARG_FUNC,
722: .opt.argfunc = s_server_opt_keymatexportlen,
723: },
724: {
725: .name = "legacy_renegotiation",
726: .type = OPTION_DISCARD,
727: },
728: {
729: .name = "msg",
730: .desc = "Show protocol messages",
731: .type = OPTION_FLAG,
1.40 inoguchi 732: .opt.flag = &s_server_config.msg,
1.39 inoguchi 733: },
1.45 jsing 734: #ifndef OPENSSL_NO_DTLS
1.39 inoguchi 735: {
736: .name = "mtu",
737: .argname = "mtu",
738: .desc = "Set link layer MTU",
739: .type = OPTION_ARG_FUNC,
740: .opt.argfunc = s_server_opt_mtu,
741: },
742: #endif
743: {
744: .name = "named_curve",
745: .argname = "arg",
746: .type = OPTION_ARG,
747: .opt.arg = &s_server_config.named_curve,
748: },
749: {
750: .name = "nbio",
751: .desc = "Run with non-blocking I/O",
752: .type = OPTION_FLAG,
1.40 inoguchi 753: .opt.flag = &s_server_config.nbio,
1.39 inoguchi 754: },
755: {
756: .name = "nbio_test",
757: .desc = "Test with the non-blocking test bio",
758: .type = OPTION_FUNC,
759: .opt.func = s_server_opt_nbio_test,
760: },
761: {
762: .name = "nextprotoneg",
763: .argname = "arg",
764: .type = OPTION_ARG,
765: .opt.arg = &s_server_config.npn_in, /* Ignored. */
766: },
767: {
768: .name = "no_cache",
769: .desc = "Disable session cache",
770: .type = OPTION_FLAG,
771: .opt.flag = &s_server_config.no_cache,
772: },
773: {
774: .name = "no_comp",
775: .desc = "Disable SSL/TLS compression",
776: .type = OPTION_VALUE_OR,
777: .opt.value = &s_server_config.off,
778: .value = SSL_OP_NO_COMPRESSION,
779: },
780: {
781: .name = "no_dhe",
782: .desc = "Disable ephemeral DH",
783: .type = OPTION_FLAG,
784: .opt.flag = &s_server_config.no_dhe,
785: },
786: {
787: .name = "no_ecdhe",
788: .desc = "Disable ephemeral ECDH",
789: .type = OPTION_FLAG,
790: .opt.flag = &s_server_config.no_ecdhe,
791: },
792: {
793: .name = "no_ticket",
794: .desc = "Disable use of RFC4507bis session tickets",
795: .type = OPTION_VALUE_OR,
796: .opt.value = &s_server_config.off,
797: .value = SSL_OP_NO_TICKET,
798: },
799: {
800: .name = "no_ssl2",
801: .type = OPTION_VALUE_OR,
802: .opt.value = &s_server_config.off,
803: .value = SSL_OP_NO_SSLv2,
804: },
805: {
806: .name = "no_ssl3",
807: .type = OPTION_VALUE_OR,
808: .opt.value = &s_server_config.off,
809: .value = SSL_OP_NO_SSLv3,
810: },
811: {
812: .name = "no_tls1",
813: .desc = "Just disable TLSv1",
814: .type = OPTION_VALUE_OR,
815: .opt.value = &s_server_config.off,
816: .value = SSL_OP_NO_TLSv1,
817: },
818: {
819: .name = "no_tls1_1",
820: .desc = "Just disable TLSv1.1",
821: .type = OPTION_VALUE_OR,
822: .opt.value = &s_server_config.off,
823: .value = SSL_OP_NO_TLSv1_1,
824: },
825: {
826: .name = "no_tls1_2",
827: .desc = "Just disable TLSv1.2",
828: .type = OPTION_VALUE_OR,
829: .opt.value = &s_server_config.off,
830: .value = SSL_OP_NO_TLSv1_2,
831: },
832: {
833: .name = "no_tls1_3",
834: .desc = "Just disable TLSv1.3",
835: .type = OPTION_VALUE_OR,
836: .opt.value = &s_server_config.off,
837: .value = SSL_OP_NO_TLSv1_3,
838: },
839: {
840: .name = "no_tmp_rsa",
841: .type = OPTION_DISCARD,
842: },
843: {
844: .name = "nocert",
845: .desc = "Don't use any certificates (Anon-DH)",
846: .type = OPTION_FLAG,
847: .opt.flag = &s_server_config.nocert,
848: },
849: {
850: .name = "pass",
851: .argname = "arg",
852: .desc = "Private key file pass phrase source",
853: .type = OPTION_ARG,
854: .opt.arg = &s_server_config.passarg,
855: },
856: {
857: .name = "port",
858: .argname = "port",
859: .type = OPTION_ARG_FUNC,
860: .opt.argfunc = s_server_opt_port,
861: },
862: {
863: .name = "quiet",
864: .desc = "Inhibit printing of session and certificate information",
865: .type = OPTION_FLAG,
1.40 inoguchi 866: .opt.flag = &s_server_config.quiet,
1.39 inoguchi 867: },
868: {
869: .name = "servername",
870: .argname = "name",
871: .desc = "Servername for HostName TLS extension",
872: .type = OPTION_ARG,
873: .opt.arg = &s_server_config.tlsextcbp.servername,
874: },
875: {
876: .name = "servername_fatal",
877: .desc = "On mismatch send fatal alert (default warning alert)",
878: .type = OPTION_VALUE,
879: .opt.value = &s_server_config.tlsextcbp.extension_error,
880: .value = SSL_TLSEXT_ERR_ALERT_FATAL,
881: },
882: {
883: .name = "serverpref",
884: .desc = "Use server's cipher preferences",
885: .type = OPTION_VALUE_OR,
886: .opt.value = &s_server_config.off,
887: .value = SSL_OP_CIPHER_SERVER_PREFERENCE,
888: },
889: {
890: .name = "state",
891: .desc = "Print the SSL states",
892: .type = OPTION_FLAG,
893: .opt.flag = &s_server_config.state,
894: },
895: {
896: .name = "status",
897: .desc = "Respond to certificate status requests",
898: .type = OPTION_FLAG,
1.40 inoguchi 899: .opt.flag = &s_server_config.tlsextstatus,
1.39 inoguchi 900: },
901: {
902: .name = "status_timeout",
903: .argname = "nsec",
904: .desc = "Status request responder timeout",
905: .type = OPTION_ARG_FUNC,
906: .opt.argfunc = s_server_opt_status_timeout,
907: },
908: {
909: .name = "status_url",
910: .argname = "url",
911: .desc = "Status request fallback URL",
912: .type = OPTION_ARG_FUNC,
913: .opt.argfunc = s_server_opt_status_url,
914: },
915: {
916: .name = "status_verbose",
917: .desc = "Enable status request verbose printout",
918: .type = OPTION_FUNC,
919: .opt.func = s_server_opt_status_verbose,
920: },
1.45 jsing 921: #ifndef OPENSSL_NO_DTLS
1.39 inoguchi 922: {
923: .name = "timeout",
924: .desc = "Enable timeouts",
925: .type = OPTION_FLAG,
926: .opt.flag = &s_server_config.enable_timeouts,
927: },
928: #endif
929: {
930: .name = "tls1",
931: .desc = "Just talk TLSv1",
932: .type = OPTION_FUNC,
1.46 ! jsing 933: .opt.func = s_server_opt_protocol_version_tls1,
1.39 inoguchi 934: },
935: {
936: .name = "tls1_1",
937: .desc = "Just talk TLSv1.1",
938: .type = OPTION_FUNC,
1.46 ! jsing 939: .opt.func = s_server_opt_protocol_version_tls1_1,
1.39 inoguchi 940: },
941: {
942: .name = "tls1_2",
943: .desc = "Just talk TLSv1.2",
944: .type = OPTION_FUNC,
1.46 ! jsing 945: .opt.func = s_server_opt_protocol_version_tls1_2,
1.39 inoguchi 946: },
947: {
948: .name = "tls1_3",
949: .desc = "Just talk TLSv1.3",
950: .type = OPTION_FUNC,
1.46 ! jsing 951: .opt.func = s_server_opt_protocol_version_tls1_3,
1.39 inoguchi 952: },
953: {
954: .name = "tlsextdebug",
955: .desc = "Hex dump of all TLS extensions received",
956: .type = OPTION_FLAG,
1.40 inoguchi 957: .opt.flag = &s_server_config.tlsextdebug,
1.39 inoguchi 958: },
959: #ifndef OPENSSL_NO_SRTP
960: {
961: .name = "use_srtp",
962: .argname = "profiles",
963: .desc = "Offer SRTP key management with a colon-separated profile list",
964: .type = OPTION_ARG,
965: .opt.arg = &s_server_config.srtp_profiles,
966: },
967: #endif
968: {
969: .name = "Verify",
970: .argname = "depth",
971: .desc = "Turn on peer certificate verification, must have a cert",
972: .type = OPTION_ARG_FUNC,
973: .opt.argfunc = s_server_opt_verify_fail,
974: },
975: {
976: .name = "verify",
977: .argname = "depth",
978: .desc = "Turn on peer certificate verification",
979: .type = OPTION_ARG_FUNC,
980: .opt.argfunc = s_server_opt_verify,
981: },
982: {
983: .name = "verify_return_error",
984: .desc = "Return verification error",
985: .type = OPTION_FLAG,
986: .opt.flag = &verify_return_error,
987: },
988: {
989: .name = "WWW",
990: .desc = "Respond to a 'GET /<path> HTTP/1.0' with file ./<path>",
991: .type = OPTION_VALUE,
992: .opt.value = &s_server_config.www,
993: .value = 2,
994: },
995: {
996: .name = "www",
997: .desc = "Respond to a 'GET /' with a status page",
998: .type = OPTION_VALUE,
999: .opt.value = &s_server_config.www,
1000: .value = 1,
1001: },
1002: {
1003: .name = NULL,
1004: .desc = "",
1005: .type = OPTION_ARGV_FUNC,
1006: .opt.argvfunc = s_server_opt_verify_param,
1007: },
1008: { NULL },
1009: };
1.1 jsing 1010:
1011: static void
1012: s_server_init(void)
1013: {
1014: accept_socket = -1;
1.39 inoguchi 1015: s_server_config.cipher = NULL;
1.40 inoguchi 1016: s_server_config.server_verify = SSL_VERIFY_NONE;
1017: s_server_config.dcert_file = NULL;
1018: s_server_config.dkey_file = NULL;
1019: s_server_config.cert_file = TEST_CERT;
1020: s_server_config.key_file = NULL;
1021: s_server_config.cert_file2 = TEST_CERT2;
1022: s_server_config.key_file2 = NULL;
1.1 jsing 1023: ctx2 = NULL;
1.40 inoguchi 1024: s_server_config.nbio = 0;
1025: s_server_config.nbio_test = 0;
1.1 jsing 1026: ctx = NULL;
1.39 inoguchi 1027: s_server_config.www = 0;
1.1 jsing 1028:
1029: bio_s_out = NULL;
1.40 inoguchi 1030: s_server_config.debug = 0;
1031: s_server_config.msg = 0;
1032: s_server_config.quiet = 0;
1.1 jsing 1033: }
1034:
1035: static void
1036: sv_usage(void)
1037: {
1.39 inoguchi 1038: fprintf(stderr, "usage: s_server "
1039: "[-accept port] [-alpn protocols] [-bugs] [-CAfile file]\n"
1040: " [-CApath directory] [-cert file] [-cert2 file]\n"
1041: " [-certform der | pem] [-cipher cipherlist]\n"
1042: " [-context id] [-crl_check] [-crl_check_all] [-crlf]\n"
1043: " [-dcert file] [-dcertform der | pem] [-debug]\n"
1044: " [-dhparam file] [-dkey file] [-dkeyform der | pem]\n"
1.45 jsing 1045: " [-dpass arg] [-dtls] [-dtls1] [-dtls1_2] [-groups list] [-HTTP]\n"
1.39 inoguchi 1046: " [-id_prefix arg] [-key keyfile] [-key2 keyfile]\n"
1047: " [-keyform der | pem] [-keymatexport label]\n"
1048: " [-keymatexportlen len] [-msg] [-mtu mtu]\n"
1049: " [-named_curve arg] [-nbio] [-nbio_test] [-no_cache]\n"
1050: " [-no_dhe] [-no_ecdhe] [-no_ticket] [-no_tls1]\n"
1051: " [-no_tls1_1] [-no_tls1_2] [-no_tls1_3] [-no_tmp_rsa]\n"
1052: " [-nocert] [-pass arg] [-quiet] [-servername name]\n"
1053: " [-servername_fatal] [-serverpref] [-state] [-status]\n"
1054: " [-status_timeout nsec] [-status_url url]\n"
1055: " [-status_verbose] [-timeout] [-tls1] [-tls1_1]\n"
1056: " [-tls1_2] [-tls1_3] [-tlsextdebug] [-use_srtp profiles]\n"
1057: " [-Verify depth] [-verify depth] [-verify_return_error]\n"
1058: " [-WWW] [-www]\n");
1059: fprintf(stderr, "\n");
1060: options_usage(s_server_options);
1061: fprintf(stderr, "\n");
1.1 jsing 1062: }
1063:
1064: int
1065: s_server_main(int argc, char *argv[])
1066: {
1.39 inoguchi 1067: int badop = 0;
1.1 jsing 1068: int ret = 1;
1.39 inoguchi 1069: char *pass = NULL;
1070: char *dpass = NULL;
1.1 jsing 1071: X509 *s_cert = NULL, *s_dcert = NULL;
1072: EVP_PKEY *s_key = NULL, *s_dkey = NULL;
1073: EVP_PKEY *s_key2 = NULL;
1074: X509 *s_cert2 = NULL;
1.8 jsing 1075: tlsextalpnctx alpn_ctx = { NULL, 0 };
1.20 doug 1076:
1077: if (single_execution) {
1.25 deraadt 1078: if (pledge("stdio rpath inet dns tty", NULL) == -1) {
1.20 doug 1079: perror("pledge");
1.22 doug 1080: exit(1);
1081: }
1.20 doug 1082: }
1083:
1.39 inoguchi 1084: memset(&s_server_config, 0, sizeof(s_server_config));
1085: s_server_config.keymatexportlen = 20;
1086: s_server_config.meth = TLS_server_method();
1087: s_server_config.port = PORT;
1.40 inoguchi 1088: s_server_config.cert_file = TEST_CERT;
1089: s_server_config.cert_file2 = TEST_CERT2;
1090: s_server_config.cert_format = FORMAT_PEM;
1091: s_server_config.dcert_format = FORMAT_PEM;
1092: s_server_config.dkey_format = FORMAT_PEM;
1093: s_server_config.key_format = FORMAT_PEM;
1094: s_server_config.server_verify = SSL_VERIFY_NONE;
1.39 inoguchi 1095: s_server_config.socket_type = SOCK_STREAM;
1096: s_server_config.tlscstatp.timeout = -1;
1.43 inoguchi 1097: s_server_config.tlsextcbp.extension_error =
1098: SSL_TLSEXT_ERR_ALERT_WARNING;
1.1 jsing 1099:
1100: local_argc = argc;
1101: local_argv = argv;
1102:
1103: s_server_init();
1104:
1105: verify_depth = 0;
1106:
1.39 inoguchi 1107: if (options_parse(argc, argv, s_server_options, NULL, NULL) != 0) {
1108: badop = 1;
1109: goto bad;
1.1 jsing 1110: }
1111: if (badop) {
1.30 jsing 1112: bad:
1.39 inoguchi 1113: if (s_server_config.errstr == NULL)
1.1 jsing 1114: sv_usage();
1115: goto end;
1116: }
1117:
1.43 inoguchi 1118: if (!app_passwd(bio_err, s_server_config.passarg,
1119: s_server_config.dpassarg, &pass, &dpass)) {
1.1 jsing 1120: BIO_printf(bio_err, "Error getting password\n");
1121: goto end;
1122: }
1.40 inoguchi 1123: if (s_server_config.key_file == NULL)
1124: s_server_config.key_file = s_server_config.cert_file;
1125: if (s_server_config.key_file2 == NULL)
1126: s_server_config.key_file2 = s_server_config.cert_file2;
1.1 jsing 1127:
1.39 inoguchi 1128: if (s_server_config.nocert == 0) {
1.43 inoguchi 1129: s_key = load_key(bio_err, s_server_config.key_file,
1130: s_server_config.key_format, 0, pass,
1.1 jsing 1131: "server certificate private key file");
1132: if (!s_key) {
1133: ERR_print_errors(bio_err);
1134: goto end;
1135: }
1.43 inoguchi 1136: s_cert = load_cert(bio_err, s_server_config.cert_file,
1137: s_server_config.cert_format,
1.17 bcook 1138: NULL, "server certificate file");
1.1 jsing 1139:
1140: if (!s_cert) {
1141: ERR_print_errors(bio_err);
1142: goto end;
1143: }
1.39 inoguchi 1144: if (s_server_config.tlsextcbp.servername) {
1.43 inoguchi 1145: s_key2 = load_key(bio_err, s_server_config.key_file2,
1146: s_server_config.key_format, 0, pass,
1.1 jsing 1147: "second server certificate private key file");
1148: if (!s_key2) {
1149: ERR_print_errors(bio_err);
1150: goto end;
1151: }
1.43 inoguchi 1152: s_cert2 = load_cert(bio_err, s_server_config.cert_file2,
1153: s_server_config.cert_format,
1.17 bcook 1154: NULL, "second server certificate file");
1.1 jsing 1155:
1156: if (!s_cert2) {
1157: ERR_print_errors(bio_err);
1158: goto end;
1159: }
1160: }
1161: }
1.8 jsing 1162: alpn_ctx.data = NULL;
1.39 inoguchi 1163: if (s_server_config.alpn_in) {
1.8 jsing 1164: unsigned short len;
1.43 inoguchi 1165: alpn_ctx.data = next_protos_parse(&len,
1166: s_server_config.alpn_in);
1.8 jsing 1167: if (alpn_ctx.data == NULL)
1168: goto end;
1169: alpn_ctx.len = len;
1170: }
1.1 jsing 1171:
1.40 inoguchi 1172: if (s_server_config.dcert_file) {
1.1 jsing 1173:
1.40 inoguchi 1174: if (s_server_config.dkey_file == NULL)
1175: s_server_config.dkey_file = s_server_config.dcert_file;
1.1 jsing 1176:
1.43 inoguchi 1177: s_dkey = load_key(bio_err, s_server_config.dkey_file,
1178: s_server_config.dkey_format,
1.17 bcook 1179: 0, dpass, "second certificate private key file");
1.1 jsing 1180: if (!s_dkey) {
1181: ERR_print_errors(bio_err);
1182: goto end;
1183: }
1.43 inoguchi 1184: s_dcert = load_cert(bio_err, s_server_config.dcert_file,
1185: s_server_config.dcert_format,
1.17 bcook 1186: NULL, "second server certificate file");
1.1 jsing 1187:
1188: if (!s_dcert) {
1189: ERR_print_errors(bio_err);
1190: goto end;
1191: }
1192: }
1193: if (bio_s_out == NULL) {
1.43 inoguchi 1194: if (s_server_config.quiet && !s_server_config.debug &&
1195: !s_server_config.msg) {
1.1 jsing 1196: bio_s_out = BIO_new(BIO_s_null());
1197: } else {
1198: if (bio_s_out == NULL)
1199: bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
1200: }
1201: }
1.39 inoguchi 1202: if (s_server_config.nocert) {
1.40 inoguchi 1203: s_server_config.cert_file = NULL;
1204: s_server_config.key_file = NULL;
1205: s_server_config.dcert_file = NULL;
1206: s_server_config.dkey_file = NULL;
1207: s_server_config.cert_file2 = NULL;
1208: s_server_config.key_file2 = NULL;
1.1 jsing 1209: }
1.39 inoguchi 1210: ctx = SSL_CTX_new(s_server_config.meth);
1.1 jsing 1211: if (ctx == NULL) {
1212: ERR_print_errors(bio_err);
1213: goto end;
1214: }
1.37 tb 1215:
1216: SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
1.35 inoguchi 1217:
1.39 inoguchi 1218: if (!SSL_CTX_set_min_proto_version(ctx, s_server_config.min_version))
1.35 inoguchi 1219: goto end;
1.39 inoguchi 1220: if (!SSL_CTX_set_max_proto_version(ctx, s_server_config.max_version))
1.35 inoguchi 1221: goto end;
1222:
1.39 inoguchi 1223: if (s_server_config.session_id_prefix) {
1224: if (strlen(s_server_config.session_id_prefix) >= 32)
1.1 jsing 1225: BIO_printf(bio_err,
1226: "warning: id_prefix is too long, only one new session will be possible\n");
1.39 inoguchi 1227: else if (strlen(s_server_config.session_id_prefix) >= 16)
1.1 jsing 1228: BIO_printf(bio_err,
1229: "warning: id_prefix is too long if you use SSLv2\n");
1230: if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
1231: BIO_printf(bio_err, "error setting 'id_prefix'\n");
1232: ERR_print_errors(bio_err);
1233: goto end;
1234: }
1.43 inoguchi 1235: BIO_printf(bio_err, "id_prefix '%s' set.\n",
1236: s_server_config.session_id_prefix);
1.1 jsing 1237: }
1238: SSL_CTX_set_quiet_shutdown(ctx, 1);
1.39 inoguchi 1239: if (s_server_config.bugs)
1.1 jsing 1240: SSL_CTX_set_options(ctx, SSL_OP_ALL);
1.39 inoguchi 1241: SSL_CTX_set_options(ctx, s_server_config.off);
1.1 jsing 1242: /*
1243: * DTLS: partial reads end up discarding unread UDP bytes :-( Setting
1244: * read ahead solves this problem.
1245: */
1.39 inoguchi 1246: if (s_server_config.socket_type == SOCK_DGRAM)
1.1 jsing 1247: SSL_CTX_set_read_ahead(ctx, 1);
1248:
1.39 inoguchi 1249: if (s_server_config.state)
1.1 jsing 1250: SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
1.39 inoguchi 1251: if (s_server_config.no_cache)
1.1 jsing 1252: SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
1253: else
1254: SSL_CTX_sess_set_cache_size(ctx, 128);
1255:
1256: #ifndef OPENSSL_NO_SRTP
1.39 inoguchi 1257: if (s_server_config.srtp_profiles != NULL)
1258: SSL_CTX_set_tlsext_use_srtp(ctx, s_server_config.srtp_profiles);
1.1 jsing 1259: #endif
1260:
1.43 inoguchi 1261: if ((!SSL_CTX_load_verify_locations(ctx, s_server_config.CAfile,
1262: s_server_config.CApath)) ||
1.1 jsing 1263: (!SSL_CTX_set_default_verify_paths(ctx))) {
1264: /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
1265: ERR_print_errors(bio_err);
1266: /* goto end; */
1267: }
1.39 inoguchi 1268: if (s_server_config.vpm)
1269: SSL_CTX_set1_param(ctx, s_server_config.vpm);
1.1 jsing 1270:
1271: if (s_cert2) {
1.39 inoguchi 1272: ctx2 = SSL_CTX_new(s_server_config.meth);
1.1 jsing 1273: if (ctx2 == NULL) {
1274: ERR_print_errors(bio_err);
1275: goto end;
1276: }
1.35 inoguchi 1277:
1.43 inoguchi 1278: if (!SSL_CTX_set_min_proto_version(ctx2,
1279: s_server_config.min_version))
1.35 inoguchi 1280: goto end;
1.43 inoguchi 1281: if (!SSL_CTX_set_max_proto_version(ctx2,
1282: s_server_config.max_version))
1.35 inoguchi 1283: goto end;
1.38 tb 1284: SSL_CTX_clear_mode(ctx2, SSL_MODE_AUTO_RETRY);
1.1 jsing 1285: }
1286: if (ctx2) {
1287: BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
1288:
1.39 inoguchi 1289: if (s_server_config.session_id_prefix) {
1290: if (strlen(s_server_config.session_id_prefix) >= 32)
1.1 jsing 1291: BIO_printf(bio_err,
1292: "warning: id_prefix is too long, only one new session will be possible\n");
1.39 inoguchi 1293: else if (strlen(s_server_config.session_id_prefix) >= 16)
1.1 jsing 1294: BIO_printf(bio_err,
1295: "warning: id_prefix is too long if you use SSLv2\n");
1.43 inoguchi 1296: if (!SSL_CTX_set_generate_session_id(ctx2,
1297: generate_session_id)) {
1298: BIO_printf(bio_err,
1299: "error setting 'id_prefix'\n");
1.1 jsing 1300: ERR_print_errors(bio_err);
1301: goto end;
1302: }
1.43 inoguchi 1303: BIO_printf(bio_err, "id_prefix '%s' set.\n",
1304: s_server_config.session_id_prefix);
1.1 jsing 1305: }
1306: SSL_CTX_set_quiet_shutdown(ctx2, 1);
1.39 inoguchi 1307: if (s_server_config.bugs)
1.1 jsing 1308: SSL_CTX_set_options(ctx2, SSL_OP_ALL);
1.39 inoguchi 1309: SSL_CTX_set_options(ctx2, s_server_config.off);
1.1 jsing 1310: /*
1311: * DTLS: partial reads end up discarding unread UDP bytes :-(
1312: * Setting read ahead solves this problem.
1313: */
1.39 inoguchi 1314: if (s_server_config.socket_type == SOCK_DGRAM)
1.1 jsing 1315: SSL_CTX_set_read_ahead(ctx2, 1);
1316:
1.39 inoguchi 1317: if (s_server_config.state)
1.1 jsing 1318: SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
1319:
1.39 inoguchi 1320: if (s_server_config.no_cache)
1.1 jsing 1321: SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
1322: else
1323: SSL_CTX_sess_set_cache_size(ctx2, 128);
1324:
1.43 inoguchi 1325: if ((!SSL_CTX_load_verify_locations(ctx2,
1326: s_server_config.CAfile, s_server_config.CApath)) ||
1.1 jsing 1327: (!SSL_CTX_set_default_verify_paths(ctx2))) {
1328: ERR_print_errors(bio_err);
1329: }
1.39 inoguchi 1330: if (s_server_config.vpm)
1331: SSL_CTX_set1_param(ctx2, s_server_config.vpm);
1.1 jsing 1332: }
1.8 jsing 1333: if (alpn_ctx.data)
1334: SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
1.1 jsing 1335:
1.39 inoguchi 1336: if (s_server_config.groups_in != NULL) {
1337: if (SSL_CTX_set1_groups_list(ctx, s_server_config.groups_in) != 1) {
1.33 jsing 1338: BIO_printf(bio_err, "Failed to set groups '%s'\n",
1.39 inoguchi 1339: s_server_config.groups_in);
1.33 jsing 1340: goto end;
1341: }
1342: }
1343:
1.1 jsing 1344: #ifndef OPENSSL_NO_DH
1.39 inoguchi 1345: if (!s_server_config.no_dhe) {
1.1 jsing 1346: DH *dh = NULL;
1347:
1.39 inoguchi 1348: if (s_server_config.dhfile)
1349: dh = load_dh_param(s_server_config.dhfile);
1.40 inoguchi 1350: else if (s_server_config.cert_file)
1351: dh = load_dh_param(s_server_config.cert_file);
1.1 jsing 1352:
1.4 jsing 1353: if (dh != NULL)
1.1 jsing 1354: BIO_printf(bio_s_out, "Setting temp DH parameters\n");
1.4 jsing 1355: else
1356: BIO_printf(bio_s_out, "Using auto DH parameters\n");
1357: (void) BIO_flush(bio_s_out);
1358:
1359: if (dh == NULL)
1360: SSL_CTX_set_dh_auto(ctx, 1);
1361: else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
1362: BIO_printf(bio_err,
1363: "Error setting temp DH parameters\n");
1364: ERR_print_errors(bio_err);
1365: DH_free(dh);
1366: goto end;
1.1 jsing 1367: }
1368:
1369: if (ctx2) {
1.39 inoguchi 1370: if (!s_server_config.dhfile) {
1.14 doug 1371: DH *dh2 = NULL;
1372:
1.40 inoguchi 1373: if (s_server_config.cert_file2 != NULL)
1.43 inoguchi 1374: dh2 = load_dh_param(
1375: s_server_config.cert_file2);
1.1 jsing 1376: if (dh2 != NULL) {
1.43 inoguchi 1377: BIO_printf(bio_s_out,
1378: "Setting temp DH parameters\n");
1.1 jsing 1379: (void) BIO_flush(bio_s_out);
1380:
1381: DH_free(dh);
1382: dh = dh2;
1383: }
1384: }
1.4 jsing 1385: if (dh == NULL)
1386: SSL_CTX_set_dh_auto(ctx2, 1);
1387: else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
1388: BIO_printf(bio_err,
1389: "Error setting temp DH parameters\n");
1390: ERR_print_errors(bio_err);
1391: DH_free(dh);
1392: goto end;
1393: }
1.1 jsing 1394: }
1395: DH_free(dh);
1396: }
1397: #endif
1398:
1.39 inoguchi 1399: if (!s_server_config.no_ecdhe && s_server_config.named_curve != NULL) {
1.1 jsing 1400: EC_KEY *ecdh = NULL;
1.33 jsing 1401: int nid;
1.1 jsing 1402:
1.39 inoguchi 1403: if ((nid = OBJ_sn2nid(s_server_config.named_curve)) == 0) {
1.33 jsing 1404: BIO_printf(bio_err, "unknown curve name (%s)\n",
1.39 inoguchi 1405: s_server_config.named_curve);
1.33 jsing 1406: goto end;
1.39 inoguchi 1407: }
1.33 jsing 1408: if ((ecdh = EC_KEY_new_by_curve_name(nid)) == NULL) {
1409: BIO_printf(bio_err, "unable to create curve (%s)\n",
1.39 inoguchi 1410: s_server_config.named_curve);
1.33 jsing 1411: goto end;
1.39 inoguchi 1412: }
1.33 jsing 1413: BIO_printf(bio_s_out, "Setting temp ECDH parameters\n");
1.1 jsing 1414: (void) BIO_flush(bio_s_out);
1415:
1416: SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1417: if (ctx2)
1418: SSL_CTX_set_tmp_ecdh(ctx2, ecdh);
1419: EC_KEY_free(ecdh);
1420: }
1421:
1422: if (!set_cert_key_stuff(ctx, s_cert, s_key))
1423: goto end;
1424: if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2))
1425: goto end;
1426: if (s_dcert != NULL) {
1427: if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
1428: goto end;
1429: }
1430:
1.39 inoguchi 1431: if (s_server_config.cipher != NULL) {
1432: if (!SSL_CTX_set_cipher_list(ctx, s_server_config.cipher)) {
1.1 jsing 1433: BIO_printf(bio_err, "error setting cipher list\n");
1434: ERR_print_errors(bio_err);
1435: goto end;
1436: }
1.43 inoguchi 1437: if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,
1438: s_server_config.cipher)) {
1.1 jsing 1439: BIO_printf(bio_err, "error setting cipher list\n");
1440: ERR_print_errors(bio_err);
1441: goto end;
1442: }
1443: }
1.40 inoguchi 1444: SSL_CTX_set_verify(ctx, s_server_config.server_verify, verify_callback);
1.43 inoguchi 1445: SSL_CTX_set_session_id_context(ctx,
1446: (void *) &s_server_session_id_context,
1.1 jsing 1447: sizeof s_server_session_id_context);
1448:
1449: /* Set DTLS cookie generation and verification callbacks */
1450: SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
1451: SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
1452:
1453: if (ctx2) {
1.43 inoguchi 1454: SSL_CTX_set_verify(ctx2, s_server_config.server_verify,
1455: verify_callback);
1456: SSL_CTX_set_session_id_context(ctx2,
1457: (void *) &s_server_session_id_context,
1.1 jsing 1458: sizeof s_server_session_id_context);
1459:
1.39 inoguchi 1460: s_server_config.tlsextcbp.biodebug = bio_s_out;
1.1 jsing 1461: SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
1.43 inoguchi 1462: SSL_CTX_set_tlsext_servername_arg(ctx2,
1463: &s_server_config.tlsextcbp);
1.1 jsing 1464: SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1.43 inoguchi 1465: SSL_CTX_set_tlsext_servername_arg(ctx,
1466: &s_server_config.tlsextcbp);
1.1 jsing 1467: }
1468:
1.39 inoguchi 1469: if (s_server_config.CAfile != NULL) {
1.43 inoguchi 1470: SSL_CTX_set_client_CA_list(ctx,
1471: SSL_load_client_CA_file(s_server_config.CAfile));
1.1 jsing 1472: if (ctx2)
1.43 inoguchi 1473: SSL_CTX_set_client_CA_list(ctx2,
1474: SSL_load_client_CA_file(s_server_config.CAfile));
1.1 jsing 1475: }
1476: BIO_printf(bio_s_out, "ACCEPT\n");
1477: (void) BIO_flush(bio_s_out);
1.39 inoguchi 1478: if (s_server_config.www)
1.43 inoguchi 1479: do_server(s_server_config.port, s_server_config.socket_type,
1480: &accept_socket, www_body, s_server_config.context);
1.1 jsing 1481: else
1.43 inoguchi 1482: do_server(s_server_config.port, s_server_config.socket_type,
1483: &accept_socket, sv_body, s_server_config.context);
1.1 jsing 1484: print_stats(bio_s_out, ctx);
1485: ret = 0;
1.30 jsing 1486: end:
1.29 jsing 1487: SSL_CTX_free(ctx);
1488: X509_free(s_cert);
1489: X509_free(s_dcert);
1490: EVP_PKEY_free(s_key);
1491: EVP_PKEY_free(s_dkey);
1.1 jsing 1492: free(pass);
1493: free(dpass);
1.39 inoguchi 1494: X509_VERIFY_PARAM_free(s_server_config.vpm);
1495: free(s_server_config.tlscstatp.host);
1496: free(s_server_config.tlscstatp.port);
1497: free(s_server_config.tlscstatp.path);
1.29 jsing 1498: SSL_CTX_free(ctx2);
1499: X509_free(s_cert2);
1500: EVP_PKEY_free(s_key2);
1.8 jsing 1501: free(alpn_ctx.data);
1.1 jsing 1502: if (bio_s_out != NULL) {
1503: BIO_free(bio_s_out);
1504: bio_s_out = NULL;
1505: }
1506:
1507: return (ret);
1508: }
1509:
1510: static void
1.41 inoguchi 1511: print_stats(BIO *bio, SSL_CTX *ssl_ctx)
1.1 jsing 1512: {
1513: BIO_printf(bio, "%4ld items in the session cache\n",
1514: SSL_CTX_sess_number(ssl_ctx));
1515: BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
1516: SSL_CTX_sess_connect(ssl_ctx));
1517: BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
1518: SSL_CTX_sess_connect_renegotiate(ssl_ctx));
1519: BIO_printf(bio, "%4ld client connects that finished\n",
1520: SSL_CTX_sess_connect_good(ssl_ctx));
1521: BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
1522: SSL_CTX_sess_accept(ssl_ctx));
1523: BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
1524: SSL_CTX_sess_accept_renegotiate(ssl_ctx));
1525: BIO_printf(bio, "%4ld server accepts that finished\n",
1526: SSL_CTX_sess_accept_good(ssl_ctx));
1.43 inoguchi 1527: BIO_printf(bio, "%4ld session cache hits\n",
1528: SSL_CTX_sess_hits(ssl_ctx));
1529: BIO_printf(bio, "%4ld session cache misses\n",
1530: SSL_CTX_sess_misses(ssl_ctx));
1531: BIO_printf(bio, "%4ld session cache timeouts\n",
1532: SSL_CTX_sess_timeouts(ssl_ctx));
1533: BIO_printf(bio, "%4ld callback cache hits\n",
1534: SSL_CTX_sess_cb_hits(ssl_ctx));
1.1 jsing 1535: BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
1536: SSL_CTX_sess_cache_full(ssl_ctx),
1537: SSL_CTX_sess_get_cache_size(ssl_ctx));
1538: }
1539:
1540: static int
1541: sv_body(char *hostname, int s, unsigned char *context)
1542: {
1543: char *buf = NULL;
1.7 deraadt 1544: int ret = 1;
1.1 jsing 1545: int k, i;
1546: unsigned long l;
1547: SSL *con = NULL;
1548: BIO *sbio;
1549: struct timeval timeout;
1550:
1551: if ((buf = malloc(bufsize)) == NULL) {
1552: BIO_printf(bio_err, "out of memory\n");
1553: goto err;
1554: }
1.40 inoguchi 1555: if (s_server_config.nbio) {
1556: if (!s_server_config.quiet)
1.1 jsing 1557: BIO_printf(bio_err, "turning on non blocking io\n");
1.2 bcook 1558: if (!BIO_socket_nbio(s, 1))
1.1 jsing 1559: ERR_print_errors(bio_err);
1560: }
1561:
1562: if (con == NULL) {
1563: con = SSL_new(ctx);
1.40 inoguchi 1564: if (s_server_config.tlsextdebug) {
1.1 jsing 1565: SSL_set_tlsext_debug_callback(con, tlsext_cb);
1566: SSL_set_tlsext_debug_arg(con, bio_s_out);
1567: }
1.40 inoguchi 1568: if (s_server_config.tlsextstatus) {
1.1 jsing 1569: SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
1.39 inoguchi 1570: s_server_config.tlscstatp.err = bio_err;
1.43 inoguchi 1571: SSL_CTX_set_tlsext_status_arg(ctx,
1572: &s_server_config.tlscstatp);
1.1 jsing 1573: }
1574: if (context)
1575: SSL_set_session_id_context(con, context,
1576: strlen((char *) context));
1577: }
1578: SSL_clear(con);
1579:
1.45 jsing 1580: if (SSL_is_dtls(con)) {
1.1 jsing 1581: sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1582:
1.39 inoguchi 1583: if (s_server_config.enable_timeouts) {
1.1 jsing 1584: timeout.tv_sec = 0;
1585: timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1.43 inoguchi 1586: BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0,
1587: &timeout);
1.1 jsing 1588:
1589: timeout.tv_sec = 0;
1590: timeout.tv_usec = DGRAM_SND_TIMEOUT;
1.43 inoguchi 1591: BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0,
1592: &timeout);
1.1 jsing 1593: }
1.39 inoguchi 1594: if (s_server_config.socket_mtu > 28) {
1.1 jsing 1595: SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1.39 inoguchi 1596: SSL_set_mtu(con, s_server_config.socket_mtu - 28);
1.1 jsing 1597: } else
1598: /* want to do MTU discovery */
1599: BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1600:
1601: /* turn on cookie exchange */
1602: SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
1603: } else
1604: sbio = BIO_new_socket(s, BIO_NOCLOSE);
1605:
1.40 inoguchi 1606: if (s_server_config.nbio_test) {
1.1 jsing 1607: BIO *test;
1608:
1609: test = BIO_new(BIO_f_nbio_test());
1610: sbio = BIO_push(test, sbio);
1611: }
1612:
1613: SSL_set_bio(con, sbio, sbio);
1614: SSL_set_accept_state(con);
1615: /* SSL_set_fd(con,s); */
1616:
1.40 inoguchi 1617: if (s_server_config.debug) {
1.1 jsing 1618: SSL_set_debug(con, 1);
1619: BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
1620: BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out);
1621: }
1.40 inoguchi 1622: if (s_server_config.msg) {
1.1 jsing 1623: SSL_set_msg_callback(con, msg_cb);
1624: SSL_set_msg_callback_arg(con, bio_s_out);
1625: }
1.40 inoguchi 1626: if (s_server_config.tlsextdebug) {
1.1 jsing 1627: SSL_set_tlsext_debug_callback(con, tlsext_cb);
1628: SSL_set_tlsext_debug_arg(con, bio_s_out);
1629: }
1630:
1631: for (;;) {
1632: int read_from_terminal;
1633: int read_from_sslcon;
1.7 deraadt 1634: struct pollfd pfd[2];
1635: int ptimeout;
1.1 jsing 1636:
1637: read_from_terminal = 0;
1638: read_from_sslcon = SSL_pending(con);
1639:
1640: if (!read_from_sslcon) {
1.7 deraadt 1641: pfd[0].fd = fileno(stdin);
1642: pfd[0].events = POLLIN;
1643: pfd[1].fd = s;
1644: pfd[1].events = POLLIN;
1645:
1.45 jsing 1646: if (SSL_is_dtls(con) &&
1.1 jsing 1647: DTLSv1_get_timeout(con, &timeout))
1.7 deraadt 1648: ptimeout = timeout.tv_sec * 1000 +
1649: timeout.tv_usec / 1000;
1.1 jsing 1650: else
1.7 deraadt 1651: ptimeout = -1;
1.1 jsing 1652:
1.7 deraadt 1653: i = poll(pfd, 2, ptimeout);
1.1 jsing 1654:
1.45 jsing 1655: if (SSL_is_dtls(con) &&
1656: DTLSv1_handle_timeout(con) > 0)
1.1 jsing 1657: BIO_printf(bio_err, "TIMEOUT occured\n");
1658: if (i <= 0)
1659: continue;
1.7 deraadt 1660: if (pfd[0].revents) {
1661: if ((pfd[0].revents & (POLLERR|POLLNVAL)))
1662: continue;
1.1 jsing 1663: read_from_terminal = 1;
1.7 deraadt 1664: }
1665: if (pfd[1].revents) {
1666: if ((pfd[1].revents & (POLLERR|POLLNVAL)))
1667: continue;
1.1 jsing 1668: read_from_sslcon = 1;
1.7 deraadt 1669: }
1.1 jsing 1670: }
1671: if (read_from_terminal) {
1.40 inoguchi 1672: if (s_server_config.crlf) {
1.1 jsing 1673: int j, lf_num;
1674:
1675: i = read(fileno(stdin), buf, bufsize / 2);
1676: lf_num = 0;
1677: /* both loops are skipped when i <= 0 */
1678: for (j = 0; j < i; j++)
1679: if (buf[j] == '\n')
1680: lf_num++;
1681: for (j = i - 1; j >= 0; j--) {
1682: buf[j + lf_num] = buf[j];
1683: if (buf[j] == '\n') {
1684: lf_num--;
1685: i++;
1686: buf[j + lf_num] = '\r';
1687: }
1688: }
1689: assert(lf_num == 0);
1690: } else
1691: i = read(fileno(stdin), buf, bufsize);
1.40 inoguchi 1692: if (!s_server_config.quiet) {
1.1 jsing 1693: if ((i <= 0) || (buf[0] == 'Q')) {
1694: BIO_printf(bio_s_out, "DONE\n");
1695: shutdown(s, SHUT_RD);
1696: close(s);
1697: close_accept_socket();
1698: ret = -11;
1699: goto err;
1700: }
1701: if ((i <= 0) || (buf[0] == 'q')) {
1702: BIO_printf(bio_s_out, "DONE\n");
1.45 jsing 1703: if (!SSL_is_dtls(con)) {
1.1 jsing 1704: shutdown(s, SHUT_RD);
1705: close(s);
1706: }
1707: /*
1708: * close_accept_socket(); ret= -11;
1709: */
1710: goto err;
1711: }
1712: if ((buf[0] == 'r') &&
1713: ((buf[1] == '\n') || (buf[1] == '\r'))) {
1714: SSL_renegotiate(con);
1715: i = SSL_do_handshake(con);
1716: printf("SSL_do_handshake -> %d\n", i);
1717: i = 0; /* 13; */
1718: continue;
1719: /*
1720: * RE-NEGOTIATE\n");
1721: */
1722: }
1723: if ((buf[0] == 'R') &&
1724: ((buf[1] == '\n') || (buf[1] == '\r'))) {
1725: SSL_set_verify(con,
1.43 inoguchi 1726: SSL_VERIFY_PEER |
1727: SSL_VERIFY_CLIENT_ONCE,
1728: NULL);
1.1 jsing 1729: SSL_renegotiate(con);
1730: i = SSL_do_handshake(con);
1731: printf("SSL_do_handshake -> %d\n", i);
1732: i = 0; /* 13; */
1733: continue;
1734: /*
1735: * RE-NEGOTIATE asking for client
1736: * cert\n");
1737: */
1738: }
1739: if (buf[0] == 'P') {
1.43 inoguchi 1740: static const char *str =
1741: "Lets print some clear text\n";
1742: BIO_write(SSL_get_wbio(con), str,
1743: strlen(str));
1.1 jsing 1744: }
1745: if (buf[0] == 'S') {
1.43 inoguchi 1746: print_stats(bio_s_out,
1747: SSL_get_SSL_CTX(con));
1.1 jsing 1748: }
1749: }
1750: l = k = 0;
1751: for (;;) {
1752: /* should do a select for the write */
1753: #ifdef RENEG
1754: {
1755: static count = 0;
1756: if (++count == 100) {
1757: count = 0;
1758: SSL_renegotiate(con);
1759: }
1760: }
1761: #endif
1762: k = SSL_write(con, &(buf[l]), (unsigned int) i);
1763: switch (SSL_get_error(con, k)) {
1764: case SSL_ERROR_NONE:
1765: break;
1766: case SSL_ERROR_WANT_WRITE:
1767: case SSL_ERROR_WANT_READ:
1768: case SSL_ERROR_WANT_X509_LOOKUP:
1769: BIO_printf(bio_s_out, "Write BLOCK\n");
1770: break;
1771: case SSL_ERROR_SYSCALL:
1772: case SSL_ERROR_SSL:
1773: BIO_printf(bio_s_out, "ERROR\n");
1774: ERR_print_errors(bio_err);
1775: ret = 1;
1776: goto err;
1777: /* break; */
1778: case SSL_ERROR_ZERO_RETURN:
1779: BIO_printf(bio_s_out, "DONE\n");
1780: ret = 1;
1781: goto err;
1782: }
1.36 tb 1783: if (k <= 0)
1784: continue;
1.1 jsing 1785: l += k;
1786: i -= k;
1787: if (i <= 0)
1788: break;
1789: }
1790: }
1791: if (read_from_sslcon) {
1792: if (!SSL_is_init_finished(con)) {
1793: i = init_ssl_connection(con);
1794:
1795: if (i < 0) {
1796: ret = 0;
1797: goto err;
1798: } else if (i == 0) {
1799: ret = 1;
1800: goto err;
1801: }
1802: } else {
1803: again:
1804: i = SSL_read(con, (char *) buf, bufsize);
1805: switch (SSL_get_error(con, i)) {
1806: case SSL_ERROR_NONE: {
1807: int len, n;
1808: for (len = 0; len < i;) {
1809: do {
1810: n = write(fileno(stdout), buf + len, i - len);
1811: } while (n == -1 && errno == EINTR);
1812:
1.31 deraadt 1813: if (n == -1) {
1.1 jsing 1814: BIO_printf(bio_s_out, "ERROR\n");
1815: goto err;
1816: }
1817: len += n;
1818: }
1819: }
1820: if (SSL_pending(con))
1821: goto again;
1822: break;
1823: case SSL_ERROR_WANT_WRITE:
1824: case SSL_ERROR_WANT_READ:
1825: BIO_printf(bio_s_out, "Read BLOCK\n");
1826: break;
1827: case SSL_ERROR_SYSCALL:
1828: case SSL_ERROR_SSL:
1829: BIO_printf(bio_s_out, "ERROR\n");
1830: ERR_print_errors(bio_err);
1831: ret = 1;
1832: goto err;
1833: case SSL_ERROR_ZERO_RETURN:
1834: BIO_printf(bio_s_out, "DONE\n");
1835: ret = 1;
1836: goto err;
1837: }
1838: }
1839: }
1840: }
1.30 jsing 1841: err:
1.1 jsing 1842: if (con != NULL) {
1843: BIO_printf(bio_s_out, "shutting down SSL\n");
1.43 inoguchi 1844: SSL_set_shutdown(con,
1845: SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
1.1 jsing 1846: SSL_free(con);
1847: }
1848: BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
1.26 deraadt 1849: freezero(buf, bufsize);
1.1 jsing 1850: if (ret >= 0)
1851: BIO_printf(bio_s_out, "ACCEPT\n");
1852: return (ret);
1853: }
1854:
1855: static void
1856: close_accept_socket(void)
1857: {
1858: BIO_printf(bio_err, "shutdown accept socket\n");
1859: if (accept_socket >= 0) {
1860: shutdown(accept_socket, SHUT_RDWR);
1861: close(accept_socket);
1862: }
1863: }
1864:
1865: static int
1.41 inoguchi 1866: init_ssl_connection(SSL *con)
1.1 jsing 1867: {
1868: int i;
1869: const char *str;
1870: X509 *peer;
1871: long verify_error;
1872: char buf[BUFSIZ];
1873: unsigned char *exportedkeymat;
1874:
1875: i = SSL_accept(con);
1876: if (i <= 0) {
1877: if (BIO_sock_should_retry(i)) {
1878: BIO_printf(bio_s_out, "DELAY\n");
1879: return (1);
1880: }
1881: BIO_printf(bio_err, "ERROR\n");
1882: verify_error = SSL_get_verify_result(con);
1883: if (verify_error != X509_V_OK) {
1884: BIO_printf(bio_err, "verify error:%s\n",
1885: X509_verify_cert_error_string(verify_error));
1886: } else
1887: ERR_print_errors(bio_err);
1888: return (0);
1889: }
1890: PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
1891:
1892: peer = SSL_get_peer_certificate(con);
1893: if (peer != NULL) {
1894: BIO_printf(bio_s_out, "Client certificate\n");
1895: PEM_write_bio_X509(bio_s_out, peer);
1896: X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
1897: BIO_printf(bio_s_out, "subject=%s\n", buf);
1898: X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
1899: BIO_printf(bio_s_out, "issuer=%s\n", buf);
1900: X509_free(peer);
1901: }
1902: if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
1903: BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
1904: str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
1905: BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
1906:
1907: #ifndef OPENSSL_NO_SRTP
1908: {
1909: SRTP_PROTECTION_PROFILE *srtp_profile
1910: = SSL_get_selected_srtp_profile(con);
1911:
1912: if (srtp_profile)
1.43 inoguchi 1913: BIO_printf(bio_s_out,
1914: "SRTP Extension negotiated, profile=%s\n",
1.1 jsing 1915: srtp_profile->name);
1916: }
1917: #endif
1918: if (SSL_cache_hit(con))
1919: BIO_printf(bio_s_out, "Reused session-id\n");
1920: BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
1921: SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
1.39 inoguchi 1922: if (s_server_config.keymatexportlabel != NULL) {
1.1 jsing 1923: BIO_printf(bio_s_out, "Keying material exporter:\n");
1.43 inoguchi 1924: BIO_printf(bio_s_out, " Label: '%s'\n",
1925: s_server_config.keymatexportlabel);
1.1 jsing 1926: BIO_printf(bio_s_out, " Length: %i bytes\n",
1.39 inoguchi 1927: s_server_config.keymatexportlen);
1928: exportedkeymat = malloc(s_server_config.keymatexportlen);
1.1 jsing 1929: if (exportedkeymat != NULL) {
1930: if (!SSL_export_keying_material(con, exportedkeymat,
1.39 inoguchi 1931: s_server_config.keymatexportlen,
1932: s_server_config.keymatexportlabel,
1933: strlen(s_server_config.keymatexportlabel),
1.1 jsing 1934: NULL, 0, 0)) {
1935: BIO_printf(bio_s_out, " Error\n");
1936: } else {
1937: BIO_printf(bio_s_out, " Keying material: ");
1.39 inoguchi 1938: for (i = 0; i < s_server_config.keymatexportlen; i++)
1.1 jsing 1939: BIO_printf(bio_s_out, "%02X",
1940: exportedkeymat[i]);
1941: BIO_printf(bio_s_out, "\n");
1942: }
1943: free(exportedkeymat);
1944: }
1945: }
1946: return (1);
1947: }
1948:
1949: #ifndef OPENSSL_NO_DH
1950: static DH *
1951: load_dh_param(const char *dhfile)
1952: {
1953: DH *ret = NULL;
1954: BIO *bio;
1955:
1956: if ((bio = BIO_new_file(dhfile, "r")) == NULL)
1957: goto err;
1958: ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1.30 jsing 1959: err:
1.1 jsing 1960: BIO_free(bio);
1961: return (ret);
1962: }
1963: #endif
1964:
1965: static int
1966: www_body(char *hostname, int s, unsigned char *context)
1967: {
1968: char *buf = NULL;
1969: int ret = 1;
1970: int i, j, k, dot;
1971: SSL *con;
1972: const SSL_CIPHER *c;
1973: BIO *io, *ssl_bio, *sbio;
1974:
1975: buf = malloc(bufsize);
1976: if (buf == NULL)
1977: return (0);
1978: io = BIO_new(BIO_f_buffer());
1979: ssl_bio = BIO_new(BIO_f_ssl());
1980: if ((io == NULL) || (ssl_bio == NULL))
1981: goto err;
1982:
1.40 inoguchi 1983: if (s_server_config.nbio) {
1984: if (!s_server_config.quiet)
1.1 jsing 1985: BIO_printf(bio_err, "turning on non blocking io\n");
1.2 bcook 1986: if (!BIO_socket_nbio(s, 1))
1.1 jsing 1987: ERR_print_errors(bio_err);
1988: }
1989:
1990: /* lets make the output buffer a reasonable size */
1991: if (!BIO_set_write_buffer_size(io, bufsize))
1992: goto err;
1993:
1994: if ((con = SSL_new(ctx)) == NULL)
1995: goto err;
1.40 inoguchi 1996: if (s_server_config.tlsextdebug) {
1.1 jsing 1997: SSL_set_tlsext_debug_callback(con, tlsext_cb);
1998: SSL_set_tlsext_debug_arg(con, bio_s_out);
1999: }
2000: if (context)
2001: SSL_set_session_id_context(con, context,
2002: strlen((char *) context));
2003:
2004: sbio = BIO_new_socket(s, BIO_NOCLOSE);
1.40 inoguchi 2005: if (s_server_config.nbio_test) {
1.1 jsing 2006: BIO *test;
2007:
2008: test = BIO_new(BIO_f_nbio_test());
2009: sbio = BIO_push(test, sbio);
2010: }
2011: SSL_set_bio(con, sbio, sbio);
2012: SSL_set_accept_state(con);
2013:
2014: /* SSL_set_fd(con,s); */
2015: BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
2016: BIO_push(io, ssl_bio);
2017:
1.40 inoguchi 2018: if (s_server_config.debug) {
1.1 jsing 2019: SSL_set_debug(con, 1);
2020: BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
2021: BIO_set_callback_arg(SSL_get_rbio(con), (char *) bio_s_out);
2022: }
1.40 inoguchi 2023: if (s_server_config.msg) {
1.1 jsing 2024: SSL_set_msg_callback(con, msg_cb);
2025: SSL_set_msg_callback_arg(con, bio_s_out);
2026: }
2027: for (;;) {
2028: i = BIO_gets(io, buf, bufsize - 1);
2029: if (i < 0) { /* error */
2030: if (!BIO_should_retry(io)) {
1.40 inoguchi 2031: if (!s_server_config.quiet)
1.1 jsing 2032: ERR_print_errors(bio_err);
2033: goto err;
2034: } else {
1.40 inoguchi 2035: if (s_server_config.debug) {
1.34 beck 2036: BIO_printf(bio_s_out, "read R BLOCK\n");
2037: sleep(1);
2038: }
1.1 jsing 2039: continue;
2040: }
2041: } else if (i == 0) { /* end of input */
2042: ret = 1;
2043: goto end;
2044: }
2045: /* else we have data */
1.43 inoguchi 2046: if (((s_server_config.www == 1) &&
2047: (strncmp("GET ", buf, 4) == 0)) ||
2048: ((s_server_config.www == 2) &&
2049: (strncmp("GET /stats ", buf, 11) == 0))) {
1.1 jsing 2050: char *p;
2051: X509 *peer;
1.41 inoguchi 2052: STACK_OF(SSL_CIPHER) *sk;
1.1 jsing 2053: static const char *space = " ";
2054:
2055: BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
2056: BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
2057: BIO_puts(io, "<pre>\n");
2058: /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
2059: BIO_puts(io, "\n");
2060: for (i = 0; i < local_argc; i++) {
2061: BIO_puts(io, local_argv[i]);
2062: BIO_write(io, " ", 1);
2063: }
2064: BIO_puts(io, "\n");
2065:
2066: BIO_printf(io,
2067: "Secure Renegotiation IS%s supported\n",
2068: SSL_get_secure_renegotiation_support(con) ?
2069: "" : " NOT");
2070:
2071: /*
2072: * The following is evil and should not really be
2073: * done
2074: */
1.43 inoguchi 2075: BIO_printf(io,
2076: "Ciphers supported in s_server binary\n");
1.1 jsing 2077: sk = SSL_get_ciphers(con);
2078: j = sk_SSL_CIPHER_num(sk);
2079: for (i = 0; i < j; i++) {
2080: c = sk_SSL_CIPHER_value(sk, i);
2081: BIO_printf(io, "%-11s:%-25s",
2082: SSL_CIPHER_get_version(c),
2083: SSL_CIPHER_get_name(c));
2084: if ((((i + 1) % 2) == 0) && (i + 1 != j))
2085: BIO_puts(io, "\n");
2086: }
2087: BIO_puts(io, "\n");
2088: p = SSL_get_shared_ciphers(con, buf, bufsize);
2089: if (p != NULL) {
1.43 inoguchi 2090: BIO_printf(io,
2091: "---\nCiphers common between both SSL end points:\n");
1.1 jsing 2092: j = i = 0;
2093: while (*p) {
2094: if (*p == ':') {
2095: BIO_write(io, space, 26 - j);
2096: i++;
2097: j = 0;
1.43 inoguchi 2098: BIO_write(io,
2099: ((i % 3) ? " " : "\n"), 1);
1.1 jsing 2100: } else {
2101: BIO_write(io, p, 1);
2102: j++;
2103: }
2104: p++;
2105: }
2106: BIO_puts(io, "\n");
2107: }
2108: BIO_printf(io, (SSL_cache_hit(con)
2109: ? "---\nReused, "
2110: : "---\nNew, "));
2111: c = SSL_get_current_cipher(con);
2112: BIO_printf(io, "%s, Cipher is %s\n",
2113: SSL_CIPHER_get_version(c),
2114: SSL_CIPHER_get_name(c));
2115: SSL_SESSION_print(io, SSL_get_session(con));
2116: BIO_printf(io, "---\n");
2117: print_stats(io, SSL_get_SSL_CTX(con));
2118: BIO_printf(io, "---\n");
2119: peer = SSL_get_peer_certificate(con);
2120: if (peer != NULL) {
2121: BIO_printf(io, "Client certificate\n");
2122: X509_print(io, peer);
2123: PEM_write_bio_X509(io, peer);
2124: } else
1.43 inoguchi 2125: BIO_puts(io,
2126: "no client certificate available\n");
1.1 jsing 2127: BIO_puts(io, "</BODY></HTML>\r\n\r\n");
2128: break;
1.43 inoguchi 2129: } else if ((s_server_config.www == 2 ||
2130: s_server_config.www == 3) &&
2131: (strncmp("GET /", buf, 5) == 0)) {
1.1 jsing 2132: BIO *file;
2133: char *p, *e;
2134: static const char *text = "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
2135:
2136: /* skip the '/' */
2137: p = &(buf[5]);
2138:
2139: dot = 1;
2140: for (e = p; *e != '\0'; e++) {
2141: if (e[0] == ' ')
2142: break;
2143:
2144: switch (dot) {
2145: case 1:
2146: dot = (e[0] == '.') ? 2 : 0;
2147: break;
2148: case 2:
2149: dot = (e[0] == '.') ? 3 : 0;
2150: break;
2151: case 3:
1.43 inoguchi 2152: dot = (e[0] == '/' || e[0] == '\\') ?
2153: -1 : 0;
1.1 jsing 2154: break;
2155: }
2156: if (dot == 0)
1.43 inoguchi 2157: dot = (e[0] == '/' || e[0] == '\\') ?
2158: 1 : 0;
1.1 jsing 2159: }
1.43 inoguchi 2160: dot = (dot == 3) || (dot == -1); /* filename contains
2161: * ".." component */
1.1 jsing 2162:
2163: if (*e == '\0') {
2164: BIO_puts(io, text);
1.43 inoguchi 2165: BIO_printf(io,
2166: "'%s' is an invalid file name\r\n", p);
1.1 jsing 2167: break;
2168: }
2169: *e = '\0';
2170:
2171: if (dot) {
2172: BIO_puts(io, text);
1.43 inoguchi 2173: BIO_printf(io,
2174: "'%s' contains '..' reference\r\n", p);
1.1 jsing 2175: break;
2176: }
2177: if (*p == '/') {
2178: BIO_puts(io, text);
1.43 inoguchi 2179: BIO_printf(io,
2180: "'%s' is an invalid path\r\n", p);
1.1 jsing 2181: break;
2182: }
2183: /* if a directory, do the index thang */
2184: if (app_isdir(p) > 0) {
2185: BIO_puts(io, text);
2186: BIO_printf(io, "'%s' is a directory\r\n", p);
2187: break;
2188: }
2189: if ((file = BIO_new_file(p, "r")) == NULL) {
2190: BIO_puts(io, text);
2191: BIO_printf(io, "Error opening '%s'\r\n", p);
2192: ERR_print_errors(io);
2193: break;
2194: }
1.40 inoguchi 2195: if (!s_server_config.quiet)
1.1 jsing 2196: BIO_printf(bio_err, "FILE:%s\n", p);
2197:
1.39 inoguchi 2198: if (s_server_config.www == 2) {
1.1 jsing 2199: i = strlen(p);
2200: if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
2201: ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
2202: ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
2203: BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
2204: else
2205: BIO_puts(io, "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
2206: }
2207: /* send the file */
2208: for (;;) {
2209: i = BIO_read(file, buf, bufsize);
2210: if (i <= 0)
2211: break;
2212:
2213: #ifdef RENEG
2214: total_bytes += i;
2215: fprintf(stderr, "%d\n", i);
2216: if (total_bytes > 3 * 1024) {
2217: total_bytes = 0;
2218: fprintf(stderr, "RENEGOTIATE\n");
2219: SSL_renegotiate(con);
2220: }
2221: #endif
2222:
2223: for (j = 0; j < i;) {
2224: #ifdef RENEG
2225: {
2226: static count = 0;
2227: if (++count == 13) {
2228: SSL_renegotiate(con);
2229: }
2230: }
2231: #endif
2232: k = BIO_write(io, &(buf[j]), i - j);
2233: if (k <= 0) {
2234: if (!BIO_should_retry(io))
2235: goto write_error;
2236: else {
1.43 inoguchi 2237: BIO_printf(bio_s_out,
2238: "rwrite W BLOCK\n");
1.1 jsing 2239: }
2240: } else {
2241: j += k;
2242: }
2243: }
2244: }
2245: write_error:
2246: BIO_free(file);
2247: break;
2248: }
2249: }
2250:
2251: for (;;) {
2252: i = (int) BIO_flush(io);
2253: if (i <= 0) {
2254: if (!BIO_should_retry(io))
2255: break;
2256: } else
2257: break;
2258: }
1.30 jsing 2259: end:
1.1 jsing 2260: /* make sure we re-use sessions */
2261: SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
2262:
1.30 jsing 2263: err:
1.1 jsing 2264:
2265: if (ret >= 0)
2266: BIO_printf(bio_s_out, "ACCEPT\n");
2267:
1.24 mmcc 2268: free(buf);
1.29 jsing 2269: BIO_free_all(io);
1.1 jsing 2270: /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
2271: return (ret);
2272: }
2273:
2274: #define MAX_SESSION_ID_ATTEMPTS 10
2275: static int
1.42 inoguchi 2276: generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len)
1.1 jsing 2277: {
2278: unsigned int count = 0;
2279: do {
1.3 jsing 2280: arc4random_buf(id, *id_len);
1.1 jsing 2281: /*
2282: * Prefix the session_id with the required prefix. NB: If our
2283: * prefix is too long, clip it - but there will be worse
2284: * effects anyway, eg. the server could only possibly create
2285: * 1 session ID (ie. the prefix!) so all future session
2286: * negotiations will fail due to conflicts.
2287: */
1.39 inoguchi 2288: memcpy(id, s_server_config.session_id_prefix,
2289: (strlen(s_server_config.session_id_prefix) < *id_len) ?
2290: strlen(s_server_config.session_id_prefix) : *id_len);
1.1 jsing 2291: }
2292: while (SSL_has_matching_session_id(ssl, id, *id_len) &&
2293: (++count < MAX_SESSION_ID_ATTEMPTS));
2294: if (count >= MAX_SESSION_ID_ATTEMPTS)
2295: return 0;
2296: return 1;
1.42 inoguchi 2297: }
2298:
2299: static int
2300: ssl_servername_cb(SSL *s, int *ad, void *arg)
2301: {
2302: tlsextctx *p = (tlsextctx *) arg;
1.43 inoguchi 2303: const char *servername = SSL_get_servername(s,
2304: TLSEXT_NAMETYPE_host_name);
2305:
1.42 inoguchi 2306: if (servername && p->biodebug)
1.43 inoguchi 2307: BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
2308: servername);
1.42 inoguchi 2309:
2310: if (!p->servername)
2311: return SSL_TLSEXT_ERR_NOACK;
2312:
2313: if (servername) {
2314: if (strcmp(servername, p->servername))
2315: return p->extension_error;
2316: if (ctx2) {
2317: BIO_printf(p->biodebug, "Switching server context.\n");
2318: SSL_set_SSL_CTX(s, ctx2);
2319: }
2320: }
2321: return SSL_TLSEXT_ERR_OK;
2322: }
2323:
2324: /* Certificate Status callback. This is called when a client includes a
2325: * certificate status request extension.
2326: *
2327: * This is a simplified version. It examines certificates each time and
2328: * makes one OCSP responder query for each request.
2329: *
2330: * A full version would store details such as the OCSP certificate IDs and
2331: * minimise the number of OCSP responses by caching them until they were
2332: * considered "expired".
2333: */
2334:
2335: static int
2336: cert_status_cb(SSL *s, void *arg)
2337: {
2338: tlsextstatusctx *srctx = arg;
2339: BIO *err = srctx->err;
2340: char *host = NULL, *port = NULL, *path = NULL;
2341: int use_ssl;
2342: unsigned char *rspder = NULL;
2343: int rspderlen;
2344: STACK_OF(OPENSSL_STRING) *aia = NULL;
2345: X509 *x = NULL;
2346: X509_STORE_CTX inctx;
2347: X509_OBJECT obj;
2348: OCSP_REQUEST *req = NULL;
2349: OCSP_RESPONSE *resp = NULL;
2350: OCSP_CERTID *id = NULL;
2351: STACK_OF(X509_EXTENSION) *exts;
2352: int ret = SSL_TLSEXT_ERR_NOACK;
2353: int i;
2354:
2355: if (srctx->verbose)
2356: BIO_puts(err, "cert_status: callback called\n");
2357: /* Build up OCSP query from server certificate */
2358: x = SSL_get_certificate(s);
2359: aia = X509_get1_ocsp(x);
2360: if (aia) {
2361: if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
2362: &host, &port, &path, &use_ssl)) {
2363: BIO_puts(err, "cert_status: can't parse AIA URL\n");
2364: goto err;
2365: }
2366: if (srctx->verbose)
2367: BIO_printf(err, "cert_status: AIA URL: %s\n",
2368: sk_OPENSSL_STRING_value(aia, 0));
2369: } else {
2370: if (!srctx->host) {
1.43 inoguchi 2371: BIO_puts(srctx->err,
2372: "cert_status: no AIA and no default responder URL\n");
1.42 inoguchi 2373: goto done;
2374: }
2375: host = srctx->host;
2376: path = srctx->path;
2377: port = srctx->port;
2378: use_ssl = srctx->use_ssl;
2379: }
2380:
2381: if (!X509_STORE_CTX_init(&inctx,
2382: SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
2383: NULL, NULL))
2384: goto err;
2385: if (X509_STORE_get_by_subject(&inctx, X509_LU_X509,
2386: X509_get_issuer_name(x), &obj) <= 0) {
1.43 inoguchi 2387: BIO_puts(err,
2388: "cert_status: Can't retrieve issuer certificate.\n");
1.42 inoguchi 2389: X509_STORE_CTX_cleanup(&inctx);
2390: goto done;
2391: }
2392: req = OCSP_REQUEST_new();
2393: if (!req)
2394: goto err;
2395: id = OCSP_cert_to_id(NULL, x, obj.data.x509);
2396: X509_free(obj.data.x509);
2397: X509_STORE_CTX_cleanup(&inctx);
2398: if (!id)
2399: goto err;
2400: if (!OCSP_request_add0_id(req, id))
2401: goto err;
2402: id = NULL;
2403: /* Add any extensions to the request */
2404: SSL_get_tlsext_status_exts(s, &exts);
2405: for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
2406: X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
2407: if (!OCSP_REQUEST_add_ext(req, ext, -1))
2408: goto err;
2409: }
2410: resp = process_responder(err, req, host, path, port, use_ssl, NULL,
2411: srctx->timeout);
2412: if (!resp) {
2413: BIO_puts(err, "cert_status: error querying responder\n");
2414: goto done;
2415: }
2416: rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
2417: if (rspderlen <= 0)
2418: goto err;
2419: SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
2420: if (srctx->verbose) {
2421: BIO_puts(err, "cert_status: ocsp response sent:\n");
2422: OCSP_RESPONSE_print(err, resp, 2);
2423: }
2424: ret = SSL_TLSEXT_ERR_OK;
2425: done:
2426: if (ret != SSL_TLSEXT_ERR_OK)
2427: ERR_print_errors(err);
2428: if (aia) {
2429: free(host);
2430: free(path);
2431: free(port);
2432: X509_email_free(aia);
2433: }
2434: if (id)
2435: OCSP_CERTID_free(id);
2436: if (req)
2437: OCSP_REQUEST_free(req);
2438: if (resp)
2439: OCSP_RESPONSE_free(resp);
2440: return ret;
2441: err:
2442: ret = SSL_TLSEXT_ERR_ALERT_FATAL;
2443: goto done;
2444: }
2445:
2446: static int
2447: alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
2448: const unsigned char *in, unsigned int inlen, void *arg)
2449: {
2450: tlsextalpnctx *alpn_ctx = arg;
2451:
2452: if (!s_server_config.quiet) {
2453: /* We can assume that in is syntactically valid. */
2454: unsigned i;
2455:
2456: BIO_printf(bio_s_out,
2457: "ALPN protocols advertised by the client: ");
2458: for (i = 0; i < inlen; ) {
2459: if (i)
2460: BIO_write(bio_s_out, ", ", 2);
2461: BIO_write(bio_s_out, &in[i + 1], in[i]);
2462: i += in[i] + 1;
2463: }
2464: BIO_write(bio_s_out, "\n", 1);
2465: }
2466:
2467: if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data,
2468: alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED)
2469: return (SSL_TLSEXT_ERR_NOACK);
2470:
2471: if (!s_server_config.quiet) {
2472: BIO_printf(bio_s_out, "ALPN protocols selected: ");
2473: BIO_write(bio_s_out, *out, *outlen);
2474: BIO_write(bio_s_out, "\n", 1);
2475: }
2476:
2477: return (SSL_TLSEXT_ERR_OK);
1.1 jsing 2478: }