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

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

Issue 1923433002: Certificate path builder for new certificate verification library (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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/signature_algorithm.h" 12 #include "net/cert/internal/signature_algorithm.h"
13 #include "net/cert/internal/signature_policy.h" 13 #include "net/cert/internal/signature_policy.h"
14 #include "net/cert/internal/verify_name_match.h" 14 #include "net/cert/internal/verify_name_match.h"
15 #include "net/cert/internal/verify_signed_data.h" 15 #include "net/cert/internal/verify_signed_data.h"
16 #include "net/der/input.h" 16 #include "net/der/input.h"
17 #include "net/der/parser.h" 17 #include "net/der/parser.h"
18 18
19 namespace net { 19 namespace net {
20 20
21 namespace { 21 namespace {
22 22
23 // Map from OID to ParsedExtension. 23 // Map from OID to ParsedExtension.
24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; 24 using ExtensionsMap = std::map<der::Input, ParsedExtension>;
25 25
26 // Describes all parsed properties of a certificate that are relevant for 26 // Describes all parsed properties of a certificate that are relevant for
27 // certificate verification. 27 // certificate verification.
28 struct FullyParsedCert { 28 struct FullyParsedCert {
29 ParsedCertificate cert; 29 // XXX better naming.. this results in lots of non-obvious cert.cert->foo code
30 ParsedTbsCertificate tbs; 30 const CertThing* cert;
31
32 // XXX should some of this be moved into CertThing?
31 33
32 std::unique_ptr<SignatureAlgorithm> signature_algorithm; 34 std::unique_ptr<SignatureAlgorithm> signature_algorithm;
33 35
34 // Standard extensions that were parsed. 36 // Standard extensions that were parsed.
35 bool has_basic_constraints = false; 37 bool has_basic_constraints = false;
36 ParsedBasicConstraints basic_constraints; 38 ParsedBasicConstraints basic_constraints;
37 39
38 bool has_key_usage = false; 40 bool has_key_usage = false;
39 der::BitString key_usage; 41 der::BitString key_usage;
40 42
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 } 74 }
73 return true; 75 return true;
74 } 76 }
75 77
76 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, 78 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
77 der::Input* value) { 79 der::Input* value) {
78 der::Parser parser(tlv); 80 der::Parser parser(tlv);
79 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); 81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
80 } 82 }
81 83
84 // XXX update doc
82 // Parses an X.509 Certificate fully (including the TBSCertificate and 85 // Parses an X.509 Certificate fully (including the TBSCertificate and
83 // standard extensions), saving all the properties to |out_|. 86 // standard extensions), saving all the properties to |out_|.
84 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, 87 WARN_UNUSED_RESULT bool FullyParseCertificate(const CertThing& cert,
85 FullyParsedCert* out) { 88 FullyParsedCert* out) {
86 // Parse the outer Certificate. 89 // XXX move more of this into CertThing?
87 if (!ParseCertificate(cert_tlv, &out->cert)) 90
88 return false; 91 out->cert = &cert;
89 92
90 // Parse the signature algorithm contained in the Certificate (there is 93 // Parse the signature algorithm contained in the Certificate (there is
91 // another one in the TBSCertificate, which is checked later by 94 // another one in the TBSCertificate, which is checked later by
92 // VerifySignatureAlgorithmsMatch) 95 // VerifySignatureAlgorithmsMatch)
93 out->signature_algorithm = 96 out->signature_algorithm = SignatureAlgorithm::CreateFromDer(
94 SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv); 97 cert.parsed_cert().signature_algorithm_tlv);
95 if (!out->signature_algorithm) 98 if (!out->signature_algorithm)
96 return false; 99 return false;
97 100
98 // Parse the TBSCertificate.
99 if (!ParseTbsCertificate(out->cert.tbs_certificate_tlv, &out->tbs))
100 return false;
101
102 // Reset state relating to extensions (which may not get overwritten). This is 101 // Reset state relating to extensions (which may not get overwritten). This is
103 // just a precaution, since in practice |out| will already be default 102 // just a precaution, since in practice |out| will already be default
104 // initialize. 103 // initialize.
105 out->has_basic_constraints = false; 104 out->has_basic_constraints = false;
106 out->has_key_usage = false; 105 out->has_key_usage = false;
107 out->unconsumed_extensions.clear(); 106 out->unconsumed_extensions.clear();
108 out->subject_alt_names.reset(); 107 out->subject_alt_names.reset();
109 out->has_name_constraints = false; 108 out->has_name_constraints = false;
110 109
111 // Parse the standard X.509 extensions and remove them from 110 // Parse the standard X.509 extensions and remove them from
112 // |unconsumed_extensions|. 111 // |unconsumed_extensions|.
113 if (out->tbs.has_extensions) { 112 if (cert.parsed_tbs().has_extensions) {
114 // ParseExtensions() ensures there are no duplicates, and maps the (unique) 113 // ParseExtensions() ensures there are no duplicates, and maps the (unique)
115 // OID to the extension value. 114 // OID to the extension value.
116 if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions)) 115 if (!ParseExtensions(cert.parsed_tbs().extensions_tlv,
116 &out->unconsumed_extensions))
117 return false; 117 return false;
118 118
119 ParsedExtension extension; 119 ParsedExtension extension;
120 120
121 // Basic constraints. 121 // Basic constraints.
122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, 122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions,
123 &extension)) { 123 &extension)) {
124 out->has_basic_constraints = true; 124 out->has_basic_constraints = true;
125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) 125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints))
126 return false; 126 return false;
(...skipping 15 matching lines...) Expand all
142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value); 142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value);
143 if (!out->subject_alt_names) 143 if (!out->subject_alt_names)
144 return false; 144 return false;
145 // RFC 5280 section 4.1.2.6: 145 // RFC 5280 section 4.1.2.6:
146 // If subject naming information is present only in the subjectAltName 146 // If subject naming information is present only in the subjectAltName
147 // extension (e.g., a key bound only to an email address or URI), then the 147 // extension (e.g., a key bound only to an email address or URI), then the
148 // subject name MUST be an empty sequence and the subjectAltName extension 148 // subject name MUST be an empty sequence and the subjectAltName extension
149 // MUST be critical. 149 // MUST be critical.
150 if (!extension.critical) { 150 if (!extension.critical) {
151 der::Input subject_value; 151 der::Input subject_value;
152 if (!GetSequenceValue(out->tbs.subject_tlv, &subject_value)) 152 if (!GetSequenceValue(cert.parsed_tbs().subject_tlv, &subject_value))
153 return false; 153 return false;
154 if (subject_value.Length() == 0) 154 if (subject_value.Length() == 0)
155 return false; 155 return false;
156 } 156 }
157 } 157 }
158 158
159 // Name constraints. 159 // Name constraints.
160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, 160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions,
161 &out->name_constraints_extension)) { 161 &out->name_constraints_extension)) {
162 out->has_name_constraints = true; 162 out->has_name_constraints = true;
(...skipping 25 matching lines...) Expand all
188 // 188 //
189 // A certificate is self-issued if the same DN appears in the subject 189 // A certificate is self-issued if the same DN appears in the subject
190 // and issuer fields (the two DNs are the same if they match according 190 // and issuer fields (the two DNs are the same if they match according
191 // to the rules specified in Section 7.1). In general, the issuer and 191 // to the rules specified in Section 7.1). In general, the issuer and
192 // subject of the certificates that make up a path are different for 192 // subject of the certificates that make up a path are different for
193 // each certificate. However, a CA may issue a certificate to itself to 193 // each certificate. However, a CA may issue a certificate to itself to
194 // support key rollover or changes in certificate policies. These 194 // support key rollover or changes in certificate policies. These
195 // self-issued certificates are not counted when evaluating path length 195 // self-issued certificates are not counted when evaluating path length
196 // or name constraints. 196 // or name constraints.
197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { 197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) {
198 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); 198 return cert.cert->normalized_subject() == cert.cert->normalized_issuer();
199 } 199 }
200 200
201 // Returns true if |cert| is valid at time |time|. 201 // Returns true if |cert| is valid at time |time|.
202 // 202 //
203 // The certificate's validity requirements are described by RFC 5280 section 203 // The certificate's validity requirements are described by RFC 5280 section
204 // 4.1.2.5: 204 // 4.1.2.5:
205 // 205 //
206 // The validity period for a certificate is the period of time from 206 // The validity period for a certificate is the period of time from
207 // notBefore through notAfter, inclusive. 207 // notBefore through notAfter, inclusive.
208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, 208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert,
209 const der::GeneralizedTime time) { 209 const der::GeneralizedTime time) {
210 return !(time < cert.tbs.validity_not_before) && 210 return !(time < cert.cert->parsed_tbs().validity_not_before) &&
211 !(cert.tbs.validity_not_after < time); 211 !(cert.cert->parsed_tbs().validity_not_after < time);
212 } 212 }
213 213
214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for 214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for
215 // RSA with SHA1. 215 // RSA with SHA1.
216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( 216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm(
217 const der::Input& signature_algorithm_tlv) { 217 const der::Input& signature_algorithm_tlv) {
218 std::unique_ptr<SignatureAlgorithm> algorithm = 218 std::unique_ptr<SignatureAlgorithm> algorithm =
219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); 219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv);
220 220
221 return algorithm && 221 return algorithm &&
(...skipping 15 matching lines...) Expand all
237 // 237 //
238 // The spec is not explicit about what "the same algorithm identifier" means. 238 // The spec is not explicit about what "the same algorithm identifier" means.
239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte 239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte
240 // identical. 240 // identical.
241 // 241 //
242 // In practice however there are certificates which use different encodings for 242 // In practice however there are certificates which use different encodings for
243 // specifying RSA with SHA1 (different OIDs). This is special-cased for 243 // specifying RSA with SHA1 (different OIDs). This is special-cased for
244 // compatibility sake. 244 // compatibility sake.
245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( 245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch(
246 const FullyParsedCert& cert) { 246 const FullyParsedCert& cert) {
247 const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv; 247 const der::Input& alg1_tlv = cert.cert->parsed_cert().signature_algorithm_tlv;
248 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; 248 const der::Input& alg2_tlv = cert.cert->parsed_tbs().signature_algorithm_tlv;
249 249
250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte 250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte
251 // equal, but make a compatibility concession for RSA with SHA1. 251 // equal, but make a compatibility concession for RSA with SHA1.
252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && 252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) &&
253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); 253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv));
254 } 254 }
255 255
256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate 256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
257 // Processing" procedure. 257 // Processing" procedure.
258 // 258 //
259 // |skip_issuer_checks| controls whether the function will skip: 259 // |skip_issuer_checks| controls whether the function will skip:
260 // - Checking that |cert|'s signature using |working_spki| 260 // - Checking that |cert|'s signature using |working_spki|
261 // - Checkinging that |cert|'s issuer matches |working_issuer_name| 261 // - Checkinging that |cert|'s issuer matches |working_normalized_issuer_name|
262 // This should be set to true only when verifying a trusted root certificate. 262 // This should be set to true only when verifying a trusted root certificate.
263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( 263 WARN_UNUSED_RESULT bool BasicCertificateProcessing(
264 const FullyParsedCert& cert, 264 const FullyParsedCert& cert,
265 bool is_target_cert, 265 bool is_target_cert,
266 bool skip_issuer_checks, 266 bool skip_issuer_checks,
267 const SignaturePolicy* signature_policy, 267 const SignaturePolicy* signature_policy,
268 const der::GeneralizedTime& time, 268 const der::GeneralizedTime& time,
269 const der::Input& working_spki, 269 const der::Input& working_spki,
270 const der::Input& working_issuer_name, 270 const der::Input& working_normalized_issuer_name,
271 const std::vector<std::unique_ptr<NameConstraints>>& 271 const std::vector<std::unique_ptr<NameConstraints>>&
272 name_constraints_list) { 272 name_constraints_list) {
273 // Check that the signature algorithms in Certificate vs TBSCertificate 273 // Check that the signature algorithms in Certificate vs TBSCertificate
274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by 274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by
275 // sections 4.1.1.2 and 4.1.2.3. 275 // sections 4.1.1.2 and 4.1.2.3.
276 if (!VerifySignatureAlgorithmsMatch(cert)) 276 if (!VerifySignatureAlgorithmsMatch(cert))
277 return false; 277 return false;
278 278
279 // Verify the digital signature using the previous certificate's key (RFC 279 // Verify the digital signature using the previous certificate's key (RFC
280 // 5280 section 6.1.3 step a.1). 280 // 5280 section 6.1.3 step a.1).
281 if (!skip_issuer_checks) { 281 if (!skip_issuer_checks) {
282 if (!VerifySignedData( 282 if (!VerifySignedData(*cert.signature_algorithm,
283 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, 283 cert.cert->parsed_cert().tbs_certificate_tlv,
284 cert.cert.signature_value, working_spki, signature_policy)) { 284 cert.cert->parsed_cert().signature_value,
285 working_spki, signature_policy)) {
285 return false; 286 return false;
286 } 287 }
287 } 288 }
288 289
289 // Check the time range for the certificate's validity, ensuring it is valid 290 // Check the time range for the certificate's validity, ensuring it is valid
290 // at |time|. 291 // at |time|.
291 // (RFC 5280 section 6.1.3 step a.2) 292 // (RFC 5280 section 6.1.3 step a.2)
292 if (!VerifyTimeValidity(cert, time)) 293 if (!VerifyTimeValidity(cert, time))
293 return false; 294 return false;
294 295
295 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) 296 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3)
296 297
297 // Verify the certificate's issuer name matches the issuing certificate's 298 // Verify the certificate's issuer name matches the issuing certificate's
298 // subject name. (RFC 5280 section 6.1.3 step a.4) 299 // subject name. (RFC 5280 section 6.1.3 step a.4)
299 if (!skip_issuer_checks) { 300 if (!skip_issuer_checks) {
300 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) 301 if (der::Input(&cert.cert->normalized_issuer()) !=
302 working_normalized_issuer_name)
301 return false; 303 return false;
302 } 304 }
303 305
304 // Name constraints (RFC 5280 section 6.1.3 step b & c) 306 // Name constraints (RFC 5280 section 6.1.3 step b & c)
305 // If certificate i is self-issued and it is not the final certificate in the 307 // If certificate i is self-issued and it is not the final certificate in the
306 // path, skip this step for certificate i. 308 // path, skip this step for certificate i.
307 if (!name_constraints_list.empty() && 309 if (!name_constraints_list.empty() &&
308 (!IsSelfIssued(cert) || is_target_cert)) { 310 (!IsSelfIssued(cert) || is_target_cert)) {
311 // XXX used normalized_subject here
309 der::Input subject_value; 312 der::Input subject_value;
310 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) 313 if (!GetSequenceValue(cert.cert->parsed_tbs().subject_tlv, &subject_value))
311 return false; 314 return false;
312 for (const auto& nc : name_constraints_list) { 315 for (const auto& nc : name_constraints_list) {
313 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get())) 316 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get()))
314 return false; 317 return false;
315 } 318 }
316 } 319 }
317 320
318 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet 321 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet
319 // implemented. 322 // implemented.
320 323
321 return true; 324 return true;
322 } 325 }
323 326
324 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for 327 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for
325 // Certificate i+1" procedure. |cert| is expected to be an intermediary. 328 // Certificate i+1" procedure. |cert| is expected to be an intermediary.
326 WARN_UNUSED_RESULT bool PrepareForNextCertificate( 329 WARN_UNUSED_RESULT bool PrepareForNextCertificate(
327 const FullyParsedCert& cert, 330 const FullyParsedCert& cert,
328 size_t* max_path_length_ptr, 331 size_t* max_path_length_ptr,
329 der::Input* working_spki, 332 der::Input* working_spki,
330 der::Input* working_issuer_name, 333 der::Input* working_normalized_issuer_name,
331 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { 334 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) {
332 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet 335 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet
333 // implemented. 336 // implemented.
334 337
335 // From RFC 5280 section 6.1.4 step c: 338 // From RFC 5280 section 6.1.4 step c:
336 // 339 //
337 // Assign the certificate subject name to working_issuer_name. 340 // Assign the certificate subject name to working_normalized_issuer_name.
338 *working_issuer_name = cert.tbs.subject_tlv; 341 *working_normalized_issuer_name =
342 der::Input(&cert.cert->normalized_subject());
339 343
340 // From RFC 5280 section 6.1.4 step d: 344 // From RFC 5280 section 6.1.4 step d:
341 // 345 //
342 // Assign the certificate subjectPublicKey to working_public_key. 346 // Assign the certificate subjectPublicKey to working_public_key.
343 *working_spki = cert.tbs.spki_tlv; 347 *working_spki = cert.cert->parsed_tbs().spki_tlv;
344 348
345 // Note that steps e and f are omitted as they are handled by 349 // Note that steps e and f are omitted as they are handled by
346 // the assignment to |working_spki| above. See the definition 350 // the assignment to |working_spki| above. See the definition
347 // of |working_spki|. 351 // of |working_spki|.
348 352
349 // From RFC 5280 section 6.1.4 step g: 353 // From RFC 5280 section 6.1.4 step g:
350 if (cert.has_name_constraints) { 354 if (cert.has_name_constraints) {
351 std::unique_ptr<NameConstraints> name_constraints( 355 std::unique_ptr<NameConstraints> name_constraints(
352 NameConstraints::CreateFromDer( 356 NameConstraints::CreateFromDer(
353 cert.name_constraints_extension.value, 357 cert.name_constraints_extension.value,
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", 491 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure",
488 // however is implied by RFC 5280 section 4.2.1.9. 492 // however is implied by RFC 5280 section 4.2.1.9.
489 if (!VerifyTargetCertHasConsistentCaBits(cert)) 493 if (!VerifyTargetCertHasConsistentCaBits(cert))
490 return false; 494 return false;
491 495
492 return true; 496 return true;
493 } 497 }
494 498
495 } // namespace 499 } // namespace
496 500
497 TrustAnchor::TrustAnchor() {} 501 CertThing::CertThing() {}
498 TrustAnchor::~TrustAnchor() {} 502 CertThing::~CertThing() {}
499 503
500 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData( 504 std::unique_ptr<CertThing> CertThing::CreateFromCertificateData(
501 const uint8_t* data, 505 const uint8_t* data,
502 size_t length, 506 size_t length,
503 DataSource source) { 507 DataSource source) {
504 std::unique_ptr<TrustAnchor> result(new TrustAnchor); 508 std::unique_ptr<CertThing> result(new CertThing);
505 509
506 switch (source) { 510 switch (source) {
507 case DataSource::INTERNAL_COPY: 511 case DataSource::INTERNAL_COPY:
508 result->cert_data_.assign(data, data + length); 512 result->cert_data_.assign(data, data + length);
509 result->cert_ = 513 result->cert_ =
510 der::Input(result->cert_data_.data(), result->cert_data_.size()); 514 der::Input(result->cert_data_.data(), result->cert_data_.size());
511 break; 515 break;
512 case DataSource::EXTERNAL_REFERENCE: 516 case DataSource::EXTERNAL_REFERENCE:
513 result->cert_ = der::Input(data, length); 517 result->cert_ = der::Input(data, length);
514 break; 518 break;
515 } 519 }
516 520
517 // Parse the certificate to get its name. 521 // Parse the certificate to get its name.
518 ParsedCertificate cert; 522 if (!ParseCertificate(result->cert_, &result->parsed_cert_))
519 if (!ParseCertificate(result->cert(), &cert))
520 return nullptr; 523 return nullptr;
521 524
522 ParsedTbsCertificate tbs; 525 if (!ParseTbsCertificate(result->parsed_cert_.tbs_certificate_tlv,
523 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) 526 &result->parsed_tbs_))
524 return nullptr; 527 return nullptr;
525 528
526 result->name_ = tbs.subject_tlv; 529 der::Input subject_value;
527 530 if (!GetSequenceValue(result->parsed_tbs_.subject_tlv, &subject_value) ||
528 // TODO(eroman): If adding a self-signed certificate, check that its 531 !NormalizeName(subject_value, &result->normalized_subject_))
529 // signature is correct? This check will not otherwise be done during 532 return nullptr;
530 // verification. 533 der::Input issuer_value;
534 if (!GetSequenceValue(result->parsed_tbs_.issuer_tlv, &issuer_value) ||
535 !NormalizeName(issuer_value, &result->normalized_issuer_))
536 return nullptr;
531 537
532 return result; 538 return result;
533 } 539 }
534 540
535 bool TrustAnchor::MatchesName(const der::Input& name) const { 541 std::unique_ptr<CertThing> CertThing::CreateFromCertificateCopy(
536 return NameMatches(name, name_); 542 const base::StringPiece& data) {
543 return CertThing::CreateFromCertificateData(
544 reinterpret_cast<const uint8_t*>(data.data()), data.size(),
545 DataSource::INTERNAL_COPY);
546 }
547
548 std::unique_ptr<CertThing> CertThing::Clone() const {
549 // XXX Should it always INTERNAL_COPY, or should it continue with what the
550 // previous had?.. lifetimes could get weird with that. (Eg, someone created a
551 // Cert, passed it to a function they could gaurantee it would outlive, but
552 // that function internall makes a clone and returns it as part of the results
553 // or error info..)
554 /*std::unique_ptr<CertThing>
555 result(CreateFromCertificateData(cert_.UnsafeData(), cert_.Length(),
556 CertThing::DataSource::INTERNAL_COPY));
557 // If it parsed to make this object, it should never fail to parse again.
558 CHECK(result);
559 return result;*/
560
561 std::unique_ptr<CertThing> result(new CertThing);
562
563 result->cert_data_.assign(
564 reinterpret_cast<const char*>(cert_.UnsafeData()),
565 reinterpret_cast<const char*>(cert_.UnsafeData()) + cert_.Length());
566 result->cert_ =
567 der::Input(result->cert_data_.data(), result->cert_data_.size());
568
569 result->parsed_cert_ = ParsedCertificate(parsed_cert_, cert_, result->cert_);
570 result->parsed_tbs_ = ParsedTbsCertificate(parsed_tbs_, cert_, result->cert_);
571
572 result->normalized_subject_ = normalized_subject_;
573 result->normalized_issuer_ = normalized_issuer_;
574
575 // XXX clean up
576 /*result->parsed_cert_.tbs_certificate_tlv = der::Input(
577 result->cert_.UnsafeData() +
578 (parsed_cert_.tbs_certificate_tlv.UnsafeData() - cert_.UnsafeData()),
579 parsed_cert_.tbs_certificate_tlv.Length());*/
580
581 return result;
582 }
583
584 bool CertThing::MatchesName(const der::Input& name) const {
585 return NameMatches(name, parsed_tbs_.subject_tlv); // XXX don't re-normalize
537 } 586 }
538 587
539 TrustStore::TrustStore() {} 588 TrustStore::TrustStore() {}
540 TrustStore::~TrustStore() {} 589 TrustStore::~TrustStore() {}
541 590
542 void TrustStore::Clear() { 591 void TrustStore::Clear() {
543 anchors_.clear(); 592 anchors_.clear();
544 } 593 }
545 594
546 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { 595 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) {
596 // TODO(eroman): If adding a self-signed certificate, check that its
597 // signature is correct? This check will not otherwise be done during
598 // verification.
547 return AddTrustedCertificate(data, length, 599 return AddTrustedCertificate(data, length,
548 TrustAnchor::DataSource::INTERNAL_COPY); 600 CertThing::DataSource::INTERNAL_COPY);
549 } 601 }
550 602
551 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { 603 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) {
552 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), 604 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()),
553 data.size()); 605 data.size());
554 } 606 }
555 607
556 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, 608 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data,
557 size_t length) { 609 size_t length) {
558 return AddTrustedCertificate(data, length, 610 return AddTrustedCertificate(data, length,
559 TrustAnchor::DataSource::EXTERNAL_REFERENCE); 611 CertThing::DataSource::EXTERNAL_REFERENCE);
560 } 612 }
561 613
562 const TrustAnchor* TrustStore::FindTrustAnchorByName( 614 const CertThing* TrustStore::FindTrustAnchorByName(
563 const der::Input& name) const { 615 const der::Input& name) const {
564 for (const auto& anchor : anchors_) { 616 for (const auto& anchor : anchors_) {
565 if (anchor->MatchesName(name)) { 617 if (anchor->MatchesName(name)) {
566 return anchor.get(); 618 return anchor.get();
567 } 619 }
568 } 620 }
569 return nullptr; 621 return nullptr;
570 } 622 }
571 623
624 std::vector<const CertThing*> TrustStore::FindTrustAnchorsByNormalizedName(
625 const std::string& normalized_name) const {
626 std::vector<const CertThing*> result;
627 for (const auto& anchor : anchors_) {
628 if (anchor->normalized_subject() == normalized_name) {
629 result.push_back(anchor.get());
630 }
631 }
632 return result;
633 }
634
572 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { 635 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const {
573 for (const auto& anchor : anchors_) { 636 for (const auto& anchor : anchors_) {
574 if (anchor->cert() == cert_der) 637 if (anchor->der_cert() == cert_der)
575 return true; 638 return true;
576 } 639 }
577 return false; 640 return false;
578 } 641 }
579 642
580 bool TrustStore::AddTrustedCertificate(const uint8_t* data, 643 bool TrustStore::AddTrustedCertificate(const uint8_t* data,
581 size_t length, 644 size_t length,
582 TrustAnchor::DataSource source) { 645 CertThing::DataSource source) {
583 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source); 646 auto anchor = CertThing::CreateFromCertificateData(data, length, source);
584 if (!anchor) 647 if (!anchor)
585 return false; 648 return false;
586 anchors_.push_back(std::move(anchor)); 649 anchors_.push_back(std::move(anchor));
587 return true; 650 return true;
588 } 651 }
589 652
590 // TODO(eroman): Move this into existing anonymous namespace.
591 namespace {
592
593 // This implementation is structured to mimic the description of certificate 653 // This implementation is structured to mimic the description of certificate
594 // path verification given by RFC 5280 section 6.1. 654 // path verification given by RFC 5280 section 6.1.
595 // 655 //
596 // Unlike RFC 5280, the trust anchor is specified as the root certificate in 656 // Unlike RFC 5280, the trust anchor is specified as the root certificate in
597 // the chain. This root certificate is assumed to be trusted, and neither its 657 // the chain. This root certificate is assumed to be trusted, and neither its
598 // signature nor issuer name are verified. (It needn't be self-signed). 658 // signature nor issuer name are verified. (It needn't be self-signed).
599 bool VerifyCertificateChainAssumingTrustedRoot( 659 bool VerifyCertificateChainAssumingTrustedRoot(
600 const std::vector<der::Input>& certs_der, 660 const std::vector<std::unique_ptr<CertThing>>& certs,
601 // The trust store is only used for assertions. 661 // The trust store is only used for assertions.
602 const TrustStore& trust_store, 662 const TrustStore& trust_store,
603 const SignaturePolicy* signature_policy, 663 const SignaturePolicy* signature_policy,
604 const der::GeneralizedTime& time) { 664 const der::GeneralizedTime& time) {
605 // An empty chain is necessarily invalid. 665 // An empty chain is necessarily invalid.
606 if (certs_der.empty()) 666 if (certs.empty())
607 return false; 667 return false;
608 668
609 // IMPORTANT: the assumption being made is that the root certificate in 669 // IMPORTANT: the assumption being made is that the root certificate in
610 // the given path is the trust anchor (and has already been verified as 670 // the given path is the trust anchor (and has already been verified as
611 // such). 671 // such).
612 DCHECK(trust_store.IsTrustedCertificate(certs_der.back())); 672 DCHECK(trust_store.IsTrustedCertificate(certs.back()->der_cert())); // XXX
613 673
614 // Will contain a NameConstraints for each previous cert in the chain which 674 // Will contain a NameConstraints for each previous cert in the chain which
615 // had nameConstraints. This corresponds to the permitted_subtrees and 675 // had nameConstraints. This corresponds to the permitted_subtrees and
616 // excluded_subtrees state variables from RFC 5280. 676 // excluded_subtrees state variables from RFC 5280.
617 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; 677 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list;
618 678
619 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: 679 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280:
620 // * working_public_key 680 // * working_public_key
621 // * working_public_key_algorithm 681 // * working_public_key_algorithm
622 // * working_public_key_parameters 682 // * working_public_key_parameters
623 // 683 //
624 // They are combined for simplicity since the signature verification takes an 684 // They are combined for simplicity since the signature verification takes an
625 // SPKI, and the parameter inheritence is not applicable for the supported 685 // SPKI, and the parameter inheritence is not applicable for the supported
626 // key types. 686 // key types.
627 // 687 //
628 // An approximate explanation of |working_spki| is this description from RFC 688 // An approximate explanation of |working_spki| is this description from RFC
629 // 5280 section 6.1.2: 689 // 5280 section 6.1.2:
630 // 690 //
631 // working_public_key: the public key used to verify the 691 // working_public_key: the public key used to verify the
632 // signature of a certificate. 692 // signature of a certificate.
633 der::Input working_spki; 693 der::Input working_spki;
634 694
635 // |working_issuer_name| corresponds with the same named variable in RFC 5280 695 // |working_normalized_issuer_name| is the normalized value of the
636 // section 6.1.2: 696 // working_issuer_name variable in RFC 5280 section 6.1.2:
637 // 697 //
638 // working_issuer_name: the issuer distinguished name expected 698 // working_issuer_name: the issuer distinguished name expected
639 // in the next certificate in the chain. 699 // in the next certificate in the chain.
640 der::Input working_issuer_name; 700 der::Input working_normalized_issuer_name;
641 701
642 // |max_path_length| corresponds with the same named variable in RFC 5280 702 // |max_path_length| corresponds with the same named variable in RFC 5280
643 // section 6.1.2: 703 // section 6.1.2:
644 // 704 //
645 // max_path_length: this integer is initialized to n, is 705 // max_path_length: this integer is initialized to n, is
646 // decremented for each non-self-issued certificate in the path, 706 // decremented for each non-self-issued certificate in the path,
647 // and may be reduced to the value in the path length constraint 707 // and may be reduced to the value in the path length constraint
648 // field within the basic constraints extension of a CA 708 // field within the basic constraints extension of a CA
649 // certificate. 709 // certificate.
650 size_t max_path_length = certs_der.size(); 710 size_t max_path_length = certs.size();
651 711
652 // Iterate over all the certificates in the reverse direction: starting from 712 // Iterate over all the certificates in the reverse direction: starting from
653 // the trust anchor and progressing towards the target certificate. 713 // the trust anchor and progressing towards the target certificate.
654 // 714 //
655 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. 715 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based.
656 // 716 //
657 // * i=0 : Trust anchor. 717 // * i=0 : Trust anchor.
658 // * i=N-1 : Target certificate. 718 // * i=N-1 : Target certificate.
659 for (size_t i = 0; i < certs_der.size(); ++i) { 719 for (size_t i = 0; i < certs.size(); ++i) {
660 const size_t index_into_certs_der = certs_der.size() - i - 1; 720 const size_t index_into_certs = certs.size() - i - 1;
661 721
662 // |is_target_cert| is true if the current certificate is the target 722 // |is_target_cert| is true if the current certificate is the target
663 // certificate being verified. The target certificate isn't necessarily an 723 // certificate being verified. The target certificate isn't necessarily an
664 // end-entity certificate. 724 // end-entity certificate.
665 const bool is_target_cert = index_into_certs_der == 0; 725 const bool is_target_cert = index_into_certs == 0;
666 726
667 // |is_trust_anchor| is true if the current certificate is the trust 727 // |is_trust_anchor| is true if the current certificate is the trust
668 // anchor. This certificate is implicitly trusted. 728 // anchor. This certificate is implicitly trusted.
669 const bool is_trust_anchor = i == 0; 729 const bool is_trust_anchor = i == 0;
670 730
671 // Parse the current certificate into |cert|. 731 // Parse the current certificate into |cert|.
672 FullyParsedCert cert; 732 FullyParsedCert cert;
673 const der::Input& cert_der = certs_der[index_into_certs_der]; 733 const CertThing& cert_thing = *certs[index_into_certs];
674 if (!FullyParseCertificate(cert_der, &cert)) 734 if (!FullyParseCertificate(cert_thing, &cert))
675 return false; 735 return false;
676 736
677 // Per RFC 5280 section 6.1: 737 // Per RFC 5280 section 6.1:
678 // * Do basic processing for each certificate 738 // * Do basic processing for each certificate
679 // * If it is the last certificate in the path (target certificate) 739 // * If it is the last certificate in the path (target certificate)
680 // - Then run "Wrap up" 740 // - Then run "Wrap up"
681 // - Otherwise run "Prepare for Next cert" 741 // - Otherwise run "Prepare for Next cert"
682 if (!BasicCertificateProcessing( 742 if (!BasicCertificateProcessing(cert, is_target_cert, is_trust_anchor,
683 cert, is_target_cert, is_trust_anchor, signature_policy, time, 743 signature_policy, time, working_spki,
684 working_spki, working_issuer_name, name_constraints_list)) { 744 working_normalized_issuer_name,
745 name_constraints_list)) {
685 return false; 746 return false;
686 } 747 }
687 if (!is_target_cert) { 748 if (!is_target_cert) {
688 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, 749 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki,
689 &working_issuer_name, 750 &working_normalized_issuer_name,
690 &name_constraints_list)) { 751 &name_constraints_list)) {
691 return false; 752 return false;
692 } 753 }
693 } else { 754 } else {
694 if (!WrapUp(cert)) 755 if (!WrapUp(cert))
695 return false; 756 return false;
696 } 757 }
697 } 758 }
698 759
699 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: 760 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
700 // 761 //
701 // A certificate MUST NOT appear more than once in a prospective 762 // A certificate MUST NOT appear more than once in a prospective
702 // certification path. 763 // certification path.
703 764
704 return true; 765 return true;
705 } 766 }
706 767
768 // TODO(eroman): Move this into existing anonymous namespace.
769 namespace {
770
707 // TODO(eroman): This function is a temporary hack in the absence of full 771 // TODO(eroman): This function is a temporary hack in the absence of full
708 // path building. It may insert 1 certificate at the root of the 772 // path building. It may insert 1 certificate at the root of the
709 // chain to ensure that the path's root certificate is a trust anchor. 773 // chain to ensure that the path's root certificate is a trust anchor.
710 // 774 //
711 // Beyond this no other verification is done on the chain. The caller is 775 // Beyond this no other verification is done on the chain. The caller is
712 // responsible for verifying the subsequent chain's correctness. 776 // responsible for verifying the subsequent chain's correctness.
713 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( 777 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor(
714 const std::vector<der::Input>& certs_der, 778 const std::vector<der::Input>& certs_der,
715 const TrustStore& trust_store, 779 const TrustStore& trust_store,
716 std::vector<der::Input>* certs_der_trusted_root) { 780 std::vector<der::Input>* certs_der_trusted_root) {
(...skipping 14 matching lines...) Expand all
731 ParsedCertificate cert; 795 ParsedCertificate cert;
732 ParsedTbsCertificate tbs; 796 ParsedTbsCertificate tbs;
733 if (!ParseCertificate(certs_der.back(), &cert) || 797 if (!ParseCertificate(certs_der.back(), &cert) ||
734 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { 798 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) {
735 return false; 799 return false;
736 } 800 }
737 801
738 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); 802 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv);
739 if (!trust_anchor) 803 if (!trust_anchor)
740 return false; 804 return false;
741 certs_der_trusted_root->push_back(trust_anchor->cert()); 805 certs_der_trusted_root->push_back(trust_anchor->der_cert());
742 return true; 806 return true;
743 } 807 }
744 808
745 } // namespace 809 } // namespace
746 810
747 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, 811 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der,
748 const TrustStore& trust_store, 812 const TrustStore& trust_store,
749 const SignaturePolicy* signature_policy, 813 const SignaturePolicy* signature_policy,
750 const der::GeneralizedTime& time) { 814 const der::GeneralizedTime& time) {
751 // Modify the certificate chain so that its root is a trusted certificate. 815 // Modify the certificate chain so that its root is a trusted certificate.
752 std::vector<der::Input> certs_der_trusted_root; 816 std::vector<der::Input> certs_der_trusted_root;
753 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, 817 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store,
754 &certs_der_trusted_root)) { 818 &certs_der_trusted_root)) {
755 return false; 819 return false;
756 } 820 }
757 821
822 std::vector<std::unique_ptr<CertThing>> certs_trusted_root;
823 for (const auto& cert_der : certs_der_trusted_root) {
824 std::unique_ptr<CertThing> cert(CertThing::CreateFromCertificateData(
825 cert_der.UnsafeData(), cert_der.Length(),
826 CertThing::DataSource::EXTERNAL_REFERENCE));
827 if (!cert)
828 return false;
829 certs_trusted_root.push_back(std::move(cert));
830 }
831
758 // Verify the chain. 832 // Verify the chain.
759 return VerifyCertificateChainAssumingTrustedRoot( 833 return VerifyCertificateChainAssumingTrustedRoot(
760 certs_der_trusted_root, trust_store, signature_policy, time); 834 certs_trusted_root, trust_store, signature_policy, time);
761 } 835 }
762 836
763 } // namespace net 837 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698