From 45e1e3f2fa8cd478e2edd8a773812c88edb7b6b1 Mon Sep 17 00:00:00 2001 From: "Roland C. Dowdeswell" Date: Mon, 18 Dec 2023 22:32:09 +0000 Subject: [PATCH] Replace use of pyhsm with PyKCS11 Turns out pyhsm is, although simpler to use, not really maintained recently. --- cloudformation/template | 10 ---------- requirements.txt | 1 - scripts/build-package-al2023 | 10 ---------- tezos_signer/hsmsigner.py | 36 +++++++++++++++++++++++------------- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/cloudformation/template b/cloudformation/template index 9ff0967..207c0d6 100644 --- a/cloudformation/template +++ b/cloudformation/template @@ -15,13 +15,6 @@ Parameters: AllowedValues: - remote-signer-dev.tar.gz - remote-signer.tar.gz - LibHSM: - Type: String - Default: libhsm-1.0.zip - AllowedValues: - - libhsm-1.0.zip - - libhsm-2.0.zip - - libhsm.zip VPC: Type: 'AWS::EC2::VPC::Id' Subnets: @@ -67,8 +60,6 @@ Metadata: default: The S3 bucket that contains the remote signer artifacts Artifact: default: The zip file within the S3 artifact bucket that is the artifact - LibHSM: - default: The zip file within the S3 artifact bucket that is the HSM library VPC: default: Choose which VPC the autoscaling group should be deployed to Subnets: @@ -103,7 +94,6 @@ Metadata: Parameters: - ArtifactBucket - Artifact - - LibHSM - Label: default: VPC Configuration Parameters: diff --git a/requirements.txt b/requirements.txt index 733a6d2..1afb6d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,6 @@ Jinja2==3.1.2 jmespath==1.0.1 MarkupSafe==2.1.3 PyKCS11==1.5.10 -py-hsm==2.5.0 pyblake2==1.1.2 pytezos-core==1.0.0rc1 python-dateutil==2.8.2 diff --git a/scripts/build-package-al2023 b/scripts/build-package-al2023 index d0e81a1..565cbe1 100755 --- a/scripts/build-package-al2023 +++ b/scripts/build-package-al2023 @@ -29,16 +29,6 @@ yum install -y libsodium gmp jq aws-cli $BUILD_DEPS chown -R ec2-user . sudo -H -u ec2-user $PIP --no-cache install wheel . -# XXXrcd: -# py-hsm==git+https://github.com/tacoinfra/py-hsm - -# -# This may not be the best place to build libhsm, but this just -# happens to be where we have the compilers installed... - -git clone https://github.com/tacoinfra/libhsm -( cd libhsm/build && ./build_libhsm && cp libhsm.so /usr/lib64/libhsm.so ) - # # XXXrcd: # The following are hacks to make Amazon Linux 2023 have few files from diff --git a/tezos_signer/hsmsigner.py b/tezos_signer/hsmsigner.py index 9bce18e..7e951bd 100644 --- a/tezos_signer/hsmsigner.py +++ b/tezos_signer/hsmsigner.py @@ -4,8 +4,8 @@ import logging import threading -from pyhsm.hsmclient import HsmClient -from pyhsm.hsmenums import HsmMech +from PyKCS11 import CK_OBJECT_HANDLE, CKF_RW_SESSION, CKF_SERIAL_SESSION, \ + CKM_ECDSA, Mechanism, PyKCS11Lib from tezos_signer import Signer @@ -22,20 +22,30 @@ def __init__(self, config, key): self.key = key self.lock = threading.Lock() + pkcs11 = PyKCS11Lib() + pkcs11.load(self.hsm_libfile) + self.session = pkcs11.openSession(self.hsm_slot, + CKF_SERIAL_SESSION|CKF_RW_SESSION) + self.session.login(self.hsm_pin) + self.key = CK_OBJECT_HANDLE(self.session) + self.key.assign(self.hsm_private_handle) + def sign(self, sigreq): logging.debug(f'Signing with HSM client:') logging.debug(f' Slot = {self.hsm_slot}') logging.debug(f' lib = {self.hsm_libfile}') logging.debug(f' private_handle = {self.hsm_private_handle}') + # + # XXXrcd: we continue to use a lock because it was necessary + # when we were using py-hsm. We are not sure we needed + # it due to bugs in py-hsm or the underlying PKCS#11 + # library. Although we strongly suspect the former, we + # have not had time to test our hypothesis. with self.lock: - with HsmClient(slot=self.hsm_slot, pin=self.hsm_pin, - pkcs11_lib=self.hsm_libfile) as c: - hashed_data = sigreq.get_hashed_payload() - logging.debug(f'Hashed data to sign: {hashed_data}') - sig = c.sign(handle=self.hsm_private_handle, data=hashed_data, - mechanism=HsmMech.ECDSA) - - logging.debug(f'Raw signature: {sig}') - encoded_sig = Signer.b58encode_signature(sig) - logging.debug(f'Base58-encoded signature: {encoded_sig}') - return encoded_sig + sig = self.session.sign(self.key, sigreq.get_hashed_payload(), + Mechanism(CKM_ECDSA, None)) + sig = bytes(sig) + logging.debug(f'Raw signature: {sig}') + encoded_sig = Signer.b58encode_signature(sig) + logging.debug(f'Base58-encoded signature: {encoded_sig}') + return encoded_sig