security/manager/pki/src/nsNSSDialogs.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:3b6154dc20c1
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /*
8 * Dialog services for PIP.
9 */
10 #include "nsCOMPtr.h"
11 #include "nsString.h"
12 #include "nsXPIDLString.h"
13 #include "nsReadableUtils.h"
14 #include "nsIDOMWindow.h"
15 #include "nsIDialogParamBlock.h"
16 #include "nsIComponentManager.h"
17 #include "nsIServiceManager.h"
18 #include "nsIStringBundle.h"
19 #include "nsIInterfaceRequestor.h"
20 #include "nsIInterfaceRequestorUtils.h"
21 #include "nsIX509Cert.h"
22 #include "nsIX509CertDB.h"
23 #include "nsIDateTimeFormat.h"
24 #include "nsDateTimeFormatCID.h"
25 #include "nsPromiseFlatString.h"
26
27 #include "nsNSSDialogs.h"
28 #include "nsPKIParamBlock.h"
29 #include "nsIKeygenThread.h"
30 #include "nsIProtectedAuthThread.h"
31 #include "nsNSSDialogHelper.h"
32 #include "nsIWindowWatcher.h"
33 #include "nsIX509CertValidity.h"
34
35 #include "nsEmbedCID.h"
36 #include "nsIPromptService.h"
37
38 #define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties"
39
40 /* ==== */
41
42 nsNSSDialogs::nsNSSDialogs()
43 {
44 }
45
46 nsNSSDialogs::~nsNSSDialogs()
47 {
48 }
49
50 NS_IMPL_ISUPPORTS(nsNSSDialogs, nsITokenPasswordDialogs,
51 nsICertificateDialogs,
52 nsIClientAuthDialogs,
53 nsICertPickDialogs,
54 nsITokenDialogs,
55 nsIDOMCryptoDialogs,
56 nsIGeneratingKeypairInfoDialogs,
57 nsISSLCertErrorDialog)
58
59 nsresult
60 nsNSSDialogs::Init()
61 {
62 nsresult rv;
63
64 nsCOMPtr<nsIStringBundleService> service =
65 do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
66 if (NS_FAILED(rv)) return rv;
67
68 rv = service->CreateBundle(PIPSTRING_BUNDLE_URL,
69 getter_AddRefs(mPIPStringBundle));
70 return rv;
71 }
72
73 nsresult
74 nsNSSDialogs::SetPassword(nsIInterfaceRequestor *ctx,
75 const char16_t *tokenName, bool* _canceled)
76 {
77 nsresult rv;
78
79 *_canceled = false;
80
81 // Get the parent window for the dialog
82 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
83
84 nsCOMPtr<nsIDialogParamBlock> block =
85 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
86 if (!block) return NS_ERROR_FAILURE;
87
88 // void ChangePassword(in wstring tokenName, out int status);
89 rv = block->SetString(1, tokenName);
90 if (NS_FAILED(rv)) return rv;
91
92 rv = nsNSSDialogHelper::openDialog(parent,
93 "chrome://pippki/content/changepassword.xul",
94 block);
95
96 if (NS_FAILED(rv)) return rv;
97
98 int32_t status;
99
100 rv = block->GetInt(1, &status);
101 if (NS_FAILED(rv)) return rv;
102
103 *_canceled = (status == 0)?true:false;
104
105 return rv;
106 }
107
108 nsresult
109 nsNSSDialogs::GetPassword(nsIInterfaceRequestor *ctx,
110 const char16_t *tokenName,
111 char16_t **_password,
112 bool* _canceled)
113 {
114 nsresult rv;
115 *_canceled = false;
116 // Get the parent window for the dialog
117 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
118 nsCOMPtr<nsIDialogParamBlock> block =
119 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
120 if (!block) return NS_ERROR_FAILURE;
121 // Set the token name in the window
122 rv = block->SetString(1, tokenName);
123 if (NS_FAILED(rv)) return rv;
124 // open up the window
125 rv = nsNSSDialogHelper::openDialog(parent,
126 "chrome://pippki/content/getpassword.xul",
127 block);
128 if (NS_FAILED(rv)) return rv;
129 // see if user canceled
130 int32_t status;
131 rv = block->GetInt(1, &status);
132 if (NS_FAILED(rv)) return rv;
133 *_canceled = (status == 0) ? true : false;
134 if (!*_canceled) {
135 // retrieve the password
136 rv = block->GetString(2, _password);
137 }
138 return rv;
139 }
140
141 NS_IMETHODIMP
142 nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx,
143 nsIX509Cert *cert,
144 uint32_t *_trust,
145 bool *_retval)
146 {
147 nsresult rv;
148
149 *_retval = true;
150
151 // Get the parent window for the dialog
152 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
153
154 nsCOMPtr<nsIPKIParamBlock> block =
155 do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
156 if (!block)
157 return NS_ERROR_FAILURE;
158
159 rv = block->SetISupportAtIndex(1, cert);
160 if (NS_FAILED(rv))
161 return rv;
162
163 rv = nsNSSDialogHelper::openDialog(parent,
164 "chrome://pippki/content/downloadcert.xul",
165 block);
166 if (NS_FAILED(rv)) return rv;
167
168 int32_t status;
169 int32_t ssl, email, objsign;
170
171 nsCOMPtr<nsIDialogParamBlock> dlgParamBlock = do_QueryInterface(block);
172
173 rv = dlgParamBlock->GetInt(1, &status);
174 if (NS_FAILED(rv)) return rv;
175 rv = dlgParamBlock->GetInt(2, &ssl);
176 if (NS_FAILED(rv)) return rv;
177 rv = dlgParamBlock->GetInt(3, &email);
178 if (NS_FAILED(rv)) return rv;
179 rv = dlgParamBlock->GetInt(4, &objsign);
180 if (NS_FAILED(rv)) return rv;
181
182 *_trust = nsIX509CertDB::UNTRUSTED;
183 *_trust |= (ssl) ? nsIX509CertDB::TRUSTED_SSL : 0;
184 *_trust |= (email) ? nsIX509CertDB::TRUSTED_EMAIL : 0;
185 *_trust |= (objsign) ? nsIX509CertDB::TRUSTED_OBJSIGN : 0;
186
187 *_retval = (status == 0)?false:true;
188
189 return rv;
190 }
191
192
193 NS_IMETHODIMP
194 nsNSSDialogs::NotifyCACertExists(nsIInterfaceRequestor *ctx)
195 {
196 nsresult rv;
197
198 nsCOMPtr<nsIPromptService> promptSvc(do_GetService(NS_PROMPTSERVICE_CONTRACTID));
199 if (!promptSvc)
200 return NS_ERROR_FAILURE;
201
202 // Get the parent window for the dialog
203 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
204
205 nsAutoString title;
206 rv = mPIPStringBundle->GetStringFromName(MOZ_UTF16("caCertExistsTitle"),
207 getter_Copies(title));
208 NS_ENSURE_SUCCESS(rv, rv);
209
210 nsAutoString msg;
211 rv = mPIPStringBundle->GetStringFromName(MOZ_UTF16("caCertExistsMessage"),
212 getter_Copies(msg));
213 NS_ENSURE_SUCCESS(rv, rv);
214
215 rv = promptSvc->Alert(parent, title.get(), msg.get());
216
217 return rv;
218 }
219
220
221 NS_IMETHODIMP
222 nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor *ctx, const char16_t *cn, const char16_t *organization, const char16_t *issuer, const char16_t **certNickList, const char16_t **certDetailsList, uint32_t count, int32_t *selectedIndex, bool *canceled)
223 {
224 nsresult rv;
225 uint32_t i;
226
227 *canceled = false;
228
229 // Get the parent window for the dialog
230 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
231
232 nsCOMPtr<nsIDialogParamBlock> block =
233 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
234 if (!block) return NS_ERROR_FAILURE;
235
236 block->SetNumberStrings(4+count*2);
237
238 rv = block->SetString(0, cn);
239 if (NS_FAILED(rv)) return rv;
240
241 rv = block->SetString(1, organization);
242 if (NS_FAILED(rv)) return rv;
243
244 rv = block->SetString(2, issuer);
245 if (NS_FAILED(rv)) return rv;
246
247 for (i = 0; i < count; i++) {
248 rv = block->SetString(i+3, certNickList[i]);
249 if (NS_FAILED(rv)) return rv;
250 }
251
252 for (i = 0; i < count; i++) {
253 rv = block->SetString(i+count+3, certDetailsList[i]);
254 if (NS_FAILED(rv)) return rv;
255 }
256
257 rv = block->SetInt(0, count);
258 if (NS_FAILED(rv)) return rv;
259
260 rv = nsNSSDialogHelper::openDialog(nullptr,
261 "chrome://pippki/content/clientauthask.xul",
262 block);
263 if (NS_FAILED(rv)) return rv;
264
265 int32_t status;
266 rv = block->GetInt(0, &status);
267 if (NS_FAILED(rv)) return rv;
268
269 nsCOMPtr<nsIClientAuthUserDecision> extraResult = do_QueryInterface(ctx);
270 if (extraResult) {
271 int32_t rememberSelection;
272 rv = block->GetInt(2, &rememberSelection);
273 if (NS_SUCCEEDED(rv)) {
274 extraResult->SetRememberClientAuthCertificate(rememberSelection!=0);
275 }
276 }
277
278 *canceled = (status == 0)?true:false;
279 if (!*canceled) {
280 // retrieve the nickname
281 rv = block->GetInt(1, selectedIndex);
282 }
283 return rv;
284 }
285
286
287 NS_IMETHODIMP
288 nsNSSDialogs::PickCertificate(nsIInterfaceRequestor *ctx,
289 const char16_t **certNickList,
290 const char16_t **certDetailsList,
291 uint32_t count,
292 int32_t *selectedIndex,
293 bool *canceled)
294 {
295 nsresult rv;
296 uint32_t i;
297
298 *canceled = false;
299
300 // Get the parent window for the dialog
301 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
302
303 nsCOMPtr<nsIDialogParamBlock> block =
304 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
305 if (!block) return NS_ERROR_FAILURE;
306
307 block->SetNumberStrings(1+count*2);
308
309 for (i = 0; i < count; i++) {
310 rv = block->SetString(i, certNickList[i]);
311 if (NS_FAILED(rv)) return rv;
312 }
313
314 for (i = 0; i < count; i++) {
315 rv = block->SetString(i+count, certDetailsList[i]);
316 if (NS_FAILED(rv)) return rv;
317 }
318
319 rv = block->SetInt(0, count);
320 if (NS_FAILED(rv)) return rv;
321
322 rv = block->SetInt(1, *selectedIndex);
323 if (NS_FAILED(rv)) return rv;
324
325 rv = nsNSSDialogHelper::openDialog(nullptr,
326 "chrome://pippki/content/certpicker.xul",
327 block);
328 if (NS_FAILED(rv)) return rv;
329
330 int32_t status;
331
332 rv = block->GetInt(0, &status);
333 if (NS_FAILED(rv)) return rv;
334
335 *canceled = (status == 0)?true:false;
336 if (!*canceled) {
337 rv = block->GetInt(1, selectedIndex);
338 }
339 return rv;
340 }
341
342
343 NS_IMETHODIMP
344 nsNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor *ctx,
345 nsAString &_password,
346 bool *_retval)
347 {
348 nsresult rv;
349 *_retval = true;
350 // Get the parent window for the dialog
351 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
352 nsCOMPtr<nsIDialogParamBlock> block =
353 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
354 if (!block) return NS_ERROR_FAILURE;
355 // open up the window
356 rv = nsNSSDialogHelper::openDialog(parent,
357 "chrome://pippki/content/setp12password.xul",
358 block);
359 if (NS_FAILED(rv)) return rv;
360 // see if user canceled
361 int32_t status;
362 rv = block->GetInt(1, &status);
363 if (NS_FAILED(rv)) return rv;
364 *_retval = (status == 0) ? false : true;
365 if (*_retval) {
366 // retrieve the password
367 char16_t *pw;
368 rv = block->GetString(2, &pw);
369 if (NS_SUCCEEDED(rv)) {
370 _password = pw;
371 nsMemory::Free(pw);
372 }
373 }
374 return rv;
375 }
376
377 NS_IMETHODIMP
378 nsNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor *ctx,
379 nsAString &_password,
380 bool *_retval)
381 {
382 nsresult rv;
383 *_retval = true;
384 // Get the parent window for the dialog
385 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
386 nsCOMPtr<nsIDialogParamBlock> block =
387 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
388 if (!block) return NS_ERROR_FAILURE;
389 // open up the window
390 rv = nsNSSDialogHelper::openDialog(parent,
391 "chrome://pippki/content/getp12password.xul",
392 block);
393 if (NS_FAILED(rv)) return rv;
394 // see if user canceled
395 int32_t status;
396 rv = block->GetInt(1, &status);
397 if (NS_FAILED(rv)) return rv;
398 *_retval = (status == 0) ? false : true;
399 if (*_retval) {
400 // retrieve the password
401 char16_t *pw;
402 rv = block->GetString(2, &pw);
403 if (NS_SUCCEEDED(rv)) {
404 _password = pw;
405 nsMemory::Free(pw);
406 }
407 }
408 return rv;
409 }
410
411 /* void viewCert (in nsIX509Cert cert); */
412 NS_IMETHODIMP
413 nsNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx,
414 nsIX509Cert *cert)
415 {
416 nsresult rv;
417
418 nsCOMPtr<nsIPKIParamBlock> block =
419 do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
420 if (!block)
421 return NS_ERROR_FAILURE;
422
423 rv = block->SetISupportAtIndex(1, cert);
424 if (NS_FAILED(rv))
425 return rv;
426
427 // Get the parent window for the dialog
428 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
429
430 rv = nsNSSDialogHelper::openDialog(parent,
431 "chrome://pippki/content/certViewer.xul",
432 block,
433 false);
434 return rv;
435 }
436
437 NS_IMETHODIMP
438 nsNSSDialogs::DisplayGeneratingKeypairInfo(nsIInterfaceRequestor *aCtx, nsIKeygenThread *runnable)
439 {
440 nsresult rv;
441
442 // Get the parent window for the dialog
443 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(aCtx);
444
445 rv = nsNSSDialogHelper::openDialog(parent,
446 "chrome://pippki/content/createCertInfo.xul",
447 runnable);
448 return rv;
449 }
450
451 NS_IMETHODIMP
452 nsNSSDialogs::ChooseToken(nsIInterfaceRequestor *aCtx, const char16_t **aTokenList, uint32_t aCount, char16_t **aTokenChosen, bool *aCanceled) {
453 nsresult rv;
454 uint32_t i;
455
456 *aCanceled = false;
457
458 // Get the parent window for the dialog
459 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(aCtx);
460
461 nsCOMPtr<nsIDialogParamBlock> block =
462 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
463 if (!block) return NS_ERROR_FAILURE;
464
465 block->SetNumberStrings(aCount);
466
467 for (i = 0; i < aCount; i++) {
468 rv = block->SetString(i, aTokenList[i]);
469 if (NS_FAILED(rv)) return rv;
470 }
471
472 rv = block->SetInt(0, aCount);
473 if (NS_FAILED(rv)) return rv;
474
475 rv = nsNSSDialogHelper::openDialog(nullptr,
476 "chrome://pippki/content/choosetoken.xul",
477 block);
478 if (NS_FAILED(rv)) return rv;
479
480 int32_t status;
481
482 rv = block->GetInt(0, &status);
483 if (NS_FAILED(rv)) return rv;
484
485 *aCanceled = (status == 0)?true:false;
486 if (!*aCanceled) {
487 // retrieve the nickname
488 rv = block->GetString(0, aTokenChosen);
489 }
490 return rv;
491 }
492
493 /* boolean ConfirmKeyEscrow (in nsIX509Cert escrowAuthority); */
494 NS_IMETHODIMP
495 nsNSSDialogs::ConfirmKeyEscrow(nsIX509Cert *escrowAuthority, bool *_retval)
496
497 {
498 *_retval = false;
499
500 nsresult rv;
501
502 nsCOMPtr<nsIPKIParamBlock> block =
503 do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
504 if (!block)
505 return NS_ERROR_FAILURE;
506
507 rv = block->SetISupportAtIndex(1, escrowAuthority);
508 if (NS_FAILED(rv))
509 return rv;
510
511 rv = nsNSSDialogHelper::openDialog(nullptr,
512 "chrome://pippki/content/escrowWarn.xul",
513 block);
514
515 if (NS_FAILED(rv))
516 return rv;
517
518 int32_t status=0;
519 nsCOMPtr<nsIDialogParamBlock> dlgParamBlock = do_QueryInterface(block);
520 rv = dlgParamBlock->GetInt(1, &status);
521
522 if (status) {
523 *_retval = true;
524 }
525 return rv;
526 }
527
528 NS_IMETHODIMP
529 nsNSSDialogs::DisplayProtectedAuth(nsIInterfaceRequestor *aCtx, nsIProtectedAuthThread *runnable)
530 {
531 // We cannot use nsNSSDialogHelper here. We cannot allow close widget
532 // in the window because protected authentication is interruptible
533 // from user interface and changing nsNSSDialogHelper's static variable
534 // would not be thread-safe
535
536 nsresult rv = NS_ERROR_FAILURE;
537
538 // Get the parent window for the dialog
539 nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(aCtx);
540
541 nsCOMPtr<nsIWindowWatcher> windowWatcher =
542 do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv);
543 if (NS_FAILED(rv))
544 return rv;
545
546 if (!parent) {
547 windowWatcher->GetActiveWindow(getter_AddRefs(parent));
548 }
549
550 nsCOMPtr<nsIDOMWindow> newWindow;
551 rv = windowWatcher->OpenWindow(parent,
552 "chrome://pippki/content/protectedAuth.xul",
553 "_blank",
554 "centerscreen,chrome,modal,titlebar,close=no",
555 runnable,
556 getter_AddRefs(newWindow));
557
558 return rv;
559 }
560
561 NS_IMETHODIMP
562 nsNSSDialogs::ShowCertError(nsIInterfaceRequestor *ctx,
563 nsISSLStatus *status,
564 nsIX509Cert *cert,
565 const nsAString & textErrorMessage,
566 const nsAString & htmlErrorMessage,
567 const nsACString & hostName,
568 uint32_t portNumber)
569 {
570 nsCOMPtr<nsIPKIParamBlock> block =
571 do_CreateInstance(NS_PKIPARAMBLOCK_CONTRACTID);
572 if (!block)
573 return NS_ERROR_OUT_OF_MEMORY;
574
575 nsCOMPtr<nsIDialogParamBlock> dialogBlock = do_QueryInterface(block);
576
577 nsresult rv;
578 rv = dialogBlock->SetInt(1, portNumber);
579 if (NS_FAILED(rv))
580 return rv;
581
582 rv = dialogBlock->SetString(1, NS_ConvertUTF8toUTF16(hostName).get());
583 if (NS_FAILED(rv))
584 return rv;
585
586 rv = dialogBlock->SetString(2, PromiseFlatString(textErrorMessage).get());
587 if (NS_FAILED(rv))
588 return rv;
589
590 rv = block->SetISupportAtIndex(1, cert);
591 if (NS_FAILED(rv))
592 return rv;
593
594 rv = nsNSSDialogHelper::openDialog(nullptr,
595 "chrome://pippki/content/certerror.xul",
596 block);
597 return rv;
598 }

mercurial