1 /* $NetBSD: tls_verify.c,v 1.1.1.3 2013/08/21 20:09:55 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* tls_verify 3 6 /* SUMMARY 7 /* peer name and peer certificate verification 8 /* SYNOPSIS 9 /* #define TLS_INTERNAL 10 /* #include <tls.h> 11 /* 12 /* char *tls_peer_CN(peercert, TLScontext) 13 /* X509 *peercert; 14 /* TLS_SESS_STATE *TLScontext; 15 /* 16 /* char *tls_issuer_CN(peercert, TLScontext) 17 /* X509 *peercert; 18 /* TLS_SESS_STATE *TLScontext; 19 /* 20 /* const char *tls_dns_name(gn, TLScontext) 21 /* const GENERAL_NAME *gn; 22 /* TLS_SESS_STATE *TLScontext; 23 /* 24 /* char *tls_fingerprint(peercert, dgst) 25 /* X509 *peercert; 26 /* const char *dgst; 27 /* 28 /* char *tls_pkey_fprint(peercert, dgst) 29 /* X509 *peercert; 30 /* const char *dgst; 31 /* 32 /* int tls_verify_certificate_callback(ok, ctx) 33 /* int ok; 34 /* X509_STORE_CTX *ctx; 35 /* DESCRIPTION 36 /* tls_peer_CN() returns the text CommonName for the peer 37 /* certificate subject, or an empty string if no CommonName was 38 /* found. The result is allocated with mymalloc() and must be 39 /* freed by the caller; it contains UTF-8 without non-printable 40 /* ASCII characters. 41 /* 42 /* tls_issuer_CN() returns the text CommonName for the peer 43 /* certificate issuer, or an empty string if no CommonName was 44 /* found. The result is allocated with mymalloc() and must be 45 /* freed by the caller; it contains UTF-8 without non-printable 46 /* ASCII characters. 47 /* 48 /* tls_dns_name() returns the string value of a GENERAL_NAME 49 /* from a DNS subjectAltName extension. If non-printable characters 50 /* are found, a null string is returned instead. Further sanity 51 /* checks may be added if the need arises. 52 /* 53 /* tls_fingerprint() returns a fingerprint of the the given 54 /* certificate using the requested message digest. Panics if the 55 /* (previously verified) digest algorithm is not found. The return 56 /* value is dynamically allocated with mymalloc(), and the caller 57 /* must eventually free it with myfree(). 58 /* 59 /* tls_pkey_fprint() returns a public-key fingerprint; in all 60 /* other respects the function behaves as tls_fingerprint(). 61 /* The var_tls_bc_pkey_fprint variable enables an incorrect 62 /* algorithm that was used in Postfix versions 2.9.[0-5]. 63 /* 64 /* tls_verify_callback() is called several times (directly or 65 /* indirectly) from crypto/x509/x509_vfy.c. It is called as 66 /* a final check, and if it returns "0", the handshake is 67 /* immediately shut down and the connection fails. 68 /* 69 /* Postfix/TLS has two modes, the "opportunistic" mode and 70 /* the "enforce" mode: 71 /* 72 /* In the "opportunistic" mode we never want the connection 73 /* to fail just because there is something wrong with the 74 /* peer's certificate. After all, we would have sent or received 75 /* the mail even if TLS weren't available. Therefore the 76 /* return value is always "1". 77 /* 78 /* The SMTP client or server may require TLS (e.g. to protect 79 /* passwords), while peer certificates are optional. In this 80 /* case we must return "1" even when we are unhappy with the 81 /* peer certificate. Only when peer certificates are required, 82 /* certificate verification failure will result in immediate 83 /* termination (return 0). 84 /* 85 /* The only error condition not handled inside the OpenSSL 86 /* library is the case of a too-long certificate chain. We 87 /* test for this condition only if "ok = 1", that is, if 88 /* verification didn't fail because of some earlier problem. 89 /* 90 /* Arguments: 91 /* .IP ok 92 /* Result of prior verification: non-zero means success. In 93 /* order to reduce the noise level, some tests or error reports 94 /* are disabled when verification failed because of some 95 /* earlier problem. 96 /* .IP ctx 97 /* SSL application context. This links to the Postfix TLScontext 98 /* with enforcement and logging options. 99 /* .IP gn 100 /* An OpenSSL GENERAL_NAME structure holding a DNS subjectAltName 101 /* to be decoded and checked for validity. 102 /* .IP peercert 103 /* Server or client X.509 certificate. 104 /* .IP dgst 105 /* Name of a message digest algorithm suitable for computing secure 106 /* (1st pre-image resistant) message digests of certificates. For now, 107 /* md5, sha1, or member of SHA-2 family if supported by OpenSSL. 108 /* .IP TLScontext 109 /* Server or client context for warning messages. 110 /* DIAGNOSTICS 111 /* tls_peer_CN(), tls_issuer_CN() and tls_dns_name() log a warning 112 /* when 1) the requested information is not available in the specified 113 /* certificate, 2) the result exceeds a fixed limit, 3) the result 114 /* contains NUL characters or the result contains non-printable or 115 /* non-ASCII characters. 116 /* LICENSE 117 /* .ad 118 /* .fi 119 /* This software is free. You can do with it whatever you want. 120 /* The original author kindly requests that you acknowledge 121 /* the use of his software. 122 /* AUTHOR(S) 123 /* Originally written by: 124 /* Lutz Jaenicke 125 /* BTU Cottbus 126 /* Allgemeine Elektrotechnik 127 /* Universitaetsplatz 3-4 128 /* D-03044 Cottbus, Germany 129 /* 130 /* Updated by: 131 /* Wietse Venema 132 /* IBM T.J. Watson Research 133 /* P.O. Box 704 134 /* Yorktown Heights, NY 10598, USA 135 /* 136 /* Victor Duchovni 137 /* Morgan Stanley 138 /*--*/ 139 140 /* System library. */ 141 142 #include <sys_defs.h> 143 #include <ctype.h> 144 145 #ifdef USE_TLS 146 #include <string.h> 147 148 /* Utility library. */ 149 150 #include <msg.h> 151 #include <mymalloc.h> 152 #include <stringops.h> 153 154 /* Global library. */ 155 156 #include <mail_params.h> 157 158 /* TLS library. */ 159 160 #define TLS_INTERNAL 161 #include <tls.h> 162 163 /* Application-specific. */ 164 165 static const char hexcodes[] = "0123456789ABCDEF"; 166 167 /* tls_verify_certificate_callback - verify peer certificate info */ 168 169 int tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx) 170 { 171 char buf[CCERT_BUFSIZ]; 172 X509 *cert; 173 int err; 174 int depth; 175 SSL *con; 176 TLS_SESS_STATE *TLScontext; 177 178 depth = X509_STORE_CTX_get_error_depth(ctx); 179 cert = X509_STORE_CTX_get_current_cert(ctx); 180 con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); 181 TLScontext = SSL_get_ex_data(con, TLScontext_index); 182 183 /* 184 * The callback function is called repeatedly, first with the root 185 * certificate, and then with each intermediate certificate ending with 186 * the peer certificate. 187 * 188 * With each call, the validity of the current certificate (usage bits, 189 * attributes, expiration, ... checked by the OpenSSL library) is 190 * available in the "ok" argument. Error details are available via 191 * X509_STORE_CTX API. 192 * 193 * We never terminate the SSL handshake in the verification callback, rather 194 * we allow the TLS handshake to continue, but mark the session as 195 * unverified. The application is responsible for closing any sessions 196 * with unverified credentials. 197 * 198 * Certificate chain depth limit violations are mis-reported by the OpenSSL 199 * library, from SSL_CTX_set_verify(3): 200 * 201 * The certificate verification depth set with SSL[_CTX]_verify_depth() 202 * stops the verification at a certain depth. The error message produced 203 * will be that of an incomplete certificate chain and not 204 * X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected. 205 * 206 * We set a limit that is one higher than the user requested limit. If this 207 * higher limit is reached, we raise an error even a trusted root CA is 208 * present at this depth. This disambiguates trust chain truncation from 209 * an incomplete trust chain. 210 */ 211 if (depth >= SSL_get_verify_depth(con)) { 212 ok = 0; 213 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG); 214 } 215 if (TLScontext->log_mask & TLS_LOG_VERBOSE) { 216 X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); 217 msg_info("%s: certificate verification depth=%d verify=%d subject=%s", 218 TLScontext->namaddr, depth, ok, printable(buf, '?')); 219 } 220 221 /* 222 * If no errors, or we are not logging verification errors, we are done. 223 */ 224 if (ok || (TLScontext->log_mask & TLS_LOG_UNTRUSTED) == 0) 225 return (1); 226 227 /* 228 * One counter-example is enough. 229 */ 230 TLScontext->log_mask &= ~TLS_LOG_UNTRUSTED; 231 232 #define PURPOSE ((depth>0) ? "CA": TLScontext->am_server ? "client": "server") 233 234 /* 235 * Specific causes for verification failure. 236 */ 237 switch (err = X509_STORE_CTX_get_error(ctx)) { 238 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 239 msg_info("certificate verification failed for %s: " 240 "self-signed certificate", TLScontext->namaddr); 241 break; 242 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 243 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 244 245 /* 246 * There is no difference between issuing cert not provided and 247 * provided, but not found in CAfile/CApath. Either way, we don't 248 * trust it. 249 */ 250 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), 251 buf, sizeof(buf)); 252 msg_info("certificate verification failed for %s: untrusted issuer %s", 253 TLScontext->namaddr, printable(buf, '?')); 254 break; 255 case X509_V_ERR_CERT_NOT_YET_VALID: 256 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 257 msg_info("%s certificate verification failed for %s: certificate not" 258 " yet valid", PURPOSE, TLScontext->namaddr); 259 break; 260 case X509_V_ERR_CERT_HAS_EXPIRED: 261 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 262 msg_info("%s certificate verification failed for %s: certificate has" 263 " expired", PURPOSE, TLScontext->namaddr); 264 break; 265 case X509_V_ERR_INVALID_PURPOSE: 266 msg_info("certificate verification failed for %s: not designated for " 267 "use as a %s certificate", TLScontext->namaddr, PURPOSE); 268 break; 269 case X509_V_ERR_CERT_CHAIN_TOO_LONG: 270 msg_info("certificate verification failed for %s: " 271 "certificate chain longer than limit(%d)", 272 TLScontext->namaddr, SSL_get_verify_depth(con) - 1); 273 break; 274 default: 275 msg_info("%s certificate verification failed for %s: num=%d:%s", 276 PURPOSE, TLScontext->namaddr, err, 277 X509_verify_cert_error_string(err)); 278 break; 279 } 280 281 return (1); 282 } 283 284 #ifndef DONT_GRIPE 285 #define DONT_GRIPE 0 286 #define DO_GRIPE 1 287 #endif 288 289 /* tls_text_name - extract certificate property value by name */ 290 291 static char *tls_text_name(X509_NAME *name, int nid, const char *label, 292 const TLS_SESS_STATE *TLScontext, int gripe) 293 { 294 const char *myname = "tls_text_name"; 295 int pos; 296 X509_NAME_ENTRY *entry; 297 ASN1_STRING *entry_str; 298 int asn1_type; 299 int utf8_length; 300 unsigned char *utf8_value; 301 int ch; 302 unsigned char *cp; 303 304 if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) { 305 if (gripe != DONT_GRIPE) { 306 msg_warn("%s: %s: peer certificate has no %s", 307 myname, TLScontext->namaddr, label); 308 tls_print_errors(); 309 } 310 return (0); 311 } 312 #if 0 313 314 /* 315 * If the match is required unambiguous, insist that that no other values 316 * be present. 317 */ 318 if (X509_NAME_get_index_by_NID(name, nid, pos) >= 0) { 319 msg_warn("%s: %s: multiple %ss in peer certificate", 320 myname, TLScontext->namaddr, label); 321 return (0); 322 } 323 #endif 324 325 if ((entry = X509_NAME_get_entry(name, pos)) == 0) { 326 /* This should not happen */ 327 msg_warn("%s: %s: error reading peer certificate %s entry", 328 myname, TLScontext->namaddr, label); 329 tls_print_errors(); 330 return (0); 331 } 332 if ((entry_str = X509_NAME_ENTRY_get_data(entry)) == 0) { 333 /* This should not happen */ 334 msg_warn("%s: %s: error reading peer certificate %s data", 335 myname, TLScontext->namaddr, label); 336 tls_print_errors(); 337 return (0); 338 } 339 340 /* 341 * XXX Convert everything into UTF-8. This is a super-set of ASCII, so we 342 * don't have to bother with separate code paths for ASCII-like content. 343 * If the payload is ASCII then we won't waste lots of CPU cycles 344 * converting it into UTF-8. It's up to OpenSSL to do something 345 * reasonable when converting ASCII formats that contain non-ASCII 346 * content. 347 * 348 * XXX Don't bother optimizing the string length error check. It is not 349 * worth the complexity. 350 */ 351 asn1_type = ASN1_STRING_type(entry_str); 352 if ((utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_str)) < 0) { 353 msg_warn("%s: %s: error decoding peer %s of ASN.1 type=%d", 354 myname, TLScontext->namaddr, label, asn1_type); 355 tls_print_errors(); 356 return (0); 357 } 358 359 /* 360 * No returns without cleaning up. A good optimizer will replace multiple 361 * blocks of identical code by jumps to just one such block. 362 */ 363 #define TLS_TEXT_NAME_RETURN(x) do { \ 364 char *__tls_text_name_temp = (x); \ 365 OPENSSL_free(utf8_value); \ 366 return (__tls_text_name_temp); \ 367 } while (0) 368 369 /* 370 * Remove trailing null characters. They would give false alarms with the 371 * length check and with the embedded null check. 372 */ 373 #define TRIM0(s, l) do { while ((l) > 0 && (s)[(l)-1] == 0) --(l); } while (0) 374 375 TRIM0(utf8_value, utf8_length); 376 377 /* 378 * Enforce the length limit, because the caller will copy the result into 379 * a fixed-length buffer. 380 */ 381 if (utf8_length >= CCERT_BUFSIZ) { 382 msg_warn("%s: %s: peer %s too long: %d", 383 myname, TLScontext->namaddr, label, utf8_length); 384 TLS_TEXT_NAME_RETURN(0); 385 } 386 387 /* 388 * Reject embedded nulls in ASCII or UTF-8 names. OpenSSL is responsible 389 * for producing properly-formatted UTF-8. 390 */ 391 if (utf8_length != strlen((char *) utf8_value)) { 392 msg_warn("%s: %s: NULL character in peer %s", 393 myname, TLScontext->namaddr, label); 394 TLS_TEXT_NAME_RETURN(0); 395 } 396 397 /* 398 * Reject non-printable ASCII characters in UTF-8 content. 399 * 400 * Note: the code below does not find control characters in illegal UTF-8 401 * sequences. It's OpenSSL's job to produce valid UTF-8, and reportedly, 402 * it does validation. 403 */ 404 for (cp = utf8_value; (ch = *cp) != 0; cp++) { 405 if (ISASCII(ch) && !ISPRINT(ch)) { 406 msg_warn("%s: %s: non-printable content in peer %s", 407 myname, TLScontext->namaddr, label); 408 TLS_TEXT_NAME_RETURN(0); 409 } 410 } 411 TLS_TEXT_NAME_RETURN(mystrdup((char *) utf8_value)); 412 } 413 414 /* tls_dns_name - Extract valid DNS name from subjectAltName value */ 415 416 const char *tls_dns_name(const GENERAL_NAME * gn, 417 const TLS_SESS_STATE *TLScontext) 418 { 419 const char *myname = "tls_dns_name"; 420 char *cp; 421 const char *dnsname; 422 int len; 423 424 /* 425 * Peername checks are security sensitive, carefully scrutinize the 426 * input! 427 */ 428 if (gn->type != GEN_DNS) 429 msg_panic("%s: Non DNS input argument", myname); 430 431 /* 432 * We expect the OpenSSL library to construct GEN_DNS extesion objects as 433 * ASN1_IA5STRING values. Check we got the right union member. 434 */ 435 if (ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING) { 436 msg_warn("%s: %s: invalid ASN1 value type in subjectAltName", 437 myname, TLScontext->namaddr); 438 return (0); 439 } 440 441 /* 442 * Safe to treat as an ASCII string possibly holding a DNS name 443 */ 444 dnsname = (char *) ASN1_STRING_data(gn->d.ia5); 445 len = ASN1_STRING_length(gn->d.ia5); 446 TRIM0(dnsname, len); 447 448 /* 449 * Per Dr. Steven Henson of the OpenSSL development team, ASN1_IA5STRING 450 * values can have internal ASCII NUL values in this context because 451 * their length is taken from the decoded ASN1 buffer, a trailing NUL is 452 * always appended to make sure that the string is terminated, but the 453 * ASN.1 length may differ from strlen(). 454 */ 455 if (len != strlen(dnsname)) { 456 msg_warn("%s: %s: internal NUL in subjectAltName", 457 myname, TLScontext->namaddr); 458 return 0; 459 } 460 461 /* 462 * XXX: Should we be more strict and call valid_hostname()? So long as 463 * the name is safe to handle, if it is not a valid hostname, it will not 464 * compare equal to the expected peername, so being more strict than 465 * "printable" is likely excessive... 466 */ 467 if (*dnsname && !allprint(dnsname)) { 468 cp = mystrdup(dnsname); 469 msg_warn("%s: %s: non-printable characters in subjectAltName: %.100s", 470 myname, TLScontext->namaddr, printable(cp, '?')); 471 myfree(cp); 472 return 0; 473 } 474 return (dnsname); 475 } 476 477 /* tls_peer_CN - extract peer common name from certificate */ 478 479 char *tls_peer_CN(X509 *peercert, const TLS_SESS_STATE *TLScontext) 480 { 481 char *cn; 482 483 cn = tls_text_name(X509_get_subject_name(peercert), NID_commonName, 484 "subject CN", TLScontext, DO_GRIPE); 485 return (cn ? cn : mystrdup("")); 486 } 487 488 /* tls_issuer_CN - extract issuer common name from certificate */ 489 490 char *tls_issuer_CN(X509 *peer, const TLS_SESS_STATE *TLScontext) 491 { 492 X509_NAME *name; 493 char *cn; 494 495 name = X509_get_issuer_name(peer); 496 497 /* 498 * If no issuer CN field, use Organization instead. CA certs without a CN 499 * are common, so we only complain if the organization is also missing. 500 */ 501 if ((cn = tls_text_name(name, NID_commonName, 502 "issuer CN", TLScontext, DONT_GRIPE)) == 0) 503 cn = tls_text_name(name, NID_organizationName, 504 "issuer Organization", TLScontext, DO_GRIPE); 505 return (cn ? cn : mystrdup("")); 506 } 507 508 /* tls_fprint - compute and encode digest of DER-encoded object */ 509 510 static char *tls_fprint(const char *buf, int len, const char *dgst) 511 { 512 const char *myname = "tls_fprint"; 513 EVP_MD_CTX *mdctx; 514 const EVP_MD *md_alg; 515 unsigned char md_buf[EVP_MAX_MD_SIZE]; 516 unsigned int md_len; 517 int i; 518 char *result = 0; 519 520 /* Previously available in "init" routine. */ 521 if ((md_alg = EVP_get_digestbyname(dgst)) == 0) 522 msg_panic("%s: digest algorithm \"%s\" not found", myname, dgst); 523 524 mdctx = EVP_MD_CTX_create(); 525 if (EVP_DigestInit_ex(mdctx, md_alg, NULL) == 0 526 || EVP_DigestUpdate(mdctx, buf, len) == 0 527 || EVP_DigestFinal_ex(mdctx, md_buf, &md_len) == 0) 528 msg_fatal("%s: error computing %s message digest", myname, dgst); 529 EVP_MD_CTX_destroy(mdctx); 530 531 /* Check for OpenSSL contract violation */ 532 if (md_len > EVP_MAX_MD_SIZE || md_len >= INT_MAX / 3) 533 msg_panic("%s: unexpectedly large %s digest size: %u", 534 myname, dgst, md_len); 535 536 result = mymalloc(md_len * 3); 537 for (i = 0; i < md_len; i++) { 538 result[i * 3] = hexcodes[(md_buf[i] & 0xf0) >> 4U]; 539 result[(i * 3) + 1] = hexcodes[(md_buf[i] & 0x0f)]; 540 result[(i * 3) + 2] = (i + 1 != md_len) ? ':' : '\0'; 541 } 542 return (result); 543 } 544 545 /* tls_fingerprint - extract certificate fingerprint */ 546 547 char *tls_fingerprint(X509 *peercert, const char *dgst) 548 { 549 int len; 550 char *buf; 551 char *buf2; 552 char *result; 553 554 len = i2d_X509(peercert, NULL); 555 buf2 = buf = mymalloc(len); 556 i2d_X509(peercert, (unsigned char **)&buf2); 557 if (buf2 - buf != len) 558 msg_panic("i2d_X509 invalid result length"); 559 560 result = tls_fprint(buf, len, dgst); 561 myfree(buf); 562 563 return (result); 564 } 565 566 /* tls_pkey_fprint - extract public key fingerprint from certificate */ 567 568 char *tls_pkey_fprint(X509 *peercert, const char *dgst) 569 { 570 if (var_tls_bc_pkey_fprint) { 571 const char *myname = "tls_pkey_fprint"; 572 ASN1_BIT_STRING *key; 573 char *result; 574 575 key = X509_get0_pubkey_bitstr(peercert); 576 if (key == 0) 577 msg_fatal("%s: error extracting legacy public-key fingerprint: %m", 578 myname); 579 580 result = tls_fprint((char *) key->data, key->length, dgst); 581 return (result); 582 } else { 583 int len; 584 char *buf; 585 char *buf2; 586 char *result; 587 588 len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), NULL); 589 buf2 = buf = mymalloc(len); 590 i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), (unsigned char **) &buf2); 591 if (buf2 - buf != len) 592 msg_panic("i2d_X509_PUBKEY invalid result length"); 593 594 result = tls_fprint(buf, len, dgst); 595 myfree(buf); 596 return (result); 597 } 598 } 599 600 #endif 601