Coverage Report

Created: 2025-12-07 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/pki/general_names.cc
Line
Count
Source
1
// Copyright 2017 The Chromium Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "general_names.h"
16
17
#include <openssl/base.h>
18
#include <openssl/bytestring.h>
19
20
#include <climits>
21
#include <cstring>
22
23
#include "cert_error_params.h"
24
#include "cert_errors.h"
25
#include "input.h"
26
#include "ip_util.h"
27
#include "parser.h"
28
#include "string_util.h"
29
30
BSSL_NAMESPACE_BEGIN
31
32
DEFINE_CERT_ERROR_ID(kFailedParsingGeneralName, "Failed parsing GeneralName");
33
34
namespace {
35
36
DEFINE_CERT_ERROR_ID(kRFC822NameNotAscii, "rfc822Name is not ASCII");
37
DEFINE_CERT_ERROR_ID(kDnsNameNotAscii, "dNSName is not ASCII");
38
DEFINE_CERT_ERROR_ID(kURINotAscii, "uniformResourceIdentifier is not ASCII");
39
DEFINE_CERT_ERROR_ID(kFailedParsingIp, "Failed parsing iPAddress");
40
DEFINE_CERT_ERROR_ID(kUnknownGeneralNameType, "Unknown GeneralName type");
41
DEFINE_CERT_ERROR_ID(kFailedReadingGeneralNames,
42
                     "Failed reading GeneralNames SEQUENCE");
43
DEFINE_CERT_ERROR_ID(kGeneralNamesTrailingData,
44
                     "GeneralNames contains trailing data after the sequence");
45
DEFINE_CERT_ERROR_ID(kGeneralNamesEmpty,
46
                     "GeneralNames is a sequence of 0 elements");
47
DEFINE_CERT_ERROR_ID(kFailedReadingGeneralName,
48
                     "Failed reading GeneralName TLV");
49
50
}  // namespace
51
52
2.68k
GeneralNames::GeneralNames() = default;
53
54
2.68k
GeneralNames::~GeneralNames() = default;
55
56
// static
57
std::unique_ptr<GeneralNames> GeneralNames::Create(der::Input general_names_tlv,
58
223
                                                   CertErrors *errors) {
59
223
  BSSL_CHECK(errors);
60
61
  // RFC 5280 section 4.2.1.6:
62
  // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
63
223
  der::Parser parser(general_names_tlv);
64
223
  der::Input sequence_value;
65
223
  if (!parser.ReadTag(CBS_ASN1_SEQUENCE, &sequence_value)) {
66
1
    errors->AddError(kFailedReadingGeneralNames);
67
1
    return nullptr;
68
1
  }
69
  // Should not have trailing data after GeneralNames sequence.
70
222
  if (parser.HasMore()) {
71
1
    errors->AddError(kGeneralNamesTrailingData);
72
1
    return nullptr;
73
1
  }
74
221
  return CreateFromValue(sequence_value, errors);
75
222
}
76
77
// static
78
std::unique_ptr<GeneralNames> GeneralNames::CreateFromValue(
79
2.48k
    der::Input general_names_value, CertErrors *errors) {
80
2.48k
  BSSL_CHECK(errors);
81
82
2.48k
  auto general_names = std::make_unique<GeneralNames>();
83
84
2.48k
  der::Parser sequence_parser(general_names_value);
85
  // The GeneralNames sequence should have at least 1 element.
86
2.48k
  if (!sequence_parser.HasMore()) {
87
11
    errors->AddError(kGeneralNamesEmpty);
88
11
    return nullptr;
89
11
  }
90
91
24.1k
  while (sequence_parser.HasMore()) {
92
22.2k
    der::Input raw_general_name;
93
22.2k
    if (!sequence_parser.ReadRawTLV(&raw_general_name)) {
94
90
      errors->AddError(kFailedReadingGeneralName);
95
90
      return nullptr;
96
90
    }
97
98
22.1k
    if (!ParseGeneralName(raw_general_name, IP_ADDRESS_ONLY,
99
22.1k
                          general_names.get(), errors)) {
100
489
      errors->AddError(kFailedParsingGeneralName);
101
489
      return nullptr;
102
489
    }
103
22.1k
  }
104
105
1.89k
  return general_names;
106
2.47k
}
107
108
[[nodiscard]] bool ParseGeneralName(
109
    der::Input input,
110
    GeneralNames::ParseGeneralNameIPAddressType ip_address_type,
111
22.4k
    GeneralNames *subtrees, CertErrors *errors) {
112
22.4k
  BSSL_CHECK(errors);
113
22.4k
  der::Parser parser(input);
114
22.4k
  CBS_ASN1_TAG tag;
115
22.4k
  der::Input value;
116
22.4k
  if (!parser.ReadTagAndValue(&tag, &value)) {
117
0
    return false;
118
0
  }
119
22.4k
  GeneralNameTypes name_type = GENERAL_NAME_NONE;
120
22.4k
  if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
121
    // otherName                       [0]     OtherName,
122
2.00k
    name_type = GENERAL_NAME_OTHER_NAME;
123
2.00k
    subtrees->other_names.push_back(value);
124
20.4k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 1)) {
125
    // rfc822Name                      [1]     IA5String,
126
3.20k
    name_type = GENERAL_NAME_RFC822_NAME;
127
3.20k
    const std::string_view s = BytesAsStringView(value);
128
3.20k
    if (!bssl::string_util::IsAscii(s)) {
129
16
      errors->AddError(kRFC822NameNotAscii);
130
16
      return false;
131
16
    }
132
3.18k
    subtrees->rfc822_names.push_back(s);
133
17.2k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 2)) {
134
    // dNSName                         [2]     IA5String,
135
3.61k
    name_type = GENERAL_NAME_DNS_NAME;
136
3.61k
    const std::string_view s = BytesAsStringView(value);
137
3.61k
    if (!bssl::string_util::IsAscii(s)) {
138
23
      errors->AddError(kDnsNameNotAscii);
139
23
      return false;
140
23
    }
141
3.59k
    subtrees->dns_names.push_back(s);
142
13.6k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3)) {
143
    // x400Address                     [3]     ORAddress,
144
2.64k
    name_type = GENERAL_NAME_X400_ADDRESS;
145
2.64k
    subtrees->x400_addresses.push_back(value);
146
10.9k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 4)) {
147
    // directoryName                   [4]     Name,
148
976
    name_type = GENERAL_NAME_DIRECTORY_NAME;
149
    // Name is a CHOICE { rdnSequence  RDNSequence }, therefore the SEQUENCE
150
    // tag is explicit. Remove it, since the name matching functions expect
151
    // only the value portion.
152
976
    der::Parser name_parser(value);
153
976
    der::Input name_value;
154
976
    if (!name_parser.ReadTag(CBS_ASN1_SEQUENCE, &name_value) ||
155
957
        parser.HasMore()) {
156
19
      return false;
157
19
    }
158
957
    subtrees->directory_names.push_back(name_value);
159
9.98k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 5)) {
160
    // ediPartyName                    [5]     EDIPartyName,
161
2.26k
    name_type = GENERAL_NAME_EDI_PARTY_NAME;
162
2.26k
    subtrees->edi_party_names.push_back(value);
163
7.72k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 6)) {
164
    // uniformResourceIdentifier       [6]     IA5String,
165
3.28k
    name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER;
166
3.28k
    const std::string_view s = BytesAsStringView(value);
167
3.28k
    if (!bssl::string_util::IsAscii(s)) {
168
17
      errors->AddError(kURINotAscii);
169
17
      return false;
170
17
    }
171
3.26k
    subtrees->uniform_resource_identifiers.push_back(s);
172
4.44k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 7)) {
173
    // iPAddress                       [7]     OCTET STRING,
174
1.22k
    name_type = GENERAL_NAME_IP_ADDRESS;
175
1.22k
    if (ip_address_type == GeneralNames::IP_ADDRESS_ONLY) {
176
      // RFC 5280 section 4.2.1.6:
177
      // When the subjectAltName extension contains an iPAddress, the address
178
      // MUST be stored in the octet string in "network byte order", as
179
      // specified in [RFC791].  The least significant bit (LSB) of each octet
180
      // is the LSB of the corresponding byte in the network address.  For IP
181
      // version 4, as specified in [RFC791], the octet string MUST contain
182
      // exactly four octets.  For IP version 6, as specified in [RFC2460],
183
      // the octet string MUST contain exactly sixteen octets.
184
1.07k
      if ((value.size() != kIPv4AddressSize &&
185
272
           value.size() != kIPv6AddressSize)) {
186
44
        errors->AddError(kFailedParsingIp);
187
44
        return false;
188
44
      }
189
1.03k
      subtrees->ip_addresses.push_back(value);
190
1.03k
    } else {
191
153
      BSSL_CHECK(ip_address_type == GeneralNames::IP_ADDRESS_AND_NETMASK);
192
      // RFC 5280 section 4.2.1.10:
193
      // The syntax of iPAddress MUST be as described in Section 4.2.1.6 with
194
      // the following additions specifically for name constraints. For IPv4
195
      // addresses, the iPAddress field of GeneralName MUST contain eight (8)
196
      // octets, encoded in the style of RFC 4632 (CIDR) to represent an
197
      // address range [RFC4632]. For IPv6 addresses, the iPAddress field
198
      // MUST contain 32 octets similarly encoded. For example, a name
199
      // constraint for "class C" subnet 192.0.2.0 is represented as the
200
      // octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
201
      // 192.0.2.0/24 (mask 255.255.255.0).
202
153
      if (value.size() != kIPv4AddressSize * 2 &&
203
28
          value.size() != kIPv6AddressSize * 2) {
204
9
        errors->AddError(kFailedParsingIp);
205
9
        return false;
206
9
      }
207
144
      der::Input addr = value.first(value.size() / 2);
208
144
      der::Input mask = value.subspan(value.size() / 2);
209
144
      if (!IsValidNetmask(mask)) {
210
18
        errors->AddError(kFailedParsingIp);
211
18
        return false;
212
18
      }
213
126
      subtrees->ip_address_ranges.emplace_back(addr, mask);
214
126
    }
215
3.21k
  } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 8)) {
216
    // registeredID                    [8]     OBJECT IDENTIFIER }
217
2.81k
    name_type = GENERAL_NAME_REGISTERED_ID;
218
2.81k
    subtrees->registered_ids.push_back(value);
219
2.81k
  } else {
220
402
    errors->AddError(kUnknownGeneralNameType,
221
402
                     CreateCertErrorParams1SizeT("tag", tag));
222
402
    return false;
223
402
  }
224
21.8k
  BSSL_CHECK(GENERAL_NAME_NONE != name_type);
225
21.8k
  subtrees->present_name_types |= name_type;
226
21.8k
  return true;
227
21.8k
}
228
229
BSSL_NAMESPACE_END