xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/general_names.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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