| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 bool X509Certificate::Equals(const X509Certificate* other) const { | 486 bool X509Certificate::Equals(const X509Certificate* other) const { |
| 487 return IsSameOSCert(cert_handle_, other->cert_handle_); | 487 return IsSameOSCert(cert_handle_, other->cert_handle_); |
| 488 } | 488 } |
| 489 | 489 |
| 490 // static | 490 // static |
| 491 bool X509Certificate::VerifyHostname( | 491 bool X509Certificate::VerifyHostname( |
| 492 const std::string& hostname, | 492 const std::string& hostname, |
| 493 const std::string& cert_common_name, | 493 const std::string& cert_common_name, |
| 494 const std::vector<std::string>& cert_san_dns_names, | 494 const std::vector<std::string>& cert_san_dns_names, |
| 495 const std::vector<std::string>& cert_san_ip_addrs, | 495 const std::vector<std::string>& cert_san_ip_addrs, |
| 496 bool* common_name_fallback_used) { | 496 bool allow_common_name_fallback) { |
| 497 DCHECK(!hostname.empty()); | 497 DCHECK(!hostname.empty()); |
| 498 // Perform name verification following http://tools.ietf.org/html/rfc6125. | 498 // Perform name verification following http://tools.ietf.org/html/rfc6125. |
| 499 // The terminology used in this method is as per that RFC:- | 499 // The terminology used in this method is as per that RFC:- |
| 500 // Reference identifier == the host the local user/agent is intending to | 500 // Reference identifier == the host the local user/agent is intending to |
| 501 // access, i.e. the thing displayed in the URL bar. | 501 // access, i.e. the thing displayed in the URL bar. |
| 502 // Presented identifier(s) == name(s) the server knows itself as, in its cert. | 502 // Presented identifier(s) == name(s) the server knows itself as, in its cert. |
| 503 | 503 |
| 504 // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. | 504 // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. |
| 505 const std::string host_or_ip = hostname.find(':') != std::string::npos ? | 505 const std::string host_or_ip = hostname.find(':') != std::string::npos ? |
| 506 "[" + hostname + "]" : hostname; | 506 "[" + hostname + "]" : hostname; |
| 507 url::CanonHostInfo host_info; | 507 url::CanonHostInfo host_info; |
| 508 std::string reference_name = CanonicalizeHost(host_or_ip, &host_info); | 508 std::string reference_name = CanonicalizeHost(host_or_ip, &host_info); |
| 509 // CanonicalizeHost does not normalize absolute vs relative DNS names. If | 509 // CanonicalizeHost does not normalize absolute vs relative DNS names. If |
| 510 // the input name was absolute (included trailing .), normalize it as if it | 510 // the input name was absolute (included trailing .), normalize it as if it |
| 511 // was relative. | 511 // was relative. |
| 512 if (!reference_name.empty() && *reference_name.rbegin() == '.') | 512 if (!reference_name.empty() && *reference_name.rbegin() == '.') |
| 513 reference_name.resize(reference_name.size() - 1); | 513 reference_name.resize(reference_name.size() - 1); |
| 514 if (reference_name.empty()) | 514 if (reference_name.empty()) |
| 515 return false; | 515 return false; |
| 516 | 516 |
| 517 // Allow fallback to Common name matching? | 517 if (!allow_common_name_fallback && cert_san_dns_names.empty() && |
| 518 const bool common_name_fallback = cert_san_dns_names.empty() && | 518 cert_san_ip_addrs.empty()) { |
| 519 cert_san_ip_addrs.empty(); | 519 // Common Name matching is not allowed, so fail fast. |
| 520 *common_name_fallback_used = common_name_fallback; | 520 return false; |
| 521 } |
| 521 | 522 |
| 522 // Fully handle all cases where |hostname| contains an IP address. | 523 // Fully handle all cases where |hostname| contains an IP address. |
| 523 if (host_info.IsIPAddress()) { | 524 if (host_info.IsIPAddress()) { |
| 524 if (common_name_fallback && host_info.family == url::CanonHostInfo::IPV4) { | 525 if (allow_common_name_fallback && cert_san_dns_names.empty() && |
| 526 cert_san_ip_addrs.empty() && |
| 527 host_info.family == url::CanonHostInfo::IPV4) { |
| 525 // Fallback to Common name matching. As this is deprecated and only | 528 // Fallback to Common name matching. As this is deprecated and only |
| 526 // supported for compatibility refuse it for IPv6 addresses. | 529 // supported for compatibility refuse it for IPv6 addresses. |
| 527 return reference_name == cert_common_name; | 530 return reference_name == cert_common_name; |
| 528 } | 531 } |
| 529 base::StringPiece ip_addr_string( | 532 base::StringPiece ip_addr_string( |
| 530 reinterpret_cast<const char*>(host_info.address), | 533 reinterpret_cast<const char*>(host_info.address), |
| 531 host_info.AddressLength()); | 534 host_info.AddressLength()); |
| 532 return std::find(cert_san_ip_addrs.begin(), cert_san_ip_addrs.end(), | 535 return std::find(cert_san_ip_addrs.begin(), cert_san_ip_addrs.end(), |
| 533 ip_addr_string) != cert_san_ip_addrs.end(); | 536 ip_addr_string) != cert_san_ip_addrs.end(); |
| 534 } | 537 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 allow_wildcards = | 576 allow_wildcards = |
| 574 !is_registry_controlled && | 577 !is_registry_controlled && |
| 575 reference_name.find_first_not_of("0123456789.") != std::string::npos; | 578 reference_name.find_first_not_of("0123456789.") != std::string::npos; |
| 576 } | 579 } |
| 577 | 580 |
| 578 // Now step through the DNS names doing wild card comparison (if necessary) | 581 // Now step through the DNS names doing wild card comparison (if necessary) |
| 579 // on each against the reference name. If subjectAltName is empty, then | 582 // on each against the reference name. If subjectAltName is empty, then |
| 580 // fallback to use the common name instead. | 583 // fallback to use the common name instead. |
| 581 std::vector<std::string> common_name_as_vector; | 584 std::vector<std::string> common_name_as_vector; |
| 582 const std::vector<std::string>* presented_names = &cert_san_dns_names; | 585 const std::vector<std::string>* presented_names = &cert_san_dns_names; |
| 583 if (common_name_fallback) { | 586 if (allow_common_name_fallback && cert_san_dns_names.empty() && |
| 587 cert_san_ip_addrs.empty()) { |
| 584 // Note: there's a small possibility cert_common_name is an international | 588 // Note: there's a small possibility cert_common_name is an international |
| 585 // domain name in non-standard encoding (e.g. UTF8String or BMPString | 589 // domain name in non-standard encoding (e.g. UTF8String or BMPString |
| 586 // instead of A-label). As common name fallback is deprecated we're not | 590 // instead of A-label). As common name fallback is deprecated we're not |
| 587 // doing anything specific to deal with this. | 591 // doing anything specific to deal with this. |
| 588 common_name_as_vector.push_back(cert_common_name); | 592 common_name_as_vector.push_back(cert_common_name); |
| 589 presented_names = &common_name_as_vector; | 593 presented_names = &common_name_as_vector; |
| 590 } | 594 } |
| 591 for (std::vector<std::string>::const_iterator it = | 595 for (std::vector<std::string>::const_iterator it = |
| 592 presented_names->begin(); | 596 presented_names->begin(); |
| 593 it != presented_names->end(); ++it) { | 597 it != presented_names->end(); ++it) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 621 | 625 |
| 622 if (!allow_wildcards) | 626 if (!allow_wildcards) |
| 623 continue; | 627 continue; |
| 624 | 628 |
| 625 return true; | 629 return true; |
| 626 } | 630 } |
| 627 return false; | 631 return false; |
| 628 } | 632 } |
| 629 | 633 |
| 630 bool X509Certificate::VerifyNameMatch(const std::string& hostname, | 634 bool X509Certificate::VerifyNameMatch(const std::string& hostname, |
| 631 bool* common_name_fallback_used) const { | 635 bool allow_common_name_fallback) const { |
| 632 std::vector<std::string> dns_names, ip_addrs; | 636 std::vector<std::string> dns_names, ip_addrs; |
| 633 GetSubjectAltName(&dns_names, &ip_addrs); | 637 GetSubjectAltName(&dns_names, &ip_addrs); |
| 634 return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs, | 638 return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs, |
| 635 common_name_fallback_used); | 639 allow_common_name_fallback); |
| 636 } | 640 } |
| 637 | 641 |
| 638 // static | 642 // static |
| 639 bool X509Certificate::GetPEMEncodedFromDER(const std::string& der_encoded, | 643 bool X509Certificate::GetPEMEncodedFromDER(const std::string& der_encoded, |
| 640 std::string* pem_encoded) { | 644 std::string* pem_encoded) { |
| 641 if (der_encoded.empty()) | 645 if (der_encoded.empty()) |
| 642 return false; | 646 return false; |
| 643 std::string b64_encoded; | 647 std::string b64_encoded; |
| 644 base::Base64Encode(der_encoded, &b64_encoded); | 648 base::Base64Encode(der_encoded, &b64_encoded); |
| 645 *pem_encoded = "-----BEGIN CERTIFICATE-----\n"; | 649 *pem_encoded = "-----BEGIN CERTIFICATE-----\n"; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 RemoveFromCache(cert_handle_); | 719 RemoveFromCache(cert_handle_); |
| 716 FreeOSCertHandle(cert_handle_); | 720 FreeOSCertHandle(cert_handle_); |
| 717 } | 721 } |
| 718 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | 722 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { |
| 719 RemoveFromCache(intermediate_ca_certs_[i]); | 723 RemoveFromCache(intermediate_ca_certs_[i]); |
| 720 FreeOSCertHandle(intermediate_ca_certs_[i]); | 724 FreeOSCertHandle(intermediate_ca_certs_[i]); |
| 721 } | 725 } |
| 722 } | 726 } |
| 723 | 727 |
| 724 } // namespace net | 728 } // namespace net |
| OLD | NEW |