1// Copyright (c) 2010 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 <windows.h>
8#include <wincrypt.h>
9#pragma comment(lib, "crypt32.lib")
10
11#include "net/base/net_errors.h"
12#include "net/base/x509_certificate.h"
13
14namespace net {
15
16CertDatabase::CertDatabase() {
17}
18
19int CertDatabase::CheckUserCert(X509Certificate* cert) {
20  if (!cert)
21    return ERR_CERT_INVALID;
22  if (cert->HasExpired())
23    return ERR_CERT_DATE_INVALID;
24
25  // TODO(rsleevi): Should CRYPT_FIND_SILENT_KEYSET_FLAG be specified? A UI
26  // may be shown here / this call may block.
27  if (!CryptFindCertificateKeyProvInfo(cert->os_cert_handle(), 0, NULL))
28    return ERR_NO_PRIVATE_KEY_FOR_CERT;
29
30  return OK;
31}
32
33int CertDatabase::AddUserCert(X509Certificate* cert) {
34  // TODO(rsleevi): Would it be more appropriate to have the CertDatabase take
35  // construction parameters (Keychain filepath on Mac OS X, PKCS #11 slot on
36  // NSS, and Store Type / Path) here? For now, certs will be stashed into the
37  // user's personal store, which will not automatically mark them as trusted,
38  // but will allow them to be used for client auth.
39  HCERTSTORE cert_db = CertOpenSystemStore(NULL, L"MY");
40  if (!cert_db)
41    return ERR_ADD_USER_CERT_FAILED;
42
43  BOOL added = CertAddCertificateContextToStore(cert_db,
44                                                cert->os_cert_handle(),
45                                                CERT_STORE_ADD_USE_EXISTING,
46                                                NULL);
47
48  CertCloseStore(cert_db, 0);
49
50  if (!added)
51    return ERR_ADD_USER_CERT_FAILED;
52
53  CertDatabase::NotifyObserversOfUserCertAdded(cert);
54  return OK;
55}
56
57}  // namespace net
58