| // Copyright 2015 The Chromium Authors | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #ifndef BSSL_PKI_NAME_CONSTRAINTS_H_ | |
| #define BSSL_PKI_NAME_CONSTRAINTS_H_ | |
| #include <memory> | |
| #include <openssl/base.h> | |
| #include "general_names.h" | |
| BSSL_NAMESPACE_BEGIN | |
| class CertErrors; | |
| namespace der { | |
| class Input; | |
| } // namespace der | |
| // Parses a NameConstraints extension value and allows testing whether names are | |
| // allowed under those constraints as defined by RFC 5280 section 4.2.1.10. | |
| class OPENSSL_EXPORT NameConstraints { | |
| public: | |
| // Parses a DER-encoded NameConstraints extension and initializes this object. | |
| // `extension_value` should be the extnValue from the extension (not including | |
| // the OCTET STRING tag). `is_critical` should be true if the extension was | |
| // marked critical. Returns nullptr if parsing the extension failed. | |
| // The object may reference data from `extension_value`, so is only valid as | |
| // long as `extension_value` is. | |
| static std::unique_ptr<NameConstraints> Create(der::Input extension_value, | |
| bool is_critical, | |
| CertErrors *errors); | |
| // Create a NameConstraints object with only permitted names from the passed | |
| // in `permitted_subtrees`. Should never return nullptr. | |
| static std::unique_ptr<NameConstraints> CreateFromPermittedSubtrees( | |
| GeneralNames permitted_subtrees); | |
| // Tests if a certificate is allowed by the name constraints. | |
| // `subject_rdn_sequence` should be the DER-encoded value of the subject's | |
| // RDNSequence (not including Sequence tag), and may be an empty ASN.1 | |
| // sequence. `subject_alt_names` should be the parsed representation of the | |
| // subjectAltName extension or nullptr if the extension was not present. | |
| // If the certificate is not allowed, an error will be added to `errors`. | |
| // Note that this method does not check hostname or IP address in commonName, | |
| // which is deprecated (crbug.com/308330). | |
| void IsPermittedCert(der::Input subject_rdn_sequence, | |
| const GeneralNames *subject_alt_names, | |
| CertErrors *errors) const; | |
| // Returns true if the ASCII email address `name` is permitted. `name` should | |
| // be a "mailbox" as specified by RFC 2821, with the additional restriction | |
| // that quoted names and whitespace are not allowed by this implementation. | |
| bool IsPermittedRfc822Name(std::string_view name, | |
| bool case_insensitive_exclude_localpart) const; | |
| // Returns true if the ASCII hostname `name` is permitted. | |
| // `name` may be a wildcard hostname (starts with "*."). Eg, "*.bar.com" | |
| // would not be permitted if "bar.com" is permitted and "foo.bar.com" is | |
| // excluded, while "*.baz.com" would only be permitted if "baz.com" is | |
| // permitted. | |
| bool IsPermittedDNSName(std::string_view name) const; | |
| // Returns true if the directoryName `name_rdn_sequence` is permitted. | |
| // `name_rdn_sequence` should be the DER-encoded RDNSequence value (not | |
| // including the Sequence tag.) | |
| bool IsPermittedDirectoryName(der::Input name_rdn_sequence) const; | |
| // Returns true if the iPAddress `ip` is permitted. | |
| bool IsPermittedIP(der::Input ip) const; | |
| // Returns a bitfield of GeneralNameTypes of all the types constrained by this | |
| // NameConstraints. Name types that aren't supported will only be present if | |
| // the name constraint they appeared in was marked critical. | |
| // | |
| // RFC 5280 section 4.2.1.10 says: | |
| // Applications conforming to this profile MUST be able to process name | |
| // constraints that are imposed on the directoryName name form and SHOULD be | |
| // able to process name constraints that are imposed on the rfc822Name, | |
| // uniformResourceIdentifier, dNSName, and iPAddress name forms. | |
| // 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. | |
| int constrained_name_types() const { return constrained_name_types_; } | |
| const GeneralNames &permitted_subtrees() const { return permitted_subtrees_; } | |
| const GeneralNames &excluded_subtrees() const { return excluded_subtrees_; } | |
| private: | |
| [[nodiscard]] bool Parse(der::Input extension_value, bool is_critical, | |
| CertErrors *errors); | |
| GeneralNames permitted_subtrees_; | |
| GeneralNames excluded_subtrees_; | |
| int constrained_name_types_ = GENERAL_NAME_NONE; | |
| }; | |
| BSSL_NAMESPACE_END | |
| #endif // BSSL_PKI_NAME_CONSTRAINTS_H_ |