summaryrefslogtreecommitdiff
path: root/chromium/net/ssl/server_bound_cert_service.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/ssl/server_bound_cert_service.h')
-rw-r--r--chromium/net/ssl/server_bound_cert_service.h214
1 files changed, 214 insertions, 0 deletions
diff --git a/chromium/net/ssl/server_bound_cert_service.h b/chromium/net/ssl/server_bound_cert_service.h
new file mode 100644
index 00000000000..0dc7f4ae390
--- /dev/null
+++ b/chromium/net/ssl/server_bound_cert_service.h
@@ -0,0 +1,214 @@
+// Copyright (c) 2012 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.
+
+#ifndef NET_SSL_SERVER_BOUND_CERT_SERVICE_H_
+#define NET_SSL_SERVER_BOUND_CERT_SERVICE_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/time/time.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "net/ssl/server_bound_cert_store.h"
+
+namespace base {
+class TaskRunner;
+}
+
+namespace net {
+
+class ServerBoundCertServiceJob;
+class ServerBoundCertServiceRequest;
+class ServerBoundCertServiceWorker;
+
+// A class for creating and fetching server bound certs. These certs are used
+// to identify users' machines; their public keys are used as channel IDs in
+// http://tools.ietf.org/html/draft-balfanz-tls-channelid-00.
+// As a result although certs are set to be invalid after one year, we don't
+// actually expire them. Once generated, certs are valid as long as the users
+// want. Users can delete existing certs, and new certs will be generated
+// automatically.
+
+// Inherits from NonThreadSafe in order to use the function
+// |CalledOnValidThread|.
+class NET_EXPORT ServerBoundCertService
+ : NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+ class NET_EXPORT RequestHandle {
+ public:
+ RequestHandle();
+ ~RequestHandle();
+
+ // Cancel the request. Does nothing if the request finished or was already
+ // cancelled.
+ void Cancel();
+
+ bool is_active() const { return request_ != NULL; }
+
+ private:
+ friend class ServerBoundCertService;
+
+ void RequestStarted(ServerBoundCertService* service,
+ ServerBoundCertServiceRequest* request,
+ const CompletionCallback& callback);
+
+ void OnRequestComplete(int result);
+
+ ServerBoundCertService* service_;
+ ServerBoundCertServiceRequest* request_;
+ CompletionCallback callback_;
+ };
+
+ // Password used on EncryptedPrivateKeyInfo data stored in EC private_key
+ // values. (This is not used to provide any security, but to workaround NSS
+ // being unable to import unencrypted PrivateKeyInfo for EC keys.)
+ static const char kEPKIPassword[];
+
+ // This object owns |server_bound_cert_store|. |task_runner| will
+ // be used to post certificate generation worker tasks. The tasks are
+ // safe for use with WorkerPool and SequencedWorkerPool::CONTINUE_ON_SHUTDOWN.
+ ServerBoundCertService(
+ ServerBoundCertStore* server_bound_cert_store,
+ const scoped_refptr<base::TaskRunner>& task_runner);
+
+ ~ServerBoundCertService();
+
+ // Returns the domain to be used for |host|. The domain is the
+ // "registry controlled domain", or the "ETLD + 1" where one exists, or
+ // the origin otherwise.
+ static std::string GetDomainForHost(const std::string& host);
+
+ // Tests whether the system time is within the supported range for
+ // certificate generation. This value is cached when ServerBoundCertService
+ // is created, so if the system time is changed by a huge amount, this may no
+ // longer hold.
+ bool IsSystemTimeValid() const { return is_system_time_valid_; }
+
+ // Fetches the domain bound cert for the specified host if one exists and
+ // creates one otherwise. Returns OK if successful or an error code upon
+ // failure.
+ //
+ // On successful completion, |private_key| stores a DER-encoded
+ // PrivateKeyInfo struct, and |cert| stores a DER-encoded certificate.
+ // The PrivateKeyInfo is always an ECDSA private key.
+ //
+ // |callback| must not be null. ERR_IO_PENDING is returned if the operation
+ // could not be completed immediately, in which case the result code will
+ // be passed to the callback when available.
+ //
+ // |*out_req| will be initialized with a handle to the async request. This
+ // RequestHandle object must be cancelled or destroyed before the
+ // ServerBoundCertService is destroyed.
+ int GetOrCreateDomainBoundCert(
+ const std::string& host,
+ std::string* private_key,
+ std::string* cert,
+ const CompletionCallback& callback,
+ RequestHandle* out_req);
+
+ // Fetches the domain bound cert for the specified host if one exists.
+ // Returns OK if successful, ERR_FILE_NOT_FOUND if none exists, or an error
+ // code upon failure.
+ //
+ // On successful completion, |private_key| stores a DER-encoded
+ // PrivateKeyInfo struct, and |cert| stores a DER-encoded certificate.
+ // The PrivateKeyInfo is always an ECDSA private key.
+ //
+ // |callback| must not be null. ERR_IO_PENDING is returned if the operation
+ // could not be completed immediately, in which case the result code will
+ // be passed to the callback when available. If an in-flight
+ // GetDomainBoundCert is pending, and a new GetOrCreateDomainBoundCert
+ // request arrives for the same domain, the GetDomainBoundCert request will
+ // not complete until a new cert is created.
+ //
+ // |*out_req| will be initialized with a handle to the async request. This
+ // RequestHandle object must be cancelled or destroyed before the
+ // ServerBoundCertService is destroyed.
+ int GetDomainBoundCert(
+ const std::string& host,
+ std::string* private_key,
+ std::string* cert,
+ const CompletionCallback& callback,
+ RequestHandle* out_req);
+
+ // Returns the backing ServerBoundCertStore.
+ ServerBoundCertStore* GetCertStore();
+
+ // Public only for unit testing.
+ int cert_count();
+ uint64 requests() const { return requests_; }
+ uint64 cert_store_hits() const { return cert_store_hits_; }
+ uint64 inflight_joins() const { return inflight_joins_; }
+ uint64 workers_created() const { return workers_created_; }
+
+ private:
+ // Cancels the specified request. |req| is the handle stored by
+ // GetDomainBoundCert(). After a request is canceled, its completion
+ // callback will not be called.
+ void CancelRequest(ServerBoundCertServiceRequest* req);
+
+ void GotServerBoundCert(int err,
+ const std::string& server_identifier,
+ base::Time expiration_time,
+ const std::string& key,
+ const std::string& cert);
+ void GeneratedServerBoundCert(
+ const std::string& server_identifier,
+ int error,
+ scoped_ptr<ServerBoundCertStore::ServerBoundCert> cert);
+ void HandleResult(int error,
+ const std::string& server_identifier,
+ const std::string& private_key,
+ const std::string& cert);
+
+ // Searches for an in-flight request for the same domain. If found,
+ // attaches to the request and returns true. Returns false if no in-flight
+ // request is found.
+ bool JoinToInFlightRequest(const base::TimeTicks& request_start,
+ const std::string& domain,
+ std::string* private_key,
+ std::string* cert,
+ bool create_if_missing,
+ const CompletionCallback& callback,
+ RequestHandle* out_req);
+
+ // Looks for the domain bound cert for |domain| in this service's store.
+ // Returns OK if it can be found synchronously, ERR_IO_PENDING if the
+ // result cannot be obtained synchronously, or a network error code on
+ // failure (including failure to find a domain-bound cert of |domain|).
+ int LookupDomainBoundCert(const base::TimeTicks& request_start,
+ const std::string& domain,
+ std::string* private_key,
+ std::string* cert,
+ bool create_if_missing,
+ const CompletionCallback& callback,
+ RequestHandle* out_req);
+
+ scoped_ptr<ServerBoundCertStore> server_bound_cert_store_;
+ scoped_refptr<base::TaskRunner> task_runner_;
+
+ // inflight_ maps from a server to an active generation which is taking
+ // place.
+ std::map<std::string, ServerBoundCertServiceJob*> inflight_;
+ base::WeakPtrFactory<ServerBoundCertService> weak_ptr_factory_;
+
+ uint64 requests_;
+ uint64 cert_store_hits_;
+ uint64 inflight_joins_;
+ uint64 workers_created_;
+
+ bool is_system_time_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServerBoundCertService);
+};
+
+} // namespace net
+
+#endif // NET_SSL_SERVER_BOUND_CERT_SERVICE_H_