| Index: net/base/origin_bound_cert_service.temp.cc
|
| ===================================================================
|
| --- net/base/origin_bound_cert_service.temp.cc (revision 94628)
|
| +++ net/base/origin_bound_cert_service.temp.cc (working copy)
|
| @@ -2,14 +2,21 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "net/base/cert_verifier.h"
|
| +#include "net/base/origin_bound_cert_service.h"
|
|
|
| +#include <limits>
|
| +
|
| #include "base/compiler_specific.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "base/message_loop.h"
|
| +#include "base/rand_util.h"
|
| #include "base/stl_util.h"
|
| -#include "base/synchronization/lock.h"
|
| #include "base/threading/worker_pool.h"
|
| +#include "crypto/rsa_private_key.h"
|
| #include "net/base/net_errors.h"
|
| +#include "net/base/origin_bound_cert_store.h"
|
| #include "net/base/x509_certificate.h"
|
|
|
| #if defined(USE_NSS)
|
| @@ -18,93 +25,40 @@
|
|
|
| namespace net {
|
|
|
| -////////////////////////////////////////////////////////////////////////////
|
| -
|
| -// Life of a request:
|
| -//
|
| -// CertVerifier CertVerifierJob CertVerifierWorker Request
|
| -// | (origin loop) (worker loop)
|
| -// |
|
| -// Verify()
|
| -// |---->-------------------<creates>
|
| -// |
|
| -// |---->----<creates>
|
| -// |
|
| -// |---->---------------------------------------------------<creates>
|
| -// |
|
| -// |---->--------------------Start
|
| -// | |
|
| -// | PostTask
|
| -// |
|
| -// | <starts verifying>
|
| -// |---->-----AddRequest |
|
| -// |
|
| -// |
|
| -// |
|
| -// Finish
|
| -// |
|
| -// PostTask
|
| -//
|
| -// |
|
| -// DoReply
|
| -// |----<-----------------------|
|
| -// HandleResult
|
| -// |
|
| -// |---->-----HandleResult
|
| -// |
|
| -// |------>-----------------------------------Post
|
| -//
|
| -//
|
| -//
|
| -// On a cache hit, CertVerifier::Verify() returns synchronously without
|
| -// posting a task to a worker thread.
|
| -
|
| -// The number of CachedCertVerifyResult objects that we'll cache.
|
| -static const unsigned kMaxCacheEntries = 256;
|
| -
|
| -// The number of seconds for which we'll cache a cache entry.
|
| -static const unsigned kTTLSecs = 1800; // 30 minutes.
|
| -
|
| namespace {
|
|
|
| -class DefaultTimeService : public CertVerifier::TimeService {
|
| - public:
|
| - // CertVerifier::TimeService methods:
|
| - virtual base::Time Now() { return base::Time::Now(); }
|
| -};
|
| +const int kKeySizeInBits = 1024;
|
| +const int kValidityPeriodInDays = 365;
|
|
|
| } // namespace
|
|
|
| -CachedCertVerifyResult::CachedCertVerifyResult() : error(ERR_FAILED) {
|
| -}
|
| -
|
| -CachedCertVerifyResult::~CachedCertVerifyResult() {}
|
| -
|
| -bool CachedCertVerifyResult::HasExpired(const base::Time current_time) const {
|
| - return current_time >= expiry;
|
| -}
|
| -
|
| // Represents the output and result callback of a request.
|
| -class CertVerifierRequest {
|
| +class OriginBoundCertServiceRequest {
|
| public:
|
| - CertVerifierRequest(CompletionCallback* callback,
|
| - CertVerifyResult* verify_result)
|
| + OriginBoundCertServiceRequest(CompletionCallback* callback,
|
| + std::string* private_key,
|
| + std::string* cert)
|
| : callback_(callback),
|
| - verify_result_(verify_result) {
|
| + private_key_(private_key),
|
| + cert_(cert) {
|
| }
|
|
|
| // Ensures that the result callback will never be made.
|
| void Cancel() {
|
| callback_ = NULL;
|
| - verify_result_ = NULL;
|
| + private_key_ = NULL;
|
| + cert_ = NULL;
|
| }
|
|
|
| - // Copies the contents of |verify_result| to the caller's
|
| - // CertVerifyResult and calls the callback.
|
| - void Post(const CachedCertVerifyResult& verify_result) {
|
| + // Copies the contents of |private_key| and |cert| to the caller's output
|
| + // arguments and calls the callback.
|
| + void Post(int error,
|
| + const std::string& private_key,
|
| + const std::string& cert) {
|
| if (callback_) {
|
| - *verify_result_ = verify_result.result;
|
| - callback_->Run(verify_result.error);
|
| + *private_key_ = private_key;
|
| + *cert_ = cert;
|
| + callback_->Run(error);
|
| }
|
| delete this;
|
| }
|
| @@ -113,24 +67,22 @@
|
|
|
| private:
|
| CompletionCallback* callback_;
|
| - CertVerifyResult* verify_result_;
|
| + std::string* private_key_;
|
| + std::string* cert_;
|
| };
|
|
|
| -
|
| -// CertVerifierWorker runs on a worker thread and takes care of the blocking
|
| -// process of performing the certificate verification. Deletes itself
|
| -// eventually if Start() succeeds.
|
| -class CertVerifierWorker {
|
| +// OriginBoundCertServiceWorker runs on a worker thread and takes care of the
|
| +// blocking process of performing key generation. Deletes itself eventually
|
| +// if Start() succeeds.
|
| +class OriginBoundCertServiceWorker {
|
| public:
|
| - CertVerifierWorker(X509Certificate* cert,
|
| - const std::string& hostname,
|
| - int flags,
|
| - CertVerifier* cert_verifier)
|
| - : cert_(cert),
|
| - hostname_(hostname),
|
| - flags_(flags),
|
| + OriginBoundCertServiceWorker(
|
| + const std::string& origin,
|
| + OriginBoundCertService* origin_bound_cert_service)
|
| + : origin_(origin),
|
| + serial_number_(base::RandInt(0, std::numeric_limits<int>::max())),
|
| origin_loop_(MessageLoop::current()),
|
| - cert_verifier_(cert_verifier),
|
| + origin_bound_cert_service_(origin_bound_cert_service),
|
| canceled_(false),
|
| error_(ERR_FAILED) {
|
| }
|
| @@ -139,12 +91,13 @@
|
| DCHECK_EQ(MessageLoop::current(), origin_loop_);
|
|
|
| return base::WorkerPool::PostTask(
|
| - FROM_HERE, NewRunnableMethod(this, &CertVerifierWorker::Run),
|
| + FROM_HERE,
|
| + NewRunnableMethod(this, &OriginBoundCertServiceWorker::Run),
|
| true /* task is slow */);
|
| }
|
|
|
| - // Cancel is called from the origin loop when the CertVerifier is getting
|
| - // deleted.
|
| + // Cancel is called from the origin loop when the OriginBoundCertService is
|
| + // getting deleted.
|
| void Cancel() {
|
| DCHECK_EQ(MessageLoop::current(), origin_loop_);
|
| base::AutoLock locked(lock_);
|
| @@ -154,13 +107,16 @@
|
| private:
|
| void Run() {
|
| // Runs on a worker thread.
|
| - error_ = cert_->Verify(hostname_, flags_, &verify_result_);
|
| + error_ = OriginBoundCertService::GenerateCert(origin_,
|
| + serial_number_,
|
| + &private_key_,
|
| + &cert_);
|
| #if defined(USE_NSS)
|
| // Detach the thread from NSPR.
|
| // Calling NSS functions attaches the thread to NSPR, which stores
|
| // the NSPR thread ID in thread-specific data.
|
| // The threads in our thread pool terminate after we have called
|
| - // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
|
| + // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
|
| // segfaults on shutdown when the threads' thread-specific data
|
| // destructors run.
|
| PR_DetachThread();
|
| @@ -178,8 +134,8 @@
|
| // memory leaks or worse errors.
|
| base::AutoLock locked(lock_);
|
| if (!canceled_) {
|
| - cert_verifier_->HandleResult(cert_, hostname_, flags_,
|
| - error_, verify_result_);
|
| + origin_bound_cert_service_->HandleResult(origin_, error_,
|
| + private_key_, cert_);
|
| }
|
| }
|
| delete this;
|
| @@ -187,14 +143,14 @@
|
|
|
| void Finish() {
|
| // Runs on the worker thread.
|
| - // We assume that the origin loop outlives the CertVerifier. If the
|
| - // CertVerifier is deleted, it will call Cancel on us. If it does so
|
| - // before the Acquire, we'll delete ourselves and return. If it's trying to
|
| - // do so concurrently, then it'll block on the lock and we'll call PostTask
|
| - // while the CertVerifier (and therefore the MessageLoop) is still alive.
|
| - // If it does so after this function, we assume that the MessageLoop will
|
| - // process pending tasks. In which case we'll notice the |canceled_| flag
|
| - // in DoReply.
|
| + // We assume that the origin loop outlives the OriginBoundCertService. If
|
| + // the OriginBoundCertService is deleted, it will call Cancel on us. If it
|
| + // does so before the Acquire, we'll delete ourselves and return. If it's
|
| + // trying to do so concurrently, then it'll block on the lock and we'll
|
| + // call PostTask while the OriginBoundCertService (and therefore the
|
| + // MessageLoop) is still alive. If it does so after this function, we
|
| + // assume that the MessageLoop will process pending tasks. In which case
|
| + // we'll notice the |canceled_| flag in DoReply.
|
|
|
| bool canceled;
|
| {
|
| @@ -202,141 +158,130 @@
|
| canceled = canceled_;
|
| if (!canceled) {
|
| origin_loop_->PostTask(
|
| - FROM_HERE, NewRunnableMethod(this, &CertVerifierWorker::DoReply));
|
| + FROM_HERE,
|
| + NewRunnableMethod(this, &OriginBoundCertServiceWorker::DoReply));
|
| }
|
| }
|
| -
|
| if (canceled)
|
| delete this;
|
| }
|
|
|
| - scoped_refptr<X509Certificate> cert_;
|
| - const std::string hostname_;
|
| - const int flags_;
|
| + const std::string origin_;
|
| + uint32 serial_number_;
|
| MessageLoop* const origin_loop_;
|
| - CertVerifier* const cert_verifier_;
|
| + OriginBoundCertService* const origin_bound_cert_service_;
|
|
|
| // lock_ protects canceled_.
|
| base::Lock lock_;
|
|
|
| // If canceled_ is true,
|
| // * origin_loop_ cannot be accessed by the worker thread,
|
| - // * cert_verifier_ cannot be accessed by any thread.
|
| + // * origin_bound_cert_service_ cannot be accessed by any thread.
|
| bool canceled_;
|
|
|
| int error_;
|
| - CertVerifyResult verify_result_;
|
| + std::string private_key_;
|
| + std::string cert_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(CertVerifierWorker);
|
| + DISALLOW_COPY_AND_ASSIGN(OriginBoundCertServiceWorker);
|
| };
|
|
|
| -// A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It
|
| -// lives only on the CertVerifier's origin message loop.
|
| -class CertVerifierJob {
|
| +// An OriginBoundCertServiceJob is a one-to-one counterpart of an
|
| +// OriginBoundCertServiceWorker. It lives only on the OriginBoundCertService's
|
| +// origin message loop.
|
| +class OriginBoundCertServiceJob {
|
| public:
|
| - explicit CertVerifierJob(CertVerifierWorker* worker) : worker_(worker) {
|
| + explicit OriginBoundCertServiceJob(OriginBoundCertServiceWorker* worker)
|
| + : worker_(worker) {
|
| }
|
|
|
| - ~CertVerifierJob() {
|
| + ~OriginBoundCertServiceJob() {
|
| if (worker_) {
|
| worker_->Cancel();
|
| DeleteAllCanceled();
|
| }
|
| }
|
|
|
| - void AddRequest(CertVerifierRequest* request) {
|
| + void AddRequest(OriginBoundCertServiceRequest* request) {
|
| requests_.push_back(request);
|
| }
|
|
|
| - void HandleResult(const CachedCertVerifyResult& verify_result) {
|
| + void HandleResult(int error,
|
| + const std::string& private_key,
|
| + const std::string& cert) {
|
| worker_ = NULL;
|
| - PostAll(verify_result);
|
| + PostAll(error, private_key, cert);
|
| }
|
|
|
| private:
|
| - void PostAll(const CachedCertVerifyResult& verify_result) {
|
| - std::vector<CertVerifierRequest*> requests;
|
| + void PostAll(int error,
|
| + const std::string& private_key,
|
| + const std::string& cert) {
|
| + std::vector<OriginBoundCertServiceRequest*> requests;
|
| requests_.swap(requests);
|
|
|
| - for (std::vector<CertVerifierRequest*>::iterator
|
| + for (std::vector<OriginBoundCertServiceRequest*>::iterator
|
| i = requests.begin(); i != requests.end(); i++) {
|
| - (*i)->Post(verify_result);
|
| - // Post() causes the CertVerifierRequest to delete itself.
|
| + (*i)->Post(error, private_key, cert);
|
| + // Post() causes the OriginBoundCertServiceRequest to delete itself.
|
| }
|
| }
|
|
|
| void DeleteAllCanceled() {
|
| - for (std::vector<CertVerifierRequest*>::iterator
|
| + for (std::vector<OriginBoundCertServiceRequest*>::iterator
|
| i = requests_.begin(); i != requests_.end(); i++) {
|
| if ((*i)->canceled()) {
|
| delete *i;
|
| } else {
|
| - LOG(DFATAL) << "CertVerifierRequest leaked!";
|
| + LOG(DFATAL) << "OriginBoundCertServiceRequest leaked!";
|
| }
|
| }
|
| }
|
|
|
| - std::vector<CertVerifierRequest*> requests_;
|
| - CertVerifierWorker* worker_;
|
| + std::vector<OriginBoundCertServiceRequest*> requests_;
|
| + OriginBoundCertServiceWorker* worker_;
|
| };
|
|
|
| -
|
| -CertVerifier::CertVerifier()
|
| - : time_service_(new DefaultTimeService),
|
| +OriginBoundCertService::OriginBoundCertService(
|
| + OriginBoundCertStore* origin_bound_cert_store)
|
| + : origin_bound_cert_store_(origin_bound_cert_store),
|
| requests_(0),
|
| - cache_hits_(0),
|
| - inflight_joins_(0) {
|
| - CertDatabase::AddObserver(this);
|
| -}
|
| + synchronous_completions_(0),
|
| + inflight_joins_(0) {}
|
|
|
| -CertVerifier::CertVerifier(TimeService* time_service)
|
| - : time_service_(time_service),
|
| - requests_(0),
|
| - cache_hits_(0),
|
| - inflight_joins_(0) {
|
| - CertDatabase::AddObserver(this);
|
| -}
|
| -
|
| -CertVerifier::~CertVerifier() {
|
| +OriginBoundCertService::~OriginBoundCertService() {
|
| STLDeleteValues(&inflight_);
|
| -
|
| - CertDatabase::RemoveObserver(this);
|
| }
|
|
|
| -int CertVerifier::Verify(X509Certificate* cert,
|
| - const std::string& hostname,
|
| - int flags,
|
| - CertVerifyResult* verify_result,
|
| - CompletionCallback* callback,
|
| - RequestHandle* out_req) {
|
| +int OriginBoundCertService::GetOriginBoundCert(const std::string& origin,
|
| + std::string* private_key,
|
| + std::string* cert,
|
| + CompletionCallback* callback,
|
| + RequestHandle* out_req) {
|
| +
|
| DCHECK(CalledOnValidThread());
|
|
|
| - if (!callback || !verify_result || hostname.empty()) {
|
| + if (!callback || !private_key || !cert || origin.empty()) {
|
| *out_req = NULL;
|
| return ERR_INVALID_ARGUMENT;
|
| }
|
|
|
| requests_++;
|
|
|
| - const RequestParams key = {cert->fingerprint(), hostname, flags};
|
| - // First check the cache.
|
| - std::map<RequestParams, CachedCertVerifyResult>::iterator i;
|
| - i = cache_.find(key);
|
| - if (i != cache_.end()) {
|
| - if (!i->second.HasExpired(time_service_->Now())) {
|
| - cache_hits_++;
|
| - *out_req = NULL;
|
| - *verify_result = i->second.result;
|
| - return i->second.error;
|
| - }
|
| - // Cache entry has expired.
|
| - cache_.erase(i);
|
| + // Check if an origin bound cert already exists for this origin.
|
| + if (origin_bound_cert_store_->GetOriginBoundCert(origin,
|
| + private_key,
|
| + cert)) {
|
| + synchronous_completions_++;
|
| + *out_req = NULL;
|
| + return OK;
|
| }
|
|
|
| - // No cache hit. See if an identical request is currently in flight.
|
| - CertVerifierJob* job;
|
| - std::map<RequestParams, CertVerifierJob*>::const_iterator j;
|
| - j = inflight_.find(key);
|
| + // |origin_bound_cert_store_| has no cert for this origin. See if an
|
| + // identical request is currently in flight.
|
| + OriginBoundCertServiceJob* job;
|
| + std::map<std::string, OriginBoundCertServiceJob*>::const_iterator j;
|
| + j = inflight_.find(origin);
|
| if (j != inflight_.end()) {
|
| // An identical request is in flight already. We'll just attach our
|
| // callback.
|
| @@ -344,163 +289,104 @@
|
| job = j->second;
|
| } else {
|
| // Need to make a new request.
|
| - CertVerifierWorker* worker = new CertVerifierWorker(cert, hostname, flags,
|
| - this);
|
| - job = new CertVerifierJob(worker);
|
| + OriginBoundCertServiceWorker* worker =
|
| + new OriginBoundCertServiceWorker(origin, this);
|
| + job = new OriginBoundCertServiceJob(worker);
|
| if (!worker->Start()) {
|
| delete job;
|
| delete worker;
|
| *out_req = NULL;
|
| - // TODO(wtc): log to the NetLog.
|
| - LOG(ERROR) << "CertVerifierWorker couldn't be started.";
|
| + // TODO(rkn): Log to the NetLog.
|
| + LOG(ERROR) << "OriginBoundCertServiceWorker couldn't be started.";
|
| return ERR_INSUFFICIENT_RESOURCES; // Just a guess.
|
| }
|
| - inflight_.insert(std::make_pair(key, job));
|
| + inflight_[origin] = job;
|
| }
|
|
|
| - CertVerifierRequest* request =
|
| - new CertVerifierRequest(callback, verify_result);
|
| + OriginBoundCertServiceRequest* request =
|
| + new OriginBoundCertServiceRequest(callback, private_key, cert);
|
| job->AddRequest(request);
|
| *out_req = request;
|
| return ERR_IO_PENDING;
|
| }
|
|
|
| -void CertVerifier::CancelRequest(RequestHandle req) {
|
| - DCHECK(CalledOnValidThread());
|
| - CertVerifierRequest* request = reinterpret_cast<CertVerifierRequest*>(req);
|
| - request->Cancel();
|
| -}
|
| +// static
|
| +int OriginBoundCertService::GenerateCert(const std::string& origin,
|
| + uint32 serial_number,
|
| + std::string* private_key,
|
| + std::string* cert) {
|
| + std::string subject = "CN=OBC";
|
| + scoped_ptr<crypto::RSAPrivateKey> key(
|
| + crypto::RSAPrivateKey::Create(kKeySizeInBits));
|
| + if (!key.get()) {
|
| + LOG(WARNING) << "Unable to create key pair for client";
|
| + return ERR_KEY_GENERATION_FAILED;
|
| + }
|
|
|
| -void CertVerifier::ClearCache() {
|
| - DCHECK(CalledOnValidThread());
|
| + scoped_refptr<X509Certificate> x509_cert = X509Certificate::CreateSelfSigned(
|
| + key.get(),
|
| + subject,
|
| + serial_number,
|
| + base::TimeDelta::FromDays(kValidityPeriodInDays));
|
| + if (!x509_cert) {
|
| + LOG(WARNING) << "Unable to create x509 cert for client";
|
| + return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED;
|
| + }
|
|
|
| - cache_.clear();
|
| - // Leaves inflight_ alone.
|
| + std::vector<uint8> private_key_info;
|
| + if (!key->ExportPrivateKey(&private_key_info)) {
|
| + LOG(WARNING) << "Unable to export private key";
|
| + return ERR_PRIVATE_KEY_EXPORT_FAILED;
|
| + }
|
| + // TODO(rkn): Perhaps ExportPrivateKey should be changed to output a
|
| + // std::string* to prevent this copying.
|
| + std::string key_out(private_key_info.begin(), private_key_info.end());
|
| +
|
| + std::string der_cert;
|
| + if (!x509_cert->GetDEREncoded(&der_cert)) {
|
| + LOG(WARNING) << "Unable to get DER-encoded cert";
|
| + return ERR_GET_CERT_BYTES_FAILED;
|
| + }
|
| +
|
| + private_key->swap(key_out);
|
| + cert->swap(der_cert);
|
| + return OK;
|
| }
|
|
|
| -size_t CertVerifier::GetCacheSize() const {
|
| +void OriginBoundCertService::CancelRequest(RequestHandle req) {
|
| DCHECK(CalledOnValidThread());
|
| -
|
| - return cache_.size();
|
| + OriginBoundCertServiceRequest* request =
|
| + reinterpret_cast<OriginBoundCertServiceRequest*>(req);
|
| + request->Cancel();
|
| }
|
|
|
| -// HandleResult is called by CertVerifierWorker on the origin message loop.
|
| -// It deletes CertVerifierJob.
|
| -void CertVerifier::HandleResult(X509Certificate* cert,
|
| - const std::string& hostname,
|
| - int flags,
|
| - int error,
|
| - const CertVerifyResult& verify_result) {
|
| +// HandleResult is called by OriginBoundCertServiceWorker on the origin message
|
| +// loop. It deletes OriginBoundCertServiceJob.
|
| +void OriginBoundCertService::HandleResult(const std::string& origin,
|
| + int error,
|
| + const std::string& private_key,
|
| + const std::string& cert) {
|
| DCHECK(CalledOnValidThread());
|
|
|
| - const base::Time current_time(time_service_->Now());
|
| + origin_bound_cert_store_->SetOriginBoundCert(origin, private_key, cert);
|
|
|
| - CachedCertVerifyResult cached_result;
|
| - cached_result.error = error;
|
| - cached_result.result = verify_result;
|
| - uint32 ttl = kTTLSecs;
|
| - cached_result.expiry = current_time + base::TimeDelta::FromSeconds(ttl);
|
| -
|
| - const RequestParams key = {cert->fingerprint(), hostname, flags};
|
| -
|
| - DCHECK_GE(kMaxCacheEntries, 1u);
|
| - DCHECK_LE(cache_.size(), kMaxCacheEntries);
|
| - if (cache_.size() == kMaxCacheEntries) {
|
| - // Need to remove an element of the cache.
|
| - std::map<RequestParams, CachedCertVerifyResult>::iterator i, cur;
|
| - for (i = cache_.begin(); i != cache_.end(); ) {
|
| - cur = i++;
|
| - if (cur->second.HasExpired(current_time))
|
| - cache_.erase(cur);
|
| - }
|
| - }
|
| - if (cache_.size() == kMaxCacheEntries) {
|
| - // If we didn't clear out any expired entries, we just remove the first
|
| - // element. Crummy but simple.
|
| - cache_.erase(cache_.begin());
|
| - }
|
| -
|
| - cache_.insert(std::make_pair(key, cached_result));
|
| -
|
| - std::map<RequestParams, CertVerifierJob*>::iterator j;
|
| - j = inflight_.find(key);
|
| + std::map<std::string, OriginBoundCertServiceJob*>::iterator j;
|
| + j = inflight_.find(origin);
|
| if (j == inflight_.end()) {
|
| NOTREACHED();
|
| return;
|
| }
|
| - CertVerifierJob* job = j->second;
|
| + OriginBoundCertServiceJob* job = j->second;
|
| inflight_.erase(j);
|
|
|
| - job->HandleResult(cached_result);
|
| + job->HandleResult(error, private_key, cert);
|
| delete job;
|
| }
|
|
|
| -void CertVerifier::OnCertTrustChanged(const X509Certificate* cert) {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - ClearCache();
|
| +int OriginBoundCertService::cert_count() {
|
| + return origin_bound_cert_store_->GetCertCount();
|
| }
|
|
|
| -/////////////////////////////////////////////////////////////////////
|
| -
|
| -SingleRequestCertVerifier::SingleRequestCertVerifier(
|
| - CertVerifier* cert_verifier)
|
| - : cert_verifier_(cert_verifier),
|
| - cur_request_(NULL),
|
| - cur_request_callback_(NULL),
|
| - ALLOW_THIS_IN_INITIALIZER_LIST(
|
| - callback_(this, &SingleRequestCertVerifier::OnVerifyCompletion)) {
|
| - DCHECK(cert_verifier_ != NULL);
|
| -}
|
| -
|
| -SingleRequestCertVerifier::~SingleRequestCertVerifier() {
|
| - if (cur_request_) {
|
| - cert_verifier_->CancelRequest(cur_request_);
|
| - cur_request_ = NULL;
|
| - }
|
| -}
|
| -
|
| -int SingleRequestCertVerifier::Verify(X509Certificate* cert,
|
| - const std::string& hostname,
|
| - int flags,
|
| - CertVerifyResult* verify_result,
|
| - CompletionCallback* callback) {
|
| - // Should not be already in use.
|
| - DCHECK(!cur_request_ && !cur_request_callback_);
|
| -
|
| - // Do a synchronous verification.
|
| - if (!callback)
|
| - return cert->Verify(hostname, flags, verify_result);
|
| -
|
| - CertVerifier::RequestHandle request = NULL;
|
| -
|
| - // We need to be notified of completion before |callback| is called, so that
|
| - // we can clear out |cur_request_*|.
|
| - int rv = cert_verifier_->Verify(
|
| - cert, hostname, flags, verify_result, &callback_, &request);
|
| -
|
| - if (rv == ERR_IO_PENDING) {
|
| - // Cleared in OnVerifyCompletion().
|
| - cur_request_ = request;
|
| - cur_request_callback_ = callback;
|
| - }
|
| -
|
| - return rv;
|
| -}
|
| -
|
| -void SingleRequestCertVerifier::OnVerifyCompletion(int result) {
|
| - DCHECK(cur_request_ && cur_request_callback_);
|
| -
|
| - CompletionCallback* callback = cur_request_callback_;
|
| -
|
| - // Clear the outstanding request information.
|
| - cur_request_ = NULL;
|
| - cur_request_callback_ = NULL;
|
| -
|
| - // Call the user's original callback.
|
| - callback->Run(result);
|
| -}
|
| -
|
| } // namespace net
|
|
|
| -DISABLE_RUNNABLE_METHOD_REFCOUNT(net::CertVerifierWorker);
|
| +DISABLE_RUNNABLE_METHOD_REFCOUNT(net::OriginBoundCertServiceWorker);
|
|
|