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