Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_ | |
| 6 #define NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_ | |
| 7 | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/compiler_specific.h" | |
| 11 #include "base/memory/scoped_ptr.h" | |
| 12 #include "net/base/ip_address_number.h" | |
| 13 | |
| 14 namespace net { | |
| 15 | |
| 16 namespace der { | |
| 17 class Input; | |
| 18 } // namespace der | |
| 19 | |
| 20 enum GeneralNameTypes { | |
|
Ryan Sleevi
2015/09/24 22:06:19
Document / reference where these names come from,
mattm
2015/09/30 04:52:31
Done.
| |
| 21 GENERAL_NAME_OTHER_NAME = 1 << 0, | |
| 22 GENERAL_NAME_RFC822_NAME = 1 << 1, | |
| 23 GENERAL_NAME_DNS_NAME = 1 << 2, | |
| 24 GENERAL_NAME_X400_ADDRESS = 1 << 3, | |
| 25 GENERAL_NAME_DIRECTORY_NAME = 1 << 4, | |
| 26 GENERAL_NAME_EDI_PARTY_NAME = 1 << 5, | |
| 27 GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER = 1 << 6, | |
| 28 GENERAL_NAME_IP_ADDRESS = 1 << 7, | |
| 29 GENERAL_NAME_REGISTERED_ID = 1 << 8, | |
| 30 }; | |
| 31 | |
| 32 // Parses a NameConstraints extension value and allows testing whether names are | |
| 33 // allowed under those constraints as defined by RFC 5280 section 4.2.1.10. | |
| 34 class NET_EXPORT NameConstraints { | |
| 35 public: | |
| 36 // TODO(mattm): This may need to be split out into a public class, since | |
| 37 // GeneralNames is used other places in a certificate also... | |
| 38 struct GeneralNames { | |
|
Ryan Sleevi
2015/09/24 22:06:19
DESIGN: Why is this a plural field?
That is, why
mattm
2015/09/30 04:52:31
Added a comment. It's mostly just an ease of use o
| |
| 39 GeneralNames(); | |
| 40 ~GeneralNames(); | |
| 41 | |
| 42 // ASCII hostnames. | |
|
Ryan Sleevi
2015/09/24 22:06:20
Pedantry: In a name constraint, it isn't a hostnam
mattm
2015/09/30 04:52:32
Is ".foo.com" valid in a dNSName constraint? That
Ryan Sleevi
2015/10/01 23:52:23
It is not; I learned something new :)
Doesn't mea
mattm
2015/10/06 21:55:07
Ok, left as is but added a test of this. (ParseNam
| |
| 43 std::vector<std::string> dns_names; | |
| 44 | |
| 45 // DER-encoded Name values (not including the Sequence tag). | |
| 46 std::vector<std::vector<uint8_t>> directory_names; | |
|
Ryan Sleevi
2015/09/24 22:06:19
Despite the MUST, I'm curious whether or not it's
mattm
2015/09/30 04:52:31
In the CT database, 3/4ths of the name constraints
| |
| 47 | |
| 48 // iPAddresses. For Subject Alternative Name this will be 4 bytes for IPv4 | |
| 49 // or 16 bytes for IPv6. For Name Constraints, it will be ip + netmask | |
| 50 // (8 bytes for IPv4, 32 bytes for IPv6). | |
|
Ryan Sleevi
2015/09/24 22:06:19
pedantry: "ipAddresses" is not a complete sentence
mattm
2015/09/30 04:52:31
done
| |
| 51 std::vector<std::vector<uint8_t>> ip_addresses; | |
| 52 | |
| 53 // Which name types were present, as a bitfield of GeneralNameTypes. | |
| 54 // Includes both the supported and unsupported types (although unsupported | |
| 55 // ones may not be recorded depending on the context, like non-critical name | |
| 56 // constraints.) | |
| 57 int present_name_types = 0; | |
| 58 }; | |
| 59 | |
| 60 ~NameConstraints(); | |
| 61 | |
| 62 // Parses a DER-encoded NameConstraints extension and initializes this object. | |
| 63 // Should only be called once on a given NameConstraints object (whether | |
| 64 // successful or not). | |
|
Ryan Sleevi
2015/09/24 22:06:19
This part of the comment isn't relevant, is it? Si
mattm
2015/09/30 04:52:32
Done.
| |
| 65 // |extension_value| should be the extnValue from the extension (not including | |
| 66 // the OCTET STRING tag). |is_critical| should be true if the extension was | |
| 67 // marked critical. Returns true if the extension was parsed successfully, | |
|
Ryan Sleevi
2015/09/24 22:06:19
single space after sentences. This file is inconsi
mattm
2015/09/30 04:52:31
Done.
| |
| 68 // after which the IsPermitted methods may be used to test if Names are | |
| 69 // permitted by the NameConstraints. | |
|
Ryan Sleevi
2015/09/24 22:06:19
This comment seems out of date?
mattm
2015/09/30 04:52:31
Done.
| |
| 70 // The object lifetime is not bound to the lifetime of |extension_value| data. | |
| 71 static scoped_ptr<NameConstraints> CreateFromDer( | |
| 72 const der::Input& extension_value, | |
| 73 bool is_critical); | |
| 74 | |
| 75 // Tests if a certificate is allowed by the name constraints. | |
|
Ryan Sleevi
2015/09/24 22:06:19
This isn't really testing a certificate though, it
mattm
2015/09/30 04:52:31
It doesn't take a certificate directly, but I'd sa
| |
| 76 // |subject_rdn_sequence| should be the DER-encoded value of the subject's | |
| 77 // RDNSequence (not including Sequence tag), and may be an empty ASN.1 | |
| 78 // sequence. |subject_alt_name_extnvalue_tlv| should be the extnValue of the | |
| 79 // subjectAltName extension (including the OCTET STRING tag & length), or | |
| 80 // empty if the cert did not have a subjectAltName extension. |is_leaf_cert| | |
| 81 // should be true if the certificate is the leaf of the certificate chain, in | |
| 82 // which case subject commonName hostname/ip checking is done. | |
| 83 bool IsPermittedCert(const der::Input& subject_rdn_sequence, | |
| 84 const der::Input& subject_alt_name_extnvalue_tlv, | |
| 85 bool is_leaf_cert) const; | |
|
Ryan Sleevi
2015/09/24 22:06:19
The design of this seems predicated on whether or
mattm
2015/09/30 04:52:31
If I understand the question, yes it would be poss
| |
| 86 | |
| 87 // Returns true if the ASCII hostname |name| is permitted. | |
| 88 // |name| may be a wildcard hostname (starts with "*."). Eg, "*.bar.com" | |
| 89 // would not be permitted if "bar.com" is permitted and "foo.bar.com" is | |
| 90 // excluded, while "*.baz.com" would only be permitted if "baz.com" is | |
| 91 // permitted. | |
| 92 bool IsPermittedDNSName(const std::string& name) const; | |
| 93 | |
| 94 // Returns true if the directoryName |name_rdn_sequence| is permitted. | |
| 95 // |name_rdn_sequence| should be the DER-encoded RDNSequence value (not | |
| 96 // including the Sequence tag.) | |
| 97 bool IsPermittedDirectoryName(const der::Input& name_rdn_sequence) const; | |
| 98 | |
| 99 // Returns true if the iPAddress |ip| is permitted. | |
| 100 bool IsPermittedIP(const IPAddressNumber& ip) const; | |
| 101 | |
| 102 // Returns a bitfield of GeneralNameTypes of all the types constrained by this | |
| 103 // NameConstraints. Name types that aren't supported will only be present if | |
| 104 // the name constraint they appeared in was marked critical. | |
| 105 // | |
| 106 // RFC 5280 section 4.2.1.10 says: | |
| 107 // Applications conforming to this profile MUST be able to process name | |
| 108 // constraints that are imposed on the directoryName name form and SHOULD be | |
| 109 // able to process name constraints that are imposed on the rfc822Name, | |
| 110 // uniformResourceIdentifier, dNSName, and iPAddress name forms. | |
| 111 // If a name constraints extension that is marked as critical | |
| 112 // imposes constraints on a particular name form, and an instance of | |
| 113 // that name form appears in the subject field or subjectAltName | |
| 114 // extension of a subsequent certificate, then the application MUST | |
| 115 // either process the constraint or reject the certificate. | |
| 116 int ConstrainedNameTypes() const; | |
| 117 | |
| 118 private: | |
| 119 bool Parse(const der::Input& extension_value, | |
| 120 bool is_critical) WARN_UNUSED_RESULT; | |
| 121 | |
| 122 GeneralNames permitted_subtrees_; | |
| 123 GeneralNames excluded_subtrees_; | |
| 124 }; | |
| 125 | |
| 126 } // namespace net | |
| 127 | |
| 128 #endif // NET_CERT_INTERNAL_NAME_CONSTRAINTS_H_ | |
| OLD | NEW |