• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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