OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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. | |
4 | |
5 #include "net/cert/internal/parsed_certificate.h" | |
6 | |
7 #include "net/cert/internal/name_constraints.h" | |
8 #include "net/cert/internal/signature_algorithm.h" | |
9 #include "net/cert/internal/verify_name_match.h" | |
10 #include "net/der/parser.h" | |
11 | |
12 namespace net { | |
13 | |
14 namespace { | |
15 | |
16 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, | |
17 der::Input* value) { | |
18 der::Parser parser(tlv); | |
19 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); | |
20 } | |
21 | |
22 } // namespace | |
23 | |
24 ParsedCertificate::ParsedCertificate() {} | |
25 ParsedCertificate::~ParsedCertificate() {} | |
26 | |
27 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateData( | |
28 const uint8_t* data, | |
29 size_t length, | |
30 DataSource source) { | |
31 scoped_refptr<ParsedCertificate> result(new ParsedCertificate); | |
32 | |
33 switch (source) { | |
34 case DataSource::INTERNAL_COPY: | |
35 result->cert_data_.assign(data, data + length); | |
36 result->cert_ = | |
37 der::Input(result->cert_data_.data(), result->cert_data_.size()); | |
38 break; | |
39 case DataSource::EXTERNAL_REFERENCE: | |
40 result->cert_ = der::Input(data, length); | |
41 break; | |
42 } | |
43 | |
44 if (!ParseCertificate(result->cert_, &result->tbs_certificate_tlv_, | |
45 &result->signature_algorithm_tlv_, | |
46 &result->signature_value_)) | |
47 return nullptr; | |
eroman
2016/05/12 18:12:29
nit: curly braces?
mattm
2016/05/13 02:17:36
Done.
| |
48 | |
49 if (!ParseTbsCertificate(result->tbs_certificate_tlv_, &result->parsed_tbs_)) | |
50 return nullptr; | |
51 | |
52 // Attempt to parse the signature algorithm contained in the Certificate. | |
53 // Do not give up on failure here, since SignatureAlgorithm::CreateFromDer | |
54 // will fail on valid but unsupported signature algorithms. | |
eroman
2016/05/12 18:12:29
What current consumer is this allowance made for?
mattm
2016/05/13 02:17:36
There are several in tests (PKITS and ours), they
| |
55 // TODO(mattm): should distinguish between unsupported algorithms and parsing | |
56 // errors. | |
57 result->signature_algorithm_ = | |
58 SignatureAlgorithm::CreateFromDer(result->signature_algorithm_tlv_); | |
59 | |
60 der::Input subject_value; | |
61 if (!GetSequenceValue(result->parsed_tbs_.subject_tlv, &subject_value) || | |
62 !NormalizeName(subject_value, &result->normalized_subject_)) | |
63 return nullptr; | |
64 der::Input issuer_value; | |
65 if (!GetSequenceValue(result->parsed_tbs_.issuer_tlv, &issuer_value) || | |
66 !NormalizeName(issuer_value, &result->normalized_issuer_)) | |
67 return nullptr; | |
eroman
2016/05/12 18:12:29
Same question throughout -- if we consider these m
mattm
2016/05/13 02:17:36
yeah, I always forget that. done.
| |
68 | |
69 // Parse the standard X.509 extensions and remove them from | |
70 // |unconsumed_extensions|. | |
71 if (result->parsed_tbs_.has_extensions) { | |
72 // ParseExtensions() ensures there are no duplicates, and maps the (unique) | |
73 // OID to the extension value. | |
74 if (!ParseExtensions(result->parsed_tbs_.extensions_tlv, | |
75 &result->unconsumed_extensions_)) | |
76 return nullptr; | |
77 | |
78 ParsedExtension extension; | |
79 | |
80 // Basic constraints. | |
81 if (ConsumeExtension(BasicConstraintsOid(), &result->unconsumed_extensions_, | |
82 &extension)) { | |
83 result->has_basic_constraints_ = true; | |
84 if (!ParseBasicConstraints(extension.value, &result->basic_constraints_)) | |
85 return nullptr; | |
86 } | |
87 | |
88 // KeyUsage. | |
89 if (ConsumeExtension(KeyUsageOid(), &result->unconsumed_extensions_, | |
90 &extension)) { | |
91 result->has_key_usage_ = true; | |
92 if (!ParseKeyUsage(extension.value, &result->key_usage_)) | |
93 return nullptr; | |
94 } | |
95 | |
96 // Subject alternative name. | |
97 if (ConsumeExtension(SubjectAltNameOid(), &result->unconsumed_extensions_, | |
98 &result->subject_alt_names_extension_)) { | |
99 // RFC 5280 section 4.2.1.6: | |
100 // SubjectAltName ::= GeneralNames | |
101 result->subject_alt_names_ = GeneralNames::CreateFromDer( | |
102 result->subject_alt_names_extension_.value); | |
103 if (!result->subject_alt_names_) | |
104 return nullptr; | |
105 // RFC 5280 section 4.1.2.6: | |
106 // If subject naming information is present only in the subjectAltName | |
107 // extension (e.g., a key bound only to an email address or URI), then the | |
108 // subject name MUST be an empty sequence and the subjectAltName extension | |
109 // MUST be critical. | |
110 if (subject_value.Length() == 0 && | |
111 !result->subject_alt_names_extension_.critical) | |
112 return nullptr; | |
113 } | |
114 | |
115 // Name constraints. | |
116 if (ConsumeExtension(NameConstraintsOid(), &result->unconsumed_extensions_, | |
117 &extension)) { | |
118 result->name_constraints_ = | |
119 NameConstraints::CreateFromDer(extension.value, extension.critical); | |
120 if (!result->name_constraints_) | |
121 return nullptr; | |
122 } | |
123 } | |
124 | |
125 return result; | |
126 } | |
127 | |
128 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateCopy( | |
129 const base::StringPiece& data) { | |
130 return ParsedCertificate::CreateFromCertificateData( | |
131 reinterpret_cast<const uint8_t*>(data.data()), data.size(), | |
132 DataSource::INTERNAL_COPY); | |
133 } | |
134 | |
135 } // namespace net | |
OLD | NEW |