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 |