Index: net/quic/quic_crypto_client_stream.cc |
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc |
index 78b39e759e2db3e042261175dc1f0c337c6a2147..18b739ce720e20c79ccb35e99ed74263d5aa8870 100644 |
--- a/net/quic/quic_crypto_client_stream.cc |
+++ b/net/quic/quic_crypto_client_stream.cc |
@@ -10,6 +10,7 @@ |
#include "net/quic/crypto/crypto_utils.h" |
#include "net/quic/crypto/null_encrypter.h" |
#include "net/quic/crypto/proof_verifier.h" |
+#include "net/quic/crypto/proof_verifier_chromium.h" |
#include "net/quic/quic_protocol.h" |
#include "net/quic/quic_session.h" |
#include "net/ssl/ssl_connection_status_flags.h" |
@@ -17,30 +18,70 @@ |
namespace net { |
+// ProofVerifierCallbackClientStream is passed as the callback method to |
+// VerifyProof. The ProofVerifier calls this class with the result of proof |
+// verification when verification is performed asynchronously. |
+class ProofVerifierCallbackClientStream : public ProofVerifierCallback { |
Ryan Hamilton
2013/07/23 18:40:50
This code can land in google3, right? (It will ju
agl
2013/07/23 21:04:57
Right.
|
+ public: |
+ explicit ProofVerifierCallbackClientStream(QuicCryptoClientStream* stream) |
+ : stream_(stream) {} |
+ |
+ // ProofVerifierCallback interface. |
+ virtual void Run(bool ok, |
+ string* error_details, |
+ ProofVerifyDetails* details) OVERRIDE { |
+ if (stream_ == NULL) { |
+ delete details; |
+ return; |
+ } |
+ |
+ stream_->verify_ok_ = ok; |
+ stream_->verify_error_details_ = *error_details; |
+ stream_->verify_details_.reset(details); |
+ stream_->proof_verify_callback_ = NULL; |
+ stream_->DoHandshakeLoop(NULL); |
+ |
+ // The ProofVerifier owns this object and will delete it when this method |
+ // returns. |
+ } |
+ |
+ // Cancel causes any future callbacks to be ignored. It must be called on the |
+ // same thread as the callback will be made on. |
+ void Cancel() { |
+ stream_ = NULL; |
+ } |
+ |
+ private: |
+ QuicCryptoClientStream* stream_; |
+}; |
+ |
QuicCryptoClientStream::QuicCryptoClientStream( |
const string& server_hostname, |
QuicSession* session, |
QuicCryptoClientConfig* crypto_config) |
: QuicCryptoStream(session), |
- weak_factory_(this), |
next_state_(STATE_IDLE), |
num_client_hellos_(0), |
crypto_config_(crypto_config), |
server_hostname_(server_hostname), |
- generation_counter_(0) { |
+ generation_counter_(0), |
+ proof_verify_callback_(NULL) { |
} |
QuicCryptoClientStream::~QuicCryptoClientStream() { |
+ if (proof_verify_callback_) { |
+ proof_verify_callback_->Cancel(); |
+ } |
} |
void QuicCryptoClientStream::OnHandshakeMessage( |
const CryptoHandshakeMessage& message) { |
- DoHandshakeLoop(&message, OK); |
+ DoHandshakeLoop(&message); |
} |
bool QuicCryptoClientStream::CryptoConnect() { |
next_state_ = STATE_SEND_CHLO; |
- DoHandshakeLoop(NULL, OK); |
+ DoHandshakeLoop(NULL); |
return true; |
} |
@@ -57,7 +98,8 @@ bool QuicCryptoClientStream::GetSSLInfo(SSLInfo* ssl_info) { |
return false; |
} |
const CertVerifyResult* cert_verify_result = |
- cached->cert_verify_result(); |
+ &(reinterpret_cast<const ProofVerifyDetailsChromium*>( |
+ cached->proof_verify_details()))->cert_verify_result; |
ssl_info->cert_status = cert_verify_result->cert_status; |
ssl_info->cert = cert_verify_result->verified_cert; |
@@ -95,8 +137,7 @@ bool QuicCryptoClientStream::GetSSLInfo(SSLInfo* ssl_info) { |
static const int kMaxClientHellos = 3; |
void QuicCryptoClientStream::DoHandshakeLoop( |
- const CryptoHandshakeMessage* in, |
- int result) { |
+ const CryptoHandshakeMessage* in) { |
CryptoHandshakeMessage out; |
QuicErrorCode error; |
string error_details; |
@@ -112,7 +153,6 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
next_state_ = STATE_IDLE; |
switch (state) { |
case STATE_SEND_CHLO: { |
- DCHECK_EQ(OK, result); |
// Send the client hello in plaintext. |
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
if (num_client_hellos_ > kMaxClientHellos) { |
@@ -171,7 +211,6 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
return; |
} |
case STATE_RECV_REJ: |
- DCHECK_EQ(OK, result); |
// We sent a dummy CHLO because we didn't have enough information to |
// perform a handshake, or we sent a full hello that the server |
// rejected. Here we hope to have a REJ that contains the information |
@@ -205,25 +244,40 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
DCHECK(verifier); |
next_state_ = STATE_VERIFY_PROOF_COMPLETE; |
generation_counter_ = cached->generation_counter(); |
- result = verifier->VerifyProof( |
+ |
+ ProofVerifierCallbackClientStream* proof_verify_callback = new |
+ ProofVerifierCallbackClientStream(this); |
+ |
+ verify_ok_ = false; |
+ |
+ ProofVerifier::Status status = verifier->VerifyProof( |
server_hostname_, |
cached->server_config(), |
cached->certs(), |
cached->signature(), |
- &error_details_, |
- &cert_verify_result_, |
- base::Bind(&QuicCryptoClientStream::OnVerifyProofComplete, |
- weak_factory_.GetWeakPtr())); |
- if (result == ERR_IO_PENDING) { |
- DVLOG(1) << "Doing VerifyProof"; |
- return; |
+ &error_details, |
+ &verify_details_, |
+ proof_verify_callback); |
+ |
+ switch (status) { |
+ case ProofVerifier::PENDING: |
+ proof_verify_callback_ = proof_verify_callback; |
+ DVLOG(1) << "Doing VerifyProof"; |
+ return; |
+ case ProofVerifier::ERROR: |
+ CloseConnectionWithDetails( |
+ QUIC_PROOF_INVALID, "Proof invalid: " + error_details); |
+ return; |
+ case ProofVerifier::OK: |
+ verify_ok_ = true; |
+ break; |
} |
break; |
} |
case STATE_VERIFY_PROOF_COMPLETE: |
- if (result != OK) { |
+ if (!verify_ok_) { |
CloseConnectionWithDetails( |
- QUIC_PROOF_INVALID, "Proof invalid: " + error_details_); |
+ QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); |
return; |
} |
// Check if generation_counter has changed between STATE_VERIFY_PROOF |
@@ -232,7 +286,7 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
next_state_ = STATE_VERIFY_PROOF; |
} else { |
cached->SetProofValid(); |
- cached->SetCertVerifyResult(cert_verify_result_); |
+ cached->SetProofVerifyDetails(verify_details_.release()); |
next_state_ = STATE_SEND_CHLO; |
} |
break; |
@@ -305,10 +359,4 @@ void QuicCryptoClientStream::DoHandshakeLoop( |
} |
} |
-void QuicCryptoClientStream::OnVerifyProofComplete(int result) { |
- DCHECK_EQ(STATE_VERIFY_PROOF_COMPLETE, next_state_); |
- DVLOG(1) << "VerifyProof completed: " << result; |
- DoHandshakeLoop(NULL, result); |
-} |
- |
} // namespace net |