diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 19:48:01 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-13 19:48:01 +0000 |
commit | 5c78ce686bfc945434c5c21d2a5b40370938d202 (patch) | |
tree | dd2af50c06be2f108af1dd52e606468dd978762f /net | |
parent | 16e2a4415f0a6de2a3f6e589e100d75d7cd658c9 (diff) | |
download | chromium_src-5c78ce686bfc945434c5c21d2a5b40370938d202.zip chromium_src-5c78ce686bfc945434c5c21d2a5b40370938d202.tar.gz chromium_src-5c78ce686bfc945434c5c21d2a5b40370938d202.tar.bz2 |
Enable the ProofVerifierChromium to handle multiple simultaneous requests.
Review URL: https://codereview.chromium.org/196953006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256896 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/quic/crypto/proof_verifier_chromium.cc | 132 | ||||
-rw-r--r-- | net/quic/crypto/proof_verifier_chromium.h | 41 |
2 files changed, 121 insertions, 52 deletions
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc index 68ad25c..8584aed 100644 --- a/net/quic/crypto/proof_verifier_chromium.cc +++ b/net/quic/crypto/proof_verifier_chromium.cc @@ -9,6 +9,7 @@ #include "base/callback_helpers.h" #include "base/compiler_specific.h" #include "base/logging.h" +#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "crypto/signature_verifier.h" #include "net/base/net_errors.h" @@ -30,18 +31,74 @@ using std::vector; namespace net { -ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier, - const BoundNetLog& net_log) - : cert_verifier_(cert_verifier), - next_state_(STATE_NONE), - net_log_(net_log) { -} +// A Job handles the verification of a single proof. It is owned by the +// ProofVerifier. If the verification can not complete synchronously, it +// will notify the ProofVerifier upon completion. +class ProofVerifierChromium::Job { + public: + Job(ProofVerifierChromium* proof_verifier, + CertVerifier* cert_verifier, + const BoundNetLog& net_log); -ProofVerifierChromium::~ProofVerifierChromium() { - verifier_.reset(); + // Starts the proof verification. If |PENDING| is returned, then |callback| + // will be invoked asynchronously when the verification completes. + Status VerifyProof(const std::string& hostname, + const std::string& server_config, + const std::vector<std::string>& certs, + const std::string& signature, + std::string* error_details, + scoped_ptr<ProofVerifyDetails>* details, + ProofVerifierCallback* callback); + + private: + enum State { + STATE_NONE, + STATE_VERIFY_CERT, + STATE_VERIFY_CERT_COMPLETE, + }; + + int DoLoop(int last_io_result); + void OnIOComplete(int result); + int DoVerifyCert(int result); + int DoVerifyCertComplete(int result); + + bool VerifySignature(const std::string& signed_data, + const std::string& signature, + const std::string& cert); + + // Proof verifier to notify when this jobs completes. + ProofVerifierChromium* proof_verifier_; + + // The underlying verifier used for verifying certificates. + scoped_ptr<SingleRequestCertVerifier> verifier_; + + // |hostname| specifies the hostname for which |certs| is a valid chain. + std::string hostname_; + + scoped_ptr<ProofVerifierCallback> callback_; + scoped_ptr<ProofVerifyDetailsChromium> verify_details_; + std::string error_details_; + + // X509Certificate from a chain of DER encoded certificates. + scoped_refptr<X509Certificate> cert_; + + State next_state_; + + BoundNetLog net_log_; + + DISALLOW_COPY_AND_ASSIGN(Job); +}; + +ProofVerifierChromium::Job::Job(ProofVerifierChromium* proof_verifier, + CertVerifier* cert_verifier, + const BoundNetLog& net_log) + : proof_verifier_(proof_verifier), + verifier_(new SingleRequestCertVerifier(cert_verifier)), + next_state_(STATE_NONE), + net_log_(net_log) { } -ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( +ProofVerifierChromium::Status ProofVerifierChromium::Job::VerifyProof( const string& hostname, const string& server_config, const vector<string>& certs, @@ -56,10 +113,9 @@ ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( callback_.reset(callback); error_details->clear(); - DCHECK_EQ(STATE_NONE, next_state_); if (STATE_NONE != next_state_) { *error_details = "Certificate is already set and VerifyProof has begun"; - DLOG(WARNING) << *error_details; + DLOG(DFATAL) << *error_details; return FAILURE; } @@ -113,7 +169,7 @@ ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( } } -int ProofVerifierChromium::DoLoop(int last_result) { +int ProofVerifierChromium::Job::DoLoop(int last_result) { int rv = last_result; do { State state = next_state_; @@ -136,32 +192,34 @@ int ProofVerifierChromium::DoLoop(int last_result) { return rv; } -void ProofVerifierChromium::OnIOComplete(int result) { +void ProofVerifierChromium::Job::OnIOComplete(int result) { int rv = DoLoop(result); if (rv != ERR_IO_PENDING) { - scoped_ptr<ProofVerifyDetails> scoped_details(verify_details_.release()); - callback_->Run(rv == OK, error_details_, &scoped_details); - callback_.reset(); + scoped_ptr<ProofVerifierCallback> callback(callback_.release()); + // Callback expects ProofVerifyDetails not ProofVerifyDetailsChromium. + scoped_ptr<ProofVerifyDetails> verify_details(verify_details_.release()); + callback->Run(rv == OK, error_details_, &verify_details); + // Will delete |this|. + proof_verifier_->OnJobComplete(this); } } -int ProofVerifierChromium::DoVerifyCert(int result) { +int ProofVerifierChromium::Job::DoVerifyCert(int result) { next_state_ = STATE_VERIFY_CERT_COMPLETE; int flags = 0; - verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); return verifier_->Verify( cert_.get(), hostname_, flags, SSLConfigService::GetCRLSet().get(), &verify_details_->cert_verify_result, - base::Bind(&ProofVerifierChromium::OnIOComplete, + base::Bind(&ProofVerifierChromium::Job::OnIOComplete, base::Unretained(this)), net_log_); } -int ProofVerifierChromium::DoVerifyCertComplete(int result) { +int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { verifier_.reset(); if (result <= ERR_FAILED) { @@ -176,7 +234,7 @@ int ProofVerifierChromium::DoVerifyCertComplete(int result) { return result; } -bool ProofVerifierChromium::VerifySignature(const string& signed_data, +bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data, const string& signature, const string& cert) { StringPiece spki; @@ -252,4 +310,36 @@ bool ProofVerifierChromium::VerifySignature(const string& signed_data, return true; } +ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier, + const BoundNetLog& net_log) + : cert_verifier_(cert_verifier), + net_log_(net_log) { +} + +ProofVerifierChromium::~ProofVerifierChromium() { + STLDeleteElements(&active_jobs_); +} + +ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( + const std::string& hostname, + const std::string& server_config, + const std::vector<std::string>& certs, + const std::string& signature, + std::string* error_details, + scoped_ptr<ProofVerifyDetails>* details, + ProofVerifierCallback* callback) { + scoped_ptr<Job> job(new Job(this, cert_verifier_, net_log_)); + Status status = job->VerifyProof(hostname, server_config, certs, signature, + error_details, details, callback); + if (status == PENDING) { + active_jobs_.insert(job.release()); + } + return status; +} + +void ProofVerifierChromium::OnJobComplete(Job* job) { + active_jobs_.erase(job); + delete job; +} + } // namespace net diff --git a/net/quic/crypto/proof_verifier_chromium.h b/net/quic/crypto/proof_verifier_chromium.h index 4969cc8..7f695e6 100644 --- a/net/quic/crypto/proof_verifier_chromium.h +++ b/net/quic/crypto/proof_verifier_chromium.h @@ -5,17 +5,16 @@ #ifndef NET_QUIC_CRYPTO_PROOF_VERIFIER_CHROMIUM_H_ #define NET_QUIC_CRYPTO_PROOF_VERIFIER_CHROMIUM_H_ +#include <set> #include <string> #include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" -#include "net/base/completion_callback.h" #include "net/base/net_export.h" #include "net/base/net_log.h" #include "net/cert/cert_verify_result.h" -#include "net/cert/x509_certificate.h" #include "net/quic/crypto/proof_verifier.h" namespace net { @@ -30,8 +29,8 @@ struct ProofVerifyDetailsChromium : public ProofVerifyDetails { CertVerifyResult cert_verify_result; }; -// ProofVerifierChromium implements the QUIC ProofVerifier interface. -// TODO(rtenneti): Add support for multiple requests for one ProofVerifier. +// ProofVerifierChromium implements the QUIC ProofVerifier interface. It is +// capable of handling multiple simultaneous requests. class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier { public: ProofVerifierChromium(CertVerifier* cert_verifier, @@ -48,36 +47,16 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier { ProofVerifierCallback* callback) OVERRIDE; private: - enum State { - STATE_NONE, - STATE_VERIFY_CERT, - STATE_VERIFY_CERT_COMPLETE, - }; - - int DoLoop(int last_io_result); - void OnIOComplete(int result); - int DoVerifyCert(int result); - int DoVerifyCertComplete(int result); - - bool VerifySignature(const std::string& signed_data, - const std::string& signature, - const std::string& cert); - - // |cert_verifier_| and |verifier_| are used for verifying certificates. - CertVerifier* const cert_verifier_; - scoped_ptr<SingleRequestCertVerifier> verifier_; - - // |hostname| specifies the hostname for which |certs| is a valid chain. - std::string hostname_; + class Job; - scoped_ptr<ProofVerifierCallback> callback_; - scoped_ptr<ProofVerifyDetailsChromium> verify_details_; - std::string error_details_; + void OnJobComplete(Job* job); - // X509Certificate from a chain of DER encoded certificates. - scoped_refptr<X509Certificate> cert_; + // Set owning pointers to active jobs. + typedef std::set<Job*> JobSet; + JobSet active_jobs_; - State next_state_; + // Underlying verifier used to verify certificates. + CertVerifier* const cert_verifier_; BoundNetLog net_log_; |