Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/manager/pki/nsNSSDialogs.cpp
Line
Count
Source (jump to first uncovered line)
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
11
#include "nsNSSDialogs.h"
12
13
#include "mozIDOMWindow.h"
14
#include "nsArray.h"
15
#include "nsEmbedCID.h"
16
#include "nsHashPropertyBag.h"
17
#include "nsIDialogParamBlock.h"
18
#include "nsIInterfaceRequestor.h"
19
#include "nsIInterfaceRequestorUtils.h"
20
#include "nsIKeygenThread.h"
21
#include "nsIPK11Token.h"
22
#include "nsIPromptService.h"
23
#include "nsIProtectedAuthThread.h"
24
#include "nsIWindowWatcher.h"
25
#include "nsIX509CertDB.h"
26
#include "nsIX509Cert.h"
27
#include "nsNSSDialogHelper.h"
28
#include "nsPromiseFlatString.h"
29
#include "nsString.h"
30
#include "nsVariant.h"
31
32
0
#define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties"
33
34
nsNSSDialogs::nsNSSDialogs()
35
0
{
36
0
}
37
38
nsNSSDialogs::~nsNSSDialogs()
39
0
{
40
0
}
41
42
NS_IMPL_ISUPPORTS(nsNSSDialogs, nsITokenPasswordDialogs,
43
                  nsICertificateDialogs,
44
                  nsIClientAuthDialogs,
45
                  nsITokenDialogs,
46
                  nsIGeneratingKeypairInfoDialogs)
47
48
nsresult
49
nsNSSDialogs::Init()
50
0
{
51
0
  nsresult rv;
52
0
53
0
  nsCOMPtr<nsIStringBundleService> service =
54
0
           do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
55
0
  if (NS_FAILED(rv)) return rv;
56
0
57
0
  rv = service->CreateBundle(PIPSTRING_BUNDLE_URL,
58
0
                             getter_AddRefs(mPIPStringBundle));
59
0
  return rv;
60
0
}
61
62
NS_IMETHODIMP
63
nsNSSDialogs::SetPassword(nsIInterfaceRequestor* ctx,
64
                          nsIPK11Token* token,
65
                  /*out*/ bool* canceled)
66
0
{
67
0
  // |ctx| is allowed to be null.
68
0
  NS_ENSURE_ARG(canceled);
69
0
70
0
  *canceled = false;
71
0
72
0
  // Get the parent window for the dialog
73
0
  nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
74
0
75
0
  nsCOMPtr<nsIDialogParamBlock> block =
76
0
           do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
77
0
  if (!block) return NS_ERROR_FAILURE;
78
0
79
0
  nsCOMPtr<nsIMutableArray> objects = nsArrayBase::Create();
80
0
  if (!objects) {
81
0
    return NS_ERROR_FAILURE;
82
0
  }
83
0
  nsresult rv = objects->AppendElement(token);
84
0
  if (NS_FAILED(rv)) {
85
0
    return rv;
86
0
  }
87
0
  rv = block->SetObjects(objects);
88
0
  if (NS_FAILED(rv)) {
89
0
    return rv;
90
0
  }
91
0
92
0
  rv = nsNSSDialogHelper::openDialog(parent,
93
0
                                "chrome://pippki/content/changepassword.xul",
94
0
                                block);
95
0
96
0
  if (NS_FAILED(rv)) return rv;
97
0
98
0
  int32_t status;
99
0
100
0
  rv = block->GetInt(1, &status);
101
0
  if (NS_FAILED(rv)) return rv;
102
0
103
0
  *canceled = (status == 0);
104
0
105
0
  return rv;
106
0
}
107
108
NS_IMETHODIMP
109
nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor* ctx,
110
                                    nsIX509Cert* cert,
111
                            /*out*/ uint32_t* trust,
112
                            /*out*/ bool* importConfirmed)
