OLD | NEW |
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/cert_errors.h" |
10 #include "net/cert/internal/name_constraints.h" | 11 #include "net/cert/internal/name_constraints.h" |
11 #include "net/cert/internal/parse_certificate.h" | 12 #include "net/cert/internal/parse_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/trust_store.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 |
| 22 using namespace verify_certificate_chain_errors; |
| 23 |
21 namespace { | 24 namespace { |
22 | 25 |
23 // Returns true if the certificate does not contain any unconsumed _critical_ | 26 // Returns true if the certificate does not contain any unconsumed _critical_ |
24 // extensions. | 27 // extensions. |
25 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( | 28 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( |
26 const ParsedCertificate& cert) { | 29 const ParsedCertificate& cert, |
| 30 CertErrors* errors) { |
| 31 bool has_unconsumed_critical_extensions = false; |
| 32 |
27 for (const auto& entry : cert.unparsed_extensions()) { | 33 for (const auto& entry : cert.unparsed_extensions()) { |
28 if (entry.second.critical) | 34 if (entry.second.critical) { |
29 return false; | 35 has_unconsumed_critical_extensions = true; |
| 36 errors->AddWith2DerParams(kUnconsumedCriticalExtension, entry.second.oid, |
| 37 entry.second.value); |
| 38 } |
30 } | 39 } |
31 return true; | 40 |
| 41 return !has_unconsumed_critical_extensions; |
32 } | 42 } |
33 | 43 |
34 // Returns true if |cert| was self-issued. The definition of self-issuance | 44 // Returns true if |cert| was self-issued. The definition of self-issuance |
35 // comes from RFC 5280 section 6.1: | 45 // comes from RFC 5280 section 6.1: |
36 // | 46 // |
37 // A certificate is self-issued if the same DN appears in the subject | 47 // A certificate is self-issued if the same DN appears in the subject |
38 // and issuer fields (the two DNs are the same if they match according | 48 // and issuer fields (the two DNs are the same if they match according |
39 // to the rules specified in Section 7.1). In general, the issuer and | 49 // to the rules specified in Section 7.1). In general, the issuer and |
40 // subject of the certificates that make up a path are different for | 50 // subject of the certificates that make up a path are different for |
41 // each certificate. However, a CA may issue a certificate to itself to | 51 // each certificate. However, a CA may issue a certificate to itself to |
42 // support key rollover or changes in certificate policies. These | 52 // support key rollover or changes in certificate policies. These |
43 // self-issued certificates are not counted when evaluating path length | 53 // self-issued certificates are not counted when evaluating path length |
44 // or name constraints. | 54 // or name constraints. |
45 WARN_UNUSED_RESULT bool IsSelfIssued(const ParsedCertificate& cert) { | 55 WARN_UNUSED_RESULT bool IsSelfIssued(const ParsedCertificate& cert) { |
46 return cert.normalized_subject() == cert.normalized_issuer(); | 56 return cert.normalized_subject() == cert.normalized_issuer(); |
47 } | 57 } |
48 | 58 |
49 // Returns true if |cert| is valid at time |time|. | 59 // Returns true if |cert| is valid at time |time|. |
50 // | 60 // |
51 // The certificate's validity requirements are described by RFC 5280 section | 61 // The certificate's validity requirements are described by RFC 5280 section |
52 // 4.1.2.5: | 62 // 4.1.2.5: |
53 // | 63 // |
54 // The validity period for a certificate is the period of time from | 64 // The validity period for a certificate is the period of time from |
55 // notBefore through notAfter, inclusive. | 65 // notBefore through notAfter, inclusive. |
56 WARN_UNUSED_RESULT bool VerifyTimeValidity(const ParsedCertificate& cert, | 66 WARN_UNUSED_RESULT bool VerifyTimeValidity(const ParsedCertificate& cert, |
57 const der::GeneralizedTime time) { | 67 const der::GeneralizedTime time, |
58 return !(time < cert.tbs().validity_not_before) && | 68 CertErrors* errors) { |
59 !(cert.tbs().validity_not_after < time); | 69 if (time < cert.tbs().validity_not_before) { |
| 70 errors->Add(kValidityFailedNotBefore); |
| 71 return false; |
| 72 } |
| 73 |
| 74 if (cert.tbs().validity_not_after < time) { |
| 75 errors->Add(kValidityFailedNotAfter); |
| 76 return false; |
| 77 } |
| 78 |
| 79 return true; |
60 } | 80 } |
61 | 81 |
62 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for | 82 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for |
63 // RSA with SHA1. | 83 // RSA with SHA1. |
64 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( | 84 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( |
65 const der::Input& signature_algorithm_tlv) { | 85 const der::Input& signature_algorithm_tlv) { |
66 std::unique_ptr<SignatureAlgorithm> algorithm = | 86 std::unique_ptr<SignatureAlgorithm> algorithm = |
67 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); | 87 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); |
68 | 88 |
69 return algorithm && | 89 return algorithm && |
(...skipping 14 matching lines...) Expand all Loading... |
84 // signature field in the sequence tbsCertificate (Section 4.1.2.3). | 104 // signature field in the sequence tbsCertificate (Section 4.1.2.3). |
85 // | 105 // |
86 // The spec is not explicit about what "the same algorithm identifier" means. | 106 // The spec is not explicit about what "the same algorithm identifier" means. |
87 // Our interpretation is that the two DER-encoded fields must be byte-for-byte | 107 // Our interpretation is that the two DER-encoded fields must be byte-for-byte |
88 // identical. | 108 // identical. |
89 // | 109 // |
90 // In practice however there are certificates which use different encodings for | 110 // In practice however there are certificates which use different encodings for |
91 // specifying RSA with SHA1 (different OIDs). This is special-cased for | 111 // specifying RSA with SHA1 (different OIDs). This is special-cased for |
92 // compatibility sake. | 112 // compatibility sake. |
93 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( | 113 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( |
94 const ParsedCertificate& cert) { | 114 const ParsedCertificate& cert, |
| 115 CertErrors* errors) { |
95 const der::Input& alg1_tlv = cert.signature_algorithm_tlv(); | 116 const der::Input& alg1_tlv = cert.signature_algorithm_tlv(); |
96 const der::Input& alg2_tlv = cert.tbs().signature_algorithm_tlv; | 117 const der::Input& alg2_tlv = cert.tbs().signature_algorithm_tlv; |
97 | 118 |
98 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 119 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
99 // equal, but make a compatibility concession for RSA with SHA1. | 120 // equal. |
100 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 121 if (alg1_tlv == alg2_tlv) |
101 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); | 122 return true; |
| 123 |
| 124 // But make a compatibility concession for RSA with SHA1. |
| 125 if (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
| 126 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)) { |
| 127 errors->AddWith2DerParams(kSignatureAlgorithmsDifferentEncoding, alg1_tlv, |
| 128 alg2_tlv); |
| 129 return true; |
| 130 } |
| 131 |
| 132 errors->AddWith2DerParams(kSignatureAlgorithmMismatch, alg1_tlv, alg2_tlv); |
| 133 |
| 134 return false; |
102 } | 135 } |
103 | 136 |
104 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 137 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
105 // Processing" procedure. | 138 // Processing" procedure. |
106 WARN_UNUSED_RESULT bool BasicCertificateProcessing( | 139 WARN_UNUSED_RESULT bool BasicCertificateProcessing( |
107 const ParsedCertificate& cert, | 140 const ParsedCertificate& cert, |
108 bool is_target_cert, | 141 bool is_target_cert, |
109 const SignaturePolicy* signature_policy, | 142 const SignaturePolicy* signature_policy, |
110 const der::GeneralizedTime& time, | 143 const der::GeneralizedTime& time, |
111 const der::Input& working_spki, | 144 const der::Input& working_spki, |
112 const der::Input& working_normalized_issuer_name, | 145 const der::Input& working_normalized_issuer_name, |
113 const std::vector<const NameConstraints*>& name_constraints_list) { | 146 const std::vector<const NameConstraints*>& name_constraints_list, |
| 147 CertErrors* errors) { |
114 // Check that the signature algorithms in Certificate vs TBSCertificate | 148 // Check that the signature algorithms in Certificate vs TBSCertificate |
115 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by | 149 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by |
116 // sections 4.1.1.2 and 4.1.2.3. | 150 // sections 4.1.1.2 and 4.1.2.3. |
117 if (!VerifySignatureAlgorithmsMatch(cert)) | 151 if (!VerifySignatureAlgorithmsMatch(cert, errors)) |
118 return false; | 152 return false; |
119 | 153 |
120 // Verify the digital signature using the previous certificate's key (RFC | 154 // Verify the digital signature using the previous certificate's key (RFC |
121 // 5280 section 6.1.3 step a.1). | 155 // 5280 section 6.1.3 step a.1). |
122 if (!cert.has_valid_supported_signature_algorithm() || | 156 if (!cert.has_valid_supported_signature_algorithm()) { |
123 !VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), | 157 errors->AddWith1DerParam(kInvalidOrUnsupportedAlgorithm, |
| 158 cert.signature_algorithm_tlv()); |
| 159 return false; |
| 160 } |
| 161 |
| 162 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), |
124 cert.signature_value(), working_spki, | 163 cert.signature_value(), working_spki, |
125 signature_policy)) { | 164 signature_policy)) { |
| 165 errors->Add(kSignatureVerificationFailed); |
126 return false; | 166 return false; |
127 } | 167 } |
128 | 168 |
129 // Check the time range for the certificate's validity, ensuring it is valid | 169 // Check the time range for the certificate's validity, ensuring it is valid |
130 // at |time|. | 170 // at |time|. |
131 // (RFC 5280 section 6.1.3 step a.2) | 171 // (RFC 5280 section 6.1.3 step a.2) |
132 if (!VerifyTimeValidity(cert, time)) | 172 if (!VerifyTimeValidity(cert, time, errors)) |
133 return false; | 173 return false; |
134 | 174 |
135 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) | 175 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) |
136 | 176 |
137 // Verify the certificate's issuer name matches the issuing certificate's | 177 // Verify the certificate's issuer name matches the issuing certificate's |
138 // subject name. (RFC 5280 section 6.1.3 step a.4) | 178 // subject name. (RFC 5280 section 6.1.3 step a.4) |
139 if (cert.normalized_issuer() != working_normalized_issuer_name) | 179 if (cert.normalized_issuer() != working_normalized_issuer_name) { |
| 180 errors->Add(kSubjectDoesNotMatchIssuer); |
140 return false; | 181 return false; |
| 182 } |
141 | 183 |
142 // Name constraints (RFC 5280 section 6.1.3 step b & c) | 184 // Name constraints (RFC 5280 section 6.1.3 step b & c) |
143 // If certificate i is self-issued and it is not the final certificate in the | 185 // If certificate i is self-issued and it is not the final certificate in the |
144 // path, skip this step for certificate i. | 186 // path, skip this step for certificate i. |
145 if (!name_constraints_list.empty() && | 187 if (!name_constraints_list.empty() && |
146 (!IsSelfIssued(cert) || is_target_cert)) { | 188 (!IsSelfIssued(cert) || is_target_cert)) { |
147 for (const NameConstraints* nc : name_constraints_list) { | 189 for (const NameConstraints* nc : name_constraints_list) { |
148 if (!nc->IsPermittedCert(cert.normalized_subject(), | 190 if (!nc->IsPermittedCert(cert.normalized_subject(), |
149 cert.subject_alt_names())) { | 191 cert.subject_alt_names())) { |
| 192 errors->Add(kNotPermittedByNameConstraints); |
150 return false; | 193 return false; |
151 } | 194 } |
152 } | 195 } |
153 } | 196 } |
154 | 197 |
155 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet | 198 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet |
156 // implemented. | 199 // implemented. |
157 | 200 |
158 return true; | 201 return true; |
159 } | 202 } |
160 | 203 |
161 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for | 204 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for |
162 // Certificate i+1" procedure. |cert| is expected to be an intermediate. | 205 // Certificate i+1" procedure. |cert| is expected to be an intermediate. |
163 WARN_UNUSED_RESULT bool PrepareForNextCertificate( | 206 WARN_UNUSED_RESULT bool PrepareForNextCertificate( |
164 const ParsedCertificate& cert, | 207 const ParsedCertificate& cert, |
165 size_t* max_path_length_ptr, | 208 size_t* max_path_length_ptr, |
166 der::Input* working_spki, | 209 der::Input* working_spki, |
167 der::Input* working_normalized_issuer_name, | 210 der::Input* working_normalized_issuer_name, |
168 std::vector<const NameConstraints*>* name_constraints_list) { | 211 std::vector<const NameConstraints*>* name_constraints_list, |
| 212 CertErrors* errors) { |
169 // TODO(crbug.com/634456): Steps a-b are omitted, as policy mappings are not | 213 // TODO(crbug.com/634456): Steps a-b are omitted, as policy mappings are not |
170 // yet implemented. | 214 // yet implemented. |
171 | 215 |
172 // From RFC 5280 section 6.1.4 step c: | 216 // From RFC 5280 section 6.1.4 step c: |
173 // | 217 // |
174 // Assign the certificate subject name to working_normalized_issuer_name. | 218 // Assign the certificate subject name to working_normalized_issuer_name. |
175 *working_normalized_issuer_name = cert.normalized_subject(); | 219 *working_normalized_issuer_name = cert.normalized_subject(); |
176 | 220 |
177 // From RFC 5280 section 6.1.4 step d: | 221 // From RFC 5280 section 6.1.4 step d: |
178 // | 222 // |
(...skipping 17 matching lines...) Expand all Loading... |
196 // basicConstraints extension is present and that cA is set to | 240 // basicConstraints extension is present and that cA is set to |
197 // TRUE. (If certificate i is a version 1 or version 2 | 241 // TRUE. (If certificate i is a version 1 or version 2 |
198 // certificate, then the application MUST either verify that | 242 // certificate, then the application MUST either verify that |
199 // certificate i is a CA certificate through out-of-band means | 243 // certificate i is a CA certificate through out-of-band means |
200 // or reject the certificate. Conforming implementations may | 244 // or reject the certificate. Conforming implementations may |
201 // choose to reject all version 1 and version 2 intermediate | 245 // choose to reject all version 1 and version 2 intermediate |
202 // certificates.) | 246 // certificates.) |
203 // | 247 // |
204 // This code implicitly rejects non version 3 intermediates, since they | 248 // This code implicitly rejects non version 3 intermediates, since they |
205 // can't contain a BasicConstraints extension. | 249 // can't contain a BasicConstraints extension. |
206 if (!cert.has_basic_constraints() || !cert.basic_constraints().is_ca) | 250 if (!cert.has_basic_constraints()) { |
| 251 errors->Add(kMissingBasicConstraints); |
207 return false; | 252 return false; |
| 253 } |
| 254 |
| 255 if (!cert.basic_constraints().is_ca) { |
| 256 errors->Add(kBasicConstraintsIndicatesNotCa); |
| 257 return false; |
| 258 } |
208 | 259 |
209 // From RFC 5280 section 6.1.4 step l: | 260 // From RFC 5280 section 6.1.4 step l: |
210 // | 261 // |
211 // If the certificate was not self-issued, verify that | 262 // If the certificate was not self-issued, verify that |
212 // max_path_length is greater than zero and decrement | 263 // max_path_length is greater than zero and decrement |
213 // max_path_length by 1. | 264 // max_path_length by 1. |
214 if (!IsSelfIssued(cert)) { | 265 if (!IsSelfIssued(cert)) { |
215 if (*max_path_length_ptr == 0) | 266 if (*max_path_length_ptr == 0) { |
| 267 errors->Add(kMaxPathLengthViolated); |
216 return false; | 268 return false; |
| 269 } |
217 --(*max_path_length_ptr); | 270 --(*max_path_length_ptr); |
218 } | 271 } |
219 | 272 |
220 // From RFC 5280 section 6.1.4 step m: | 273 // From RFC 5280 section 6.1.4 step m: |
221 // | 274 // |
222 // If pathLenConstraint is present in the certificate and is | 275 // If pathLenConstraint is present in the certificate and is |
223 // less than max_path_length, set max_path_length to the value | 276 // less than max_path_length, set max_path_length to the value |
224 // of pathLenConstraint. | 277 // of pathLenConstraint. |
225 if (cert.basic_constraints().has_path_len && | 278 if (cert.basic_constraints().has_path_len && |
226 cert.basic_constraints().path_len < *max_path_length_ptr) { | 279 cert.basic_constraints().path_len < *max_path_length_ptr) { |
227 *max_path_length_ptr = cert.basic_constraints().path_len; | 280 *max_path_length_ptr = cert.basic_constraints().path_len; |
228 } | 281 } |
229 | 282 |
230 // From RFC 5280 section 6.1.4 step n: | 283 // From RFC 5280 section 6.1.4 step n: |
231 // | 284 // |
232 // If a key usage extension is present, verify that the | 285 // If a key usage extension is present, verify that the |
233 // keyCertSign bit is set. | 286 // keyCertSign bit is set. |
234 if (cert.has_key_usage() && | 287 if (cert.has_key_usage() && |
235 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { | 288 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { |
| 289 errors->Add(kKeyCertSignBitNotSet); |
236 return false; | 290 return false; |
237 } | 291 } |
238 | 292 |
239 // From RFC 5280 section 6.1.4 step o: | 293 // From RFC 5280 section 6.1.4 step o: |
240 // | 294 // |
241 // Recognize and process any other critical extension present in | 295 // Recognize and process any other critical extension present in |
242 // the certificate. Process any other recognized non-critical | 296 // the certificate. Process any other recognized non-critical |
243 // extension present in the certificate that is relevant to path | 297 // extension present in the certificate that is relevant to path |
244 // processing. | 298 // processing. |
245 if (!VerifyNoUnconsumedCriticalExtensions(cert)) | 299 if (!VerifyNoUnconsumedCriticalExtensions(cert, errors)) |
246 return false; | 300 return false; |
247 | 301 |
248 return true; | 302 return true; |
249 } | 303 } |
250 | 304 |
251 // Checks that if the target certificate has properties that only a CA should | 305 // Checks that if the target certificate has properties that only a CA should |
252 // have (keyCertSign, CA=true, pathLenConstraint), then its other properties | 306 // have (keyCertSign, CA=true, pathLenConstraint), then its other properties |
253 // are consistent with being a CA. | 307 // are consistent with being a CA. |
254 // | 308 // |
255 // This follows from some requirements in RFC 5280 section 4.2.1.9. In | 309 // This follows from some requirements in RFC 5280 section 4.2.1.9. In |
256 // particular: | 310 // particular: |
257 // | 311 // |
258 // CAs MUST NOT include the pathLenConstraint field unless the cA | 312 // CAs MUST NOT include the pathLenConstraint field unless the cA |
259 // boolean is asserted and the key usage extension asserts the | 313 // boolean is asserted and the key usage extension asserts the |
260 // keyCertSign bit. | 314 // keyCertSign bit. |
261 // | 315 // |
262 // And: | 316 // And: |
263 // | 317 // |
264 // If the cA boolean is not asserted, then the keyCertSign bit in the key | 318 // If the cA boolean is not asserted, then the keyCertSign bit in the key |
265 // usage extension MUST NOT be asserted. | 319 // usage extension MUST NOT be asserted. |
266 // | 320 // |
267 // TODO(eroman): Strictly speaking the first requirement is on CAs and not the | 321 // TODO(eroman): Strictly speaking the first requirement is on CAs and not the |
268 // certificate client, so could be skipped. | 322 // certificate client, so could be skipped. |
269 // | 323 // |
270 // TODO(eroman): I don't believe Firefox enforces the keyCertSign restriction | 324 // TODO(eroman): I don't believe Firefox enforces the keyCertSign restriction |
271 // for compatibility reasons. Investigate if we need to similarly relax this | 325 // for compatibility reasons. Investigate if we need to similarly relax this |
272 // constraint. | 326 // constraint. |
273 WARN_UNUSED_RESULT bool VerifyTargetCertHasConsistentCaBits( | 327 WARN_UNUSED_RESULT bool VerifyTargetCertHasConsistentCaBits( |
274 const ParsedCertificate& cert) { | 328 const ParsedCertificate& cert, |
| 329 CertErrors* errors) { |
275 // Check if the certificate contains any property specific to CAs. | 330 // Check if the certificate contains any property specific to CAs. |
276 bool has_ca_property = | 331 bool has_ca_property = |
277 (cert.has_basic_constraints() && | 332 (cert.has_basic_constraints() && |
278 (cert.basic_constraints().is_ca || | 333 (cert.basic_constraints().is_ca || |
279 cert.basic_constraints().has_path_len)) || | 334 cert.basic_constraints().has_path_len)) || |
280 (cert.has_key_usage() && | 335 (cert.has_key_usage() && |
281 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); | 336 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); |
282 | 337 |
283 // If it "looks" like a CA because it has a CA-only property, then check that | 338 // If it "looks" like a CA because it has a CA-only property, then check that |
284 // it sets ALL the properties expected of a CA. | 339 // it sets ALL the properties expected of a CA. |
285 if (has_ca_property) { | 340 if (has_ca_property) { |
286 return cert.has_basic_constraints() && cert.basic_constraints().is_ca && | 341 bool success = cert.has_basic_constraints() && |
287 (!cert.has_key_usage() || | 342 cert.basic_constraints().is_ca && |
288 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); | 343 (!cert.has_key_usage() || |
| 344 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); |
| 345 if (!success) { |
| 346 // TODO(eroman): Add DER for basic constraints and key usage. |
| 347 errors->Add(kTargetCertInconsistentCaBits); |
| 348 } |
| 349 |
| 350 return success; |
289 } | 351 } |
290 | 352 |
291 return true; | 353 return true; |
292 } | 354 } |
293 | 355 |
294 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". | 356 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". |
295 // It does processing for the final certificate (the target cert). | 357 // It does processing for the final certificate (the target cert). |
296 WARN_UNUSED_RESULT bool WrapUp(const ParsedCertificate& cert) { | 358 WARN_UNUSED_RESULT bool WrapUp(const ParsedCertificate& cert, |
| 359 CertErrors* errors) { |
297 // TODO(crbug.com/634452): Steps a-b are omitted as policy constraints are not | 360 // TODO(crbug.com/634452): Steps a-b are omitted as policy constraints are not |
298 // yet implemented. | 361 // yet implemented. |
299 | 362 |
300 // Note step c-e are omitted the verification function does | 363 // Note step c-e are omitted the verification function does |
301 // not output the working public key. | 364 // not output the working public key. |
302 | 365 |
303 // From RFC 5280 section 6.1.5 step f: | 366 // From RFC 5280 section 6.1.5 step f: |
304 // | 367 // |
305 // Recognize and process any other critical extension present in | 368 // Recognize and process any other critical extension present in |
306 // the certificate n. Process any other recognized non-critical | 369 // the certificate n. Process any other recognized non-critical |
307 // extension present in certificate n that is relevant to path | 370 // extension present in certificate n that is relevant to path |
308 // processing. | 371 // processing. |
309 // | 372 // |
310 // Note that this is duplicated by PrepareForNextCertificate() so as to | 373 // Note that this is duplicated by PrepareForNextCertificate() so as to |
311 // directly match the procedures in RFC 5280's section 6.1. | 374 // directly match the procedures in RFC 5280's section 6.1. |
312 if (!VerifyNoUnconsumedCriticalExtensions(cert)) | 375 if (!VerifyNoUnconsumedCriticalExtensions(cert, errors)) |
313 return false; | 376 return false; |
314 | 377 |
315 // TODO(eroman): Step g is omitted, as policy constraints are not yet | 378 // TODO(eroman): Step g is omitted, as policy constraints are not yet |
316 // implemented. | 379 // implemented. |
317 | 380 |
318 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", | 381 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", |
319 // however is implied by RFC 5280 section 4.2.1.9. | 382 // however is implied by RFC 5280 section 4.2.1.9. |
320 if (!VerifyTargetCertHasConsistentCaBits(cert)) | 383 if (!VerifyTargetCertHasConsistentCaBits(cert, errors)) |
321 return false; | 384 return false; |
322 | 385 |
323 return true; | 386 return true; |
324 } | 387 } |
325 | 388 |
326 // Initializes the path validation algorithm given anchor constraints. This | 389 // Initializes the path validation algorithm given anchor constraints. This |
327 // follows the description in RFC 5937 | 390 // follows the description in RFC 5937 |
328 WARN_UNUSED_RESULT bool ProcessTrustAnchorConstraints( | 391 WARN_UNUSED_RESULT bool ProcessTrustAnchorConstraints( |
329 const TrustAnchor& trust_anchor, | 392 const TrustAnchor& trust_anchor, |
330 size_t* max_path_length_ptr, | 393 size_t* max_path_length_ptr, |
331 std::vector<const NameConstraints*>* name_constraints_list) { | 394 std::vector<const NameConstraints*>* name_constraints_list, |
| 395 CertErrors* errors) { |
| 396 // Set the trust anchor as the current context for any subsequent errors. |
| 397 ScopedCertErrorsTrustAnchorContext error_context(errors, &trust_anchor); |
| 398 |
332 // In RFC 5937 the enforcement of anchor constraints is governed by the input | 399 // In RFC 5937 the enforcement of anchor constraints is governed by the input |
333 // enforceTrustAnchorConstraints to path validation. In our implementation | 400 // enforceTrustAnchorConstraints to path validation. In our implementation |
334 // this is always on, and enforcement is controlled solely by whether or not | 401 // this is always on, and enforcement is controlled solely by whether or not |
335 // the trust anchor specified constraints. | 402 // the trust anchor specified constraints. |
336 if (!trust_anchor.enforces_constraints()) | 403 if (!trust_anchor.enforces_constraints()) |
337 return true; | 404 return true; |
338 | 405 |
339 // Anchor constraints are encoded via the attached certificate. | 406 // Anchor constraints are encoded via the attached certificate. |
340 const ParsedCertificate& cert = *trust_anchor.cert(); | 407 const ParsedCertificate& cert = *trust_anchor.cert(); |
341 | 408 |
(...skipping 24 matching lines...) Expand all Loading... |
366 // NOTE: RFC 5937 does not say to enforce the CA=true part of basic | 433 // NOTE: RFC 5937 does not say to enforce the CA=true part of basic |
367 // constraints. | 434 // constraints. |
368 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len) | 435 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len) |
369 *max_path_length_ptr = cert.basic_constraints().path_len; | 436 *max_path_length_ptr = cert.basic_constraints().path_len; |
370 | 437 |
371 // From RFC 5937 section 2: | 438 // From RFC 5937 section 2: |
372 // | 439 // |
373 // Extensions may be marked critical or not critical. When trust anchor | 440 // Extensions may be marked critical or not critical. When trust anchor |
374 // constraints are enforced, clients MUST reject certification paths | 441 // constraints are enforced, clients MUST reject certification paths |
375 // containing a trust anchor with unrecognized critical extensions. | 442 // containing a trust anchor with unrecognized critical extensions. |
376 if (!VerifyNoUnconsumedCriticalExtensions(cert)) | 443 if (!VerifyNoUnconsumedCriticalExtensions(cert, errors)) |
377 return false; | 444 return false; |
378 | 445 |
379 return true; | 446 return true; |
380 } | 447 } |
381 | 448 |
382 } // namespace | 449 } // namespace |
383 | 450 |
384 // This implementation is structured to mimic the description of certificate | 451 // This implementation is structured to mimic the description of certificate |
385 // path verification given by RFC 5280 section 6.1. | 452 // path verification given by RFC 5280 section 6.1. |
386 bool VerifyCertificateChain(const ParsedCertificateList& certs, | 453 bool VerifyCertificateChain(const ParsedCertificateList& certs, |
387 const TrustAnchor* trust_anchor, | 454 const TrustAnchor* trust_anchor, |
388 const SignaturePolicy* signature_policy, | 455 const SignaturePolicy* signature_policy, |
389 const der::GeneralizedTime& time) { | 456 const der::GeneralizedTime& time, |
| 457 CertErrors* errors) { |
| 458 DCHECK(trust_anchor); |
| 459 DCHECK(signature_policy); |
| 460 DCHECK(errors); |
| 461 |
390 // An empty chain is necessarily invalid. | 462 // An empty chain is necessarily invalid. |
391 if (certs.empty()) | 463 if (certs.empty()) { |
| 464 errors->Add(kChainIsEmpty); |
392 return false; | 465 return false; |
| 466 } |
393 | 467 |
394 // Will contain a NameConstraints for each previous cert in the chain which | 468 // Will contain a NameConstraints for each previous cert in the chain which |
395 // had nameConstraints. This corresponds to the permitted_subtrees and | 469 // had nameConstraints. This corresponds to the permitted_subtrees and |
396 // excluded_subtrees state variables from RFC 5280. | 470 // excluded_subtrees state variables from RFC 5280. |
397 std::vector<const NameConstraints*> name_constraints_list; | 471 std::vector<const NameConstraints*> name_constraints_list; |
398 | 472 |
399 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: | 473 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: |
400 // * working_public_key | 474 // * working_public_key |
401 // * working_public_key_algorithm | 475 // * working_public_key_algorithm |
402 // * working_public_key_parameters | 476 // * working_public_key_parameters |
(...skipping 22 matching lines...) Expand all Loading... |
425 // | 499 // |
426 // max_path_length: this integer is initialized to n, is | 500 // max_path_length: this integer is initialized to n, is |
427 // decremented for each non-self-issued certificate in the path, | 501 // decremented for each non-self-issued certificate in the path, |
428 // and may be reduced to the value in the path length constraint | 502 // and may be reduced to the value in the path length constraint |
429 // field within the basic constraints extension of a CA | 503 // field within the basic constraints extension of a CA |
430 // certificate. | 504 // certificate. |
431 size_t max_path_length = certs.size(); | 505 size_t max_path_length = certs.size(); |
432 | 506 |
433 // Apply any trust anchor constraints per RFC 5937. | 507 // Apply any trust anchor constraints per RFC 5937. |
434 if (!ProcessTrustAnchorConstraints(*trust_anchor, &max_path_length, | 508 if (!ProcessTrustAnchorConstraints(*trust_anchor, &max_path_length, |
435 &name_constraints_list)) { | 509 &name_constraints_list, errors)) { |
436 return false; | 510 return false; |
437 } | 511 } |
438 | 512 |
439 // Iterate over all the certificates in the reverse direction: starting from | 513 // Iterate over all the certificates in the reverse direction: starting from |
440 // the certificate signed by trust anchor and progressing towards the target | 514 // the certificate signed by trust anchor and progressing towards the target |
441 // certificate. | 515 // certificate. |
442 // | 516 // |
443 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. | 517 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. |
444 // | 518 // |
445 // * i=0 : Certificated signed by trust anchor. | 519 // * i=0 : Certificated signed by trust anchor. |
446 // * i=N-1 : Target certificate. | 520 // * i=N-1 : Target certificate. |
447 for (size_t i = 0; i < certs.size(); ++i) { | 521 for (size_t i = 0; i < certs.size(); ++i) { |
448 const size_t index_into_certs = certs.size() - i - 1; | 522 const size_t index_into_certs = certs.size() - i - 1; |
449 | 523 |
450 // |is_target_cert| is true if the current certificate is the target | 524 // |is_target_cert| is true if the current certificate is the target |
451 // certificate being verified. The target certificate isn't necessarily an | 525 // certificate being verified. The target certificate isn't necessarily an |
452 // end-entity certificate. | 526 // end-entity certificate. |
453 const bool is_target_cert = index_into_certs == 0; | 527 const bool is_target_cert = index_into_certs == 0; |
454 | 528 |
455 const ParsedCertificate& cert = *certs[index_into_certs]; | 529 const ParsedCertificate& cert = *certs[index_into_certs]; |
456 | 530 |
| 531 // Set the current certificate as the context for any subsequent errors. |
| 532 ScopedCertErrorsCertContext error_context(errors, &cert, i); |
| 533 |
457 // Per RFC 5280 section 6.1: | 534 // Per RFC 5280 section 6.1: |
458 // * Do basic processing for each certificate | 535 // * Do basic processing for each certificate |
459 // * If it is the last certificate in the path (target certificate) | 536 // * If it is the last certificate in the path (target certificate) |
460 // - Then run "Wrap up" | 537 // - Then run "Wrap up" |
461 // - Otherwise run "Prepare for Next cert" | 538 // - Otherwise run "Prepare for Next cert" |
462 if (!BasicCertificateProcessing( | 539 if (!BasicCertificateProcessing( |
463 cert, is_target_cert, signature_policy, time, working_spki, | 540 cert, is_target_cert, signature_policy, time, working_spki, |
464 working_normalized_issuer_name, name_constraints_list)) { | 541 working_normalized_issuer_name, name_constraints_list, errors)) { |
465 return false; | 542 return false; |
466 } | 543 } |
467 if (!is_target_cert) { | 544 if (!is_target_cert) { |
468 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, | 545 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, |
469 &working_normalized_issuer_name, | 546 &working_normalized_issuer_name, |
470 &name_constraints_list)) { | 547 &name_constraints_list, errors)) { |
471 return false; | 548 return false; |
472 } | 549 } |
473 } else { | 550 } else { |
474 if (!WrapUp(cert)) | 551 if (!WrapUp(cert, errors)) |
475 return false; | 552 return false; |
476 } | 553 } |
477 } | 554 } |
478 | 555 |
479 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 556 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
480 // | 557 // |
481 // A certificate MUST NOT appear more than once in a prospective | 558 // A certificate MUST NOT appear more than once in a prospective |
482 // certification path. | 559 // certification path. |
483 | 560 |
484 return true; | 561 return true; |
485 } | 562 } |
486 | 563 |
| 564 namespace verify_certificate_chain_errors { |
| 565 |
| 566 DEFINE_CERT_ERROR_TYPE( |
| 567 kSignatureAlgorithmMismatch, |
| 568 "Certificate.signatureAlgorithm != TBSCertificate.signature"); |
| 569 DEFINE_CERT_ERROR_TYPE(kInvalidOrUnsupportedAlgorithm, |
| 570 "Invalid or unsupported signature algorithm"); |
| 571 DEFINE_CERT_ERROR_TYPE(kChainIsEmpty, "Chain is empty"); |
| 572 DEFINE_CERT_ERROR_TYPE(kUnconsumedCriticalExtension, |
| 573 "Unconsumed critical extension"); |
| 574 DEFINE_CERT_ERROR_TYPE( |
| 575 kTargetCertInconsistentCaBits, |
| 576 "Target certificate looks like a CA but does not set all CA properties"); |
| 577 DEFINE_CERT_ERROR_TYPE(kKeyCertSignBitNotSet, "keyCertSign bit is not set"); |
| 578 DEFINE_CERT_ERROR_TYPE(kMaxPathLengthViolated, "max_path_length reached"); |
| 579 DEFINE_CERT_ERROR_TYPE(kBasicConstraintsIndicatesNotCa, |
| 580 "Basic Constraints indicates not a CA"); |
| 581 DEFINE_CERT_ERROR_TYPE(kMissingBasicConstraints, |
| 582 "Does not have Basic Constraints"); |
| 583 DEFINE_CERT_ERROR_TYPE(kNotPermittedByNameConstraints, |
| 584 "Not permitted by name constraints"); |
| 585 DEFINE_CERT_ERROR_TYPE(kSubjectDoesNotMatchIssuer, |
| 586 "subject does not match issuer"); |
| 587 DEFINE_CERT_ERROR_TYPE(kSignatureVerificationFailed, |
| 588 "Signature verification failed"); |
| 589 DEFINE_CERT_ERROR_TYPE(kValidityFailedNotAfter, "Time is after notAfter"); |
| 590 DEFINE_CERT_ERROR_TYPE(kValidityFailedNotBefore, "Time is before notBefore"); |
| 591 DEFINE_CERT_ERROR_TYPE(kSignatureAlgorithmsDifferentEncoding, |
| 592 "Certificate.signatureAlgorithm is encoded differently " |
| 593 "than TBSCertificate.signature"); |
| 594 |
| 595 } // verify_certificate_chain_errors |
| 596 |
487 } // namespace net | 597 } // namespace net |
OLD | NEW |