Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: net/cert/x509_certificate.cc

Issue 2735733003: Disable commonName matching for certificates (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cert/x509_certificate.h ('k') | net/cert/x509_certificate_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/cert/x509_certificate.h ('k') | net/cert/x509_certificate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698