113
0
{
114
0
  // |ctx| is allowed to be null.
115
0
  NS_ENSURE_ARG(cert);
116
0
  NS_ENSURE_ARG(trust);
117
0
  NS_ENSURE_ARG(importConfirmed);
118
0
119
0
  nsCOMPtr<nsIMutableArray> argArray = nsArrayBase::Create();
120
0
  if (!argArray) {
121
0
    return NS_ERROR_FAILURE;
122
0
  }
123
0
124
0
  nsresult rv = argArray->AppendElement(cert);
125
0
  if (NS_FAILED(rv)) {
126
0
    return rv;
127
0
  }
128
0
129
0
  nsCOMPtr<nsIWritablePropertyBag2> retVals = new nsHashPropertyBag();
130
0
  rv = argArray->AppendElement(retVals);
131
0
  if (NS_FAILED(rv)) {
132
0
    return rv;
133
0
  }
134
0
135
0
  // Get the parent window for the dialog
136
0
  nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
137
0
  rv = nsNSSDialogHelper::openDialog(parent,
138
0
                                     "chrome://pippki/content/downloadcert.xul",
139
0
                                     argArray);
140
0
  if (NS_FAILED(rv)) {
141
0
    return rv;
142
0
  }
143
0
144
0
  rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("importConfirmed"),
145
0
                                  importConfirmed);
146
0
  if (NS_FAILED(rv)) {
147
0
    return rv;
148
0
  }
149
0
150
0
  *trust = nsIX509CertDB::UNTRUSTED;
151
0
  if (!*importConfirmed) {
152
0
    return NS_OK;
153
0
  }
154
0
155
0
  bool trustForSSL = false;
156
0
  rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForSSL"),
157
0
                                  &trustForSSL);
158
0
  if (NS_FAILED(rv)) {
159
0
    return rv;
160
0
  }
161
0
  bool trustForEmail = false;
162
0
  rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForEmail"),
163
0
                                  &trustForEmail);
164
0
  if (NS_FAILED(rv)) {
165
0
    return rv;
166
0
  }
167
0
168
0
  *trust |= trustForSSL ? nsIX509CertDB::TRUSTED_SSL : 0;
169
0
  *trust |= trustForEmail ? nsIX509CertDB::TRUSTED_EMAIL : 0;
170
0
171
0
  return NS_OK;
172
0
}
173
174
NS_IMETHODIMP
175
nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx,
176
                                const nsACString& hostname,
177
                                int32_t port,
178
                                const nsACString& organization,
179
                                const nsACString& issuerOrg,
180
                                nsIArray* certList,
181
                        /*out*/ uint32_t* selectedIndex,
182
                        /*out*/ bool* certificateChosen)
183
0
{
184
0
  NS_ENSURE_ARG_POINTER(ctx);
185
0
  NS_ENSURE_ARG_POINTER(certList);
186
0
  NS_ENSURE_ARG_POINTER(selectedIndex);
187
0
  NS_ENSURE_ARG_POINTER(certificateChosen);
188
0
189
0
  *certificateChosen = false;
190
0
191
0
  nsCOMPtr<nsIMutableArray> argArray = nsArrayBase::Create();
192
0
  if (!argArray) {
193
0
    return NS_ERROR_FAILURE;
194
0
  }
195
0
196
0
  nsCOMPtr<nsIWritableVariant> hostnameVariant = new nsVariant();
197
0
  nsresult rv = hostnameVariant->SetAsAUTF8String(hostname);
198
0
  if (NS_FAILED(rv)) {
199
0
    return rv;
200
0
  }
201
0
  rv = argArray->AppendElement(hostnameVariant);
202
0
  if (NS_FAILED(rv)) {
203
0
    return rv;
204
0
  }
205
0
206
0
  nsCOMPtr<nsIWritableVariant> organizationVariant = new nsVariant();
207
0
  rv = organizationVariant->SetAsAUTF8String(organization);
208
0
  if (NS_FAILED(rv)) {
209
0
    return rv;
210
0
  }
211
0
  rv = argArray->AppendElement(organizationVariant);
212
0
  if (NS_FAILED(rv)) {
213
0
    return rv;
214
0
  }
215
0
216
0
  nsCOMPtr<nsIWritableVariant> issuerOrgVariant = new nsVariant();
217
0
  rv = issuerOrgVariant->SetAsAUTF8String(issuerOrg);
218
0
  if (NS_FAILED(rv)) {
219
0
    return rv;
220
0
  }
221
0
  rv = argArray->AppendElement(issuerOrgVariant);
222
0
  if (NS_FAILED(rv)) {
223
0
    return rv;
224
0
  }
225
0
226
0
  nsCOMPtr<nsIWritableVariant> portVariant = new nsVariant();
227
0
  rv = portVariant->SetAsInt32(port);
228
0
  if (NS_FAILED(rv)) {
229
0
    return rv;
230
0
  }
231
0
  rv = argArray->AppendElement(portVariant);
232
0
  if (NS_FAILED(rv)) {
233
0
    return rv;
234
0
  }
235
0
236
0
  rv = argArray->AppendElement(certList);
237
0
  if (NS_FAILED(rv)) {
238
0
    return rv;
239
0
  }
240
0
241
0
  nsCOMPtr<nsIWritablePropertyBag2> retVals = new nsHashPropertyBag();
242
0
  rv = argArray->AppendElement(retVals);
243
0
  if (NS_FAILED(rv)) {
244
0
    return rv;
245
0
  }
246
0
247
0
  rv = nsNSSDialogHelper::openDialog(nullptr,
248
0
                                     "chrome://pippki/content/clientauthask.xul",
249
0
                                     argArray);
250
0
  if (NS_FAILED(rv)) {
251
0
    return rv;
252
0
  }
253
0
254
0
  nsCOMPtr<nsIClientAuthUserDecision> extraResult = do_QueryInterface(ctx);
255
0
  if (extraResult) {
256
0
    bool rememberSelection = false;
257
0
    rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("rememberSelection"),
258
0
                                    &rememberSelection);
259
0
    if (NS_SUCCEEDED(rv)) {
260
0
      extraResult->SetRememberClientAuthCertificate(rememberSelection);
261
0
    }
262
0
  }
