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 #include <openssl/bytestring.h>
9
10 #include <climits>
11 #include <cstring>
12
13 #include "cert_error_params.h"
14 #include "cert_errors.h"
15 #include "input.h"
16 #include "ip_util.h"
17 #include "parser.h"
18 #include "string_util.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(der::Input general_names_tlv,CertErrors * errors)47 std::unique_ptr<GeneralNames> GeneralNames::Create(der::Input general_names_tlv,
48 CertErrors *errors) {
49 BSSL_CHECK(errors);
50
51 // RFC 5280 section 4.2.1.6:
52 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
53 der::Parser parser(general_names_tlv);
54 der::Input sequence_value;
55 if (!parser.ReadTag(CBS_ASN1_SEQUENCE, &sequence_value)) {
56 errors->AddError(kFailedReadingGeneralNames);
57 return nullptr;
58 }
59 // Should not have trailing data after GeneralNames sequence.
60 if (parser.HasMore()) {
61 errors->AddError(kGeneralNamesTrailingData);
62 return nullptr;
63 }
64 return CreateFromValue(sequence_value, errors);
65 }
66
67 // static
CreateFromValue(der::Input general_names_value,CertErrors * errors)68 std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue(
69 der::Input general_names_value, CertErrors *errors) {
70 BSSL_CHECK(errors);
71
72 auto general_names = std::make_unique<GeneralNames>();
73
74 der::Parser sequence_parser(general_names_value);
75 // The GeneralNames sequence should have at least 1 element.
76 if (!sequence_parser.HasMore()) {
77 errors->AddError(kGeneralNamesEmpty);
78 return nullptr;
79 }
80
81 while (sequence_parser.HasMore()) {
82 der::Input raw_general_name;
83 if (!sequence_parser.ReadRawTLV(&raw_general_name)) {
84 errors->AddError(kFailedReadingGeneralName);
85 return nullptr;
86 }
87
88 if (!ParseGeneralName(raw_general_name, IP_ADDRESS_ONLY,
89 general_names.get(), errors)) {
90 errors->AddError(kFailedParsingGeneralName);
91 return nullptr;
92 }
93 }
94
95 return general_names;
96 }
97
ParseGeneralName(der::Input input,GeneralNames::ParseGeneralNameIPAddressType ip_address_type,GeneralNames * subtrees,CertErrors * errors)98 [[nodiscard]] bool ParseGeneralName(
99 der::Input input,
100 GeneralNames::ParseGeneralNameIPAddressType ip_address_type,
101 GeneralNames *subtrees, CertErrors *errors) {
102 BSSL_CHECK(errors);
103 der::Parser parser(input);
104 CBS_ASN1_TAG tag;
105 der::Input value;
106 if (!parser.ReadTagAndValue(&tag, &value)) {
107 return false;
108 }
109 GeneralNameTypes name_type = GENERAL_NAME_NONE;
110 if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
111 // otherName [0] OtherName,
112 name_type = GENERAL_NAME_OTHER_NAME;
113 subtrees->other_names.push_back(value);
114 } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 1)) {
115 // rfc822Name [1] IA5String,
116 name_type = GENERAL_NAME_RFC822_NAME;
117 const std::string_view s = BytesAsStringView(value);
118 if (!bssl::string_util::IsAscii(s)) {
119 errors->AddError(kRFC822NameNotAscii);
120 return false;
121 }
122 subtrees->rfc822_names.push_back(s);
123 } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 2)) {
124 // dNSName [2] IA5String,
125 name_type = GENERAL_NAME_DNS_NAME;
126 const std::string_view s = BytesAsStringView(value);
127 if (!bssl::string_util::IsAscii(s)) {
128 errors->AddError(kDnsNameNotAscii);
129 return false;
130 }
131 subtrees->dns_names.push_back(s);
132 } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3)) {
133 // x400Address [3] ORAddress,
134 name_type = GENERAL_NAME_X400_ADDRESS;
135 subtrees->x400_addresses.push_back(value);
136 } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 4)) {
137 // directoryName [4] Name,
138 name_type = GENERAL_NAME_DIRECTORY_NAME;
139 // Name is a CHOICE { rdnSequence RDNSequence }, therefore the SEQUENCE
140 // tag is explicit. Remove it, since the name matching functions expect
141 // only the value portion.
142 der::Parser name_parser(value);
143 der::Input name_value;
144 if (!name_parser.ReadTag(CBS_ASN1_SEQUENCE, &name_value) ||
145 parser.HasMore()) {
146 return false;
147 }
148 subtrees->directory_names.push_back(name_value);
149 } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 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 == (CBS_ASN1_CONTEXT_SPECIFIC | 6)) {
154 // uniformResourceIdentifier [6] IA5String,
155 name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER;
156 const std::string_view s = BytesAsStringView(value);
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 == (CBS_ASN1_CONTEXT_SPECIFIC | 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.size() != kIPv4AddressSize &&
175 value.size() != 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.size() != kIPv4AddressSize * 2 &&
193 value.size() != kIPv6AddressSize * 2) {
194 errors->AddError(kFailedParsingIp);
195 return false;
196 }
197 der::Input addr = value.first(value.size() / 2);
198 der::Input mask = value.subspan(value.size() / 2);
199 if (!IsValidNetmask(mask)) {
200 errors->AddError(kFailedParsingIp);
201 return false;
202 }
203 subtrees->ip_address_ranges.emplace_back(addr, mask);
204 }
205 } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 8)) {
206 // registeredID [8] OBJECT IDENTIFIER }
207 name_type = GENERAL_NAME_REGISTERED_ID;
208 subtrees->registered_ids.push_back(value);
209 } else {
210 errors->AddError(kUnknownGeneralNameType,
211 CreateCertErrorParams1SizeT("tag", tag));
212 return false;
213 }
214 BSSL_CHECK(GENERAL_NAME_NONE != name_type);
215 subtrees->present_name_types |= name_type;
216 return true;
217 }
218
219 } // namespace bssl
220