blob: a881c11e8605519fdaac2006189b6117505ab20e [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// 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
Bob Beck05007562023-08-17 20:22:17 +00007#include <openssl/base.h>
8
Bob Beckbc97b7a2023-04-18 08:35:15 -06009#include <climits>
10#include <cstring>
11
12#include "cert_error_params.h"
13#include "cert_errors.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060014#include "input.h"
Bob Beck5c7a2a02023-11-20 17:28:21 -070015#include "ip_util.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060016#include "parser.h"
Bob Beck5c7a2a02023-11-20 17:28:21 -070017#include "string_util.h"
Bob Beckbc97b7a2023-04-18 08:35:15 -060018#include "tag.h"
19
20namespace bssl {
21
22DEFINE_CERT_ERROR_ID(kFailedParsingGeneralName, "Failed parsing GeneralName");
23
24namespace {
25
26DEFINE_CERT_ERROR_ID(kRFC822NameNotAscii, "rfc822Name is not ASCII");
27DEFINE_CERT_ERROR_ID(kDnsNameNotAscii, "dNSName is not ASCII");
28DEFINE_CERT_ERROR_ID(kURINotAscii, "uniformResourceIdentifier is not ASCII");
29DEFINE_CERT_ERROR_ID(kFailedParsingIp, "Failed parsing iPAddress");
30DEFINE_CERT_ERROR_ID(kUnknownGeneralNameType, "Unknown GeneralName type");
31DEFINE_CERT_ERROR_ID(kFailedReadingGeneralNames,
32 "Failed reading GeneralNames SEQUENCE");
33DEFINE_CERT_ERROR_ID(kGeneralNamesTrailingData,
34 "GeneralNames contains trailing data after the sequence");
35DEFINE_CERT_ERROR_ID(kGeneralNamesEmpty,
36 "GeneralNames is a sequence of 0 elements");
37DEFINE_CERT_ERROR_ID(kFailedReadingGeneralName,
38 "Failed reading GeneralName TLV");
39
Bob Beckbc97b7a2023-04-18 08:35:15 -060040} // namespace
41
42GeneralNames::GeneralNames() = default;
43
44GeneralNames::~GeneralNames() = default;
45
46// static
47std::unique_ptr<GeneralNames> GeneralNames::Create(
Bob Beck5c7a2a02023-11-20 17:28:21 -070048 const der::Input &general_names_tlv, CertErrors *errors) {
Bob Beck05007562023-08-17 20:22:17 +000049 BSSL_CHECK(errors);
Bob Beckbc97b7a2023-04-18 08:35:15 -060050
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(der::kSequence, &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
68std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue(
Bob Beck5c7a2a02023-11-20 17:28:21 -070069 const der::Input &general_names_value, CertErrors *errors) {
Bob Beck05007562023-08-17 20:22:17 +000070 BSSL_CHECK(errors);
Bob Beckbc97b7a2023-04-18 08:35:15 -060071
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
98[[nodiscard]] bool ParseGeneralName(
Bob Beck5c7a2a02023-11-20 17:28:21 -070099 const der::Input &input,
Bob Beckbc97b7a2023-04-18 08:35:15 -0600100 GeneralNames::ParseGeneralNameIPAddressType ip_address_type,
Bob Beck5c7a2a02023-11-20 17:28:21 -0700101 GeneralNames *subtrees, CertErrors *errors) {
Bob Beck05007562023-08-17 20:22:17 +0000102 BSSL_CHECK(errors);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600103 der::Parser parser(input);
104 der::Tag tag;
105 der::Input value;
Bob Beck6beabf32023-11-21 09:43:52 -0700106 if (!parser.ReadTagAndValue(&tag, &value)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600107 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700108 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600109 GeneralNameTypes name_type = GENERAL_NAME_NONE;
110 if (tag == der::ContextSpecificConstructed(0)) {
111 // otherName [0] OtherName,
112 name_type = GENERAL_NAME_OTHER_NAME;
113 subtrees->other_names.push_back(value);
114 } else if (tag == der::ContextSpecificPrimitive(1)) {
115 // rfc822Name [1] IA5String,
116 name_type = GENERAL_NAME_RFC822_NAME;
117 const std::string_view s = value.AsStringView();
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 == der::ContextSpecificPrimitive(2)) {
124 // dNSName [2] IA5String,
125 name_type = GENERAL_NAME_DNS_NAME;
126 const std::string_view s = value.AsStringView();
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 == der::ContextSpecificConstructed(3)) {
133 // x400Address [3] ORAddress,
134 name_type = GENERAL_NAME_X400_ADDRESS;
135 subtrees->x400_addresses.push_back(value);
136 } else if (tag == der::ContextSpecificConstructed(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;
Bob Beck6beabf32023-11-21 09:43:52 -0700144 if (!name_parser.ReadTag(der::kSequence, &name_value) || parser.HasMore()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600145 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700146 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600147 subtrees->directory_names.push_back(name_value);
148 } else if (tag == der::ContextSpecificConstructed(5)) {
149 // ediPartyName [5] EDIPartyName,
150 name_type = GENERAL_NAME_EDI_PARTY_NAME;
151 subtrees->edi_party_names.push_back(value);
152 } else if (tag == der::ContextSpecificPrimitive(6)) {
153 // uniformResourceIdentifier [6] IA5String,
154 name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER;
155 const std::string_view s = value.AsStringView();
156 if (!bssl::string_util::IsAscii(s)) {
157 errors->AddError(kURINotAscii);
158 return false;
159 }
160 subtrees->uniform_resource_identifiers.push_back(s);
161 } else if (tag == der::ContextSpecificPrimitive(7)) {
162 // iPAddress [7] OCTET STRING,
163 name_type = GENERAL_NAME_IP_ADDRESS;
164 if (ip_address_type == GeneralNames::IP_ADDRESS_ONLY) {
165 // RFC 5280 section 4.2.1.6:
166 // When the subjectAltName extension contains an iPAddress, the address
167 // MUST be stored in the octet string in "network byte order", as
168 // specified in [RFC791]. The least significant bit (LSB) of each octet
169 // is the LSB of the corresponding byte in the network address. For IP
170 // version 4, as specified in [RFC791], the octet string MUST contain
171 // exactly four octets. For IP version 6, as specified in [RFC2460],
172 // the octet string MUST contain exactly sixteen octets.
Bob Beck8e7025e2023-09-05 17:05:26 -0600173 if ((value.Length() != kIPv4AddressSize &&
174 value.Length() != kIPv6AddressSize)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600175 errors->AddError(kFailedParsingIp);
176 return false;
177 }
Bob Beck8e7025e2023-09-05 17:05:26 -0600178 subtrees->ip_addresses.push_back(value);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600179 } else {
Bob Beck05007562023-08-17 20:22:17 +0000180 BSSL_CHECK(ip_address_type == GeneralNames::IP_ADDRESS_AND_NETMASK);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600181 // RFC 5280 section 4.2.1.10:
182 // The syntax of iPAddress MUST be as described in Section 4.2.1.6 with
183 // the following additions specifically for name constraints. For IPv4
184 // addresses, the iPAddress field of GeneralName MUST contain eight (8)
185 // octets, encoded in the style of RFC 4632 (CIDR) to represent an
186 // address range [RFC4632]. For IPv6 addresses, the iPAddress field
187 // MUST contain 32 octets similarly encoded. For example, a name
188 // constraint for "class C" subnet 192.0.2.0 is represented as the
189 // octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
190 // 192.0.2.0/24 (mask 255.255.255.0).
Bob Beck8e7025e2023-09-05 17:05:26 -0600191 if (value.Length() != kIPv4AddressSize * 2 &&
192 value.Length() != kIPv6AddressSize * 2) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600193 errors->AddError(kFailedParsingIp);
194 return false;
195 }
Bob Beck8e7025e2023-09-05 17:05:26 -0600196 der::Input addr(value.UnsafeData(), value.Length() / 2);
197 der::Input mask(value.UnsafeData() + value.Length() / 2,
198 value.Length() / 2);
199 if (!IsValidNetmask(mask)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600200 errors->AddError(kFailedParsingIp);
201 return false;
202 }
Bob Beck8e7025e2023-09-05 17:05:26 -0600203 subtrees->ip_address_ranges.emplace_back(addr, mask);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600204 }
205 } else if (tag == der::ContextSpecificPrimitive(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 }
Bob Beck05007562023-08-17 20:22:17 +0000214 BSSL_CHECK(GENERAL_NAME_NONE != name_type);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600215 subtrees->present_name_types |= name_type;
216 return true;
217}
218
Bob Beck5c7a2a02023-11-20 17:28:21 -0700219} // namespace bssl