tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 });