OLD | NEW |
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 <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "net/cert/pem_tokenizer.h" | 27 #include "net/cert/pem_tokenizer.h" |
28 #include "url/url_canon.h" | 28 #include "url/url_canon.h" |
29 | 29 |
30 namespace net { | 30 namespace net { |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 // Indicates the order to use when trying to decode binary data, which is | 34 // Indicates the order to use when trying to decode binary data, which is |
35 // based on (speculation) as to what will be most common -> least common | 35 // based on (speculation) as to what will be most common -> least common |
36 const X509Certificate::Format kFormatDecodePriority[] = { | 36 const X509Certificate::Format kFormatDecodePriority[] = { |
37 X509Certificate::FORMAT_SINGLE_CERTIFICATE, | 37 X509Certificate::FORMAT_SINGLE_CERTIFICATE, X509Certificate::FORMAT_PKCS7}; |
38 X509Certificate::FORMAT_PKCS7 | |
39 }; | |
40 | 38 |
41 // The PEM block header used for DER certificates | 39 // The PEM block header used for DER certificates |
42 const char kCertificateHeader[] = "CERTIFICATE"; | 40 const char kCertificateHeader[] = "CERTIFICATE"; |
43 // The PEM block header used for PKCS#7 data | 41 // The PEM block header used for PKCS#7 data |
44 const char kPKCS7Header[] = "PKCS7"; | 42 const char kPKCS7Header[] = "PKCS7"; |
45 | 43 |
46 #if !defined(USE_NSS) | 44 #if !defined(USE_NSS) |
47 // A thread-safe cache for OS certificate handles. | 45 // A thread-safe cache for OS certificate handles. |
48 // | 46 // |
49 // Within each of the supported underlying crypto libraries, a certificate | 47 // Within each of the supported underlying crypto libraries, a certificate |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 // You must acquire this lock before using any private data of this object | 100 // You must acquire this lock before using any private data of this object |
103 // You must not block while holding this lock. | 101 // You must not block while holding this lock. |
104 base::Lock lock_; | 102 base::Lock lock_; |
105 | 103 |
106 // The certificate cache. You must acquire |lock_| before using |cache_|. | 104 // The certificate cache. You must acquire |lock_| before using |cache_|. |
107 CertMap cache_; | 105 CertMap cache_; |
108 | 106 |
109 DISALLOW_COPY_AND_ASSIGN(X509CertificateCache); | 107 DISALLOW_COPY_AND_ASSIGN(X509CertificateCache); |
110 }; | 108 }; |
111 | 109 |
112 base::LazyInstance<X509CertificateCache>::Leaky | 110 base::LazyInstance<X509CertificateCache>::Leaky g_x509_certificate_cache = |
113 g_x509_certificate_cache = LAZY_INSTANCE_INITIALIZER; | 111 LAZY_INSTANCE_INITIALIZER; |
114 | 112 |
115 void X509CertificateCache::InsertOrUpdate( | 113 void X509CertificateCache::InsertOrUpdate( |
116 X509Certificate::OSCertHandle* cert_handle) { | 114 X509Certificate::OSCertHandle* cert_handle) { |
117 DCHECK(cert_handle); | 115 DCHECK(cert_handle); |
118 SHA1HashValue fingerprint = | 116 SHA1HashValue fingerprint = |
119 X509Certificate::CalculateFingerprint(*cert_handle); | 117 X509Certificate::CalculateFingerprint(*cert_handle); |
120 | 118 |
121 X509Certificate::OSCertHandle old_handle = NULL; | 119 X509Certificate::OSCertHandle old_handle = NULL; |
122 { | 120 { |
123 base::AutoLock lock(lock_); | 121 base::AutoLock lock(lock_); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 | 160 |
163 void X509CertificateCache::Remove(X509Certificate::OSCertHandle cert_handle) { | 161 void X509CertificateCache::Remove(X509Certificate::OSCertHandle cert_handle) { |
164 SHA1HashValue fingerprint = | 162 SHA1HashValue fingerprint = |
165 X509Certificate::CalculateFingerprint(cert_handle); | 163 X509Certificate::CalculateFingerprint(cert_handle); |
166 base::AutoLock lock(lock_); | 164 base::AutoLock lock(lock_); |
167 | 165 |
168 CertMap::iterator pos = cache_.find(fingerprint); | 166 CertMap::iterator pos = cache_.find(fingerprint); |
169 if (pos == cache_.end()) | 167 if (pos == cache_.end()) |
170 return; // A hash collision where the winning cert was already freed. | 168 return; // A hash collision where the winning cert was already freed. |
171 | 169 |
172 bool is_same_cert = X509Certificate::IsSameOSCert(cert_handle, | 170 bool is_same_cert = |
173 pos->second.cert_handle); | 171 X509Certificate::IsSameOSCert(cert_handle, pos->second.cert_handle); |
174 if (!is_same_cert) | 172 if (!is_same_cert) |
175 return; // A hash collision where the winning cert is still around. | 173 return; // A hash collision where the winning cert is still around. |
176 | 174 |
177 if (--pos->second.ref_count == 0) { | 175 if (--pos->second.ref_count == 0) { |
178 // The last reference to |cert_handle| has been removed, so release the | 176 // The last reference to |cert_handle| has been removed, so release the |
179 // Entry's OS handle and remove the Entry. The caller still holds a | 177 // Entry's OS handle and remove the Entry. The caller still holds a |
180 // reference to |cert_handle| and is responsible for freeing it. | 178 // reference to |cert_handle| and is responsible for freeing it. |
181 X509Certificate::FreeOSCertHandle(pos->second.cert_handle); | 179 X509Certificate::FreeOSCertHandle(pos->second.cert_handle); |
182 cache_.erase(pos); | 180 cache_.erase(pos); |
183 } | 181 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 215 } |
218 | 216 |
219 } // namespace | 217 } // namespace |
220 | 218 |
221 bool X509Certificate::LessThan::operator()( | 219 bool X509Certificate::LessThan::operator()( |
222 const scoped_refptr<X509Certificate>& lhs, | 220 const scoped_refptr<X509Certificate>& lhs, |
223 const scoped_refptr<X509Certificate>& rhs) const { | 221 const scoped_refptr<X509Certificate>& rhs) const { |
224 if (lhs.get() == rhs.get()) | 222 if (lhs.get() == rhs.get()) |
225 return false; | 223 return false; |
226 | 224 |
227 int rv = memcmp(lhs->fingerprint_.data, rhs->fingerprint_.data, | 225 int rv = memcmp(lhs->fingerprint_.data, |
| 226 rhs->fingerprint_.data, |
228 sizeof(lhs->fingerprint_.data)); | 227 sizeof(lhs->fingerprint_.data)); |
229 if (rv != 0) | 228 if (rv != 0) |
230 return rv < 0; | 229 return rv < 0; |
231 | 230 |
232 rv = memcmp(lhs->ca_fingerprint_.data, rhs->ca_fingerprint_.data, | 231 rv = memcmp(lhs->ca_fingerprint_.data, |
| 232 rhs->ca_fingerprint_.data, |
233 sizeof(lhs->ca_fingerprint_.data)); | 233 sizeof(lhs->ca_fingerprint_.data)); |
234 return rv < 0; | 234 return rv < 0; |
235 } | 235 } |
236 | 236 |
237 X509Certificate::X509Certificate(const std::string& subject, | 237 X509Certificate::X509Certificate(const std::string& subject, |
238 const std::string& issuer, | 238 const std::string& issuer, |
239 base::Time start_date, | 239 base::Time start_date, |
240 base::Time expiration_date) | 240 base::Time expiration_date) |
241 : subject_(subject), | 241 : subject_(subject), |
242 issuer_(issuer), | 242 issuer_(issuer), |
(...skipping 23 matching lines...) Expand all Loading... |
266 OSCertHandle handle = CreateOSCertHandleFromBytes( | 266 OSCertHandle handle = CreateOSCertHandleFromBytes( |
267 const_cast<char*>(der_certs[i].data()), der_certs[i].size()); | 267 const_cast<char*>(der_certs[i].data()), der_certs[i].size()); |
268 if (!handle) | 268 if (!handle) |
269 break; | 269 break; |
270 intermediate_ca_certs.push_back(handle); | 270 intermediate_ca_certs.push_back(handle); |
271 } | 271 } |
272 | 272 |
273 OSCertHandle handle = NULL; | 273 OSCertHandle handle = NULL; |
274 // Return NULL if we failed to parse any of the certs. | 274 // Return NULL if we failed to parse any of the certs. |
275 if (der_certs.size() - 1 == intermediate_ca_certs.size()) { | 275 if (der_certs.size() - 1 == intermediate_ca_certs.size()) { |
276 handle = CreateOSCertHandleFromBytes( | 276 handle = CreateOSCertHandleFromBytes(const_cast<char*>(der_certs[0].data()), |
277 const_cast<char*>(der_certs[0].data()), der_certs[0].size()); | 277 der_certs[0].size()); |
278 } | 278 } |
279 | 279 |
280 X509Certificate* cert = NULL; | 280 X509Certificate* cert = NULL; |
281 if (handle) { | 281 if (handle) { |
282 cert = CreateFromHandle(handle, intermediate_ca_certs); | 282 cert = CreateFromHandle(handle, intermediate_ca_certs); |
283 FreeOSCertHandle(handle); | 283 FreeOSCertHandle(handle); |
284 } | 284 } |
285 | 285 |
286 for (size_t i = 0; i < intermediate_ca_certs.size(); i++) | 286 for (size_t i = 0; i < intermediate_ca_certs.size(); i++) |
287 FreeOSCertHandle(intermediate_ca_certs[i]); | 287 FreeOSCertHandle(intermediate_ca_certs[i]); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 cert = CreateFromHandle(cert_handle, intermediates); | 382 cert = CreateFromHandle(cert_handle, intermediates); |
383 FreeOSCertHandle(cert_handle); | 383 FreeOSCertHandle(cert_handle); |
384 for (size_t i = 0; i < intermediates.size(); ++i) | 384 for (size_t i = 0; i < intermediates.size(); ++i) |
385 FreeOSCertHandle(intermediates[i]); | 385 FreeOSCertHandle(intermediates[i]); |
386 | 386 |
387 return cert; | 387 return cert; |
388 } | 388 } |
389 | 389 |
390 // static | 390 // static |
391 CertificateList X509Certificate::CreateCertificateListFromBytes( | 391 CertificateList X509Certificate::CreateCertificateListFromBytes( |
392 const char* data, int length, int format) { | 392 const char* data, |
| 393 int length, |
| 394 int format) { |
393 OSCertHandles certificates; | 395 OSCertHandles certificates; |
394 | 396 |
395 // Check to see if it is in a PEM-encoded form. This check is performed | 397 // Check to see if it is in a PEM-encoded form. This check is performed |
396 // first, as both OS X and NSS will both try to convert if they detect | 398 // first, as both OS X and NSS will both try to convert if they detect |
397 // PEM encoding, except they don't do it consistently between the two. | 399 // PEM encoding, except they don't do it consistently between the two. |
398 base::StringPiece data_string(data, length); | 400 base::StringPiece data_string(data, length); |
399 std::vector<std::string> pem_headers; | 401 std::vector<std::string> pem_headers; |
400 | 402 |
401 // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally | 403 // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally |
402 // valid PEM block header for any format. | 404 // valid PEM block header for any format. |
(...skipping 13 matching lines...) Expand all Loading... |
416 // also be DER encoded certificates wrapped inside of PEM blocks. | 418 // also be DER encoded certificates wrapped inside of PEM blocks. |
417 format = FORMAT_PEM_CERT_SEQUENCE; | 419 format = FORMAT_PEM_CERT_SEQUENCE; |
418 certificates.push_back(handle); | 420 certificates.push_back(handle); |
419 continue; | 421 continue; |
420 } | 422 } |
421 | 423 |
422 // If the first block failed to parse as a DER certificate, and | 424 // If the first block failed to parse as a DER certificate, and |
423 // formats other than PEM are acceptable, check to see if the decoded | 425 // formats other than PEM are acceptable, check to see if the decoded |
424 // data is one of the accepted formats. | 426 // data is one of the accepted formats. |
425 if (format & ~FORMAT_PEM_CERT_SEQUENCE) { | 427 if (format & ~FORMAT_PEM_CERT_SEQUENCE) { |
426 for (size_t i = 0; certificates.empty() && | 428 for (size_t i = 0; |
427 i < arraysize(kFormatDecodePriority); ++i) { | 429 certificates.empty() && i < arraysize(kFormatDecodePriority); |
| 430 ++i) { |
428 if (format & kFormatDecodePriority[i]) { | 431 if (format & kFormatDecodePriority[i]) { |
429 certificates = CreateOSCertHandlesFromBytes(decoded.c_str(), | 432 certificates = CreateOSCertHandlesFromBytes( |
430 decoded.size(), kFormatDecodePriority[i]); | 433 decoded.c_str(), decoded.size(), kFormatDecodePriority[i]); |
431 } | 434 } |
432 } | 435 } |
433 } | 436 } |
434 | 437 |
435 // Stop parsing after the first block for any format but a sequence of | 438 // Stop parsing after the first block for any format but a sequence of |
436 // PEM-encoded DER certificates. The case of FORMAT_PEM_CERT_SEQUENCE | 439 // PEM-encoded DER certificates. The case of FORMAT_PEM_CERT_SEQUENCE |
437 // is handled above, and continues processing until a certificate fails | 440 // is handled above, and continues processing until a certificate fails |
438 // to parse. | 441 // to parse. |
439 break; | 442 break; |
440 } | 443 } |
441 | 444 |
442 // Try each of the formats, in order of parse preference, to see if |data| | 445 // Try each of the formats, in order of parse preference, to see if |data| |
443 // contains the binary representation of a Format, if it failed to parse | 446 // contains the binary representation of a Format, if it failed to parse |
444 // as a PEM certificate/chain. | 447 // as a PEM certificate/chain. |
445 for (size_t i = 0; certificates.empty() && | 448 for (size_t i = 0; |
446 i < arraysize(kFormatDecodePriority); ++i) { | 449 certificates.empty() && i < arraysize(kFormatDecodePriority); |
| 450 ++i) { |
447 if (format & kFormatDecodePriority[i]) | 451 if (format & kFormatDecodePriority[i]) |
448 certificates = CreateOSCertHandlesFromBytes(data, length, | 452 certificates = |
449 kFormatDecodePriority[i]); | 453 CreateOSCertHandlesFromBytes(data, length, kFormatDecodePriority[i]); |
450 } | 454 } |
451 | 455 |
452 CertificateList results; | 456 CertificateList results; |
453 // No certificates parsed. | 457 // No certificates parsed. |
454 if (certificates.empty()) | 458 if (certificates.empty()) |
455 return results; | 459 return results; |
456 | 460 |
457 for (OSCertHandles::iterator it = certificates.begin(); | 461 for (OSCertHandles::iterator it = certificates.begin(); |
458 it != certificates.end(); ++it) { | 462 it != certificates.end(); |
| 463 ++it) { |
459 X509Certificate* result = CreateFromHandle(*it, OSCertHandles()); | 464 X509Certificate* result = CreateFromHandle(*it, OSCertHandles()); |
460 results.push_back(scoped_refptr<X509Certificate>(result)); | 465 results.push_back(scoped_refptr<X509Certificate>(result)); |
461 FreeOSCertHandle(*it); | 466 FreeOSCertHandle(*it); |
462 } | 467 } |
463 | 468 |
464 return results; | 469 return results; |
465 } | 470 } |
466 | 471 |
467 void X509Certificate::Persist(Pickle* pickle) { | 472 void X509Certificate::Persist(Pickle* pickle) { |
468 DCHECK(cert_handle_); | 473 DCHECK(cert_handle_); |
469 // This would be an absolutely insane number of intermediates. | 474 // This would be an absolutely insane number of intermediates. |
470 if (intermediate_ca_certs_.size() > static_cast<size_t>(INT_MAX) - 1) { | 475 if (intermediate_ca_certs_.size() > static_cast<size_t>(INT_MAX) - 1) { |
471 NOTREACHED(); | 476 NOTREACHED(); |
472 return; | 477 return; |
473 } | 478 } |
474 if (!pickle->WriteInt( | 479 if (!pickle->WriteInt(static_cast<int>(intermediate_ca_certs_.size() + 1)) || |
475 static_cast<int>(intermediate_ca_certs_.size() + 1)) || | |
476 !WriteOSCertHandleToPickle(cert_handle_, pickle)) { | 480 !WriteOSCertHandleToPickle(cert_handle_, pickle)) { |
477 NOTREACHED(); | 481 NOTREACHED(); |
478 return; | 482 return; |
479 } | 483 } |
480 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | 484 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { |
481 if (!WriteOSCertHandleToPickle(intermediate_ca_certs_[i], pickle)) { | 485 if (!WriteOSCertHandleToPickle(intermediate_ca_certs_[i], pickle)) { |
482 NOTREACHED(); | 486 NOTREACHED(); |
483 return; | 487 return; |
484 } | 488 } |
485 } | 489 } |
(...skipping 21 matching lines...) Expand all Loading... |
507 const std::vector<std::string>& cert_san_ip_addrs, | 511 const std::vector<std::string>& cert_san_ip_addrs, |
508 bool* common_name_fallback_used) { | 512 bool* common_name_fallback_used) { |
509 DCHECK(!hostname.empty()); | 513 DCHECK(!hostname.empty()); |
510 // Perform name verification following http://tools.ietf.org/html/rfc6125. | 514 // Perform name verification following http://tools.ietf.org/html/rfc6125. |
511 // The terminology used in this method is as per that RFC:- | 515 // The terminology used in this method is as per that RFC:- |
512 // Reference identifier == the host the local user/agent is intending to | 516 // Reference identifier == the host the local user/agent is intending to |
513 // access, i.e. the thing displayed in the URL bar. | 517 // access, i.e. the thing displayed in the URL bar. |
514 // Presented identifier(s) == name(s) the server knows itself as, in its cert. | 518 // Presented identifier(s) == name(s) the server knows itself as, in its cert. |
515 | 519 |
516 // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. | 520 // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. |
517 const std::string host_or_ip = hostname.find(':') != std::string::npos ? | 521 const std::string host_or_ip = |
518 "[" + hostname + "]" : hostname; | 522 hostname.find(':') != std::string::npos ? "[" + hostname + "]" : hostname; |
519 url::CanonHostInfo host_info; | 523 url::CanonHostInfo host_info; |
520 std::string reference_name = CanonicalizeHost(host_or_ip, &host_info); | 524 std::string reference_name = CanonicalizeHost(host_or_ip, &host_info); |
521 // CanonicalizeHost does not normalize absolute vs relative DNS names. If | 525 // CanonicalizeHost does not normalize absolute vs relative DNS names. If |
522 // the input name was absolute (included trailing .), normalize it as if it | 526 // the input name was absolute (included trailing .), normalize it as if it |
523 // was relative. | 527 // was relative. |
524 if (!reference_name.empty() && *reference_name.rbegin() == '.') | 528 if (!reference_name.empty() && *reference_name.rbegin() == '.') |
525 reference_name.resize(reference_name.size() - 1); | 529 reference_name.resize(reference_name.size() - 1); |
526 if (reference_name.empty()) | 530 if (reference_name.empty()) |
527 return false; | 531 return false; |
528 | 532 |
529 // Allow fallback to Common name matching? | 533 // Allow fallback to Common name matching? |
530 const bool common_name_fallback = cert_san_dns_names.empty() && | 534 const bool common_name_fallback = |
531 cert_san_ip_addrs.empty(); | 535 cert_san_dns_names.empty() && cert_san_ip_addrs.empty(); |
532 *common_name_fallback_used = common_name_fallback; | 536 *common_name_fallback_used = common_name_fallback; |
533 | 537 |
534 // Fully handle all cases where |hostname| contains an IP address. | 538 // Fully handle all cases where |hostname| contains an IP address. |
535 if (host_info.IsIPAddress()) { | 539 if (host_info.IsIPAddress()) { |
536 if (common_name_fallback && host_info.family == url::CanonHostInfo::IPV4) { | 540 if (common_name_fallback && host_info.family == url::CanonHostInfo::IPV4) { |
537 // Fallback to Common name matching. As this is deprecated and only | 541 // Fallback to Common name matching. As this is deprecated and only |
538 // supported for compatibility refuse it for IPv6 addresses. | 542 // supported for compatibility refuse it for IPv6 addresses. |
539 return reference_name == cert_common_name; | 543 return reference_name == cert_common_name; |
540 } | 544 } |
541 base::StringPiece ip_addr_string( | 545 base::StringPiece ip_addr_string( |
542 reinterpret_cast<const char*>(host_info.address), | 546 reinterpret_cast<const char*>(host_info.address), |
543 host_info.AddressLength()); | 547 host_info.AddressLength()); |
544 return std::find(cert_san_ip_addrs.begin(), cert_san_ip_addrs.end(), | 548 return std::find(cert_san_ip_addrs.begin(), |
| 549 cert_san_ip_addrs.end(), |
545 ip_addr_string) != cert_san_ip_addrs.end(); | 550 ip_addr_string) != cert_san_ip_addrs.end(); |
546 } | 551 } |
547 | 552 |
548 // |reference_domain| is the remainder of |host| after the leading host | 553 // |reference_domain| is the remainder of |host| after the leading host |
549 // component is stripped off, but includes the leading dot e.g. | 554 // component is stripped off, but includes the leading dot e.g. |
550 // "www.f.com" -> ".f.com". | 555 // "www.f.com" -> ".f.com". |
551 // If there is no meaningful domain part to |host| (e.g. it contains no dots) | 556 // If there is no meaningful domain part to |host| (e.g. it contains no dots) |
552 // then |reference_domain| will be empty. | 557 // then |reference_domain| will be empty. |
553 base::StringPiece reference_host, reference_domain; | 558 base::StringPiece reference_host, reference_domain; |
554 SplitOnChar(reference_name, '.', &reference_host, &reference_domain); | 559 SplitOnChar(reference_name, '.', &reference_host, &reference_domain); |
555 bool allow_wildcards = false; | 560 bool allow_wildcards = false; |
556 if (!reference_domain.empty()) { | 561 if (!reference_domain.empty()) { |
557 DCHECK(reference_domain.starts_with(".")); | 562 DCHECK(reference_domain.starts_with(".")); |
558 | 563 |
559 // Do not allow wildcards for public/ICANN registry controlled domains - | 564 // Do not allow wildcards for public/ICANN registry controlled domains - |
560 // that is, prevent *.com or *.co.uk as valid presented names, but do not | 565 // that is, prevent *.com or *.co.uk as valid presented names, but do not |
561 // prevent *.appspot.com (a private registry controlled domain). | 566 // prevent *.appspot.com (a private registry controlled domain). |
562 // In addition, unknown top-level domains (such as 'intranet' domains or | 567 // In addition, unknown top-level domains (such as 'intranet' domains or |
563 // new TLDs/gTLDs not yet added to the registry controlled domain dataset) | 568 // new TLDs/gTLDs not yet added to the registry controlled domain dataset) |
564 // are also implicitly prevented. | 569 // are also implicitly prevented. |
565 // Because |reference_domain| must contain at least one name component that | 570 // Because |reference_domain| must contain at least one name component that |
566 // is not registry controlled, this ensures that all reference domains | 571 // is not registry controlled, this ensures that all reference domains |
567 // contain at least three domain components when using wildcards. | 572 // contain at least three domain components when using wildcards. |
568 size_t registry_length = | 573 size_t registry_length = registry_controlled_domains::GetRegistryLength( |
569 registry_controlled_domains::GetRegistryLength( | 574 reference_name, |
570 reference_name, | 575 registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES, |
571 registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES, | 576 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
572 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | |
573 | 577 |
574 // Because |reference_name| was already canonicalized, the following | 578 // Because |reference_name| was already canonicalized, the following |
575 // should never happen. | 579 // should never happen. |
576 CHECK_NE(std::string::npos, registry_length); | 580 CHECK_NE(std::string::npos, registry_length); |
577 | 581 |
578 // Account for the leading dot in |reference_domain|. | 582 // Account for the leading dot in |reference_domain|. |
579 bool is_registry_controlled = | 583 bool is_registry_controlled = |
580 registry_length != 0 && | 584 registry_length != 0 && |
581 registry_length == (reference_domain.size() - 1); | 585 registry_length == (reference_domain.size() - 1); |
582 | 586 |
(...skipping 10 matching lines...) Expand all Loading... |
593 std::vector<std::string> common_name_as_vector; | 597 std::vector<std::string> common_name_as_vector; |
594 const std::vector<std::string>* presented_names = &cert_san_dns_names; | 598 const std::vector<std::string>* presented_names = &cert_san_dns_names; |
595 if (common_name_fallback) { | 599 if (common_name_fallback) { |
596 // Note: there's a small possibility cert_common_name is an international | 600 // Note: there's a small possibility cert_common_name is an international |
597 // domain name in non-standard encoding (e.g. UTF8String or BMPString | 601 // domain name in non-standard encoding (e.g. UTF8String or BMPString |
598 // instead of A-label). As common name fallback is deprecated we're not | 602 // instead of A-label). As common name fallback is deprecated we're not |
599 // doing anything specific to deal with this. | 603 // doing anything specific to deal with this. |
600 common_name_as_vector.push_back(cert_common_name); | 604 common_name_as_vector.push_back(cert_common_name); |
601 presented_names = &common_name_as_vector; | 605 presented_names = &common_name_as_vector; |
602 } | 606 } |
603 for (std::vector<std::string>::const_iterator it = | 607 for (std::vector<std::string>::const_iterator it = presented_names->begin(); |
604 presented_names->begin(); | 608 it != presented_names->end(); |
605 it != presented_names->end(); ++it) { | 609 ++it) { |
606 // Catch badly corrupt cert names up front. | 610 // Catch badly corrupt cert names up front. |
607 if (it->empty() || it->find('\0') != std::string::npos) { | 611 if (it->empty() || it->find('\0') != std::string::npos) { |
608 DVLOG(1) << "Bad name in cert: " << *it; | 612 DVLOG(1) << "Bad name in cert: " << *it; |
609 continue; | 613 continue; |
610 } | 614 } |
611 std::string presented_name(StringToLowerASCII(*it)); | 615 std::string presented_name(StringToLowerASCII(*it)); |
612 | 616 |
613 // Remove trailing dot, if any. | 617 // Remove trailing dot, if any. |
614 if (*presented_name.rbegin() == '.') | 618 if (*presented_name.rbegin() == '.') |
615 presented_name.resize(presented_name.length() - 1); | 619 presented_name.resize(presented_name.length() - 1); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 reference_host.ends_with(pattern_end)) | 651 reference_host.ends_with(pattern_end)) |
648 return true; | 652 return true; |
649 } | 653 } |
650 return false; | 654 return false; |
651 } | 655 } |
652 | 656 |
653 bool X509Certificate::VerifyNameMatch(const std::string& hostname, | 657 bool X509Certificate::VerifyNameMatch(const std::string& hostname, |
654 bool* common_name_fallback_used) const { | 658 bool* common_name_fallback_used) const { |
655 std::vector<std::string> dns_names, ip_addrs; | 659 std::vector<std::string> dns_names, ip_addrs; |
656 GetSubjectAltName(&dns_names, &ip_addrs); | 660 GetSubjectAltName(&dns_names, &ip_addrs); |
657 return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs, | 661 return VerifyHostname(hostname, |
| 662 subject_.common_name, |
| 663 dns_names, |
| 664 ip_addrs, |
658 common_name_fallback_used); | 665 common_name_fallback_used); |
659 } | 666 } |
660 | 667 |
661 // static | 668 // static |
662 bool X509Certificate::GetPEMEncodedFromDER(const std::string& der_encoded, | 669 bool X509Certificate::GetPEMEncodedFromDER(const std::string& der_encoded, |
663 std::string* pem_encoded) { | 670 std::string* pem_encoded) { |
664 if (der_encoded.empty()) | 671 if (der_encoded.empty()) |
665 return false; | 672 return false; |
666 std::string b64_encoded; | 673 std::string b64_encoded; |
667 base::Base64Encode(der_encoded, &b64_encoded); | 674 base::Base64Encode(der_encoded, &b64_encoded); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 RemoveFromCache(cert_handle_); | 734 RemoveFromCache(cert_handle_); |
728 FreeOSCertHandle(cert_handle_); | 735 FreeOSCertHandle(cert_handle_); |
729 } | 736 } |
730 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | 737 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { |
731 RemoveFromCache(intermediate_ca_certs_[i]); | 738 RemoveFromCache(intermediate_ca_certs_[i]); |
732 FreeOSCertHandle(intermediate_ca_certs_[i]); | 739 FreeOSCertHandle(intermediate_ca_certs_[i]); |
733 } | 740 } |
734 } | 741 } |
735 | 742 |
736 } // namespace net | 743 } // namespace net |
OLD | NEW |