Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Side by Side Diff: net/cert/internal/verify_certificate_chain.cc

Issue 1976433002: Add new ParsedCertificate class, move TrustStore to own file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-parsing-remove-old-parsedcertificate
Patch Set: . Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/internal/verify_certificate_chain.h" 5 #include "net/cert/internal/verify_certificate_chain.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "net/cert/internal/name_constraints.h" 10 #include "net/cert/internal/name_constraints.h"
11 #include "net/cert/internal/parse_certificate.h" 11 #include "net/cert/internal/parse_certificate.h"
12 #include "net/cert/internal/parsed_certificate.h"
12 #include "net/cert/internal/signature_algorithm.h" 13 #include "net/cert/internal/signature_algorithm.h"
13 #include "net/cert/internal/signature_policy.h" 14 #include "net/cert/internal/signature_policy.h"
14 #include "net/cert/internal/verify_name_match.h" 15 #include "net/cert/internal/trust_store.h"
15 #include "net/cert/internal/verify_signed_data.h" 16 #include "net/cert/internal/verify_signed_data.h"
16 #include "net/der/input.h" 17 #include "net/der/input.h"
17 #include "net/der/parser.h" 18 #include "net/der/parser.h"
18 19
19 namespace net { 20 namespace net {
20 21
21 namespace { 22 namespace {
22 23
23 // Map from OID to ParsedExtension.
24 using ExtensionsMap = std::map<der::Input, ParsedExtension>;
25
26 // Describes all parsed properties of a certificate that are relevant for
27 // certificate verification.
28 struct FullyParsedCert {
29 der::Input tbs_certificate_tlv;
30 der::Input signature_algorithm_tlv;
31 der::BitString signature_value;
32 ParsedTbsCertificate tbs;
33
34 std::unique_ptr<SignatureAlgorithm> signature_algorithm;
35
36 // Standard extensions that were parsed.
37 bool has_basic_constraints = false;
38 ParsedBasicConstraints basic_constraints;
39
40 bool has_key_usage = false;
41 der::BitString key_usage;
42
43 std::unique_ptr<GeneralNames> subject_alt_names;
44
45 bool has_name_constraints = false;
46 ParsedExtension name_constraints_extension;
47
48 // The remaining extensions (excludes the standard ones above).
49 ExtensionsMap unconsumed_extensions;
50 };
51
52 // Removes the extension with OID |oid| from |unconsumed_extensions| and fills
53 // |extension| with the matching extension value. If there was no extension
54 // matching |oid| then returns |false|.
55 WARN_UNUSED_RESULT bool ConsumeExtension(const der::Input& oid,
56 ExtensionsMap* unconsumed_extensions,
57 ParsedExtension* extension) {
58 auto it = unconsumed_extensions->find(oid);
59 if (it == unconsumed_extensions->end())
60 return false;
61
62 *extension = it->second;
63 unconsumed_extensions->erase(it);
64 return true;
65 }
66
67 // Returns true if the certificate does not contain any unconsumed _critical_ 24 // Returns true if the certificate does not contain any unconsumed _critical_
68 // extensions. 25 // extensions.
69 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( 26 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions(
70 const FullyParsedCert& cert) { 27 const ParsedCertificate& cert) {
71 for (const auto& entry : cert.unconsumed_extensions) { 28 for (const auto& entry : cert.unconsumed_extensions()) {
72 if (entry.second.critical) 29 if (entry.second.critical)
73 return false; 30 return false;
74 } 31 }
75 return true; 32 return true;
76 } 33 }
77 34
78 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
79 der::Input* value) {
80 der::Parser parser(tlv);
81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
82 }
83
84 // Parses an X.509 Certificate fully (including the TBSCertificate and
85 // standard extensions), saving all the properties to |out_|.
86 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv,
87 FullyParsedCert* out) {
88 // Parse the outer Certificate.
89 if (!ParseCertificate(cert_tlv, &out->tbs_certificate_tlv,
90 &out->signature_algorithm_tlv, &out->signature_value))
91 return false;
92
93 // Parse the signature algorithm contained in the Certificate (there is
94 // another one in the TBSCertificate, which is checked later by
95 // VerifySignatureAlgorithmsMatch)
96 out->signature_algorithm =
97 SignatureAlgorithm::CreateFromDer(out->signature_algorithm_tlv);
98 if (!out->signature_algorithm)
99 return false;
100
101 // Parse the TBSCertificate.
102 if (!ParseTbsCertificate(out->tbs_certificate_tlv, &out->tbs))
103 return false;
104
105 // Reset state relating to extensions (which may not get overwritten). This is
106 // just a precaution, since in practice |out| will already be default
107 // initialize.
108 out->has_basic_constraints = false;
109 out->has_key_usage = false;
110 out->unconsumed_extensions.clear();
111 out->subject_alt_names.reset();
112 out->has_name_constraints = false;
113
114 // Parse the standard X.509 extensions and remove them from
115 // |unconsumed_extensions|.
116 if (out->tbs.has_extensions) {
117 // ParseExtensions() ensures there are no duplicates, and maps the (unique)
118 // OID to the extension value.
119 if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions))
120 return false;
121
122 ParsedExtension extension;
123
124 // Basic constraints.
125 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions,
126 &extension)) {
127 out->has_basic_constraints = true;
128 if (!ParseBasicConstraints(extension.value, &out->basic_constraints))
129 return false;
130 }
131
132 // KeyUsage.
133 if (ConsumeExtension(KeyUsageOid(), &out->unconsumed_extensions,
134 &extension)) {
135 out->has_key_usage = true;
136 if (!ParseKeyUsage(extension.value, &out->key_usage))
137 return false;
138 }
139
140 // Subject alternative name.
141 if (ConsumeExtension(SubjectAltNameOid(), &out->unconsumed_extensions,
142 &extension)) {
143 // RFC 5280 section 4.2.1.6:
144 // SubjectAltName ::= GeneralNames
145 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value);
146 if (!out->subject_alt_names)
147 return false;
148 // RFC 5280 section 4.1.2.6:
149 // If subject naming information is present only in the subjectAltName
150 // extension (e.g., a key bound only to an email address or URI), then the
151 // subject name MUST be an empty sequence and the subjectAltName extension
152 // MUST be critical.
153 if (!extension.critical) {
154 der::Input subject_value;
155 if (!GetSequenceValue(out->tbs.subject_tlv, &subject_value))
156 return false;
157 if (subject_value.Length() == 0)
158 return false;
159 }
160 }
161
162 // Name constraints.
163 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions,
164 &out->name_constraints_extension)) {
165 out->has_name_constraints = true;
166 }
167 }
168
169 return true;
170 }
171
172 // Returns true if |name1_tlv| matches |name2_tlv|. The two inputs must be
173 // tag-length-value for RFC 5280's Name.
174 WARN_UNUSED_RESULT bool NameMatches(const der::Input& name1_tlv,
175 const der::Input& name2_tlv) {
176 der::Input name1_value;
177 der::Input name2_value;
178
179 // Assume that the Name is an RDNSequence. VerifyNameMatch() expects the
180 // value from a SEQUENCE, so strip off the tag.
181 if (!GetSequenceValue(name1_tlv, &name1_value) ||
182 !GetSequenceValue(name2_tlv, &name2_value)) {
183 return false;
184 }
185
186 return VerifyNameMatch(name1_value, name2_value);
187 }
188
189 // Returns true if |cert| was self-issued. The definition of self-issuance 35 // Returns true if |cert| was self-issued. The definition of self-issuance
190 // comes from RFC 5280 section 6.1: 36 // comes from RFC 5280 section 6.1:
191 // 37 //
192 // A certificate is self-issued if the same DN appears in the subject 38 // A certificate is self-issued if the same DN appears in the subject
193 // and issuer fields (the two DNs are the same if they match according 39 // and issuer fields (the two DNs are the same if they match according
194 // to the rules specified in Section 7.1). In general, the issuer and 40 // to the rules specified in Section 7.1). In general, the issuer and
195 // subject of the certificates that make up a path are different for 41 // subject of the certificates that make up a path are different for
196 // each certificate. However, a CA may issue a certificate to itself to 42 // each certificate. However, a CA may issue a certificate to itself to
197 // support key rollover or changes in certificate policies. These 43 // support key rollover or changes in certificate policies. These
198 // self-issued certificates are not counted when evaluating path length 44 // self-issued certificates are not counted when evaluating path length
199 // or name constraints. 45 // or name constraints.
200 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { 46 WARN_UNUSED_RESULT bool IsSelfIssued(const ParsedCertificate& cert) {
201 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); 47 return cert.normalized_subject() == cert.normalized_issuer();
eroman 2016/05/12 18:12:30 yay!
202 } 48 }
203 49
204 // Returns true if |cert| is valid at time |time|. 50 // Returns true if |cert| is valid at time |time|.
205 // 51 //
206 // The certificate's validity requirements are described by RFC 5280 section 52 // The certificate's validity requirements are described by RFC 5280 section
207 // 4.1.2.5: 53 // 4.1.2.5:
208 // 54 //
209 // The validity period for a certificate is the period of time from 55 // The validity period for a certificate is the period of time from
210 // notBefore through notAfter, inclusive. 56 // notBefore through notAfter, inclusive.
211 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, 57 WARN_UNUSED_RESULT bool VerifyTimeValidity(const ParsedCertificate& cert,
212 const der::GeneralizedTime time) { 58 const der::GeneralizedTime time) {
213 return !(time < cert.tbs.validity_not_before) && 59 return !(time < cert.parsed_tbs().validity_not_before) &&
eroman 2016/05/12 18:12:30 maybe we can call the function just cert.tbs() (
mattm 2016/05/13 02:17:37 Done.
214 !(cert.tbs.validity_not_after < time); 60 !(cert.parsed_tbs().validity_not_after < time);
215 } 61 }
216 62
217 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for 63 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for
218 // RSA with SHA1. 64 // RSA with SHA1.
219 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( 65 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm(
220 const der::Input& signature_algorithm_tlv) { 66 const der::Input& signature_algorithm_tlv) {
221 std::unique_ptr<SignatureAlgorithm> algorithm = 67 std::unique_ptr<SignatureAlgorithm> algorithm =
222 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); 68 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv);
223 69
224 return algorithm && 70 return algorithm &&
(...skipping 14 matching lines...) Expand all
239 // signature field in the sequence tbsCertificate (Section 4.1.2.3). 85 // signature field in the sequence tbsCertificate (Section 4.1.2.3).
240 // 86 //
241 // The spec is not explicit about what "the same algorithm identifier" means. 87 // The spec is not explicit about what "the same algorithm identifier" means.
242 // Our interpretation is that the two DER-encoded fields must be byte-for-byte 88 // Our interpretation is that the two DER-encoded fields must be byte-for-byte
243 // identical. 89 // identical.
244 // 90 //
245 // In practice however there are certificates which use different encodings for 91 // In practice however there are certificates which use different encodings for
246 // specifying RSA with SHA1 (different OIDs). This is special-cased for 92 // specifying RSA with SHA1 (different OIDs). This is special-cased for
247 // compatibility sake. 93 // compatibility sake.
248 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( 94 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch(
249 const FullyParsedCert& cert) { 95 const ParsedCertificate& cert) {
250 const der::Input& alg1_tlv = cert.signature_algorithm_tlv; 96 const der::Input& alg1_tlv = cert.signature_algorithm_tlv();
251 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; 97 const der::Input& alg2_tlv = cert.parsed_tbs().signature_algorithm_tlv;
252 98
253 // Ensure that the two DER-encoded signature algorithms are byte-for-byte 99 // Ensure that the two DER-encoded signature algorithms are byte-for-byte
254 // equal, but make a compatibility concession for RSA with SHA1. 100 // equal, but make a compatibility concession for RSA with SHA1.
255 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && 101 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) &&
256 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); 102 IsRsaWithSha1SignatureAlgorithm(alg2_tlv));
257 } 103 }
258 104
259 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate 105 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
260 // Processing" procedure. 106 // Processing" procedure.
261 // 107 //
262 // |skip_issuer_checks| controls whether the function will skip: 108 // |skip_issuer_checks| controls whether the function will skip:
263 // - Checking that |cert|'s signature using |working_spki| 109 // - Checking that |cert|'s signature using |working_spki|
264 // - Checkinging that |cert|'s issuer matches |working_issuer_name| 110 // - Checkinging that |cert|'s issuer matches |working_normalized_issuer_name|
265 // This should be set to true only when verifying a trusted root certificate. 111 // This should be set to true only when verifying a trusted root certificate.
266 WARN_UNUSED_RESULT bool BasicCertificateProcessing( 112 WARN_UNUSED_RESULT bool BasicCertificateProcessing(
267 const FullyParsedCert& cert, 113 const ParsedCertificate& cert,
268 bool is_target_cert, 114 bool is_target_cert,
269 bool skip_issuer_checks, 115 bool skip_issuer_checks,
270 const SignaturePolicy* signature_policy, 116 const SignaturePolicy* signature_policy,
271 const der::GeneralizedTime& time, 117 const der::GeneralizedTime& time,
272 const der::Input& working_spki, 118 const der::Input& working_spki,
273 const der::Input& working_issuer_name, 119 const der::Input& working_normalized_issuer_name,
274 const std::vector<std::unique_ptr<NameConstraints>>& 120 const std::vector<const NameConstraints*>& name_constraints_list) {
275 name_constraints_list) {
276 // Check that the signature algorithms in Certificate vs TBSCertificate 121 // Check that the signature algorithms in Certificate vs TBSCertificate
277 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by 122 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by
278 // sections 4.1.1.2 and 4.1.2.3. 123 // sections 4.1.1.2 and 4.1.2.3.
279 if (!VerifySignatureAlgorithmsMatch(cert)) 124 if (!VerifySignatureAlgorithmsMatch(cert))
280 return false; 125 return false;
281 126
282 // Verify the digital signature using the previous certificate's key (RFC 127 // Verify the digital signature using the previous certificate's key (RFC
283 // 5280 section 6.1.3 step a.1). 128 // 5280 section 6.1.3 step a.1).
284 if (!skip_issuer_checks) { 129 if (!skip_issuer_checks) {
285 if (!VerifySignedData(*cert.signature_algorithm, cert.tbs_certificate_tlv, 130 if (!cert.has_supported_signature_algorithm() ||
286 cert.signature_value, working_spki, 131 !VerifySignedData(cert.signature_algorithm(),
287 signature_policy)) { 132 cert.tbs_certificate_tlv(), cert.signature_value(),
133 working_spki, signature_policy)) {
288 return false; 134 return false;
289 } 135 }
290 } 136 }
291 137
292 // Check the time range for the certificate's validity, ensuring it is valid 138 // Check the time range for the certificate's validity, ensuring it is valid
293 // at |time|. 139 // at |time|.
294 // (RFC 5280 section 6.1.3 step a.2) 140 // (RFC 5280 section 6.1.3 step a.2)
295 if (!VerifyTimeValidity(cert, time)) 141 if (!VerifyTimeValidity(cert, time))
296 return false; 142 return false;
297 143
298 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) 144 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3)
299 145
300 // Verify the certificate's issuer name matches the issuing certificate's 146 // Verify the certificate's issuer name matches the issuing certificate's
301 // subject name. (RFC 5280 section 6.1.3 step a.4) 147 // subject name. (RFC 5280 section 6.1.3 step a.4)
302 if (!skip_issuer_checks) { 148 if (!skip_issuer_checks) {
303 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) 149 if (der::Input(&cert.normalized_issuer()) != working_normalized_issuer_name)
304 return false; 150 return false;
305 } 151 }
306 152
307 // Name constraints (RFC 5280 section 6.1.3 step b & c) 153 // Name constraints (RFC 5280 section 6.1.3 step b & c)
308 // If certificate i is self-issued and it is not the final certificate in the 154 // If certificate i is self-issued and it is not the final certificate in the
309 // path, skip this step for certificate i. 155 // path, skip this step for certificate i.
310 if (!name_constraints_list.empty() && 156 if (!name_constraints_list.empty() &&
311 (!IsSelfIssued(cert) || is_target_cert)) { 157 (!IsSelfIssued(cert) || is_target_cert)) {
312 der::Input subject_value; 158 for (const NameConstraints* nc : name_constraints_list) {
313 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) 159 if (!nc->IsPermittedCert(der::Input(&cert.normalized_subject()),
314 return false; 160 cert.subject_alt_names()))
315 for (const auto& nc : name_constraints_list) {
316 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get()))
317 return false; 161 return false;
318 } 162 }
319 } 163 }
320 164
321 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet 165 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet
322 // implemented. 166 // implemented.
323 167
324 return true; 168 return true;
325 } 169 }
326 170
327 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for 171 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for
328 // Certificate i+1" procedure. |cert| is expected to be an intermediary. 172 // Certificate i+1" procedure. |cert| is expected to be an intermediary.
329 WARN_UNUSED_RESULT bool PrepareForNextCertificate( 173 WARN_UNUSED_RESULT bool PrepareForNextCertificate(
330 const FullyParsedCert& cert, 174 const ParsedCertificate& cert,
331 size_t* max_path_length_ptr, 175 size_t* max_path_length_ptr,
332 der::Input* working_spki, 176 der::Input* working_spki,
333 der::Input* working_issuer_name, 177 der::Input* working_normalized_issuer_name,
334 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { 178 std::vector<const NameConstraints*>* name_constraints_list) {
335 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet 179 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet
336 // implemented. 180 // implemented.
337 181
338 // From RFC 5280 section 6.1.4 step c: 182 // From RFC 5280 section 6.1.4 step c:
339 // 183 //
340 // Assign the certificate subject name to working_issuer_name. 184 // Assign the certificate subject name to working_normalized_issuer_name.
341 *working_issuer_name = cert.tbs.subject_tlv; 185 *working_normalized_issuer_name = der::Input(&cert.normalized_subject());
342 186
343 // From RFC 5280 section 6.1.4 step d: 187 // From RFC 5280 section 6.1.4 step d:
344 // 188 //
345 // Assign the certificate subjectPublicKey to working_public_key. 189 // Assign the certificate subjectPublicKey to working_public_key.
346 *working_spki = cert.tbs.spki_tlv; 190 *working_spki = cert.parsed_tbs().spki_tlv;
347 191
348 // Note that steps e and f are omitted as they are handled by 192 // Note that steps e and f are omitted as they are handled by
349 // the assignment to |working_spki| above. See the definition 193 // the assignment to |working_spki| above. See the definition
350 // of |working_spki|. 194 // of |working_spki|.
351 195
352 // From RFC 5280 section 6.1.4 step g: 196 // From RFC 5280 section 6.1.4 step g:
353 if (cert.has_name_constraints) { 197 if (cert.has_name_constraints())
354 std::unique_ptr<NameConstraints> name_constraints( 198 name_constraints_list->push_back(&cert.name_constraints());
355 NameConstraints::CreateFromDer(
356 cert.name_constraints_extension.value,
357 cert.name_constraints_extension.critical));
358 if (!name_constraints)
359 return false;
360 name_constraints_list->push_back(std::move(name_constraints));
361 }
362 199
363 // TODO(eroman): Steps h-j are omitted as policy constraints are not yet 200 // TODO(eroman): Steps h-j are omitted as policy constraints are not yet
364 // implemented. 201 // implemented.
365 202
366 // From RFC 5280 section 6.1.4 step k: 203 // From RFC 5280 section 6.1.4 step k:
367 // 204 //
368 // If certificate i is a version 3 certificate, verify that the 205 // If certificate i is a version 3 certificate, verify that the
369 // basicConstraints extension is present and that cA is set to 206 // basicConstraints extension is present and that cA is set to
370 // TRUE. (If certificate i is a version 1 or version 2 207 // TRUE. (If certificate i is a version 1 or version 2
371 // certificate, then the application MUST either verify that 208 // certificate, then the application MUST either verify that
372 // certificate i is a CA certificate through out-of-band means 209 // certificate i is a CA certificate through out-of-band means
373 // or reject the certificate. Conforming implementations may 210 // or reject the certificate. Conforming implementations may
374 // choose to reject all version 1 and version 2 intermediate 211 // choose to reject all version 1 and version 2 intermediate
375 // certificates.) 212 // certificates.)
376 // 213 //
377 // This code implicitly rejects non version 3 intermediaries, since they 214 // This code implicitly rejects non version 3 intermediaries, since they
378 // can't contain a BasicConstraints extension. 215 // can't contain a BasicConstraints extension.
379 if (!cert.has_basic_constraints || !cert.basic_constraints.is_ca) 216 if (!cert.has_basic_constraints() || !cert.basic_constraints().is_ca)
380 return false; 217 return false;
381 218
382 // From RFC 5280 section 6.1.4 step l: 219 // From RFC 5280 section 6.1.4 step l:
383 // 220 //
384 // If the certificate was not self-issued, verify that 221 // If the certificate was not self-issued, verify that
385 // max_path_length is greater than zero and decrement 222 // max_path_length is greater than zero and decrement
386 // max_path_length by 1. 223 // max_path_length by 1.
387 if (!IsSelfIssued(cert)) { 224 if (!IsSelfIssued(cert)) {
388 if (*max_path_length_ptr == 0) 225 if (*max_path_length_ptr == 0)
389 return false; 226 return false;
390 --(*max_path_length_ptr); 227 --(*max_path_length_ptr);
391 } 228 }
392 229
393 // From RFC 5280 section 6.1.4 step m: 230 // From RFC 5280 section 6.1.4 step m:
394 // 231 //
395 // If pathLenConstraint is present in the certificate and is 232 // If pathLenConstraint is present in the certificate and is
396 // less than max_path_length, set max_path_length to the value 233 // less than max_path_length, set max_path_length to the value
397 // of pathLenConstraint. 234 // of pathLenConstraint.
398 if (cert.basic_constraints.has_path_len && 235 if (cert.basic_constraints().has_path_len &&
399 cert.basic_constraints.path_len < *max_path_length_ptr) { 236 cert.basic_constraints().path_len < *max_path_length_ptr) {
400 *max_path_length_ptr = cert.basic_constraints.path_len; 237 *max_path_length_ptr = cert.basic_constraints().path_len;
401 } 238 }
402 239
403 // From RFC 5280 section 6.1.4 step n: 240 // From RFC 5280 section 6.1.4 step n:
404 // 241 //
405 // If a key usage extension is present, verify that the 242 // If a key usage extension is present, verify that the
406 // keyCertSign bit is set. 243 // keyCertSign bit is set.
407 if (cert.has_key_usage && 244 if (cert.has_key_usage() &&
408 !cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { 245 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
409 return false; 246 return false;
410 } 247 }
411 248
412 // From RFC 5280 section 6.1.4 step o: 249 // From RFC 5280 section 6.1.4 step o:
413 // 250 //
414 // Recognize and process any other critical extension present in 251 // Recognize and process any other critical extension present in
415 // the certificate. Process any other recognized non-critical 252 // the certificate. Process any other recognized non-critical
416 // extension present in the certificate that is relevant to path 253 // extension present in the certificate that is relevant to path
417 // processing. 254 // processing.
418 if (!VerifyNoUnconsumedCriticalExtensions(cert)) 255 if (!VerifyNoUnconsumedCriticalExtensions(cert))
(...skipping 18 matching lines...) Expand all
437 // If the cA boolean is not asserted, then the keyCertSign bit in the key 274 // If the cA boolean is not asserted, then the keyCertSign bit in the key
438 // usage extension MUST NOT be asserted. 275 // usage extension MUST NOT be asserted.
439 // 276 //
440 // TODO(eroman): Strictly speaking the first requirement is on CAs and not the 277 // TODO(eroman): Strictly speaking the first requirement is on CAs and not the
441 // certificate client, so could be skipped. 278 // certificate client, so could be skipped.
442 // 279 //
443 // TODO(eroman): I don't believe Firefox enforces the keyCertSign restriction 280 // TODO(eroman): I don't believe Firefox enforces the keyCertSign restriction
444 // for compatibility reasons. Investigate if we need to similarly relax this 281 // for compatibility reasons. Investigate if we need to similarly relax this
445 // constraint. 282 // constraint.
446 WARN_UNUSED_RESULT bool VerifyTargetCertHasConsistentCaBits( 283 WARN_UNUSED_RESULT bool VerifyTargetCertHasConsistentCaBits(
447 const FullyParsedCert& cert) { 284 const ParsedCertificate& cert) {
448 // Check if the certificate contains any property specific to CAs. 285 // Check if the certificate contains any property specific to CAs.
449 bool has_ca_property = 286 bool has_ca_property =
450 (cert.has_basic_constraints && 287 (cert.has_basic_constraints() &&
451 (cert.basic_constraints.is_ca || cert.basic_constraints.has_path_len)) || 288 (cert.basic_constraints().is_ca ||
452 (cert.has_key_usage && 289 cert.basic_constraints().has_path_len)) ||
453 cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); 290 (cert.has_key_usage() &&
291 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
454 292
455 // If it "looks" like a CA because it has a CA-only property, then check that 293 // If it "looks" like a CA because it has a CA-only property, then check that
456 // it sets ALL the properties expected of a CA. 294 // it sets ALL the properties expected of a CA.
457 if (has_ca_property) { 295 if (has_ca_property) {
458 return cert.has_basic_constraints && cert.basic_constraints.is_ca && 296 return cert.has_basic_constraints() && cert.basic_constraints().is_ca &&
459 (!cert.has_key_usage || 297 (!cert.has_key_usage() ||
460 cert.key_usage.AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); 298 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
461 } 299 }
462 300
463 return true; 301 return true;
464 } 302 }
465 303
466 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". 304 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure".
467 // It does processing for the final certificate (the target cert). 305 // It does processing for the final certificate (the target cert).
468 WARN_UNUSED_RESULT bool WrapUp(const FullyParsedCert& cert) { 306 WARN_UNUSED_RESULT bool WrapUp(const ParsedCertificate& cert) {
469 // TODO(eroman): Steps a-b are omitted as policy constraints are not yet 307 // TODO(eroman): Steps a-b are omitted as policy constraints are not yet
470 // implemented. 308 // implemented.
471 309
472 // Note step c-e are omitted the verification function does 310 // Note step c-e are omitted the verification function does
473 // not output the working public key. 311 // not output the working public key.
474 312
475 // From RFC 5280 section 6.1.5 step f: 313 // From RFC 5280 section 6.1.5 step f:
476 // 314 //
477 // Recognize and process any other critical extension present in 315 // Recognize and process any other critical extension present in
478 // the certificate n. Process any other recognized non-critical 316 // the certificate n. Process any other recognized non-critical
(...skipping 11 matching lines...) Expand all
490 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", 328 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure",
491 // however is implied by RFC 5280 section 4.2.1.9. 329 // however is implied by RFC 5280 section 4.2.1.9.
492 if (!VerifyTargetCertHasConsistentCaBits(cert)) 330 if (!VerifyTargetCertHasConsistentCaBits(cert))
493 return false; 331 return false;
494 332
495 return true; 333 return true;
496 } 334 }
497 335
498 } // namespace 336 } // namespace
499 337
500 TrustAnchor::TrustAnchor() {}
501 TrustAnchor::~TrustAnchor() {}
502
503 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData(
504 const uint8_t* data,
505 size_t length,
506 DataSource source) {
507 std::unique_ptr<TrustAnchor> result(new TrustAnchor);
508
509 switch (source) {
510 case DataSource::INTERNAL_COPY:
511 result->cert_data_.assign(data, data + length);
512 result->cert_ =
513 der::Input(result->cert_data_.data(), result->cert_data_.size());
514 break;
515 case DataSource::EXTERNAL_REFERENCE:
516 result->cert_ = der::Input(data, length);
517 break;
518 }
519
520 // Parse the certificate to get its name.
521 der::Input tbs_certificate_tlv;
522 der::Input signature_algorithm_tlv;
523 der::BitString signature_value;
524 if (!ParseCertificate(result->cert(), &tbs_certificate_tlv,
525 &signature_algorithm_tlv, &signature_value))
526 return nullptr;
527
528 ParsedTbsCertificate tbs;
529 if (!ParseTbsCertificate(tbs_certificate_tlv, &tbs))
530 return nullptr;
531
532 result->name_ = tbs.subject_tlv;
533
534 // TODO(eroman): If adding a self-signed certificate, check that its
535 // signature is correct? This check will not otherwise be done during
536 // verification.
537
538 return result;
539 }
540
541 bool TrustAnchor::MatchesName(const der::Input& name) const {
542 return NameMatches(name, name_);
543 }
544
545 TrustStore::TrustStore() {}
546 TrustStore::~TrustStore() {}
547
548 void TrustStore::Clear() {
549 anchors_.clear();
550 }
551
552 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) {
553 return AddTrustedCertificate(data, length,
554 TrustAnchor::DataSource::INTERNAL_COPY);
555 }
556
557 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) {
558 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()),
559 data.size());
560 }
561
562 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data,
563 size_t length) {
564 return AddTrustedCertificate(data, length,
565 TrustAnchor::DataSource::EXTERNAL_REFERENCE);
566 }
567
568 const TrustAnchor* TrustStore::FindTrustAnchorByName(
569 const der::Input& name) const {
570 for (const auto& anchor : anchors_) {
571 if (anchor->MatchesName(name)) {
572 return anchor.get();
573 }
574 }
575 return nullptr;
576 }
577
578 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const {
579 for (const auto& anchor : anchors_) {
580 if (anchor->cert() == cert_der)
581 return true;
582 }
583 return false;
584 }
585
586 bool TrustStore::AddTrustedCertificate(const uint8_t* data,
587 size_t length,
588 TrustAnchor::DataSource source) {
589 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source);
590 if (!anchor)
591 return false;
592 anchors_.push_back(std::move(anchor));
593 return true;
594 }
595
596 // TODO(eroman): Move this into existing anonymous namespace. 338 // TODO(eroman): Move this into existing anonymous namespace.
597 namespace { 339 namespace {
598 340
599 // This implementation is structured to mimic the description of certificate 341 // This implementation is structured to mimic the description of certificate
600 // path verification given by RFC 5280 section 6.1. 342 // path verification given by RFC 5280 section 6.1.
601 // 343 //
602 // Unlike RFC 5280, the trust anchor is specified as the root certificate in 344 // Unlike RFC 5280, the trust anchor is specified as the root certificate in
603 // the chain. This root certificate is assumed to be trusted, and neither its 345 // the chain. This root certificate is assumed to be trusted, and neither its
604 // signature nor issuer name are verified. (It needn't be self-signed). 346 // signature nor issuer name are verified. (It needn't be self-signed).
605 bool VerifyCertificateChainAssumingTrustedRoot( 347 bool VerifyCertificateChainAssumingTrustedRoot(
606 const std::vector<der::Input>& certs_der, 348 const std::vector<scoped_refptr<ParsedCertificate>>& certs,
607 // The trust store is only used for assertions. 349 // The trust store is only used for assertions.
608 const TrustStore& trust_store, 350 const TrustStore& trust_store,
609 const SignaturePolicy* signature_policy, 351 const SignaturePolicy* signature_policy,
610 const der::GeneralizedTime& time) { 352 const der::GeneralizedTime& time) {
611 // An empty chain is necessarily invalid. 353 // An empty chain is necessarily invalid.
612 if (certs_der.empty()) 354 if (certs.empty())
613 return false; 355 return false;
614 356
615 // IMPORTANT: the assumption being made is that the root certificate in 357 // IMPORTANT: the assumption being made is that the root certificate in
616 // the given path is the trust anchor (and has already been verified as 358 // the given path is the trust anchor (and has already been verified as
617 // such). 359 // such).
618 DCHECK(trust_store.IsTrustedCertificate(certs_der.back())); 360 DCHECK(trust_store.IsTrustedCertificate(certs.back().get()));
619 361
620 // Will contain a NameConstraints for each previous cert in the chain which 362 // Will contain a NameConstraints for each previous cert in the chain which
621 // had nameConstraints. This corresponds to the permitted_subtrees and 363 // had nameConstraints. This corresponds to the permitted_subtrees and
622 // excluded_subtrees state variables from RFC 5280. 364 // excluded_subtrees state variables from RFC 5280.
623 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; 365 std::vector<const NameConstraints*> name_constraints_list;
624 366
625 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: 367 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280:
626 // * working_public_key 368 // * working_public_key
627 // * working_public_key_algorithm 369 // * working_public_key_algorithm
628 // * working_public_key_parameters 370 // * working_public_key_parameters
629 // 371 //
630 // They are combined for simplicity since the signature verification takes an 372 // They are combined for simplicity since the signature verification takes an
631 // SPKI, and the parameter inheritence is not applicable for the supported 373 // SPKI, and the parameter inheritence is not applicable for the supported
632 // key types. 374 // key types.
633 // 375 //
634 // An approximate explanation of |working_spki| is this description from RFC 376 // An approximate explanation of |working_spki| is this description from RFC
635 // 5280 section 6.1.2: 377 // 5280 section 6.1.2:
636 // 378 //
637 // working_public_key: the public key used to verify the 379 // working_public_key: the public key used to verify the
638 // signature of a certificate. 380 // signature of a certificate.
639 der::Input working_spki; 381 der::Input working_spki;
640 382
641 // |working_issuer_name| corresponds with the same named variable in RFC 5280 383 // |working_normalized_issuer_name| is the normalized value of the
642 // section 6.1.2: 384 // working_issuer_name variable in RFC 5280 section 6.1.2:
eroman 2016/05/12 18:12:30 thanks for updating the comments throughout!
643 // 385 //
644 // working_issuer_name: the issuer distinguished name expected 386 // working_issuer_name: the issuer distinguished name expected
645 // in the next certificate in the chain. 387 // in the next certificate in the chain.
646 der::Input working_issuer_name; 388 der::Input working_normalized_issuer_name;
647 389
648 // |max_path_length| corresponds with the same named variable in RFC 5280 390 // |max_path_length| corresponds with the same named variable in RFC 5280
649 // section 6.1.2: 391 // section 6.1.2:
650 // 392 //
651 // max_path_length: this integer is initialized to n, is 393 // max_path_length: this integer is initialized to n, is
652 // decremented for each non-self-issued certificate in the path, 394 // decremented for each non-self-issued certificate in the path,
653 // and may be reduced to the value in the path length constraint 395 // and may be reduced to the value in the path length constraint
654 // field within the basic constraints extension of a CA 396 // field within the basic constraints extension of a CA
655 // certificate. 397 // certificate.
656 size_t max_path_length = certs_der.size(); 398 size_t max_path_length = certs.size();
657 399
658 // Iterate over all the certificates in the reverse direction: starting from 400 // Iterate over all the certificates in the reverse direction: starting from
659 // the trust anchor and progressing towards the target certificate. 401 // the trust anchor and progressing towards the target certificate.
660 // 402 //
661 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. 403 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based.
662 // 404 //
663 // * i=0 : Trust anchor. 405 // * i=0 : Trust anchor.
664 // * i=N-1 : Target certificate. 406 // * i=N-1 : Target certificate.
665 for (size_t i = 0; i < certs_der.size(); ++i) { 407 for (size_t i = 0; i < certs.size(); ++i) {
666 const size_t index_into_certs_der = certs_der.size() - i - 1; 408 const size_t index_into_certs = certs.size() - i - 1;
667 409
668 // |is_target_cert| is true if the current certificate is the target 410 // |is_target_cert| is true if the current certificate is the target
669 // certificate being verified. The target certificate isn't necessarily an 411 // certificate being verified. The target certificate isn't necessarily an
670 // end-entity certificate. 412 // end-entity certificate.
671 const bool is_target_cert = index_into_certs_der == 0; 413 const bool is_target_cert = index_into_certs == 0;
672 414
673 // |is_trust_anchor| is true if the current certificate is the trust 415 // |is_trust_anchor| is true if the current certificate is the trust
674 // anchor. This certificate is implicitly trusted. 416 // anchor. This certificate is implicitly trusted.
675 const bool is_trust_anchor = i == 0; 417 const bool is_trust_anchor = i == 0;
676 418
677 // Parse the current certificate into |cert|. 419 const ParsedCertificate& cert = *certs[index_into_certs];
678 FullyParsedCert cert;
679 const der::Input& cert_der = certs_der[index_into_certs_der];
680 if (!FullyParseCertificate(cert_der, &cert))
681 return false;
682 420
683 // Per RFC 5280 section 6.1: 421 // Per RFC 5280 section 6.1:
684 // * Do basic processing for each certificate 422 // * Do basic processing for each certificate
685 // * If it is the last certificate in the path (target certificate) 423 // * If it is the last certificate in the path (target certificate)
686 // - Then run "Wrap up" 424 // - Then run "Wrap up"
687 // - Otherwise run "Prepare for Next cert" 425 // - Otherwise run "Prepare for Next cert"
688 if (!BasicCertificateProcessing( 426 if (!BasicCertificateProcessing(cert, is_target_cert, is_trust_anchor,
689 cert, is_target_cert, is_trust_anchor, signature_policy, time, 427 signature_policy, time, working_spki,
690 working_spki, working_issuer_name, name_constraints_list)) { 428 working_normalized_issuer_name,
429 name_constraints_list)) {
691 return false; 430 return false;
692 } 431 }
693 if (!is_target_cert) { 432 if (!is_target_cert) {
694 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, 433 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki,
695 &working_issuer_name, 434 &working_normalized_issuer_name,
696 &name_constraints_list)) { 435 &name_constraints_list)) {
697 return false; 436 return false;
698 } 437 }
699 } else { 438 } else {
700 if (!WrapUp(cert)) 439 if (!WrapUp(cert))
701 return false; 440 return false;
702 } 441 }
703 } 442 }
704 443
705 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: 444 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
706 // 445 //
707 // A certificate MUST NOT appear more than once in a prospective 446 // A certificate MUST NOT appear more than once in a prospective
708 // certification path. 447 // certification path.
709 448
710 return true; 449 return true;
711 } 450 }
712 451
713 // TODO(eroman): This function is a temporary hack in the absence of full 452 // TODO(eroman): This function is a temporary hack in the absence of full
714 // path building. It may insert 1 certificate at the root of the 453 // path building. It may insert 1 certificate at the root of the
715 // chain to ensure that the path's root certificate is a trust anchor. 454 // chain to ensure that the path's root certificate is a trust anchor.
716 // 455 //
717 // Beyond this no other verification is done on the chain. The caller is 456 // Beyond this no other verification is done on the chain. The caller is
718 // responsible for verifying the subsequent chain's correctness. 457 // responsible for verifying the subsequent chain's correctness.
719 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( 458 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor(
720 const std::vector<der::Input>& certs_der,
721 const TrustStore& trust_store, 459 const TrustStore& trust_store,
722 std::vector<der::Input>* certs_der_trusted_root) { 460 std::vector<scoped_refptr<ParsedCertificate>>* certs) {
723 // Copy the input chain. 461 if (certs->empty())
724 *certs_der_trusted_root = certs_der;
725
726 if (certs_der.empty())
727 return false; 462 return false;
728 463
729 // Check if the current root certificate is trusted. If it is then no 464 // Check if the current root certificate is trusted. If it is then no
730 // extra work is needed. 465 // extra work is needed.
731 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back())) 466 if (trust_store.IsTrustedCertificate(certs->back().get()))
732 return true; 467 return true;
733 468
734 // Otherwise if it is not trusted, check whether its issuer is trusted. If 469 std::vector<scoped_refptr<ParsedCertificate>> trust_anchors;
735 // so, make *that* trusted certificate the root. If the issuer is not in 470 trust_store.FindTrustAnchorsByNormalizedName(
736 // the trust store then give up and fail (this is not full path building). 471 certs->back()->normalized_issuer(), &trust_anchors);
737 der::Input tbs_certificate_tlv; 472 if (trust_anchors.empty())
738 der::Input signature_algorithm_tlv;
739 der::BitString signature_value;
740 ParsedTbsCertificate tbs;
741 if (!ParseCertificate(certs_der.back(), &tbs_certificate_tlv,
742 &signature_algorithm_tlv, &signature_value) ||
743 !ParseTbsCertificate(tbs_certificate_tlv, &tbs)) {
744 return false; 473 return false;
745 } 474 certs->push_back(std::move(trust_anchors[0]));
746
747 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv);
748 if (!trust_anchor)
749 return false;
750 certs_der_trusted_root->push_back(trust_anchor->cert());
751 return true; 475 return true;
752 } 476 }
753 477
754 } // namespace 478 } // namespace
755 479
756 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, 480 bool VerifyCertificateChain(
757 const TrustStore& trust_store, 481 const std::vector<scoped_refptr<ParsedCertificate>>& cert_chain,
758 const SignaturePolicy* signature_policy, 482 const TrustStore& trust_store,
759 const der::GeneralizedTime& time) { 483 const SignaturePolicy* signature_policy,
484 const der::GeneralizedTime& time) {
485 if (cert_chain.empty())
486 return false;
487
488 std::vector<scoped_refptr<ParsedCertificate>> full_chain = cert_chain;
489
760 // Modify the certificate chain so that its root is a trusted certificate. 490 // Modify the certificate chain so that its root is a trusted certificate.
761 std::vector<der::Input> certs_der_trusted_root; 491 if (!BuildSimplePathToTrustAnchor(trust_store, &full_chain)) {
762 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store,
763 &certs_der_trusted_root)) {
764 return false; 492 return false;
765 } 493 }
766 494
767 // Verify the chain. 495 // Verify the chain.
768 return VerifyCertificateChainAssumingTrustedRoot( 496 return VerifyCertificateChainAssumingTrustedRoot(full_chain, trust_store,
769 certs_der_trusted_root, trust_store, signature_policy, time); 497 signature_policy, time);
770 } 498 }
771 499
772 } // namespace net 500 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698