Skip to content

Commit

Permalink
EC sign and verify test (prehashed bc softhsm)
Browse files Browse the repository at this point in the history
  • Loading branch information
msetina committed Apr 5, 2024
1 parent 1c29e63 commit 158ad36
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 28 deletions.
56 changes: 30 additions & 26 deletions cryptography_keys_tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,30 +85,34 @@ def test_rsa_sign_verify(self):
r = current_admin.delete_key_pair()
assert r

# only prehashed supported for EC in softhsm2
def test_ec_sign_verify(self):
from pkcs11_cryptography_keys import (
list_token_labels,
PKCS11AdminSession,
PKCS11KeySession,
)
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.ec import ECDSA
from cryptography.hazmat.primitives.asymmetric import utils

# only prehashed supported for EC in softhsm2
# def test_ec_sign_verify(self):
# from pkcs11_cryptography_keys import (
# list_token_labels,
# PKCS11AdminSession,
# PKCS11KeySession,
# )
# from cryptography.hazmat.primitives import hashes
# from cryptography.hazmat.primitives.asymmetric.ec import ECDSA

# data = b"How to encode this sentence"
# for label in list_token_labels(_pkcs11lib):
# a_session = PKCS11AdminSession(_pkcs11lib, label, "1234", True)
# with a_session as current_admin:
# pub, priv = current_admin.create_ec_key_pair("secp256r1")
# assert pub is not None and priv is not None
# k_session = PKCS11KeySession(_pkcs11lib, label, "1234")
# with k_session as current_key:
# public = current_key.public_key()
# algo = ECDSA(hashes.SHA256())
# signature = current_key.sign(data, algo)
# rezult = public.verify(signature, data, algo)
# assert rezult is None
# with a_session as current_admin:
# r = current_admin.delete_key_pair()
# assert r
data = b"How to encode this sentence"
chosen_hash = hashes.SHA256()
hasher = hashes.Hash(chosen_hash)
hasher.update(data)
digest = hasher.finalize()
for label in list_token_labels(_pkcs11lib):
a_session = PKCS11AdminSession(_pkcs11lib, label, "1234", True)
with a_session as current_admin:
pub, priv = current_admin.create_ec_key_pair("secp256r1")
assert pub is not None and priv is not None
k_session = PKCS11KeySession(_pkcs11lib, label, "1234")
with k_session as current_key:
public = current_key.public_key()
algo = ECDSA(utils.Prehashed(chosen_hash))
signature = current_key.sign(digest, algo)
rezult = public.verify(signature, digest, algo)
assert rezult is None
with a_session as current_admin:
r = current_admin.delete_key_pair()
assert r
21 changes: 19 additions & 2 deletions pkcs11_cryptography_keys/keys/ec.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from cryptography.hazmat.primitives.asymmetric.utils import (
Prehashed,
encode_dss_signature,
decode_dss_signature,
)
from cryptography.hazmat.primitives.serialization import (
Encoding,
Expand Down Expand Up @@ -88,7 +89,7 @@ def _get_PKSC11_mechanism(operation_dict, algorithm):


# ECDSA signtures come from the card RS encoded, for transformation we need separate r and s
def _decode_RS_signature(data):
def _decode_RS_signature(data) -> tuple:
l = len(data) / 2
r = bytearray()
s = bytearray()
Expand All @@ -100,12 +101,24 @@ def _decode_RS_signature(data):
return r, s


def _encode_RS_signature(r_s: tuple, key_size: int) -> bytes | None:
l = int(key_size / 8)
signature = None
try:
signature = int(r_s[0]).to_bytes(l, "big") + int(r_s[1]).to_bytes(
l, "big"
)
except Exception as e:
pass
return signature


class EllipticCurvePublicKeyPKCS11:
def __init__(self, session, public_key, operations: dict):
self._session = session
self._public_key = public_key
self._operations = operations
self._public_key_buffer: EllipticCurvePublicKey
self._public_key_buffer: EllipticCurvePublicKey | None = None

def _read_public_key_data(self) -> EllipticCurvePublicKey:
if self._session is not None and self._public_key_buffer is None:
Expand Down Expand Up @@ -173,6 +186,10 @@ def verify(
PK_me = _get_PKSC11_mechanism(
self._operations["VERIFY"], signature_algorithm
)
sig_ec = decode_dss_signature(signature)
signature = _encode_RS_signature(sig_ec, self.key_size)
if signature is None:
raise InvalidSignature("Signature could not be verified.")
rez = False
if PK_me is None:
rez = self._session.verify(self._public_key, data, signature)
Expand Down

0 comments on commit 158ad36

Please sign in to comment.