Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: chrome/browser/extensions/api/certificate_provider/certificate_provider_api.cc

Issue 2094333002: Implementation for chrome.certificateProvider.requestPin/stopPinRequest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Improved the browser tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/certificate_provider/certificate_provide r_api.h" 5 #include "chrome/browser/extensions/api/certificate_provider/certificate_provide r_api.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_serv ice.h" 14 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_serv ice.h"
15 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_serv ice_factory.h" 15 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_serv ice_factory.h"
16 #include "chrome/common/extensions/api/certificate_provider.h" 16 #include "chrome/common/extensions/api/certificate_provider.h"
17 #include "chrome/common/extensions/api/certificate_provider_internal.h" 17 #include "chrome/common/extensions/api/certificate_provider_internal.h"
18 #include "content/public/common/console_message_level.h" 18 #include "content/public/common/console_message_level.h"
19 #include "net/cert/x509_certificate.h" 19 #include "net/cert/x509_certificate.h"
20 #include "net/ssl/ssl_private_key.h" 20 #include "net/ssl/ssl_private_key.h"
21 21
22 namespace extensions { 22 namespace api_cp = extensions::api::certificate_provider;
23 23 namespace api_cpi = extensions::api::certificate_provider_internal;
24 namespace api_cp = api::certificate_provider;
25 namespace api_cpi = api::certificate_provider_internal;
26 24
27 namespace { 25 namespace {
28 26
27 chromeos::RequestPinView::RequestPinErrorType GetErrorTypeForView(
28 api_cp::PinRequestErrorType error_type) {
29 switch (error_type) {
30 case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_INVALID_PIN:
31 return chromeos::RequestPinView::RequestPinErrorType::INVALID_PIN;
32 case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_INVALID_PUK:
33 return chromeos::RequestPinView::RequestPinErrorType::INVALID_PUK;
34 case api_cp::PinRequestErrorType::
35 PIN_REQUEST_ERROR_TYPE_MAX_ATTEMPTS_EXCEEDED:
36 return chromeos::RequestPinView::RequestPinErrorType::
37 MAX_ATTEMPTS_EXCEEDED;
38 case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_UNKNOWN_ERROR:
39 return chromeos::RequestPinView::RequestPinErrorType::UNKNOWN_ERROR;
40 case api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_NONE:
41 return chromeos::RequestPinView::RequestPinErrorType::NONE;
42 }
43
44 NOTREACHED();
45 return chromeos::RequestPinView::RequestPinErrorType::NONE;
46 }
47
48 } // namespace
49
50 namespace extensions {
51
52 namespace {
53
29 const char kErrorInvalidX509Cert[] = 54 const char kErrorInvalidX509Cert[] =
30 "Certificate is not a valid X.509 certificate."; 55 "Certificate is not a valid X.509 certificate.";
31 const char kErrorECDSANotSupported[] = "Key type ECDSA not supported."; 56 const char kErrorECDSANotSupported[] = "Key type ECDSA not supported.";
32 const char kErrorUnknownKeyType[] = "Key type unknown."; 57 const char kErrorUnknownKeyType[] = "Key type unknown.";
33 const char kErrorAborted[] = "Request was aborted."; 58 const char kErrorAborted[] = "Request was aborted.";
34 const char kErrorTimeout[] = "Request timed out, reply rejected."; 59 const char kErrorTimeout[] = "Request timed out, reply rejected.";
35 60
61 // requestPin constants.
62 const char kNoActiveDialog[] = "No active dialog from extension.";
63 const char kInvalidId[] = "Invalid signRequestId";
64 const char kOtherFlowInProgress[] = "Other flow in progress";
65 const char kPreviousDialogActive[] = "Previous request not finished";
66 const char kNoUserInput[] = "No user input received";
67
36 } // namespace 68 } // namespace
37 69
70 const int api::certificate_provider::kMaxClosedDialogsPer10Mins = 2;
71
38 CertificateProviderInternalReportCertificatesFunction:: 72 CertificateProviderInternalReportCertificatesFunction::
39 ~CertificateProviderInternalReportCertificatesFunction() {} 73 ~CertificateProviderInternalReportCertificatesFunction() {}
40 74
41 ExtensionFunction::ResponseAction 75 ExtensionFunction::ResponseAction
42 CertificateProviderInternalReportCertificatesFunction::Run() { 76 CertificateProviderInternalReportCertificatesFunction::Run() {
43 std::unique_ptr<api_cpi::ReportCertificates::Params> params( 77 std::unique_ptr<api_cpi::ReportCertificates::Params> params(
44 api_cpi::ReportCertificates::Params::Create(*args_)); 78 api_cpi::ReportCertificates::Params::Create(*args_));
45 EXTENSION_FUNCTION_VALIDATE(params); 79 EXTENSION_FUNCTION_VALIDATE(params);
46 80
47 chromeos::CertificateProviderService* const service = 81 chromeos::CertificateProviderService* const service =
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 out_info->supported_hashes.push_back(net::SSLPrivateKey::Hash::SHA512); 175 out_info->supported_hashes.push_back(net::SSLPrivateKey::Hash::SHA512);
142 break; 176 break;
143 case api_cp::HASH_NONE: 177 case api_cp::HASH_NONE:
144 NOTREACHED(); 178 NOTREACHED();
145 return false; 179 return false;
146 } 180 }
147 } 181 }
148 return true; 182 return true;
149 } 183 }
150 184
185 CertificateProviderStopPinRequestFunction::
186 ~CertificateProviderStopPinRequestFunction() {}
187
188 ExtensionFunction::ResponseAction
189 CertificateProviderStopPinRequestFunction::Run() {
190 std::unique_ptr<api_cp::RequestPin::Params> params(
191 api_cp::RequestPin::Params::Create(*args_));
192 EXTENSION_FUNCTION_VALIDATE(params);
193
194 chromeos::CertificateProviderService* const service =
195 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
196 browser_context());
197 DCHECK(service);
198 if (params->details.error_type ==
199 api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_NONE) {
200 bool dialog_closed =
201 service->pin_dialog_manager()->CloseDialog(extension_id());
202 if (!dialog_closed) {
203 // This might happen if the user closed the dialog while extension was
204 // processing the input.
205 return RespondNow(Error(kNoActiveDialog));
206 }
207
208 return RespondNow(NoArguments());
209 }
210
211 chromeos::RequestPinView::RequestPinErrorType error_type =
212 GetErrorTypeForView(params->details.error_type);
213 chromeos::PinDialogManager::StopPinRequestResponse update_response =
214 service->pin_dialog_manager()->UpdatePinDialog(
215 extension()->id(), error_type,
216 false, // Don't accept any input.
217 base::Bind(&CertificateProviderStopPinRequestFunction::DialogClosed,
218 this));
219 switch (update_response) {
220 case chromeos::PinDialogManager::StopPinRequestResponse::NO_ACTIVE_DIALOG:
221 return RespondNow(Error(kNoActiveDialog));
222 case chromeos::PinDialogManager::StopPinRequestResponse::NO_USER_INPUT:
223 return RespondNow(Error(kNoUserInput));
Devlin 2016/11/29 21:09:03 Why is this an error? Can the extension not cance
igorcov 2016/11/30 15:32:38 The extension can cancel the flow without user inp
224 case chromeos::PinDialogManager::StopPinRequestResponse::STOPPED:
225 return RespondLater();
226 }
227
228 NOTREACHED();
229 return RespondLater();
230 }
231
232 void CertificateProviderStopPinRequestFunction::DialogClosed(
233 const base::string16& value) {
234 chromeos::CertificateProviderService* const service =
235 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
236 browser_context());
237 DCHECK(service);
238
239 Respond(NoArguments());
240 service->pin_dialog_manager()->OnPinDialogClosed();
241 }
242
243 CertificateProviderRequestPinFunction::
244 ~CertificateProviderRequestPinFunction() {}
245
246 bool CertificateProviderRequestPinFunction::ShouldSkipQuotaLimiting() const {
247 chromeos::CertificateProviderService* const service =
248 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
249 browser_context());
250 DCHECK(service);
251
252 return !service->pin_dialog_manager()->LastPinDialogClosed(extension_id());
253 }
254
255 void CertificateProviderRequestPinFunction::GetQuotaLimitHeuristics(
256 extensions::QuotaLimitHeuristics* heuristics) const {
257 QuotaLimitHeuristic::Config short_limit_config = {
258 api::certificate_provider::kMaxClosedDialogsPer10Mins,
259 base::TimeDelta::FromMinutes(10)};
260 heuristics->push_back(base::MakeUnique<QuotaService::TimedLimit>(
261 short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(),
262 "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES"));
263 }
264
265 ExtensionFunction::ResponseAction CertificateProviderRequestPinFunction::Run() {
266 std::unique_ptr<api_cp::RequestPin::Params> params(
267 api_cp::RequestPin::Params::Create(*args_));
268 EXTENSION_FUNCTION_VALIDATE(params);
269
270 api_cp::PinRequestType pin_request_type =
271 params->details.request_type ==
272 api_cp::PinRequestType::PIN_REQUEST_TYPE_NONE
273 ? api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN
274 : params->details.request_type;
275
276 chromeos::RequestPinView::RequestPinErrorType error_type =
277 GetErrorTypeForView(params->details.error_type);
278
279 chromeos::RequestPinView::RequestPinCodeType code_type =
280 (pin_request_type == api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN)
281 ? chromeos::RequestPinView::RequestPinCodeType::PIN
282 : chromeos::RequestPinView::RequestPinCodeType::PUK;
283
284 chromeos::CertificateProviderService* const service =
285 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
286 browser_context());
287 DCHECK(service);
288
289 int attempts_left =
290 params->details.attempts_left ? *params->details.attempts_left : -1;
291 chromeos::PinDialogManager::RequestPinResponse result =
292 service->pin_dialog_manager()->ShowPinDialog(
293 extension()->id(), extension()->name(),
294 params->details.sign_request_id, code_type, error_type, attempts_left,
295 base::Bind(&CertificateProviderRequestPinFunction::OnInputReceived,
296 this));
297 switch (result) {
298 case chromeos::PinDialogManager::RequestPinResponse::SUCCESS:
299 return RespondLater();
300 case chromeos::PinDialogManager::RequestPinResponse::INVALID_ID:
301 return RespondNow(Error(kInvalidId));
302 case chromeos::PinDialogManager::RequestPinResponse::OTHER_FLOW_IN_PROGRESS:
303 return RespondNow(Error(kOtherFlowInProgress));
304 case chromeos::PinDialogManager::RequestPinResponse::
305 DIALOG_DISPLAYED_ALREADY:
306 return RespondNow(Error(kPreviousDialogActive));
307 }
308
309 NOTREACHED();
310 return RespondNow(Error(kPreviousDialogActive));
311 }
312
313 void CertificateProviderRequestPinFunction::OnInputReceived(
314 const base::string16& value) {
315 std::unique_ptr<base::ListValue> create_results(new base::ListValue());
316 chromeos::CertificateProviderService* const service =
317 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
318 browser_context());
319 DCHECK(service);
320 if (!value.empty()) {
321 api::certificate_provider::PinResponseDetails details;
322 details.user_input.reset(new std::string(value.begin(), value.end()));
323 create_results->Append(details.ToValue());
324 }
325
326 Respond(ArgumentList(std::move(create_results)));
327 if (!value.empty()) {
328 service->pin_dialog_manager()->OnPinDialogInput();
Devlin 2016/11/29 21:09:03 Why is the API doing this instead of the dialog or
igorcov 2016/11/30 15:32:38 Moved to be notified by the dialog.
329 }
330 }
331
151 CertificateProviderInternalReportSignatureFunction:: 332 CertificateProviderInternalReportSignatureFunction::
152 ~CertificateProviderInternalReportSignatureFunction() {} 333 ~CertificateProviderInternalReportSignatureFunction() {}
153 334
154 ExtensionFunction::ResponseAction 335 ExtensionFunction::ResponseAction
155 CertificateProviderInternalReportSignatureFunction::Run() { 336 CertificateProviderInternalReportSignatureFunction::Run() {
156 std::unique_ptr<api_cpi::ReportSignature::Params> params( 337 std::unique_ptr<api_cpi::ReportSignature::Params> params(
157 api_cpi::ReportSignature::Params::Create(*args_)); 338 api_cpi::ReportSignature::Params::Create(*args_));
158 EXTENSION_FUNCTION_VALIDATE(params); 339 EXTENSION_FUNCTION_VALIDATE(params);
159 340
160 chromeos::CertificateProviderService* const service = 341 chromeos::CertificateProviderService* const service =
161 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( 342 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
162 browser_context()); 343 browser_context());
163 DCHECK(service); 344 DCHECK(service);
164 345
165 std::vector<uint8_t> signature; 346 std::vector<uint8_t> signature;
166 // If an error occurred, |signature| will not be set. 347 // If an error occurred, |signature| will not be set.
167 if (params->signature) 348 if (params->signature)
168 signature.assign(params->signature->begin(), params->signature->end()); 349 signature.assign(params->signature->begin(), params->signature->end());
169 350
170 service->ReplyToSignRequest(extension_id(), params->request_id, signature); 351 service->ReplyToSignRequest(extension_id(), params->request_id, signature);
171 return RespondNow(NoArguments()); 352 return RespondNow(NoArguments());
172 } 353 }
173 354
174 } // namespace extensions 355 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698