summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js
blob: d28c61b7f2bbfd489545905bfb1155a257fda05d (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
"use strict";

// Tests that the client authentication certificate chooser correctly displays
// provided information and correctly returns user input.

const TEST_HOSTNAME = "Test Hostname";
const TEST_ORG = "Test Org";
const TEST_ISSUER_ORG = "Test Issuer Org";
const TEST_PORT = 123;

var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
  Ci.nsIX509CertDB
);
/**
 * Test certificate (i.e. build/pgo/certs/mochitest.client).
 *
 * @type {nsIX509Cert}
 */
var cert;

/**
 * Opens the client auth cert chooser 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 openClientAuthDialog(cert) {
  let certList = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
  certList.appendElement(cert);

  let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
    Ci.nsIWritablePropertyBag2
  );
  let win = window.openDialog(
    "chrome://pippki/content/clientauthask.xhtml",
    "",
    "",
    TEST_HOSTNAME,
    TEST_ORG,
    TEST_ISSUER_ORG,
    TEST_PORT,
    certList,
    returnVals
  );
  return TestUtils.topicObserved("cert-dialog-loaded").then(() => [
    win,
    returnVals,
  ]);
}

/**
 * Checks that the contents of the given cert chooser dialog match the details
 * of build/pgo/certs/mochitest.client.
 *
 * @param {window} win The cert chooser window.
 * @param {string} notBefore
 *        The formatted notBefore date of mochitest.client.
 * @param {string} notAfter
 *        The formatted notAfter date of mochitest.client.
 */
function checkDialogContents(win, notBefore, notAfter) {
  is(
    win.document.getElementById("hostname").textContent,
    `${TEST_HOSTNAME}:${TEST_PORT}`,
    "Actual and expected hostname and port should be equal"
  );
  is(
    win.document.getElementById("organization").textContent,
    `Organization: “${TEST_ORG}”`,
    "Actual and expected organization should be equal"
  );
  is(
    win.document.getElementById("issuer").textContent,
    `Issued Under: “${TEST_ISSUER_ORG}”`,
    "Actual and expected issuer organization should be equal"
  );

  is(
    win.document.getElementById("nicknames").label,
    "Mochitest client [03]",
    "Actual and expected selected cert nickname and serial should be equal"
  );
  is(
    win.document.getElementById("nicknames").itemCount,
    1,
    "correct number of items"
  );

  let [
    subject,
    serialNum,
    validity,
    issuer,
    tokenName,
  ] = win.document.getElementById("details").value.split("\n");
  is(
    subject,
    "Issued to: CN=Mochitest client",
    "Actual and expected subject should be equal"
  );
  is(
    serialNum,
    "Serial number: 03",
    "Actual and expected serial number should be equal"
  );
  is(
    validity,
    `Valid from ${notBefore} to ${notAfter}`,
    "Actual and expected validity should be equal"
  );
  is(
    issuer,
    "Issued by: OU=Profile Guided Optimization,O=Mozilla Testing,CN=Temporary Certificate Authority",
    "Actual and expected issuer should be equal"
  );
  is(
    tokenName,
    "Stored on: Software Security Device",
    "Actual and expected token name should be equal"
  );
}

function findCertByCommonName(commonName) {
  for (let cert of certDB.getCerts()) {
    if (cert.commonName == commonName) {
      return cert;
    }
  }
  return null;
}

add_setup(async function() {
  cert = findCertByCommonName("Mochitest client");
  isnot(cert, null, "Should be able to find the test client cert");
});

// Test that the contents of the dialog correspond to the details of the
// provided cert.
add_task(async function testContents() {
  const formatter = new Intl.DateTimeFormat(undefined, {
    dateStyle: "medium",
    timeStyle: "long",
  });
  let [win] = await openClientAuthDialog(cert);
  checkDialogContents(
    win,
    formatter.format(new Date(cert.validity.notBefore / 1000)),
    formatter.format(new Date(cert.validity.notAfter / 1000))
  );
  await BrowserTestUtils.closeWindow(win);
});

// Test that the right values are returned when the dialog is accepted.
add_task(async function testAcceptDialogReturnValues() {
  let [win, retVals] = await openClientAuthDialog(cert);
  win.document.getElementById("rememberBox").checked = true;
  info("Accepting dialog");
  win.document.getElementById("certAuthAsk").acceptDialog();
  await BrowserTestUtils.windowClosed(win);

  ok(
    retVals.get("certChosen"),
    "Return value should signal user chose a certificate"
  );
  is(
    retVals.get("selectedIndex"),
    0,
    "0 should be returned as the selected index"
  );
  ok(
    retVals.get("rememberSelection"),
    "Return value should signal 'Remember this decision' checkbox was checked"
  );
});

// Test that the right values are returned when the dialog is canceled.
add_task(async function testCancelDialogReturnValues() {
  let [win, retVals] = await openClientAuthDialog(cert);
  win.document.getElementById("rememberBox").checked = false;
  info("Canceling dialog");
  win.document.getElementById("certAuthAsk").cancelDialog();
  await BrowserTestUtils.windowClosed(win);

  ok(
    !retVals.get("certChosen"),
    "Return value should signal user did not choose a certificate"
  );
  ok(
    !retVals.get("rememberSelection"),
    "Return value should signal 'Remember this decision' checkbox was unchecked"
  );
});