| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/internal/name_constraints.h" | 5 #include "net/cert/internal/name_constraints.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 | 8 |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "net/cert/internal/verify_name_match.h" | 10 #include "net/cert/internal/verify_name_match.h" |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 return false; | 389 return false; |
| 390 | 390 |
| 391 if (sequence_parser.HasMore()) | 391 if (sequence_parser.HasMore()) |
| 392 return false; | 392 return false; |
| 393 | 393 |
| 394 return true; | 394 return true; |
| 395 } | 395 } |
| 396 | 396 |
| 397 bool NameConstraints::IsPermittedCert( | 397 bool NameConstraints::IsPermittedCert( |
| 398 const der::Input& subject_rdn_sequence, | 398 const der::Input& subject_rdn_sequence, |
| 399 const der::Input& subject_alt_name_extnvalue_tlv) const { | 399 bool has_subject_alt_name, |
| 400 const der::Input& subject_alt_name_tlv) const { |
| 400 // Subject Alternative Name handling: | 401 // Subject Alternative Name handling: |
| 401 // | 402 // |
| 402 // RFC 5280 section 4.2.1.6: | 403 // RFC 5280 section 4.2.1.6: |
| 403 // id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } | 404 // id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } |
| 404 // | 405 // |
| 405 // SubjectAltName ::= GeneralNames | 406 // SubjectAltName ::= GeneralNames |
| 406 // | 407 // |
| 407 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName | 408 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName |
| 408 | 409 |
| 409 GeneralNames san_names; | 410 GeneralNames san_names; |
| 410 if (subject_alt_name_extnvalue_tlv.Length()) { | 411 if (has_subject_alt_name) { |
| 411 der::Parser extnvalue_parser(subject_alt_name_extnvalue_tlv); | |
| 412 der::Input subject_alt_name_tlv; | |
| 413 if (!extnvalue_parser.ReadTag(der::kOctetString, &subject_alt_name_tlv)) | |
| 414 return false; | |
| 415 | |
| 416 der::Parser subject_alt_name_parser(subject_alt_name_tlv); | 412 der::Parser subject_alt_name_parser(subject_alt_name_tlv); |
| 417 der::Parser san_sequence_parser; | 413 der::Parser san_sequence_parser; |
| 418 if (!subject_alt_name_parser.ReadSequence(&san_sequence_parser)) | 414 if (!subject_alt_name_parser.ReadSequence(&san_sequence_parser)) |
| 419 return false; | 415 return false; |
| 420 // Should not have trailing data after subjectAltName sequence. | 416 // Should not have trailing data after subjectAltName sequence. |
| 421 if (subject_alt_name_parser.HasMore()) | 417 if (subject_alt_name_parser.HasMore()) |
| 422 return false; | 418 return false; |
| 423 // The subjectAltName sequence should have at least 1 element. | 419 // The subjectAltName sequence should have at least 1 element. |
| 424 if (!san_sequence_parser.HasMore()) | 420 if (!san_sequence_parser.HasMore()) |
| 425 return false; | 421 return false; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 if (!IsPermittedDirectoryName( | 455 if (!IsPermittedDirectoryName( |
| 460 der::Input(directory_name.data(), directory_name.size()))) { | 456 der::Input(directory_name.data(), directory_name.size()))) { |
| 461 return false; | 457 return false; |
| 462 } | 458 } |
| 463 } | 459 } |
| 464 | 460 |
| 465 for (const auto& ip_address : san_names.ip_addresses) { | 461 for (const auto& ip_address : san_names.ip_addresses) { |
| 466 if (!IsPermittedIP(ip_address)) | 462 if (!IsPermittedIP(ip_address)) |
| 467 return false; | 463 return false; |
| 468 } | 464 } |
| 465 } else { |
| 466 DCHECK_EQ(0U, subject_alt_name_tlv.Length()); |
| 469 } | 467 } |
| 470 | 468 |
| 471 // Subject handling: | 469 // Subject handling: |
| 472 | 470 |
| 473 // RFC 5280 section 4.2.1.10: | 471 // RFC 5280 section 4.2.1.10: |
| 474 // Legacy implementations exist where an electronic mail address is embedded | 472 // Legacy implementations exist where an electronic mail address is embedded |
| 475 // in the subject distinguished name in an attribute of type emailAddress | 473 // in the subject distinguished name in an attribute of type emailAddress |
| 476 // (Section 4.1.2.6). When constraints are imposed on the rfc822Name name | 474 // (Section 4.1.2.6). When constraints are imposed on the rfc822Name name |
| 477 // form, but the certificate does not include a subject alternative name, the | 475 // form, but the certificate does not include a subject alternative name, the |
| 478 // rfc822Name constraint MUST be applied to the attribute of type emailAddress | 476 // rfc822Name constraint MUST be applied to the attribute of type emailAddress |
| 479 // in the subject distinguished name. | 477 // in the subject distinguished name. |
| 480 if (!subject_alt_name_extnvalue_tlv.Length() && | 478 if (!has_subject_alt_name && |
| 481 (ConstrainedNameTypes() & GENERAL_NAME_RFC822_NAME)) { | 479 (ConstrainedNameTypes() & GENERAL_NAME_RFC822_NAME)) { |
| 482 bool contained_email_address = false; | 480 bool contained_email_address = false; |
| 483 if (!NameContainsEmailAddress(subject_rdn_sequence, | 481 if (!NameContainsEmailAddress(subject_rdn_sequence, |
| 484 &contained_email_address)) { | 482 &contained_email_address)) { |
| 485 return false; | 483 return false; |
| 486 } | 484 } |
| 487 if (contained_email_address) | 485 if (contained_email_address) |
| 488 return false; | 486 return false; |
| 489 } | 487 } |
| 490 | 488 |
| 491 // RFC 5280 4.1.2.6: | 489 // RFC 5280 4.1.2.6: |
| 492 // If subject naming information is present only in the subjectAltName | 490 // If subject naming information is present only in the subjectAltName |
| 493 // extension (e.g., a key bound only to an email address or URI), then the | 491 // extension (e.g., a key bound only to an email address or URI), then the |
| 494 // subject name MUST be an empty sequence and the subjectAltName extension | 492 // subject name MUST be an empty sequence and the subjectAltName extension |
| 495 // MUST be critical. | 493 // MUST be critical. |
| 496 // This code assumes that criticality condition is checked by the caller, and | 494 // This code assumes that criticality condition is checked by the caller, and |
| 497 // therefore only needs to avoid the IsPermittedDirectoryName check against an | 495 // therefore only needs to avoid the IsPermittedDirectoryName check against an |
| 498 // empty subject in such a case. | 496 // empty subject in such a case. |
| 499 if (subject_alt_name_extnvalue_tlv.Length() && | 497 if (has_subject_alt_name && subject_rdn_sequence.Length() == 0) |
| 500 subject_rdn_sequence.Length() == 0) { | |
| 501 return true; | 498 return true; |
| 502 } | |
| 503 | 499 |
| 504 return IsPermittedDirectoryName(subject_rdn_sequence); | 500 return IsPermittedDirectoryName(subject_rdn_sequence); |
| 505 } | 501 } |
| 506 | 502 |
| 507 bool NameConstraints::IsPermittedDNSName(const std::string& name) const { | 503 bool NameConstraints::IsPermittedDNSName(const std::string& name) const { |
| 508 for (const std::string& excluded_name : excluded_subtrees_.dns_names) { | 504 for (const std::string& excluded_name : excluded_subtrees_.dns_names) { |
| 509 // When matching wildcard hosts against excluded subtrees, consider it a | 505 // When matching wildcard hosts against excluded subtrees, consider it a |
| 510 // match if the constraint would match any expansion of the wildcard. Eg, | 506 // match if the constraint would match any expansion of the wildcard. Eg, |
| 511 // *.bar.com should match a constraint of foo.bar.com. | 507 // *.bar.com should match a constraint of foo.bar.com. |
| 512 if (DNSNameMatches(name, excluded_name, WILDCARD_PARTIAL_MATCH)) | 508 if (DNSNameMatches(name, excluded_name, WILDCARD_PARTIAL_MATCH)) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 | 569 |
| 574 return false; | 570 return false; |
| 575 } | 571 } |
| 576 | 572 |
| 577 int NameConstraints::ConstrainedNameTypes() const { | 573 int NameConstraints::ConstrainedNameTypes() const { |
| 578 return (permitted_subtrees_.present_name_types | | 574 return (permitted_subtrees_.present_name_types | |
| 579 excluded_subtrees_.present_name_types); | 575 excluded_subtrees_.present_name_types); |
| 580 } | 576 } |
| 581 | 577 |
| 582 } // namespace net | 578 } // namespace net |
| OLD | NEW |