Home | History | Annotate | Download | only in base
      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 
     17 CertDatabase::CertDatabase() {
     18 }
     19 
     20 int 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 
     43 int 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