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

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: Fixed review comments Created 4 years, 2 months 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:
Devlin 2016/10/20 21:20:44 Any reason to not use these enums in the RequestPi
igorcov 2016/10/25 16:38:35 RequestPinView class is from ui folder and I tried
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
36 } // namespace 67 } // namespace
37 68
69 const int api::certificate_provider::kMaxClosedDialogsPer10Mins = 2;
70
38 CertificateProviderInternalReportCertificatesFunction:: 71 CertificateProviderInternalReportCertificatesFunction::
39 ~CertificateProviderInternalReportCertificatesFunction() {} 72 ~CertificateProviderInternalReportCertificatesFunction() {}
40 73
41 ExtensionFunction::ResponseAction 74 ExtensionFunction::ResponseAction
42 CertificateProviderInternalReportCertificatesFunction::Run() { 75 CertificateProviderInternalReportCertificatesFunction::Run() {
43 std::unique_ptr<api_cpi::ReportCertificates::Params> params( 76 std::unique_ptr<api_cpi::ReportCertificates::Params> params(
44 api_cpi::ReportCertificates::Params::Create(*args_)); 77 api_cpi::ReportCertificates::Params::Create(*args_));
45 EXTENSION_FUNCTION_VALIDATE(params); 78 EXTENSION_FUNCTION_VALIDATE(params);
46 79
47 chromeos::CertificateProviderService* const service = 80 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); 174 out_info->supported_hashes.push_back(net::SSLPrivateKey::Hash::SHA512);
142 break; 175 break;
143 case api_cp::HASH_NONE: 176 case api_cp::HASH_NONE:
144 NOTREACHED(); 177 NOTREACHED();
145 return false; 178 return false;
146 } 179 }
147 } 180 }
148 return true; 181 return true;
149 } 182 }
150 183
184 CertificateProviderStopPinRequestFunction::
185 ~CertificateProviderStopPinRequestFunction() {}
186
187 ExtensionFunction::ResponseAction
188 CertificateProviderStopPinRequestFunction::Run() {
189 std::unique_ptr<api_cp::RequestPin::Params> params(
190 api_cp::RequestPin::Params::Create(*args_));
191 EXTENSION_FUNCTION_VALIDATE(params.get());
192
193 chromeos::CertificateProviderService* const service =
194 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
195 browser_context());
196 DCHECK(service);
197 if (params->details.error_type ==
198 api_cp::PinRequestErrorType::PIN_REQUEST_ERROR_TYPE_NONE) {
199 bool dialog_closed =
200 service->pin_dialog_manager()->CloseDialog(extension_id());
201 if (!dialog_closed) {
202 // This might happen if the user closed the dialog while extension was
203 // processing the input.
204 LOG(ERROR) << "Wrong extension requesting to close the dialog";
Devlin 2016/10/20 21:20:44 When is this error going to be used/seen? Is it a
igorcov 2016/10/25 16:38:35 It happens in case extension is calling stopPinReq
Devlin 2016/10/26 16:59:15 Errors in extension logic should result in an erro
igorcov 2016/11/04 15:51:41 Agree, good point.
205 return RespondNow(Error(kNoActiveDialog));
206 }
207
208 std::unique_ptr<base::ListValue> create_results(new base::ListValue());
209 return RespondNow(ArgumentList(std::move(create_results)));
Devlin 2016/10/20 21:20:44 RespondNow(NoArguments())
igorcov 2016/10/25 16:38:35 Done.
210 }
211
212 chromeos::RequestPinView::RequestPinErrorType error_type =
213 GetErrorTypeForView(params->details.error_type);
214 bool success = 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 if (!success) {
220 return RespondNow(Error(kNoActiveDialog));
221 }
222
223 return RespondLater();
224 }
225
226 void CertificateProviderStopPinRequestFunction::DialogClosed(
227 const base::string16& value) {
228 std::unique_ptr<base::ListValue> create_results(new base::ListValue());
229 chromeos::CertificateProviderService* const service =
230 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
231 browser_context());
232 DCHECK(service);
233
234 Respond(ArgumentList(std::move(create_results)));
Devlin 2016/10/20 21:20:44 Respond(NoArguments())
igorcov 2016/10/25 16:38:35 Done.
235 service->pin_dialog_manager()->OnPinDialogClosed();
236 }
237
238 CertificateProviderRequestPinFunction::
239 ~CertificateProviderRequestPinFunction() {}
240
241 bool CertificateProviderRequestPinFunction::ShouldSkipQuotaLimiting() const {
242 chromeos::CertificateProviderService* const service =
243 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
244 browser_context());
245 DCHECK(service);
246
247 return !service->pin_dialog_manager()->LastPinDialogClosed(extension_id());
248 }
249
250 void CertificateProviderRequestPinFunction::GetQuotaLimitHeuristics(
251 extensions::QuotaLimitHeuristics* heuristics) const {
252 QuotaLimitHeuristic::Config short_limit_config = {
253 api::certificate_provider::kMaxClosedDialogsPer10Mins,
254 base::TimeDelta::FromMinutes(1)};
255 heuristics->push_back(new QuotaService::TimedLimit(
256 short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(),
257 "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES"));
258 }
259
260 ExtensionFunction::ResponseAction CertificateProviderRequestPinFunction::Run() {
261 std::unique_ptr<api_cp::RequestPin::Params> params(
262 api_cp::RequestPin::Params::Create(*args_));
263 EXTENSION_FUNCTION_VALIDATE(params.get());
264
265 api_cp::PinRequestType pin_request_type =
266 (params->details.request_type ==
267 api_cp::PinRequestType::PIN_REQUEST_TYPE_NONE)
268 ? api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN
269 : params->details.request_type;
270
271 chromeos::RequestPinView::RequestPinErrorType error_type =
272 GetErrorTypeForView(params->details.error_type);
273
274 chromeos::RequestPinView::RequestPinCodeType code_type =
275 (pin_request_type == api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN)
276 ? chromeos::RequestPinView::RequestPinCodeType::PIN
277 : chromeos::RequestPinView::RequestPinCodeType::PUK;
278
279 chromeos::CertificateProviderService* const service =
280 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
281 browser_context());
282 DCHECK(service);
283
284 int attempts_left =
285 params->details.attempts_left ? *params->details.attempts_left.get() : -1;
Devlin 2016/10/20 21:20:44 *...get() -> *...
igorcov 2016/10/25 16:38:35 Done.
286 chromeos::PinDialogManager::RequestPinResponse result =
287 service->pin_dialog_manager()->ShowPinDialog(
288 extension()->id(), extension()->name(),
289 params->details.sign_request_id, code_type, error_type, attempts_left,
290 base::Bind(&CertificateProviderRequestPinFunction::OnInputReceived,
291 this));
292 switch (result) {
293 case chromeos::PinDialogManager::RequestPinResponse::SUCCESS:
294 return RespondLater();
295 case chromeos::PinDialogManager::RequestPinResponse::INVALID_ID:
296 return RespondNow(Error(kInvalidId));
297 case chromeos::PinDialogManager::RequestPinResponse::OTHER_FLOW_IN_PROGRESS:
298 return RespondNow(Error(kOtherFlowInProgress));
299 case chromeos::PinDialogManager::RequestPinResponse::
300 DIALOG_DISPLAYED_ALREADY:
301 return RespondNow(Error(kPreviousDialogActive));
302 }
303
304 NOTREACHED();
305 return RespondNow(Error(kPreviousDialogActive));
306 }
307
308 void CertificateProviderRequestPinFunction::OnInputReceived(
309 const base::string16& value) {
310 std::unique_ptr<base::ListValue> create_results(new base::ListValue());
311 chromeos::CertificateProviderService* const service =
312 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
313 browser_context());
314 DCHECK(service);
315 if (!value.empty()) {
316 api::certificate_provider::PinResponseDetails details;
317 details.user_input.reset(new std::string(value.begin(), value.end()));
318 create_results->Append(details.ToValue());
319 }
320
321 Respond(ArgumentList(std::move(create_results)));
Devlin 2016/10/20 21:20:44 Use the OneArgument() macro here.
igorcov 2016/10/25 16:38:35 It can be also NoArgument (if the input |value| is
322 if (!value.empty()) {
323 service->pin_dialog_manager()->OnPinDialogInput();
324 }
325 }
326
151 CertificateProviderInternalReportSignatureFunction:: 327 CertificateProviderInternalReportSignatureFunction::
152 ~CertificateProviderInternalReportSignatureFunction() {} 328 ~CertificateProviderInternalReportSignatureFunction() {}
153 329
154 ExtensionFunction::ResponseAction 330 ExtensionFunction::ResponseAction
155 CertificateProviderInternalReportSignatureFunction::Run() { 331 CertificateProviderInternalReportSignatureFunction::Run() {
156 std::unique_ptr<api_cpi::ReportSignature::Params> params( 332 std::unique_ptr<api_cpi::ReportSignature::Params> params(
157 api_cpi::ReportSignature::Params::Create(*args_)); 333 api_cpi::ReportSignature::Params::Create(*args_));
158 EXTENSION_FUNCTION_VALIDATE(params); 334 EXTENSION_FUNCTION_VALIDATE(params);
159 335
160 chromeos::CertificateProviderService* const service = 336 chromeos::CertificateProviderService* const service =
161 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( 337 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
162 browser_context()); 338 browser_context());
163 DCHECK(service); 339 DCHECK(service);
164 340
165 std::vector<uint8_t> signature; 341 std::vector<uint8_t> signature;
166 // If an error occurred, |signature| will not be set. 342 // If an error occurred, |signature| will not be set.
167 if (params->signature) 343 if (params->signature)
168 signature.assign(params->signature->begin(), params->signature->end()); 344 signature.assign(params->signature->begin(), params->signature->end());
169 345
170 service->ReplyToSignRequest(extension_id(), params->request_id, signature); 346 service->ReplyToSignRequest(extension_id(), params->request_id, signature);
171 return RespondNow(NoArguments()); 347 return RespondNow(NoArguments());
172 } 348 }
173 349
174 } // namespace extensions 350 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698