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