263
0
264
0
  rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("certChosen"),
265
0
                                  certificateChosen);
266
0
  if (NS_FAILED(rv)) {
267
0
    return rv;
268
0
  }
269
0
  if (*certificateChosen) {
270
0
    rv = retVals->GetPropertyAsUint32(NS_LITERAL_STRING("selectedIndex"),
271
0
                                      selectedIndex);
272
0
    if (NS_FAILED(rv)) {
273
0
      return rv;
274
0
    }
275
0
  }
276
0
277
0
  return NS_OK;
278
0
}
279
280
NS_IMETHODIMP
281
nsNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor* ctx,
282
                            /*out*/ nsAString& password,
283
                            /*out*/ bool* confirmedPassword)
284
0
{
285
0
  // |ctx| is allowed to be null.
286
0
  NS_ENSURE_ARG(confirmedPassword);
287
0
288
0
  // Get the parent window for the dialog
289
0
  nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
290
0
  nsCOMPtr<nsIWritablePropertyBag2> retVals = new nsHashPropertyBag();
291
0
  nsresult rv =
292
0
    nsNSSDialogHelper::openDialog(parent,
293
0
                                  "chrome://pippki/content/setp12password.xul",
294
0
                                  retVals);
295
0
  if (NS_FAILED(rv)) {
296
0
    return rv;
297
0
  }
298
0
299
0
  rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("confirmedPassword"),
300
0
                                  confirmedPassword);
301
0
  if (NS_FAILED(rv)) {
302
0
    return rv;
303
0
  }
304
0
305
0
  if (!*confirmedPassword) {
306
0
    return NS_OK;
307
0
  }
308
0
309
0
  return retVals->GetPropertyAsAString(NS_LITERAL_STRING("password"), password);
310
0
}
311
312
NS_IMETHODIMP
313
nsNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor* ctx,
314
                                    nsAString& _password,
315
                                    bool* _retval)
