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