Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/parse_ocsp.h" | |
| 6 | |
| 5 #include <algorithm> | 7 #include <algorithm> |
| 6 | 8 |
| 7 #include "base/sha1.h" | 9 #include "base/sha1.h" |
| 8 #include "crypto/sha2.h" | 10 #include "crypto/sha2.h" |
| 9 #include "net/cert/internal/parse_ocsp.h" | 11 #include "net/cert/internal/extended_key_usage.h" |
| 12 #include "net/cert/internal/signature_policy.h" | |
| 13 #include "net/cert/internal/verify_name_match.h" | |
| 14 #include "net/cert/internal/verify_signed_data.h" | |
| 10 | 15 |
| 11 namespace net { | 16 namespace net { |
| 12 | 17 |
| 13 OCSPCertID::OCSPCertID() {} | 18 OCSPCertID::OCSPCertID() {} |
| 14 OCSPCertID::~OCSPCertID() {} | 19 OCSPCertID::~OCSPCertID() {} |
| 15 | 20 |
| 16 OCSPSingleResponse::OCSPSingleResponse() {} | 21 OCSPSingleResponse::OCSPSingleResponse() {} |
| 17 OCSPSingleResponse::~OCSPSingleResponse() {} | 22 OCSPSingleResponse::~OCSPSingleResponse() {} |
| 18 | 23 |
| 19 OCSPResponseData::OCSPResponseData() {} | 24 OCSPResponseData::OCSPResponseData() {} |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 } | 527 } |
| 523 } | 528 } |
| 524 } | 529 } |
| 525 | 530 |
| 526 if (!found) | 531 if (!found) |
| 527 out->status = OCSPCertStatus::Status::UNKNOWN; | 532 out->status = OCSPCertStatus::Status::UNKNOWN; |
| 528 | 533 |
| 529 return found; | 534 return found; |
| 530 } | 535 } |
| 531 | 536 |
| 537 namespace { | |
| 538 | |
| 539 // Checks that the ResponderID |id| matches the certificate |cert|. | |
|
eroman
2016/05/02 22:36:50
Same comment here -- justify what parts of the sta
svaldez
2016/05/04 15:31:20
Done.
| |
| 540 bool CheckResponder(const OCSPResponseData::ResponderID& id, | |
| 541 const ParsedTbsCertificate& cert) { | |
|
eroman
2016/05/02 22:36:50
WARN_UNUSED_RESULT
svaldez
2016/05/04 15:31:19
Done.
| |
| 542 if (id.type == OCSPResponseData::ResponderType::NAME) { | |
| 543 der::Input name_rdn; | |
| 544 der::Input cert_rdn; | |
| 545 if (!der::Parser(id.name).ReadTag(der::kSequence, &name_rdn) || | |
|
eroman
2016/05/02 22:36:50
Is this sufficient?
The assumption is that id.name
svaldez
2016/05/04 15:31:19
The outer name I believe is guaranteed to be a sin
| |
| 546 !der::Parser(cert.subject_tlv).ReadTag(der::kSequence, &cert_rdn)) | |
| 547 return false; | |
| 548 return VerifyNameMatch(name_rdn, cert_rdn); | |
| 549 } else { | |
|
eroman
2016/05/02 22:36:50
don't include the else after a short-circuit.
Als
svaldez
2016/05/04 15:31:19
Fixed. Due to the lack of extensability with the A
| |
| 550 der::Parser parser(cert.spki_tlv); | |
| 551 der::Parser spki_parser; | |
| 552 der::BitString key_bits; | |
| 553 if (!parser.ReadSequence(&spki_parser)) | |
|
eroman
2016/05/02 22:36:50
Same thing as elsewhere -- describe intent.
Looks
svaldez
2016/05/04 15:31:19
Done.
| |
| 554 return false; | |
| 555 if (!spki_parser.SkipTag(der::kSequence)) | |
| 556 return false; | |
| 557 if (!spki_parser.ReadBitString(&key_bits)) | |
| 558 return false; | |
| 559 | |
| 560 der::Input key = key_bits.bytes(); | |
| 561 HashValue key_hash(HASH_VALUE_SHA1); | |
|
eroman
2016/05/02 22:36:51
I am not familiar with OCSP (beyond what I read to
svaldez
2016/05/04 15:31:20
This is safe since we are only using the Responder
| |
| 562 base::SHA1HashBytes(key.UnsafeData(), key.Length(), key_hash.data()); | |
| 563 return key_hash.Equals(id.key_hash); | |
| 564 } | |
| 565 } | |
| 566 | |
| 567 } // namespace | |
| 568 | |
| 569 bool VerifyOCSPResponse(const OCSPResponse& response, | |
|
eroman
2016/05/02 22:36:51
Please documentation throughout this implementatio
svaldez
2016/05/04 15:31:20
Done.
| |
| 570 const ParsedCertificate& issuer_cert) { | |
| 571 SimpleSignaturePolicy signature_policy(1024); | |
|
eroman
2016/05/02 22:36:51
Why this signature policy? 1024-bit RSA is weak. D
svaldez
2016/05/04 15:31:19
Done.
| |
| 572 | |
| 573 OCSPResponseData response_data; | |
|
eroman
2016/05/02 22:36:50
I didn't review the rest of this in detail -- will
svaldez
2016/05/04 15:31:19
Done.
| |
| 574 if (!ParseOCSPResponseData(response.data, &response_data)) | |
| 575 return false; | |
| 576 | |
| 577 ParsedTbsCertificate issuer; | |
| 578 ParsedTbsCertificate responder; | |
| 579 if (!ParseTbsCertificate(issuer_cert.tbs_certificate_tlv, &issuer)) | |
| 580 return false; | |
| 581 | |
| 582 if (CheckResponder(response_data.responder_id, issuer)) { | |
| 583 responder = issuer; | |
| 584 } else { | |
| 585 bool found = false; | |
| 586 for (const auto& responder_cert_tlv : response.certs) { | |
| 587 ParsedCertificate responder_cert; | |
| 588 ParsedTbsCertificate tbs_cert; | |
| 589 if (!ParseCertificate(responder_cert_tlv, &responder_cert)) | |
| 590 return false; | |
| 591 if (!ParseTbsCertificate(responder_cert.tbs_certificate_tlv, &tbs_cert)) | |
| 592 return false; | |
| 593 | |
| 594 if (CheckResponder(response_data.responder_id, tbs_cert)) { | |
| 595 found = true; | |
| 596 responder = tbs_cert; | |
| 597 | |
| 598 scoped_ptr<SignatureAlgorithm> signature_algorithm = | |
| 599 SignatureAlgorithm::CreateFromDer( | |
| 600 responder_cert.signature_algorithm_tlv); | |
| 601 if (!signature_algorithm) | |
| 602 return false; | |
| 603 der::Input issuer_spki = issuer.spki_tlv; | |
| 604 if (!VerifySignedData(*signature_algorithm, | |
| 605 responder_cert.tbs_certificate_tlv, | |
| 606 responder_cert.signature_value, issuer_spki, | |
| 607 &signature_policy)) { | |
| 608 return false; | |
| 609 } | |
| 610 | |
| 611 std::map<der::Input, ParsedExtension> extensions; | |
| 612 std::vector<der::Input> eku; | |
| 613 if (!ParseExtensions(responder.extensions_tlv, &extensions)) | |
| 614 return false; | |
| 615 if (!ParseEKUExtension(extensions[ExtKeyUsageOid()].value, &eku)) | |
| 616 return false; | |
| 617 if (std::find(eku.begin(), eku.end(), OCSPSigning()) == eku.end()) | |
| 618 return false; | |
| 619 break; | |
| 620 } | |
| 621 } | |
| 622 if (!found) | |
| 623 return false; | |
| 624 } | |
| 625 return VerifySignedData(*(response.signature_algorithm), response.data, | |
| 626 response.signature, responder.spki_tlv, | |
| 627 &signature_policy); | |
| 628 } | |
| 629 | |
| 532 } // namespace net | 630 } // namespace net |
| OLD | NEW |