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