| Index: net/base/cert_database_mac.cc
|
| diff --git a/net/base/cert_database_mac.cc b/net/base/cert_database_mac.cc
|
| deleted file mode 100644
|
| index 2d3ef14616efafd12a85d492dbf727fb52ae2171..0000000000000000000000000000000000000000
|
| --- a/net/base/cert_database_mac.cc
|
| +++ /dev/null
|
| @@ -1,172 +0,0 @@
|
| -// Copyright (c) 2012 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/cert_database.h"
|
| -
|
| -#include <Security/Security.h>
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/mac/mac_logging.h"
|
| -#include "base/message_loop.h"
|
| -#include "base/observer_list_threadsafe.h"
|
| -#include "base/process_util.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/synchronization/lock.h"
|
| -#include "crypto/mac_security_services_lock.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/x509_certificate.h"
|
| -
|
| -namespace net {
|
| -
|
| -// Helper that observes events from the Keychain and forwards them to the
|
| -// given CertDatabase.
|
| -class CertDatabase::Notifier {
|
| - public:
|
| - // Creates a new Notifier that will forward Keychain events to |cert_db|.
|
| - // |message_loop| must refer to a thread with an associated CFRunLoop - a
|
| - // TYPE_UI thread. Events will be dispatched from this message loop.
|
| - Notifier(CertDatabase* cert_db, MessageLoop* message_loop)
|
| - : cert_db_(cert_db),
|
| - registered_(false),
|
| - called_shutdown_(false) {
|
| - // Ensure an associated CFRunLoop.
|
| - DCHECK(message_loop->IsType(MessageLoop::TYPE_UI));
|
| - task_runner_ = message_loop->message_loop_proxy();
|
| - task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&Notifier::Init,
|
| - base::Unretained(this)));
|
| - }
|
| -
|
| - // Should be called from the |task_runner_|'s thread. Use Shutdown()
|
| - // to shutdown on arbitrary threads.
|
| - ~Notifier() {
|
| - DCHECK(called_shutdown_);
|
| - // Only unregister from the same thread where registration was performed.
|
| - if (registered_ && task_runner_->RunsTasksOnCurrentThread())
|
| - SecKeychainRemoveCallback(&Notifier::KeychainCallback);
|
| - }
|
| -
|
| - void Shutdown() {
|
| - called_shutdown_ = true;
|
| - if (!task_runner_->DeleteSoon(FROM_HERE, this)) {
|
| - // If the task runner is no longer running, it's safe to just delete
|
| - // the object, since no further events will or can be delivered by
|
| - // Keychain Services.
|
| - delete this;
|
| - }
|
| - }
|
| -
|
| - private:
|
| - void Init() {
|
| - SecKeychainEventMask event_mask =
|
| - kSecKeychainListChangedMask | kSecTrustSettingsChangedEventMask;
|
| - OSStatus status = SecKeychainAddCallback(&Notifier::KeychainCallback,
|
| - event_mask, this);
|
| - if (status == noErr)
|
| - registered_ = true;
|
| - }
|
| -
|
| - // SecKeychainCallback function that receives notifications from securityd
|
| - // and forwards them to the |cert_db_|.
|
| - static OSStatus KeychainCallback(SecKeychainEvent keychain_event,
|
| - SecKeychainCallbackInfo* info,
|
| - void* context);
|
| -
|
| - CertDatabase* const cert_db_;
|
| - scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
| - bool registered_;
|
| - bool called_shutdown_;
|
| -};
|
| -
|
| -// static
|
| -OSStatus CertDatabase::Notifier::KeychainCallback(
|
| - SecKeychainEvent keychain_event,
|
| - SecKeychainCallbackInfo* info,
|
| - void* context) {
|
| - Notifier* that = reinterpret_cast<Notifier*>(context);
|
| -
|
| - if (info->version > SEC_KEYCHAIN_SETTINGS_VERS1) {
|
| - NOTREACHED();
|
| - return errSecWrongSecVersion;
|
| - }
|
| -
|
| - if (info->pid == base::GetCurrentProcId()) {
|
| - // Ignore events generated by the current process, as the assumption is
|
| - // that they have already been handled. This may miss events that
|
| - // originated as a result of spawning native dialogs that allow the user
|
| - // to modify Keychain settings. However, err on the side of missing
|
| - // events rather than sending too many events.
|
| - return errSecSuccess;
|
| - }
|
| -
|
| - switch (keychain_event) {
|
| - case kSecKeychainListChangedEvent:
|
| - case kSecTrustSettingsChangedEvent:
|
| - that->cert_db_->NotifyObserversOfCertTrustChanged(NULL);
|
| - break;
|
| - }
|
| -
|
| - return errSecSuccess;
|
| -}
|
| -
|
| -void CertDatabase::SetMessageLoopForKeychainEvents() {
|
| - // Shutdown will take care to delete the notifier on the right thread.
|
| - if (notifier_.get())
|
| - notifier_.release()->Shutdown();
|
| -
|
| - notifier_.reset(new Notifier(this, MessageLoopForUI::current()));
|
| -}
|
| -
|
| -CertDatabase::CertDatabase()
|
| - : observer_list_(new ObserverListThreadSafe<Observer>) {
|
| -}
|
| -
|
| -CertDatabase::~CertDatabase() {
|
| - // Shutdown will take care to delete the notifier on the right thread.
|
| - if (notifier_.get())
|
| - notifier_.release()->Shutdown();
|
| -}
|
| -
|
| -int CertDatabase::CheckUserCert(X509Certificate* cert) {
|
| - if (!cert)
|
| - return ERR_CERT_INVALID;
|
| - if (cert->HasExpired())
|
| - return ERR_CERT_DATE_INVALID;
|
| -
|
| - // Verify the Keychain already has the corresponding private key:
|
| - SecIdentityRef identity = NULL;
|
| - OSStatus err = SecIdentityCreateWithCertificate(NULL, cert->os_cert_handle(),
|
| - &identity);
|
| - if (err == errSecItemNotFound)
|
| - return ERR_NO_PRIVATE_KEY_FOR_CERT;
|
| -
|
| - if (err != noErr || !identity) {
|
| - // TODO(snej): Map the error code more intelligently.
|
| - return ERR_CERT_INVALID;
|
| - }
|
| -
|
| - CFRelease(identity);
|
| - return OK;
|
| -}
|
| -
|
| -int CertDatabase::AddUserCert(X509Certificate* cert) {
|
| - OSStatus err;
|
| - {
|
| - base::AutoLock locked(crypto::GetMacSecurityServicesLock());
|
| - err = SecCertificateAddToKeychain(cert->os_cert_handle(), NULL);
|
| - }
|
| - switch (err) {
|
| - case noErr:
|
| - CertDatabase::NotifyObserversOfCertAdded(cert);
|
| - // Fall through.
|
| - case errSecDuplicateItem:
|
| - return OK;
|
| - default:
|
| - OSSTATUS_LOG(ERROR, err) << "CertDatabase failed to add cert to keychain";
|
| - // TODO(snej): Map the error code more intelligently.
|
| - return ERR_ADD_USER_CERT_FAILED;
|
| - }
|
| -}
|
| -
|
| -} // namespace net
|
|
|