/src/boringssl/pki/parse_certificate.cc
Line | Count | Source |
1 | | // Copyright 2015 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 "parse_certificate.h" |
16 | | |
17 | | #include <optional> |
18 | | #include <utility> |
19 | | |
20 | | #include <openssl/base.h> |
21 | | #include <openssl/bytestring.h> |
22 | | |
23 | | #include "cert_error_params.h" |
24 | | #include "cert_errors.h" |
25 | | #include "general_names.h" |
26 | | #include "input.h" |
27 | | #include "parse_values.h" |
28 | | #include "parser.h" |
29 | | #include "string_util.h" |
30 | | |
31 | | BSSL_NAMESPACE_BEGIN |
32 | | |
33 | | namespace { |
34 | | |
35 | | DEFINE_CERT_ERROR_ID(kCertificateNotSequence, |
36 | | "Failed parsing Certificate SEQUENCE"); |
37 | | DEFINE_CERT_ERROR_ID(kUnconsumedDataInsideCertificateSequence, |
38 | | "Unconsumed data inside Certificate SEQUENCE"); |
39 | | DEFINE_CERT_ERROR_ID(kUnconsumedDataAfterCertificateSequence, |
40 | | "Unconsumed data after Certificate SEQUENCE"); |
41 | | DEFINE_CERT_ERROR_ID(kTbsCertificateNotSequence, |
42 | | "Couldn't read tbsCertificate as SEQUENCE"); |
43 | | DEFINE_CERT_ERROR_ID( |
44 | | kSignatureAlgorithmNotSequence, |
45 | | "Couldn't read Certificate.signatureAlgorithm as SEQUENCE"); |
46 | | DEFINE_CERT_ERROR_ID(kSignatureValueNotBitString, |
47 | | "Couldn't read Certificate.signatureValue as BIT STRING"); |
48 | | DEFINE_CERT_ERROR_ID(kUnconsumedDataInsideTbsCertificateSequence, |
49 | | "Unconsumed data inside TBSCertificate"); |
50 | | DEFINE_CERT_ERROR_ID(kTbsNotSequence, "Failed parsing TBSCertificate SEQUENCE"); |
51 | | DEFINE_CERT_ERROR_ID(kFailedReadingVersion, "Failed reading version"); |
52 | | DEFINE_CERT_ERROR_ID(kFailedParsingVersion, "Failed parsing version"); |
53 | | DEFINE_CERT_ERROR_ID(kVersionExplicitlyV1, |
54 | | "Version explicitly V1 (should be omitted)"); |
55 | | DEFINE_CERT_ERROR_ID(kFailedReadingSerialNumber, "Failed reading serialNumber"); |
56 | | DEFINE_CERT_ERROR_ID(kFailedReadingSignatureValue, "Failed reading signature"); |
57 | | DEFINE_CERT_ERROR_ID(kFailedReadingIssuer, "Failed reading issuer"); |
58 | | DEFINE_CERT_ERROR_ID(kFailedReadingValidity, "Failed reading validity"); |
59 | | DEFINE_CERT_ERROR_ID(kFailedParsingValidity, "Failed parsing validity"); |
60 | | DEFINE_CERT_ERROR_ID(kFailedReadingSubject, "Failed reading subject"); |
61 | | DEFINE_CERT_ERROR_ID(kFailedReadingSpki, "Failed reading subjectPublicKeyInfo"); |
62 | | DEFINE_CERT_ERROR_ID(kFailedReadingIssuerUniqueId, |
63 | | "Failed reading issuerUniqueId"); |
64 | | DEFINE_CERT_ERROR_ID(kFailedParsingIssuerUniqueId, |
65 | | "Failed parsing issuerUniqueId"); |
66 | | DEFINE_CERT_ERROR_ID( |
67 | | kIssuerUniqueIdNotExpected, |
68 | | "Unexpected issuerUniqueId (must be V2 or V3 certificate)"); |
69 | | DEFINE_CERT_ERROR_ID(kFailedReadingSubjectUniqueId, |
70 | | "Failed reading subjectUniqueId"); |
71 | | DEFINE_CERT_ERROR_ID(kFailedParsingSubjectUniqueId, |
72 | | "Failed parsing subjectUniqueId"); |
73 | | DEFINE_CERT_ERROR_ID( |
74 | | kSubjectUniqueIdNotExpected, |
75 | | "Unexpected subjectUniqueId (must be V2 or V3 certificate)"); |
76 | | DEFINE_CERT_ERROR_ID(kFailedReadingExtensions, |
77 | | "Failed reading extensions SEQUENCE"); |
78 | | DEFINE_CERT_ERROR_ID(kUnexpectedExtensions, |
79 | | "Unexpected extensions (must be V3 certificate)"); |
80 | | DEFINE_CERT_ERROR_ID(kSerialNumberIsNegative, "Serial number is negative"); |
81 | | DEFINE_CERT_ERROR_ID(kSerialNumberIsZero, "Serial number is zero"); |
82 | | DEFINE_CERT_ERROR_ID(kSerialNumberLengthOver20, |
83 | | "Serial number is longer than 20 octets"); |
84 | | DEFINE_CERT_ERROR_ID(kSerialNumberNotValidInteger, |
85 | | "Serial number is not a valid INTEGER"); |
86 | | |
87 | | // Returns true if |input| is a SEQUENCE and nothing else. |
88 | 13.4k | [[nodiscard]] bool IsSequenceTLV(der::Input input) { |
89 | 13.4k | der::Parser parser(input); |
90 | 13.4k | der::Parser unused_sequence_parser; |
91 | 13.4k | if (!parser.ReadSequence(&unused_sequence_parser)) { |
92 | 34 | return false; |
93 | 34 | } |
94 | | // Should by a single SEQUENCE by definition of the function. |
95 | 13.4k | return !parser.HasMore(); |
96 | 13.4k | } |
97 | | |
98 | | // Reads a SEQUENCE from |parser| and writes the full tag-length-value into |
99 | | // |out|. On failure |parser| may or may not have been advanced. |
100 | 12.3k | [[nodiscard]] bool ReadSequenceTLV(der::Parser *parser, der::Input *out) { |
101 | 12.3k | return parser->ReadRawTLV(out) && IsSequenceTLV(*out); |
102 | 12.3k | } |
103 | | |
104 | | // Parses a Version according to RFC 5280: |
105 | | // |
106 | | // Version ::= INTEGER { v1(0), v2(1), v3(2) } |
107 | | // |
108 | | // No value other that v1, v2, or v3 is allowed (and if given will fail). RFC |
109 | | // 5280 minimally requires the handling of v3 (and overwhelmingly these are the |
110 | | // certificate versions in use today): |
111 | | // |
112 | | // Implementations SHOULD be prepared to accept any version certificate. |
113 | | // At a minimum, conforming implementations MUST recognize version 3 |
114 | | // certificates. |
115 | 1.40k | [[nodiscard]] bool ParseVersion(der::Input in, CertificateVersion *version) { |
116 | 1.40k | der::Parser parser(in); |
117 | 1.40k | uint64_t version64; |
118 | 1.40k | if (!parser.ReadUint64(&version64)) { |
119 | 21 | return false; |
120 | 21 | } |
121 | | |
122 | 1.38k | switch (version64) { |
123 | 1 | case 0: |
124 | 1 | *version = CertificateVersion::V1; |
125 | 1 | break; |
126 | 25 | case 1: |
127 | 25 | *version = CertificateVersion::V2; |
128 | 25 | break; |
129 | 1.25k | case 2: |
130 | 1.25k | *version = CertificateVersion::V3; |
131 | 1.25k | break; |
132 | 101 | default: |
133 | | // Don't allow any other version identifier. |
134 | 101 | return false; |
135 | 1.38k | } |
136 | | |
137 | | // By definition the input to this function was a single INTEGER, so there |
138 | | // shouldn't be anything else after it. |
139 | 1.28k | return !parser.HasMore(); |
140 | 1.38k | } |
141 | | |
142 | | // Returns true if every bit in |bits| is zero (including empty). |
143 | 358 | [[nodiscard]] bool BitStringIsAllZeros(const der::BitString &bits) { |
144 | | // Note that it is OK to read from the unused bits, since BitString parsing |
145 | | // guarantees they are all zero. |
146 | 466 | for (uint8_t b : bits.bytes()) { |
147 | 466 | if (b != 0) { |
148 | 357 | return false; |
149 | 357 | } |
150 | 466 | } |
151 | 1 | return true; |
152 | 358 | } |
153 | | |
154 | | // Parses a DistributionPointName. |
155 | | // |
156 | | // From RFC 5280: |
157 | | // |
158 | | // DistributionPointName ::= CHOICE { |
159 | | // fullName [0] GeneralNames, |
160 | | // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } |
161 | | bool ParseDistributionPointName(der::Input dp_name, |
162 | 2.23k | ParsedDistributionPoint *distribution_point) { |
163 | 2.23k | der::Parser parser(dp_name); |
164 | 2.23k | std::optional<der::Input> der_full_name; |
165 | 2.23k | if (!parser.ReadOptionalTag( |
166 | 2.23k | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, |
167 | 2.23k | &der_full_name)) { |
168 | 7 | return false; |
169 | 7 | } |
170 | 2.22k | if (der_full_name) { |
171 | | // TODO(mattm): surface the CertErrors. |
172 | 1.88k | CertErrors errors; |
173 | 1.88k | distribution_point->distribution_point_fullname = |
174 | 1.88k | GeneralNames::CreateFromValue(*der_full_name, &errors); |
175 | 1.88k | if (!distribution_point->distribution_point_fullname) { |
176 | 232 | return false; |
177 | 232 | } |
178 | 1.65k | return !parser.HasMore(); |
179 | 1.88k | } |
180 | | |
181 | 341 | if (!parser.ReadOptionalTag( |
182 | 341 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, |
183 | 341 | &distribution_point |
184 | 341 | ->distribution_point_name_relative_to_crl_issuer)) { |
185 | 0 | return false; |
186 | 0 | } |
187 | 341 | if (distribution_point->distribution_point_name_relative_to_crl_issuer) { |
188 | 331 | return !parser.HasMore(); |
189 | 331 | } |
190 | | |
191 | | // The CHOICE must contain either fullName or nameRelativeToCRLIssuer. |
192 | 10 | return false; |
193 | 341 | } |
194 | | |
195 | | // RFC 5280, section 4.2.1.13. |
196 | | // |
197 | | // DistributionPoint ::= SEQUENCE { |
198 | | // distributionPoint [0] DistributionPointName OPTIONAL, |
199 | | // reasons [1] ReasonFlags OPTIONAL, |
200 | | // cRLIssuer [2] GeneralNames OPTIONAL } |
201 | | bool ParseAndAddDistributionPoint( |
202 | | der::Parser *parser, |
203 | 3.39k | std::vector<ParsedDistributionPoint> *distribution_points) { |
204 | 3.39k | ParsedDistributionPoint distribution_point; |
205 | | |
206 | | // DistributionPoint ::= SEQUENCE { |
207 | 3.39k | der::Parser distrib_point_parser; |
208 | 3.39k | if (!parser->ReadSequence(&distrib_point_parser)) { |
209 | 36 | return false; |
210 | 36 | } |
211 | | |
212 | | // distributionPoint [0] DistributionPointName OPTIONAL, |
213 | 3.35k | std::optional<der::Input> distribution_point_name; |
214 | 3.35k | if (!distrib_point_parser.ReadOptionalTag( |
215 | 3.35k | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, |
216 | 3.35k | &distribution_point_name)) { |
217 | 13 | return false; |
218 | 13 | } |
219 | | |
220 | 3.34k | if (distribution_point_name && |
221 | 2.23k | !ParseDistributionPointName(*distribution_point_name, |
222 | 2.23k | &distribution_point)) { |
223 | 256 | return false; |
224 | 256 | } |
225 | | |
226 | | // reasons [1] ReasonFlags OPTIONAL, |
227 | 3.08k | if (!distrib_point_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, |
228 | 3.08k | &distribution_point.reasons)) { |
229 | 2 | return false; |
230 | 2 | } |
231 | | |
232 | | // cRLIssuer [2] GeneralNames OPTIONAL } |
233 | 3.08k | if (!distrib_point_parser.ReadOptionalTag( |
234 | 3.08k | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2, |
235 | 3.08k | &distribution_point.crl_issuer)) { |
236 | 3 | return false; |
237 | 3 | } |
238 | | // TODO(eroman): Parse "cRLIssuer"? |
239 | | |
240 | | // RFC 5280, section 4.2.1.13: |
241 | | // either distributionPoint or cRLIssuer MUST be present. |
242 | 3.08k | if (!distribution_point_name && !distribution_point.crl_issuer) { |
243 | 62 | return false; |
244 | 62 | } |
245 | | |
246 | 3.01k | if (distrib_point_parser.HasMore()) { |
247 | 3 | return false; |
248 | 3 | } |
249 | | |
250 | 3.01k | distribution_points->push_back(std::move(distribution_point)); |
251 | 3.01k | return true; |
252 | 3.01k | } |
253 | | |
254 | | } // namespace |
255 | | |
256 | 2.96k | ParsedTbsCertificate::ParsedTbsCertificate() = default; |
257 | | |
258 | 0 | ParsedTbsCertificate::ParsedTbsCertificate(ParsedTbsCertificate &&other) = |
259 | | default; |
260 | | |
261 | 2.96k | ParsedTbsCertificate::~ParsedTbsCertificate() = default; |
262 | | |
263 | | bool VerifySerialNumber(der::Input value, bool warnings_only, |
264 | 2.16k | CertErrors *errors) { |
265 | | // If |warnings_only| was set to true, the exact same errors will be logged, |
266 | | // only they will be logged with a lower severity (warning rather than error). |
267 | 2.16k | CertError::Severity error_severity = |
268 | 2.16k | warnings_only ? CertError::SEVERITY_WARNING : CertError::SEVERITY_HIGH; |
269 | | |
270 | 2.16k | bool negative; |
271 | 2.16k | if (!der::IsValidInteger(value, &negative)) { |
272 | 17 | errors->Add(error_severity, kSerialNumberNotValidInteger, nullptr); |
273 | 17 | return false; |
274 | 17 | } |
275 | | |
276 | | // RFC 5280 section 4.1.2.2: |
277 | | // |
278 | | // Note: Non-conforming CAs may issue certificates with serial numbers |
279 | | // that are negative or zero. Certificate users SHOULD be prepared to |
280 | | // gracefully handle such certificates. |
281 | 2.14k | if (negative) { |
282 | 722 | errors->AddWarning(kSerialNumberIsNegative); |
283 | 722 | } |
284 | 2.14k | if (value.size() == 1 && value[0] == 0) { |
285 | 20 | errors->AddWarning(kSerialNumberIsZero); |
286 | 20 | } |
287 | | |
288 | | // RFC 5280 section 4.1.2.2: |
289 | | // |
290 | | // Certificate users MUST be able to handle serialNumber values up to 20 |
291 | | // octets. Conforming CAs MUST NOT use serialNumber values longer than 20 |
292 | | // octets. |
293 | 2.14k | if (value.size() > 20) { |
294 | 33 | errors->Add(error_severity, kSerialNumberLengthOver20, |
295 | 33 | CreateCertErrorParams1SizeT("length", value.size())); |
296 | 33 | return false; |
297 | 33 | } |
298 | | |
299 | 2.11k | return true; |
300 | 2.14k | } |
301 | | |
302 | 11.9k | bool ReadUTCOrGeneralizedTime(der::Parser *parser, der::GeneralizedTime *out) { |
303 | 11.9k | der::Input value; |
304 | 11.9k | CBS_ASN1_TAG tag; |
305 | | |
306 | 11.9k | if (!parser->ReadTagAndValue(&tag, &value)) { |
307 | 33 | return false; |
308 | 33 | } |
309 | | |
310 | 11.8k | if (tag == CBS_ASN1_UTCTIME) { |
311 | 8.29k | return der::ParseUTCTime(value, out); |
312 | 8.29k | } |
313 | | |
314 | 3.59k | if (tag == CBS_ASN1_GENERALIZEDTIME) { |
315 | 3.32k | return der::ParseGeneralizedTime(value, out); |
316 | 3.32k | } |
317 | | |
318 | | // Unrecognized tag. |
319 | 269 | return false; |
320 | 3.59k | } |
321 | | |
322 | | bool ParseValidity(der::Input validity_tlv, der::GeneralizedTime *not_before, |
323 | 2.04k | der::GeneralizedTime *not_after) { |
324 | 2.04k | der::Parser parser(validity_tlv); |
325 | | |
326 | | // Validity ::= SEQUENCE { |
327 | 2.04k | der::Parser validity_parser; |
328 | 2.04k | if (!parser.ReadSequence(&validity_parser)) { |
329 | 1 | return false; |
330 | 1 | } |
331 | | |
332 | | // notBefore Time, |
333 | 2.03k | if (!ReadUTCOrGeneralizedTime(&validity_parser, not_before)) { |
334 | 261 | return false; |
335 | 261 | } |
336 | | |
337 | | // notAfter Time } |
338 | 1.77k | if (!ReadUTCOrGeneralizedTime(&validity_parser, not_after)) { |
339 | 85 | return false; |
340 | 85 | } |
341 | | |
342 | | // By definition the input was a single Validity sequence, so there shouldn't |
343 | | // be unconsumed data. |
344 | 1.69k | if (parser.HasMore()) { |
345 | 0 | return false; |
346 | 0 | } |
347 | | |
348 | | // The Validity type does not have an extension point. |
349 | 1.69k | if (validity_parser.HasMore()) { |
350 | 2 | return false; |
351 | 2 | } |
352 | | |
353 | | // Note that RFC 5280 doesn't require notBefore to be <= |
354 | | // notAfter, so that will not be considered a "parsing" error here. Instead it |
355 | | // will be considered an expired certificate later when testing against the |
356 | | // current timestamp. |
357 | 1.69k | return true; |
358 | 1.69k | } |
359 | | |
360 | | bool ParseCertificate(der::Input certificate_tlv, |
361 | | der::Input *out_tbs_certificate_tlv, |
362 | | der::Input *out_signature_algorithm_tlv, |
363 | | der::BitString *out_signature_value, |
364 | 2.96k | CertErrors *out_errors) { |
365 | | // |out_errors| is optional. But ensure it is non-null for the remainder of |
366 | | // this function. |
367 | 2.96k | CertErrors unused_errors; |
368 | 2.96k | if (!out_errors) { |
369 | 0 | out_errors = &unused_errors; |
370 | 0 | } |
371 | | |
372 | 2.96k | der::Parser parser(certificate_tlv); |
373 | | |
374 | | // Certificate ::= SEQUENCE { |
375 | 2.96k | der::Parser certificate_parser; |
376 | 2.96k | if (!parser.ReadSequence(&certificate_parser)) { |
377 | 511 | out_errors->AddError(kCertificateNotSequence); |
378 | 511 | return false; |
379 | 511 | } |
380 | | |
381 | | // tbsCertificate TBSCertificate, |
382 | 2.45k | if (!ReadSequenceTLV(&certificate_parser, out_tbs_certificate_tlv)) { |
383 | 59 | out_errors->AddError(kTbsCertificateNotSequence); |
384 | 59 | return false; |
385 | 59 | } |
386 | | |
387 | | // signatureAlgorithm AlgorithmIdentifier, |
388 | 2.39k | if (!ReadSequenceTLV(&certificate_parser, out_signature_algorithm_tlv)) { |
389 | 24 | out_errors->AddError(kSignatureAlgorithmNotSequence); |
390 | 24 | return false; |
391 | 24 | } |
392 | | |
393 | | // signatureValue BIT STRING } |
394 | 2.36k | std::optional<der::BitString> signature_value = |
395 | 2.36k | certificate_parser.ReadBitString(); |
396 | 2.36k | if (!signature_value) { |
397 | 31 | out_errors->AddError(kSignatureValueNotBitString); |
398 | 31 | return false; |
399 | 31 | } |
400 | 2.33k | *out_signature_value = signature_value.value(); |
401 | | |
402 | | // There isn't an extension point at the end of Certificate. |
403 | 2.33k | if (certificate_parser.HasMore()) { |
404 | 15 | out_errors->AddError(kUnconsumedDataInsideCertificateSequence); |
405 | 15 | return false; |
406 | 15 | } |
407 | | |
408 | | // By definition the input was a single Certificate, so there shouldn't be |
409 | | // unconsumed data. |
410 | 2.32k | if (parser.HasMore()) { |
411 | 24 | out_errors->AddError(kUnconsumedDataAfterCertificateSequence); |
412 | 24 | return false; |
413 | 24 | } |
414 | | |
415 | 2.29k | return true; |
416 | 2.32k | } |
417 | | |
418 | | // From RFC 5280 section 4.1: |
419 | | // |
420 | | // TBSCertificate ::= SEQUENCE { |
421 | | // version [0] EXPLICIT Version DEFAULT v1, |
422 | | // serialNumber CertificateSerialNumber, |
423 | | // signature AlgorithmIdentifier, |
424 | | // issuer Name, |
425 | | // validity Validity, |
426 | | // subject Name, |
427 | | // subjectPublicKeyInfo SubjectPublicKeyInfo, |
428 | | // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, |
429 | | // -- If present, version MUST be v2 or v3 |
430 | | // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, |
431 | | // -- If present, version MUST be v2 or v3 |
432 | | // extensions [3] EXPLICIT Extensions OPTIONAL |
433 | | // -- If present, version MUST be v3 |
434 | | // } |
435 | | bool ParseTbsCertificate(der::Input tbs_tlv, |
436 | | const ParseCertificateOptions &options, |
437 | 2.29k | ParsedTbsCertificate *out, CertErrors *errors) { |
438 | | // The rest of this function assumes that |errors| is non-null. |
439 | 2.29k | CertErrors unused_errors; |
440 | 2.29k | if (!errors) { |
441 | 0 | errors = &unused_errors; |
442 | 0 | } |
443 | | |
444 | | // TODO(crbug.com/634443): Add useful error information to |errors|. |
445 | | |
446 | 2.29k | der::Parser parser(tbs_tlv); |
447 | | |
448 | | // TBSCertificate ::= SEQUENCE { |
449 | 2.29k | der::Parser tbs_parser; |
450 | 2.29k | if (!parser.ReadSequence(&tbs_parser)) { |
451 | 0 | errors->AddError(kTbsNotSequence); |
452 | 0 | return false; |
453 | 0 | } |
454 | | |
455 | | // version [0] EXPLICIT Version DEFAULT v1, |
456 | 2.29k | std::optional<der::Input> version; |
457 | 2.29k | if (!tbs_parser.ReadOptionalTag( |
458 | 2.29k | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &version)) { |
459 | 6 | errors->AddError(kFailedReadingVersion); |
460 | 6 | return false; |
461 | 6 | } |
462 | 2.29k | if (version) { |
463 | 1.40k | if (!ParseVersion(version.value(), &out->version)) { |
464 | 122 | errors->AddError(kFailedParsingVersion); |
465 | 122 | return false; |
466 | 122 | } |
467 | 1.28k | if (out->version == CertificateVersion::V1) { |
468 | 1 | errors->AddError(kVersionExplicitlyV1); |
469 | | // The correct way to specify v1 is to omit the version field since v1 is |
470 | | // the DEFAULT. |
471 | 1 | return false; |
472 | 1 | } |
473 | 1.28k | } else { |
474 | 884 | out->version = CertificateVersion::V1; |
475 | 884 | } |
476 | | |
477 | | // serialNumber CertificateSerialNumber, |
478 | 2.16k | if (!tbs_parser.ReadTag(CBS_ASN1_INTEGER, &out->serial_number)) { |
479 | 64 | errors->AddError(kFailedReadingSerialNumber); |
480 | 64 | return false; |
481 | 64 | } |
482 | 2.10k | if (!VerifySerialNumber(out->serial_number, |
483 | 2.10k | options.allow_invalid_serial_numbers, errors)) { |
484 | | // Invalid serial numbers are only considered fatal failures if |
485 | | // |!allow_invalid_serial_numbers|. |
486 | 26 | if (!options.allow_invalid_serial_numbers) { |
487 | 26 | return false; |
488 | 26 | } |
489 | 26 | } |
490 | | |
491 | | // signature AlgorithmIdentifier, |
492 | 2.07k | if (!ReadSequenceTLV(&tbs_parser, &out->signature_algorithm_tlv)) { |
493 | 33 | errors->AddError(kFailedReadingSignatureValue); |
494 | 33 | return false; |
495 | 33 | } |
496 | | |
497 | | // issuer Name, |
498 | 2.04k | if (!ReadSequenceTLV(&tbs_parser, &out->issuer_tlv)) { |
499 | 4 | errors->AddError(kFailedReadingIssuer); |
500 | 4 | return false; |
501 | 4 | } |
502 | | |
503 | | // validity Validity, |
504 | 2.04k | if (!tbs_parser.ReadRawTLV(&out->validity_tlv)) { |
505 | 1 | errors->AddError(kFailedReadingValidity); |
506 | 1 | return false; |
507 | 1 | } |
508 | 2.04k | if (!ParseValidity(out->validity_tlv, &out->validity_not_before, |
509 | 2.04k | &out->validity_not_after)) { |
510 | 349 | errors->AddError(kFailedParsingValidity); |
511 | 349 | return false; |
512 | 349 | } |
513 | | |
514 | | // subject Name, |
515 | 1.69k | if (!ReadSequenceTLV(&tbs_parser, &out->subject_tlv)) { |
516 | 1 | errors->AddError(kFailedReadingSubject); |
517 | 1 | return false; |
518 | 1 | } |
519 | | |
520 | | // subjectPublicKeyInfo SubjectPublicKeyInfo, |
521 | 1.69k | if (!ReadSequenceTLV(&tbs_parser, &out->spki_tlv)) { |
522 | 1 | errors->AddError(kFailedReadingSpki); |
523 | 1 | return false; |
524 | 1 | } |
525 | | |
526 | 1.68k | out->bytes_after_spki = tbs_parser.RemainingBytes(); |
527 | | |
528 | | // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, |
529 | | // -- If present, version MUST be v2 or v3 |
530 | 1.68k | std::optional<der::Input> issuer_unique_id; |
531 | 1.68k | if (!tbs_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, |
532 | 1.68k | &issuer_unique_id)) { |
533 | 2 | errors->AddError(kFailedReadingIssuerUniqueId); |
534 | 2 | return false; |
535 | 2 | } |
536 | 1.68k | if (issuer_unique_id) { |
537 | 13 | out->issuer_unique_id = der::ParseBitString(issuer_unique_id.value()); |
538 | 13 | if (!out->issuer_unique_id) { |
539 | 1 | errors->AddError(kFailedParsingIssuerUniqueId); |
540 | 1 | return false; |
541 | 1 | } |
542 | 12 | if (out->version != CertificateVersion::V2 && |
543 | 3 | out->version != CertificateVersion::V3) { |
544 | 1 | errors->AddError(kIssuerUniqueIdNotExpected); |
545 | 1 | return false; |
546 | 1 | } |
547 | 12 | } |
548 | | |
549 | | // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, |
550 | | // -- If present, version MUST be v2 or v3 |
551 | 1.68k | std::optional<der::Input> subject_unique_id; |
552 | 1.68k | if (!tbs_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 2, |
553 | 1.68k | &subject_unique_id)) { |
554 | 1 | errors->AddError(kFailedReadingSubjectUniqueId); |
555 | 1 | return false; |
556 | 1 | } |
557 | 1.68k | if (subject_unique_id) { |
558 | 12 | out->subject_unique_id = der::ParseBitString(subject_unique_id.value()); |
559 | 12 | if (!out->subject_unique_id) { |
560 | 2 | errors->AddError(kFailedParsingSubjectUniqueId); |
561 | 2 | return false; |
562 | 2 | } |
563 | 10 | if (out->version != CertificateVersion::V2 && |
564 | 3 | out->version != CertificateVersion::V3) { |
565 | 1 | errors->AddError(kSubjectUniqueIdNotExpected); |
566 | 1 | return false; |
567 | 1 | } |
568 | 10 | } |
569 | | |
570 | | // extensions [3] EXPLICIT Extensions OPTIONAL |
571 | | // -- If present, version MUST be v3 |
572 | 1.68k | if (!tbs_parser.ReadOptionalTag( |
573 | 1.68k | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3, |
574 | 1.68k | &out->extensions_tlv)) { |
575 | 3 | errors->AddError(kFailedReadingExtensions); |
576 | 3 | return false; |
577 | 3 | } |
578 | 1.67k | if (out->extensions_tlv) { |
579 | | // extensions_tlv must be a single element. Also check that it is a |
580 | | // SEQUENCE. |
581 | 1.20k | if (!IsSequenceTLV(out->extensions_tlv.value())) { |
582 | 1 | errors->AddError(kFailedReadingExtensions); |
583 | 1 | return false; |
584 | 1 | } |
585 | 1.20k | if (out->version != CertificateVersion::V3) { |
586 | 2 | errors->AddError(kUnexpectedExtensions); |
587 | 2 | return false; |
588 | 2 | } |
589 | 1.20k | } |
590 | | |
591 | | // Note that there IS an extension point at the end of TBSCertificate |
592 | | // (according to RFC 5912), so from that interpretation, unconsumed data would |
593 | | // be allowed in |tbs_parser|. |
594 | | // |
595 | | // However because only v1, v2, and v3 certificates are supported by the |
596 | | // parsing, there shouldn't be any subsequent data in those versions, so |
597 | | // reject. |
598 | 1.67k | if (tbs_parser.HasMore()) { |
599 | 6 | errors->AddError(kUnconsumedDataInsideTbsCertificateSequence); |
600 | 6 | return false; |
601 | 6 | } |
602 | | |
603 | | // By definition the input was a single TBSCertificate, so there shouldn't be |
604 | | // unconsumed data. |
605 | 1.66k | if (parser.HasMore()) { |
606 | 0 | return false; |
607 | 0 | } |
608 | | |
609 | 1.66k | return true; |
610 | 1.66k | } |
611 | | |
612 | | // From RFC 5280: |
613 | | // |
614 | | // Extension ::= SEQUENCE { |
615 | | // extnID OBJECT IDENTIFIER, |
616 | | // critical BOOLEAN DEFAULT FALSE, |
617 | | // extnValue OCTET STRING |
618 | | // -- contains the DER encoding of an ASN.1 value |
619 | | // -- corresponding to the extension type identified |
620 | | // -- by extnID |
621 | | // } |
622 | 16.6k | bool ParseExtension(der::Input extension_tlv, ParsedExtension *out) { |
623 | 16.6k | der::Parser parser(extension_tlv); |
624 | | |
625 | | // Extension ::= SEQUENCE { |
626 | 16.6k | der::Parser extension_parser; |
627 | 16.6k | if (!parser.ReadSequence(&extension_parser)) { |
628 | 21 | return false; |
629 | 21 | } |
630 | | |
631 | | // extnID OBJECT IDENTIFIER, |
632 | 16.6k | if (!extension_parser.ReadTag(CBS_ASN1_OBJECT, &out->oid)) { |
633 | 23 | return false; |
634 | 23 | } |
635 | | |
636 | | // critical BOOLEAN DEFAULT FALSE, |
637 | 16.6k | out->critical = false; |
638 | 16.6k | bool has_critical; |
639 | 16.6k | der::Input critical; |
640 | 16.6k | if (!extension_parser.ReadOptionalTag(CBS_ASN1_BOOLEAN, &critical, |
641 | 16.6k | &has_critical)) { |
642 | 17 | return false; |
643 | 17 | } |
644 | 16.6k | if (has_critical) { |
645 | 1.70k | if (!der::ParseBool(critical, &out->critical)) { |
646 | 42 | return false; |
647 | 42 | } |
648 | 1.66k | if (!out->critical) { |
649 | 3 | return false; // DER-encoding requires DEFAULT values be omitted. |
650 | 3 | } |
651 | 1.66k | } |
652 | | |
653 | | // extnValue OCTET STRING |
654 | 16.5k | if (!extension_parser.ReadTag(CBS_ASN1_OCTETSTRING, &out->value)) { |
655 | 80 | return false; |
656 | 80 | } |
657 | | |
658 | | // The Extension type does not have an extension point (everything goes in |
659 | | // extnValue). |
660 | 16.4k | if (extension_parser.HasMore()) { |
661 | 3 | return false; |
662 | 3 | } |
663 | | |
664 | | // By definition the input was a single Extension sequence, so there shouldn't |
665 | | // be unconsumed data. |
666 | 16.4k | if (parser.HasMore()) { |
667 | 0 | return false; |
668 | 0 | } |
669 | | |
670 | 16.4k | return true; |
671 | 16.4k | } |
672 | | |
673 | | OPENSSL_EXPORT bool ParseExtensions( |
674 | | der::Input extensions_tlv, |
675 | 2.38k | std::map<der::Input, ParsedExtension> *extensions) { |
676 | 2.38k | der::Parser parser(extensions_tlv); |
677 | | |
678 | | // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension |
679 | 2.38k | der::Parser extensions_parser; |
680 | 2.38k | if (!parser.ReadSequence(&extensions_parser)) { |
681 | 3 | return false; |
682 | 3 | } |
683 | | |
684 | | // The Extensions SEQUENCE must contains at least 1 element (otherwise it |
685 | | // should have been omitted). |
686 | 2.37k | if (!extensions_parser.HasMore()) { |
687 | 2 | return false; |
688 | 2 | } |
689 | | |
690 | 2.37k | extensions->clear(); |
691 | | |
692 | 18.8k | while (extensions_parser.HasMore()) { |
693 | 16.7k | ParsedExtension extension; |
694 | | |
695 | 16.7k | der::Input extension_tlv; |
696 | 16.7k | if (!extensions_parser.ReadRawTLV(&extension_tlv)) { |
697 | 24 | return false; |
698 | 24 | } |
699 | | |
700 | 16.6k | if (!ParseExtension(extension_tlv, &extension)) { |
701 | 189 | return false; |
702 | 189 | } |
703 | | |
704 | 16.4k | bool is_duplicate = |
705 | 16.4k | !extensions->insert(std::make_pair(extension.oid, extension)).second; |
706 | | |
707 | | // RFC 5280 says that an extension should not appear more than once. |
708 | 16.4k | if (is_duplicate) { |
709 | 25 | return false; |
710 | 25 | } |
711 | 16.4k | } |
712 | | |
713 | | // By definition the input was a single Extensions sequence, so there |
714 | | // shouldn't be unconsumed data. |
715 | 2.13k | if (parser.HasMore()) { |
716 | 0 | return false; |
717 | 0 | } |
718 | | |
719 | 2.13k | return true; |
720 | 2.13k | } |
721 | | |
722 | | OPENSSL_EXPORT bool ConsumeExtension( |
723 | | der::Input oid, |
724 | | std::map<der::Input, ParsedExtension> *unconsumed_extensions, |
725 | 0 | ParsedExtension *extension) { |
726 | 0 | auto it = unconsumed_extensions->find(oid); |
727 | 0 | if (it == unconsumed_extensions->end()) { |
728 | 0 | return false; |
729 | 0 | } |
730 | | |
731 | 0 | *extension = it->second; |
732 | 0 | unconsumed_extensions->erase(it); |
733 | 0 | return true; |
734 | 0 | } |
735 | | |
736 | | bool ParseBasicConstraints(der::Input basic_constraints_tlv, |
737 | 207 | ParsedBasicConstraints *out) { |
738 | 207 | der::Parser parser(basic_constraints_tlv); |
739 | | |
740 | | // BasicConstraints ::= SEQUENCE { |
741 | 207 | der::Parser sequence_parser; |
742 | 207 | if (!parser.ReadSequence(&sequence_parser)) { |
743 | 2 | return false; |
744 | 2 | } |
745 | | |
746 | | // cA BOOLEAN DEFAULT FALSE, |
747 | 205 | out->is_ca = false; |
748 | 205 | bool has_ca; |
749 | 205 | der::Input ca; |
750 | 205 | if (!sequence_parser.ReadOptionalTag(CBS_ASN1_BOOLEAN, &ca, &has_ca)) { |
751 | 1 | return false; |
752 | 1 | } |
753 | 204 | if (has_ca) { |
754 | 169 | if (!der::ParseBool(ca, &out->is_ca)) { |
755 | 1 | return false; |
756 | 1 | } |
757 | | // TODO(eroman): Should reject if CA was set to false, since |
758 | | // DER-encoding requires DEFAULT values be omitted. In |
759 | | // practice however there are a lot of certificates that use |
760 | | // the broken encoding. |
761 | 169 | } |
762 | | |
763 | | // pathLenConstraint INTEGER (0..MAX) OPTIONAL } |
764 | 203 | der::Input encoded_path_len; |
765 | 203 | if (!sequence_parser.ReadOptionalTag(CBS_ASN1_INTEGER, &encoded_path_len, |
766 | 203 | &out->has_path_len)) { |
767 | 1 | return false; |
768 | 1 | } |
769 | 202 | if (out->has_path_len) { |
770 | | // TODO(eroman): Surface reason for failure if length was longer than uint8. |
771 | 21 | if (!der::ParseUint8(encoded_path_len, &out->path_len)) { |
772 | 8 | return false; |
773 | 8 | } |
774 | 181 | } else { |
775 | | // Default initialize to 0 as a precaution. |
776 | 181 | out->path_len = 0; |
777 | 181 | } |
778 | | |
779 | | // There shouldn't be any unconsumed data in the extension. |
780 | 194 | if (sequence_parser.HasMore()) { |
781 | 2 | return false; |
782 | 2 | } |
783 | | |
784 | | // By definition the input was a single BasicConstraints sequence, so there |
785 | | // shouldn't be unconsumed data. |
786 | 192 | if (parser.HasMore()) { |
787 | 1 | return false; |
788 | 1 | } |
789 | | |
790 | 191 | return true; |
791 | 192 | } |
792 | | |
793 | | // TODO(crbug.com/1314019): return std::optional<BitString> when converting |
794 | | // has_key_usage_ and key_usage_ into single std::optional field. |
795 | 361 | bool ParseKeyUsage(der::Input key_usage_tlv, der::BitString *key_usage) { |
796 | 361 | der::Parser parser(key_usage_tlv); |
797 | 361 | std::optional<der::BitString> key_usage_internal = parser.ReadBitString(); |
798 | 361 | if (!key_usage_internal) { |
799 | 2 | return false; |
800 | 2 | } |
801 | | |
802 | | // By definition the input was a single BIT STRING. |
803 | 359 | if (parser.HasMore()) { |
804 | 1 | return false; |
805 | 1 | } |
806 | | |
807 | | // RFC 5280 section 4.2.1.3: |
808 | | // |
809 | | // When the keyUsage extension appears in a certificate, at least |
810 | | // one of the bits MUST be set to 1. |
811 | 358 | if (BitStringIsAllZeros(key_usage_internal.value())) { |
812 | 1 | return false; |
813 | 1 | } |
814 | | |
815 | 357 | *key_usage = key_usage_internal.value(); |
816 | 357 | return true; |
817 | 358 | } |
818 | | |
819 | | bool ParseAuthorityInfoAccess( |
820 | | der::Input authority_info_access_tlv, |
821 | 130 | std::vector<AuthorityInfoAccessDescription> *out_access_descriptions) { |
822 | 130 | der::Parser parser(authority_info_access_tlv); |
823 | | |
824 | 130 | out_access_descriptions->clear(); |
825 | | |
826 | | // AuthorityInfoAccessSyntax ::= |
827 | | // SEQUENCE SIZE (1..MAX) OF AccessDescription |
828 | 130 | der::Parser sequence_parser; |
829 | 130 | if (!parser.ReadSequence(&sequence_parser)) { |
830 | 3 | return false; |
831 | 3 | } |
832 | 127 | if (!sequence_parser.HasMore()) { |
833 | 1 | return false; |
834 | 1 | } |
835 | | |
836 | 739 | while (sequence_parser.HasMore()) { |
837 | 624 | AuthorityInfoAccessDescription access_description; |
838 | | |
839 | | // AccessDescription ::= SEQUENCE { |
840 | 624 | der::Parser access_description_sequence_parser; |
841 | 624 | if (!sequence_parser.ReadSequence(&access_description_sequence_parser)) { |
842 | 4 | return false; |
843 | 4 | } |
844 | | |
845 | | // accessMethod OBJECT IDENTIFIER, |
846 | 620 | if (!access_description_sequence_parser.ReadTag( |
847 | 620 | CBS_ASN1_OBJECT, &access_description.access_method_oid)) { |
848 | 4 | return false; |
849 | 4 | } |
850 | | |
851 | | // accessLocation GeneralName } |
852 | 616 | if (!access_description_sequence_parser.ReadRawTLV( |
853 | 616 | &access_description.access_location)) { |
854 | 1 | return false; |
855 | 1 | } |
856 | | |
857 | 615 | if (access_description_sequence_parser.HasMore()) { |
858 | 2 | return false; |
859 | 2 | } |
860 | | |
861 | 613 | out_access_descriptions->push_back(access_description); |
862 | 613 | } |
863 | | |
864 | 115 | return true; |
865 | 126 | } |
866 | | |
867 | | bool ParseAuthorityInfoAccessURIs( |
868 | | der::Input authority_info_access_tlv, |
869 | | std::vector<std::string_view> *out_ca_issuers_uris, |
870 | 130 | std::vector<std::string_view> *out_ocsp_uris) { |
871 | 130 | std::vector<AuthorityInfoAccessDescription> access_descriptions; |
872 | 130 | if (!ParseAuthorityInfoAccess(authority_info_access_tlv, |
873 | 130 | &access_descriptions)) { |
874 | 15 | return false; |
875 | 15 | } |
876 | | |
877 | 508 | for (const auto &access_description : access_descriptions) { |
878 | 508 | der::Parser access_location_parser(access_description.access_location); |
879 | 508 | CBS_ASN1_TAG access_location_tag; |
880 | 508 | der::Input access_location_value; |
881 | 508 | if (!access_location_parser.ReadTagAndValue(&access_location_tag, |
882 | 508 | &access_location_value)) { |
883 | 0 | return false; |
884 | 0 | } |
885 | | |
886 | | // GeneralName ::= CHOICE { |
887 | 508 | if (access_location_tag == (CBS_ASN1_CONTEXT_SPECIFIC | 6)) { |
888 | | // uniformResourceIdentifier [6] IA5String, |
889 | 157 | std::string_view uri = BytesAsStringView(access_location_value); |
890 | 157 | if (!bssl::string_util::IsAscii(uri)) { |
891 | 1 | return false; |
892 | 1 | } |
893 | | |
894 | 156 | if (access_description.access_method_oid == der::Input(kAdCaIssuersOid)) { |
895 | 65 | out_ca_issuers_uris->push_back(uri); |
896 | 91 | } else if (access_description.access_method_oid == |
897 | 91 | der::Input(kAdOcspOid)) { |
898 | 32 | out_ocsp_uris->push_back(uri); |
899 | 32 | } |
900 | 156 | } |
901 | 508 | } |
902 | 114 | return true; |
903 | 115 | } |
904 | | |
905 | 3.39k | ParsedDistributionPoint::ParsedDistributionPoint() = default; |
906 | | ParsedDistributionPoint::ParsedDistributionPoint( |
907 | 6.97k | ParsedDistributionPoint &&other) = default; |
908 | 10.3k | ParsedDistributionPoint::~ParsedDistributionPoint() = default; |
909 | | |
910 | | bool ParseCrlDistributionPoints( |
911 | | der::Input extension_value, |
912 | 1.10k | std::vector<ParsedDistributionPoint> *distribution_points) { |
913 | 1.10k | distribution_points->clear(); |
914 | | |
915 | | // RFC 5280, section 4.2.1.13. |
916 | | // |
917 | | // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint |
918 | 1.10k | der::Parser extension_value_parser(extension_value); |
919 | 1.10k | der::Parser distribution_points_parser; |
920 | 1.10k | if (!extension_value_parser.ReadSequence(&distribution_points_parser)) { |
921 | 504 | return false; |
922 | 504 | } |
923 | 602 | if (extension_value_parser.HasMore()) { |
924 | 44 | return false; |
925 | 44 | } |
926 | | |
927 | | // Sequence must have a minimum of 1 item. |
928 | 558 | if (!distribution_points_parser.HasMore()) { |
929 | 1 | return false; |
930 | 1 | } |
931 | | |
932 | 3.57k | while (distribution_points_parser.HasMore()) { |
933 | 3.39k | if (!ParseAndAddDistributionPoint(&distribution_points_parser, |
934 | 3.39k | distribution_points)) { |
935 | 375 | return false; |
936 | 375 | } |
937 | 3.39k | } |
938 | | |
939 | 182 | return true; |
940 | 557 | } |
941 | | |
942 | 722 | ParsedAuthorityKeyIdentifier::ParsedAuthorityKeyIdentifier() = default; |
943 | 777 | ParsedAuthorityKeyIdentifier::~ParsedAuthorityKeyIdentifier() = default; |
944 | | ParsedAuthorityKeyIdentifier::ParsedAuthorityKeyIdentifier( |
945 | 55 | ParsedAuthorityKeyIdentifier &&other) = default; |
946 | | ParsedAuthorityKeyIdentifier &ParsedAuthorityKeyIdentifier::operator=( |
947 | 0 | ParsedAuthorityKeyIdentifier &&other) = default; |
948 | | |
949 | | bool ParseAuthorityKeyIdentifier( |
950 | | der::Input extension_value, |
951 | 722 | ParsedAuthorityKeyIdentifier *authority_key_identifier) { |
952 | | // RFC 5280, section 4.2.1.1. |
953 | | // AuthorityKeyIdentifier ::= SEQUENCE { |
954 | | // keyIdentifier [0] KeyIdentifier OPTIONAL, |
955 | | // authorityCertIssuer [1] GeneralNames OPTIONAL, |
956 | | // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } |
957 | | // |
958 | | // KeyIdentifier ::= OCTET STRING |
959 | | |
960 | 722 | der::Parser extension_value_parser(extension_value); |
961 | 722 | der::Parser aki_parser; |
962 | 722 | if (!extension_value_parser.ReadSequence(&aki_parser)) { |
963 | 530 | return false; |
964 | 530 | } |
965 | 192 | if (extension_value_parser.HasMore()) { |
966 | 62 | return false; |
967 | 62 | } |
968 | | |
969 | | // TODO(mattm): Should having an empty AuthorityKeyIdentifier SEQUENCE be an |
970 | | // error? RFC 5280 doesn't explicitly say it. |
971 | | |
972 | | // keyIdentifier [0] KeyIdentifier OPTIONAL, |
973 | 130 | if (!aki_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 0, |
974 | 130 | &authority_key_identifier->key_identifier)) { |
975 | 16 | return false; |
976 | 16 | } |
977 | | |
978 | | // authorityCertIssuer [1] GeneralNames OPTIONAL, |
979 | 114 | if (!aki_parser.ReadOptionalTag( |
980 | 114 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, |
981 | 114 | &authority_key_identifier->authority_cert_issuer)) { |
982 | 5 | return false; |
983 | 5 | } |
984 | | |
985 | | // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } |
986 | 109 | if (!aki_parser.ReadOptionalTag( |
987 | 109 | CBS_ASN1_CONTEXT_SPECIFIC | 2, |
988 | 109 | &authority_key_identifier->authority_cert_serial_number)) { |
989 | 11 | return false; |
990 | 11 | } |
991 | | |
992 | | // -- authorityCertIssuer and authorityCertSerialNumber MUST both |
993 | | // -- be present or both be absent |
994 | 98 | if (authority_key_identifier->authority_cert_issuer.has_value() != |
995 | 98 | authority_key_identifier->authority_cert_serial_number.has_value()) { |
996 | 13 | return false; |
997 | 13 | } |
998 | | |
999 | | // There shouldn't be any unconsumed data in the AuthorityKeyIdentifier |
1000 | | // SEQUENCE. |
1001 | 85 | if (aki_parser.HasMore()) { |
1002 | 58 | return false; |
1003 | 58 | } |
1004 | | |
1005 | 27 | return true; |
1006 | 85 | } |
1007 | | |
1008 | | bool ParseSubjectKeyIdentifier(der::Input extension_value, |
1009 | 38 | der::Input *subject_key_identifier) { |
1010 | | // SubjectKeyIdentifier ::= KeyIdentifier |
1011 | | // |
1012 | | // KeyIdentifier ::= OCTET STRING |
1013 | 38 | der::Parser extension_value_parser(extension_value); |
1014 | 38 | if (!extension_value_parser.ReadTag(CBS_ASN1_OCTETSTRING, |
1015 | 38 | subject_key_identifier)) { |
1016 | 9 | return false; |
1017 | 9 | } |
1018 | | |
1019 | | // There shouldn't be any unconsumed data in the extension SEQUENCE. |
1020 | 29 | if (extension_value_parser.HasMore()) { |
1021 | 3 | return false; |
1022 | 3 | } |
1023 | | |
1024 | 26 | return true; |
1025 | 29 | } |
1026 | | |
1027 | | BSSL_NAMESPACE_END |