summaryrefslogtreecommitdiff
path: root/chromium/net/ssl/server_bound_cert_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/ssl/server_bound_cert_service.cc')
-rw-r--r--chromium/net/ssl/server_bound_cert_service.cc201
1 files changed, 54 insertions, 147 deletions
diff --git a/chromium/net/ssl/server_bound_cert_service.cc b/chromium/net/ssl/server_bound_cert_service.cc
index 2bbcbc79e6b..4bc82ed5d9b 100644
--- a/chromium/net/ssl/server_bound_cert_service.cc
+++ b/chromium/net/ssl/server_bound_cert_service.cc
@@ -43,8 +43,7 @@ const int kValidityPeriodInDays = 365;
const int kSystemTimeValidityBufferInDays = 90;
// Used by the GetDomainBoundCertResult histogram to record the final
-// outcome of each GetDomainBoundCert or GetOrCreateDomainBoundCert call.
-// Do not re-use values.
+// outcome of each GetDomainBoundCert call. Do not re-use values.
enum GetCertResult {
// Synchronously found and returned an existing domain bound cert.
SYNC_SUCCESS = 0,
@@ -58,8 +57,7 @@ enum GetCertResult {
ASYNC_FAILURE_CREATE_CERT = 4,
ASYNC_FAILURE_EXPORT_KEY = 5,
ASYNC_FAILURE_UNKNOWN = 6,
- // GetDomainBoundCert or GetOrCreateDomainBoundCert was called with
- // invalid arguments.
+ // GetDomainBoundCert was called with invalid arguments.
INVALID_ARGUMENT = 7,
// We don't support any of the cert types the server requested.
UNSUPPORTED_TYPE = 8,
@@ -279,18 +277,14 @@ class ServerBoundCertServiceWorker {
// origin message loop.
class ServerBoundCertServiceJob {
public:
- ServerBoundCertServiceJob(bool create_if_missing)
- : create_if_missing_(create_if_missing) {
- }
+ ServerBoundCertServiceJob() { }
~ServerBoundCertServiceJob() {
if (!requests_.empty())
DeleteAllCanceled();
}
- void AddRequest(ServerBoundCertServiceRequest* request,
- bool create_if_missing = false) {
- create_if_missing_ |= create_if_missing;
+ void AddRequest(ServerBoundCertServiceRequest* request) {
requests_.push_back(request);
}
@@ -300,8 +294,6 @@ class ServerBoundCertServiceJob {
PostAll(error, private_key, cert);
}
- bool CreateIfMissing() const { return create_if_missing_; }
-
private:
void PostAll(int error,
const std::string& private_key,
@@ -328,7 +320,6 @@ class ServerBoundCertServiceJob {
}
std::vector<ServerBoundCertServiceRequest*> requests_;
- bool create_if_missing_;
};
// static
@@ -397,7 +388,7 @@ std::string ServerBoundCertService::GetDomainForHost(const std::string& host) {
return domain;
}
-int ServerBoundCertService::GetOrCreateDomainBoundCert(
+int ServerBoundCertService::GetDomainBoundCert(
const std::string& host,
std::string* private_key,
std::string* cert,
@@ -420,15 +411,49 @@ int ServerBoundCertService::GetOrCreateDomainBoundCert(
requests_++;
- // See if a request for the same domain is currently in flight.
- bool create_if_missing = true;
- if (JoinToInFlightRequest(request_start, domain, private_key, cert,
- create_if_missing, callback, out_req)) {
+ // See if an identical request is currently in flight.
+ ServerBoundCertServiceJob* job = NULL;
+ std::map<std::string, ServerBoundCertServiceJob*>::const_iterator j;
+ j = inflight_.find(domain);
+ if (j != inflight_.end()) {
+ // An identical request is in flight already. We'll just attach our
+ // callback.
+ job = j->second;
+ inflight_joins_++;
+
+ ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest(
+ request_start,
+ base::Bind(&RequestHandle::OnRequestComplete,
+ base::Unretained(out_req)),
+ private_key, cert);
+ job->AddRequest(request);
+ out_req->RequestStarted(this, request, callback);
return ERR_IO_PENDING;
}
- int err = LookupDomainBoundCert(request_start, domain, private_key, cert,
- create_if_missing, callback, out_req);
+ // Check if a domain bound cert of an acceptable type already exists for this
+ // domain. Note that |expiration_time| is ignored, and expired certs are
+ // considered valid.
+ base::Time expiration_time;
+ int err = server_bound_cert_store_->GetServerBoundCert(
+ domain,
+ &expiration_time /* ignored */,
+ private_key,
+ cert,
+ base::Bind(&ServerBoundCertService::GotServerBoundCert,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ if (err == OK) {
+ // Sync lookup found a valid cert.
+ DVLOG(1) << "Cert store had valid cert for " << domain;
+ cert_store_hits_++;
+ RecordGetDomainBoundCertResult(SYNC_SUCCESS);
+ base::TimeDelta request_time = base::TimeTicks::Now() - request_start;
+ UMA_HISTOGRAM_TIMES("DomainBoundCerts.GetCertTimeSync", request_time);
+ RecordGetCertTime(request_time);
+ return OK;
+ }
+
if (err == ERR_FILE_NOT_FOUND) {
// Sync lookup did not find a valid cert. Start generating a new one.
workers_created_++;
@@ -442,17 +467,19 @@ int ServerBoundCertService::GetOrCreateDomainBoundCert(
RecordGetDomainBoundCertResult(WORKER_FAILURE);
return ERR_INSUFFICIENT_RESOURCES;
}
- // We are waiting for cert generation. Create a job & request to track it.
- ServerBoundCertServiceJob* job =
- new ServerBoundCertServiceJob(create_if_missing);
+ }
+
+ if (err == ERR_IO_PENDING || err == ERR_FILE_NOT_FOUND) {
+ // We are either waiting for async DB lookup, or waiting for cert
+ // generation. Create a job & request to track it.
+ job = new ServerBoundCertServiceJob();
inflight_[domain] = job;
ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest(
request_start,
base::Bind(&RequestHandle::OnRequestComplete,
base::Unretained(out_req)),
- private_key,
- cert);
+ private_key, cert);
job->AddRequest(request);
out_req->RequestStarted(this, request, callback);
return ERR_IO_PENDING;
@@ -461,41 +488,6 @@ int ServerBoundCertService::GetOrCreateDomainBoundCert(
return err;
}
-int ServerBoundCertService::GetDomainBoundCert(
- const std::string& host,
- std::string* private_key,
- std::string* cert,
- const CompletionCallback& callback,
- RequestHandle* out_req) {
- DVLOG(1) << __FUNCTION__ << " " << host;
- DCHECK(CalledOnValidThread());
- base::TimeTicks request_start = base::TimeTicks::Now();
-
- if (callback.is_null() || !private_key || !cert || host.empty()) {
- RecordGetDomainBoundCertResult(INVALID_ARGUMENT);
- return ERR_INVALID_ARGUMENT;
- }
-
- std::string domain = GetDomainForHost(host);
- if (domain.empty()) {
- RecordGetDomainBoundCertResult(INVALID_ARGUMENT);
- return ERR_INVALID_ARGUMENT;
- }
-
- requests_++;
-
- // See if a request for the same domain currently in flight.
- bool create_if_missing = false;
- if (JoinToInFlightRequest(request_start, domain, private_key, cert,
- create_if_missing, callback, out_req)) {
- return ERR_IO_PENDING;
- }
-
- int err = LookupDomainBoundCert(request_start, domain, private_key, cert,
- create_if_missing, callback, out_req);
- return err;
-}
-
void ServerBoundCertService::GotServerBoundCert(
int err,
const std::string& server_identifier,
@@ -519,13 +511,7 @@ void ServerBoundCertService::GotServerBoundCert(
HandleResult(OK, server_identifier, key, cert);
return;
}
- // Async lookup did not find a valid cert. If no request asked to create one,
- // return the error directly.
- if (!j->second->CreateIfMissing()) {
- HandleResult(err, server_identifier, key, cert);
- return;
- }
- // At least one request asked to create a cert => start generating a new one.
+ // Async lookup did not find a valid cert. Start generating a new one.
workers_created_++;
ServerBoundCertServiceWorker* worker = new ServerBoundCertServiceWorker(
server_identifier,
@@ -538,6 +524,7 @@ void ServerBoundCertService::GotServerBoundCert(
server_identifier,
std::string(),
std::string());
+ return;
}
}
@@ -592,86 +579,6 @@ void ServerBoundCertService::HandleResult(
delete job;
}
-bool ServerBoundCertService::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) {
- ServerBoundCertServiceJob* job = NULL;
- std::map<std::string, ServerBoundCertServiceJob*>::const_iterator j =
- inflight_.find(domain);
- if (j != inflight_.end()) {
- // A request for the same domain is in flight already. We'll attach our
- // callback, but we'll also mark it as requiring a cert if one's mising.
- job = j->second;
- inflight_joins_++;
-
- ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest(
- request_start,
- base::Bind(&RequestHandle::OnRequestComplete,
- base::Unretained(out_req)),
- private_key,
- cert);
- job->AddRequest(request, create_if_missing);
- out_req->RequestStarted(this, request, callback);
- return true;
- }
- return false;
-}
-
-int ServerBoundCertService::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) {
- // Check if a domain bound cert already exists for this domain. Note that
- // |expiration_time| is ignored, and expired certs are considered valid.
- base::Time expiration_time;
- int err = server_bound_cert_store_->GetServerBoundCert(
- domain,
- &expiration_time /* ignored */,
- private_key,
- cert,
- base::Bind(&ServerBoundCertService::GotServerBoundCert,
- weak_ptr_factory_.GetWeakPtr()));
-
- if (err == OK) {
- // Sync lookup found a valid cert.
- DVLOG(1) << "Cert store had valid cert for " << domain;
- cert_store_hits_++;
- RecordGetDomainBoundCertResult(SYNC_SUCCESS);
- base::TimeDelta request_time = base::TimeTicks::Now() - request_start;
- UMA_HISTOGRAM_TIMES("DomainBoundCerts.GetCertTimeSync", request_time);
- RecordGetCertTime(request_time);
- return OK;
- }
-
- if (err == ERR_IO_PENDING) {
- // We are waiting for async DB lookup. Create a job & request to track it.
- ServerBoundCertServiceJob* job =
- new ServerBoundCertServiceJob(create_if_missing);
- inflight_[domain] = job;
-
- ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest(
- request_start,
- base::Bind(&RequestHandle::OnRequestComplete,
- base::Unretained(out_req)),
- private_key,
- cert);
- job->AddRequest(request);
- out_req->RequestStarted(this, request, callback);
- return ERR_IO_PENDING;
- }
-
- return err;
-}
-
int ServerBoundCertService::cert_count() {
return server_bound_cert_store_->GetCertCount();
}