1// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/base/cert_database.h" 6 7#include <Security/Security.h> 8 9#include "base/logging.h" 10#include "base/synchronization/lock.h" 11#include "crypto/mac_security_services_lock.h" 12#include "net/base/net_errors.h" 13#include "net/base/x509_certificate.h" 14 15namespace net { 16 17CertDatabase::CertDatabase() { 18} 19 20int CertDatabase::CheckUserCert(X509Certificate* cert) { 21 if (!cert) 22 return ERR_CERT_INVALID; 23 if (cert->HasExpired()) 24 return ERR_CERT_DATE_INVALID; 25 26 // Verify the Keychain already has the corresponding private key: 27 SecIdentityRef identity = NULL; 28 OSStatus err = SecIdentityCreateWithCertificate(NULL, cert->os_cert_handle(), 29 &identity); 30 if (err == errSecItemNotFound) { 31 LOG(ERROR) << "CertDatabase couldn't find private key for user cert"; 32 return ERR_NO_PRIVATE_KEY_FOR_CERT; 33 } 34 if (err != noErr || !identity) { 35 // TODO(snej): Map the error code more intelligently. 36 return ERR_CERT_INVALID; 37 } 38 39 CFRelease(identity); 40 return OK; 41} 42 43int CertDatabase::AddUserCert(X509Certificate* cert) { 44 OSStatus err; 45 { 46 base::AutoLock locked(crypto::GetMacSecurityServicesLock()); 47 err = SecCertificateAddToKeychain(cert->os_cert_handle(), NULL); 48 } 49 switch (err) { 50 case noErr: 51 CertDatabase::NotifyObserversOfUserCertAdded(cert); 52 // Fall through. 53 case errSecDuplicateItem: 54 return OK; 55 default: 56 LOG(ERROR) << "CertDatabase failed to add cert to keychain: " << err; 57 // TODO(snej): Map the error code more intelligently. 58 return ERR_ADD_USER_CERT_FAILED; 59 } 60} 61 62} // namespace net 63