summaryrefslogtreecommitdiffstats
path: root/net/base/cert_verifier.cc
diff options
context:
space:
mode:
authorwtc@google.com <wtc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-19 00:17:48 +0000
committerwtc@google.com <wtc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-19 00:17:48 +0000
commit5b62083c99317965244123c031c707d53f0a03f1 (patch)
tree80d8d2b4811aeb65736101fdc88cfdc4a2c28ff3 /net/base/cert_verifier.cc
parent349f6911964be4226312f970d038bdfc3339face (diff)
downloadchromium_src-5b62083c99317965244123c031c707d53f0a03f1.zip
chromium_src-5b62083c99317965244123c031c707d53f0a03f1.tar.gz
chromium_src-5b62083c99317965244123c031c707d53f0a03f1.tar.bz2
Add the CertVerifier class. It is based on the
HostResolver class. It's not being compiled yet. R=eroman BUG=3592 Review URL: http://codereview.chromium.org/14868 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7280 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/cert_verifier.cc')
-rw-r--r--net/base/cert_verifier.cc140
1 files changed, 140 insertions, 0 deletions
diff --git a/net/base/cert_verifier.cc b/net/base/cert_verifier.cc
new file mode 100644
index 0000000..8163690
--- /dev/null
+++ b/net/base/cert_verifier.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// 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 "base/message_loop.h"
+#include "base/worker_pool.h"
+#include "net/base/net_errors.h"
+#include "net/base/x509_certificate.h"
+
+namespace net {
+
+class CertVerifier::Request :
+ public base::RefCountedThreadSafe<CertVerifier::Request> {
+ public:
+ Request(CertVerifier* verifier,
+ X509Certificate* cert,
+ const std::string& hostname,
+ bool rev_checking_enabled,
+ int* cert_status,
+ CompletionCallback* callback)
+ : cert_(cert),
+ hostname_(hostname),
+ rev_checking_enabled_(rev_checking_enabled),
+ verifier_(verifier),
+ cert_status_(cert_status),
+ callback_(callback),
+ origin_loop_(MessageLoop::current()),
+ error_(OK),
+ result_(0) {
+ }
+
+ ~Request() {}
+
+ void DoVerify() {
+ // Running on the worker thread
+ error_ = cert_->Verify(hostname_, rev_checking_enabled_, &result_);
+
+ Task* reply = NewRunnableMethod(this, &Request::DoCallback);
+
+ // The origin loop could go away while we are trying to post to it, so we
+ // need to call its PostTask method inside a lock. See ~CertVerifier.
+ {
+ AutoLock locked(origin_loop_lock_);
+ if (origin_loop_) {
+ origin_loop_->PostTask(FROM_HERE, reply);
+ reply = NULL;
+ }
+ }
+
+ // Does nothing if it got posted.
+ delete reply;
+ }
+
+ void DoCallback() {
+ // Running on the origin thread.
+ DCHECK(error_ || result_);
+
+ // We may have been cancelled!
+ if (!verifier_)
+ return;
+
+ *cert_status_ = result_;
+
+ // Drop the verifier's reference to us. Do this before running the
+ // callback since the callback might result in the verifier being
+ // destroyed.
+ verifier_->request_ = NULL;
+
+ callback_->Run(error_);
+ }
+
+ void Cancel() {
+ verifier_ = NULL;
+
+ AutoLock locked(origin_loop_lock_);
+ origin_loop_ = NULL;
+ }
+
+ private:
+ // Set on the origin thread, read on the worker thread.
+ scoped_refptr<X509Certificate> cert_;
+ std::string hostname_;
+ bool rev_checking_enabled_;
+
+ // Only used on the origin thread (where Verify was called).
+ CertVerifier* verifier_;
+ int* cert_status_;
+ CompletionCallback* callback_;
+
+ // Used to post ourselves onto the origin thread.
+ Lock origin_loop_lock_;
+ MessageLoop* origin_loop_;
+
+ // Assigned on the worker thread, read on the origin thread.
+ int error_;
+ int result_;
+};
+
+//-----------------------------------------------------------------------------
+
+CertVerifier::CertVerifier() {
+}
+
+CertVerifier::~CertVerifier() {
+ if (request_)
+ request_->Cancel();
+}
+
+int CertVerifier::Verify(X509Certificate* cert,
+ const std::string& hostname,
+ bool rev_checking_enabled,
+ int* cert_status,
+ CompletionCallback* callback) {
+ DCHECK(!request_) << "verifier already in use";
+
+ // Do a synchronous verification.
+ if (!callback) {
+ int result;
+ int rv = cert->Verify(hostname, rev_checking_enabled, &result);
+ *cert_status = result;
+ return rv;
+ }
+
+ request_ = new Request(this, cert, hostname, rev_checking_enabled,
+ cert_status, callback);
+
+ // Dispatch to worker thread...
+ if (!WorkerPool::PostTask(FROM_HERE,
+ NewRunnableMethod(request_.get(), &Request::DoVerify), true)) {
+ NOTREACHED();
+ request_ = NULL;
+ return ERR_FAILED;
+ }
+
+ return ERR_IO_PENDING;
+}
+
+} // namespace net