summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_pkcs11_token.js
blob: 575fc26b88fb830c91e756af96f70c1e799e7204 (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
/* -*- 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 the methods and attributes for interfacing with a PKCS #11 token, using
// the internal key token.
// We don't use either of the test tokens in the test PKCS #11 module because:
//   1. Test token 1 cyclically inserts and removes itself in a tight loop.
//      Using token 1 would complicate the test and introduce intermittent
//      failures.
//   2. Neither test token implements login or password related functionality.
//      We want to test such functionality.
//   3. Using the internal token lets us actually test the internal token works
//      as expected.

// Ensure that the appropriate initialization has happened.
do_get_profile();

function checkBasicAttributes(token) {
  let bundle = Services.strings.createBundle(
    "chrome://pipnss/locale/pipnss.properties"
  );

  let expectedTokenName = bundle.GetStringFromName("PrivateTokenDescription");
  equal(
    token.tokenName,
    expectedTokenName,
    "Actual and expected name should match"
  );
  equal(
    token.tokenManID,
    bundle.GetStringFromName("ManufacturerID"),
    "Actual and expected manufacturer ID should match"
  );
  equal(
    token.tokenHWVersion,
    "0.0",
    "Actual and expected hardware version should match"
  );
  equal(
    token.tokenFWVersion,
    "0.0",
    "Actual and expected firmware version should match"
  );
  equal(
    token.tokenSerialNumber,
    "0000000000000000",
    "Actual and expected serial number should match"
  );
}

/**
 * Checks the various password related features of the given token.
 * The token should already have been init with a password and be logged into.
 * The password of the token will be reset after calling this function.
 *
 * @param {nsIPK11Token} token
 *        The token to test.
 * @param {string} initialPW
 *        The password that the token should have been init with.
 */
function checkPasswordFeaturesAndResetPassword(token, initialPW) {
  ok(
    !token.needsUserInit,
    "Token should not need user init after setting a password"
  );
  ok(
    token.hasPassword,
    "Token should have a password after setting a password"
  );

  ok(
    token.checkPassword(initialPW),
    "checkPassword() should succeed if the correct initial password is given"
  );
  token.changePassword(initialPW, "newPW ÿ 一二三");
  ok(
    token.checkPassword("newPW ÿ 一二三"),
    "checkPassword() should succeed if the correct new password is given"
  );

  ok(
    !token.checkPassword("wrongPW"),
    "checkPassword() should fail if an incorrect password is given"
  );
  ok(
    !token.isLoggedIn(),
    "Token should be logged out after an incorrect password was given"
  );
  ok(
    !token.needsUserInit,
    "Token should still be init with a password even if an incorrect " +
      "password was given"
  );

  token.reset();
  ok(token.needsUserInit, "Token should need password init after reset");
  ok(!token.hasPassword, "Token should not have a password after reset");
  ok(!token.isLoggedIn(), "Token should be logged out of after reset");
}

function run_test() {
  let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
    Ci.nsIPK11TokenDB
  );
  let token = tokenDB.getInternalKeyToken();
  notEqual(token, null, "The internal token should be present");
  ok(
    token.isInternalKeyToken,
    "The internal token should be represented as such"
  );

  checkBasicAttributes(token);

  ok(!token.isLoggedIn(), "Token should not be logged into yet");
  // Test that attempting to log out even when the token was not logged into
  // does not result in an error.
  token.logoutSimple();
  ok(!token.isLoggedIn(), "Token should still not be logged into");
  ok(
    !token.hasPassword,
    "Token should not have a password before it has been set"
  );

  let initialPW = "foo 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/? 一二三";
  token.initPassword(initialPW);
  token.login(/* force */ false);
  ok(token.isLoggedIn(), "Token should now be logged into");

  checkPasswordFeaturesAndResetPassword(token, initialPW);

  // We reset the password previously, so we need to initialize again.
  token.initPassword("arbitrary");
  ok(
    token.isLoggedIn(),
    "Token should be logged into after initializing password again"
  );
  token.logoutSimple();
  ok(
    !token.isLoggedIn(),
    "Token should be logged out after calling logoutSimple()"
  );

  ok(
    token.needsLogin(),
    "The internal token should always need authentication"
  );
}