1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/pki/general_names.h"
6
7 #include <cstring>
8
9 #include "net/cert/pki/cert_error_params.h"
10 #include "net/cert/pki/cert_errors.h"
11 #include "net/cert/pki/string_util.h"
12 #include "net/der/input.h"
13 #include "net/der/parser.h"
14 #include "net/der/tag.h"
15
16 namespace net {
17
18 DEFINE_CERT_ERROR_ID(kFailedParsingGeneralName, "Failed parsing GeneralName");
19
20 namespace {
21
22 DEFINE_CERT_ERROR_ID(kRFC822NameNotAscii, "rfc822Name is not ASCII");
23 DEFINE_CERT_ERROR_ID(kDnsNameNotAscii, "dNSName is not ASCII");
24 DEFINE_CERT_ERROR_ID(kURINotAscii, "uniformResourceIdentifier is not ASCII");
25 DEFINE_CERT_ERROR_ID(kFailedParsingIp, "Failed parsing iPAddress");
26 DEFINE_CERT_ERROR_ID(kUnknownGeneralNameType, "Unknown GeneralName type");
27 DEFINE_CERT_ERROR_ID(kFailedReadingGeneralNames,
28 "Failed reading GeneralNames SEQUENCE");
29 DEFINE_CERT_ERROR_ID(kGeneralNamesTrailingData,
30 "GeneralNames contains trailing data after the sequence");
31 DEFINE_CERT_ERROR_ID(kGeneralNamesEmpty,
32 "GeneralNames is a sequence of 0 elements");
33 DEFINE_CERT_ERROR_ID(kFailedReadingGeneralName,
34 "Failed reading GeneralName TLV");
35
36 // Return true if the bitmask |mask| contains only zeros after the first
37 // |prefix_length| bits.
IsSuffixZero(const IPAddressBytes & mask,unsigned prefix_length)38 bool IsSuffixZero(const IPAddressBytes& mask, unsigned prefix_length) {
39 size_t zero_bits = mask.size() * CHAR_BIT - prefix_length;
40 size_t zero_bytes = zero_bits / CHAR_BIT;
41 std::vector<uint8_t> zeros(zero_bytes, 0);
42 if (memcmp(zeros.data(), mask.data() + mask.size() - zero_bytes, zero_bytes))
43 return false;
44 size_t leftover_bits = zero_bits % CHAR_BIT;
45 if (leftover_bits) {
46 uint8_t b = mask[mask.size() - zero_bytes - 1];
47 for (size_t i = 0; i < leftover_bits; ++i) {
48 if (b & (1 << i))
49 return false;
50 }
51 }
52 return true;
53 }
54
55 } // namespace
56
57 GeneralNames::GeneralNames() = default;
58
59 GeneralNames::~GeneralNames() = default;
60
61 // static
Create(const der::Input & general_names_tlv,CertErrors * errors)62 std::unique_ptr<GeneralNames> GeneralNames::Create(
63 const der::Input& general_names_tlv,
64 CertErrors* errors) {
65 DCHECK(errors);
66
67 // RFC 5280 section 4.2.1.6:
68 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
69 der::Parser parser(general_names_tlv);
70 der::Input sequence_value;
71 if (!parser.ReadTag(der::kSequence, &sequence_value)) {
72 errors->AddError(kFailedReadingGeneralNames);
73 return nullptr;
74 }
75 // Should not have trailing data after GeneralNames sequence.
76 if (parser.HasMore()) {
77 errors->AddError(kGeneralNamesTrailingData);
78 return nullptr;
79 }
80 return CreateFromValue(sequence_value, errors);
81 }
82
83 // static
CreateFromValue(const der::Input & general_names_value,CertErrors * errors)84 std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue(
85 const der::Input& general_names_value,
86 CertErrors* errors) {
87 DCHECK(errors);
88
89 auto general_names = std::make_unique<GeneralNames>();
90
91 der::Parser sequence_parser(general_names_value);
92 // The GeneralNames sequence should have at least 1 element.
93 if (!sequence_parser.HasMore()) {
94 errors->AddError(kGeneralNamesEmpty);
95 return nullptr;
96 }
97
98 while (sequence_parser.HasMore()) {
99 der::Input raw_general_name;
100 if (!sequence_parser.ReadRawTLV(&raw_general_name)) {
101 errors->AddError(kFailedReadingGeneralName);
102 return nullptr;
103 }
104
105 if (!ParseGeneralName(raw_general_name, IP_ADDRESS_ONLY,
106 general_names.get(), errors)) {
107 errors->AddError(kFailedParsingGeneralName);
108 return nullptr;
109 }
110 }
111
112 return general_names;
113 }
114
ParseGeneralName(const der::Input & input,GeneralNames::ParseGeneralNameIPAddressType ip_address_type,GeneralNames * subtrees,CertErrors * errors)115 [[nodiscard]] bool ParseGeneralName(
116 const der::Input& input,
117 GeneralNames::ParseGeneralNameIPAddressType ip_address_type,
118 GeneralNames* subtrees,
119 CertErrors* errors) {
120 DCHECK(errors);
121 der::Parser parser(input);
122 der::Tag tag;
123 der::Input value;
124 if (!parser.ReadTagAndValue(&tag, &value))
125 return false;
126 GeneralNameTypes name_type = GENERAL_NAME_NONE;
127 if (tag == der::ContextSpecificConstructed(0)) {
128 // otherName [0] OtherName,
129 name_type = GENERAL_NAME_OTHER_NAME;
130 subtrees->other_names.push_back(value);
131 } else if (tag == der::ContextSpecificPrimitive(1)) {
132 // rfc822Name [1] IA5String,
133 name_type = GENERAL_NAME_RFC822_NAME;
134 const std::string_view s = value.AsStringView();
135 if (!net::string_util::IsAscii(s)) {
136 errors->AddError(kRFC822NameNotAscii);
137 return false;
138 }
139 subtrees->rfc822_names.push_back(s);
140 } else if (tag == der::ContextSpecificPrimitive(2)) {
141 // dNSName [2] IA5String,
142 name_type = GENERAL_NAME_DNS_NAME;
143 const std::string_view s = value.AsStringView();
144 if (!net::string_util::IsAscii(s)) {
145 errors->AddError(kDnsNameNotAscii);
146 return false;
147 }
148 subtrees->dns_names.push_back(s);
149 } else if (tag == der::ContextSpecificConstructed(3)) {
150 // x400Address [3] ORAddress,
151 name_type = GENERAL_NAME_X400_ADDRESS;
152 subtrees->x400_addresses.push_back(value);
153 } else if (tag == der::ContextSpecificConstructed(4)) {
154 // directoryName [4] Name,
155 name_type = GENERAL_NAME_DIRECTORY_NAME;
156 // Name is a CHOICE { rdnSequence RDNSequence }, therefore the SEQUENCE
157 // tag is explicit. Remove it, since the name matching functions expect
158 // only the value portion.
159 der::Parser name_parser(value);
160 der::Input name_value;
161 if (!name_parser.ReadTag(der::kSequence, &name_value) || parser.HasMore())
162 return false;
163 subtrees->directory_names.push_back(name_value);
164 } else if (tag == der::ContextSpecificConstructed(5)) {
165 // ediPartyName [5] EDIPartyName,
166 name_type = GENERAL_NAME_EDI_PARTY_NAME;
167 subtrees->edi_party_names.push_back(value);
168 } else if (tag == der::ContextSpecificPrimitive(6)) {
169 // uniformResourceIdentifier [6] IA5String,
170 name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER;
171 const std::string_view s = value.AsStringView();
172 if (!net::string_util::IsAscii(s)) {
173 errors->AddError(kURINotAscii);
174 return false;
175 }
176 subtrees->uniform_resource_identifiers.push_back(s);
177 } else if (tag == der::ContextSpecificPrimitive(7)) {
178 // iPAddress [7] OCTET STRING,
179 name_type = GENERAL_NAME_IP_ADDRESS;
180 if (ip_address_type == GeneralNames::IP_ADDRESS_ONLY) {
181 // RFC 5280 section 4.2.1.6:
182 // When the subjectAltName extension contains an iPAddress, the address
183 // MUST be stored in the octet string in "network byte order", as
184 // specified in [RFC791]. The least significant bit (LSB) of each octet
185 // is the LSB of the corresponding byte in the network address. For IP
186 // version 4, as specified in [RFC791], the octet string MUST contain
187 // exactly four octets. For IP version 6, as specified in [RFC2460],
188 // the octet string MUST contain exactly sixteen octets.
189 if ((value.Length() != IPAddress::kIPv4AddressSize &&
190 value.Length() != IPAddress::kIPv6AddressSize)) {
191 errors->AddError(kFailedParsingIp);
192 return false;
193 }
194 subtrees->ip_addresses.emplace_back(value.UnsafeData(), value.Length());
195 } else {
196 DCHECK_EQ(ip_address_type, GeneralNames::IP_ADDRESS_AND_NETMASK);
197 // RFC 5280 section 4.2.1.10:
198 // The syntax of iPAddress MUST be as described in Section 4.2.1.6 with
199 // the following additions specifically for name constraints. For IPv4
200 // addresses, the iPAddress field of GeneralName MUST contain eight (8)
201 // octets, encoded in the style of RFC 4632 (CIDR) to represent an
202 // address range [RFC4632]. For IPv6 addresses, the iPAddress field
203 // MUST contain 32 octets similarly encoded. For example, a name
204 // constraint for "class C" subnet 192.0.2.0 is represented as the
205 // octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
206 // 192.0.2.0/24 (mask 255.255.255.0).
207 if (value.Length() != IPAddress::kIPv4AddressSize * 2 &&
208 value.Length() != IPAddress::kIPv6AddressSize * 2) {
209 errors->AddError(kFailedParsingIp);
210 return false;
211 }
212 const IPAddress mask(value.UnsafeData() + value.Length() / 2,
213 value.Length() / 2);
214 const unsigned mask_prefix_length = MaskPrefixLength(mask);
215 if (!IsSuffixZero(mask.bytes(), mask_prefix_length)) {
216 errors->AddError(kFailedParsingIp);
217 return false;
218 }
219 subtrees->ip_address_ranges.emplace_back(
220 IPAddress(value.UnsafeData(), value.Length() / 2),
221 mask_prefix_length);
222 }
223 } else if (tag == der::ContextSpecificPrimitive(8)) {
224 // registeredID [8] OBJECT IDENTIFIER }
225 name_type = GENERAL_NAME_REGISTERED_ID;
226 subtrees->registered_ids.push_back(value);
227 } else {
228 errors->AddError(kUnknownGeneralNameType,
229 CreateCertErrorParams1SizeT("tag", tag));
230 return false;
231 }
232 DCHECK_NE(GENERAL_NAME_NONE, name_type);
233 subtrees->present_name_types |= name_type;
234 return true;
235 }
236
237 } // namespace net
238