| // Copyright (c) 2011 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/synchronization/lock.h" |
| #include "crypto/mac_security_services_lock.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/x509_certificate.h" |
| |
| namespace net { |
| |
| CertDatabase::CertDatabase() { |
| } |
| |
| 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) { |
| LOG(ERROR) << "CertDatabase couldn't find private key for user cert"; |
| 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::NotifyObserversOfUserCertAdded(cert); |
| // Fall through. |
| case errSecDuplicateItem: |
| return OK; |
| default: |
| LOG(ERROR) << "CertDatabase failed to add cert to keychain: " << err; |
| // TODO(snej): Map the error code more intelligently. |
| return ERR_ADD_USER_CERT_FAILED; |
| } |
| } |
| |
| } // namespace net |