OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic/crypto/proof_verifier_chromium.h" | 5 #include "net/quic/crypto/proof_verifier_chromium.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 using base::StringPiece; | 26 using base::StringPiece; |
27 using base::StringPrintf; | 27 using base::StringPrintf; |
28 using std::string; | 28 using std::string; |
29 using std::vector; | 29 using std::vector; |
30 | 30 |
31 namespace net { | 31 namespace net { |
32 | 32 |
33 ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier, | 33 ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier, |
34 const BoundNetLog& net_log) | 34 const BoundNetLog& net_log) |
35 : cert_verifier_(cert_verifier), | 35 : cert_verifier_(cert_verifier), |
36 cert_verify_result_(NULL), | |
37 error_details_(NULL), | |
38 next_state_(STATE_NONE), | 36 next_state_(STATE_NONE), |
39 net_log_(net_log) { | 37 net_log_(net_log) { |
40 } | 38 } |
41 | 39 |
42 ProofVerifierChromium::~ProofVerifierChromium() { | 40 ProofVerifierChromium::~ProofVerifierChromium() { |
43 verifier_.reset(); | 41 verifier_.reset(); |
44 } | 42 } |
45 | 43 |
46 int ProofVerifierChromium::VerifyProof(const string& hostname, | 44 ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( |
47 const string& server_config, | 45 const string& hostname, |
48 const vector<string>& certs, | 46 const string& server_config, |
49 const string& signature, | 47 const vector<string>& certs, |
50 std::string* error_details, | 48 const string& signature, |
51 CertVerifyResult* cert_verify_result, | 49 std::string* error_details, |
52 const CompletionCallback& callback) { | 50 scoped_ptr<ProofVerifyDetails>* details, |
51 ProofVerifierCallback* callback) OVERRIDE { | |
53 DCHECK(error_details); | 52 DCHECK(error_details); |
54 DCHECK(cert_verify_result); | 53 DCHECK(details); |
54 DCHECK(callback); | |
55 | |
56 callback_.reset(callback); | |
55 error_details->clear(); | 57 error_details->clear(); |
56 cert_verify_result->Reset(); | |
57 | 58 |
58 DCHECK_EQ(STATE_NONE, next_state_); | 59 DCHECK_EQ(STATE_NONE, next_state_); |
59 if (STATE_NONE != next_state_) { | 60 if (STATE_NONE != next_state_) { |
60 *error_details = "Certificate is already set and VerifyProof has begun"; | 61 *error_details = "Certificate is already set and VerifyProof has begun"; |
61 DLOG(WARNING) << *error_details; | 62 DLOG(WARNING) << *error_details; |
62 return ERR_FAILED; | 63 return ERROR; |
63 } | 64 } |
64 | 65 |
66 verify_details_ = new ProofVerifyDetailsChromium; | |
67 details->reset(verify_details_); | |
68 | |
65 if (certs.empty()) { | 69 if (certs.empty()) { |
66 *error_details = "Failed to create certificate chain. Certs are empty."; | 70 *error_details = "Failed to create certificate chain. Certs are empty."; |
71 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; | |
Ryan Hamilton
2013/07/23 18:40:50
super tiny nit: can you move this line below the D
agl
2013/07/23 21:04:57
Done.
| |
67 DLOG(WARNING) << *error_details; | 72 DLOG(WARNING) << *error_details; |
68 return ERR_FAILED; | 73 return ERROR; |
69 } | 74 } |
70 | 75 |
71 // Convert certs to X509Certificate. | 76 // Convert certs to X509Certificate. |
72 vector<StringPiece> cert_pieces(certs.size()); | 77 vector<StringPiece> cert_pieces(certs.size()); |
73 for (unsigned i = 0; i < certs.size(); i++) { | 78 for (unsigned i = 0; i < certs.size(); i++) { |
74 cert_pieces[i] = base::StringPiece(certs[i]); | 79 cert_pieces[i] = base::StringPiece(certs[i]); |
75 } | 80 } |
76 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces); | 81 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces); |
77 if (!cert_.get()) { | 82 if (!cert_.get()) { |
78 *error_details = "Failed to create certificate chain"; | 83 *error_details = "Failed to create certificate chain"; |
79 DLOG(WARNING) << *error_details; | 84 DLOG(WARNING) << *error_details; |
80 cert_verify_result->cert_status = CERT_STATUS_INVALID; | 85 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; |
81 return ERR_FAILED; | 86 return ERROR; |
82 } | 87 } |
83 | 88 |
84 // We call VerifySignature first to avoid copying of server_config and | 89 // We call VerifySignature first to avoid copying of server_config and |
85 // signature. | 90 // signature. |
86 if (!VerifySignature(server_config, signature, certs[0])) { | 91 if (!VerifySignature(server_config, signature, certs[0])) { |
87 *error_details = "Failed to verify signature of server config"; | 92 *error_details = "Failed to verify signature of server config"; |
88 DLOG(WARNING) << *error_details; | 93 DLOG(WARNING) << *error_details; |
89 return ERR_FAILED; | 94 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; |
95 return ERROR; | |
90 } | 96 } |
91 | 97 |
92 hostname_ = hostname; | 98 hostname_ = hostname; |
93 callback_ = callback; | |
94 error_details_ = error_details; | |
95 cert_verify_result_ = cert_verify_result; | |
96 | 99 |
97 next_state_ = STATE_VERIFY_CERT; | 100 next_state_ = STATE_VERIFY_CERT; |
98 return DoLoop(OK); | 101 switch (DoLoop(OK)) { |
102 case ::net::OK: | |
103 return OK; | |
104 case ERR_IO_PENDING: | |
Ryan Hamilton
2013/07/23 18:40:50
nit: indentation appears to be off from below this
agl
2013/07/23 21:04:57
Done.
| |
105 verify_details_ = | |
106 reinterpret_cast<ProofVerifyDetailsChromium*>(details->release()); | |
107 return PENDING; | |
108 default: | |
109 *error_details = error_details_; | |
110 return ERROR; | |
111 } | |
99 } | 112 } |
100 | 113 |
101 int ProofVerifierChromium::DoLoop(int last_result) { | 114 int ProofVerifierChromium::DoLoop(int last_result) { |
102 int rv = last_result; | 115 int rv = last_result; |
103 do { | 116 do { |
104 State state = next_state_; | 117 State state = next_state_; |
105 next_state_ = STATE_NONE; | 118 next_state_ = STATE_NONE; |
106 switch (state) { | 119 switch (state) { |
107 case STATE_VERIFY_CERT: | 120 case STATE_VERIFY_CERT: |
108 DCHECK(rv == OK); | 121 DCHECK(rv == ::net::OK); |
Ryan Hamilton
2013/07/23 18:40:50
Oh, cute :> What would you think about using SUCC
agl
2013/07/23 21:04:57
Done.
| |
109 rv = DoVerifyCert(rv); | 122 rv = DoVerifyCert(rv); |
110 break; | 123 break; |
111 case STATE_VERIFY_CERT_COMPLETE: | 124 case STATE_VERIFY_CERT_COMPLETE: |
112 rv = DoVerifyCertComplete(rv); | 125 rv = DoVerifyCertComplete(rv); |
113 break; | 126 break; |
114 case STATE_NONE: | 127 case STATE_NONE: |
115 default: | 128 default: |
116 rv = ERR_UNEXPECTED; | 129 rv = ERR_UNEXPECTED; |
117 LOG(DFATAL) << "unexpected state " << state; | 130 LOG(DFATAL) << "unexpected state " << state; |
118 break; | 131 break; |
119 } | 132 } |
120 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 133 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
121 return rv; | 134 return rv; |
122 } | 135 } |
123 | 136 |
124 void ProofVerifierChromium::OnIOComplete(int result) { | 137 void ProofVerifierChromium::OnIOComplete(int result) { |
125 int rv = DoLoop(result); | 138 int rv = DoLoop(result); |
126 if (rv != ERR_IO_PENDING) { | 139 if (rv != ERR_IO_PENDING) { |
127 base::ResetAndReturn(&callback_).Run(rv); | 140 callback_->Run(rv == OK, &error_details_, verify_details_); |
141 callback_.reset(); | |
142 verify_details_ = NULL; | |
128 } | 143 } |
129 } | 144 } |
130 | 145 |
131 int ProofVerifierChromium::DoVerifyCert(int result) { | 146 int ProofVerifierChromium::DoVerifyCert(int result) { |
132 next_state_ = STATE_VERIFY_CERT_COMPLETE; | 147 next_state_ = STATE_VERIFY_CERT_COMPLETE; |
133 | 148 |
134 int flags = 0; | 149 int flags = 0; |
135 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); | 150 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); |
136 return verifier_->Verify( | 151 return verifier_->Verify( |
137 cert_.get(), | 152 cert_.get(), |
138 hostname_, | 153 hostname_, |
139 flags, | 154 flags, |
140 SSLConfigService::GetCRLSet().get(), | 155 SSLConfigService::GetCRLSet().get(), |
141 cert_verify_result_, | 156 &verify_details_->cert_verify_result, |
142 base::Bind(&ProofVerifierChromium::OnIOComplete, | 157 base::Bind(&ProofVerifierChromium::OnIOComplete, |
143 base::Unretained(this)), | 158 base::Unretained(this)), |
144 net_log_); | 159 net_log_); |
145 } | 160 } |
146 | 161 |
147 int ProofVerifierChromium::DoVerifyCertComplete(int result) { | 162 int ProofVerifierChromium::DoVerifyCertComplete(int result) { |
148 verifier_.reset(); | 163 verifier_.reset(); |
149 | 164 |
150 if (result <= ERR_FAILED) { | 165 if (result <= ERR_FAILED) { |
151 *error_details_ = StringPrintf("Failed to verify certificate chain: %s", | 166 error_details_ = StringPrintf("Failed to verify certificate chain: %s", |
152 ErrorToString(result)); | 167 ErrorToString(result)); |
153 DLOG(WARNING) << *error_details_; | 168 DLOG(WARNING) << error_details_; |
154 result = ERR_FAILED; | 169 result = ERR_FAILED; |
155 } | 170 } |
156 | 171 |
157 // Exit DoLoop and return the result to the caller to VerifyProof. | 172 // Exit DoLoop and return the result to the caller to VerifyProof. |
158 DCHECK_EQ(STATE_NONE, next_state_); | 173 DCHECK_EQ(STATE_NONE, next_state_); |
159 return result; | 174 return result; |
160 } | 175 } |
161 | 176 |
162 bool ProofVerifierChromium::VerifySignature(const string& signed_data, | 177 bool ProofVerifierChromium::VerifySignature(const string& signed_data, |
163 const string& signature, | 178 const string& signature, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
231 if (!verifier.VerifyFinal()) { | 246 if (!verifier.VerifyFinal()) { |
232 DLOG(WARNING) << "VerifyFinal failed"; | 247 DLOG(WARNING) << "VerifyFinal failed"; |
233 return false; | 248 return false; |
234 } | 249 } |
235 | 250 |
236 DLOG(INFO) << "VerifyFinal success"; | 251 DLOG(INFO) << "VerifyFinal success"; |
237 return true; | 252 return true; |
238 } | 253 } |
239 | 254 |
240 } // namespace net | 255 } // namespace net |
OLD | NEW |