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 15 namespace net { 16 CertDatabase()17CertDatabase::CertDatabase() { 18 } 19 CheckUserCert(X509Certificate * cert)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 AddUserCert(X509Certificate * cert)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