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

Unified Diff: net/cert/known_roots_mac.cc

Issue 2833623002: Extract IsKnownRoot() functionality for testing if a certificate is a (Closed)
Patch Set: checkpoint 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/known_roots_mac.cc
diff --git a/net/cert/known_roots_mac.cc b/net/cert/known_roots_mac.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b17e17c21da6feca80be8a08a77cafc0d2a8923d
--- /dev/null
+++ b/net/cert/known_roots_mac.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2017 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/cert/known_roots_mac.h"
+
+#include <Security/Security.h>
+
+#include <set>
+
+#include "base/lazy_instance.h"
+#include "base/sha1.h"
mattm 2017/04/20 02:14:12 unnecessary?
eroman 2017/04/20 17:30:59 Done.
+#include "crypto/mac_security_services_lock.h"
+#include "crypto/sha2.h"
mattm 2017/04/20 02:14:12 unnecessary?
eroman 2017/04/20 17:30:59 Done.
+#include "net/cert/x509_util_mac.h"
+
+using base::ScopedCFTypeRef;
+
+namespace net {
+
+namespace {
+
+// Helper class for managing the set of OS X Known Roots. This is only safe
+// to initialize while the crypto::GetMacSecurityServicesLock() is held, due
+// to calling into Security.framework functions; however, once initialized,
+// it can be called at any time.
+// In practice, due to lazy initialization, it's best to just always guard
+// accesses with the lock.
+class OSXKnownRootHelper {
+ public:
+ bool IsKnownRoot(SecCertificateRef cert) {
+ // If there are no known roots, then an API failure occurred. For safety,
+ // assume that all certificates are issued by known roots.
+ if (known_roots_.empty())
+ return true;
+
+ SHA256HashValue hash = x509_util::CalculateFingerprint256(cert);
+ return known_roots_.find(hash) != known_roots_.end();
+ }
+
+ private:
+ friend struct base::LazyInstanceTraitsBase<OSXKnownRootHelper>;
+
+ OSXKnownRootHelper() {
+ crypto::GetMacSecurityServicesLock().AssertAcquired();
+
+ CFArrayRef cert_array = NULL;
+ OSStatus rv = SecTrustSettingsCopyCertificates(
+ kSecTrustSettingsDomainSystem, &cert_array);
+ if (rv != noErr) {
+ LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are "
+ << "trusted! Error " << rv;
+ return;
+ }
+ base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array);
+ for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) {
+ SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
+ const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i)));
+ known_roots_.insert(x509_util::CalculateFingerprint256(cert));
+ }
+ }
+
+ ~OSXKnownRootHelper() {}
+
+ std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_;
+};
+
+base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+bool IsKnownRoot(SecCertificateRef cert) {
+ return g_known_roots.Get().IsKnownRoot(cert);
+}
+
+void InitializeKnownRoots() {
+ base::AutoLock lock(crypto::GetMacSecurityServicesLock());
+ g_known_roots.Get();
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698