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

Unified Diff: net/base/temporary_root_certs_nss.cc

Issue 4646001: Implement LoadTemporaryRoot for Windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/net/base
Patch Set: Feedback from phajdan.jr and bulach Created 10 years, 1 month 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/base/temporary_root_certs_nss.cc
diff --git a/net/base/temporary_root_certs_nss.cc b/net/base/temporary_root_certs_nss.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3b4c52a189033fdc5f79f33c10126c47ad6c8561
--- /dev/null
+++ b/net/base/temporary_root_certs_nss.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/temporary_root_certs.h"
+
+#include <cert.h>
+
+#include "base/logging.h"
+#include "base/nss_util.h"
+#include "net/base/x509_certificate.h"
+
+namespace net {
+
+class TemporaryRootCerts::TrustEntry {
+ public:
+ TrustEntry(CERTCertificate* certificate, CERTCertTrust trust);
+ TrustEntry(const TrustEntry& entry);
+ ~TrustEntry();
+
+ TrustEntry& operator=(const TrustEntry& entry);
+
+ CERTCertificate* certificate() const { return certificate_; }
+ CERTCertTrust trust() const { return trust_; }
+
+ private:
+ // The temporary root certificate.
+ CERTCertificate* certificate_;
+
+ // The original trust settings, before |certificate_| was manipulated to
+ // be a temporarily trusted root.
+ CERTCertTrust trust_;
+};
+
+TemporaryRootCerts::TrustEntry::TrustEntry(CERTCertificate* certificate,
+ CERTCertTrust trust)
+ : certificate_(CERT_DupCertificate(certificate)),
+ trust_(trust) {}
+
+TemporaryRootCerts::TrustEntry::TrustEntry(const TrustEntry& entry)
wtc 2010/11/16 23:24:01 It seems that this is exactly what the compiler ca
Ryan Sleevi 2010/11/17 09:37:43 My understanding is that the implicitly generated
+ : certificate_(NULL) {
+ *this = entry;
+}
+
+TemporaryRootCerts::TrustEntry::~TrustEntry() {
+ CERT_DestroyCertificate(certificate_);
+}
+
+TemporaryRootCerts::TrustEntry&
+TemporaryRootCerts::TrustEntry::operator=(const TrustEntry& entry) {
+ CERT_DestroyCertificate(certificate_);
+ certificate_ = CERT_DupCertificate(entry.certificate_);
+ trust_ = entry.trust_;
+ return *this;
+}
+
+bool TemporaryRootCerts::Add(X509Certificate* certificate) {
+ if (cert_trust_map_.find(certificate->fingerprint()) !=
+ cert_trust_map_.end())
+ return true;
+
+ // Preserve the original trust bits so that they can be restored when
+ // the certificate is removed.
+ CERTCertTrust nss_trust;
+ SECStatus rv = CERT_GetCertTrust(certificate->os_cert_handle(),
+ &nss_trust);
+ // TODO(rsleevi): Not checking rv because an untrusted (ephemeral) cert
+ // will return SECFailure, rather than initializing an empty trust
+ // structure.
+
+ TrustEntry entry(certificate->os_cert_handle(), nss_trust);
bulach 2010/11/09 16:21:09 could move this further down to 88
Ryan Sleevi 2010/11/17 09:37:43 No, this copies |nss_trust|, which is then modifie
+
+ // Change the trust bits to unconditionally trust this certificate.
+ // TODO(port): remove this const_cast after NSS 3.12.3 is released.
wtc 2010/11/16 23:24:01 Nit: you can remove this TODO comment and the cons
+ rv = CERT_DecodeTrustString(&nss_trust, const_cast<char*>("TCu,Cu,Tu"));
+ if (rv != SECSuccess) {
+ LOG(ERROR) << "Cannot decode certificate trust string.";
+ return false;
+ }
+
+ rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
+ certificate->os_cert_handle(),
+ &nss_trust);
+ if (rv != SECSuccess) {
+ LOG(ERROR) << "Cannot change certificate trust.";
+ return false;
+ }
+
+ cert_trust_map_.insert(std::make_pair(certificate->fingerprint(), entry));
wtc 2010/11/16 23:24:01 Isn't this equivalent to cert_trust_map_[certifi
Ryan Sleevi 2010/11/17 09:37:43 Depends :) Using operator[] for a map<Key, T> forc
+ return true;
+}
+
+void TemporaryRootCerts::Remove(X509Certificate* certificate) {
+ CertTrustMap::iterator it =
+ cert_trust_map_.find(certificate->fingerprint());
+ if (it == cert_trust_map_.end())
+ return;
+
+ CERTCertTrust original_trust = it->second.trust();
+ cert_trust_map_.erase(it);
+
+ CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
+ certificate->os_cert_handle(),
+ &original_trust);
+}
+
+TemporaryRootCerts::TemporaryRootCerts() {
+ base::EnsureNSSInit();
+}
+
+TemporaryRootCerts::~TemporaryRootCerts() {
+ // Restore the certificate trusts to what they were originally.
+ for (CertTrustMap::iterator it = cert_trust_map_.begin();
+ it != cert_trust_map_.end(); ++it) {
+ CERTCertTrust original_trust = it->second.trust();
+ CERT_ChangeCertTrust(CERT_GetDefaultCertDB(),
+ it->second.certificate(),
+ &original_trust);
+ }
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698