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

Unified Diff: net/cert/cert_verify_proc_nss.cc

Issue 1724413002: Perform CRLSet evaluation during Path Building on NSS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/cert_verify_proc_nss.cc
diff --git a/net/cert/cert_verify_proc_nss.cc b/net/cert/cert_verify_proc_nss.cc
index ca8e8116f0ef521f61539386abbc59dd57da2f21..9db660bb9c9d5ddf733c0f74d98f2e91b3fe33e0 100644
--- a/net/cert/cert_verify_proc_nss.cc
+++ b/net/cert/cert_verify_proc_nss.cc
@@ -279,7 +279,7 @@ enum CRLSetResult {
// that some EV sites would otherwise take the hit of an OCSP lookup for
// no reason.
// kCRLSetOk: otherwise.
-CRLSetResult CheckRevocationWithCRLSet(CERTCertList* cert_list,
+CRLSetResult CheckRevocationWithCRLSet(const CERTCertList* cert_list,
CERTCertificate* root,
CRLSet* crl_set) {
std::vector<CERTCertificate*> certs;
@@ -352,6 +352,64 @@ CRLSetResult CheckRevocationWithCRLSet(CERTCertList* cert_list,
return kCRLSetOk;
}
+scoped_refptr<X509Certificate> CreateCertFromCERTList(
+ const CERTCertList* cert_list) {
+ X509Certificate::OSCertHandles intermediates;
+ for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
+ !CERT_LIST_END(node, cert_list); node = CERT_LIST_NEXT(node)) {
+ intermediates.push_back(node->cert);
+ }
+ if (intermediates.empty())
+ return nullptr;
+
+ X509Certificate::OSCertHandle leaf = intermediates.front();
+ intermediates.erase(intermediates.begin());
eroman 2016/02/25 03:12:02 Could have avoided the erase().
Ryan Sleevi 2016/03/01 22:44:57 I'm not sure your remark here, or what you're sugg
eroman 2016/03/02 00:05:07 In the construction of intermediates vector above,
+#if defined(OS_IOS)
+ return x509_util_ios::CreateCertFromNSSHandles(leaf, intermediates);
+#else
+ return X509Certificate::CreateFromHandle(leaf, intermediates);
+#endif
+}
+
+// Arguments for CheckChainRevocationWithCRLSet that are curried within the
+// CERTChainVerifyCallback's isChainValidArg.
+struct CheckChainRevocationArgs {
+ CRLSet* crl_set;
+ CERTChainVerifyCallback* next_callback;
+ scoped_refptr<X509Certificate> revoked_chain;
+};
+
+SECStatus CheckChainRevocationWithCRLSet(void* is_chain_valid_arg,
+ const CERTCertList* current_chain,
+ PRBool* chain_ok) {
+ if (!is_chain_valid_arg) {
eroman 2016/02/25 03:12:02 Is this actually reachable?
Ryan Sleevi 2016/03/01 22:44:57 It's NSS; the guarantees the API provides are undo
+ *chain_ok = PR_FALSE;
+ return SECFailure;
+ }
+
+ CheckChainRevocationArgs* args =
+ static_cast<CheckChainRevocationArgs*>(is_chain_valid_arg);
+
+ CRLSetResult crlset_result = kCRLSetUnknown;
+ if (args->crl_set)
eroman 2016/02/25 03:12:01 curlies
+ crlset_result =
+ CheckRevocationWithCRLSet(current_chain, nullptr, args->crl_set);
+
+ if (crlset_result == kCRLSetRevoked) {
+ args->revoked_chain = CreateCertFromCERTList(current_chain);
+ *chain_ok = PR_FALSE;
+ return SECSuccess;
+ }
+ args->revoked_chain = nullptr;
+
+ *chain_ok = PR_TRUE;
+ if (!args->next_callback || !args->next_callback->isChainValid)
eroman 2016/02/25 03:12:02 Is it expected that isChainValid can be NULL, or i
Ryan Sleevi 2016/03/01 22:44:57 Yes, it is; this matches the internal checks of NS
+ return SECSuccess;
+
+ return (*args->next_callback->isChainValid)(
+ args->next_callback->isChainValidArg, current_chain, chain_ok);
+}
+
// Forward declarations.
SECStatus RetryPKIXVerifyCertWithWorkarounds(
CERTCertificate* cert_handle, int num_policy_oids,
@@ -825,6 +883,17 @@ int CertVerifyProcNSS::VerifyInternalImpl(
verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
}
+ CheckChainRevocationArgs check_chain_revocation_args;
+ check_chain_revocation_args.crl_set = crl_set;
+ check_chain_revocation_args.next_callback = chain_verify_callback;
+ check_chain_revocation_args.revoked_chain = nullptr;
eroman 2016/02/25 03:12:01 could have omitted this unless you are trying to b
Ryan Sleevi 2016/03/01 22:44:58 crl_set and next_callback are pointer types; they
eroman 2016/03/02 00:05:07 I was referring to revoked_chain, which is a scope
+
+ CERTChainVerifyCallback crlset_callback;
+ memset(&crlset_callback, 0, sizeof(crlset_callback));
+ crlset_callback.isChainValid = &CheckChainRevocationWithCRLSet;
+ crlset_callback.isChainValidArg =
+ static_cast<void*>(&check_chain_revocation_args);
+
// Make sure that the cert is valid now.
SECCertTimeValidity validity = CERT_CheckCertValidTimes(
cert_handle, PR_Now(), PR_TRUE);
@@ -862,15 +931,9 @@ int CertVerifyProcNSS::VerifyInternalImpl(
CertificateListToCERTCertList(additional_trust_anchors));
}
- SECStatus status = PKIXVerifyCert(cert_handle,
- check_revocation,
- false,
- cert_io_enabled,
- NULL,
- 0,
- trust_anchors.get(),
- chain_verify_callback,
- cvout);
+ SECStatus status =
+ PKIXVerifyCert(cert_handle, check_revocation, false, cert_io_enabled,
+ NULL, 0, trust_anchors.get(), &crlset_callback, cvout);
if (status == SECSuccess &&
(flags & CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS) &&
@@ -880,15 +943,8 @@ int CertVerifyProcNSS::VerifyInternalImpl(
// NSS tests for that feature.
scoped_cvout.Clear();
verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
- status = PKIXVerifyCert(cert_handle,
- true,
- true,
- cert_io_enabled,
- NULL,
- 0,
- trust_anchors.get(),
- chain_verify_callback,
- cvout);
+ status = PKIXVerifyCert(cert_handle, true, true, cert_io_enabled, NULL, 0,
+ trust_anchors.get(), &crlset_callback, cvout);
}
if (status == SECSuccess) {
@@ -910,13 +966,20 @@ int CertVerifyProcNSS::VerifyInternalImpl(
CRLSetResult crl_set_result = kCRLSetUnknown;
if (crl_set) {
- crl_set_result = CheckRevocationWithCRLSet(
- cvout[cvout_cert_list_index].value.pointer.chain,
- cvout[cvout_trust_anchor_index].value.pointer.cert,
- crl_set);
- if (crl_set_result == kCRLSetRevoked) {
+ if (status == SECSuccess) {
+ crl_set_result = CheckRevocationWithCRLSet(
eroman 2016/02/25 03:12:02 Wasn't this already called by PKIXVerifyCert() on
Ryan Sleevi 2016/03/01 22:44:57 As with the Windows code, we're taking a defense i
+ cvout[cvout_cert_list_index].value.pointer.chain,
+ cvout[cvout_trust_anchor_index].value.pointer.cert, crl_set);
+ if (crl_set_result == kCRLSetRevoked) {
+ PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
+ status = SECFailure;
+ }
+ } else if (PORT_GetError() == SEC_ERROR_APPLICATION_CALLBACK_ERROR &&
+ check_chain_revocation_args.revoked_chain) {
eroman 2016/02/25 03:12:02 It doesn't look like the revoked_chain is every co
Ryan Sleevi 2016/03/01 22:44:58 You're right; I was originally going to sub in the
+ // If a CRLSet was supplied, and the error was an application callback
+ // error, then it was directed through the CRLSet code and that
+ // particular chain was revoked.
PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
- status = SECFailure;
}
}
@@ -949,14 +1012,8 @@ int CertVerifyProcNSS::VerifyInternalImpl(
if (check_revocation)
verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
- if (VerifyEV(cert_handle,
- flags,
- crl_set,
- check_revocation,
- metadata,
- ev_policy_oid,
- trust_anchors.get(),
- chain_verify_callback)) {
+ if (VerifyEV(cert_handle, flags, crl_set, check_revocation, metadata,
+ ev_policy_oid, trust_anchors.get(), &crlset_callback)) {
verify_result->cert_status |= CERT_STATUS_IS_EV;
}
}
« 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