diff --git a/securesystemslib/signer/_hsm_signer.py b/securesystemslib/signer/_hsm_signer.py index c4cd181a..2d2ab40b 100644 --- a/securesystemslib/signer/_hsm_signer.py +++ b/securesystemslib/signer/_hsm_signer.py @@ -11,6 +11,7 @@ from securesystemslib import KEY_TYPE_ECDSA from securesystemslib.exceptions import UnsupportedLibraryError +from securesystemslib.hash import digest from securesystemslib.keys import _get_keyid from securesystemslib.signer._key import Key, SSlibKey from securesystemslib.signer._signature import Signature @@ -44,13 +45,6 @@ PYKCS11_IMPORT_ERROR = None try: from PyKCS11 import PyKCS11 - - # TODO: Don't hardcode schemes - _MECHANISM_FOR_SCHEME = { - "ecdsa-sha2-nistp256": PyKCS11.Mechanism(PyKCS11.CKM_ECDSA_SHA256), - "ecdsa-sha2-nistp384": PyKCS11.Mechanism(PyKCS11.CKM_ECDSA_SHA384), - } - except ImportError: PYKCS11_IMPORT_ERROR = "'PyKCS11' required" @@ -141,10 +135,12 @@ def __init__( if PYKCS11_IMPORT_ERROR: raise UnsupportedLibraryError(PYKCS11_IMPORT_ERROR) - if public_key.scheme not in _MECHANISM_FOR_SCHEME: + if public_key.scheme not in [ + "ecdsa-sha2-nistp256", + "ecdsa-sha2-nistp384", + ]: raise ValueError(f"unsupported scheme {public_key.scheme}") - self._mechanism = _MECHANISM_FOR_SCHEME[public_key.scheme] self.hsm_keyid = hsm_keyid self.token_filter = token_filter self.public_key = public_key @@ -367,13 +363,18 @@ def sign(self, payload: bytes) -> Signature: Returns: Signature. """ + + hasher = digest(algorithm=f"sha{self.public_key.scheme[-3:]}") + hasher.update(payload) + pin = self.pin_handler(self.SECRETS_HANDLER_MSG) with self._get_session(self.token_filter) as session: session.login(pin) key = self._find_key( session, self.hsm_keyid, PyKCS11.CKO_PRIVATE_KEY ) - signature = session.sign(key, payload, self._mechanism) + mechanism = PyKCS11.Mechanism(PyKCS11.CKM_ECDSA) + signature = session.sign(key, hasher.digest(), mechanism) session.logout() # The PKCS11 signature octets correspond to the concatenation of the ECDSA diff --git a/tests/test_hsm_signer.py b/tests/test_hsm_signer.py index 00a4b8e9..65ad58b3 100644 --- a/tests/test_hsm_signer.py +++ b/tests/test_hsm_signer.py @@ -5,7 +5,6 @@ import shutil import tempfile import unittest -from unittest.mock import patch from asn1crypto.keys import ( # pylint: disable=import-error ECDomainParameters, @@ -15,32 +14,13 @@ from PyKCS11 import PyKCS11 from securesystemslib.exceptions import UnverifiedSignatureError -from securesystemslib.hash import digest from securesystemslib.signer import HSMSigner, Signer from securesystemslib.signer._hsm_signer import PYKCS11LIB -_orig_sign = HSMSigner.sign - - -def _sign(self, data): - """Wraps HSMSigner sign method for testing - - HSMSigner supports CKM_ECDSA_SHA256 and CKM_ECDSA_SHA384 mechanisms. But SoftHSM - only supports CKM_ECDSA. For testing we patch the HSMSigner mechanism attribute and - pre-hash the data. - """ - self._mechanism = PyKCS11.Mechanism( # pylint: disable=protected-access - PyKCS11.CKM_ECDSA - ) - hasher = digest(algorithm=f"sha{self.public_key.scheme[-3:]}") - hasher.update(data) - return _orig_sign(self, hasher.digest()) - @unittest.skipUnless( os.environ.get("PYKCS11LIB"), "set PYKCS11LIB to SoftHSM lib path" ) -@patch.object(HSMSigner, "sign", _sign) class TestHSM(unittest.TestCase): """Test HSMSigner with SoftHSM