1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/cert/internal/parse_certificate.h"
7 #include "net/der/input.h"
8 #include "net/der/parse_values.h"
9 #include "net/der/parser.h"
15 // Returns true if |input| is a SEQUENCE and nothing else.
16 WARN_UNUSED_RESULT
bool IsSequenceTLV(const der::Input
& input
) {
17 der::Parser
parser(input
);
18 der::Parser unused_sequence_parser
;
19 if (!parser
.ReadSequence(&unused_sequence_parser
))
21 // Should by a single SEQUENCE by definition of the function.
22 return !parser
.HasMore();
25 // Reads a SEQUENCE from |parser| and writes the full tag-length-value into
26 // |out|. On failure |parser| may or may not have been advanced.
27 WARN_UNUSED_RESULT
bool ReadSequenceTLV(der::Parser
* parser
, der::Input
* out
) {
28 return parser
->ReadRawTLV(out
) && IsSequenceTLV(*out
);
31 // Parses a Version according to RFC 5280:
33 // Version ::= INTEGER { v1(0), v2(1), v3(2) }
35 // No value other that v1, v2, or v3 is allowed (and if given will fail). RFC
36 // 5280 minimally requires the handling of v3 (and overwhelmingly these are the
37 // certificate versions in use today):
39 // Implementations SHOULD be prepared to accept any version certificate.
40 // At a minimum, conforming implementations MUST recognize version 3
42 WARN_UNUSED_RESULT
bool ParseVersion(const der::Input
& in
,
43 CertificateVersion
* version
) {
44 der::Parser
parser(in
);
46 if (!parser
.ReadUint64(&version64
))
51 *version
= CertificateVersion::V1
;
54 *version
= CertificateVersion::V2
;
57 *version
= CertificateVersion::V3
;
60 // Don't allow any other version identifier.
64 // By definition the input to this function was a single INTEGER, so there
65 // shouldn't be anything else after it.
66 return !parser
.HasMore();
69 // Returns true if the given serial number (CertificateSerialNumber in RFC 5280)
72 // CertificateSerialNumber ::= INTEGER
74 // The input to this function is the (unverified) value octets of the INTEGER.
75 // This function will verify that:
77 // * The octets are a valid DER-encoding of an INTEGER (for instance, minimal
80 // * No more than 20 octets are used.
82 // Note that it DOES NOT reject non-positive values (zero or negative).
84 // For reference, here is what RFC 5280 section 4.1.2.2 says:
86 // Given the uniqueness requirements above, serial numbers can be
87 // expected to contain long integers. Certificate users MUST be able to
88 // handle serialNumber values up to 20 octets. Conforming CAs MUST NOT
89 // use serialNumber values longer than 20 octets.
91 // Note: Non-conforming CAs may issue certificates with serial numbers
92 // that are negative or zero. Certificate users SHOULD be prepared to
93 // gracefully handle such certificates.
94 WARN_UNUSED_RESULT
bool VerifySerialNumber(const der::Input
& value
) {
96 if (!der::IsValidInteger(value
, &unused_negative
))
99 // Check if the serial number is too long per RFC 5280.
100 if (value
.Length() > 20)
106 // Consumes a "Time" value (as defined by RFC 5280) from |parser|. On success
107 // writes the result to |*out| and returns true. On failure no guarantees are
108 // made about the state of |parser|.
114 // generalTime GeneralizedTime }
115 WARN_UNUSED_RESULT
bool ReadTime(der::Parser
* parser
,
116 der::GeneralizedTime
* out
) {
120 if (!parser
->ReadTagAndValue(&tag
, &value
))
123 if (tag
== der::kUtcTime
)
124 return der::ParseUTCTime(value
, out
);
126 if (tag
== der::kGeneralizedTime
)
127 return der::ParseGeneralizedTime(value
, out
);
133 // Parses a DER-encoded "Validity" as specified by RFC 5280. Returns true on
134 // success and sets the results in |not_before| and |not_after|:
136 // Validity ::= SEQUENCE {
140 // Note that upon success it is NOT guaranteed that |*not_before <= *not_after|.
141 bool ParseValidity(const der::Input
& validity_tlv
,
142 der::GeneralizedTime
* not_before
,
143 der::GeneralizedTime
* not_after
) {
144 der::Parser
parser(validity_tlv
);
146 // Validity ::= SEQUENCE {
147 der::Parser validity_parser
;
148 if (!parser
.ReadSequence(&validity_parser
))
152 if (!ReadTime(&validity_parser
, not_before
))
156 if (!ReadTime(&validity_parser
, not_after
))
159 // By definition the input was a single Validity sequence, so there shouldn't
160 // be unconsumed data.
161 if (parser
.HasMore())
164 // The Validity type does not have an extension point.
165 if (validity_parser
.HasMore())
168 // Note that RFC 5280 doesn't require notBefore to be <=
169 // notAfter, so that will not be considered a "parsing" error here. Instead it
170 // will be considered an expired certificate later when testing against the
171 // current timestamp.
177 ParsedTbsCertificate::ParsedTbsCertificate() {}
179 ParsedTbsCertificate::~ParsedTbsCertificate() {}
181 bool ParseCertificate(const der::Input
& certificate_tlv
,
182 ParsedCertificate
* out
) {
183 der::Parser
parser(certificate_tlv
);
185 // Certificate ::= SEQUENCE {
186 der::Parser certificate_parser
;
187 if (!parser
.ReadSequence(&certificate_parser
))
190 // tbsCertificate TBSCertificate,
191 if (!ReadSequenceTLV(&certificate_parser
, &out
->tbs_certificate_tlv
))
194 // signatureAlgorithm AlgorithmIdentifier,
195 if (!ReadSequenceTLV(&certificate_parser
, &out
->signature_algorithm_tlv
))
198 // signatureValue BIT STRING }
199 if (!certificate_parser
.ReadBitString(&out
->signature_value
))
202 // There isn't an extension point at the end of Certificate.
203 if (certificate_parser
.HasMore())
206 // By definition the input was a single Certificate, so there shouldn't be
208 if (parser
.HasMore())
214 // From RFC 5280 section 4.1:
216 // TBSCertificate ::= SEQUENCE {
217 // version [0] EXPLICIT Version DEFAULT v1,
218 // serialNumber CertificateSerialNumber,
219 // signature AlgorithmIdentifier,
221 // validity Validity,
223 // subjectPublicKeyInfo SubjectPublicKeyInfo,
224 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
225 // -- If present, version MUST be v2 or v3
226 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
227 // -- If present, version MUST be v2 or v3
228 // extensions [3] EXPLICIT Extensions OPTIONAL
229 // -- If present, version MUST be v3
231 bool ParseTbsCertificate(const der::Input
& tbs_tlv
, ParsedTbsCertificate
* out
) {
232 der::Parser
parser(tbs_tlv
);
234 // Certificate ::= SEQUENCE {
235 der::Parser tbs_parser
;
236 if (!parser
.ReadSequence(&tbs_parser
))
239 // version [0] EXPLICIT Version DEFAULT v1,
242 if (!tbs_parser
.ReadOptionalTag(der::ContextSpecificConstructed(0), &version
,
247 if (!ParseVersion(version
, &out
->version
))
249 if (out
->version
== CertificateVersion::V1
) {
250 // The correct way to specify v1 is to omit the version field since v1 is
255 out
->version
= CertificateVersion::V1
;
258 // serialNumber CertificateSerialNumber,
259 if (!tbs_parser
.ReadTag(der::kInteger
, &out
->serial_number
))
261 if (!VerifySerialNumber(out
->serial_number
))
264 // signature AlgorithmIdentifier,
265 if (!ReadSequenceTLV(&tbs_parser
, &out
->signature_algorithm_tlv
))
269 if (!ReadSequenceTLV(&tbs_parser
, &out
->issuer_tlv
))
272 // validity Validity,
273 der::Input validity_tlv
;
274 if (!tbs_parser
.ReadRawTLV(&validity_tlv
))
276 if (!ParseValidity(validity_tlv
, &out
->validity_not_before
,
277 &out
->validity_not_after
)) {
282 if (!ReadSequenceTLV(&tbs_parser
, &out
->subject_tlv
))
285 // subjectPublicKeyInfo SubjectPublicKeyInfo,
286 if (!ReadSequenceTLV(&tbs_parser
, &out
->spki_tlv
))
289 // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
290 // -- If present, version MUST be v2 or v3
291 der::Input issuer_unique_id
;
292 if (!tbs_parser
.ReadOptionalTag(der::ContextSpecificPrimitive(1),
294 &out
->has_issuer_unique_id
)) {
297 if (out
->has_issuer_unique_id
) {
298 if (!der::ParseBitString(issuer_unique_id
, &out
->issuer_unique_id
))
300 if (out
->version
!= CertificateVersion::V2
&&
301 out
->version
!= CertificateVersion::V3
) {
306 // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
307 // -- If present, version MUST be v2 or v3
308 der::Input subject_unique_id
;
309 if (!tbs_parser
.ReadOptionalTag(der::ContextSpecificPrimitive(2),
311 &out
->has_subject_unique_id
)) {
314 if (out
->has_subject_unique_id
) {
315 if (!der::ParseBitString(subject_unique_id
, &out
->subject_unique_id
))
317 if (out
->version
!= CertificateVersion::V2
&&
318 out
->version
!= CertificateVersion::V3
) {
323 // extensions [3] EXPLICIT Extensions OPTIONAL
324 // -- If present, version MUST be v3
325 if (!tbs_parser
.ReadOptionalTag(der::ContextSpecificConstructed(3),
326 &out
->extensions_tlv
, &out
->has_extensions
)) {
329 if (out
->has_extensions
) {
330 // extensions_tlv must be a single element. Also check that it is a
332 if (!IsSequenceTLV(out
->extensions_tlv
))
334 if (out
->version
!= CertificateVersion::V3
)
338 // Note that there IS an extension point at the end of TBSCertificate
339 // (according to RFC 5912), so from that interpretation, unconsumed data would
340 // be allowed in |tbs_parser|.
342 // However because only v1, v2, and v3 certificates are supported by the
343 // parsing, there shouldn't be any subsequent data in those versions, so
345 if (tbs_parser
.HasMore())
348 // By definition the input was a single TBSCertificate, so there shouldn't be
350 if (parser
.HasMore())