Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: net/base/cert_database_win.cc

Issue 2874002: Change the Windows CertDatabase behaviour to match Mac and NSS behaviour, whe... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | net/base/keygen_handler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/cert_database.h" 5 #include "net/base/cert_database.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <wincrypt.h> 8 #include <wincrypt.h>
9 #pragma comment(lib, "crypt32.lib") 9 #pragma comment(lib, "crypt32.lib")
10 10
11 #include "base/logging.h"
12 #include "base/string_util.h"
13 #include "net/base/keygen_handler.h"
14 #include "net/base/net_errors.h" 11 #include "net/base/net_errors.h"
15 #include "net/base/x509_certificate.h" 12 #include "net/base/x509_certificate.h"
16 13
17 namespace net { 14 namespace net {
18 15
19 namespace {
20
21 // Returns an encoded version of SubjectPublicKeyInfo from |cert| that is
22 // compatible with KeygenHandler::Cache. If the cert cannot be converted, an
23 // empty string is returned.
24 std::string GetSubjectPublicKeyInfo(const X509Certificate* cert) {
25 DCHECK(cert);
26
27 std::string result;
28 if (!cert->os_cert_handle() || !cert->os_cert_handle()->pCertInfo)
29 return result;
30
31 BOOL ok;
32 DWORD size = 0;
33 PCERT_PUBLIC_KEY_INFO key_info =
34 &(cert->os_cert_handle()->pCertInfo->SubjectPublicKeyInfo);
35 ok = CryptEncodeObject(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, key_info,
36 NULL, &size);
37 if (!ok)
38 return result;
39
40 ok = CryptEncodeObject(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, key_info,
41 reinterpret_cast<BYTE*>(WriteInto(&result, size + 1)),
42 &size);
43 if (!ok) {
44 result.clear();
45 return result;
46 }
47
48 // Per MSDN, the resultant structure may be smaller than the original size
49 // supplied, so shrink to the actual size output.
50 result.resize(size);
51
52 return result;
53 }
54
55 // Returns true if |cert| was successfully modified to reference |location| to
56 // obtain the associated private key.
57 bool LinkCertToPrivateKey(X509Certificate* cert,
58 KeygenHandler::KeyLocation location) {
59 DCHECK(cert);
60
61 CRYPT_KEY_PROV_INFO prov_info = { 0 };
62 prov_info.pwszContainerName =
63 const_cast<LPWSTR>(location.container_name.c_str());
64 prov_info.pwszProvName =
65 const_cast<LPWSTR>(location.provider_name.c_str());
66
67 // Implicit by it being from KeygenHandler, which only supports RSA keys.
68 prov_info.dwProvType = PROV_RSA_FULL;
69 prov_info.dwKeySpec = AT_KEYEXCHANGE;
70
71 BOOL ok = CertSetCertificateContextProperty(cert->os_cert_handle(),
72 CERT_KEY_PROV_INFO_PROP_ID, 0,
73 &prov_info);
74 return ok != FALSE;
75 }
76
77 } // namespace
78
79 CertDatabase::CertDatabase() { 16 CertDatabase::CertDatabase() {
80 } 17 }
81 18
82 int CertDatabase::CheckUserCert(X509Certificate* cert) { 19 int CertDatabase::CheckUserCert(X509Certificate* cert) {
83 if (!cert) 20 if (!cert)
84 return ERR_CERT_INVALID; 21 return ERR_CERT_INVALID;
85 if (cert->HasExpired()) 22 if (cert->HasExpired())
86 return ERR_CERT_DATE_INVALID; 23 return ERR_CERT_DATE_INVALID;
87 24
88 std::string encoded_info = GetSubjectPublicKeyInfo(cert); 25 // TODO(rsleevi): Should CRYPT_FIND_SILENT_KEYSET_FLAG be specified? A UI
89 KeygenHandler::Cache* cache = KeygenHandler::Cache::GetInstance(); 26 // may be shown here / this call may block.
90 KeygenHandler::KeyLocation location; 27 if (!CryptFindCertificateKeyProvInfo(cert->os_cert_handle(), 0, NULL))
91
92 if (encoded_info.empty() || !cache->Find(encoded_info, &location) ||
93 !LinkCertToPrivateKey(cert, location))
94 return ERR_NO_PRIVATE_KEY_FOR_CERT; 28 return ERR_NO_PRIVATE_KEY_FOR_CERT;
95 29
96 return OK; 30 return OK;
97 } 31 }
98 32
99 int CertDatabase::AddUserCert(X509Certificate* cert) { 33 int CertDatabase::AddUserCert(X509Certificate* cert) {
100 // TODO(rsleevi): Would it be more appropriate to have the CertDatabase take 34 // TODO(rsleevi): Would it be more appropriate to have the CertDatabase take
101 // construction parameters (Keychain filepath on Mac OS X, PKCS #11 slot on 35 // construction parameters (Keychain filepath on Mac OS X, PKCS #11 slot on
102 // NSS, and Store Type / Path) here? For now, certs will be stashed into the 36 // NSS, and Store Type / Path) here? For now, certs will be stashed into the
103 // user's personal store, which will not automatically mark them as trusted, 37 // user's personal store, which will not automatically mark them as trusted,
104 // but will allow them to be used for client auth. 38 // but will allow them to be used for client auth.
105 HCERTSTORE cert_db = CertOpenSystemStore(NULL, L"MY"); 39 HCERTSTORE cert_db = CertOpenSystemStore(NULL, L"MY");
106 if (!cert_db) 40 if (!cert_db)
107 return ERR_ADD_USER_CERT_FAILED; 41 return ERR_ADD_USER_CERT_FAILED;
108 42
109 BOOL added = CertAddCertificateContextToStore(cert_db, 43 BOOL added = CertAddCertificateContextToStore(cert_db,
110 cert->os_cert_handle(), 44 cert->os_cert_handle(),
111 CERT_STORE_ADD_USE_EXISTING, 45 CERT_STORE_ADD_USE_EXISTING,
112 NULL); 46 NULL);
113 47
114 CertCloseStore(cert_db, 0); 48 CertCloseStore(cert_db, 0);
115 49
116 if (!added) 50 if (!added)
117 return ERR_ADD_USER_CERT_FAILED; 51 return ERR_ADD_USER_CERT_FAILED;
118 52
119 return OK; 53 return OK;
120 } 54 }
121 55
122 } // namespace net 56 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/base/keygen_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698