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