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

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

Issue 1762923002: Revert of Perform CRLSet evaluation during Path Building on NSS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 | « no previous file | net/cert/cert_verify_proc_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/cert_verify_proc_nss.h" 5 #include "net/cert/cert_verify_proc_nss.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include <cert.h> 10 #include <cert.h>
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 // kCRLSetRevoked: if any element of the chain is known to have been revoked. 272 // kCRLSetRevoked: if any element of the chain is known to have been revoked.
273 // kCRLSetUnknown: if there is no fresh information about the leaf 273 // kCRLSetUnknown: if there is no fresh information about the leaf
274 // certificate in the chain or if the CRLSet has expired. 274 // certificate in the chain or if the CRLSet has expired.
275 // 275 //
276 // Only the leaf certificate is considered for coverage because some 276 // Only the leaf certificate is considered for coverage because some
277 // intermediates have CRLs with no revocations (after filtering) and 277 // intermediates have CRLs with no revocations (after filtering) and
278 // those CRLs are pruned from the CRLSet at generation time. This means 278 // those CRLs are pruned from the CRLSet at generation time. This means
279 // that some EV sites would otherwise take the hit of an OCSP lookup for 279 // that some EV sites would otherwise take the hit of an OCSP lookup for
280 // no reason. 280 // no reason.
281 // kCRLSetOk: otherwise. 281 // kCRLSetOk: otherwise.
282 CRLSetResult CheckRevocationWithCRLSet(const CERTCertList* cert_list, 282 CRLSetResult CheckRevocationWithCRLSet(CERTCertList* cert_list,
283 CERTCertificate* root, 283 CERTCertificate* root,
284 CRLSet* crl_set) { 284 CRLSet* crl_set) {
285 std::vector<CERTCertificate*> certs; 285 std::vector<CERTCertificate*> certs;
286 286
287 if (cert_list) { 287 if (cert_list) {
288 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); 288 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
289 !CERT_LIST_END(node, cert_list); 289 !CERT_LIST_END(node, cert_list);
290 node = CERT_LIST_NEXT(node)) { 290 node = CERT_LIST_NEXT(node)) {
291 certs.push_back(node->cert); 291 certs.push_back(node->cert);
292 } 292 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 error = true; 345 error = true;
346 continue; 346 continue;
347 } 347 }
348 } 348 }
349 349
350 if (error || !last_covered || crl_set->IsExpired()) 350 if (error || !last_covered || crl_set->IsExpired())
351 return kCRLSetUnknown; 351 return kCRLSetUnknown;
352 return kCRLSetOk; 352 return kCRLSetOk;
353 } 353 }
354 354
355 // Arguments for CheckChainRevocationWithCRLSet that are curried within the
356 // CERTChainVerifyCallback's isChainValidArg.
357 struct CheckChainRevocationArgs {
358 // The CRLSet to evaluate against.
359 CRLSet* crl_set = nullptr;
360
361 // The next callback to invoke, if the CRLSet does not report any errors.
362 CERTChainVerifyCallback* next_callback = nullptr;
363
364 // Indicates that the application callback failure was due to a CRLSet
365 // revocation, rather than due to |next_callback| rejecting it. This is
366 // used to map the error back to the proper caller-visible error code.
367 bool was_revoked = false;
368 };
369
370 SECStatus CheckChainRevocationWithCRLSet(void* is_chain_valid_arg,
371 const CERTCertList* current_chain,
372 PRBool* chain_ok) {
373 CHECK(is_chain_valid_arg);
374
375 CheckChainRevocationArgs* args =
376 static_cast<CheckChainRevocationArgs*>(is_chain_valid_arg);
377
378 CRLSetResult crlset_result = kCRLSetUnknown;
379 if (args->crl_set) {
380 crlset_result =
381 CheckRevocationWithCRLSet(current_chain, nullptr, args->crl_set);
382 }
383
384 if (crlset_result == kCRLSetRevoked) {
385 args->was_revoked = true;
386 *chain_ok = PR_FALSE;
387 return SECSuccess;
388 }
389 args->was_revoked = false;
390
391 *chain_ok = PR_TRUE;
392 if (!args->next_callback || !args->next_callback->isChainValid)
393 return SECSuccess;
394
395 return (*args->next_callback->isChainValid)(
396 args->next_callback->isChainValidArg, current_chain, chain_ok);
397 }
398
399 // Forward declarations. 355 // Forward declarations.
400 SECStatus RetryPKIXVerifyCertWithWorkarounds( 356 SECStatus RetryPKIXVerifyCertWithWorkarounds(
401 CERTCertificate* cert_handle, int num_policy_oids, 357 CERTCertificate* cert_handle, int num_policy_oids,
402 bool cert_io_enabled, std::vector<CERTValInParam>* cvin, 358 bool cert_io_enabled, std::vector<CERTValInParam>* cvin,
403 CERTValOutParam* cvout); 359 CERTValOutParam* cvout);
404 SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle); 360 SECOidTag GetFirstCertPolicy(CERTCertificate* cert_handle);
405 361
406 // Call CERT_PKIXVerifyCert for the cert_handle. 362 // Call CERT_PKIXVerifyCert for the cert_handle.
407 // Verification results are stored in an array of CERTValOutParam. 363 // Verification results are stored in an array of CERTValOutParam.
408 // If |hard_fail| is true, and no policy_oids are supplied (eg: EV is NOT being 364 // If |hard_fail| is true, and no policy_oids are supplied (eg: EV is NOT being
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 cache_ocsp_response_from_side_channel_(CERT_GetDefaultCertDB(), cert_handle, 818 cache_ocsp_response_from_side_channel_(CERT_GetDefaultCertDB(), cert_handle,
863 PR_Now(), &ocsp_response_item, 819 PR_Now(), &ocsp_response_item,
864 nullptr); 820 nullptr);
865 } 821 }
866 822
867 if (!cert->VerifyNameMatch(hostname, 823 if (!cert->VerifyNameMatch(hostname,
868 &verify_result->common_name_fallback_used)) { 824 &verify_result->common_name_fallback_used)) {
869 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; 825 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
870 } 826 }
871 827
872 // Setup a callback to call into CheckChainRevocationWithCRLSet with the
873 // current CRLSet. If the CRLSet revokes a given chain, |was_revoked|
874 // will be set to true.
875 // The same callback and args are used for every invocation of
876 // PKIXVerifyCert, as CheckChainRevocationWithCRLSet handles resetting
877 // |was_revoked| as necessary.
878 CheckChainRevocationArgs check_chain_revocation_args;
879 check_chain_revocation_args.crl_set = crl_set;
880 check_chain_revocation_args.next_callback = chain_verify_callback;
881
882 CERTChainVerifyCallback crlset_callback;
883 memset(&crlset_callback, 0, sizeof(crlset_callback));
884 crlset_callback.isChainValid = &CheckChainRevocationWithCRLSet;
885 crlset_callback.isChainValidArg =
886 static_cast<void*>(&check_chain_revocation_args);
887
888 // Make sure that the cert is valid now. 828 // Make sure that the cert is valid now.
889 SECCertTimeValidity validity = CERT_CheckCertValidTimes( 829 SECCertTimeValidity validity = CERT_CheckCertValidTimes(
890 cert_handle, PR_Now(), PR_TRUE); 830 cert_handle, PR_Now(), PR_TRUE);
891 if (validity != secCertTimeValid) 831 if (validity != secCertTimeValid)
892 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; 832 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
893 833
894 CERTValOutParam cvout[3]; 834 CERTValOutParam cvout[3];
895 int cvout_index = 0; 835 int cvout_index = 0;
896 cvout[cvout_index].type = cert_po_certList; 836 cvout[cvout_index].type = cert_po_certList;
897 cvout[cvout_index].value.pointer.chain = NULL; 837 cvout[cvout_index].value.pointer.chain = NULL;
(...skipping 17 matching lines...) Expand all
915 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED); 855 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED);
916 if (check_revocation) 856 if (check_revocation)
917 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 857 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
918 858
919 ScopedCERTCertList trust_anchors; 859 ScopedCERTCertList trust_anchors;
920 if (!additional_trust_anchors.empty()) { 860 if (!additional_trust_anchors.empty()) {
921 trust_anchors.reset( 861 trust_anchors.reset(
922 CertificateListToCERTCertList(additional_trust_anchors)); 862 CertificateListToCERTCertList(additional_trust_anchors));
923 } 863 }
924 864
925 SECStatus status = 865 SECStatus status = PKIXVerifyCert(cert_handle,
926 PKIXVerifyCert(cert_handle, check_revocation, false, cert_io_enabled, 866 check_revocation,
927 NULL, 0, trust_anchors.get(), &crlset_callback, cvout); 867 false,
868 cert_io_enabled,
869 NULL,
870 0,
871 trust_anchors.get(),
872 chain_verify_callback,
873 cvout);
928 874
929 if (status == SECSuccess && 875 if (status == SECSuccess &&
930 (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) && 876 (flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) &&
931 !IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert)) { 877 !IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert)) {
932 // TODO(rsleevi): Optimize this by supplying the constructed chain to 878 // TODO(rsleevi): Optimize this by supplying the constructed chain to
933 // libpkix via cvin. Omitting for now, due to lack of coverage in upstream 879 // libpkix via cvin. Omitting for now, due to lack of coverage in upstream
934 // NSS tests for that feature. 880 // NSS tests for that feature.
935 scoped_cvout.Clear(); 881 scoped_cvout.Clear();
936 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 882 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
937 status = PKIXVerifyCert(cert_handle, true, true, cert_io_enabled, NULL, 0, 883 status = PKIXVerifyCert(cert_handle,
938 trust_anchors.get(), &crlset_callback, cvout); 884 true,
885 true,
886 cert_io_enabled,
887 NULL,
888 0,
889 trust_anchors.get(),
890 chain_verify_callback,
891 cvout);
939 } 892 }
940 893
941 if (status == SECSuccess) { 894 if (status == SECSuccess) {
942 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain, 895 AppendPublicKeyHashes(cvout[cvout_cert_list_index].value.pointer.chain,
943 cvout[cvout_trust_anchor_index].value.pointer.cert, 896 cvout[cvout_trust_anchor_index].value.pointer.cert,
944 &verify_result->public_key_hashes); 897 &verify_result->public_key_hashes);
945 898
946 verify_result->is_issued_by_known_root = 899 verify_result->is_issued_by_known_root =
947 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert); 900 IsKnownRoot(cvout[cvout_trust_anchor_index].value.pointer.cert);
948 verify_result->is_issued_by_additional_trust_anchor = 901 verify_result->is_issued_by_additional_trust_anchor =
949 IsAdditionalTrustAnchor( 902 IsAdditionalTrustAnchor(
950 trust_anchors.get(), 903 trust_anchors.get(),
951 cvout[cvout_trust_anchor_index].value.pointer.cert); 904 cvout[cvout_trust_anchor_index].value.pointer.cert);
952 905
953 GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain, 906 GetCertChainInfo(cvout[cvout_cert_list_index].value.pointer.chain,
954 cvout[cvout_trust_anchor_index].value.pointer.cert, 907 cvout[cvout_trust_anchor_index].value.pointer.cert,
955 verify_result); 908 verify_result);
956 } 909 }
957 910
958 CRLSetResult crl_set_result = kCRLSetUnknown; 911 CRLSetResult crl_set_result = kCRLSetUnknown;
959 if (crl_set) { 912 if (crl_set) {
960 if (status == SECSuccess) { 913 crl_set_result = CheckRevocationWithCRLSet(
961 // Reverify the returned chain; NSS should have already called 914 cvout[cvout_cert_list_index].value.pointer.chain,
962 // CheckChainRevocationWithCRLSet prior to returning, but given the 915 cvout[cvout_trust_anchor_index].value.pointer.cert,
963 // edge cases (self-signed certs that are trusted; cached chains; 916 crl_set);
964 // unreadable code), this is more about defense in depth than 917 if (crl_set_result == kCRLSetRevoked) {
965 // functional necessity.
966 crl_set_result = CheckRevocationWithCRLSet(
967 cvout[cvout_cert_list_index].value.pointer.chain,
968 cvout[cvout_trust_anchor_index].value.pointer.cert, crl_set);
969 if (crl_set_result == kCRLSetRevoked) {
970 PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
971 status = SECFailure;
972 }
973 } else if (PORT_GetError() == SEC_ERROR_APPLICATION_CALLBACK_ERROR &&
974 check_chain_revocation_args.was_revoked) {
975 // If a CRLSet was supplied, and the error was an application callback
976 // error, then it was directed through the CRLSet code and that
977 // particular chain was revoked.
978 PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); 918 PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
919 status = SECFailure;
979 } 920 }
980 } 921 }
981 922
982 if (status != SECSuccess) { 923 if (status != SECSuccess) {
983 int err = PORT_GetError(); 924 int err = PORT_GetError();
984 LOG(ERROR) << "CERT_PKIXVerifyCert for " << hostname 925 LOG(ERROR) << "CERT_PKIXVerifyCert for " << hostname
985 << " failed err=" << err; 926 << " failed err=" << err;
986 // CERT_PKIXVerifyCert rerports the wrong error code for 927 // CERT_PKIXVerifyCert rerports the wrong error code for
987 // expired certificates (NSS bug 491174) 928 // expired certificates (NSS bug 491174)
988 if (err == SEC_ERROR_CERT_NOT_VALID && 929 if (err == SEC_ERROR_CERT_NOT_VALID &&
(...skipping 12 matching lines...) Expand all
1001 return MapCertStatusToNetError(verify_result->cert_status); 942 return MapCertStatusToNetError(verify_result->cert_status);
1002 943
1003 if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate) { 944 if ((flags & CertVerifier::VERIFY_EV_CERT) && is_ev_candidate) {
1004 check_revocation |= 945 check_revocation |=
1005 crl_set_result != kCRLSetOk && 946 crl_set_result != kCRLSetOk &&
1006 cert_io_enabled && 947 cert_io_enabled &&
1007 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY); 948 (flags & CertVerifier::VERIFY_REV_CHECKING_ENABLED_EV_ONLY);
1008 if (check_revocation) 949 if (check_revocation)
1009 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; 950 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
1010 951
1011 if (VerifyEV(cert_handle, flags, crl_set, check_revocation, metadata, 952 if (VerifyEV(cert_handle,
1012 ev_policy_oid, trust_anchors.get(), &crlset_callback)) { 953 flags,
954 crl_set,
955 check_revocation,
956 metadata,
957 ev_policy_oid,
958 trust_anchors.get(),
959 chain_verify_callback)) {
1013 verify_result->cert_status |= CERT_STATUS_IS_EV; 960 verify_result->cert_status |= CERT_STATUS_IS_EV;
1014 } 961 }
1015 } 962 }
1016 963
1017 return OK; 964 return OK;
1018 } 965 }
1019 966
1020 int CertVerifyProcNSS::VerifyInternal( 967 int CertVerifyProcNSS::VerifyInternal(
1021 X509Certificate* cert, 968 X509Certificate* cert,
1022 const std::string& hostname, 969 const std::string& hostname,
1023 const std::string& ocsp_response, 970 const std::string& ocsp_response,
1024 int flags, 971 int flags,
1025 CRLSet* crl_set, 972 CRLSet* crl_set,
1026 const CertificateList& additional_trust_anchors, 973 const CertificateList& additional_trust_anchors,
1027 CertVerifyResult* verify_result) { 974 CertVerifyResult* verify_result) {
1028 return VerifyInternalImpl(cert, hostname, ocsp_response, flags, crl_set, 975 return VerifyInternalImpl(cert, hostname, ocsp_response, flags, crl_set,
1029 additional_trust_anchors, 976 additional_trust_anchors,
1030 NULL, // chain_verify_callback 977 NULL, // chain_verify_callback
1031 verify_result); 978 verify_result);
1032 } 979 }
1033 980
1034 } // namespace net 981 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698