OLD | NEW |
---|---|
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 | |
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 Loading... | |
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()); | |
Devlin
2016/11/01 16:24:30
this .get() is redundant (here and below)
igorcov
2016/11/04 15:51:42
Done.
| |
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/11/01 16:24:30
As mentioned, chrome shouldn't be logging errors f
igorcov
2016/11/04 15:51:42
Done.
| |
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 bool success = service->pin_dialog_manager()->UpdatePinDialog( | |
214 extension()->id(), error_type, | |
215 false, // Don't accept any input. | |
216 base::Bind(&CertificateProviderStopPinRequestFunction::DialogClosed, | |
217 this)); | |
218 if (!success) { | |
219 return RespondNow(Error(kNoActiveDialog)); | |
Devlin
2016/11/01 16:24:30
Can't this also happen if the dialog isn't locked?
igorcov
2016/11/04 15:51:42
Yes, the extension can close the dialog even if th
Devlin
2016/11/05 06:10:59
What I mean is, can't UpdatePinDialog also return
igorcov
2016/11/22 13:50:47
You're right, I didn't notice that. Thank you.
| |
220 } | |
221 | |
222 return RespondLater(); | |
223 } | |
224 | |
225 void CertificateProviderStopPinRequestFunction::DialogClosed( | |
226 const base::string16& value) { | |
227 chromeos::CertificateProviderService* const service = | |
228 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( | |
229 browser_context()); | |
230 DCHECK(service); | |
231 | |
232 Respond(NoArguments()); | |
233 service->pin_dialog_manager()->OnPinDialogClosed(); | |
234 } | |
235 | |
236 CertificateProviderRequestPinFunction:: | |
237 ~CertificateProviderRequestPinFunction() {} | |
238 | |
239 bool CertificateProviderRequestPinFunction::ShouldSkipQuotaLimiting() const { | |
240 chromeos::CertificateProviderService* const service = | |
241 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( | |
242 browser_context()); | |
243 DCHECK(service); | |
244 | |
245 return !service->pin_dialog_manager()->LastPinDialogClosed(extension_id()); | |
246 } | |
247 | |
248 void CertificateProviderRequestPinFunction::GetQuotaLimitHeuristics( | |
249 extensions::QuotaLimitHeuristics* heuristics) const { | |
250 QuotaLimitHeuristic::Config short_limit_config = { | |
251 api::certificate_provider::kMaxClosedDialogsPer10Mins, | |
252 base::TimeDelta::FromMinutes(1)}; | |
253 heuristics->push_back(new QuotaService::TimedLimit( | |
254 short_limit_config, new QuotaLimitHeuristic::SingletonBucketMapper(), | |
255 "MAX_PIN_DIALOGS_CLOSED_PER_10_MINUTES")); | |
256 } | |
257 | |
258 ExtensionFunction::ResponseAction CertificateProviderRequestPinFunction::Run() { | |
259 std::unique_ptr<api_cp::RequestPin::Params> params( | |
260 api_cp::RequestPin::Params::Create(*args_)); | |
261 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
262 | |
263 api_cp::PinRequestType pin_request_type = | |
264 (params->details.request_type == | |
265 api_cp::PinRequestType::PIN_REQUEST_TYPE_NONE) | |
Devlin
2016/11/01 16:24:30
parens not needed
igorcov
2016/11/04 15:51:42
Done.
| |
266 ? api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN | |
267 : params->details.request_type; | |
268 | |
269 chromeos::RequestPinView::RequestPinErrorType error_type = | |
270 GetErrorTypeForView(params->details.error_type); | |
271 | |
272 chromeos::RequestPinView::RequestPinCodeType code_type = | |
273 (pin_request_type == api_cp::PinRequestType::PIN_REQUEST_TYPE_PIN) | |
274 ? chromeos::RequestPinView::RequestPinCodeType::PIN | |
275 : chromeos::RequestPinView::RequestPinCodeType::PUK; | |
276 | |
277 chromeos::CertificateProviderService* const service = | |
278 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( | |
279 browser_context()); | |
280 DCHECK(service); | |
281 | |
282 int attempts_left = | |
283 params->details.attempts_left ? *params->details.attempts_left : -1; | |
284 chromeos::PinDialogManager::RequestPinResponse result = | |
285 service->pin_dialog_manager()->ShowPinDialog( | |
286 extension()->id(), extension()->name(), | |
287 params->details.sign_request_id, code_type, error_type, attempts_left, | |
288 base::Bind(&CertificateProviderRequestPinFunction::OnInputReceived, | |
289 this)); | |
290 switch (result) { | |
291 case chromeos::PinDialogManager::RequestPinResponse::SUCCESS: | |
292 return RespondLater(); | |
293 case chromeos::PinDialogManager::RequestPinResponse::INVALID_ID: | |
294 return RespondNow(Error(kInvalidId)); | |
295 case chromeos::PinDialogManager::RequestPinResponse::OTHER_FLOW_IN_PROGRESS: | |
296 return RespondNow(Error(kOtherFlowInProgress)); | |
297 case chromeos::PinDialogManager::RequestPinResponse:: | |
298 DIALOG_DISPLAYED_ALREADY: | |
299 return RespondNow(Error(kPreviousDialogActive)); | |
300 } | |
301 | |
302 NOTREACHED(); | |
303 return RespondNow(Error(kPreviousDialogActive)); | |
304 } | |
305 | |
306 void CertificateProviderRequestPinFunction::OnInputReceived( | |
307 const base::string16& value) { | |
308 std::unique_ptr<base::ListValue> create_results(new base::ListValue()); | |
309 chromeos::CertificateProviderService* const service = | |
310 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( | |
311 browser_context()); | |
312 DCHECK(service); | |
313 if (!value.empty()) { | |
314 api::certificate_provider::PinResponseDetails details; | |
315 details.user_input.reset(new std::string(value.begin(), value.end())); | |
316 create_results->Append(details.ToValue()); | |
317 } | |
318 | |
319 Respond(ArgumentList(std::move(create_results))); | |
320 if (!value.empty()) { | |
321 service->pin_dialog_manager()->OnPinDialogInput(); | |
322 } | |
323 } | |
324 | |
151 CertificateProviderInternalReportSignatureFunction:: | 325 CertificateProviderInternalReportSignatureFunction:: |
152 ~CertificateProviderInternalReportSignatureFunction() {} | 326 ~CertificateProviderInternalReportSignatureFunction() {} |
153 | 327 |
154 ExtensionFunction::ResponseAction | 328 ExtensionFunction::ResponseAction |
155 CertificateProviderInternalReportSignatureFunction::Run() { | 329 CertificateProviderInternalReportSignatureFunction::Run() { |
156 std::unique_ptr<api_cpi::ReportSignature::Params> params( | 330 std::unique_ptr<api_cpi::ReportSignature::Params> params( |
157 api_cpi::ReportSignature::Params::Create(*args_)); | 331 api_cpi::ReportSignature::Params::Create(*args_)); |
158 EXTENSION_FUNCTION_VALIDATE(params); | 332 EXTENSION_FUNCTION_VALIDATE(params); |
159 | 333 |
160 chromeos::CertificateProviderService* const service = | 334 chromeos::CertificateProviderService* const service = |
161 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( | 335 chromeos::CertificateProviderServiceFactory::GetForBrowserContext( |
162 browser_context()); | 336 browser_context()); |
163 DCHECK(service); | 337 DCHECK(service); |
164 | 338 |
165 std::vector<uint8_t> signature; | 339 std::vector<uint8_t> signature; |
166 // If an error occurred, |signature| will not be set. | 340 // If an error occurred, |signature| will not be set. |
167 if (params->signature) | 341 if (params->signature) |
168 signature.assign(params->signature->begin(), params->signature->end()); | 342 signature.assign(params->signature->begin(), params->signature->end()); |
169 | 343 |
170 service->ReplyToSignRequest(extension_id(), params->request_id, signature); | 344 service->ReplyToSignRequest(extension_id(), params->request_id, signature); |
171 return RespondNow(NoArguments()); | 345 return RespondNow(NoArguments()); |
172 } | 346 } |
173 | 347 |
174 } // namespace extensions | 348 } // namespace extensions |
OLD | NEW |