Chromium Code Reviews| 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 |