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