OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/cert/multi_log_ct_verifier.h" | |
6 | |
7 #include "net/base/net_errors.h" | |
8 #include "net/cert/ct_log_verifier.h" | |
9 #include "net/cert/ct_objects_extractor.h" | |
10 #include "net/cert/ct_serialization.h" | |
11 #include "net/cert/ct_verify_result.h" | |
12 #include "net/cert/signed_certificate_timestamp.h" | |
wtc
2013/11/21 02:05:02
Nit: already included by the .h file.
Eran M. (Google)
2013/11/21 20:06:02
Done.
| |
13 #include "net/cert/x509_certificate.h" | |
14 | |
15 namespace net { | |
16 | |
17 MultiLogCTVerifier::MultiLogCTVerifier() { | |
18 } | |
19 | |
20 MultiLogCTVerifier::~MultiLogCTVerifier() { } | |
wtc
2013/11/21 02:05:02
Nit: the constructor and destructor should use the
wtc
2013/11/21 02:05:02
Nit: the constructor and destructor should use the
Eran M. (Google)
2013/11/21 20:06:02
Done.
Eran M. (Google)
2013/11/21 20:06:02
Done.
| |
21 | |
22 void MultiLogCTVerifier::AddLog(scoped_ptr<CTLogVerifier> log_verifier) { | |
23 std::string log_id(log_verifier->key_id()); | |
24 logs_[log_id] = linked_ptr<CTLogVerifier>(log_verifier.release()); | |
wtc
2013/11/21 02:05:02
1. Nit: you should be able to do
logs_[log_id].r
Eran M. (Google)
2013/11/21 20:06:02
1. Done
2. Will look into changing the type of th
wtc
2013/11/21 23:26:34
You can declare the |log_verifier| parameter as a
Ryan Sleevi
2013/11/21 23:37:02
Taking a scoped_ptr<CTLogVerifier> and turning it
Eran M. (Google)
2013/11/23 21:02:06
Done as Ryan suggested - only modification is I've
wtc
2013/11/25 01:48:32
I think
logs_[log_id].reset(log_verifier.relea
wtc
2013/11/25 23:01:59
Thanks for the explanation.
You wrote:
| |
25 } | |
26 | |
27 int MultiLogCTVerifier::Verify( | |
28 X509Certificate* verified_cert, | |
29 const std::string& sct_list_from_ocsp, | |
30 const std::string& sct_list_from_tls_handshake, | |
31 ct::CTVerifyResult* result) { | |
32 DCHECK(verified_cert); | |
33 DCHECK(result); | |
34 | |
35 result->verified_scts.clear(); | |
36 result->unverified_scts.clear(); | |
37 result->unknown_logs_scts.clear(); | |
38 | |
39 bool has_verified_scts = false; | |
40 | |
41 std::string embedded_scts; | |
42 if (!verified_cert->GetIntermediateCertificates().empty() && | |
43 ct::ExtractEmbeddedSCTList( | |
44 verified_cert->os_cert_handle(), | |
45 &embedded_scts)) { | |
wtc
2013/11/21 02:05:02
Nit: indent by four spaces with respect to "ct::Ex
Eran M. (Google)
2013/11/21 20:06:02
Done.
| |
46 ct::LogEntry embedded_log_entry; | |
wtc
2013/11/21 02:05:02
Nit: if the |x509_entry| variable you declare belo
Eran M. (Google)
2013/11/21 20:06:02
Done.
| |
47 | |
48 has_verified_scts = | |
49 ct::GetPrecertLogEntry( | |
wtc
2013/11/21 02:05:02
Nit: indent by four spaces.
Eran M. (Google)
2013/11/21 20:06:02
Done.
| |
50 verified_cert->os_cert_handle(), | |
51 verified_cert->GetIntermediateCertificates().front(), | |
52 &embedded_log_entry) && | |
53 VerifySCTs( | |
54 embedded_scts, | |
55 embedded_log_entry, | |
56 ct::SignedCertificateTimestamp::SCT_EMBEDDED, | |
57 result); | |
58 } | |
59 | |
60 ct::LogEntry x509_entry; | |
61 if (!ct::GetX509LogEntry(verified_cert->os_cert_handle(), &x509_entry)) { | |
62 return has_verified_scts ? OK : ERR_FAILED; | |
wtc
2013/11/21 02:05:02
IMPORTANT: use a more informative error code than
Eran M. (Google)
2013/11/21 20:06:02
Done - ended up adding another category for the va
| |
63 } | |
wtc
2013/11/21 02:05:02
Nit: omit curly braces.
Eran M. (Google)
2013/11/21 20:06:02
Done.
| |
64 | |
65 has_verified_scts |= VerifySCTs( | |
66 sct_list_from_ocsp, | |
67 x509_entry, | |
68 ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE, | |
69 result); | |
70 | |
71 has_verified_scts |= VerifySCTs( | |
72 sct_list_from_tls_handshake, | |
73 x509_entry, | |
74 ct::SignedCertificateTimestamp::SCT_FROM_TLS_HANDSHAKE, | |
75 result); | |
76 | |
77 //XXX(eranm): Add a specific error code to indicate no presence | |
78 // of SCTs at all. | |
79 return has_verified_scts ? OK : ERR_FAILED; | |
80 } | |
81 | |
82 bool MultiLogCTVerifier::VerifySCTs( | |
83 const std::string& encoded_sct_list, | |
84 const ct::LogEntry& expected_entry, | |
85 ct::SignedCertificateTimestamp::Origin origin, | |
86 ct::CTVerifyResult* result) { | |
87 if (logs_.empty()) | |
88 return false; | |
89 | |
90 base::StringPiece temp(encoded_sct_list); | |
91 std::vector<base::StringPiece> sct_list; | |
92 | |
93 if (!ct::DecodeSCTList(&temp, &sct_list)) | |
94 return false; | |
95 | |
96 bool verified = false; | |
97 for (std::vector<base::StringPiece>::const_iterator it = sct_list.begin(); | |
98 it != sct_list.end(); ++it) { | |
99 base::StringPiece encoded_sct(*it); | |
100 ct::SignedCertificateTimestamp decoded_sct; | |
101 if (!DecodeSignedCertificateTimestamp(&encoded_sct, &decoded_sct)) { | |
102 // XXX(rsleevi): Should we really just skip over bad SCTs? | |
103 continue; | |
104 } | |
105 decoded_sct.origin = origin; | |
106 | |
107 verified |= VerifySingleSCT(decoded_sct, expected_entry, result); | |
108 } | |
109 | |
110 return verified; | |
111 } | |
112 | |
113 bool MultiLogCTVerifier::VerifySingleSCT( | |
114 const ct::SignedCertificateTimestamp& sct, | |
115 const ct::LogEntry& expected_entry, | |
116 ct::CTVerifyResult* result) { | |
117 | |
118 // Assume this SCT is untrusted until proven otherwise. | |
119 result->unverified_scts.push_back(sct); | |
wtc
2013/11/21 02:05:02
Nit: it seems clearer to just push |sct| to the ap
Eran M. (Google)
2013/11/21 20:06:02
Done - that was my attempt at defensive programmin
| |
120 | |
121 IDToLogMap::iterator it = logs_.find(sct.log_id); | |
122 if (it == logs_.end()) { | |
123 DVLOG(1) << "SCT does not match any known log."; | |
124 result->unverified_scts.pop_back(); | |
125 result->unknown_logs_scts.push_back(sct); | |
126 return false; | |
127 } | |
128 | |
129 if (!it->second->Verify(expected_entry, sct)) { | |
130 DVLOG(1) << "Unable to verify SCT signature."; | |
131 return false; | |
132 } | |
133 | |
134 // SCT verified ok, just make sure the timestamp is legitimate. | |
135 if (sct.timestamp + base::TimeDelta::FromSeconds(1) > base::Time::Now()) { | |
wtc
2013/11/21 02:05:02
Should add a comment to explain why we need to add
Eran M. (Google)
2013/11/21 20:06:02
Done, although I'll be the first to admit it's not
| |
136 DVLOG(1) << "SCT is from the future!"; | |
137 return false; | |
138 } | |
139 | |
140 result->unverified_scts.pop_back(); | |
141 result->verified_scts.push_back(sct); | |
142 return true; | |
143 } | |
144 | |
145 } // namespace net | |
OLD | NEW |