Skip to content

Commit

Permalink
HSMSigner: Skip uninitialized tokens
Browse files Browse the repository at this point in the history
This is (mostly) useful for testing as softhsm always has one
uninitialized token. By skipping those we can actually test the default
import_().

Also remove a debug print() call.
  • Loading branch information
jku committed Mar 6, 2023
1 parent 9a3ab72 commit c660d3b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
28 changes: 19 additions & 9 deletions securesystemslib/signer/_hsm_signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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".
Expand Down Expand Up @@ -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():
Expand All @@ -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

Expand Down Expand Up @@ -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 = {}
Expand Down
13 changes: 11 additions & 2 deletions tests/test_hsm_signer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c660d3b

Please sign in to comment.