Bug 1404421 - Add an empty slot to the test PKCS#11 module r=keeler draft
authorWouter Verhelst <w@uter.be>
Sun, 01 Oct 2017 12:10:20 +0200
changeset 683493 cd3bb819bcf66c769f36a428ed26ea8fa6c68a26
parent 682778 9f8b3fc384ae6fe8053b087548c57020a55f00fd
child 736668 8f8e7abf6ae68b23bf3a05f3a078dedd2105bcb8
push id85399
push userbmo:w@uter.be
push dateThu, 19 Oct 2017 20:54:47 +0000
reviewerskeeler
bugs1404421
milestone58.0a1
Bug 1404421 - Add an empty slot to the test PKCS#11 module r=keeler It is helpful to have a slot which never has a token, so that the absense of a token can be asserted in unit tests. Add a third token that is always empty, and update a number of unit tests to check for it. MozReview-Commit-ID: 4apvRRhZJus
browser/components/extensions/test/xpcshell/test_ext_pkcs11_management.js
security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp
security/manager/ssl/tests/unit/test_pkcs11_module.js
security/manager/ssl/tests/unit/test_pkcs11_slot.js
--- a/browser/components/extensions/test/xpcshell/test_ext_pkcs11_management.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_pkcs11_management.js
@@ -97,16 +97,17 @@ add_task(async function test_pkcs11() {
       browser.test.assertFalse(isInstalled, "PKCS#11 module is not installed before we install it");
       await browser.pkcs11.installModule("testmodule", 0);
       isInstalled = await browser.pkcs11.isModuleInstalled("testmodule");
       browser.test.assertTrue(isInstalled, "PKCS#11 module is installed after we install it");
       let slots = await browser.pkcs11.getModuleSlots("testmodule");
       browser.test.assertEq("Test PKCS11 Slot", slots[0].name, "The first slot name matches the expected name");
       browser.test.assertEq("Test PKCS11 Slot 二", slots[1].name, "The second slot name matches the expected name");
       browser.test.assertTrue(slots[1].token, "The second slot has a token");
+      browser.test.assertFalse(slots[2].token, "The third slot has no token");
       browser.test.assertEq("Test PKCS11 Tokeñ 2 Label", slots[1].token.name, "The token name matches the expected name");
       browser.test.assertEq("Test PKCS11 Manufacturer ID", slots[1].token.manufacturer, "The token manufacturer matches the expected manufacturer");
       browser.test.assertEq("0.0", slots[1].token.HWVersion, "The token hardware version matches the expected version");
       browser.test.assertEq("0.0", slots[1].token.FWVersion, "The token firmware version matches the expected version");
       browser.test.assertEq("", slots[1].token.serial, "The token has no serial number");
       browser.test.assertFalse(slots[1].token.isLoggedIn, "The token is not logged in");
       await browser.pkcs11.uninstallModule("testmodule");
       isInstalled = await browser.pkcs11.isModuleInstalled("testmodule");
--- a/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp
+++ b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp
@@ -7,16 +7,17 @@
 // removed from a slot every 50ms. This is achieved mainly in
 // Test_C_WaitForSlotEvent. The smartcard monitoring code essentially calls
 // this function in a tight loop. Each time, this module waits for 50ms and
 // returns, having changed its internal state to report that the token has
 // either been inserted or removed, as appropriate.
 // This module also provides an alternate token that is always present for tests
 // that don't want the cyclic behavior described above.
 
+#include <assert.h>
 #include <string.h>
 
 #if defined(WIN32)
 #  include <windows.h> // for Sleep
 #else
 #  include <unistd.h> // for usleep
 #endif
 
@@ -74,39 +75,64 @@ static int tokenPresent = 0;
 CK_RV Test_C_GetSlotList(CK_BBOOL limitToTokensPresent,
                          CK_SLOT_ID_PTR pSlotList,
                          CK_ULONG_PTR pulCount)
 {
   if (!pulCount) {
     return CKR_ARGUMENTS_BAD;
   }
 
-  // Slot 2 is always present, while slot 1 may or may not be present.
-  CK_ULONG slotCount = (!limitToTokensPresent || tokenPresent ? 1 : 0) + 1;
+  // We always return slot 2
+  CK_ULONG slotCount = 1;
+  if (!limitToTokensPresent) {
+    // If we want empty slots, we also return slots 1 and 3
+    slotCount += 2;
+  } else if (tokenPresent) {
+    // If we don't want empty slots, but token 1 is present, return that (but
+    // not slot 3)
+    slotCount++;
+  }
 
   if (pSlotList) {
     if (*pulCount < slotCount) {
       return CKR_BUFFER_TOO_SMALL;
     }
     // apparently CK_SLOT_IDs are integers [1,N] because
     // who likes counting from 0 all the time?
-    if (slotCount == 1) {
-      pSlotList[0] = 2;
-    } else {
-      pSlotList[0] = 1;
-      pSlotList[1] = 2;
+    switch(slotCount) {
+      case 1:
+        pSlotList[0] = 2;
+        break;
+      case 2:
+        if (tokenPresent) {
+          pSlotList[0] = 1;
+          pSlotList[1] = 2;
+        } else {
+          pSlotList[0] = 2;
+          pSlotList[1] = 3;
+        }
+        break;
+      case 3:
+        pSlotList[0] = 1;
+        pSlotList[1] = 2;
+        pSlotList[2] = 3;
+        break;
+      default:
+        assert("Unexpected slot count in Test_C_GetSlotList" == NULL);
+        return CKR_GENERAL_ERROR;
     }
   }
 
   *pulCount = slotCount;
   return CKR_OK;
 }
 
 static const char TestSlotDescription[] = "Test PKCS11 Slot";
 static const char TestSlot2Description[] = "Test PKCS11 Slot 二";
+static const char TestSlot3Description[] = "Empty PKCS11 Slot";
 
 CK_RV Test_C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
 {
   if (!pInfo) {
     return CKR_ARGUMENTS_BAD;
   }
 
   switch (slotID) {
@@ -114,16 +140,20 @@ CK_RV Test_C_GetSlotInfo(CK_SLOT_ID slot
       CopyString(pInfo->slotDescription, TestSlotDescription);
       pInfo->flags = (tokenPresent ? CKF_TOKEN_PRESENT : 0) |
                      CKF_REMOVABLE_DEVICE;
       break;
     case 2:
       CopyString(pInfo->slotDescription, TestSlot2Description);
       pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE;
       break;
+    case 3:
+      CopyString(pInfo->slotDescription, TestSlot3Description);
+      pInfo->flags = CKF_REMOVABLE_DEVICE;
+      break;
     default:
       return CKR_ARGUMENTS_BAD;
   }
 
   CopyString(pInfo->manufacturerID, TestManufacturerID);
   pInfo->hardwareVersion = TestLibraryVersion;
   pInfo->firmwareVersion = TestLibraryVersion;
   return CKR_OK;
--- a/security/manager/ssl/tests/unit/test_pkcs11_module.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_module.js
@@ -100,17 +100,17 @@ function run_test() {
   // Check that listing the slots for the test module works.
   let slots = testModule.listSlots();
   let testModuleSlotNames = [];
   while (slots.hasMoreElements()) {
     let slot = slots.getNext().QueryInterface(Ci.nsIPKCS11Slot);
     testModuleSlotNames.push(slot.name);
   }
   testModuleSlotNames.sort();
-  const expectedSlotNames = ["Test PKCS11 Slot", "Test PKCS11 Slot 二"];
+  const expectedSlotNames = ["Empty PKCS11 Slot", "Test PKCS11 Slot", "Test PKCS11 Slot 二"];
   deepEqual(testModuleSlotNames, expectedSlotNames,
             "Actual and expected slot names should be equal");
 
   // Check that finding the test slot by name is possible, and that trying to
   // find a non-present slot fails.
   notEqual(testModule.findSlotByName("Test PKCS11 Slot"), null,
            "Test slot should be findable by name");
   throws(() => testModule.findSlotByName("Not Present"), /NS_ERROR_FAILURE/,
--- a/security/manager/ssl/tests/unit/test_pkcs11_slot.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_slot.js
@@ -30,9 +30,14 @@ function run_test() {
         "Actual and expected status should match");
   equal(testSlot.tokenName, "Test PKCS11 Tokeñ 2 Label",
         "Actual and expected token name should match");
 
   let testToken = testSlot.getToken();
   notEqual(testToken, null, "getToken() should succeed");
   equal(testToken.tokenLabel, "Test PKCS11 Tokeñ 2 Label",
         "Spot check: the actual and expected test token labels should be equal");
+
+  testSlot = testModule.findSlotByName("Empty PKCS11 Slot");
+  equal(testSlot.tokenName, null, "Empty slot is empty");
+  equal(testSlot.status, Ci.nsIPKCS11Slot.SLOT_NOT_PRESENT,
+        "Actual and expected status should match");
 }