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