xref: /netbsd-src/external/ibm-public/postfix/dist/src/tls/tls_misc.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: tls_misc.c,v 1.1.1.8 2014/01/18 17:04:20 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	tls_misc 3
6 /* SUMMARY
7 /*	miscellaneous TLS support routines
8 /* SYNOPSIS
9 /*	#define TLS_INTERNAL
10 /*	#include <tls.h>
11 /*
12 /*	char	*var_tls_high_clist;
13 /*	char	*var_tls_medium_clist;
14 /*	char	*var_tls_low_clist;
15 /*	char	*var_tls_export_clist;
16 /*	char	*var_tls_null_clist;
17 /*	char	*var_tls_eecdh_strong;
18 /*	char	*var_tls_eecdh_ultra;
19 /*	int	var_tls_daemon_rand_bytes;
20 /*	bool    var_tls_append_def_CA;
21 /*	bool	var_tls_preempt_clist;
22 /*	bool	var_tls_bc_pkey_fprint;
23 /*
24 /*	TLS_APPL_STATE *tls_alloc_app_context(ssl_ctx, log_mask)
25 /*	SSL_CTX	*ssl_ctx;
26 /*	int	log_mask;
27 /*
28 /*	void	tls_free_app_context(app_ctx)
29 /*	void	*app_ctx;
30 /*
31 /*	TLS_SESS_STATE *tls_alloc_sess_context(log_mask, namaddr)
32 /*	int	log_mask;
33 /*	const char *namaddr;
34 /*
35 /*	void	tls_free_context(TLScontext)
36 /*	TLS_SESS_STATE *TLScontext;
37 /*
38 /*	void	tls_check_version()
39 /*
40 /*	long	tls_bug_bits()
41 /*
42 /*	void	tls_param_init()
43 /*
44 /*	int	tls_protocol_mask(plist)
45 /*	const char *plist;
46 /*
47 /*	int	tls_cipher_grade(name)
48 /*	const char *name;
49 /*
50 /*	const char *str_tls_cipher_grade(grade)
51 /*	int	grade;
52 /*
53 /*	const char *tls_set_ciphers(app_ctx, context, grade, exclusions)
54 /*	TLS_APPL_STATE *app_ctx;
55 /*	const char *context;
56 /*	int	grade;
57 /*	const char *exclusions;
58 /*
59 /*	void	tls_print_errors()
60 /*
61 /*	void	tls_info_callback(ssl, where, ret)
62 /*	const SSL *ssl; /* unused */
63 /*	int	where;
64 /*	int	ret;
65 /*
66 /*	long	tls_bio_dump_cb(bio, cmd, argp, argi, argl, ret)
67 /*	BIO	*bio;
68 /*	int	cmd;
69 /*	const char *argp;
70 /*	int	argi;
71 /*	long	argl; /* unused */
72 /*	long	ret;
73 /*
74 /*	int	tls_log_mask(log_param, log_level)
75 /*	const char *log_param;
76 /*	const char *log_level;
77 /* DESCRIPTION
78 /*	This module implements routines that support the TLS client
79 /*	and server internals.
80 /*
81 /*	tls_alloc_app_context() creates an application context that
82 /*	holds the SSL context for the application and related cached state.
83 /*
84 /*	tls_free_app_context() deallocates the application context and its
85 /*	contents (the application context is stored outside the TLS library).
86 /*
87 /*	tls_alloc_sess_context() creates an initialized TLS session context
88 /*	structure with the specified log mask and peer name[addr].
89 /*
90 /*	tls_free_context() destroys a TLScontext structure
91 /*	together with OpenSSL structures that are attached to it.
92 /*
93 /*	tls_check_version() logs a warning when the run-time OpenSSL
94 /*	library differs in its major, minor or micro number from
95 /*	the compile-time OpenSSL headers.
96 /*
97 /*	tls_bug_bits() returns the bug compatibility mask appropriate
98 /*	for the run-time library. Some of the bug work-arounds are
99 /*	not appropriate for some library versions.
100 /*
101 /*	tls_param_init() loads main.cf parameters used internally in
102 /*	TLS library. Any errors are fatal.
103 /*
104 /*	tls_protocol_mask() returns a bitmask of excluded protocols, given
105 /*	a list (plist) of protocols to include or (preceded by a '!') exclude.
106 /*	If "plist" contains invalid protocol names, TLS_PROTOCOL_INVALID is
107 /*	returned and no warning is logged.
108 /*
109 /*	tls_cipher_grade() converts a case-insensitive cipher grade
110 /*	name (high, medium, low, export, null) to the corresponding
111 /*	TLS_CIPHER_ constant.  When the input specifies an unrecognized
112 /*	grade, tls_cipher_grade() logs no warning, and returns
113 /*	TLS_CIPHER_NONE.
114 /*
115 /*	str_tls_cipher_grade() converts a cipher grade to a name.
116 /*	When the input specifies an undefined grade, str_tls_cipher_grade()
117 /*	logs no warning, returns a null pointer.
118 /*
119 /*	tls_set_ciphers() generates a cipher list from the specified
120 /*	grade, minus any ciphers specified via a list of exclusions.
121 /*	The cipherlist is applied to the supplied SSL context if it
122 /*	is different from the most recently applied value. The return
123 /*	value is the cipherlist used and is overwritten upon each call.
124 /*	When the input is invalid, tls_set_ciphers() logs a warning with
125 /*	the specified context, and returns a null pointer result.
126 /*
127 /*	tls_print_errors() queries the OpenSSL error stack,
128 /*	logs the error messages, and clears the error stack.
129 /*
130 /*	tls_info_callback() is a call-back routine for the
131 /*	SSL_CTX_set_info_callback() routine. It logs SSL events
132 /*	to the Postfix logfile.
133 /*
134 /*	tls_bio_dump_cb() is a call-back routine for the
135 /*	BIO_set_callback() routine. It logs SSL content to the
136 /*	Postfix logfile.
137 /*
138 /*	tls_log_mask() converts a TLS log_level value from string
139 /*	to mask.  The main.cf parameter name is passed along for
140 /*	diagnostics.
141 /* LICENSE
142 /* .ad
143 /* .fi
144 /*	This software is free. You can do with it whatever you want.
145 /*	The original author kindly requests that you acknowledge
146 /*	the use of his software.
147 /* AUTHOR(S)
148 /*	Originally written by:
149 /*	Lutz Jaenicke
150 /*	BTU Cottbus
151 /*	Allgemeine Elektrotechnik
152 /*	Universitaetsplatz 3-4
153 /*	D-03044 Cottbus, Germany
154 /*
155 /*	Updated by:
156 /*	Wietse Venema
157 /*	IBM T.J. Watson Research
158 /*	P.O. Box 704
159 /*	Yorktown Heights, NY 10598, USA
160 /*
161 /*	Victor Duchovni
162 /*	Morgan Stanley
163 /*--*/
164 
165 /* System library. */
166 
167 #include <sys_defs.h>
168 #include <ctype.h>
169 #include <string.h>
170 
171 #ifdef USE_TLS
172 
173 /* Utility library. */
174 
175 #include <vstream.h>
176 #include <msg.h>
177 #include <mymalloc.h>
178 #include <vstring.h>
179 #include <stringops.h>
180 #include <argv.h>
181 #include <name_mask.h>
182 #include <name_code.h>
183 
184  /*
185   * Global library.
186   */
187 #include <mail_params.h>
188 #include <mail_conf.h>
189 
190  /*
191   * TLS library.
192   */
193 #define TLS_INTERNAL
194 #include <tls.h>
195 
196  /* Application-specific. */
197 
198  /*
199   * Tunable parameters.
200   */
201 char   *var_tls_high_clist;
202 char   *var_tls_medium_clist;
203 char   *var_tls_low_clist;
204 char   *var_tls_export_clist;
205 char   *var_tls_null_clist;
206 int     var_tls_daemon_rand_bytes;
207 char   *var_tls_eecdh_strong;
208 char   *var_tls_eecdh_ultra;
209 bool    var_tls_append_def_CA;
210 char   *var_tls_bug_tweaks;
211 bool    var_tls_bc_pkey_fprint;
212 
213 #ifdef VAR_TLS_PREEMPT_CLIST
214 bool    var_tls_preempt_clist;
215 
216 #endif
217 
218  /*
219   * Index to attach TLScontext pointers to SSL objects, so that they can be
220   * accessed by call-back routines.
221   */
222 int     TLScontext_index = -1;
223 
224  /*
225   * Protocol name <=> mask conversion.
226   */
227 static const NAME_CODE protocol_table[] = {
228     SSL_TXT_SSLV2, TLS_PROTOCOL_SSLv2,
229     SSL_TXT_SSLV3, TLS_PROTOCOL_SSLv3,
230     SSL_TXT_TLSV1, TLS_PROTOCOL_TLSv1,
231 #ifdef SSL_TXT_TLSV1_1
232     SSL_TXT_TLSV1_1, TLS_PROTOCOL_TLSv1_1,
233 #endif
234 #ifdef SSL_TXT_TLSV1_2
235     SSL_TXT_TLSV1_2, TLS_PROTOCOL_TLSv1_2,
236 #endif
237     0, TLS_PROTOCOL_INVALID,
238 };
239 
240  /*
241   * SSL_OP_MUMBLE bug work-around name <=> mask conversion.
242   */
243 #define NAMEBUG(x)	#x, SSL_OP_##x
244 static const LONG_NAME_MASK ssl_bug_tweaks[] = {
245 
246 #ifndef SSL_OP_MICROSOFT_SESS_ID_BUG
247 #define SSL_OP_MICROSOFT_SESS_ID_BUG		0
248 #endif
249     NAMEBUG(MICROSOFT_SESS_ID_BUG),
250 
251 #ifndef SSL_OP_NETSCAPE_CHALLENGE_BUG
252 #define SSL_OP_NETSCAPE_CHALLENGE_BUG		0
253 #endif
254     NAMEBUG(NETSCAPE_CHALLENGE_BUG),
255 
256 #ifndef SSL_OP_LEGACY_SERVER_CONNECT
257 #define SSL_OP_LEGACY_SERVER_CONNECT		0
258 #endif
259     NAMEBUG(LEGACY_SERVER_CONNECT),
260 
261 #ifndef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
262 #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0
263 #endif
264     NAMEBUG(NETSCAPE_REUSE_CIPHER_CHANGE_BUG),
265     "CVE-2010-4180", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG,
266 
267 #ifndef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
268 #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG	0
269 #endif
270     NAMEBUG(SSLREF2_REUSE_CERT_TYPE_BUG),
271 
272 #ifndef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
273 #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER	0
274 #endif
275     NAMEBUG(MICROSOFT_BIG_SSLV3_BUFFER),
276 
277 #ifndef SSL_OP_MSIE_SSLV2_RSA_PADDING
278 #define SSL_OP_MSIE_SSLV2_RSA_PADDING		0
279 #endif
280     NAMEBUG(MSIE_SSLV2_RSA_PADDING),
281     "CVE-2005-2969", SSL_OP_MSIE_SSLV2_RSA_PADDING,
282 
283 #ifndef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
284 #define SSL_OP_SSLEAY_080_CLIENT_DH_BUG		0
285 #endif
286     NAMEBUG(SSLEAY_080_CLIENT_DH_BUG),
287 
288 #ifndef SSL_OP_TLS_D5_BUG
289 #define SSL_OP_TLS_D5_BUG			0
290 #endif
291     NAMEBUG(TLS_D5_BUG),
292 
293 #ifndef SSL_OP_TLS_BLOCK_PADDING_BUG
294 #define SSL_OP_TLS_BLOCK_PADDING_BUG		0
295 #endif
296     NAMEBUG(TLS_BLOCK_PADDING_BUG),
297 
298 #ifndef SSL_OP_TLS_ROLLBACK_BUG
299 #define SSL_OP_TLS_ROLLBACK_BUG			0
300 #endif
301     NAMEBUG(TLS_ROLLBACK_BUG),
302 
303 #ifndef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
304 #define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS	0
305 #endif
306     NAMEBUG(DONT_INSERT_EMPTY_FRAGMENTS),
307 
308 #ifndef SSL_OP_CRYPTOPRO_TLSEXT_BUG
309 #define SSL_OP_CRYPTOPRO_TLSEXT_BUG		0
310 #endif
311     NAMEBUG(CRYPTOPRO_TLSEXT_BUG),
312     0, 0,
313 };
314 
315  /*
316   * Ciphersuite name <=> code conversion.
317   */
318 const NAME_CODE tls_cipher_grade_table[] = {
319     "high", TLS_CIPHER_HIGH,
320     "medium", TLS_CIPHER_MEDIUM,
321     "low", TLS_CIPHER_LOW,
322     "export", TLS_CIPHER_EXPORT,
323     "null", TLS_CIPHER_NULL,
324     "invalid", TLS_CIPHER_NONE,
325     0, TLS_CIPHER_NONE,
326 };
327 
328  /*
329   * Log keyword <=> mask conversion.
330   */
331 #define TLS_LOG_0 TLS_LOG_NONE
332 #define TLS_LOG_1 TLS_LOG_SUMMARY
333 #define TLS_LOG_2 (TLS_LOG_1 | TLS_LOG_VERBOSE | TLS_LOG_CACHE | TLS_LOG_DEBUG)
334 #define TLS_LOG_3 (TLS_LOG_2 | TLS_LOG_TLSPKTS)
335 #define TLS_LOG_4 (TLS_LOG_3 | TLS_LOG_ALLPKTS)
336 
337 static const NAME_MASK tls_log_table[] = {
338     "0", TLS_LOG_0,
339     "none", TLS_LOG_NONE,
340     "1", TLS_LOG_1,
341     "routine", TLS_LOG_1,
342     "2", TLS_LOG_2,
343     "debug", TLS_LOG_2,
344     "3", TLS_LOG_3,
345     "ssl-expert", TLS_LOG_3,
346     "4", TLS_LOG_4,
347     "ssl-developer", TLS_LOG_4,
348     "5", TLS_LOG_4,			/* for good measure */
349     "6", TLS_LOG_4,			/* for good measure */
350     "7", TLS_LOG_4,			/* for good measure */
351     "8", TLS_LOG_4,			/* for good measure */
352     "9", TLS_LOG_4,			/* for good measure */
353     "summary", TLS_LOG_SUMMARY,
354     "untrusted", TLS_LOG_UNTRUSTED,
355     "peercert", TLS_LOG_PEERCERT,
356     "certmatch", TLS_LOG_CERTMATCH,
357     "verbose", TLS_LOG_VERBOSE,		/* Postfix TLS library verbose */
358     "cache", TLS_LOG_CACHE,
359     "ssl-debug", TLS_LOG_DEBUG,		/* SSL library debug/verbose */
360     "ssl-handshake-packet-dump", TLS_LOG_TLSPKTS,
361     "ssl-session-packet-dump", TLS_LOG_TLSPKTS | TLS_LOG_ALLPKTS,
362     0, 0,
363 };
364 
365  /*
366   * Parsed OpenSSL version number.
367   */
368 typedef struct {
369     int     major;
370     int     minor;
371     int     micro;
372     int     patch;
373     int     status;
374 } TLS_VINFO;
375 
376  /*
377   * OpenSSL adopted the cipher selection patch, so we don't expect any more
378   * broken ciphers other than AES and CAMELLIA.
379   */
380 typedef struct {
381     const char *ssl_name;
382     const int alg_bits;
383     const char *evp_name;
384 } cipher_probe_t;
385 
386 static const cipher_probe_t cipher_probes[] = {
387     "AES", 256, "AES-256-CBC",
388     "CAMELLIA", 256, "CAMELLIA-256-CBC",
389     0, 0, 0,
390 };
391 
392 /* tls_log_mask - Convert user TLS loglevel to internal log feature mask */
393 
394 int     tls_log_mask(const char *log_param, const char *log_level)
395 {
396     int     mask;
397 
398     mask = name_mask_opt(log_param, tls_log_table, log_level,
399 			 NAME_MASK_ANY_CASE | NAME_MASK_RETURN);
400     return (mask);
401 }
402 
403 /* tls_exclude_missing - Append exclusions for missing ciphers */
404 
405 static const char *tls_exclude_missing(SSL_CTX *ctx, VSTRING *buf)
406 {
407     const char *myname = "tls_exclude_missing";
408     static ARGV *exclude;		/* Cached */
409     SSL    *s = 0;
410 
411     STACK_OF(SSL_CIPHER) * ciphers;
412     SSL_CIPHER *c;
413     const cipher_probe_t *probe;
414     int     alg_bits;
415     int     num;
416     int     i;
417 
418     /*
419      * Process a list of probes which specify:
420      *
421      * An SSL cipher-suite name for a family of ciphers that use the same
422      * symmetric algorithm at two or more key sizes, typically 128/256 bits.
423      *
424      * The key size (typically 256) that OpenSSL fails to check, and assumes
425      * available when another key size (typically 128) is usable.
426      *
427      * The OpenSSL name of the symmetric algorithm associated with the SSL
428      * cipher-suite. Typically, this is MUMBLE-256-CBC, where "MUMBLE" is the
429      * name of the SSL cipher-suite that use the MUMBLE symmetric algorithm.
430      * On systems that support the required encryption algorithm, the name is
431      * listed in the output of "openssl list-cipher-algorithms".
432      *
433      * When an encryption algorithm is not available at the given key size but
434      * the corresponding OpenSSL cipher-suite contains ciphers that have have
435      * this key size, the problem ciphers are explicitly disabled in Postfix.
436      * The list is cached in the static "exclude" array.
437      */
438     if (exclude == 0) {
439 	exclude = argv_alloc(1);
440 
441 	/*
442 	 * Iterate over the probe list
443 	 */
444 	for (probe = cipher_probes; probe->ssl_name; ++probe) {
445 	    /* No exclusions if evp_name is a valid algorithm */
446 	    if (EVP_get_cipherbyname(probe->evp_name))
447 		continue;
448 
449 	    /*
450 	     * Sadly there is no SSL_CTX_get_ciphers() interface, so we are
451 	     * forced to allocate and free an SSL object. Fatal error if we
452 	     * can't allocate the SSL object.
453 	     */
454 	    ERR_clear_error();
455 	    if (s == 0 && (s = SSL_new(ctx)) == 0) {
456 		tls_print_errors();
457 		msg_fatal("%s: error allocating SSL object", myname);
458 	    }
459 
460 	    /*
461 	     * Cipher is not supported by libcrypto, nothing to do if also
462 	     * not supported by libssl. Flush the OpenSSL error stack.
463 	     *
464 	     * XXX: There may be additional places in pre-existing code where
465 	     * SSL errors are generated and ignored, that require a similar
466 	     * "flush". Better yet, is to always flush before calls that run
467 	     * tls_print_errors() on failure.
468 	     *
469 	     * Contrary to documentation, on SunOS 5.10 SSL_set_cipher_list()
470 	     * returns success with no ciphers selected, when this happens
471 	     * SSL_get_ciphers() produces a stack with 0 elements!
472 	     */
473 	    if (SSL_set_cipher_list(s, probe->ssl_name) == 0
474 		|| (ciphers = SSL_get_ciphers(s)) == 0
475 		|| (num = sk_SSL_CIPHER_num(ciphers)) == 0) {
476 		ERR_clear_error();		/* flush any generated errors */
477 		continue;
478 	    }
479 	    for (i = 0; i < num; ++i) {
480 		c = sk_SSL_CIPHER_value(ciphers, i);
481 		(void) SSL_CIPHER_get_bits(c, &alg_bits);
482 		if (alg_bits == probe->alg_bits)
483 		    argv_add(exclude, SSL_CIPHER_get_name(c), ARGV_END);
484 	    }
485 	}
486 	if (s != 0)
487 	    SSL_free(s);
488     }
489     for (i = 0; i < exclude->argc; ++i)
490 	vstring_sprintf_append(buf, ":!%s", exclude->argv[i]);
491     return (vstring_str(buf));
492 }
493 
494 /* tls_apply_cipher_list - update SSL_CTX cipher list */
495 
496 static const char *tls_apply_cipher_list(TLS_APPL_STATE *app_ctx,
497 				         const char *context, VSTRING *spec)
498 {
499     const char *new = tls_exclude_missing(app_ctx->ssl_ctx, spec);
500 
501     ERR_clear_error();
502     if (SSL_CTX_set_cipher_list(app_ctx->ssl_ctx, new) == 0) {
503 	tls_print_errors();
504 	vstring_sprintf(app_ctx->why, "invalid %s cipher list: \"%s\"",
505 			context, new);
506 	return (0);
507     }
508     return (new);
509 }
510 
511 /* tls_protocol_mask - Bitmask of protocols to exclude */
512 
513 int     tls_protocol_mask(const char *plist)
514 {
515     char   *save;
516     char   *tok;
517     char   *cp;
518     int     code;
519     int     exclude = 0;
520     int     include = 0;
521 
522 #define FREE_AND_RETURN(ptr, res) do { \
523 	myfree(ptr); \
524 	return (res); \
525     } while (0)
526 
527     save = cp = mystrdup(plist);
528     while ((tok = mystrtok(&cp, "\t\n\r ,:")) != 0) {
529 	if (*tok == '!')
530 	    exclude |= code =
531 		name_code(protocol_table, NAME_CODE_FLAG_NONE, ++tok);
532 	else
533 	    include |= code =
534 		name_code(protocol_table, NAME_CODE_FLAG_NONE, tok);
535 	if (code == TLS_PROTOCOL_INVALID)
536 	    FREE_AND_RETURN(save, TLS_PROTOCOL_INVALID);
537     }
538 
539     /*
540      * When the include list is empty, use only the explicit exclusions.
541      * Otherwise, also exclude the complement of the include list from the
542      * built-in list of known protocols. There is no way to exclude protocols
543      * we don't know about at compile time, and this is unavoidable because
544      * the OpenSSL API works with compile-time *exclusion* bit-masks.
545      */
546     FREE_AND_RETURN(save,
547 	(include ? (exclude | (TLS_KNOWN_PROTOCOLS & ~include)) : exclude));
548 }
549 
550 /* tls_param_init - Load TLS related config parameters */
551 
552 void    tls_param_init(void)
553 {
554     static const CONFIG_STR_TABLE str_table[] = {
555 	VAR_TLS_HIGH_CLIST, DEF_TLS_HIGH_CLIST, &var_tls_high_clist, 1, 0,
556 	VAR_TLS_MEDIUM_CLIST, DEF_TLS_MEDIUM_CLIST, &var_tls_medium_clist, 1, 0,
557 	VAR_TLS_LOW_CLIST, DEF_TLS_LOW_CLIST, &var_tls_low_clist, 1, 0,
558 	VAR_TLS_EXPORT_CLIST, DEF_TLS_EXPORT_CLIST, &var_tls_export_clist, 1, 0,
559 	VAR_TLS_NULL_CLIST, DEF_TLS_NULL_CLIST, &var_tls_null_clist, 1, 0,
560 	VAR_TLS_EECDH_STRONG, DEF_TLS_EECDH_STRONG, &var_tls_eecdh_strong, 1, 0,
561 	VAR_TLS_EECDH_ULTRA, DEF_TLS_EECDH_ULTRA, &var_tls_eecdh_ultra, 1, 0,
562 	VAR_TLS_BUG_TWEAKS, DEF_TLS_BUG_TWEAKS, &var_tls_bug_tweaks, 0, 0,
563 	0,
564     };
565     static const CONFIG_INT_TABLE int_table[] = {
566 	VAR_TLS_DAEMON_RAND_BYTES, DEF_TLS_DAEMON_RAND_BYTES, &var_tls_daemon_rand_bytes, 1, 0,
567 	0,
568     };
569     static const CONFIG_BOOL_TABLE bool_table[] = {
570 	VAR_TLS_APPEND_DEF_CA, DEF_TLS_APPEND_DEF_CA, &var_tls_append_def_CA,
571 	VAR_TLS_BC_PKEY_FPRINT, DEF_TLS_BC_PKEY_FPRINT, &var_tls_bc_pkey_fprint,
572 #if OPENSSL_VERSION_NUMBER >= 0x0090700fL	/* OpenSSL 0.9.7 and later */
573 	VAR_TLS_PREEMPT_CLIST, DEF_TLS_PREEMPT_CLIST, &var_tls_preempt_clist,
574 #endif
575 	0,
576     };
577     static int init_done;
578 
579     if (init_done)
580 	return;
581     init_done = 1;
582 
583     get_mail_conf_str_table(str_table);
584     get_mail_conf_int_table(int_table);
585     get_mail_conf_bool_table(bool_table);
586 }
587 
588 /* tls_set_ciphers - Set SSL context cipher list */
589 
590 const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context,
591 			          const char *grade, const char *exclusions)
592 {
593     const char *myname = "tls_set_ciphers";
594     static VSTRING *buf;
595     int     new_grade;
596     char   *save;
597     char   *cp;
598     char   *tok;
599     const char *new_list;
600 
601     new_grade = tls_cipher_grade(grade);
602     if (new_grade == TLS_CIPHER_NONE) {
603 	vstring_sprintf(app_ctx->why, "invalid %s cipher grade: \"%s\"",
604 			context, grade);
605 	return (0);
606     }
607     if (buf == 0)
608 	buf = vstring_alloc(10);
609     VSTRING_RESET(buf);
610 
611     /*
612      * Given cached state and identical input, we return the same result.
613      */
614     if (app_ctx->cipher_list) {
615 	if (new_grade == app_ctx->cipher_grade
616 	    && strcmp(app_ctx->cipher_exclusions, exclusions) == 0)
617 	    return (app_ctx->cipher_list);
618 
619 	/* Change required, flush cached state */
620 	app_ctx->cipher_grade = TLS_CIPHER_NONE;
621 
622 	myfree(app_ctx->cipher_exclusions);
623 	app_ctx->cipher_exclusions = 0;
624 
625 	myfree(app_ctx->cipher_list);
626 	app_ctx->cipher_list = 0;
627     }
628     switch (new_grade) {
629     case TLS_CIPHER_HIGH:
630 	vstring_strcpy(buf, var_tls_high_clist);
631 	break;
632     case TLS_CIPHER_MEDIUM:
633 	vstring_strcpy(buf, var_tls_medium_clist);
634 	break;
635     case TLS_CIPHER_LOW:
636 	vstring_strcpy(buf, var_tls_low_clist);
637 	break;
638     case TLS_CIPHER_EXPORT:
639 	vstring_strcpy(buf, var_tls_export_clist);
640 	break;
641     case TLS_CIPHER_NULL:
642 	vstring_strcpy(buf, var_tls_null_clist);
643 	break;
644     default:
645 
646 	/*
647 	 * The caller MUST provide a valid cipher grade
648 	 */
649 	msg_panic("invalid %s cipher grade: %d", context, new_grade);
650     }
651 
652     /*
653      * The base lists for each grade can't be empty.
654      */
655     if (VSTRING_LEN(buf) == 0)
656 	msg_panic("%s: empty \"%s\" cipherlist", myname, grade);
657 
658     /*
659      * Apply locally-specified exclusions.
660      */
661 #define CIPHER_SEP "\t\n\r ,:"
662     if (exclusions != 0) {
663 	cp = save = mystrdup(exclusions);
664 	while ((tok = mystrtok(&cp, CIPHER_SEP)) != 0) {
665 
666 	    /*
667 	     * Can't exclude ciphers that start with modifiers.
668 	     */
669 	    if (strchr("!+-@", *tok)) {
670 		vstring_sprintf(app_ctx->why,
671 				"invalid unary '!+-@' in %s cipher "
672 				"exclusion: \"%s\"", context, tok);
673 		return (0);
674 	    }
675 	    vstring_sprintf_append(buf, ":!%s", tok);
676 	}
677 	myfree(save);
678     }
679     if ((new_list = tls_apply_cipher_list(app_ctx, context, buf)) == 0)
680 	return (0);
681 
682     /* Cache new state */
683     app_ctx->cipher_grade = new_grade;
684     app_ctx->cipher_exclusions = mystrdup(exclusions);
685 
686     return (app_ctx->cipher_list = mystrdup(new_list));
687 }
688 
689 /* tls_alloc_app_context - allocate TLS application context */
690 
691 TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *ssl_ctx, int log_mask)
692 {
693     TLS_APPL_STATE *app_ctx;
694 
695     app_ctx = (TLS_APPL_STATE *) mymalloc(sizeof(*app_ctx));
696 
697     /* See portability note below with other memset() call. */
698     memset((char *) app_ctx, 0, sizeof(*app_ctx));
699     app_ctx->ssl_ctx = ssl_ctx;
700     app_ctx->log_mask = log_mask;
701 
702     /* See also: cache purging code in tls_set_ciphers(). */
703     app_ctx->cipher_grade = TLS_CIPHER_NONE;
704     app_ctx->cipher_exclusions = 0;
705     app_ctx->cipher_list = 0;
706     app_ctx->cache_type = 0;
707     app_ctx->why = vstring_alloc(1);
708 
709     return (app_ctx);
710 }
711 
712 /* tls_free_app_context - Free TLS application context */
713 
714 void    tls_free_app_context(TLS_APPL_STATE *app_ctx)
715 {
716     if (app_ctx->ssl_ctx)
717 	SSL_CTX_free(app_ctx->ssl_ctx);
718     if (app_ctx->cache_type)
719 	myfree(app_ctx->cache_type);
720     /* See also: cache purging code in tls_set_ciphers(). */
721     if (app_ctx->cipher_exclusions)
722 	myfree(app_ctx->cipher_exclusions);
723     if (app_ctx->cipher_list)
724 	myfree(app_ctx->cipher_list);
725     if (app_ctx->why)
726 	vstring_free(app_ctx->why);
727     myfree((char *) app_ctx);
728 }
729 
730 /* tls_alloc_sess_context - allocate TLS session context */
731 
732 TLS_SESS_STATE *tls_alloc_sess_context(int log_mask, const char *namaddr)
733 {
734     TLS_SESS_STATE *TLScontext;
735 
736     /*
737      * PORTABILITY: Do not assume that null pointers are all-zero bits. Use
738      * explicit assignments to initialize pointers.
739      *
740      * See the C language FAQ item 5.17, or if you have time to burn,
741      * http://www.google.com/search?q=zero+bit+null+pointer
742      *
743      * However, it's OK to use memset() to zero integer values.
744      */
745     TLScontext = (TLS_SESS_STATE *) mymalloc(sizeof(TLS_SESS_STATE));
746     memset((char *) TLScontext, 0, sizeof(*TLScontext));
747     TLScontext->con = 0;
748     TLScontext->cache_type = 0;
749     TLScontext->serverid = 0;
750     TLScontext->peer_CN = 0;
751     TLScontext->issuer_CN = 0;
752     TLScontext->peer_fingerprint = 0;
753     TLScontext->peer_pkey_fprint = 0;
754     TLScontext->protocol = 0;
755     TLScontext->cipher_name = 0;
756     TLScontext->log_mask = log_mask;
757     TLScontext->namaddr = lowercase(mystrdup(namaddr));
758     TLScontext->fpt_dgst = 0;
759 
760     return (TLScontext);
761 }
762 
763 /* tls_free_context - deallocate TLScontext and members */
764 
765 void    tls_free_context(TLS_SESS_STATE *TLScontext)
766 {
767 
768     /*
769      * Free the SSL structure and the BIOs. Warning: the internal_bio is
770      * connected to the SSL structure and is automatically freed with it. Do
771      * not free it again (core dump)!! Only free the network_bio.
772      */
773     if (TLScontext->con != 0)
774 	SSL_free(TLScontext->con);
775 
776     if (TLScontext->namaddr)
777 	myfree(TLScontext->namaddr);
778     if (TLScontext->serverid)
779 	myfree(TLScontext->serverid);
780 
781     if (TLScontext->peer_CN)
782 	myfree(TLScontext->peer_CN);
783     if (TLScontext->issuer_CN)
784 	myfree(TLScontext->issuer_CN);
785     if (TLScontext->peer_fingerprint)
786 	myfree(TLScontext->peer_fingerprint);
787     if (TLScontext->peer_pkey_fprint)
788 	myfree(TLScontext->peer_pkey_fprint);
789     if (TLScontext->fpt_dgst)
790 	myfree(TLScontext->fpt_dgst);
791 
792     myfree((char *) TLScontext);
793 }
794 
795 /* tls_version_split - Split OpenSSL version number into major, minor, ... */
796 
797 static void tls_version_split(long version, TLS_VINFO *info)
798 {
799 
800     /*
801      * OPENSSL_VERSION_NUMBER(3):
802      *
803      * OPENSSL_VERSION_NUMBER is a numeric release version identifier:
804      *
805      * MMNNFFPPS: major minor fix patch status
806      *
807      * The status nibble has one of the values 0 for development, 1 to e for
808      * betas 1 to 14, and f for release. Parsed OpenSSL version number. for
809      * example
810      *
811      * 0x000906000 == 0.9.6 dev 0x000906023 == 0.9.6b beta 3 0x00090605f ==
812      * 0.9.6e release
813      *
814      * Versions prior to 0.9.3 have identifiers < 0x0930.  Versions between
815      * 0.9.3 and 0.9.5 had a version identifier with this interpretation:
816      *
817      * MMNNFFRBB major minor fix final beta/patch
818      *
819      * for example
820      *
821      * 0x000904100 == 0.9.4 release 0x000905000 == 0.9.5 dev
822      *
823      * Version 0.9.5a had an interim interpretation that is like the current
824      * one, except the patch level got the highest bit set, to keep continu-
825      * ity.  The number was therefore 0x0090581f.
826      */
827 
828     if (version < 0x0930) {
829 	info->status = 0;
830 	info->patch = version & 0x0f;
831 	version >>= 4;
832 	info->micro = version & 0x0f;
833 	version >>= 4;
834 	info->minor = version & 0x0f;
835 	version >>= 4;
836 	info->major = version & 0x0f;
837     } else if (version < 0x00905800L) {
838 	info->patch = version & 0xff;
839 	version >>= 8;
840 	info->status = version & 0xf;
841 	version >>= 4;
842 	info->micro = version & 0xff;
843 	version >>= 8;
844 	info->minor = version & 0xff;
845 	version >>= 8;
846 	info->major = version & 0xff;
847     } else {
848 	info->status = version & 0xf;
849 	version >>= 4;
850 	info->patch = version & 0xff;
851 	version >>= 8;
852 	info->micro = version & 0xff;
853 	version >>= 8;
854 	info->minor = version & 0xff;
855 	version >>= 8;
856 	info->major = version & 0xff;
857 	if (version < 0x00906000L)
858 	    info->patch &= ~0x80;
859     }
860 }
861 
862 /* tls_check_version - Detect mismatch between headers and library. */
863 
864 void    tls_check_version(void)
865 {
866     TLS_VINFO hdr_info;
867     TLS_VINFO lib_info;
868 
869     tls_version_split(OPENSSL_VERSION_NUMBER, &hdr_info);
870     tls_version_split(SSLeay(), &lib_info);
871 
872     if (lib_info.major != hdr_info.major
873 	|| lib_info.minor != hdr_info.minor
874 	|| lib_info.micro != hdr_info.micro)
875 	msg_warn("run-time library vs. compile-time header version mismatch: "
876 	     "OpenSSL %d.%d.%d may not be compatible with OpenSSL %d.%d.%d",
877 		 lib_info.major, lib_info.minor, lib_info.micro,
878 		 hdr_info.major, hdr_info.minor, hdr_info.micro);
879 }
880 
881 /* tls_bug_bits - SSL bug compatibility bits for this OpenSSL version */
882 
883 long    tls_bug_bits(void)
884 {
885     long    bits = SSL_OP_ALL;		/* Work around all known bugs */
886 
887 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && \
888 	OPENSSL_VERSION_NUMBER < 0x10000000L
889     long    lib_version = SSLeay();
890 
891     /*
892      * In OpenSSL 0.9.8[ab], enabling zlib compression breaks the padding bug
893      * work-around, leading to false positives and failed connections. We may
894      * not interoperate with systems with the bug, but this is better than
895      * breaking on all 0.9.8[ab] systems that have zlib support enabled.
896      */
897     if (lib_version >= 0x00908000L && lib_version <= 0x0090802fL) {
898 	STACK_OF(SSL_COMP) * comp_methods;
899 
900 	comp_methods = SSL_COMP_get_compression_methods();
901 	if (comp_methods != 0 && sk_SSL_COMP_num(comp_methods) > 0)
902 	    bits &= ~SSL_OP_TLS_BLOCK_PADDING_BUG;
903     }
904 #endif
905 
906     /*
907      * Silently ignore any strings that don't appear in the tweaks table, or
908      * hex bits that are not in SSL_OP_ALL.
909      */
910     if (*var_tls_bug_tweaks) {
911 	bits &= ~long_name_mask_opt(VAR_TLS_BUG_TWEAKS, ssl_bug_tweaks,
912 				    var_tls_bug_tweaks, NAME_MASK_ANY_CASE |
913 				    NAME_MASK_NUMBER | NAME_MASK_WARN);
914 #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
915 	/* Not relevant to SMTP */
916 	bits &= ~SSL_OP_SAFARI_ECDHE_ECDSA_BUG;
917 #endif
918     }
919     return (bits);
920 }
921 
922 /* tls_print_errors - print and clear the error stack */
923 
924 void    tls_print_errors(void)
925 {
926     unsigned long err;
927     char    buffer[1024];		/* XXX */
928     const char *file;
929     const char *data;
930     int     line;
931     int     flags;
932     unsigned long thread;
933 
934     thread = CRYPTO_thread_id();
935     while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
936 	ERR_error_string_n(err, buffer, sizeof(buffer));
937 	if (flags & ERR_TXT_STRING)
938 	    msg_warn("TLS library problem: %lu:%s:%s:%d:%s:",
939 		     thread, buffer, file, line, data);
940 	else
941 	    msg_warn("TLS library problem: %lu:%s:%s:%d:",
942 		     thread, buffer, file, line);
943     }
944 }
945 
946 /* tls_info_callback - callback for logging SSL events via Postfix */
947 
948 void    tls_info_callback(const SSL *s, int where, int ret)
949 {
950     char   *str;
951     int     w;
952 
953     /* Adapted from OpenSSL apps/s_cb.c. */
954 
955     w = where & ~SSL_ST_MASK;
956 
957     if (w & SSL_ST_CONNECT)
958 	str = "SSL_connect";
959     else if (w & SSL_ST_ACCEPT)
960 	str = "SSL_accept";
961     else
962 	str = "unknown";
963 
964     if (where & SSL_CB_LOOP) {
965 	msg_info("%s:%s", str, SSL_state_string_long((SSL *) s));
966     } else if (where & SSL_CB_ALERT) {
967 	str = (where & SSL_CB_READ) ? "read" : "write";
968 	if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
969 	    msg_info("SSL3 alert %s:%s:%s", str,
970 		     SSL_alert_type_string_long(ret),
971 		     SSL_alert_desc_string_long(ret));
972     } else if (where & SSL_CB_EXIT) {
973 	if (ret == 0)
974 	    msg_info("%s:failed in %s",
975 		     str, SSL_state_string_long((SSL *) s));
976 	else if (ret < 0) {
977 #ifndef LOG_NON_ERROR_STATES
978 	    switch (SSL_get_error((SSL *) s, ret)) {
979 	    case SSL_ERROR_WANT_READ:
980 	    case SSL_ERROR_WANT_WRITE:
981 		/* Don't log non-error states. */
982 		break;
983 	    default:
984 #endif
985 		msg_info("%s:error in %s",
986 			 str, SSL_state_string_long((SSL *) s));
987 #ifndef LOG_NON_ERROR_STATES
988 	    }
989 #endif
990 	}
991     }
992 }
993 
994  /*
995   * taken from OpenSSL crypto/bio/b_dump.c.
996   *
997   * Modified to save a lot of strcpy and strcat by Matti Aarnio.
998   *
999   * Rewritten by Wietse to elimate fixed-size stack buffer, array index
1000   * multiplication and division, sprintf() and strcpy(), and lots of strlen()
1001   * calls. We could make it a little faster by using a fixed-size stack-based
1002   * buffer.
1003   *
1004   * 200412 - use %lx to print pointers, after casting them to unsigned long.
1005   */
1006 
1007 #define TRUNCATE_SPACE_NULL
1008 #define DUMP_WIDTH	16
1009 #define VERT_SPLIT	7
1010 
1011 static void tls_dump_buffer(const unsigned char *start, int len)
1012 {
1013     VSTRING *buf = vstring_alloc(100);
1014     const unsigned char *last = start + len - 1;
1015     const unsigned char *row;
1016     const unsigned char *col;
1017     int     ch;
1018 
1019 #ifdef TRUNCATE_SPACE_NULL
1020     while (last >= start && (*last == ' ' || *last == 0))
1021 	last--;
1022 #endif
1023 
1024     for (row = start; row <= last; row += DUMP_WIDTH) {
1025 	VSTRING_RESET(buf);
1026 	vstring_sprintf(buf, "%04lx ", (unsigned long) (row - start));
1027 	for (col = row; col < row + DUMP_WIDTH; col++) {
1028 	    if (col > last) {
1029 		vstring_strcat(buf, "   ");
1030 	    } else {
1031 		ch = *col;
1032 		vstring_sprintf_append(buf, "%02x%c",
1033 				   ch, col - row == VERT_SPLIT ? '|' : ' ');
1034 	    }
1035 	}
1036 	VSTRING_ADDCH(buf, ' ');
1037 	for (col = row; col < row + DUMP_WIDTH; col++) {
1038 	    if (col > last)
1039 		break;
1040 	    ch = *col;
1041 	    if (!ISPRINT(ch))
1042 		ch = '.';
1043 	    VSTRING_ADDCH(buf, ch);
1044 	    if (col - row == VERT_SPLIT)
1045 		VSTRING_ADDCH(buf, ' ');
1046 	}
1047 	VSTRING_TERMINATE(buf);
1048 	msg_info("%s", vstring_str(buf));
1049     }
1050 #ifdef TRUNCATE_SPACE_NULL
1051     if ((last + 1) - start < len)
1052 	msg_info("%04lx - <SPACES/NULLS>",
1053 		 (unsigned long) ((last + 1) - start));
1054 #endif
1055     vstring_free(buf);
1056 }
1057 
1058 /* taken from OpenSSL apps/s_cb.c */
1059 
1060 long    tls_bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi,
1061 			        long unused_argl, long ret)
1062 {
1063     if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
1064 	msg_info("read from %08lX [%08lX] (%d bytes => %ld (0x%lX))",
1065 		 (unsigned long) bio, (unsigned long) argp, argi,
1066 		 ret, (unsigned long) ret);
1067 	tls_dump_buffer((unsigned char *) argp, (int) ret);
1068     } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
1069 	msg_info("write to %08lX [%08lX] (%d bytes => %ld (0x%lX))",
1070 		 (unsigned long) bio, (unsigned long) argp, argi,
1071 		 ret, (unsigned long) ret);
1072 	tls_dump_buffer((unsigned char *) argp, (int) ret);
1073     }
1074     return (ret);
1075 }
1076 
1077 #else
1078 
1079  /*
1080   * Broken linker workaround.
1081   */
1082 int     tls_dummy_for_broken_linkers;
1083 
1084 #endif
1085