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

Side by Side Diff: net/cert/x509_certificate_win.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/cert/x509_certificate.h" 5 #include "net/cert/x509_certificate.h"
6 6
7 #include <blapi.h> // Implement CalculateChainFingerprint() with NSS. 7 #include <blapi.h> // Implement CalculateChainFingerprint() with NSS.
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/pickle.h" 11 #include "base/pickle.h"
12 #include "base/sha1.h" 12 #include "base/sha1.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "crypto/capi_util.h" 15 #include "crypto/capi_util.h"
16 #include "crypto/scoped_capi_types.h" 16 #include "crypto/scoped_capi_types.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 18
19 #pragma comment(lib, "crypt32.lib") 19 #pragma comment(lib, "crypt32.lib")
20 20
21 using base::Time; 21 using base::Time;
22 22
23 namespace net { 23 namespace net {
24 24
25 namespace { 25 namespace {
26 26
27 typedef crypto::ScopedCAPIHandle< 27 typedef crypto::ScopedCAPIHandle<
28 HCERTSTORE, 28 HCERTSTORE,
29 crypto::CAPIDestroyerWithFlags<HCERTSTORE, 29 crypto::CAPIDestroyerWithFlags<HCERTSTORE, CertCloseStore, 0> >
30 CertCloseStore, 0> > ScopedHCERTSTORE; 30 ScopedHCERTSTORE;
31 31
32 void ExplodedTimeToSystemTime(const base::Time::Exploded& exploded, 32 void ExplodedTimeToSystemTime(const base::Time::Exploded& exploded,
33 SYSTEMTIME* system_time) { 33 SYSTEMTIME* system_time) {
34 system_time->wYear = exploded.year; 34 system_time->wYear = exploded.year;
35 system_time->wMonth = exploded.month; 35 system_time->wMonth = exploded.month;
36 system_time->wDayOfWeek = exploded.day_of_week; 36 system_time->wDayOfWeek = exploded.day_of_week;
37 system_time->wDay = exploded.day_of_month; 37 system_time->wDay = exploded.day_of_month;
38 system_time->wHour = exploded.hour; 38 system_time->wHour = exploded.hour;
39 system_time->wMinute = exploded.minute; 39 system_time->wMinute = exploded.minute;
40 system_time->wSecond = exploded.second; 40 system_time->wSecond = exploded.second;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 output->reset(alt_name_info); 73 output->reset(alt_name_info);
74 } 74 }
75 75
76 void AddCertsFromStore(HCERTSTORE store, 76 void AddCertsFromStore(HCERTSTORE store,
77 X509Certificate::OSCertHandles* results) { 77 X509Certificate::OSCertHandles* results) {
78 PCCERT_CONTEXT cert = NULL; 78 PCCERT_CONTEXT cert = NULL;
79 79
80 while ((cert = CertEnumCertificatesInStore(store, cert)) != NULL) { 80 while ((cert = CertEnumCertificatesInStore(store, cert)) != NULL) {
81 PCCERT_CONTEXT to_add = NULL; 81 PCCERT_CONTEXT to_add = NULL;
82 if (CertAddCertificateContextToStore( 82 if (CertAddCertificateContextToStore(
83 NULL, // The cert won't be persisted in any cert store. This breaks 83 NULL, // The cert won't be persisted in any cert store. This breaks
84 // any association the context currently has to |store|, which 84 // any association the context currently has to |store|, which
85 // allows us, the caller, to safely close |store| without 85 // allows us, the caller, to safely close |store| without
86 // releasing the cert handles. 86 // releasing the cert handles.
87 cert, 87 cert,
88 CERT_STORE_ADD_USE_EXISTING, 88 CERT_STORE_ADD_USE_EXISTING,
89 &to_add) && to_add != NULL) { 89 &to_add) &&
90 to_add != NULL) {
90 // When processing stores generated from PKCS#7/PKCS#12 files, it 91 // When processing stores generated from PKCS#7/PKCS#12 files, it
91 // appears that the order returned is the inverse of the order that it 92 // appears that the order returned is the inverse of the order that it
92 // appeared in the file. 93 // appeared in the file.
93 // TODO(rsleevi): Ensure this order is consistent across all Win 94 // TODO(rsleevi): Ensure this order is consistent across all Win
94 // versions 95 // versions
95 results->insert(results->begin(), to_add); 96 results->insert(results->begin(), to_add);
96 } 97 }
97 } 98 }
98 } 99 }
99 100
100 X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) { 101 X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) {
101 X509Certificate::OSCertHandles results; 102 X509Certificate::OSCertHandles results;
102 CERT_BLOB data_blob; 103 CERT_BLOB data_blob;
103 data_blob.cbData = length; 104 data_blob.cbData = length;
104 data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data)); 105 data_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(data));
105 106
106 HCERTSTORE out_store = NULL; 107 HCERTSTORE out_store = NULL;
107 108
108 DWORD expected_types = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED | 109 DWORD expected_types = CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
109 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED | 110 CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED |
110 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED; 111 CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED;
111 112
112 if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &data_blob, expected_types, 113 if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
113 CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, 114 &data_blob,
114 &out_store, NULL, NULL) || out_store == NULL) { 115 expected_types,
116 CERT_QUERY_FORMAT_FLAG_BINARY,
117 0,
118 NULL,
119 NULL,
120 NULL,
121 &out_store,
122 NULL,
123 NULL) ||
124 out_store == NULL) {
115 return results; 125 return results;
116 } 126 }
117 127
118 AddCertsFromStore(out_store, &results); 128 AddCertsFromStore(out_store, &results);
119 CertCloseStore(out_store, CERT_CLOSE_STORE_CHECK_FLAG); 129 CertCloseStore(out_store, CERT_CLOSE_STORE_CHECK_FLAG);
120 130
121 return results; 131 return results;
122 } 132 }
123 133
124 // Given a CERT_NAME_BLOB, returns true if it appears in a given list, 134 // Given a CERT_NAME_BLOB, returns true if it appears in a given list,
125 // formatted as a vector of strings holding DER-encoded X.509 135 // formatted as a vector of strings holding DER-encoded X.509
126 // DistinguishedName entries. 136 // DistinguishedName entries.
127 bool IsCertNameBlobInIssuerList( 137 bool IsCertNameBlobInIssuerList(CERT_NAME_BLOB* name_blob,
128 CERT_NAME_BLOB* name_blob, 138 const std::vector<std::string>& issuer_names) {
129 const std::vector<std::string>& issuer_names) {
130 for (std::vector<std::string>::const_iterator it = issuer_names.begin(); 139 for (std::vector<std::string>::const_iterator it = issuer_names.begin();
131 it != issuer_names.end(); ++it) { 140 it != issuer_names.end();
141 ++it) {
132 CERT_NAME_BLOB issuer_blob; 142 CERT_NAME_BLOB issuer_blob;
133 issuer_blob.pbData = 143 issuer_blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(it->data()));
134 reinterpret_cast<BYTE*>(const_cast<char*>(it->data()));
135 issuer_blob.cbData = static_cast<DWORD>(it->length()); 144 issuer_blob.cbData = static_cast<DWORD>(it->length());
136 145
137 BOOL rb = CertCompareCertificateName( 146 BOOL rb = CertCompareCertificateName(
138 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &issuer_blob, name_blob); 147 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &issuer_blob, name_blob);
139 if (rb) 148 if (rb)
140 return true; 149 return true;
141 } 150 }
142 return false; 151 return false;
143 } 152 }
144 153
145 } // namespace 154 } // namespace
146 155
147 void X509Certificate::Initialize() { 156 void X509Certificate::Initialize() {
148 DCHECK(cert_handle_); 157 DCHECK(cert_handle_);
149 subject_.ParseDistinguishedName(cert_handle_->pCertInfo->Subject.pbData, 158 subject_.ParseDistinguishedName(cert_handle_->pCertInfo->Subject.pbData,
150 cert_handle_->pCertInfo->Subject.cbData); 159 cert_handle_->pCertInfo->Subject.cbData);
151 issuer_.ParseDistinguishedName(cert_handle_->pCertInfo->Issuer.pbData, 160 issuer_.ParseDistinguishedName(cert_handle_->pCertInfo->Issuer.pbData,
152 cert_handle_->pCertInfo->Issuer.cbData); 161 cert_handle_->pCertInfo->Issuer.cbData);
153 162
154 valid_start_ = Time::FromFileTime(cert_handle_->pCertInfo->NotBefore); 163 valid_start_ = Time::FromFileTime(cert_handle_->pCertInfo->NotBefore);
155 valid_expiry_ = Time::FromFileTime(cert_handle_->pCertInfo->NotAfter); 164 valid_expiry_ = Time::FromFileTime(cert_handle_->pCertInfo->NotAfter);
156 165
157 fingerprint_ = CalculateFingerprint(cert_handle_); 166 fingerprint_ = CalculateFingerprint(cert_handle_);
158 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); 167 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
159 168
160 const CRYPT_INTEGER_BLOB* serial = &cert_handle_->pCertInfo->SerialNumber; 169 const CRYPT_INTEGER_BLOB* serial = &cert_handle_->pCertInfo->SerialNumber;
161 scoped_ptr<uint8[]> serial_bytes(new uint8[serial->cbData]); 170 scoped_ptr<uint8[]> serial_bytes(new uint8[serial->cbData]);
162 for (unsigned i = 0; i < serial->cbData; i++) 171 for (unsigned i = 0; i < serial->cbData; i++)
163 serial_bytes[i] = serial->pbData[serial->cbData - i - 1]; 172 serial_bytes[i] = serial->pbData[serial->cbData - i - 1];
164 serial_number_ = std::string( 173 serial_number_ =
165 reinterpret_cast<char*>(serial_bytes.get()), serial->cbData); 174 std::string(reinterpret_cast<char*>(serial_bytes.get()), serial->cbData);
166 } 175 }
167 176
168 void X509Certificate::GetSubjectAltName( 177 void X509Certificate::GetSubjectAltName(
169 std::vector<std::string>* dns_names, 178 std::vector<std::string>* dns_names,
170 std::vector<std::string>* ip_addrs) const { 179 std::vector<std::string>* ip_addrs) const {
171 if (dns_names) 180 if (dns_names)
172 dns_names->clear(); 181 dns_names->clear();
173 if (ip_addrs) 182 if (ip_addrs)
174 ip_addrs->clear(); 183 ip_addrs->clear();
175 184
176 if (!cert_handle_) 185 if (!cert_handle_)
177 return; 186 return;
178 187
179 scoped_ptr<CERT_ALT_NAME_INFO, base::FreeDeleter> alt_name_info; 188 scoped_ptr<CERT_ALT_NAME_INFO, base::FreeDeleter> alt_name_info;
180 GetCertSubjectAltName(cert_handle_, &alt_name_info); 189 GetCertSubjectAltName(cert_handle_, &alt_name_info);
181 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); 190 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get();
182 if (alt_name) { 191 if (alt_name) {
183 int num_entries = alt_name->cAltEntry; 192 int num_entries = alt_name->cAltEntry;
184 for (int i = 0; i < num_entries; i++) { 193 for (int i = 0; i < num_entries; i++) {
185 // dNSName is an ASN.1 IA5String representing a string of ASCII 194 // dNSName is an ASN.1 IA5String representing a string of ASCII
186 // characters, so we can use UTF16ToASCII here. 195 // characters, so we can use UTF16ToASCII here.
187 const CERT_ALT_NAME_ENTRY& entry = alt_name->rgAltEntry[i]; 196 const CERT_ALT_NAME_ENTRY& entry = alt_name->rgAltEntry[i];
188 197
189 if (dns_names && entry.dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) { 198 if (dns_names && entry.dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) {
190 dns_names->push_back(base::UTF16ToASCII(entry.pwszDNSName)); 199 dns_names->push_back(base::UTF16ToASCII(entry.pwszDNSName));
191 } else if (ip_addrs && 200 } else if (ip_addrs &&
192 entry.dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS) { 201 entry.dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS) {
193 ip_addrs->push_back(std::string( 202 ip_addrs->push_back(
194 reinterpret_cast<const char*>(entry.IPAddress.pbData), 203 std::string(reinterpret_cast<const char*>(entry.IPAddress.pbData),
195 entry.IPAddress.cbData)); 204 entry.IPAddress.cbData));
196 } 205 }
197 } 206 }
198 } 207 }
199 } 208 }
200 209
201 PCCERT_CONTEXT X509Certificate::CreateOSCertChainForCert() const { 210 PCCERT_CONTEXT X509Certificate::CreateOSCertChainForCert() const {
202 // Create an in-memory certificate store to hold this certificate and 211 // Create an in-memory certificate store to hold this certificate and
203 // any intermediate certificates in |intermediate_ca_certs_|. The store 212 // any intermediate certificates in |intermediate_ca_certs_|. The store
204 // will be referenced in the returned PCCERT_CONTEXT, and will not be freed 213 // will be referenced in the returned PCCERT_CONTEXT, and will not be freed
205 // until the PCCERT_CONTEXT is freed. 214 // until the PCCERT_CONTEXT is freed.
206 ScopedHCERTSTORE store(CertOpenStore( 215 ScopedHCERTSTORE store(
207 CERT_STORE_PROV_MEMORY, 0, NULL, 216 CertOpenStore(CERT_STORE_PROV_MEMORY,
208 CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL)); 217 0,
218 NULL,
219 CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
220 NULL));
209 if (!store.get()) 221 if (!store.get())
210 return NULL; 222 return NULL;
211 223
212 // NOTE: This preserves all of the properties of |os_cert_handle()| except 224 // NOTE: This preserves all of the properties of |os_cert_handle()| except
213 // for CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two 225 // for CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two
214 // properties that hold access to already-opened private keys. If a handle 226 // properties that hold access to already-opened private keys. If a handle
215 // has already been unlocked (eg: PIN prompt), then the first time that the 227 // has already been unlocked (eg: PIN prompt), then the first time that the
216 // identity is used for client auth, it may prompt the user again. 228 // identity is used for client auth, it may prompt the user again.
217 PCCERT_CONTEXT primary_cert; 229 PCCERT_CONTEXT primary_cert;
218 BOOL ok = CertAddCertificateContextToStore(store.get(), os_cert_handle(), 230 BOOL ok = CertAddCertificateContextToStore(
219 CERT_STORE_ADD_ALWAYS, 231 store.get(), os_cert_handle(), CERT_STORE_ADD_ALWAYS, &primary_cert);
220 &primary_cert);
221 if (!ok || !primary_cert) 232 if (!ok || !primary_cert)
222 return NULL; 233 return NULL;
223 234
224 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { 235 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
225 CertAddCertificateContextToStore(store.get(), intermediate_ca_certs_[i], 236 CertAddCertificateContextToStore(
226 CERT_STORE_ADD_ALWAYS, NULL); 237 store.get(), intermediate_ca_certs_[i], CERT_STORE_ADD_ALWAYS, NULL);
227 } 238 }
228 239
229 // Note: |store| is explicitly not released, as the call to CertCloseStore() 240 // Note: |store| is explicitly not released, as the call to CertCloseStore()
230 // when |store| goes out of scope will not actually free the store. Instead, 241 // when |store| goes out of scope will not actually free the store. Instead,
231 // the store will be freed when |primary_cert| is freed. 242 // the store will be freed when |primary_cert| is freed.
232 return primary_cert; 243 return primary_cert;
233 } 244 }
234 245
235 // static 246 // static
236 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, 247 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
237 std::string* encoded) { 248 std::string* encoded) {
238 if (!cert_handle->pbCertEncoded || !cert_handle->cbCertEncoded) 249 if (!cert_handle->pbCertEncoded || !cert_handle->cbCertEncoded)
239 return false; 250 return false;
240 encoded->assign(reinterpret_cast<char*>(cert_handle->pbCertEncoded), 251 encoded->assign(reinterpret_cast<char*>(cert_handle->pbCertEncoded),
241 cert_handle->cbCertEncoded); 252 cert_handle->cbCertEncoded);
242 return true; 253 return true;
243 } 254 }
244 255
245 // static 256 // static
246 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, 257 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
247 X509Certificate::OSCertHandle b) { 258 X509Certificate::OSCertHandle b) {
248 DCHECK(a && b); 259 DCHECK(a && b);
249 if (a == b) 260 if (a == b)
250 return true; 261 return true;
251 return a->cbCertEncoded == b->cbCertEncoded && 262 return a->cbCertEncoded == b->cbCertEncoded &&
252 memcmp(a->pbCertEncoded, b->pbCertEncoded, a->cbCertEncoded) == 0; 263 memcmp(a->pbCertEncoded, b->pbCertEncoded, a->cbCertEncoded) == 0;
253 } 264 }
254 265
255 // static 266 // static
256 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 267 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
257 const char* data, int length) { 268 const char* data,
269 int length) {
258 OSCertHandle cert_handle = NULL; 270 OSCertHandle cert_handle = NULL;
259 if (!CertAddEncodedCertificateToStore( 271 if (!CertAddEncodedCertificateToStore(NULL,
260 NULL, X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(data), 272 X509_ASN_ENCODING,
261 length, CERT_STORE_ADD_USE_EXISTING, &cert_handle)) 273 reinterpret_cast<const BYTE*>(data),
274 length,
275 CERT_STORE_ADD_USE_EXISTING,
276 &cert_handle))
262 return NULL; 277 return NULL;
263 278
264 return cert_handle; 279 return cert_handle;
265 } 280 }
266 281
267 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( 282 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
268 const char* data, int length, Format format) { 283 const char* data,
284 int length,
285 Format format) {
269 OSCertHandles results; 286 OSCertHandles results;
270 switch (format) { 287 switch (format) {
271 case FORMAT_SINGLE_CERTIFICATE: { 288 case FORMAT_SINGLE_CERTIFICATE: {
272 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); 289 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
273 if (handle != NULL) 290 if (handle != NULL)
274 results.push_back(handle); 291 results.push_back(handle);
275 break; 292 break;
276 } 293 }
277 case FORMAT_PKCS7: 294 case FORMAT_PKCS7:
278 results = ParsePKCS7(data, length); 295 results = ParsePKCS7(data, length);
(...skipping 11 matching lines...) Expand all
290 OSCertHandle cert_handle) { 307 OSCertHandle cert_handle) {
291 return CertDuplicateCertificateContext(cert_handle); 308 return CertDuplicateCertificateContext(cert_handle);
292 } 309 }
293 310
294 // static 311 // static
295 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 312 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
296 CertFreeCertificateContext(cert_handle); 313 CertFreeCertificateContext(cert_handle);
297 } 314 }
298 315
299 // static 316 // static
300 SHA1HashValue X509Certificate::CalculateFingerprint( 317 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) {
301 OSCertHandle cert) {
302 DCHECK(NULL != cert->pbCertEncoded); 318 DCHECK(NULL != cert->pbCertEncoded);
303 DCHECK_NE(static_cast<DWORD>(0), cert->cbCertEncoded); 319 DCHECK_NE(static_cast<DWORD>(0), cert->cbCertEncoded);
304 320
305 BOOL rv; 321 BOOL rv;
306 SHA1HashValue sha1; 322 SHA1HashValue sha1;
307 DWORD sha1_size = sizeof(sha1.data); 323 DWORD sha1_size = sizeof(sha1.data);
308 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, 324 rv = CryptHashCertificate(NULL,
309 cert->cbCertEncoded, sha1.data, &sha1_size); 325 CALG_SHA1,
326 0,
327 cert->pbCertEncoded,
328 cert->cbCertEncoded,
329 sha1.data,
330 &sha1_size);
310 DCHECK(rv && sha1_size == sizeof(sha1.data)); 331 DCHECK(rv && sha1_size == sizeof(sha1.data));
311 if (!rv) 332 if (!rv)
312 memset(sha1.data, 0, sizeof(sha1.data)); 333 memset(sha1.data, 0, sizeof(sha1.data));
313 return sha1; 334 return sha1;
314 } 335 }
315 336
316 // TODO(wtc): This function is implemented with NSS low-level hash 337 // TODO(wtc): This function is implemented with NSS low-level hash
317 // functions to ensure it is fast. Reimplement this function with 338 // functions to ensure it is fast. Reimplement this function with
318 // CryptoAPI. May need to cache the HCRYPTPROV to reduce the overhead. 339 // CryptoAPI. May need to cache the HCRYPTPROV to reduce the overhead.
319 // static 340 // static
(...skipping 11 matching lines...) Expand all
331 SHA1_Update(sha1_ctx, ca_cert->pbCertEncoded, ca_cert->cbCertEncoded); 352 SHA1_Update(sha1_ctx, ca_cert->pbCertEncoded, ca_cert->cbCertEncoded);
332 } 353 }
333 unsigned int result_len; 354 unsigned int result_len;
334 SHA1_End(sha1_ctx, sha1.data, &result_len, SHA1_LENGTH); 355 SHA1_End(sha1_ctx, sha1.data, &result_len, SHA1_LENGTH);
335 SHA1_DestroyContext(sha1_ctx, PR_TRUE); 356 SHA1_DestroyContext(sha1_ctx, PR_TRUE);
336 357
337 return sha1; 358 return sha1;
338 } 359 }
339 360
340 // static 361 // static
341 X509Certificate::OSCertHandle 362 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle(
342 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { 363 PickleIterator* pickle_iter) {
343 const char* data; 364 const char* data;
344 int length; 365 int length;
345 if (!pickle_iter->ReadData(&data, &length)) 366 if (!pickle_iter->ReadData(&data, &length))
346 return NULL; 367 return NULL;
347 368
348 // Legacy serialized certificates were serialized with extended attributes, 369 // Legacy serialized certificates were serialized with extended attributes,
349 // rather than as DER only. As a result, these serialized certificates are 370 // rather than as DER only. As a result, these serialized certificates are
350 // not portable across platforms and may have side-effects on Windows due 371 // not portable across platforms and may have side-effects on Windows due
351 // to extended attributes being serialized/deserialized - 372 // to extended attributes being serialized/deserialized -
352 // http://crbug.com/118706. To avoid deserializing these attributes, write 373 // http://crbug.com/118706. To avoid deserializing these attributes, write
353 // the deserialized cert into a temporary cert store and then create a new 374 // the deserialized cert into a temporary cert store and then create a new
354 // cert from the DER - that is, without attributes. 375 // cert from the DER - that is, without attributes.
355 ScopedHCERTSTORE store( 376 ScopedHCERTSTORE store(
356 CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL)); 377 CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL));
357 if (!store.get()) 378 if (!store.get())
358 return NULL; 379 return NULL;
359 380
360 OSCertHandle cert_handle = NULL; 381 OSCertHandle cert_handle = NULL;
361 if (!CertAddSerializedElementToStore( 382 if (!CertAddSerializedElementToStore(
362 store.get(), reinterpret_cast<const BYTE*>(data), length, 383 store.get(),
363 CERT_STORE_ADD_NEW, 0, CERT_STORE_CERTIFICATE_CONTEXT_FLAG, 384 reinterpret_cast<const BYTE*>(data),
364 NULL, reinterpret_cast<const void **>(&cert_handle))) { 385 length,
386 CERT_STORE_ADD_NEW,
387 0,
388 CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
389 NULL,
390 reinterpret_cast<const void**>(&cert_handle))) {
365 return NULL; 391 return NULL;
366 } 392 }
367 393
368 std::string encoded; 394 std::string encoded;
369 bool ok = GetDEREncoded(cert_handle, &encoded); 395 bool ok = GetDEREncoded(cert_handle, &encoded);
370 FreeOSCertHandle(cert_handle); 396 FreeOSCertHandle(cert_handle);
371 cert_handle = NULL; 397 cert_handle = NULL;
372 398
373 if (ok) 399 if (ok)
374 cert_handle = CreateOSCertHandleFromBytes(encoded.data(), encoded.size()); 400 cert_handle = CreateOSCertHandleFromBytes(encoded.data(), encoded.size());
375 return cert_handle; 401 return cert_handle;
376 } 402 }
377 403
378 // static 404 // static
379 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, 405 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
380 Pickle* pickle) { 406 Pickle* pickle) {
381 return pickle->WriteData( 407 return pickle->WriteData(reinterpret_cast<char*>(cert_handle->pbCertEncoded),
382 reinterpret_cast<char*>(cert_handle->pbCertEncoded), 408 cert_handle->cbCertEncoded);
383 cert_handle->cbCertEncoded);
384 } 409 }
385 410
386 // static 411 // static
387 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, 412 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
388 size_t* size_bits, 413 size_t* size_bits,
389 PublicKeyType* type) { 414 PublicKeyType* type) {
390 *type = kPublicKeyTypeUnknown; 415 *type = kPublicKeyTypeUnknown;
391 *size_bits = 0; 416 *size_bits = 0;
392 417
393 PCCRYPT_OID_INFO oid_info = CryptFindOIDInfo( 418 PCCRYPT_OID_INFO oid_info = CryptFindOIDInfo(
394 CRYPT_OID_INFO_OID_KEY, 419 CRYPT_OID_INFO_OID_KEY,
395 cert_handle->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId, 420 cert_handle->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,
396 CRYPT_PUBKEY_ALG_OID_GROUP_ID); 421 CRYPT_PUBKEY_ALG_OID_GROUP_ID);
397 if (!oid_info) 422 if (!oid_info)
398 return; 423 return;
399 424
400 CHECK_EQ(oid_info->dwGroupId, 425 CHECK_EQ(oid_info->dwGroupId,
401 static_cast<DWORD>(CRYPT_PUBKEY_ALG_OID_GROUP_ID)); 426 static_cast<DWORD>(CRYPT_PUBKEY_ALG_OID_GROUP_ID));
402 427
403 *size_bits = CertGetPublicKeyLength( 428 *size_bits =
404 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 429 CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
405 &cert_handle->pCertInfo->SubjectPublicKeyInfo); 430 &cert_handle->pCertInfo->SubjectPublicKeyInfo);
406 431
407 if (IS_SPECIAL_OID_INFO_ALGID(oid_info->Algid)) { 432 if (IS_SPECIAL_OID_INFO_ALGID(oid_info->Algid)) {
408 // For an EC public key, oid_info->Algid is CALG_OID_INFO_PARAMETERS 433 // For an EC public key, oid_info->Algid is CALG_OID_INFO_PARAMETERS
409 // (0xFFFFFFFE). Need to handle it as a special case. 434 // (0xFFFFFFFE). Need to handle it as a special case.
410 if (strcmp(oid_info->pszOID, szOID_ECC_PUBLIC_KEY) == 0) { 435 if (strcmp(oid_info->pszOID, szOID_ECC_PUBLIC_KEY) == 0) {
411 *type = kPublicKeyTypeECDSA; 436 *type = kPublicKeyTypeECDSA;
412 } else { 437 } else {
413 NOTREACHED(); 438 NOTREACHED();
414 } 439 }
415 return; 440 return;
(...skipping 10 matching lines...) Expand all
426 *type = kPublicKeyTypeECDSA; 451 *type = kPublicKeyTypeECDSA;
427 break; 452 break;
428 case CALG_ECDH: 453 case CALG_ECDH:
429 *type = kPublicKeyTypeECDH; 454 *type = kPublicKeyTypeECDH;
430 break; 455 break;
431 } 456 }
432 } 457 }
433 458
434 bool X509Certificate::IsIssuedByEncoded( 459 bool X509Certificate::IsIssuedByEncoded(
435 const std::vector<std::string>& valid_issuers) { 460 const std::vector<std::string>& valid_issuers) {
436
437 // If the certificate's issuer in the list? 461 // If the certificate's issuer in the list?
438 if (IsCertNameBlobInIssuerList(&cert_handle_->pCertInfo->Issuer, 462 if (IsCertNameBlobInIssuerList(&cert_handle_->pCertInfo->Issuer,
439 valid_issuers)) { 463 valid_issuers)) {
440 return true; 464 return true;
441 } 465 }
442 // Otherwise, is any of the intermediate CA subjects in the list? 466 // Otherwise, is any of the intermediate CA subjects in the list?
443 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); 467 for (OSCertHandles::iterator it = intermediate_ca_certs_.begin();
444 it != intermediate_ca_certs_.end(); ++it) { 468 it != intermediate_ca_certs_.end();
445 if (IsCertNameBlobInIssuerList(&(*it)->pCertInfo->Issuer, 469 ++it) {
446 valid_issuers)) { 470 if (IsCertNameBlobInIssuerList(&(*it)->pCertInfo->Issuer, valid_issuers)) {
447 return true; 471 return true;
448 } 472 }
449 } 473 }
450 474
451 return false; 475 return false;
452 } 476 }
453 477
454 } // namespace net 478 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698