Annotation of src/usr.bin/openssl/s_client.c, Revision 1.51
1.51 ! inoguchi 1: /* $OpenBSD: s_client.c,v 1.50 2020/07/10 12:05:52 inoguchi 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 2005 Nokia. All rights reserved.
113: *
114: * The portions of the attached software ("Contribution") is developed by
115: * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116: * license.
117: *
118: * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119: * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120: * support (see RFC 4279) to OpenSSL.
121: *
122: * No patent licenses or other rights except those expressly stated in
123: * the OpenSSL open source license shall be deemed granted or received
124: * expressly, by implication, estoppel, or otherwise.
125: *
126: * No assurances are provided by Nokia that the Contribution does not
127: * infringe the patent or other intellectual property rights of any third
128: * party or that the license provides you with all the necessary rights
129: * to make use of the Contribution.
130: *
131: * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132: * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133: * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134: * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135: * OTHERWISE.
136: */
137:
138: #include <sys/types.h>
139: #include <sys/socket.h>
140:
141: #include <netinet/in.h>
142:
143: #include <assert.h>
144: #include <ctype.h>
145: #include <limits.h>
146: #include <netdb.h>
147: #include <stdio.h>
148: #include <stdlib.h>
149: #include <string.h>
150: #include <unistd.h>
1.9 deraadt 151: #include <poll.h>
1.1 jsing 152:
153: #include "apps.h"
154:
155: #include <openssl/bn.h>
156: #include <openssl/err.h>
157: #include <openssl/ocsp.h>
158: #include <openssl/pem.h>
159: #include <openssl/ssl.h>
160: #include <openssl/x509.h>
161:
162: #include "s_apps.h"
163: #include "timeouts.h"
164:
165: /*#define SSL_HOST_NAME "www.netscape.com" */
166: /*#define SSL_HOST_NAME "193.118.187.102" */
167: #define SSL_HOST_NAME "localhost"
168:
169: /*#define TEST_CERT "client.pem" *//* no default cert. */
170:
171: #define BUFSIZZ 1024*8
172:
173: static void sc_usage(void);
1.51 ! inoguchi 174: static void print_stuff(BIO *berr, SSL *con, int full);
! 175: static int ocsp_resp_cb(SSL *s, void *arg);
! 176: static int ssl_servername_cb(SSL *s, int *ad, void *arg);
1.1 jsing 177:
1.47 inoguchi 178: enum {
179: PROTO_OFF = 0,
180: PROTO_SMTP,
181: PROTO_LMTP,
182: PROTO_POP3,
183: PROTO_IMAP,
184: PROTO_FTP,
185: PROTO_XMPP,
186: };
187:
1.51 ! inoguchi 188: /* This is a context that we pass to callbacks */
! 189: typedef struct tlsextctx_st {
! 190: BIO *biodebug;
! 191: int ack;
! 192: } tlsextctx;
! 193:
1.47 inoguchi 194: static struct {
195: int af;
196: char *alpn_in;
197: int bugs;
198: char *CAfile;
199: char *CApath;
200: char *cert_file;
201: int cert_format;
202: char *cipher;
203: unsigned int clr;
204: char *connect;
205: int crlf;
1.48 inoguchi 206: int debug;
1.47 inoguchi 207: int enable_timeouts;
208: const char *errstr;
209: char *groups_in;
210: char *host;
1.48 inoguchi 211: int ign_eof;
1.47 inoguchi 212: char *key_file;
213: int key_format;
214: char *keymatexportlabel;
215: int keymatexportlen;
216: uint16_t max_version;
217: uint16_t min_version;
218: const SSL_METHOD *meth;
1.48 inoguchi 219: int msg;
220: int nbio;
1.47 inoguchi 221: int nbio_test;
222: char *npn_in;
223: unsigned int off;
224: char *passarg;
1.48 inoguchi 225: int pause;
1.47 inoguchi 226: int peekaboo;
227: char *port;
228: int prexit;
229: char *proxy;
1.48 inoguchi 230: int quiet;
1.47 inoguchi 231: int reconnect;
232: char *servername;
233: char *sess_in;
234: char *sess_out;
1.48 inoguchi 235: int showcerts;
1.47 inoguchi 236: int socket_type;
237: long socket_mtu;
238: #ifndef OPENSSL_NO_SRTP
239: char *srtp_profiles;
240: #endif
241: int starttls_proto;
242: int state;
1.48 inoguchi 243: int status_req;
244: int tlsextdebug;
1.47 inoguchi 245: int verify;
246: X509_VERIFY_PARAM *vpm;
247: char *xmpphost;
248: } s_client_config;
249:
250: static int
251: s_client_opt_keymatexportlen(char *arg)
252: {
253: s_client_config.keymatexportlen = strtonum(arg, 1, INT_MAX,
254: &s_client_config.errstr);
255: if (s_client_config.errstr != NULL) {
256: BIO_printf(bio_err, "invalid argument %s: %s\n",
257: arg, s_client_config.errstr);
258: return (1);
259: }
260: return (0);
261: }
262:
263: #ifndef OPENSSL_NO_DTLS1
264: static int
265: s_client_opt_mtu(char *arg)
266: {
267: s_client_config.socket_mtu = strtonum(arg, 0, LONG_MAX,
268: &s_client_config.errstr);
269: if (s_client_config.errstr != NULL) {
270: BIO_printf(bio_err, "invalid argument %s: %s\n",
271: arg, s_client_config.errstr);
272: return (1);
273: }
274: return (0);
275: }
276: #endif
277:
278: static int
279: s_client_opt_port(char *arg)
280: {
281: if (*arg == '\0')
282: return (1);
283:
284: s_client_config.port = arg;
285: return (0);
286: }
287:
288: #ifndef OPENSSL_NO_DTLS1
289: static int
290: s_client_opt_protocol_version_dtls1(void)
291: {
292: s_client_config.meth = DTLS_client_method();
293: s_client_config.socket_type = SOCK_DGRAM;
294: return (0);
295: }
296: #endif
297:
298: static int
299: s_client_opt_protocol_version_tls1(void)
300: {
301: s_client_config.min_version = TLS1_VERSION;
302: s_client_config.max_version = TLS1_VERSION;
303: return (0);
304: }
305:
306: static int
307: s_client_opt_protocol_version_tls1_1(void)
308: {
309: s_client_config.min_version = TLS1_1_VERSION;
310: s_client_config.max_version = TLS1_1_VERSION;
311: return (0);
312: }
313:
314: static int
315: s_client_opt_protocol_version_tls1_2(void)
316: {
317: s_client_config.min_version = TLS1_2_VERSION;
318: s_client_config.max_version = TLS1_2_VERSION;
319: return (0);
320: }
321:
322: static int
323: s_client_opt_protocol_version_tls1_3(void)
324: {
325: s_client_config.min_version = TLS1_3_VERSION;
326: s_client_config.max_version = TLS1_3_VERSION;
327: return (0);
328: }
329:
330: static int
331: s_client_opt_quiet(void)
332: {
1.48 inoguchi 333: s_client_config.quiet = 1;
334: s_client_config.ign_eof = 1;
1.47 inoguchi 335: return (0);
336: }
337:
338: static int
339: s_client_opt_starttls(char *arg)
340: {
341: if (strcmp(arg, "smtp") == 0)
342: s_client_config.starttls_proto = PROTO_SMTP;
343: else if (strcmp(arg, "lmtp") == 0)
344: s_client_config.starttls_proto = PROTO_LMTP;
345: else if (strcmp(arg, "pop3") == 0)
346: s_client_config.starttls_proto = PROTO_POP3;
347: else if (strcmp(arg, "imap") == 0)
348: s_client_config.starttls_proto = PROTO_IMAP;
349: else if (strcmp(arg, "ftp") == 0)
350: s_client_config.starttls_proto = PROTO_FTP;
351: else if (strcmp(arg, "xmpp") == 0)
352: s_client_config.starttls_proto = PROTO_XMPP;
353: else
354: return (1);
355: return (0);
356: }
357:
358: static int
359: s_client_opt_verify(char *arg)
360: {
361: s_client_config.verify = SSL_VERIFY_PEER;
362:
363: verify_depth = strtonum(arg, 0, INT_MAX, &s_client_config.errstr);
364: if (s_client_config.errstr != NULL) {
365: BIO_printf(bio_err, "invalid argument %s: %s\n",
366: arg, s_client_config.errstr);
367: return (1);
368: }
369: BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
370: return (0);
371: }
372:
373: static int
374: s_client_opt_verify_param(int argc, char **argv, int *argsused)
375: {
376: char **pargs = argv;
377: int pargc = argc;
378: int badarg = 0;
379:
380: if (!args_verify(&pargs, &pargc, &badarg, bio_err,
381: &s_client_config.vpm)) {
382: BIO_printf(bio_err, "unknown option %s\n", *argv);
383: return (1);
384: }
385: if (badarg)
386: return (1);
387:
388: *argsused = argc - pargc;
389: return (0);
390: }
391:
392: static const struct option s_client_options[] = {
393: {
394: .name = "4",
395: .desc = "Use IPv4 only",
396: .type = OPTION_VALUE,
397: .opt.value = &s_client_config.af,
398: .value = AF_INET,
399: },
400: {
401: .name = "6",
402: .desc = "Use IPv6 only",
403: .type = OPTION_VALUE,
404: .opt.value = &s_client_config.af,
405: .value = AF_INET6,
406: },
407: {
408: .name = "alpn",
409: .argname = "protocols",
410: .desc = "Set the advertised protocols for ALPN"
411: " (comma-separated list)",
412: .type = OPTION_ARG,
413: .opt.arg = &s_client_config.alpn_in,
414: },
415: {
416: .name = "bugs",
417: .desc = "Enable various workarounds for buggy implementations",
418: .type = OPTION_FLAG,
419: .opt.flag = &s_client_config.bugs,
420: },
421: {
422: .name = "CAfile",
423: .argname = "file",
424: .desc = "PEM format file of CA certificates",
425: .type = OPTION_ARG,
426: .opt.arg = &s_client_config.CAfile,
427: },
428: {
429: .name = "CApath",
430: .argname = "directory",
431: .desc = "PEM format directory of CA certificates",
432: .type = OPTION_ARG,
433: .opt.arg = &s_client_config.CApath,
434: },
435: {
436: .name = "cert",
437: .argname = "file",
438: .desc = "Certificate file to use, PEM format assumed",
439: .type = OPTION_ARG,
440: .opt.arg = &s_client_config.cert_file,
441: },
442: {
443: .name = "certform",
444: .argname = "fmt",
445: .desc = "Certificate format (PEM or DER) PEM default",
446: .type = OPTION_ARG_FORMAT,
447: .opt.value = &s_client_config.cert_format,
448: },
449: {
450: .name = "cipher",
451: .argname = "cipherlist",
452: .desc = "Preferred cipher to use (see 'openssl ciphers')",
453: .type = OPTION_ARG,
454: .opt.arg = &s_client_config.cipher,
455: },
456: {
457: .name = "connect",
458: .argname = "host:port",
459: .desc = "Who to connect to (default is localhost:4433)",
460: .type = OPTION_ARG,
461: .opt.arg = &s_client_config.connect,
462: },
463: {
464: .name = "crlf",
465: .desc = "Convert LF from terminal into CRLF",
466: .type = OPTION_FLAG,
467: .opt.flag = &s_client_config.crlf,
468: },
469: {
470: .name = "debug",
471: .desc = "Print extensive debugging information",
472: .type = OPTION_FLAG,
1.48 inoguchi 473: .opt.flag = &s_client_config.debug,
1.47 inoguchi 474: },
475: #ifndef OPENSSL_NO_DTLS1
476: {
477: .name = "dtls1",
478: .desc = "Just use DTLSv1",
479: .type = OPTION_FUNC,
480: .opt.func = s_client_opt_protocol_version_dtls1,
481: },
482: #endif
483: {
484: .name = "groups",
485: .argname = "list",
486: .desc = "Specify EC groups (colon-separated list)",
487: .type = OPTION_ARG,
488: .opt.arg = &s_client_config.groups_in,
489: },
490: {
491: .name = "host",
492: .argname = "host",
493: .desc = "Use -connect instead",
494: .type = OPTION_ARG,
495: .opt.arg = &s_client_config.host,
496: },
497: {
498: .name = "ign_eof",
499: .desc = "Ignore input EOF (default when -quiet)",
500: .type = OPTION_VALUE,
1.48 inoguchi 501: .opt.value = &s_client_config.ign_eof,
1.47 inoguchi 502: .value = 1,
503: },
504: {
505: .name = "key",
506: .argname = "file",
507: .desc = "Private key file to use, if not, -cert file is used",
508: .type = OPTION_ARG,
509: .opt.arg = &s_client_config.key_file,
510: },
511: {
512: .name = "keyform",
513: .argname = "fmt",
514: .desc = "Key format (PEM or DER) PEM default",
515: .type = OPTION_ARG_FORMAT,
516: .opt.value = &s_client_config.key_format,
517: },
518: {
519: .name = "keymatexport",
520: .argname = "label",
521: .desc = "Export keying material using label",
522: .type = OPTION_ARG,
523: .opt.arg = &s_client_config.keymatexportlabel,
524: },
525: {
526: .name = "keymatexportlen",
527: .argname = "len",
528: .desc = "Export len bytes of keying material (default 20)",
529: .type = OPTION_ARG_FUNC,
530: .opt.argfunc = s_client_opt_keymatexportlen,
531: },
532: {
533: .name = "legacy_renegotiation",
534: .type = OPTION_DISCARD,
535: },
536: {
537: .name = "legacy_server_connect",
538: .desc = "Allow initial connection to servers that don't support RI",
539: .type = OPTION_VALUE_OR,
540: .opt.value = &s_client_config.off,
541: .value = SSL_OP_LEGACY_SERVER_CONNECT,
542: },
543: {
544: .name = "msg",
545: .desc = "Show all protocol messages with hex dump",
546: .type = OPTION_FLAG,
1.48 inoguchi 547: .opt.flag = &s_client_config.msg,
1.47 inoguchi 548: },
549: #ifndef OPENSSL_NO_DTLS1
550: {
551: .name = "mtu",
552: .argname = "mtu",
553: .desc = "Set the link layer MTU on DTLS connections",
554: .type = OPTION_ARG_FUNC,
555: .opt.argfunc = s_client_opt_mtu,
556: },
557: #endif
558: {
559: .name = "nbio",
560: .desc = "Turn on non-blocking I/O",
561: .type = OPTION_FLAG,
1.48 inoguchi 562: .opt.flag = &s_client_config.nbio,
1.47 inoguchi 563: },
564: {
565: .name = "nbio_test",
566: .desc = "Test non-blocking I/O",
567: .type = OPTION_FLAG,
568: .opt.flag = &s_client_config.nbio_test,
569: },
570: {
571: .name = "nextprotoneg",
572: .argname = "protocols",
573: .type = OPTION_ARG,
574: .opt.arg = &s_client_config.npn_in, /* Ignored. */
575: },
576: {
577: .name = "no_comp",
578: .type = OPTION_VALUE_OR,
579: .opt.value = &s_client_config.off,
580: .value = SSL_OP_NO_COMPRESSION,
581: },
582: {
583: .name = "no_ign_eof",
584: .desc = "Don't ignore input EOF",
585: .type = OPTION_VALUE,
1.48 inoguchi 586: .opt.value = &s_client_config.ign_eof,
1.47 inoguchi 587: .value = 0,
588: },
589: {
590: .name = "no_legacy_server_connect",
591: .desc = "Disallow initial connection to servers that don't support RI",
592: .type = OPTION_VALUE_OR,
593: .opt.value = &s_client_config.clr,
594: .value = SSL_OP_LEGACY_SERVER_CONNECT,
595: },
596: {
597: .name = "no_ssl2",
598: .type = OPTION_VALUE_OR,
599: .opt.value = &s_client_config.off,
600: .value = SSL_OP_NO_SSLv2,
601: },
602: {
603: .name = "no_ssl3",
604: .type = OPTION_VALUE_OR,
605: .opt.value = &s_client_config.off,
606: .value = SSL_OP_NO_SSLv3,
607: },
608: {
609: .name = "no_ticket",
610: .desc = "Disable use of RFC4507 session ticket support",
611: .type = OPTION_VALUE_OR,
612: .opt.value = &s_client_config.off,
613: .value = SSL_OP_NO_TICKET,
614: },
615: {
616: .name = "no_tls1",
617: .desc = "Disable the use of TLSv1",
618: .type = OPTION_VALUE_OR,
619: .opt.value = &s_client_config.off,
620: .value = SSL_OP_NO_TLSv1,
621: },
622: {
623: .name = "no_tls1_1",
624: .desc = "Disable the use of TLSv1.1",
625: .type = OPTION_VALUE_OR,
626: .opt.value = &s_client_config.off,
627: .value = SSL_OP_NO_TLSv1_1,
628: },
629: {
630: .name = "no_tls1_2",
631: .desc = "Disable the use of TLSv1.2",
632: .type = OPTION_VALUE_OR,
633: .opt.value = &s_client_config.off,
634: .value = SSL_OP_NO_TLSv1_2,
635: },
636: {
637: .name = "no_tls1_3",
638: .desc = "Disable the use of TLSv1.3",
639: .type = OPTION_VALUE_OR,
640: .opt.value = &s_client_config.off,
641: .value = SSL_OP_NO_TLSv1_3,
642: },
643: {
644: .name = "pass",
645: .argname = "arg",
646: .desc = "Private key file pass phrase source",
647: .type = OPTION_ARG,
648: .opt.arg = &s_client_config.passarg,
649: },
650: {
651: .name = "pause",
652: .desc = "Pause 1 second between each read and write call",
653: .type = OPTION_FLAG,
1.48 inoguchi 654: .opt.flag = &s_client_config.pause,
1.47 inoguchi 655: },
656: {
657: .name = "peekaboo",
658: .type = OPTION_FLAG,
659: .opt.flag = &s_client_config.peekaboo,
660: },
661: {
662: .name = "port",
663: .argname = "port",
664: .desc = "Use -connect instead",
665: .type = OPTION_ARG_FUNC,
666: .opt.argfunc = s_client_opt_port,
667: },
668: {
669: .name = "prexit",
670: .desc = "Print session information when the program exits",
671: .type = OPTION_FLAG,
672: .opt.flag = &s_client_config.prexit,
673: },
674: {
675: .name = "proxy",
676: .argname = "host:port",
677: .desc = "Connect to http proxy",
678: .type = OPTION_ARG,
679: .opt.arg = &s_client_config.proxy,
680: },
681: {
682: .name = "quiet",
683: .desc = "Inhibit printing of session and certificate info",
684: .type = OPTION_FUNC,
685: .opt.func = s_client_opt_quiet,
686: },
687: {
688: .name = "reconnect",
689: .desc = "Drop and re-make the connection with the same Session-ID",
690: .type = OPTION_VALUE,
691: .opt.value = &s_client_config.reconnect,
692: .value = 5,
693: },
694: {
695: .name = "servername",
696: .argname = "name",
697: .desc = "Set TLS extension servername in ClientHello (SNI)",
698: .type = OPTION_ARG,
699: .opt.arg = &s_client_config.servername,
700: },
701: {
702: .name = "serverpref",
703: .desc = "Use server's cipher preferences",
704: .type = OPTION_VALUE_OR,
705: .opt.value = &s_client_config.off,
706: .value = SSL_OP_CIPHER_SERVER_PREFERENCE,
707: },
708: {
709: .name = "sess_in",
710: .argname = "file",
711: .desc = "File to read TLS session from",
712: .type = OPTION_ARG,
713: .opt.arg = &s_client_config.sess_in,
714: },
715: {
716: .name = "sess_out",
717: .argname = "file",
718: .desc = "File to write TLS session to",
719: .type = OPTION_ARG,
720: .opt.arg = &s_client_config.sess_out,
721: },
722: {
723: .name = "showcerts",
724: .desc = "Show all server certificates in the chain",
725: .type = OPTION_FLAG,
1.48 inoguchi 726: .opt.flag = &s_client_config.showcerts,
1.47 inoguchi 727: },
728: {
729: .name = "starttls",
730: .argname = "protocol",
731: .desc = "Use the STARTTLS command before starting TLS,\n"
732: "smtp, lmtp, pop3, imap, ftp and xmpp are supported.",
733: .type = OPTION_ARG_FUNC,
734: .opt.argfunc = s_client_opt_starttls,
735: },
736: {
737: .name = "state",
738: .desc = "Print the TLS session states",
739: .type = OPTION_FLAG,
740: .opt.flag = &s_client_config.state,
741: },
742: {
743: .name = "status",
744: .desc = "Send a certificate status request to the server (OCSP)",
745: .type = OPTION_FLAG,
1.48 inoguchi 746: .opt.flag = &s_client_config.status_req,
1.47 inoguchi 747: },
748: #ifndef OPENSSL_NO_DTLS1
749: {
750: .name = "timeout",
751: .desc = "Enable send/receive timeout on DTLS connections",
752: .type = OPTION_FLAG,
753: .opt.flag = &s_client_config.enable_timeouts,
754: },
755: #endif
756: {
757: .name = "tls1",
758: .desc = "Just use TLSv1",
759: .type = OPTION_FUNC,
760: .opt.func = s_client_opt_protocol_version_tls1,
761: },
762: {
763: .name = "tls1_1",
764: .desc = "Just use TLSv1.1",
765: .type = OPTION_FUNC,
766: .opt.func = s_client_opt_protocol_version_tls1_1,
767: },
768: {
769: .name = "tls1_2",
770: .desc = "Just use TLSv1.2",
771: .type = OPTION_FUNC,
772: .opt.func = s_client_opt_protocol_version_tls1_2,
773: },
774: {
775: .name = "tls1_3",
776: .desc = "Just use TLSv1.3",
777: .type = OPTION_FUNC,
778: .opt.func = s_client_opt_protocol_version_tls1_3,
779: },
780: {
781: .name = "tlsextdebug",
782: .desc = "Hex dump of all TLS extensions received",
783: .type = OPTION_FLAG,
1.48 inoguchi 784: .opt.flag = &s_client_config.tlsextdebug,
1.47 inoguchi 785: },
786: #ifndef OPENSSL_NO_SRTP
787: {
788: .name = "use_srtp",
789: .argname = "profiles",
790: .desc = "Offer SRTP key management with a colon-separated profiles",
791: .type = OPTION_ARG,
792: .opt.arg = &s_client_config.srtp_profiles,
793: },
794: #endif
795: {
796: .name = "verify",
797: .argname = "depth",
798: .desc = "Turn on peer certificate verification, with a max of depth",
799: .type = OPTION_ARG_FUNC,
800: .opt.argfunc = s_client_opt_verify,
801: },
802: {
803: .name = "verify_return_error",
804: .desc = "Return verification error",
805: .type = OPTION_FLAG,
806: .opt.flag = &verify_return_error,
807: },
808: {
809: .name = "xmpphost",
810: .argname = "host",
811: .desc = "Connect to this virtual host on the xmpp server",
812: .type = OPTION_ARG,
813: .opt.arg = &s_client_config.xmpphost,
814: },
815: {
816: .name = NULL,
817: .desc = "",
818: .type = OPTION_ARGV_FUNC,
819: .opt.argvfunc = s_client_opt_verify_param,
820: },
821: { NULL },
822: };
1.1 jsing 823:
824: static void
825: sc_usage(void)
826: {
1.47 inoguchi 827: fprintf(stderr, "usage: s_client "
828: "[-4 | -6] [-alpn protocols] [-bugs] [-CAfile file]\n"
829: " [-CApath directory] [-cert file] [-certform der | pem] [-check_ss_sig]\n"
830: " [-cipher cipherlist] [-connect host[:port]] [-crl_check]\n"
831: " [-crl_check_all] [-crlf] [-debug] [-dtls1] [-extended_crl]\n"
832: " [-groups list] [-host host] [-ign_eof] [-ignore_critical]\n"
833: " [-issuer_checks] [-key keyfile] [-keyform der | pem]\n"
834: " [-keymatexport label] [-keymatexportlen len] [-legacy_server_connect]\n"
835: " [-msg] [-mtu mtu] [-nbio] [-nbio_test] [-no_comp] [-no_ign_eof]\n"
836: " [-no_legacy_server_connect] [-no_ticket] [-no_tls1] [-no_tls1_1]\n"
837: " [-no_tls1_2] [-no_tls1_3] [-pass arg] [-pause] [-policy_check]\n"
838: " [-port port] [-prexit] [-proxy host:port] [-quiet] [-reconnect]\n"
839: " [-servername name] [-serverpref] [-sess_in file] [-sess_out file]\n"
840: " [-showcerts] [-starttls protocol] [-state] [-status] [-timeout]\n"
841: " [-tls1] [-tls1_1] [-tls1_2] [-tls1_3] [-tlsextdebug]\n"
842: " [-use_srtp profiles] [-verify depth] [-verify_return_error]\n"
843: " [-x509_strict] [-xmpphost host]\n");
844: fprintf(stderr, "\n");
845: options_usage(s_client_options);
846: fprintf(stderr, "\n");
1.1 jsing 847: }
848:
849: int
850: s_client_main(int argc, char **argv)
851: {
852: SSL *con = NULL;
1.47 inoguchi 853: int s, k, p = 0, pending = 0;
1.39 beck 854: char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL, *pbuf = NULL;
1.1 jsing 855: int cbuf_len, cbuf_off;
856: int sbuf_len, sbuf_off;
1.39 beck 857: int pbuf_len, pbuf_off;
1.1 jsing 858: int full_log = 1;
1.47 inoguchi 859: char *pass = NULL;
1.1 jsing 860: X509 *cert = NULL;
861: EVP_PKEY *key = NULL;
1.47 inoguchi 862: int badop = 0;
1.1 jsing 863: int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
864: SSL_CTX *ctx = NULL;
1.47 inoguchi 865: int ret = 1, in_init = 1, i;
1.50 inoguchi 866: BIO *bio_c_out = NULL;
1.1 jsing 867: BIO *sbio;
868: int mbuf_len = 0;
1.9 deraadt 869: struct timeval timeout;
1.33 jsing 870: tlsextctx tlsextcbp = {NULL, 0};
1.45 deraadt 871: struct sockaddr_storage peer;
1.1 jsing 872: int peerlen = sizeof(peer);
1.21 doug 873:
874: if (single_execution) {
1.30 deraadt 875: if (pledge("stdio cpath wpath rpath inet dns tty", NULL) == -1) {
1.21 doug 876: perror("pledge");
1.23 doug 877: exit(1);
878: }
1.21 doug 879: }
1.1 jsing 880:
1.47 inoguchi 881: memset(&s_client_config, 0, sizeof(s_client_config));
882: s_client_config.af = AF_UNSPEC;
883: s_client_config.cert_format = FORMAT_PEM;
884: s_client_config.host = SSL_HOST_NAME;
885: s_client_config.key_format = FORMAT_PEM;
886: s_client_config.keymatexportlen = 20;
887: s_client_config.meth = TLS_client_method();
888: s_client_config.port = PORT_STR;
889: s_client_config.socket_type = SOCK_STREAM;
890: s_client_config.starttls_proto = PROTO_OFF;
891: s_client_config.verify = SSL_VERIFY_NONE;
1.1 jsing 892:
893: if (((cbuf = malloc(BUFSIZZ)) == NULL) ||
894: ((sbuf = malloc(BUFSIZZ)) == NULL) ||
1.39 beck 895: ((pbuf = malloc(BUFSIZZ)) == NULL) ||
1.1 jsing 896: ((mbuf = malloc(BUFSIZZ + 1)) == NULL)) { /* NUL byte */
897: BIO_printf(bio_err, "out of memory\n");
898: goto end;
899: }
900: verify_depth = 0;
901:
1.47 inoguchi 902: if (options_parse(argc, argv, s_client_options, NULL, NULL) != 0) {
903: badop = 1;
904: goto bad;
1.1 jsing 905: }
1.47 inoguchi 906: if (s_client_config.proxy != NULL) {
1.49 inoguchi 907: if (!extract_host_port(s_client_config.proxy,
908: &s_client_config.host, NULL, &s_client_config.port))
1.12 bluhm 909: goto bad;
1.47 inoguchi 910: if (s_client_config.connect == NULL)
911: s_client_config.connect = SSL_HOST_NAME;
912: } else if (s_client_config.connect != NULL) {
1.49 inoguchi 913: if (!extract_host_port(s_client_config.connect,
914: &s_client_config.host, NULL, &s_client_config.port))
1.12 bluhm 915: goto bad;
916: }
1.1 jsing 917: if (badop) {
1.35 jsing 918: bad:
1.47 inoguchi 919: if (s_client_config.errstr == NULL)
1.1 jsing 920: sc_usage();
921: goto end;
922: }
923:
1.47 inoguchi 924: if (!app_passwd(bio_err, s_client_config.passarg, NULL, &pass, NULL)) {
1.1 jsing 925: BIO_printf(bio_err, "Error getting password\n");
926: goto end;
927: }
1.47 inoguchi 928: if (s_client_config.key_file == NULL)
929: s_client_config.key_file = s_client_config.cert_file;
1.1 jsing 930:
931:
1.47 inoguchi 932: if (s_client_config.key_file) {
1.1 jsing 933:
1.49 inoguchi 934: key = load_key(bio_err, s_client_config.key_file,
935: s_client_config.key_format, 0, pass,
1.1 jsing 936: "client certificate private key file");
937: if (!key) {
938: ERR_print_errors(bio_err);
939: goto end;
940: }
941: }
1.47 inoguchi 942: if (s_client_config.cert_file) {
1.49 inoguchi 943: cert = load_cert(bio_err, s_client_config.cert_file,
944: s_client_config.cert_format,
1.19 bcook 945: NULL, "client certificate file");
1.1 jsing 946:
947: if (!cert) {
948: ERR_print_errors(bio_err);
949: goto end;
950: }
951: }
1.50 inoguchi 952: if (s_client_config.quiet && !s_client_config.debug &&
953: !s_client_config.msg) {
954: if ((bio_c_out = BIO_new(BIO_s_null())) == NULL)
955: goto end;
956: } else {
957: if ((bio_c_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
958: goto end;
1.1 jsing 959: }
960:
1.47 inoguchi 961: ctx = SSL_CTX_new(s_client_config.meth);
1.1 jsing 962: if (ctx == NULL) {
963: ERR_print_errors(bio_err);
964: goto end;
965: }
1.46 tb 966:
967: SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
968:
1.47 inoguchi 969: if (s_client_config.vpm)
970: SSL_CTX_set1_param(ctx, s_client_config.vpm);
1.42 jsing 971:
1.47 inoguchi 972: if (!SSL_CTX_set_min_proto_version(ctx, s_client_config.min_version))
1.42 jsing 973: goto end;
1.47 inoguchi 974: if (!SSL_CTX_set_max_proto_version(ctx, s_client_config.max_version))
1.42 jsing 975: goto end;
1.1 jsing 976:
977: #ifndef OPENSSL_NO_SRTP
1.47 inoguchi 978: if (s_client_config.srtp_profiles != NULL)
979: SSL_CTX_set_tlsext_use_srtp(ctx, s_client_config.srtp_profiles);
1.1 jsing 980: #endif
1.47 inoguchi 981: if (s_client_config.bugs)
982: SSL_CTX_set_options(ctx, SSL_OP_ALL | s_client_config.off);
1.1 jsing 983: else
1.47 inoguchi 984: SSL_CTX_set_options(ctx, s_client_config.off);
1.1 jsing 985:
1.47 inoguchi 986: if (s_client_config.clr)
987: SSL_CTX_clear_options(ctx, s_client_config.clr);
1.1 jsing 988: /*
989: * DTLS: partial reads end up discarding unread UDP bytes :-( Setting
990: * read ahead solves this problem.
991: */
1.47 inoguchi 992: if (s_client_config.socket_type == SOCK_DGRAM)
1.1 jsing 993: SSL_CTX_set_read_ahead(ctx, 1);
994:
1.47 inoguchi 995: if (s_client_config.alpn_in) {
1.10 jsing 996: unsigned short alpn_len;
1.49 inoguchi 997: unsigned char *alpn;
1.10 jsing 998:
1.49 inoguchi 999: alpn = next_protos_parse(&alpn_len, s_client_config.alpn_in);
1.10 jsing 1000: if (alpn == NULL) {
1001: BIO_printf(bio_err, "Error parsing -alpn argument\n");
1002: goto end;
1003: }
1004: SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
1005: free(alpn);
1.31 jsing 1006: }
1.47 inoguchi 1007: if (s_client_config.groups_in != NULL) {
1008: if (SSL_CTX_set1_groups_list(ctx, s_client_config.groups_in) != 1) {
1.31 jsing 1009: BIO_printf(bio_err, "Failed to set groups '%s'\n",
1.47 inoguchi 1010: s_client_config.groups_in);
1.31 jsing 1011: goto end;
1012: }
1.10 jsing 1013: }
1.1 jsing 1014:
1.47 inoguchi 1015: if (s_client_config.state)
1.1 jsing 1016: SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
1.47 inoguchi 1017: if (s_client_config.cipher != NULL)
1018: if (!SSL_CTX_set_cipher_list(ctx, s_client_config.cipher)) {
1.1 jsing 1019: BIO_printf(bio_err, "error setting cipher list\n");
1020: ERR_print_errors(bio_err);
1021: goto end;
1022: }
1023:
1.47 inoguchi 1024: SSL_CTX_set_verify(ctx, s_client_config.verify, verify_callback);
1.1 jsing 1025: if (!set_cert_key_stuff(ctx, cert, key))
1026: goto end;
1027:
1.47 inoguchi 1028: if ((s_client_config.CAfile || s_client_config.CApath)
1.49 inoguchi 1029: && !SSL_CTX_load_verify_locations(ctx, s_client_config.CAfile,
1030: s_client_config.CApath))
1.1 jsing 1031: ERR_print_errors(bio_err);
1.28 bcook 1032:
1033: if (!SSL_CTX_set_default_verify_paths(ctx))
1034: ERR_print_errors(bio_err);
1035:
1.47 inoguchi 1036: if (s_client_config.servername != NULL) {
1.1 jsing 1037: tlsextcbp.biodebug = bio_err;
1038: SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
1039: SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
1040: }
1041:
1042: con = SSL_new(ctx);
1.47 inoguchi 1043: if (s_client_config.sess_in) {
1.1 jsing 1044: SSL_SESSION *sess;
1.47 inoguchi 1045: BIO *stmp = BIO_new_file(s_client_config.sess_in, "r");
1.1 jsing 1046: if (!stmp) {
1047: BIO_printf(bio_err, "Can't open session file %s\n",
1.47 inoguchi 1048: s_client_config.sess_in);
1.1 jsing 1049: ERR_print_errors(bio_err);
1050: goto end;
1051: }
1052: sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
1053: BIO_free(stmp);
1054: if (!sess) {
1055: BIO_printf(bio_err, "Can't open session file %s\n",
1.47 inoguchi 1056: s_client_config.sess_in);
1.1 jsing 1057: ERR_print_errors(bio_err);
1058: goto end;
1059: }
1060: SSL_set_session(con, sess);
1061: SSL_SESSION_free(sess);
1062: }
1.47 inoguchi 1063: if (s_client_config.servername != NULL) {
1064: if (!SSL_set_tlsext_host_name(con, s_client_config.servername)) {
1.49 inoguchi 1065: BIO_printf(bio_err,
1066: "Unable to set TLS servername extension.\n");
1.1 jsing 1067: ERR_print_errors(bio_err);
1068: goto end;
1069: }
1070: }
1071: /* SSL_set_cipher_list(con,"RC4-MD5"); */
1072:
1.49 inoguchi 1073: re_start:
1.1 jsing 1074:
1.49 inoguchi 1075: if (init_client(&s, s_client_config.host, s_client_config.port,
1076: s_client_config.socket_type, s_client_config.af) == 0) {
1.1 jsing 1077: BIO_printf(bio_err, "connect:errno=%d\n", errno);
1078: goto end;
1079: }
1080: BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
1081:
1.48 inoguchi 1082: if (s_client_config.nbio) {
1083: if (!s_client_config.quiet)
1.3 bcook 1084: BIO_printf(bio_c_out, "turning on non blocking io\n");
1085: if (!BIO_socket_nbio(s, 1)) {
1.1 jsing 1086: ERR_print_errors(bio_err);
1087: goto end;
1088: }
1089: }
1.48 inoguchi 1090: if (s_client_config.pause & 0x01)
1.1 jsing 1091: SSL_set_debug(con, 1);
1092:
1093: if (SSL_version(con) == DTLS1_VERSION) {
1094:
1095: sbio = BIO_new_dgram(s, BIO_NOCLOSE);
1.45 deraadt 1096: if (getsockname(s, (struct sockaddr *)&peer,
1097: (void *)&peerlen) == -1) {
1.1 jsing 1098: BIO_printf(bio_err, "getsockname:errno=%d\n",
1099: errno);
1100: shutdown(s, SHUT_RD);
1101: close(s);
1102: goto end;
1103: }
1104: (void) BIO_ctrl_set_connected(sbio, 1, &peer);
1105:
1.47 inoguchi 1106: if (s_client_config.enable_timeouts) {
1.1 jsing 1107: timeout.tv_sec = 0;
1108: timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1.49 inoguchi 1109: BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0,
1110: &timeout);
1.1 jsing 1111:
1112: timeout.tv_sec = 0;
1113: timeout.tv_usec = DGRAM_SND_TIMEOUT;
1.49 inoguchi 1114: BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0,
1115: &timeout);
1.1 jsing 1116: }
1.47 inoguchi 1117: if (s_client_config.socket_mtu > 28) {
1.1 jsing 1118: SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1.47 inoguchi 1119: SSL_set_mtu(con, s_client_config.socket_mtu - 28);
1.1 jsing 1120: } else
1121: /* want to do MTU discovery */
1122: BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1123: } else
1124: sbio = BIO_new_socket(s, BIO_NOCLOSE);
1125:
1.47 inoguchi 1126: if (s_client_config.nbio_test) {
1.1 jsing 1127: BIO *test;
1128:
1129: test = BIO_new(BIO_f_nbio_test());
1130: sbio = BIO_push(test, sbio);
1131: }
1.48 inoguchi 1132: if (s_client_config.debug) {
1.1 jsing 1133: SSL_set_debug(con, 1);
1134: BIO_set_callback(sbio, bio_dump_callback);
1135: BIO_set_callback_arg(sbio, (char *) bio_c_out);
1136: }
1.48 inoguchi 1137: if (s_client_config.msg) {
1.1 jsing 1138: SSL_set_msg_callback(con, msg_cb);
1139: SSL_set_msg_callback_arg(con, bio_c_out);
1140: }
1.48 inoguchi 1141: if (s_client_config.tlsextdebug) {
1.1 jsing 1142: SSL_set_tlsext_debug_callback(con, tlsext_cb);
1143: SSL_set_tlsext_debug_arg(con, bio_c_out);
1144: }
1.48 inoguchi 1145: if (s_client_config.status_req) {
1.1 jsing 1146: SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
1147: SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
1148: SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
1149: }
1150:
1151: SSL_set_bio(con, sbio, sbio);
1152: SSL_set_connect_state(con);
1153:
1154: /* ok, lets connect */
1155: read_tty = 1;
1156: write_tty = 0;
1157: tty_on = 0;
1158: read_ssl = 1;
1159: write_ssl = 1;
1160:
1161: cbuf_len = 0;
1162: cbuf_off = 0;
1163: sbuf_len = 0;
1164: sbuf_off = 0;
1.39 beck 1165: pbuf_len = 0;
1166: pbuf_off = 0;
1.1 jsing 1167:
1168: /* This is an ugly hack that does a lot of assumptions */
1169: /*
1170: * We do have to handle multi-line responses which may come in a
1171: * single packet or not. We therefore have to use BIO_gets() which
1172: * does need a buffering BIO. So during the initial chitchat we do
1173: * push a buffering BIO into the chain that is removed again later on
1174: * to not disturb the rest of the s_client operation.
1175: */
1.49 inoguchi 1176: if (s_client_config.starttls_proto == PROTO_SMTP ||
1177: s_client_config.starttls_proto == PROTO_LMTP) {
1.1 jsing 1178: int foundit = 0;
1179: BIO *fbio = BIO_new(BIO_f_buffer());
1180: BIO_push(fbio, sbio);
1181: /* wait for multi-line response to end from SMTP */
1182: do {
1183: mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1184: }
1185: while (mbuf_len > 3 && mbuf[3] == '-');
1186: /* STARTTLS command requires EHLO... */
1187: BIO_printf(fbio, "%cHLO openssl.client.net\r\n",
1.49 inoguchi 1188: s_client_config.starttls_proto == PROTO_SMTP ? 'E' : 'L');
1.1 jsing 1189: (void) BIO_flush(fbio);
1190: /* wait for multi-line response to end EHLO SMTP response */
1191: do {
1192: mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1193: if (strstr(mbuf, "STARTTLS"))
1194: foundit = 1;
1195: }
1196: while (mbuf_len > 3 && mbuf[3] == '-');
1197: (void) BIO_flush(fbio);
1198: BIO_pop(fbio);
1199: BIO_free(fbio);
1200: if (!foundit)
1201: BIO_printf(bio_err,
1.36 jmc 1202: "didn't find starttls in server response,"
1.1 jsing 1203: " try anyway...\n");
1204: BIO_printf(sbio, "STARTTLS\r\n");
1205: BIO_read(sbio, sbuf, BUFSIZZ);
1.47 inoguchi 1206: } else if (s_client_config.starttls_proto == PROTO_POP3) {
1.1 jsing 1207: mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
1208: if (mbuf_len == -1) {
1209: BIO_printf(bio_err, "BIO_read failed\n");
1210: goto end;
1211: }
1212: BIO_printf(sbio, "STLS\r\n");
1213: BIO_read(sbio, sbuf, BUFSIZZ);
1.47 inoguchi 1214: } else if (s_client_config.starttls_proto == PROTO_IMAP) {
1.1 jsing 1215: int foundit = 0;
1216: BIO *fbio = BIO_new(BIO_f_buffer());
1217: BIO_push(fbio, sbio);
1218: BIO_gets(fbio, mbuf, BUFSIZZ);
1219: /* STARTTLS command requires CAPABILITY... */
1220: BIO_printf(fbio, ". CAPABILITY\r\n");
1221: (void) BIO_flush(fbio);
1222: /* wait for multi-line CAPABILITY response */
1223: do {
1224: mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1225: if (strstr(mbuf, "STARTTLS"))
1226: foundit = 1;
1227: }
1228: while (mbuf_len > 3 && mbuf[0] != '.');
1229: (void) BIO_flush(fbio);
1230: BIO_pop(fbio);
1231: BIO_free(fbio);
1232: if (!foundit)
1233: BIO_printf(bio_err,
1.37 tb 1234: "didn't find STARTTLS in server response,"
1.1 jsing 1235: " try anyway...\n");
1236: BIO_printf(sbio, ". STARTTLS\r\n");
1237: BIO_read(sbio, sbuf, BUFSIZZ);
1.47 inoguchi 1238: } else if (s_client_config.starttls_proto == PROTO_FTP) {
1.1 jsing 1239: BIO *fbio = BIO_new(BIO_f_buffer());
1240: BIO_push(fbio, sbio);
1241: /* wait for multi-line response to end from FTP */
1242: do {
1243: mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
1244: }
1245: while (mbuf_len > 3 && mbuf[3] == '-');
1246: (void) BIO_flush(fbio);
1247: BIO_pop(fbio);
1248: BIO_free(fbio);
1249: BIO_printf(sbio, "AUTH TLS\r\n");
1250: BIO_read(sbio, sbuf, BUFSIZZ);
1.47 inoguchi 1251: } else if (s_client_config.starttls_proto == PROTO_XMPP) {
1.1 jsing 1252: int seen = 0;
1253: BIO_printf(sbio, "<stream:stream "
1254: "xmlns:stream='http://etherx.jabber.org/streams' "
1.49 inoguchi 1255: "xmlns='jabber:client' to='%s' version='1.0'>",
1256: s_client_config.xmpphost ?
1257: s_client_config.xmpphost : s_client_config.host);
1.1 jsing 1258: seen = BIO_read(sbio, mbuf, BUFSIZZ);
1.15 landry 1259:
1260: if (seen <= 0)
1261: goto shut;
1262:
1.1 jsing 1263: mbuf[seen] = 0;
1.15 landry 1264: while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
1265: !strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"")) {
1266: seen = BIO_read(sbio, mbuf, BUFSIZZ);
1267:
1268: if (seen <= 0)
1.1 jsing 1269: goto shut;
1.15 landry 1270:
1.1 jsing 1271: mbuf[seen] = 0;
1272: }
1.49 inoguchi 1273: BIO_printf(sbio,
1274: "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1.1 jsing 1275: seen = BIO_read(sbio, sbuf, BUFSIZZ);
1276: sbuf[seen] = 0;
1277: if (!strstr(sbuf, "<proceed"))
1278: goto shut;
1279: mbuf[0] = 0;
1.47 inoguchi 1280: } else if (s_client_config.proxy != NULL) {
1.49 inoguchi 1281: BIO_printf(sbio, "CONNECT %s HTTP/1.0\r\n\r\n",
1282: s_client_config.connect);
1.12 bluhm 1283: mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
1284: if (mbuf_len == -1) {
1285: BIO_printf(bio_err, "BIO_read failed\n");
1286: goto end;
1287: }
1.1 jsing 1288: }
1289: for (;;) {
1.9 deraadt 1290: struct pollfd pfd[3]; /* stdin, stdout, socket */
1291: int ptimeout = -1;
1.1 jsing 1292:
1293: if ((SSL_version(con) == DTLS1_VERSION) &&
1294: DTLSv1_get_timeout(con, &timeout))
1.49 inoguchi 1295: ptimeout = timeout.tv_sec * 1000 +
1296: timeout.tv_usec / 1000;
1.1 jsing 1297:
1298: if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
1299: in_init = 1;
1300: tty_on = 0;
1301: } else {
1302: tty_on = 1;
1303: if (in_init) {
1304: in_init = 0;
1.47 inoguchi 1305: if (s_client_config.sess_out) {
1.49 inoguchi 1306: BIO *stmp = BIO_new_file(
1307: s_client_config.sess_out, "w");
1.1 jsing 1308: if (stmp) {
1.49 inoguchi 1309: PEM_write_bio_SSL_SESSION(stmp,
1310: SSL_get_session(con));
1.1 jsing 1311: BIO_free(stmp);
1312: } else
1.49 inoguchi 1313: BIO_printf(bio_err,
1314: "Error writing session file %s\n",
1315: s_client_config.sess_out);
1.1 jsing 1316: }
1317: print_stuff(bio_c_out, con, full_log);
1318: if (full_log > 0)
1319: full_log--;
1320:
1.47 inoguchi 1321: if (s_client_config.starttls_proto) {
1.1 jsing 1322: BIO_write(bio_err, mbuf, mbuf_len);
1323: /* We don't need to know any more */
1.47 inoguchi 1324: s_client_config.starttls_proto = PROTO_OFF;
1.1 jsing 1325: }
1.47 inoguchi 1326: if (s_client_config.reconnect) {
1327: s_client_config.reconnect--;
1.49 inoguchi 1328: BIO_printf(bio_c_out,
1329: "drop connection and then reconnect\n");
1.1 jsing 1330: SSL_shutdown(con);
1331: SSL_set_connect_state(con);
1332: shutdown(SSL_get_fd(con), SHUT_RD);
1333: close(SSL_get_fd(con));
1334: goto re_start;
1335: }
1336: }
1337: }
1338:
1339: ssl_pending = read_ssl && SSL_pending(con);
1340:
1.9 deraadt 1341: pfd[0].fd = -1;
1342: pfd[1].fd = -1;
1.1 jsing 1343: if (!ssl_pending) {
1344: if (tty_on) {
1.9 deraadt 1345: if (read_tty) {
1346: pfd[0].fd = fileno(stdin);
1347: pfd[0].events = POLLIN;
1348: }
1349: if (write_tty) {
1350: pfd[1].fd = fileno(stdout);
1351: pfd[1].events = POLLOUT;
1352: }
1.1 jsing 1353: }
1.9 deraadt 1354:
1355: pfd[2].fd = SSL_get_fd(con);
1356: pfd[2].events = 0;
1.1 jsing 1357: if (read_ssl)
1.9 deraadt 1358: pfd[2].events |= POLLIN;
1.1 jsing 1359: if (write_ssl)
1.9 deraadt 1360: pfd[2].events |= POLLOUT;
1361:
1.1 jsing 1362: /* printf("mode tty(%d %d%d) ssl(%d%d)\n",
1363: tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
1364:
1.9 deraadt 1365: i = poll(pfd, 3, ptimeout);
1.38 deraadt 1366: if (i == -1) {
1.1 jsing 1367: BIO_printf(bio_err, "bad select %d\n",
1368: errno);
1369: goto shut;
1370: /* goto end; */
1371: }
1372: }
1.49 inoguchi 1373: if ((SSL_version(con) == DTLS1_VERSION) &&
1374: DTLSv1_handle_timeout(con) > 0) {
1.1 jsing 1375: BIO_printf(bio_err, "TIMEOUT occured\n");
1376: }
1.49 inoguchi 1377: if (!ssl_pending &&
1378: (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) {
1.9 deraadt 1379: if (pfd[2].revents & (POLLERR|POLLNVAL)) {
1380: BIO_printf(bio_err, "poll error");
1381: goto shut;
1382: }
1.1 jsing 1383: k = SSL_write(con, &(cbuf[cbuf_off]),
1384: (unsigned int) cbuf_len);
1385: switch (SSL_get_error(con, k)) {
1386: case SSL_ERROR_NONE:
1387: cbuf_off += k;
1388: cbuf_len -= k;
1389: if (k <= 0)
1390: goto end;
1391: /* we have done a write(con,NULL,0); */
1392: if (cbuf_len <= 0) {
1393: read_tty = 1;
1394: write_ssl = 0;
1395: } else { /* if (cbuf_len > 0) */
1396: read_tty = 0;
1397: write_ssl = 1;
1398: }
1399: break;
1400: case SSL_ERROR_WANT_WRITE:
1401: BIO_printf(bio_c_out, "write W BLOCK\n");
1402: write_ssl = 1;
1403: read_tty = 0;
1404: break;
1405: case SSL_ERROR_WANT_READ:
1406: BIO_printf(bio_c_out, "write R BLOCK\n");
1407: write_tty = 0;
1408: read_ssl = 1;
1409: write_ssl = 0;
1410: break;
1411: case SSL_ERROR_WANT_X509_LOOKUP:
1412: BIO_printf(bio_c_out, "write X BLOCK\n");
1413: break;
1414: case SSL_ERROR_ZERO_RETURN:
1415: if (cbuf_len != 0) {
1416: BIO_printf(bio_c_out, "shutdown\n");
1417: ret = 0;
1418: goto shut;
1419: } else {
1420: read_tty = 1;
1421: write_ssl = 0;
1422: break;
1423: }
1424:
1425: case SSL_ERROR_SYSCALL:
1426: if ((k != 0) || (cbuf_len != 0)) {
1427: BIO_printf(bio_err, "write:errno=%d\n",
1428: errno);
1429: goto shut;
1430: } else {
1431: read_tty = 1;
1432: write_ssl = 0;
1433: }
1434: break;
1435: case SSL_ERROR_SSL:
1436: ERR_print_errors(bio_err);
1437: goto shut;
1438: }
1.9 deraadt 1439: } else if (!ssl_pending &&
1440: (pfd[1].revents & (POLLOUT|POLLERR|POLLNVAL))) {
1441: if (pfd[1].revents & (POLLERR|POLLNVAL)) {
1442: BIO_printf(bio_err, "poll error");
1443: goto shut;
1444: }
1.1 jsing 1445: i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len);
1446:
1447: if (i <= 0) {
1448: BIO_printf(bio_c_out, "DONE\n");
1449: ret = 0;
1450: goto shut;
1451: /* goto end; */
1452: }
1453: sbuf_len -= i;
1454: sbuf_off += i;
1455: if (sbuf_len <= 0) {
1456: read_ssl = 1;
1457: write_tty = 0;
1458: }
1.9 deraadt 1459: } else if (ssl_pending || (pfd[2].revents & (POLLIN|POLLHUP))) {
1.1 jsing 1460: #ifdef RENEG
1461: {
1462: static int iiii;
1463: if (++iiii == 52) {
1464: SSL_renegotiate(con);
1465: iiii = 0;
1466: }
1467: }
1468: #endif
1.47 inoguchi 1469: if (s_client_config.peekaboo) {
1.40 jsing 1470: k = p = SSL_peek(con, pbuf, 1024 /* BUFSIZZ */ );
1.41 beck 1471: pending = SSL_pending(con);
1.40 jsing 1472: if (SSL_get_error(con, p) == SSL_ERROR_NONE) {
1.39 beck 1473: if (p <= 0)
1474: goto end;
1475: pbuf_off = 0;
1476: pbuf_len = p;
1477:
1.40 jsing 1478: k = SSL_read(con, sbuf, p);
1.39 beck 1479: }
1.40 jsing 1480: } else {
1481: k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ );
1.39 beck 1482: }
1.1 jsing 1483:
1484: switch (SSL_get_error(con, k)) {
1485: case SSL_ERROR_NONE:
1486: if (k <= 0)
1487: goto end;
1488: sbuf_off = 0;
1489: sbuf_len = k;
1.47 inoguchi 1490: if (s_client_config.peekaboo) {
1.41 beck 1491: if (p != pending) {
1492: ret = -1;
1493: BIO_printf(bio_err,
1.49 inoguchi 1494: "peeked %d but pending %d!\n",
1495: p, pending);
1.41 beck 1496: goto shut;
1497: }
1.39 beck 1498: if (k < p) {
1499: ret = -1;
1500: BIO_printf(bio_err,
1501: "read less than peek!\n");
1502: goto shut;
1503: }
1.49 inoguchi 1504: if (p > 0 &&
1505: (memcmp(sbuf, pbuf, p) != 0)) {
1.39 beck 1506: ret = -1;
1507: BIO_printf(bio_err,
1508: "peek of %d different from read of %d!\n",
1509: p, k);
1510: goto shut;
1511: }
1512: }
1.1 jsing 1513: read_ssl = 0;
1514: write_tty = 1;
1515: break;
1516: case SSL_ERROR_WANT_WRITE:
1517: BIO_printf(bio_c_out, "read W BLOCK\n");
1518: write_ssl = 1;
1519: read_tty = 0;
1520: break;
1521: case SSL_ERROR_WANT_READ:
1522: BIO_printf(bio_c_out, "read R BLOCK\n");
1523: write_tty = 0;
1524: read_ssl = 1;
1525: if ((read_tty == 0) && (write_ssl == 0))
1526: write_ssl = 1;
1527: break;
1528: case SSL_ERROR_WANT_X509_LOOKUP:
1529: BIO_printf(bio_c_out, "read X BLOCK\n");
1530: break;
1531: case SSL_ERROR_SYSCALL:
1532: ret = errno;
1533: BIO_printf(bio_err, "read:errno=%d\n", ret);
1534: goto shut;
1535: case SSL_ERROR_ZERO_RETURN:
1536: BIO_printf(bio_c_out, "closed\n");
1537: ret = 0;
1538: goto shut;
1539: case SSL_ERROR_SSL:
1540: ERR_print_errors(bio_err);
1541: goto shut;
1542: /* break; */
1543: }
1.9 deraadt 1544: } else if (pfd[0].revents) {
1545: if (pfd[0].revents & (POLLERR|POLLNVAL)) {
1546: BIO_printf(bio_err, "poll error");
1547: goto shut;
1548: }
1.47 inoguchi 1549: if (s_client_config.crlf) {
1.1 jsing 1550: int j, lf_num;
1551:
1552: i = read(fileno(stdin), cbuf, BUFSIZZ / 2);
1553: lf_num = 0;
1554: /* both loops are skipped when i <= 0 */
1555: for (j = 0; j < i; j++)
1556: if (cbuf[j] == '\n')
1557: lf_num++;
1558: for (j = i - 1; j >= 0; j--) {
1559: cbuf[j + lf_num] = cbuf[j];
1560: if (cbuf[j] == '\n') {
1561: lf_num--;
1562: i++;
1563: cbuf[j + lf_num] = '\r';
1564: }
1565: }
1566: assert(lf_num == 0);
1567: } else
1568: i = read(fileno(stdin), cbuf, BUFSIZZ);
1569:
1.49 inoguchi 1570: if ((!s_client_config.ign_eof) &&
1571: ((i <= 0) || (cbuf[0] == 'Q'))) {
1.1 jsing 1572: BIO_printf(bio_err, "DONE\n");
1573: ret = 0;
1574: goto shut;
1575: }
1.48 inoguchi 1576: if ((!s_client_config.ign_eof) && (cbuf[0] == 'R')) {
1.1 jsing 1577: BIO_printf(bio_err, "RENEGOTIATING\n");
1578: SSL_renegotiate(con);
1579: cbuf_len = 0;
1580: } else {
1581: cbuf_len = i;
1582: cbuf_off = 0;
1583: }
1584:
1585: write_ssl = 1;
1586: read_tty = 0;
1587: }
1588: }
1589:
1590: ret = 0;
1.35 jsing 1591: shut:
1.1 jsing 1592: if (in_init)
1593: print_stuff(bio_c_out, con, full_log);
1594: SSL_shutdown(con);
1595: shutdown(SSL_get_fd(con), SHUT_RD);
1596: close(SSL_get_fd(con));
1.35 jsing 1597: end:
1.1 jsing 1598: if (con != NULL) {
1.47 inoguchi 1599: if (s_client_config.prexit != 0)
1.1 jsing 1600: print_stuff(bio_c_out, con, 1);
1601: SSL_free(con);
1602: }
1.34 jsing 1603: SSL_CTX_free(ctx);
1604: X509_free(cert);
1605: EVP_PKEY_free(key);
1.1 jsing 1606: free(pass);
1.47 inoguchi 1607: X509_VERIFY_PARAM_free(s_client_config.vpm);
1.32 deraadt 1608: freezero(cbuf, BUFSIZZ);
1609: freezero(sbuf, BUFSIZZ);
1610: freezero(mbuf, BUFSIZZ);
1.50 inoguchi 1611: BIO_free(bio_c_out);
1.1 jsing 1612:
1613: return (ret);
1614: }
1615:
1616: static void
1.51 ! inoguchi 1617: print_stuff(BIO *bio, SSL *s, int full)
1.1 jsing 1618: {
1619: X509 *peer = NULL;
1620: char *p;
1621: static const char *space = " ";
1622: char buf[BUFSIZ];
1.51 ! inoguchi 1623: STACK_OF(X509) *sk;
! 1624: STACK_OF(X509_NAME) *sk2;
1.1 jsing 1625: const SSL_CIPHER *c;
1626: X509_NAME *xn;
1627: int j, i;
1628: unsigned char *exportedkeymat;
1629:
1630: if (full) {
1631: int got_a_chain = 0;
1632:
1633: sk = SSL_get_peer_cert_chain(s);
1634: if (sk != NULL) {
1635: got_a_chain = 1; /* we don't have it for SSL2
1636: * (yet) */
1637:
1638: BIO_printf(bio, "---\nCertificate chain\n");
1639: for (i = 0; i < sk_X509_num(sk); i++) {
1640: X509_NAME_oneline(X509_get_subject_name(
1641: sk_X509_value(sk, i)), buf, sizeof buf);
1642: BIO_printf(bio, "%2d s:%s\n", i, buf);
1643: X509_NAME_oneline(X509_get_issuer_name(
1644: sk_X509_value(sk, i)), buf, sizeof buf);
1645: BIO_printf(bio, " i:%s\n", buf);
1.48 inoguchi 1646: if (s_client_config.showcerts)
1.49 inoguchi 1647: PEM_write_bio_X509(bio,
1648: sk_X509_value(sk, i));
1.1 jsing 1649: }
1650: }
1651: BIO_printf(bio, "---\n");
1652: peer = SSL_get_peer_certificate(s);
1653: if (peer != NULL) {
1654: BIO_printf(bio, "Server certificate\n");
1.49 inoguchi 1655: if (!(s_client_config.showcerts && got_a_chain)) {
1656: /* Redundant if we showed the whole chain */
1.1 jsing 1657: PEM_write_bio_X509(bio, peer);
1.49 inoguchi 1658: }
1.1 jsing 1659: X509_NAME_oneline(X509_get_subject_name(peer),
1660: buf, sizeof buf);
1661: BIO_printf(bio, "subject=%s\n", buf);
1662: X509_NAME_oneline(X509_get_issuer_name(peer),
1663: buf, sizeof buf);
1664: BIO_printf(bio, "issuer=%s\n", buf);
1665: } else
1666: BIO_printf(bio, "no peer certificate available\n");
1667:
1668: sk2 = SSL_get_client_CA_list(s);
1669: if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
1.49 inoguchi 1670: BIO_printf(bio,
1671: "---\nAcceptable client certificate CA names\n");
1.1 jsing 1672: for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
1673: xn = sk_X509_NAME_value(sk2, i);
1674: X509_NAME_oneline(xn, buf, sizeof(buf));
1675: BIO_write(bio, buf, strlen(buf));
1676: BIO_write(bio, "\n", 1);
1677: }
1678: } else {
1.49 inoguchi 1679: BIO_printf(bio,
1680: "---\nNo client certificate CA names sent\n");
1.1 jsing 1681: }
1682: p = SSL_get_shared_ciphers(s, buf, sizeof buf);
1683: if (p != NULL) {
1684: /*
1685: * This works only for SSL 2. In later protocol
1686: * versions, the client does not know what other
1687: * ciphers (in addition to the one to be used in the
1688: * current connection) the server supports.
1689: */
1690:
1.49 inoguchi 1691: BIO_printf(bio,
1692: "---\nCiphers common between both SSL endpoints:\n");
1.1 jsing 1693: j = i = 0;
1694: while (*p) {
1695: if (*p == ':') {
1696: BIO_write(bio, space, 15 - j % 25);
1697: i++;
1698: j = 0;
1.49 inoguchi 1699: BIO_write(bio,
1700: ((i % 3) ? " " : "\n"), 1);
1.1 jsing 1701: } else {
1702: BIO_write(bio, p, 1);
1703: j++;
1704: }
1705: p++;
1706: }
1707: BIO_write(bio, "\n", 1);
1708: }
1.29 jsing 1709:
1710: ssl_print_tmp_key(bio, s);
1711:
1.49 inoguchi 1712: BIO_printf(bio,
1713: "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
1.1 jsing 1714: BIO_number_read(SSL_get_rbio(s)),
1715: BIO_number_written(SSL_get_wbio(s)));
1716: }
1717: BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
1718: c = SSL_get_current_cipher(s);
1719: BIO_printf(bio, "%s, Cipher is %s\n",
1720: SSL_CIPHER_get_version(c),
1721: SSL_CIPHER_get_name(c));
1722: if (peer != NULL) {
1723: EVP_PKEY *pktmp;
1724: pktmp = X509_get_pubkey(peer);
1725: BIO_printf(bio, "Server public key is %d bit\n",
1726: EVP_PKEY_bits(pktmp));
1727: EVP_PKEY_free(pktmp);
1728: }
1729: BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
1730: SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
1731:
1732: /* Compression is not supported and will always be none. */
1733: BIO_printf(bio, "Compression: NONE\n");
1734: BIO_printf(bio, "Expansion: NONE\n");
1735:
1736: #ifdef SSL_DEBUG
1737: {
1738: /* Print out local port of connection: useful for debugging */
1739: int sock;
1740: struct sockaddr_in ladd;
1741: socklen_t ladd_size = sizeof(ladd);
1742: sock = SSL_get_fd(s);
1743: getsockname(sock, (struct sockaddr *) & ladd, &ladd_size);
1.50 inoguchi 1744: BIO_printf(bio, "LOCAL PORT is %u\n",
1.49 inoguchi 1745: ntohs(ladd.sin_port));
1.1 jsing 1746: }
1747: #endif
1748:
1.10 jsing 1749: {
1750: const unsigned char *proto;
1751: unsigned int proto_len;
1752: SSL_get0_alpn_selected(s, &proto, &proto_len);
1753: if (proto_len > 0) {
1754: BIO_printf(bio, "ALPN protocol: ");
1755: BIO_write(bio, proto, proto_len);
1756: BIO_write(bio, "\n", 1);
1757: } else
1758: BIO_printf(bio, "No ALPN negotiated\n");
1759: }
1.1 jsing 1760:
1761: #ifndef OPENSSL_NO_SRTP
1762: {
1.49 inoguchi 1763: SRTP_PROTECTION_PROFILE *srtp_profile;
1.1 jsing 1764:
1.49 inoguchi 1765: srtp_profile = SSL_get_selected_srtp_profile(s);
1.1 jsing 1766: if (srtp_profile)
1.49 inoguchi 1767: BIO_printf(bio,
1768: "SRTP Extension negotiated, profile=%s\n",
1.1 jsing 1769: srtp_profile->name);
1770: }
1771: #endif
1772:
1773: SSL_SESSION_print(bio, SSL_get_session(s));
1.47 inoguchi 1774: if (s_client_config.keymatexportlabel != NULL) {
1.1 jsing 1775: BIO_printf(bio, "Keying material exporter:\n");
1.49 inoguchi 1776: BIO_printf(bio, " Label: '%s'\n",
1777: s_client_config.keymatexportlabel);
1778: BIO_printf(bio, " Length: %i bytes\n",
1779: s_client_config.keymatexportlen);
1.47 inoguchi 1780: exportedkeymat = malloc(s_client_config.keymatexportlen);
1.1 jsing 1781: if (exportedkeymat != NULL) {
1782: if (!SSL_export_keying_material(s, exportedkeymat,
1.47 inoguchi 1783: s_client_config.keymatexportlen,
1784: s_client_config.keymatexportlabel,
1785: strlen(s_client_config.keymatexportlabel),
1.1 jsing 1786: NULL, 0, 0)) {
1787: BIO_printf(bio, " Error\n");
1788: } else {
1789: BIO_printf(bio, " Keying material: ");
1.47 inoguchi 1790: for (i = 0; i < s_client_config.keymatexportlen; i++)
1.1 jsing 1791: BIO_printf(bio, "%02X",
1792: exportedkeymat[i]);
1793: BIO_printf(bio, "\n");
1794: }
1795: free(exportedkeymat);
1796: }
1797: }
1798: BIO_printf(bio, "---\n");
1.34 jsing 1799: X509_free(peer);
1.1 jsing 1800: /* flush, or debugging output gets mixed with http response */
1801: (void) BIO_flush(bio);
1802: }
1803:
1804: static int
1.51 ! inoguchi 1805: ocsp_resp_cb(SSL *s, void *arg)
1.1 jsing 1806: {
1807: const unsigned char *p;
1808: int len;
1809: OCSP_RESPONSE *rsp;
1810: len = SSL_get_tlsext_status_ocsp_resp(s, &p);
1811: BIO_puts(arg, "OCSP response: ");
1812: if (!p) {
1813: BIO_puts(arg, "no response sent\n");
1814: return 1;
1815: }
1816: rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
1817: if (!rsp) {
1818: BIO_puts(arg, "response parse error\n");
1819: BIO_dump_indent(arg, (char *) p, len, 4);
1820: return 0;
1821: }
1822: BIO_puts(arg, "\n======================================\n");
1823: OCSP_RESPONSE_print(arg, rsp, 0);
1824: BIO_puts(arg, "======================================\n");
1825: OCSP_RESPONSE_free(rsp);
1826: return 1;
1.51 ! inoguchi 1827: }
! 1828:
! 1829: static int
! 1830: ssl_servername_cb(SSL *s, int *ad, void *arg)
! 1831: {
! 1832: tlsextctx *p = (tlsextctx *) arg;
! 1833: const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
! 1834: if (SSL_get_servername_type(s) != -1)
! 1835: p->ack = !SSL_session_reused(s) && hn != NULL;
! 1836: else
! 1837: BIO_printf(bio_err, "Can't use SSL_get_servername\n");
! 1838:
! 1839: return SSL_TLSEXT_ERR_OK;
1.1 jsing 1840: }
1841: