OLD | NEW |
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 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/cert_verify_proc_builtin.h" | 5 #include "net/cert/cert_verify_proc_builtin.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #if defined(USE_NSS_CERTS) | 10 #if defined(USE_NSS_CERTS) |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 // anchor) in |partial_path| to |*hashes|. | 243 // anchor) in |partial_path| to |*hashes|. |
244 void AppendPublicKeyHashes(const CertPathBuilder::ResultPath& partial_path, | 244 void AppendPublicKeyHashes(const CertPathBuilder::ResultPath& partial_path, |
245 HashValueVector* hashes) { | 245 HashValueVector* hashes) { |
246 for (const scoped_refptr<ParsedCertificate>& cert : partial_path.path.certs) | 246 for (const scoped_refptr<ParsedCertificate>& cert : partial_path.path.certs) |
247 AppendPublicKeyHashes(cert->tbs().spki_tlv, hashes); | 247 AppendPublicKeyHashes(cert->tbs().spki_tlv, hashes); |
248 | 248 |
249 if (partial_path.path.trust_anchor) | 249 if (partial_path.path.trust_anchor) |
250 AppendPublicKeyHashes(partial_path.path.trust_anchor->spki(), hashes); | 250 AppendPublicKeyHashes(partial_path.path.trust_anchor->spki(), hashes); |
251 } | 251 } |
252 | 252 |
253 // Sets the bits on |cert_status| for all the errors encountered during the path | 253 // Sets the bits on |cert_status| for all the errors present in |errors| (the |
254 // building of |partial_path|. | 254 // errors for a particular path). |
255 void MapPathBuilderErrorsToCertStatus( | 255 void MapPathBuilderErrorsToCertStatus(const CertPathErrors& errors, |
256 const CertPathBuilder::ResultPath& partial_path, | 256 CertStatus* cert_status) { |
257 const std::string& hostname, | 257 // If there were no errors, nothing to do. |
258 CertStatus* cert_status) { | 258 if (!errors.ContainsHighSeverityErrors()) |
259 // If path building was successful, there are no errors to map (there may have | |
260 // been warnings but they do not map to CertStatus). | |
261 if (partial_path.valid) | |
262 return; | 259 return; |
263 | 260 |
264 LOG(ERROR) << "CertVerifyProcBuiltin for " << hostname << " failed:\n" | 261 if (errors.ContainsError(kRsaModulusTooSmall)) |
265 << partial_path.errors.ToDebugString(); | |
266 | |
267 if (partial_path.errors.ContainsError(kRsaModulusTooSmall)) | |
268 *cert_status |= CERT_STATUS_WEAK_KEY; | 262 *cert_status |= CERT_STATUS_WEAK_KEY; |
269 | 263 |
270 if (partial_path.errors.ContainsError(kValidityFailedNotAfter) || | 264 if (errors.ContainsError(kValidityFailedNotAfter) || |
271 partial_path.errors.ContainsError(kValidityFailedNotBefore)) { | 265 errors.ContainsError(kValidityFailedNotBefore)) { |
272 *cert_status |= CERT_STATUS_DATE_INVALID; | 266 *cert_status |= CERT_STATUS_DATE_INVALID; |
273 } | 267 } |
274 | 268 |
275 // IMPORTANT: If the path was invalid for a reason that was not | 269 // IMPORTANT: If the path was invalid for a reason that was not |
276 // explicity checked above, set a general error. This is important as | 270 // explicity checked above, set a general error. This is important as |
277 // |cert_status| is what ultimately indicates whether verification was | 271 // |cert_status| is what ultimately indicates whether verification was |
278 // successful or not (absense of errors implies success). | 272 // successful or not (absense of errors implies success). |
279 if (!IsCertStatusError(*cert_status)) | 273 if (!IsCertStatusError(*cert_status)) |
280 *cert_status |= CERT_STATUS_INVALID; | 274 *cert_status |= CERT_STATUS_INVALID; |
281 } | 275 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 // | 315 // |
322 // Any failure short-circuits from the function must set | 316 // Any failure short-circuits from the function must set |
323 // |verify_result->cert_status|. | 317 // |verify_result->cert_status|. |
324 void DoVerify(X509Certificate* input_cert, | 318 void DoVerify(X509Certificate* input_cert, |
325 const std::string& hostname, | 319 const std::string& hostname, |
326 const std::string& ocsp_response, | 320 const std::string& ocsp_response, |
327 int flags, | 321 int flags, |
328 CRLSet* crl_set, | 322 CRLSet* crl_set, |
329 const CertificateList& additional_trust_anchors, | 323 const CertificateList& additional_trust_anchors, |
330 CertVerifyResult* verify_result) { | 324 CertVerifyResult* verify_result) { |
331 CertErrors errors; | 325 CertErrors parsing_errors; |
332 | 326 |
333 // Parse the target certificate. | 327 // Parse the target certificate. |
334 scoped_refptr<ParsedCertificate> target = | 328 scoped_refptr<ParsedCertificate> target = ParseCertificateFromOSHandle( |
335 ParseCertificateFromOSHandle(input_cert->os_cert_handle(), &errors); | 329 input_cert->os_cert_handle(), &parsing_errors); |
336 if (!target) { | 330 if (!target) { |
337 // TODO(crbug.com/634443): Surface these parsing errors? | 331 // TODO(crbug.com/634443): Surface these parsing errors? |
338 verify_result->cert_status |= CERT_STATUS_INVALID; | 332 verify_result->cert_status |= CERT_STATUS_INVALID; |
339 return; | 333 return; |
340 } | 334 } |
341 | 335 |
342 std::unique_ptr<SystemTrustStore> trust_store = | 336 std::unique_ptr<SystemTrustStore> trust_store = |
343 CreateSystemTrustStore(additional_trust_anchors); | 337 CreateSystemTrustStore(additional_trust_anchors); |
344 | 338 |
345 // TODO(eroman): The path building code in this file enforces its idea of weak | 339 // TODO(eroman): The path building code in this file enforces its idea of weak |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 const CertPathBuilder::ResultPath& partial_path = | 387 const CertPathBuilder::ResultPath& partial_path = |
394 *result.paths[result.best_result_index].get(); | 388 *result.paths[result.best_result_index].get(); |
395 | 389 |
396 if (partial_path.path.trust_anchor) { | 390 if (partial_path.path.trust_anchor) { |
397 verify_result->is_issued_by_known_root = | 391 verify_result->is_issued_by_known_root = |
398 trust_store->IsKnownRoot(partial_path.path.trust_anchor); | 392 trust_store->IsKnownRoot(partial_path.path.trust_anchor); |
399 | 393 |
400 verify_result->is_issued_by_additional_trust_anchor = | 394 verify_result->is_issued_by_additional_trust_anchor = |
401 trust_store->IsAdditionalTrustAnchor(partial_path.path.trust_anchor); | 395 trust_store->IsAdditionalTrustAnchor(partial_path.path.trust_anchor); |
402 } else { | 396 } else { |
| 397 // TODO(eroman): This shouldn't be necessary -- partial_path.errors should |
| 398 // contain an error if it didn't chain to trust anchor. |
403 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; | 399 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; |
404 } | 400 } |
405 | 401 |
406 verify_result->verified_cert = | 402 verify_result->verified_cert = |
407 CreateVerifiedCertChain(input_cert, partial_path); | 403 CreateVerifiedCertChain(input_cert, partial_path); |
408 | 404 |
409 AppendPublicKeyHashes(partial_path, &verify_result->public_key_hashes); | 405 AppendPublicKeyHashes(partial_path, &verify_result->public_key_hashes); |
410 MapPathBuilderErrorsToCertStatus(partial_path, hostname, | 406 MapPathBuilderErrorsToCertStatus(partial_path.errors, |
411 &verify_result->cert_status); | 407 &verify_result->cert_status); |
| 408 |
| 409 // TODO(eroman): Is it possible that IsValid() fails but no errors were set in |
| 410 // partial_path.errors? |
| 411 CHECK(partial_path.IsValid() || |
| 412 IsCertStatusError(verify_result->cert_status)); |
| 413 |
| 414 if (partial_path.errors.ContainsHighSeverityErrors()) { |
| 415 LOG(ERROR) << "CertVerifyProcBuiltin for " << hostname << " failed:\n" |
| 416 << partial_path.errors.ToDebugString(partial_path.path.certs); |
| 417 } |
412 } | 418 } |
413 | 419 |
414 int CertVerifyProcBuiltin::VerifyInternal( | 420 int CertVerifyProcBuiltin::VerifyInternal( |
415 X509Certificate* input_cert, | 421 X509Certificate* input_cert, |
416 const std::string& hostname, | 422 const std::string& hostname, |
417 const std::string& ocsp_response, | 423 const std::string& ocsp_response, |
418 int flags, | 424 int flags, |
419 CRLSet* crl_set, | 425 CRLSet* crl_set, |
420 const CertificateList& additional_trust_anchors, | 426 const CertificateList& additional_trust_anchors, |
421 CertVerifyResult* verify_result) { | 427 CertVerifyResult* verify_result) { |
422 DoVerify(input_cert, hostname, ocsp_response, flags, crl_set, | 428 DoVerify(input_cert, hostname, ocsp_response, flags, crl_set, |
423 additional_trust_anchors, verify_result); | 429 additional_trust_anchors, verify_result); |
424 | 430 |
425 return IsCertStatusError(verify_result->cert_status) | 431 return IsCertStatusError(verify_result->cert_status) |
426 ? MapCertStatusToNetError(verify_result->cert_status) | 432 ? MapCertStatusToNetError(verify_result->cert_status) |
427 : OK; | 433 : OK; |
428 } | 434 } |
429 | 435 |
430 } // namespace | 436 } // namespace |
431 | 437 |
432 scoped_refptr<CertVerifyProc> CreateCertVerifyProcBuiltin() { | 438 scoped_refptr<CertVerifyProc> CreateCertVerifyProcBuiltin() { |
433 return scoped_refptr<CertVerifyProc>(new CertVerifyProcBuiltin()); | 439 return scoped_refptr<CertVerifyProc>(new CertVerifyProcBuiltin()); |
434 } | 440 } |
435 | 441 |
436 } // namespace net | 442 } // namespace net |
OLD | NEW |