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

Unified Diff: net/cert/internal/trust_store_nss.cc

Issue 2832703002: Allow the TrustStore interface to return matching intermediates, and identify distrusted certs. (Closed)
Patch Set: address comments Created 3 years, 8 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
Index: net/cert/internal/trust_store_nss.cc
diff --git a/net/cert/internal/trust_store_nss.cc b/net/cert/internal/trust_store_nss.cc
index 0a67939ce47d12d7b4b9ed5c9969fadd0845979f..fb43321e27ba823eb4ade5835f38e7feda8a5681 100644
--- a/net/cert/internal/trust_store_nss.cc
+++ b/net/cert/internal/trust_store_nss.cc
@@ -11,6 +11,7 @@
#include "crypto/nss_util.h"
#include "net/cert/internal/cert_errors.h"
#include "net/cert/internal/parsed_certificate.h"
+#include "net/cert/scoped_nss_types.h"
#include "net/cert/x509_util.h"
// TODO(mattm): structure so that supporting ChromeOS multi-profile stuff is
@@ -24,9 +25,8 @@ TrustStoreNSS::TrustStoreNSS(SECTrustType trust_type)
TrustStoreNSS::~TrustStoreNSS() = default;
-void TrustStoreNSS::FindTrustAnchorsForCert(
- const scoped_refptr<ParsedCertificate>& cert,
- TrustAnchors* out_anchors) const {
+void TrustStoreNSS::SyncGetIssuersOf(const ParsedCertificate* cert,
+ ParsedCertificateList* issuers) {
crypto::EnsureNSSInit();
SECItem name;
@@ -46,31 +46,71 @@ void TrustStoreNSS::FindTrustAnchorsForCert(
for (CERTCertListNode* node = CERT_LIST_HEAD(found_certs);
!CERT_LIST_END(node, found_certs); node = CERT_LIST_NEXT(node)) {
- CERTCertTrust trust;
- if (CERT_GetCertTrust(node->cert, &trust) != SECSuccess)
- continue;
-
- // TODO(mattm): handle explicit distrust (blacklisting)?
- const int ca_trust = CERTDB_TRUSTED_CA;
- if ((SEC_GET_TRUST_FLAGS(&trust, trust_type_) & ca_trust) != ca_trust)
- continue;
-
- CertErrors errors;
- scoped_refptr<ParsedCertificate> anchor_cert = ParsedCertificate::Create(
+ CertErrors parse_errors;
+ scoped_refptr<ParsedCertificate> cur_cert = ParsedCertificate::Create(
x509_util::CreateCryptoBuffer(node->cert->derCert.data,
node->cert->derCert.len),
- {}, &errors);
- if (!anchor_cert) {
+ {}, &parse_errors);
+
+ if (!cur_cert) {
// TODO(crbug.com/634443): return errors better.
LOG(ERROR) << "Error parsing issuer certificate:\n"
- << errors.ToDebugString();
+ << parse_errors.ToDebugString();
continue;
}
- out_anchors->push_back(TrustAnchor::CreateFromCertificateNoConstraints(
- std::move(anchor_cert)));
+ issuers->push_back(std::move(cur_cert));
}
CERT_DestroyCertList(found_certs);
}
+void TrustStoreNSS::GetTrust(const scoped_refptr<ParsedCertificate>& cert,
+ CertificateTrust* out_trust) const {
+ // TODO(eroman): Inefficient -- path building will convert between
+ // CERTCertificate and ParsedCertificate representations multiple times
+ // (when getting the issuers, and again here).
+
+ // Lookup the certificate by Issuer + Serial number. Note that
+ // CERT_FindCertByDERCert() doesn't check for equal DER, just matching issuer
+ // + serial number.
+ SECItem der_cert;
+ der_cert.data = const_cast<uint8_t*>(cert->der_cert().UnsafeData());
+ der_cert.len = cert->der_cert().Length();
+ der_cert.type = siDERCertBuffer;
+ ScopedCERTCertificate nss_matched_cert(
+ CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
+ if (!nss_matched_cert) {
+ *out_trust = CertificateTrust::ForUnspecified();
+ return;
+ }
+
+ // Determine the trustedness of the matched certificate.
+ CERTCertTrust trust;
+ if (CERT_GetCertTrust(nss_matched_cert.get(), &trust) != SECSuccess) {
+ *out_trust = CertificateTrust::ForUnspecified();
+ return;
+ }
+
+ // TODO(eroman): Determine if |nss_matched_cert| is distrusted.
+
+ // Determine if the certificate is a trust anchor.
+ const int ca_trust = CERTDB_TRUSTED_CA;
+ bool is_trusted =
+ (SEC_GET_TRUST_FLAGS(&trust, trust_type_) & ca_trust) == ca_trust;
+
+ // To consider |cert| trusted, need to additionally check that
+ // |cert| is the same as |nss_matched_cert|. This is because the lookup in NSS
+ // was only by issuer + serial number, so could be for a different
+ // SPKI.
+ if (is_trusted &&
+ (cert->der_cert() == der::Input(nss_matched_cert->derCert.data,
+ nss_matched_cert->derCert.len))) {
+ *out_trust = CertificateTrust::ForTrustAnchor();
+ return;
+ }
+
+ *out_trust = CertificateTrust::ForUnspecified();
+ return;
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698