| 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 |