Chromium Code Reviews| 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/base/x509_certificate.h" | 5 #include "net/base/x509_certificate.h" |
| 6 | 6 |
| 7 #include <blapi.h> // Implement CalculateChainFingerprint() with NSS. | 7 #include <blapi.h> // Implement CalculateChainFingerprint() with NSS. |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 if (result != CRLSet::REVOKED && !issuer_spki_hash.empty()) | 491 if (result != CRLSet::REVOKED && !issuer_spki_hash.empty()) |
| 492 result = crl_set->CheckSerial(serial, issuer_spki_hash); | 492 result = crl_set->CheckSerial(serial, issuer_spki_hash); |
| 493 | 493 |
| 494 issuer_spki_hash = spki_hash; | 494 issuer_spki_hash = spki_hash; |
| 495 | 495 |
| 496 switch (result) { | 496 switch (result) { |
| 497 case CRLSet::REVOKED: | 497 case CRLSet::REVOKED: |
| 498 return false; | 498 return false; |
| 499 case CRLSet::UNKNOWN: | 499 case CRLSet::UNKNOWN: |
| 500 case CRLSet::GOOD: | 500 case CRLSet::GOOD: |
| 501 case CRLSet::CRL_SET_EXPIRED: | |
|
wtc
2012/03/16 00:33:10
Removing this case means we will hit the NOTREACHE
wtc
2012/03/16 00:34:13
Please ignore this comment. I forgot to remove it
| |
| 502 continue; | 501 continue; |
| 503 default: | 502 default: |
| 504 NOTREACHED(); | 503 NOTREACHED(); |
| 505 continue; | 504 continue; |
| 506 } | 505 } |
| 507 } | 506 } |
| 508 | 507 |
| 509 return true; | 508 return true; |
| 510 } | 509 } |
| 511 | 510 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 szOID_SERVER_GATED_CRYPTO, | 722 szOID_SERVER_GATED_CRYPTO, |
| 724 szOID_SGC_NETSCAPE | 723 szOID_SGC_NETSCAPE |
| 725 }; | 724 }; |
| 726 chain_para.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; | 725 chain_para.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; |
| 727 chain_para.RequestedUsage.Usage.cUsageIdentifier = arraysize(usage); | 726 chain_para.RequestedUsage.Usage.cUsageIdentifier = arraysize(usage); |
| 728 chain_para.RequestedUsage.Usage.rgpszUsageIdentifier = | 727 chain_para.RequestedUsage.Usage.rgpszUsageIdentifier = |
| 729 const_cast<LPSTR*>(usage); | 728 const_cast<LPSTR*>(usage); |
| 730 // We can set CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS to get more chains. | 729 // We can set CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS to get more chains. |
| 731 DWORD chain_flags = CERT_CHAIN_CACHE_END_CERT | | 730 DWORD chain_flags = CERT_CHAIN_CACHE_END_CERT | |
| 732 CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; | 731 CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; |
| 733 if (flags & VERIFY_REV_CHECKING_ENABLED) { | 732 const bool rev_checking_enabled = flags & VERIFY_REV_CHECKING_ENABLED; |
| 733 | |
| 734 if (rev_checking_enabled) { | |
| 734 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; | 735 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; |
| 735 } else { | 736 } else { |
| 736 chain_flags |= CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; | 737 chain_flags |= CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; |
| 737 } | 738 } |
| 738 | 739 |
| 739 // Get the certificatePolicies extension of the certificate. | 740 // Get the certificatePolicies extension of the certificate. |
| 740 scoped_ptr_malloc<CERT_POLICIES_INFO> policies_info; | 741 scoped_ptr_malloc<CERT_POLICIES_INFO> policies_info; |
| 741 LPSTR ev_policy_oid = NULL; | 742 LPSTR ev_policy_oid = NULL; |
| 742 if (flags & VERIFY_EV_CERT) { | 743 if (flags & VERIFY_EV_CERT) { |
| 743 GetCertPoliciesInfo(cert_handle_, &policies_info); | 744 GetCertPoliciesInfo(cert_handle_, &policies_info); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 // statuses from the offline checks so we squash this error. | 909 // statuses from the offline checks so we squash this error. |
| 909 verify_result->cert_status &= ~CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; | 910 verify_result->cert_status &= ~CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; |
| 910 } | 911 } |
| 911 | 912 |
| 912 if (IsCertStatusError(verify_result->cert_status)) | 913 if (IsCertStatusError(verify_result->cert_status)) |
| 913 return MapCertStatusToNetError(verify_result->cert_status); | 914 return MapCertStatusToNetError(verify_result->cert_status); |
| 914 | 915 |
| 915 AppendPublicKeyHashes(chain_context, &verify_result->public_key_hashes); | 916 AppendPublicKeyHashes(chain_context, &verify_result->public_key_hashes); |
| 916 verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(chain_context); | 917 verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(chain_context); |
| 917 | 918 |
| 918 if (ev_policy_oid && CheckEV(chain_context, flags, ev_policy_oid)) | 919 if (ev_policy_oid && |
| 920 CheckEV(chain_context, rev_checking_enabled, ev_policy_oid)) { | |
| 919 verify_result->cert_status |= CERT_STATUS_IS_EV; | 921 verify_result->cert_status |= CERT_STATUS_IS_EV; |
| 922 } | |
| 920 return OK; | 923 return OK; |
| 921 } | 924 } |
| 922 | 925 |
| 923 // static | 926 // static |
| 924 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | 927 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
| 925 std::string* encoded) { | 928 std::string* encoded) { |
| 926 if (!cert_handle->pbCertEncoded || !cert_handle->cbCertEncoded) | 929 if (!cert_handle->pbCertEncoded || !cert_handle->cbCertEncoded) |
| 927 return false; | 930 return false; |
| 928 encoded->assign(reinterpret_cast<char*>(cert_handle->pbCertEncoded), | 931 encoded->assign(reinterpret_cast<char*>(cert_handle->pbCertEncoded), |
| 929 cert_handle->cbCertEncoded); | 932 cert_handle->cbCertEncoded); |
| 930 return true; | 933 return true; |
| 931 } | 934 } |
| 932 | 935 |
| 933 // Returns true if the certificate is an extended-validation certificate. | 936 // Returns true if the certificate is an extended-validation certificate. |
| 934 // | 937 // |
| 935 // This function checks the certificatePolicies extensions of the | 938 // This function checks the certificatePolicies extensions of the |
| 936 // certificates in the certificate chain according to Section 7 (pp. 11-12) | 939 // certificates in the certificate chain according to Section 7 (pp. 11-12) |
| 937 // of the EV Certificate Guidelines Version 1.0 at | 940 // of the EV Certificate Guidelines Version 1.0 at |
| 938 // http://cabforum.org/EV_Certificate_Guidelines.pdf. | 941 // http://cabforum.org/EV_Certificate_Guidelines.pdf. |
| 939 bool X509Certificate::CheckEV(PCCERT_CHAIN_CONTEXT chain_context, | 942 bool X509Certificate::CheckEV(PCCERT_CHAIN_CONTEXT chain_context, |
| 940 int flags, | 943 bool rev_checking_enabled, |
| 941 const char* policy_oid) const { | 944 const char* policy_oid) const { |
| 942 DCHECK_NE(static_cast<DWORD>(0), chain_context->cChain); | 945 DCHECK_NE(static_cast<DWORD>(0), chain_context->cChain); |
| 943 // If the cert doesn't match any of the policies, the | 946 // If the cert doesn't match any of the policies, the |
| 944 // CERT_TRUST_IS_NOT_VALID_FOR_USAGE bit (0x10) in | 947 // CERT_TRUST_IS_NOT_VALID_FOR_USAGE bit (0x10) in |
| 945 // chain_context->TrustStatus.dwErrorStatus is set. | 948 // chain_context->TrustStatus.dwErrorStatus is set. |
| 946 DWORD error_status = chain_context->TrustStatus.dwErrorStatus; | 949 DWORD error_status = chain_context->TrustStatus.dwErrorStatus; |
| 947 | 950 |
| 948 if (!(flags & VERIFY_REV_CHECKING_ENABLED)) { | 951 if (!rev_checking_enabled) { |
| 949 // If online revocation checking is disabled then we will have still | 952 // If online revocation checking is disabled then we will have still |
| 950 // requested that the revocation cache be checked. However, that will often | 953 // requested that the revocation cache be checked. However, that will often |
| 951 // cause the following two error bits to be set. Since they are expected, | 954 // cause the following two error bits to be set. These error bits mean that |
| 952 // we mask them away. | 955 // the local OCSP/CRL is stale or missing entries for these certificates. |
| 956 // Since they are expected, we mask them away. | |
| 953 error_status &= ~(CERT_TRUST_IS_OFFLINE_REVOCATION | | 957 error_status &= ~(CERT_TRUST_IS_OFFLINE_REVOCATION | |
| 954 CERT_TRUST_REVOCATION_STATUS_UNKNOWN); | 958 CERT_TRUST_REVOCATION_STATUS_UNKNOWN); |
| 955 } | 959 } |
| 956 if (!chain_context->cChain || error_status != CERT_TRUST_NO_ERROR) | 960 if (!chain_context->cChain || error_status != CERT_TRUST_NO_ERROR) |
| 957 return false; | 961 return false; |
| 958 | 962 |
| 959 // Check the end certificate simple chain (chain_context->rgpChain[0]). | 963 // Check the end certificate simple chain (chain_context->rgpChain[0]). |
| 960 // If the end certificate's certificatePolicies extension contains the | 964 // If the end certificate's certificatePolicies extension contains the |
| 961 // EV policy OID of the root CA, return true. | 965 // EV policy OID of the root CA, return true. |
| 962 PCERT_CHAIN_ELEMENT* element = chain_context->rgpChain[0]->rgpElement; | 966 PCERT_CHAIN_ELEMENT* element = chain_context->rgpChain[0]->rgpElement; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1137 *type = kPublicKeyTypeECDH; | 1141 *type = kPublicKeyTypeECDH; |
| 1138 break; | 1142 break; |
| 1139 default: | 1143 default: |
| 1140 *type = kPublicKeyTypeUnknown; | 1144 *type = kPublicKeyTypeUnknown; |
| 1141 *size_bits = 0; | 1145 *size_bits = 0; |
| 1142 break; | 1146 break; |
| 1143 } | 1147 } |
| 1144 } | 1148 } |
| 1145 | 1149 |
| 1146 } // namespace net | 1150 } // namespace net |
| OLD | NEW |