test_ext_pkcs11_management.js (9756B)
1 "use strict"; 2 3 ChromeUtils.defineESModuleGetters(this, { 4 MockRegistry: "resource://testing-common/MockRegistry.sys.mjs", 5 ctypes: "resource://gre/modules/ctypes.sys.mjs", 6 }); 7 8 do_get_profile(); 9 10 let tmpDir; 11 let baseDir; 12 let slug = 13 AppConstants.platform === "linux" ? "pkcs11-modules" : "PKCS11Modules"; 14 15 add_task(async function setupTest() { 16 tmpDir = await IOUtils.createUniqueDirectory( 17 Services.dirsvc.get("TmpD", Ci.nsIFile).path, 18 "PKCS11" 19 ); 20 21 baseDir = PathUtils.join(tmpDir, slug); 22 await IOUtils.makeDirectory(baseDir); 23 }); 24 25 registerCleanupFunction(async () => { 26 await IOUtils.remove(tmpDir, { recursive: true }); 27 }); 28 29 const testmodule = PathUtils.join( 30 PathUtils.parent(Services.dirsvc.get("CurWorkD", Ci.nsIFile).path, 5), 31 "security", 32 "manager", 33 "ssl", 34 "tests", 35 "unit", 36 "pkcs11testmodule", 37 ctypes.libraryName("pkcs11testmodule") 38 ); 39 40 // This function was inspired by the native messaging test under 41 // toolkit/components/extensions 42 43 async function setupManifests(modules) { 44 async function writeManifest(module) { 45 let manifest = { 46 name: module.name, 47 description: module.description, 48 path: module.path, 49 type: "pkcs11", 50 allowed_extensions: [module.id], 51 }; 52 53 let manifestPath = PathUtils.join(baseDir, `${module.name}.json`); 54 await IOUtils.writeJSON(manifestPath, manifest); 55 56 return manifestPath; 57 } 58 59 switch (AppConstants.platform) { 60 case "macosx": 61 case "linux": { 62 let dirProvider = { 63 getFile(property) { 64 if ( 65 property == "XREUserNativeManifests" || 66 property == "XRESysNativeManifests" 67 ) { 68 return new FileUtils.File(tmpDir); 69 } 70 return null; 71 }, 72 }; 73 74 Services.dirsvc.registerProvider(dirProvider); 75 registerCleanupFunction(() => { 76 Services.dirsvc.unregisterProvider(dirProvider); 77 }); 78 79 for (let module of modules) { 80 await writeManifest(module); 81 } 82 break; 83 } 84 85 case "win": { 86 const REGKEY = String.raw`Software\Mozilla\PKCS11Modules`; 87 88 let registry = new MockRegistry(); 89 registerCleanupFunction(() => { 90 registry.shutdown(); 91 }); 92 93 for (let module of modules) { 94 let manifestPath = await writeManifest(module); 95 registry.setValue( 96 Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, 97 `${REGKEY}\\${module.name}`, 98 "", 99 manifestPath 100 ); 101 } 102 break; 103 } 104 105 default: 106 ok( 107 false, 108 `Loading of PKCS#11 modules is not supported on ${AppConstants.platform}` 109 ); 110 } 111 } 112 113 add_task(async function test_pkcs11() { 114 async function background() { 115 try { 116 const { os } = await browser.runtime.getPlatformInfo(); 117 if (os !== "win") { 118 // Expect this call to not throw (explicitly cover regression fixed in Bug 1759162). 119 let isInstalledNonAbsolute = await browser.pkcs11.isModuleInstalled( 120 "testmoduleNonAbsolutePath" 121 ); 122 browser.test.assertFalse( 123 isInstalledNonAbsolute, 124 "PKCS#11 module with non absolute path expected to not be installed" 125 ); 126 } 127 let isInstalled = await browser.pkcs11.isModuleInstalled("testmodule"); 128 browser.test.assertFalse( 129 isInstalled, 130 "PKCS#11 module is not installed before we install it" 131 ); 132 await browser.pkcs11.installModule("testmodule", 0); 133 isInstalled = await browser.pkcs11.isModuleInstalled("testmodule"); 134 browser.test.assertTrue( 135 isInstalled, 136 "PKCS#11 module is installed after we install it" 137 ); 138 let slots = await browser.pkcs11.getModuleSlots("testmodule"); 139 browser.test.assertEq( 140 "Test PKCS11 Slot", 141 slots[0].name, 142 "The first slot name matches the expected name" 143 ); 144 browser.test.assertEq( 145 "Test PKCS11 Slot 二", 146 slots[1].name, 147 "The second slot name matches the expected name" 148 ); 149 browser.test.assertTrue(slots[1].token, "The second slot has a token"); 150 browser.test.assertFalse(slots[2].token, "The third slot has no token"); 151 browser.test.assertEq( 152 "Test PKCS11 Tokeñ 2 Label", 153 slots[1].token.name, 154 "The token name matches the expected name" 155 ); 156 browser.test.assertEq( 157 "Test PKCS11 Manufacturer ID", 158 slots[1].token.manufacturer, 159 "The token manufacturer matches the expected manufacturer" 160 ); 161 browser.test.assertEq( 162 "0.0", 163 slots[1].token.HWVersion, 164 "The token hardware version matches the expected version" 165 ); 166 browser.test.assertEq( 167 "0.0", 168 slots[1].token.FWVersion, 169 "The token firmware version matches the expected version" 170 ); 171 browser.test.assertEq( 172 "0000000000000000", 173 slots[1].token.serial, 174 "The token serial number matches the expected value" 175 ); 176 browser.test.assertFalse( 177 slots[1].token.isLoggedIn, 178 "The token is not logged in" 179 ); 180 await browser.pkcs11.uninstallModule("testmodule"); 181 isInstalled = await browser.pkcs11.isModuleInstalled("testmodule"); 182 browser.test.assertFalse( 183 isInstalled, 184 "PKCS#11 module is no longer installed after we uninstall it" 185 ); 186 await browser.pkcs11.installModule("testmodule"); 187 isInstalled = await browser.pkcs11.isModuleInstalled("testmodule"); 188 browser.test.assertTrue( 189 isInstalled, 190 "Installing the PKCS#11 module without flags parameter succeeds" 191 ); 192 await browser.pkcs11.uninstallModule("testmodule"); 193 await browser.test.assertRejects( 194 browser.pkcs11.isModuleInstalled("nonexistingmodule"), 195 /No such PKCS#11 module nonexistingmodule/, 196 "We cannot access modules if no JSON file exists" 197 ); 198 await browser.test.assertRejects( 199 browser.pkcs11.isModuleInstalled("othermodule"), 200 /No such PKCS#11 module othermodule/, 201 "We cannot access modules if we're not listed in the module's manifest file's allowed_extensions key" 202 ); 203 await browser.test.assertRejects( 204 browser.pkcs11.uninstallModule("internalmodule"), 205 /No such PKCS#11 module internalmodule/, 206 "We cannot uninstall the NSS Builtin Roots Module" 207 ); 208 await browser.test.assertRejects( 209 browser.pkcs11.installModule("osclientcerts", 0), 210 /No such PKCS#11 module osclientcerts/, 211 "installModule should not work on the built-in osclientcerts module" 212 ); 213 await browser.test.assertRejects( 214 browser.pkcs11.uninstallModule("osclientcerts"), 215 /No such PKCS#11 module osclientcerts/, 216 "uninstallModule should not work on the built-in osclientcerts module" 217 ); 218 await browser.test.assertRejects( 219 browser.pkcs11.isModuleInstalled("osclientcerts"), 220 /No such PKCS#11 module osclientcerts/, 221 "isModuleLoaded should not work on the built-in osclientcerts module" 222 ); 223 await browser.test.assertRejects( 224 browser.pkcs11.getModuleSlots("osclientcerts"), 225 /No such PKCS#11 module osclientcerts/, 226 "getModuleSlots should not work on the built-in osclientcerts module" 227 ); 228 await browser.test.assertRejects( 229 browser.pkcs11.installModule("ipcclientcerts", 0), 230 /No such PKCS#11 module ipcclientcerts/, 231 "installModule should not work on the built-in ipcclientcerts module" 232 ); 233 await browser.test.assertRejects( 234 browser.pkcs11.uninstallModule("ipcclientcerts"), 235 /No such PKCS#11 module ipcclientcerts/, 236 "uninstallModule should not work on the built-in ipcclientcerts module" 237 ); 238 await browser.test.assertRejects( 239 browser.pkcs11.isModuleInstalled("ipcclientcerts"), 240 /No such PKCS#11 module ipcclientcerts/, 241 "isModuleLoaded should not work on the built-in ipcclientcerts module" 242 ); 243 await browser.test.assertRejects( 244 browser.pkcs11.getModuleSlots("ipcclientcerts"), 245 /No such PKCS#11 module ipcclientcerts/, 246 "getModuleSlots should not work on the built-in ipcclientcerts module" 247 ); 248 browser.test.notifyPass("pkcs11"); 249 } catch (e) { 250 browser.test.fail(`Error: ${String(e)} :: ${e.stack}`); 251 browser.test.notifyFail("pkcs11 failed"); 252 } 253 } 254 255 let libDir = FileUtils.getDir("GreBinD", []); 256 await setupManifests([ 257 { 258 name: "testmodule", 259 description: "PKCS#11 Test Module", 260 path: testmodule, 261 id: "pkcs11@tests.mozilla.org", 262 }, 263 { 264 name: "testmoduleNonAbsolutePath", 265 description: "PKCS#11 Test Module", 266 path: ctypes.libraryName("pkcs11testmodule"), 267 id: "pkcs11@tests.mozilla.org", 268 }, 269 { 270 name: "othermodule", 271 description: "PKCS#11 Test Module", 272 path: testmodule, 273 id: "other@tests.mozilla.org", 274 }, 275 { 276 name: "internalmodule", 277 description: "Builtin Roots Module", 278 path: PathUtils.join( 279 Services.dirsvc.get("CurWorkD", Ci.nsIFile).path, 280 ctypes.libraryName("nssckbi") 281 ), 282 id: "pkcs11@tests.mozilla.org", 283 }, 284 { 285 name: "osclientcerts", 286 description: "OS Client Cert Module", 287 path: PathUtils.join(libDir.path, ctypes.libraryName("osclientcerts")), 288 id: "pkcs11@tests.mozilla.org", 289 }, 290 ]); 291 292 let extension = ExtensionTestUtils.loadExtension({ 293 manifest: { 294 permissions: ["pkcs11"], 295 browser_specific_settings: { gecko: { id: "pkcs11@tests.mozilla.org" } }, 296 }, 297 background: background, 298 }); 299 await extension.startup(); 300 await extension.awaitFinish("pkcs11"); 301 await extension.unload(); 302 });