summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js
blob: cbd59f883a375416a41f48404a602a74423a6509 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
"use strict";

// Tests that the cert download/import UI correctly identifies the cert being
// downloaded, and allows the trust of the cert to be specified.

const { MockRegistrar } =
  Cu.import("resource://testing-common/MockRegistrar.jsm", {});

/**
 * @typedef {TestCase}
 * @type Object
 * @property {String} certFilename
 *           Filename of the cert for this test case.
 * @property {String} expectedDisplayString
 *           The string we expect the UI to display to represent the given cert.
 * @property {nsIX509Cert} cert
 *           Handle to the cert once read in setup().
 */

/**
 * A list of test cases representing certs that get "downloaded".
 * @type TestCase[]
 */
const TEST_CASES = [
  { certFilename: "has-cn.pem",
    expectedDisplayString: "Foo",
    cert: null },
  { certFilename: "has-empty-subject.pem",
    expectedDisplayString: "Certificate Authority (unnamed)",
    cert: null },
];

/**
 * Opens the cert download dialog.
 *
 * @param {nsIX509Cert} cert
 *        The cert to pass to the dialog for display.
 * @returns {Promise}
 *          A promise that resolves when the dialog has finished loading, with
 *          an array consisting of:
 *            1. The window of the opened dialog.
 *            2. The return value nsIWritablePropertyBag2 passed to the dialog.
 */
function openCertDownloadDialog(cert) {
  let returnVals = Cc["@mozilla.org/hash-property-bag;1"]
                     .createInstance(Ci.nsIWritablePropertyBag2);
  let win = window.openDialog("chrome://pippki/content/downloadcert.xul", "",
                              "", cert, returnVals);
  return new Promise((resolve, reject) => {
    win.addEventListener("load", function onLoad() {
      win.removeEventListener("load", onLoad);
      resolve([win, returnVals]);
    });
  });
}

// Mock implementation of nsICertificateDialogs.
const gCertificateDialogs = {
  expectedCert: null,
  viewCertCallCount: 0,
  confirmDownloadCACert(ctx, cert, trust) {
    Assert.ok(false, "confirmDownloadCACert() should not have been called");
  },
  setPKCS12FilePassword(ctx, password) {
    Assert.ok(false, "setPKCS12FilePassword() should not have been called");
  },
  getPKCS12FilePassword(ctx, password) {
    Assert.ok(false, "getPKCS12FilePassword() should not have been called");
  },
  viewCert(ctx, cert) {
    this.viewCertCallCount++;
    Assert.notEqual(cert, null, "Cert to view should not be null");
    Assert.equal(cert, this.expectedCert,
                 "Actual and expected cert should match");
  },

  QueryInterface: XPCOMUtils.generateQI([Ci.nsICertificateDialogs])
};

add_task(function* setup() {
  for (let testCase of TEST_CASES) {
    testCase.cert = yield readCertificate(testCase.certFilename, ",,");
    Assert.notEqual(testCase.cert, null,
                    `'${testCase.certFilename}' should have been read`);
  }

  let certificateDialogsCID =
    MockRegistrar.register("@mozilla.org/nsCertificateDialogs;1",
                           gCertificateDialogs);
  registerCleanupFunction(() => {
    MockRegistrar.unregister(certificateDialogsCID);
  });
});

// Test that the trust header message corresponds to the provided cert, and that
// the View Cert button launches the cert viewer for the provided cert.
add_task(function* testTrustHeaderAndViewCertButton() {
  for (let testCase of TEST_CASES) {
    let [win, retVals] = yield openCertDownloadDialog(testCase.cert);
    let expectedTrustHeaderString =
      `Do you want to trust \u201C${testCase.expectedDisplayString}\u201D ` +
      "for the following purposes?";
    Assert.equal(win.document.getElementById("trustHeader").textContent,
                 expectedTrustHeaderString,
                 "Actual and expected trust header text should match for " +
                 `${testCase.certFilename}`);

    gCertificateDialogs.viewCertCallCount = 0;
    gCertificateDialogs.expectedCert = testCase.cert;
    info("Pressing View Cert button");
    win.document.getElementById("viewC-button").doCommand();
    Assert.equal(gCertificateDialogs.viewCertCallCount, 1,
                 "viewCert() should've been called once");

    yield BrowserTestUtils.closeWindow(win);
  }
});

// Test that the right values are returned when the dialog is accepted.
add_task(function* testAcceptDialogReturnValues() {
  let [win, retVals] = yield openCertDownloadDialog(TEST_CASES[0].cert);
  win.document.getElementById("trustSSL").checked = true;
  win.document.getElementById("trustEmail").checked = false;
  win.document.getElementById("trustObjSign").checked = true;
  info("Accepting dialog");
  win.document.getElementById("download_cert").acceptDialog();
  yield BrowserTestUtils.windowClosed(win);

  Assert.ok(retVals.get("importConfirmed"),
            "Return value should signal user chose to import the cert");
  Assert.ok(retVals.get("trustForSSL"),
            "Return value should signal SSL trust checkbox was checked");
  Assert.ok(!retVals.get("trustForEmail"),
            "Return value should signal E-mail trust checkbox was unchecked");
  Assert.ok(retVals.get("trustForObjSign"),
            "Return value should signal Obj Sign trust checkbox was checked");
});

// Test that the right values are returned when the dialog is canceled.
add_task(function* testCancelDialogReturnValues() {
  let [win, retVals] = yield openCertDownloadDialog(TEST_CASES[0].cert);
  info("Canceling dialog");
  win.document.getElementById("download_cert").cancelDialog();
  yield BrowserTestUtils.windowClosed(win);

  Assert.ok(!retVals.get("importConfirmed"),
            "Return value should signal user chose not to import the cert");
});