316
0
{
317
0
  *_retval = false;
318
0
319
0
  nsCOMPtr<nsIPromptService> promptSvc(
320
0
    do_GetService(NS_PROMPTSERVICE_CONTRACTID));
321
0
  if (!promptSvc) {
322
0
    return NS_ERROR_FAILURE;
323
0
  }
324
0
325
0
  nsAutoString msg;
326
0
  nsresult rv = mPIPStringBundle->GetStringFromName(
327
0
    "getPKCS12FilePasswordMessage", msg);
328
0
  if (NS_FAILED(rv)) {
329
0
    return rv;
330
0
  }
331
0
332
0
  // Get the parent window for the dialog
333
0
  nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
334
0
  bool ignored = false;
335
0
  char16_t* pwTemp = nullptr;
336
0
  rv = promptSvc->PromptPassword(parent, nullptr, msg.get(), &pwTemp, nullptr,
337
0
                                 &ignored, _retval);
338
0
  if (NS_FAILED(rv)) {
339
0
    return rv;
340
0
  }
341
0
342
0
  if (*_retval) {
343
0
    _password.Assign(pwTemp);
344
0
    free(pwTemp);
345
0
  }
346
0
347
0
  return NS_OK;
348
0
}
349
350
NS_IMETHODIMP
351
nsNSSDialogs::DisplayGeneratingKeypairInfo(nsIInterfaceRequestor *aCtx, nsIKeygenThread *runnable)
352
0
{
353
0
  nsresult rv;
354
0
355
0
  // Get the parent window for the dialog
356
0
  nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(aCtx);
357
0
358
0
  rv = nsNSSDialogHelper::openDialog(parent,
359
0
                                     "chrome://pippki/content/createCertInfo.xul",
360
0
                                     runnable);
361
0
  return rv;
362
0
}
363
364
NS_IMETHODIMP
365
nsNSSDialogs::ChooseToken(nsIInterfaceRequestor* /*aCtx*/,
366
                          const char16_t** aTokenList,
367
                          uint32_t aCount,
368
                  /*out*/ nsAString& aTokenChosen,
369
                  /*out*/ bool* aCanceled)
370
0
{
371
0
  NS_ENSURE_ARG(aTokenList);
372
0
  NS_ENSURE_ARG(aCanceled);
373
0
374
0
  *aCanceled = false;
375
0
376
0
  nsCOMPtr<nsIDialogParamBlock> block =
377
0
           do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
378
0
  if (!block) return NS_ERROR_FAILURE;
379
0
380
0
  block->SetNumberStrings(aCount);
381
0
382
0
  nsresult rv;
383
0
  for (uint32_t i = 0; i < aCount; i++) {
384
0
    rv = block->SetString(i, aTokenList[i]);
385
0
    if (NS_FAILED(rv)) return rv;
386
0
  }
387
0
388
0
  rv = block->SetInt(0, aCount);
389
0
  if (NS_FAILED(rv)) return rv;
390
0
391
0
  rv = nsNSSDialogHelper::openDialog(nullptr,
392
0
                                "chrome://pippki/content/choosetoken.xul",
393
0
                                block);
394
0
  if (NS_FAILED(rv)) return rv;
395
0
396
0
  int32_t status;
397
0
398
0
  rv = block->GetInt(0, &status);
399
0
  if (NS_FAILED(rv)) return rv;
400
0
401
0
  *aCanceled = (status == 0);
402
0
  if (!*aCanceled) {
403
0
    // retrieve the nickname
404
0
    rv = block->GetString(0, getter_Copies(aTokenChosen));
405
0
  }
406
0
  return rv;
407
0
}
408
409
NS_IMETHODIMP
410
nsNSSDialogs::DisplayProtectedAuth(nsIInterfaceRequestor *aCtx, nsIProtectedAuthThread *runnable)
411
0
{
412
0
    // We cannot use nsNSSDialogHelper here. We cannot allow close widget
413
0
    // in the window because protected authentication is interruptible
414
0
    // from user interface and changing nsNSSDialogHelper's static variable
415
0
    // would not be thread-safe
416
0
417
0
    nsresult rv = NS_ERROR_FAILURE;
418
0
419
0
    // Get the parent window for the dialog
420
0
    nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(aCtx);
421
0
422
0
    nsCOMPtr<nsIWindowWatcher> windowWatcher =
423
0
        do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv);
424
0
    if (NS_FAILED(rv))
425
0
        return rv;
426
0
427
0
    if (!parent) {
428
0
        windowWatcher->GetActiveWindow(getter_AddRefs(parent));
429
0
    }
430
0
431
0
    nsCOMPtr<mozIDOMWindowProxy> newWindow;
432
0
    rv = windowWatcher->OpenWindow(parent,
433
0
        "chrome://pippki/content/protectedAuth.xul",
434
0
        "_blank",
435
0
        "centerscreen,chrome,modal,titlebar,close=no",
436
0
        runnable,
437
0
        getter_AddRefs(newWindow));
438
0
439
0
    return rv;
440
0
}