// Copyright 2015 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "name_constraints.h" #include <limits.h> #include <memory> #include <optional> #include <openssl/base.h> #include <openssl/bytestring.h> #include "cert_errors.h" #include "common_cert_errors.h" #include "general_names.h" #include "input.h" #include "ip_util.h" #include "parser.h" #include "string_util.h" #include "verify_name_match.h" BSSL_NAMESPACE_BEGIN namespace { // The name types of GeneralName that are fully supported in name constraints. // // (The other types will have the minimal checking described by RFC 5280 // section 4.2.1.10: If a name constraints extension that is marked as critical // imposes constraints on a particular name form, and an instance of // that name form appears in the subject field or subjectAltName // extension of a subsequent certificate, then the application MUST // either process the constraint or reject the certificate.) const int kSupportedNameTypes = …; // Controls wildcard handling of DNSNameMatches. // If WildcardMatchType is WILDCARD_PARTIAL_MATCH "*.bar.com" is considered to // match the constraint "foo.bar.com". If it is WILDCARD_FULL_MATCH, "*.bar.com" // will match "bar.com" but not "foo.bar.com". enum WildcardMatchType { … }; // Returns true if |name| falls in the subtree defined by |dns_constraint|. // RFC 5280 section 4.2.1.10: // DNS name restrictions are expressed as host.example.com. Any DNS // name that can be constructed by simply adding zero or more labels // to the left-hand side of the name satisfies the name constraint. For // example, www.host.example.com would satisfy the constraint but // host1.example.com would not. // // |wildcard_matching| controls handling of wildcard names (|name| starts with // "*."). Wildcard handling is not specified by RFC 5280, but certificate // verification allows it, name constraints must check it similarly. bool DNSNameMatches(std::string_view name, std::string_view dns_constraint, WildcardMatchType wildcard_matching) { … } // Parses a GeneralSubtrees |value| and store the contents in |subtrees|. // The individual values stored into |subtrees| are not validated by this // function. // NOTE: |subtrees| is not pre-initialized by the function(it is expected to be // a default initialized object), and it will be modified regardless of the // return value. [[nodiscard]] bool ParseGeneralSubtrees(der::Input value, GeneralNames *subtrees, CertErrors *errors) { … } bool IsAlphaDigit(char c) { … } // Returns true if 'local_part' contains only characters that are valid in a // non-quoted mailbox local-part. Does not check any other part of the syntax // requirements. Does not allow whitespace. bool IsAllowedRfc822LocalPart(std::string_view local_part) { … } // Returns true if 'domain' contains only characters that are valid in a // mailbox domain. Does not check any other part of the syntax // requirements. Does not allow IPv6-address-literal as text IPv6 addresses are // non-unique. Does not allow other address literals either as how to handle // them with domain/subdomain matching isn't specified/possible. bool IsAllowedRfc822Domain(std::string_view domain) { … } enum class Rfc822NameMatchType { … }; bool Rfc822NameMatches(std::string_view local_part, std::string_view domain, std::string_view rfc822_constraint, Rfc822NameMatchType match_type, bool case_insensitive_local_part) { … } } // namespace NameConstraints::~NameConstraints() = default; // static std::unique_ptr<NameConstraints> NameConstraints::Create( der::Input extension_value, bool is_critical, CertErrors *errors) { … } std::unique_ptr<NameConstraints> NameConstraints::CreateFromPermittedSubtrees( GeneralNames permitted_subtrees) { … } bool NameConstraints::Parse(der::Input extension_value, bool is_critical, CertErrors *errors) { … } void NameConstraints::IsPermittedCert(der::Input subject_rdn_sequence, const GeneralNames *subject_alt_names, CertErrors *errors) const { … } bool NameConstraints::IsPermittedRfc822Name( std::string_view name, bool case_insensitive_exclude_localpart) const { … } bool NameConstraints::IsPermittedDNSName(std::string_view name) const { … } bool NameConstraints::IsPermittedDirectoryName( der::Input name_rdn_sequence) const { … } bool NameConstraints::IsPermittedIP(der::Input ip) const { … } BSSL_NAMESPACE_END