diff --git a/securesystemslib/signer/_hsm_signer.py b/securesystemslib/signer/_hsm_signer.py index c01a5ebc..e0e1a5d6 100644 --- a/securesystemslib/signer/_hsm_signer.py +++ b/securesystemslib/signer/_hsm_signer.py @@ -110,7 +110,7 @@ def pin_handler(secret: str) -> str: Arguments: hsm_keyid: Key identifier on the token. - token_filter: dictionary of token field names and values + token_filter: Dictionary of token field names and values public_key: The related public key instance. pin_handler: A function that returns the HSM user login pin, needed for signing. It receives the string argument "pin". @@ -159,10 +159,13 @@ def _get_session(filters: Dict[str, str]) -> Iterator["PyKCS11.Session"]: more than one are found. """ lib = PYKCS11LIB() - slots: List[int] = lib.getSlotList(tokenPresent=True) - matching_slots: List[int] = [] - for slot in slots: + slots: List[int] = [] + for slot in lib.getSlotList(tokenPresent=True): tokeninfo = lib.getTokenInfo(slot) + if not tokeninfo.flags & PyKCS11.CKF_TOKEN_INITIALIZED: + # useful for tests (softhsm always has an unitialized token) + continue + match = True # all values in filters must match token fields for key, value in filters.items(): @@ -171,14 +174,14 @@ def _get_session(filters: Dict[str, str]) -> Iterator["PyKCS11.Session"]: match = False if match: - matching_slots.append(slot) + slots.append(slot) - if len(matching_slots) != 1: + if len(slots) != 1: raise ValueError( - f"Found {len(matching_slots)} slots/tokens matching filter {filters}" + f"Found {len(slots)} slots/tokens matching filter {filters}" ) - session = lib.openSession(matching_slots[0]) + session = lib.openSession(slots[0]) try: yield session @@ -234,7 +237,14 @@ def _build_token_filter(cls) -> Dict[str, str]: """ lib = PYKCS11LIB() - slots: List[int] = lib.getSlotList(tokenPresent=True) + slots: List[int] = [] + for slot in lib.getSlotList(tokenPresent=True): + tokeninfo = lib.getTokenInfo(slot) + if not tokeninfo.flags & PyKCS11.CKF_TOKEN_INITIALIZED: + # useful for tests (softhsm always has an unitialized token) + continue + slots.append(slot) + if len(slots) != 1: raise ValueError(f"Expected 1 token/slot, found {len(slots)}") filters = {} diff --git a/tests/test_hsm_signer.py b/tests/test_hsm_signer.py index b844afee..00a4b8e9 100644 --- a/tests/test_hsm_signer.py +++ b/tests/test_hsm_signer.py @@ -114,10 +114,8 @@ def setUpClass(cls): slot = lib.getSlotList(tokenPresent=True)[0] lib.initToken(slot, so_pin, token_label) - # suddenly there are two slots (why?), use label to filter in tests tokeninfo = lib.getTokenInfo(slot) cls.token_filter = {"label": getattr(tokeninfo, "label")} - print(cls.token_filter) session = PYKCS11LIB().openSession(slot, PyKCS11.CKF_RW_SESSION) session.login(so_pin, PyKCS11.CKU_SO) @@ -156,6 +154,17 @@ def test_hsm(self): def test_hsm_uri(self): """Test HSM default key export and signing from URI.""" + # default import + uri, key = HSMSigner.import_() + signer = Signer.from_priv_key_uri( + uri, key, lambda sec: self.hsm_user_pin + ) + sig = signer.sign(b"DATA") + key.verify_signature(sig, b"DATA") + with self.assertRaises(UnverifiedSignatureError): + key.verify_signature(sig, b"NOT DATA") + + # Import with specified values uri, key = HSMSigner.import_(self.hsm_keyid_default, self.token_filter) signer = Signer.from_priv_key_uri( uri, key, lambda sec: self.hsm_user_pin