Skip to content

Commit

Permalink
Add back support for P256 keys
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Oct 25, 2024
1 parent 0de0cd5 commit 66191e0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
53 changes: 52 additions & 1 deletion pynitrokey/cli/nk3/piv.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,52 @@ def private_bytes(
raise NotImplementedError()


class P256PivSigner(ec.EllipticCurvePrivateKey):
_device: PivApp
_key_reference: int
_public_key: ec.EllipticCurvePublicKey

def __init__(
self, device: PivApp, key_reference: int, public_key: ec.EllipticCurvePublicKey
):
self._device = device
self._key_reference = key_reference
self._public_key = public_key

def exchange(
self, algorithm: ec.ECDH, peer_public_key: ec.EllipticCurvePublicKey
) -> bytes:
raise NotImplementedError()

def public_key(self) -> ec.EllipticCurvePublicKey:
return self._public_key

def curve(self) -> ec.EllipticCurve: # type: ignore
return self._public_key.curve

def private_numbers(self) -> ec.EllipticCurvePrivateNumbers:
raise NotImplementedError()

def key_size(self) -> int: # type: ignore
return self._public_key.key_size

def private_bytes(
self,
encoding: serialization.Encoding,
format: serialization.PrivateFormat,
encryption_algorithm: serialization.KeySerializationEncryption,
) -> bytes:
raise NotImplementedError()

def sign(
self, data: bytes, signature_algorithm: ec.EllipticCurveSignatureAlgorithm
) -> bytes:
assert isinstance(signature_algorithm, ec.ECDSA)
assert isinstance(signature_algorithm.algorithm, hashes.SHA256)

return self._device.sign_p256(data, self._key_reference)


@nk3.group()
@click.option(
"--experimental",
Expand Down Expand Up @@ -551,7 +597,12 @@ def generate_key(
csr_builder = csr_builder.add_extension(crypto_sujbect_alt_name, False)

if algo == "nistp256":
local_critical("Unimplemented algorithm")
csr = csr_builder.sign(
P256PivSigner(device, key_ref, public_key_ecc), hashes.SHA256()
)
certificate = certificate_builder.public_key(public_key_ecc).sign(
P256PivSigner(device, key_ref, public_key_ecc), hashes.SHA256()
)
elif algo == "rsa2048":
csr = csr_builder.sign(
RsaPivSigner(device, key_ref, public_key_rsa), hashes.SHA256()
Expand Down
1 change: 0 additions & 1 deletion pynitrokey/nk3/piv_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ def factory_reset(self) -> None:
self.send_receive(0xFB, 0, 0)

def sign_p256(self, data: bytes, key: int) -> bytes:
prepare_for_pkcs1v15_sign_2048(data)
digest = hashes.Hash(hashes.SHA256())
digest.update(data)
payload = digest.finalize()
Expand Down

0 comments on commit 66191e0

Please sign in to comment.