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

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

Powered by Google App Engine
This is Rietveld 408576698