OLD | NEW |
---|---|
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/x509_certificate.h" | 5 #include "net/base/x509_certificate.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/pickle.h" | |
17 #include "base/sha1.h" | 18 #include "base/sha1.h" |
18 #include "base/string_piece.h" | 19 #include "base/string_piece.h" |
19 #include "base/string_util.h" | 20 #include "base/string_util.h" |
20 #include "base/time.h" | 21 #include "base/time.h" |
21 #include "net/base/pem_tokenizer.h" | 22 #include "net/base/pem_tokenizer.h" |
22 | 23 |
23 namespace net { | 24 namespace net { |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 if (!cert_handle) | 225 if (!cert_handle) |
225 return NULL; | 226 return NULL; |
226 | 227 |
227 X509Certificate* cert = CreateFromHandle(cert_handle, | 228 X509Certificate* cert = CreateFromHandle(cert_handle, |
228 SOURCE_LONE_CERT_IMPORT, | 229 SOURCE_LONE_CERT_IMPORT, |
229 OSCertHandles()); | 230 OSCertHandles()); |
230 FreeOSCertHandle(cert_handle); | 231 FreeOSCertHandle(cert_handle); |
231 return cert; | 232 return cert; |
232 } | 233 } |
233 | 234 |
235 // static | |
236 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, | |
237 void** pickle_iter, | |
238 PickleType type) { | |
239 OSCertHandle cert_handle = ReadCertHandleFromPickle(pickle, pickle_iter); | |
240 OSCertHandles intermediates; | |
241 | |
242 // Even if a certificate fails to parse, whether the server certificate in | |
243 // |cert_handle| or one of the optional intermediates, continue reading | |
244 // the data from |pickle| so that |pickle_iter| is kept in sync for any | |
245 // other reads the caller may perform after this method returns. | |
wtc
2011/04/20 23:07:58
If a certificate fails to parse, the subsequent da
Ryan Sleevi
2011/04/20 23:59:10
There are two reasons for why parsing may fail, an
| |
246 if (type == PICKLETYPE_CERTIFICATE_CHAIN) { | |
247 size_t num_intermediates; | |
248 if (!pickle.ReadSize(pickle_iter, &num_intermediates)) { | |
249 FreeOSCertHandle(cert_handle); | |
250 return NULL; | |
251 } | |
252 | |
253 bool ok = !!cert_handle; | |
wtc
2011/04/20 23:07:58
Nit: say
bool ok = (cert_handle != NULL);
| |
254 for (size_t i = 0; i < num_intermediates; ++i) { | |
255 OSCertHandle intermediate = ReadCertHandleFromPickle(pickle, | |
256 pickle_iter); | |
257 // If an intermediate fails to load, it and any certificates after it | |
258 // will not be added. However, any intermediates that were successfully | |
259 // parsed before the failure can be safely returned. | |
260 ok &= !!intermediate; | |
261 if (ok) { | |
262 intermediates.push_back(intermediate); | |
263 } else if (intermediate) { | |
264 FreeOSCertHandle(intermediate); | |
265 } | |
266 } | |
267 } | |
268 | |
269 if (!cert_handle) | |
270 return NULL; | |
wtc
2011/04/20 23:07:58
We should also return NULL if |ok| is false.
Ryan Sleevi
2011/04/20 23:59:10
This contradicts the behaviour documented in line
| |
271 X509Certificate* cert = CreateFromHandle(cert_handle, SOURCE_FROM_CACHE, | |
272 intermediates); | |
273 FreeOSCertHandle(cert_handle); | |
274 for (size_t i = 0; i < intermediates.size(); ++i) | |
275 FreeOSCertHandle(intermediates[i]); | |
276 | |
277 return cert; | |
278 } | |
279 | |
280 // static | |
234 CertificateList X509Certificate::CreateCertificateListFromBytes( | 281 CertificateList X509Certificate::CreateCertificateListFromBytes( |
235 const char* data, int length, int format) { | 282 const char* data, int length, int format) { |
236 OSCertHandles certificates; | 283 OSCertHandles certificates; |
237 | 284 |
238 // Check to see if it is in a PEM-encoded form. This check is performed | 285 // Check to see if it is in a PEM-encoded form. This check is performed |
239 // first, as both OS X and NSS will both try to convert if they detect | 286 // first, as both OS X and NSS will both try to convert if they detect |
240 // PEM encoding, except they don't do it consistently between the two. | 287 // PEM encoding, except they don't do it consistently between the two. |
241 base::StringPiece data_string(data, length); | 288 base::StringPiece data_string(data, length); |
242 std::vector<std::string> pem_headers; | 289 std::vector<std::string> pem_headers; |
243 | 290 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 it != certificates.end(); ++it) { | 348 it != certificates.end(); ++it) { |
302 X509Certificate* result = CreateFromHandle(*it, SOURCE_LONE_CERT_IMPORT, | 349 X509Certificate* result = CreateFromHandle(*it, SOURCE_LONE_CERT_IMPORT, |
303 OSCertHandles()); | 350 OSCertHandles()); |
304 results.push_back(scoped_refptr<X509Certificate>(result)); | 351 results.push_back(scoped_refptr<X509Certificate>(result)); |
305 FreeOSCertHandle(*it); | 352 FreeOSCertHandle(*it); |
306 } | 353 } |
307 | 354 |
308 return results; | 355 return results; |
309 } | 356 } |
310 | 357 |
358 void X509Certificate::Persist(Pickle* pickle) { | |
359 DCHECK(cert_handle_); | |
360 if (!WriteCertHandleToPickle(cert_handle_, pickle)) { | |
361 NOTREACHED(); | |
362 return; | |
363 } | |
364 | |
365 if (!pickle->WriteSize(intermediate_ca_certs_.size())) { | |
366 NOTREACHED(); | |
367 return; | |
368 } | |
369 | |
370 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | |
371 if (!WriteCertHandleToPickle(intermediate_ca_certs_[i], pickle)) { | |
372 NOTREACHED(); | |
373 return; | |
374 } | |
375 } | |
376 } | |
377 | |
311 bool X509Certificate::HasExpired() const { | 378 bool X509Certificate::HasExpired() const { |
312 return base::Time::Now() > valid_expiry(); | 379 return base::Time::Now() > valid_expiry(); |
313 } | 380 } |
314 | 381 |
315 bool X509Certificate::Equals(const X509Certificate* other) const { | 382 bool X509Certificate::Equals(const X509Certificate* other) const { |
316 return IsSameOSCert(cert_handle_, other->cert_handle_); | 383 return IsSameOSCert(cert_handle_, other->cert_handle_); |
317 } | 384 } |
318 | 385 |
319 bool X509Certificate::HasIntermediateCertificate(OSCertHandle cert) { | 386 bool X509Certificate::HasIntermediateCertificate(OSCertHandle cert) { |
320 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_OPENSSL) | |
321 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | 387 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { |
322 if (IsSameOSCert(cert, intermediate_ca_certs_[i])) | 388 if (IsSameOSCert(cert, intermediate_ca_certs_[i])) |
323 return true; | 389 return true; |
324 } | 390 } |
325 return false; | 391 return false; |
326 #else | |
327 return true; | |
328 #endif | |
329 } | 392 } |
330 | 393 |
331 bool X509Certificate::HasIntermediateCertificates(const OSCertHandles& certs) { | 394 bool X509Certificate::HasIntermediateCertificates(const OSCertHandles& certs) { |
332 for (size_t i = 0; i < certs.size(); ++i) { | 395 for (size_t i = 0; i < certs.size(); ++i) { |
333 if (!HasIntermediateCertificate(certs[i])) | 396 if (!HasIntermediateCertificate(certs[i])) |
334 return false; | 397 return false; |
335 } | 398 } |
336 return true; | 399 return true; |
337 } | 400 } |
338 | 401 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
541 bool X509Certificate::IsSHA1HashInSortedArray(const SHA1Fingerprint& hash, | 604 bool X509Certificate::IsSHA1HashInSortedArray(const SHA1Fingerprint& hash, |
542 const uint8* array, | 605 const uint8* array, |
543 size_t array_byte_len) { | 606 size_t array_byte_len) { |
544 DCHECK_EQ(0u, array_byte_len % base::SHA1_LENGTH); | 607 DCHECK_EQ(0u, array_byte_len % base::SHA1_LENGTH); |
545 const unsigned arraylen = array_byte_len / base::SHA1_LENGTH; | 608 const unsigned arraylen = array_byte_len / base::SHA1_LENGTH; |
546 return NULL != bsearch(hash.data, array, arraylen, base::SHA1_LENGTH, | 609 return NULL != bsearch(hash.data, array, arraylen, base::SHA1_LENGTH, |
547 CompareSHA1Hashes); | 610 CompareSHA1Hashes); |
548 } | 611 } |
549 | 612 |
550 } // namespace net | 613 } // namespace net |
OLD | NEW |