• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()17 CertDatabase::CertDatabase() {
18 }
19 
CheckUserCert(X509Certificate * cert)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 
AddUserCert(X509Certificate * cert)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