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