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

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

Issue 22893021: Normalize certificate name verification across all platforms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 7 years, 4 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 | Annotate | Revision Log
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/cert_verify_proc_win.h" 5 #include "net/cert/cert_verify_proc_win.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 // Flag certificates that have a Subject common name with a NULL character. 720 // Flag certificates that have a Subject common name with a NULL character.
721 if (CertSubjectCommonNameHasNull(cert_handle)) 721 if (CertSubjectCommonNameHasNull(cert_handle))
722 verify_result->cert_status |= CERT_STATUS_INVALID; 722 verify_result->cert_status |= CERT_STATUS_INVALID;
723 723
724 std::wstring wstr_hostname = ASCIIToWide(hostname); 724 std::wstring wstr_hostname = ASCIIToWide(hostname);
725 725
726 SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para; 726 SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para;
727 memset(&extra_policy_para, 0, sizeof(extra_policy_para)); 727 memset(&extra_policy_para, 0, sizeof(extra_policy_para));
728 extra_policy_para.cbSize = sizeof(extra_policy_para); 728 extra_policy_para.cbSize = sizeof(extra_policy_para);
729 extra_policy_para.dwAuthType = AUTHTYPE_SERVER; 729 extra_policy_para.dwAuthType = AUTHTYPE_SERVER;
730 extra_policy_para.fdwChecks = 0; 730 // Certificate name validation happens separately, later, using an internal
731 // routine that has better support for RFC 6125 name matching.
732 extra_policy_para.fdwChecks =
733 0x00001000; // SECURITY_FLAG_IGNORE_CERT_CN_INVALID
731 extra_policy_para.pwszServerName = 734 extra_policy_para.pwszServerName =
732 const_cast<wchar_t*>(wstr_hostname.c_str()); 735 const_cast<wchar_t*>(wstr_hostname.c_str());
733 736
734 CERT_CHAIN_POLICY_PARA policy_para; 737 CERT_CHAIN_POLICY_PARA policy_para;
735 memset(&policy_para, 0, sizeof(policy_para)); 738 memset(&policy_para, 0, sizeof(policy_para));
736 policy_para.cbSize = sizeof(policy_para); 739 policy_para.cbSize = sizeof(policy_para);
737 policy_para.dwFlags = 0; 740 policy_para.dwFlags = 0;
738 policy_para.pvExtraPolicyPara = &extra_policy_para; 741 policy_para.pvExtraPolicyPara = &extra_policy_para;
739 742
740 CERT_CHAIN_POLICY_STATUS policy_status; 743 CERT_CHAIN_POLICY_STATUS policy_status;
741 memset(&policy_status, 0, sizeof(policy_status)); 744 memset(&policy_status, 0, sizeof(policy_status));
742 policy_status.cbSize = sizeof(policy_status); 745 policy_status.cbSize = sizeof(policy_status);
743 746
744 if (!CertVerifyCertificateChainPolicy( 747 if (!CertVerifyCertificateChainPolicy(
745 CERT_CHAIN_POLICY_SSL, 748 CERT_CHAIN_POLICY_SSL,
746 chain_context, 749 chain_context,
747 &policy_para, 750 &policy_para,
748 &policy_status)) { 751 &policy_status)) {
749 return MapSecurityError(GetLastError()); 752 return MapSecurityError(GetLastError());
750 } 753 }
751 754
752 if (policy_status.dwError) { 755 if (policy_status.dwError) {
753 verify_result->cert_status |= MapNetErrorToCertStatus( 756 verify_result->cert_status |= MapNetErrorToCertStatus(
754 MapSecurityError(policy_status.dwError)); 757 MapSecurityError(policy_status.dwError));
755
756 // CertVerifyCertificateChainPolicy reports only one error (in
757 // policy_status.dwError) if the certificate has multiple errors.
758 // CertGetCertificateChain doesn't report certificate name mismatch, so
759 // CertVerifyCertificateChainPolicy is the only function that can report
760 // certificate name mismatch.
761 //
762 // To prevent a potential certificate name mismatch from being hidden by
763 // some other certificate error, if we get any other certificate error,
764 // we call CertVerifyCertificateChainPolicy again, ignoring all other
765 // certificate errors. Both extra_policy_para.fdwChecks and
766 // policy_para.dwFlags allow us to ignore certificate errors, so we set
767 // them both.
768 if (policy_status.dwError != CERT_E_CN_NO_MATCH) {
769 const DWORD extra_ignore_flags =
770 0x00000080 | // SECURITY_FLAG_IGNORE_REVOCATION
771 0x00000100 | // SECURITY_FLAG_IGNORE_UNKNOWN_CA
772 0x00002000 | // SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
773 0x00000200; // SECURITY_FLAG_IGNORE_WRONG_USAGE
774 extra_policy_para.fdwChecks = extra_ignore_flags;
775 const DWORD ignore_flags =
776 CERT_CHAIN_POLICY_IGNORE_ALL_NOT_TIME_VALID_FLAGS |
777 CERT_CHAIN_POLICY_IGNORE_INVALID_BASIC_CONSTRAINTS_FLAG |
778 CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG |
779 CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG |
780 CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG |
781 CERT_CHAIN_POLICY_IGNORE_INVALID_POLICY_FLAG |
782 CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS |
783 CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG |
784 CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG |
785 CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG |
786 CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG;
787 policy_para.dwFlags = ignore_flags;
788 if (!CertVerifyCertificateChainPolicy(
789 CERT_CHAIN_POLICY_SSL,
790 chain_context,
791 &policy_para,
792 &policy_status)) {
793 return MapSecurityError(GetLastError());
794 }
795 if (policy_status.dwError) {
796 verify_result->cert_status |= MapNetErrorToCertStatus(
797 MapSecurityError(policy_status.dwError));
798 }
799 }
800 } 758 }
801 759
802 // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be 760 // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be
803 // compatible with WinHTTP, which doesn't report this error (bug 3004). 761 // compatible with WinHTTP, which doesn't report this error (bug 3004).
804 verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM; 762 verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;
805 763
764 // Perform hostname verification independent of
765 // CertVerifyCertificateChainPolicy.
766 if (!cert->VerifyNameMatch(hostname))
767 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
768
806 if (!rev_checking_enabled) { 769 if (!rev_checking_enabled) {
807 // If we didn't do online revocation checking then Windows will report 770 // If we didn't do online revocation checking then Windows will report
808 // CERT_UNABLE_TO_CHECK_REVOCATION unless it had cached OCSP or CRL 771 // CERT_UNABLE_TO_CHECK_REVOCATION unless it had cached OCSP or CRL
809 // information for every certificate. We only want to put up revoked 772 // information for every certificate. We only want to put up revoked
810 // statuses from the offline checks so we squash this error. 773 // statuses from the offline checks so we squash this error.
811 verify_result->cert_status &= ~CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; 774 verify_result->cert_status &= ~CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
812 } 775 }
813 776
814 AppendPublicKeyHashes(chain_context, &verify_result->public_key_hashes); 777 AppendPublicKeyHashes(chain_context, &verify_result->public_key_hashes);
815 verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(chain_context); 778 verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(chain_context);
816 779
817 if (IsCertStatusError(verify_result->cert_status)) 780 if (IsCertStatusError(verify_result->cert_status))
818 return MapCertStatusToNetError(verify_result->cert_status); 781 return MapCertStatusToNetError(verify_result->cert_status);
819 782
820 if (ev_policy_oid && 783 if (ev_policy_oid &&
821 CheckEV(chain_context, rev_checking_enabled, ev_policy_oid)) { 784 CheckEV(chain_context, rev_checking_enabled, ev_policy_oid)) {
822 verify_result->cert_status |= CERT_STATUS_IS_EV; 785 verify_result->cert_status |= CERT_STATUS_IS_EV;
823 } 786 }
824 return OK; 787 return OK;
825 } 788 }
826 789
827 } // namespace net 790 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/cert_verify_proc_unittest.cc ('k') | net/data/ssl/certificates/subjectAltName_sanity_check.pem » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698