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

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

Issue 649763002: git cl format the second third of the net/base directory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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/keygen_handler.h" 5 #include "net/base/keygen_handler.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 #include <rpc.h> 10 #include <rpc.h>
11 #pragma comment(lib, "rpcrt4.lib") 11 #pragma comment(lib, "rpcrt4.lib")
12 12
13 #include <list> 13 #include <list>
14 #include <string> 14 #include <string>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/base64.h" 17 #include "base/base64.h"
18 #include "base/basictypes.h" 18 #include "base/basictypes.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/strings/string_piece.h" 20 #include "base/strings/string_piece.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
23 #include "crypto/capi_util.h" 23 #include "crypto/capi_util.h"
24 #include "crypto/scoped_capi_types.h" 24 #include "crypto/scoped_capi_types.h"
25 25
26
27 namespace net { 26 namespace net {
28 27
29 // Assigns the contents of a CERT_PUBLIC_KEY_INFO structure for the signing 28 // Assigns the contents of a CERT_PUBLIC_KEY_INFO structure for the signing
30 // key in |prov| to |output|. Returns true if encoding was successful. 29 // key in |prov| to |output|. Returns true if encoding was successful.
31 bool GetSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) { 30 bool GetSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
32 BOOL ok; 31 BOOL ok;
33 DWORD size = 0; 32 DWORD size = 0;
34 33
35 // From the private key stored in HCRYPTPROV, obtain the public key, stored 34 // From the private key stored in HCRYPTPROV, obtain the public key, stored
36 // as a CERT_PUBLIC_KEY_INFO structure. Currently, only RSA public keys are 35 // as a CERT_PUBLIC_KEY_INFO structure. Currently, only RSA public keys are
37 // supported. 36 // supported.
38 ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING, 37 ok = CryptExportPublicKeyInfoEx(prov,
39 const_cast<char*>(szOID_RSA_RSA), 0, NULL, 38 AT_KEYEXCHANGE,
40 NULL, &size); 39 X509_ASN_ENCODING,
40 const_cast<char*>(szOID_RSA_RSA),
41 0,
42 NULL,
43 NULL,
44 &size);
41 DCHECK(ok); 45 DCHECK(ok);
42 if (!ok) 46 if (!ok)
43 return false; 47 return false;
44 48
45 output->resize(size); 49 output->resize(size);
46 50
47 PCERT_PUBLIC_KEY_INFO public_key_casted = 51 PCERT_PUBLIC_KEY_INFO public_key_casted =
48 reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&(*output)[0]); 52 reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&(*output)[0]);
49 ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING, 53 ok = CryptExportPublicKeyInfoEx(prov,
50 const_cast<char*>(szOID_RSA_RSA), 0, NULL, 54 AT_KEYEXCHANGE,
51 public_key_casted, &size); 55 X509_ASN_ENCODING,
56 const_cast<char*>(szOID_RSA_RSA),
57 0,
58 NULL,
59 public_key_casted,
60 &size);
52 DCHECK(ok); 61 DCHECK(ok);
53 if (!ok) 62 if (!ok)
54 return false; 63 return false;
55 64
56 output->resize(size); 65 output->resize(size);
57 66
58 return true; 67 return true;
59 } 68 }
60 69
61 // Generates a DER encoded SignedPublicKeyAndChallenge structure from the 70 // Generates a DER encoded SignedPublicKeyAndChallenge structure from the
(...skipping 19 matching lines...) Expand all
81 *reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&spki[0]); 90 *reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&spki[0]);
82 pkac.pwszChallengeString = const_cast<wchar_t*>(wide_challenge.c_str()); 91 pkac.pwszChallengeString = const_cast<wchar_t*>(wide_challenge.c_str());
83 92
84 CRYPT_ALGORITHM_IDENTIFIER sig_alg; 93 CRYPT_ALGORITHM_IDENTIFIER sig_alg;
85 memset(&sig_alg, 0, sizeof(sig_alg)); 94 memset(&sig_alg, 0, sizeof(sig_alg));
86 sig_alg.pszObjId = const_cast<char*>(szOID_RSA_MD5RSA); 95 sig_alg.pszObjId = const_cast<char*>(szOID_RSA_MD5RSA);
87 96
88 BOOL ok; 97 BOOL ok;
89 DWORD size = 0; 98 DWORD size = 0;
90 std::vector<BYTE> signed_pkac; 99 std::vector<BYTE> signed_pkac;
91 ok = CryptSignAndEncodeCertificate(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING, 100 ok = CryptSignAndEncodeCertificate(prov,
101 AT_KEYEXCHANGE,
102 X509_ASN_ENCODING,
92 X509_KEYGEN_REQUEST_TO_BE_SIGNED, 103 X509_KEYGEN_REQUEST_TO_BE_SIGNED,
93 &pkac, &sig_alg, NULL, 104 &pkac,
94 NULL, &size); 105 &sig_alg,
106 NULL,
107 NULL,
108 &size);
95 DCHECK(ok); 109 DCHECK(ok);
96 if (!ok) 110 if (!ok)
97 return false; 111 return false;
98 112
99 signed_pkac.resize(size); 113 signed_pkac.resize(size);
100 ok = CryptSignAndEncodeCertificate(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING, 114 ok = CryptSignAndEncodeCertificate(prov,
115 AT_KEYEXCHANGE,
116 X509_ASN_ENCODING,
101 X509_KEYGEN_REQUEST_TO_BE_SIGNED, 117 X509_KEYGEN_REQUEST_TO_BE_SIGNED,
102 &pkac, &sig_alg, NULL, 118 &pkac,
103 &signed_pkac[0], &size); 119 &sig_alg,
120 NULL,
121 &signed_pkac[0],
122 &size);
104 DCHECK(ok); 123 DCHECK(ok);
105 if (!ok) 124 if (!ok)
106 return false; 125 return false;
107 126
108 output->assign(reinterpret_cast<char*>(&signed_pkac[0]), size); 127 output->assign(reinterpret_cast<char*>(&signed_pkac[0]), size);
109 return true; 128 return true;
110 } 129 }
111 130
112 // Generates a unique name for the container which will store the key that is 131 // Generates a unique name for the container which will store the key that is
113 // generated. The traditional Windows approach is to use a GUID here. 132 // generated. The traditional Windows approach is to use a GUID here.
114 std::wstring GetNewKeyContainerId() { 133 std::wstring GetNewKeyContainerId() {
115 RPC_STATUS status = RPC_S_OK; 134 RPC_STATUS status = RPC_S_OK;
116 std::wstring result; 135 std::wstring result;
117 136
118 UUID id = { 0 }; 137 UUID id = {0};
119 status = UuidCreateSequential(&id); 138 status = UuidCreateSequential(&id);
120 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) 139 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY)
121 return result; 140 return result;
122 141
123 RPC_WSTR rpc_string = NULL; 142 RPC_WSTR rpc_string = NULL;
124 status = UuidToString(&id, &rpc_string); 143 status = UuidToString(&id, &rpc_string);
125 if (status != RPC_S_OK) 144 if (status != RPC_S_OK)
126 return result; 145 return result;
127 146
128 // RPC_WSTR is unsigned short*. wchar_t is a built-in type of Visual C++, 147 // RPC_WSTR is unsigned short*. wchar_t is a built-in type of Visual C++,
129 // so the type cast is necessary. 148 // so the type cast is necessary.
130 result.assign(reinterpret_cast<wchar_t*>(rpc_string)); 149 result.assign(reinterpret_cast<wchar_t*>(rpc_string));
131 RpcStringFree(&rpc_string); 150 RpcStringFree(&rpc_string);
132 151
133 return result; 152 return result;
134 } 153 }
135 154
136 // This is a helper struct designed to optionally delete a key after releasing 155 // This is a helper struct designed to optionally delete a key after releasing
137 // the associated provider. 156 // the associated provider.
138 struct KeyContainer { 157 struct KeyContainer {
139 public: 158 public:
140 explicit KeyContainer(bool delete_keyset) 159 explicit KeyContainer(bool delete_keyset) : delete_keyset_(delete_keyset) {}
141 : delete_keyset_(delete_keyset) {}
142 160
143 ~KeyContainer() { 161 ~KeyContainer() {
144 if (provider_) { 162 if (provider_) {
145 provider_.reset(); 163 provider_.reset();
146 if (delete_keyset_ && !key_id_.empty()) { 164 if (delete_keyset_ && !key_id_.empty()) {
147 HCRYPTPROV provider; 165 HCRYPTPROV provider;
148 crypto::CryptAcquireContextLocked(&provider, key_id_.c_str(), NULL, 166 crypto::CryptAcquireContextLocked(&provider,
149 PROV_RSA_FULL, CRYPT_SILENT | CRYPT_DELETEKEYSET); 167 key_id_.c_str(),
168 NULL,
169 PROV_RSA_FULL,
170 CRYPT_SILENT | CRYPT_DELETEKEYSET);
150 } 171 }
151 } 172 }
152 } 173 }
153 174
154 crypto::ScopedHCRYPTPROV provider_; 175 crypto::ScopedHCRYPTPROV provider_;
155 std::wstring key_id_; 176 std::wstring key_id_;
156 177
157 private: 178 private:
158 bool delete_keyset_; 179 bool delete_keyset_;
159 }; 180 };
(...skipping 12 matching lines...) Expand all
172 // creating their own keys, they should ensure unique naming schemes to 193 // creating their own keys, they should ensure unique naming schemes to
173 // prevent overlap with any other applications or consumers of CSPs, and 194 // prevent overlap with any other applications or consumers of CSPs, and
174 // *should not* store new keys within the default, NULL key container. 195 // *should not* store new keys within the default, NULL key container.
175 key_container.key_id_ = GetNewKeyContainerId(); 196 key_container.key_id_ = GetNewKeyContainerId();
176 if (key_container.key_id_.empty()) 197 if (key_container.key_id_.empty())
177 return std::string(); 198 return std::string();
178 199
179 // Only create new key containers, so that existing key containers are not 200 // Only create new key containers, so that existing key containers are not
180 // overwritten. 201 // overwritten.
181 if (crypto::CryptAcquireContextLocked(key_container.provider_.receive(), 202 if (crypto::CryptAcquireContextLocked(key_container.provider_.receive(),
182 key_container.key_id_.c_str(), NULL, PROV_RSA_FULL, 203 key_container.key_id_.c_str(),
183 CRYPT_SILENT | CRYPT_NEWKEYSET)) 204 NULL,
205 PROV_RSA_FULL,
206 CRYPT_SILENT | CRYPT_NEWKEYSET))
184 break; 207 break;
185 208
186 if (GetLastError() != NTE_BAD_KEYSET) { 209 if (GetLastError() != NTE_BAD_KEYSET) {
187 LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider " 210 LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider "
188 "context: " << GetLastError(); 211 "context: " << GetLastError();
189 return std::string(); 212 return std::string();
190 } 213 }
191 } 214 }
192 if (attempt == kMaxAttempts) { 215 if (attempt == kMaxAttempts) {
193 LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider " 216 LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider "
194 "context: Max retries exceeded"; 217 "context: Max retries exceeded";
195 return std::string(); 218 return std::string();
196 } 219 }
197 220
198 { 221 {
199 crypto::ScopedHCRYPTKEY key; 222 crypto::ScopedHCRYPTKEY key;
200 if (!CryptGenKey(key_container.provider_, CALG_RSA_KEYX, 223 if (!CryptGenKey(key_container.provider_,
201 (key_size_in_bits_ << 16) | CRYPT_EXPORTABLE, key.receive())) { 224 CALG_RSA_KEYX,
225 (key_size_in_bits_ << 16) | CRYPT_EXPORTABLE,
226 key.receive())) {
202 LOG(ERROR) << "Keygen failed: Couldn't generate an RSA key"; 227 LOG(ERROR) << "Keygen failed: Couldn't generate an RSA key";
203 return std::string(); 228 return std::string();
204 } 229 }
205 230
206 std::string spkac; 231 std::string spkac;
207 if (!GetSignedPublicKeyAndChallenge(key_container.provider_, challenge_, 232 if (!GetSignedPublicKeyAndChallenge(
208 &spkac)) { 233 key_container.provider_, challenge_, &spkac)) {
209 LOG(ERROR) << "Keygen failed: Couldn't generate the signed public key " 234 LOG(ERROR) << "Keygen failed: Couldn't generate the signed public key "
210 "and challenge"; 235 "and challenge";
211 return std::string(); 236 return std::string();
212 } 237 }
213 238
214 std::string result; 239 std::string result;
215 base::Base64Encode(spkac, &result); 240 base::Base64Encode(spkac, &result);
216 241
217 VLOG(1) << "Keygen succeeded"; 242 VLOG(1) << "Keygen succeeded";
218 return result; 243 return result;
219 } 244 }
220 } 245 }
221 246
222 } // namespace net 247 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698