diff options
Diffstat (limited to 'chromium/net/ssl/server_bound_cert_service.cc')
-rw-r--r-- | chromium/net/ssl/server_bound_cert_service.cc | 201 |
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(); } |