cryptography.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. from typing import Any, Optional, Type
  2. from cryptography.hazmat.primitives import serialization
  3. from dns.dnssecalgs.base import GenericPrivateKey, GenericPublicKey
  4. from dns.exception import AlgorithmKeyMismatch
  5. class CryptographyPublicKey(GenericPublicKey):
  6. key: Any = None
  7. key_cls: Any = None
  8. def __init__(self, key: Any) -> None: # pylint: disable=super-init-not-called
  9. if self.key_cls is None:
  10. raise TypeError("Undefined private key class")
  11. if not isinstance( # pylint: disable=isinstance-second-argument-not-valid-type
  12. key, self.key_cls
  13. ):
  14. raise AlgorithmKeyMismatch
  15. self.key = key
  16. @classmethod
  17. def from_pem(cls, public_pem: bytes) -> "GenericPublicKey":
  18. key = serialization.load_pem_public_key(public_pem)
  19. return cls(key=key)
  20. def to_pem(self) -> bytes:
  21. return self.key.public_bytes(
  22. encoding=serialization.Encoding.PEM,
  23. format=serialization.PublicFormat.SubjectPublicKeyInfo,
  24. )
  25. class CryptographyPrivateKey(GenericPrivateKey):
  26. key: Any = None
  27. key_cls: Any = None
  28. public_cls: Type[CryptographyPublicKey]
  29. def __init__(self, key: Any) -> None: # pylint: disable=super-init-not-called
  30. if self.key_cls is None:
  31. raise TypeError("Undefined private key class")
  32. if not isinstance( # pylint: disable=isinstance-second-argument-not-valid-type
  33. key, self.key_cls
  34. ):
  35. raise AlgorithmKeyMismatch
  36. self.key = key
  37. def public_key(self) -> "CryptographyPublicKey":
  38. return self.public_cls(key=self.key.public_key())
  39. @classmethod
  40. def from_pem(
  41. cls, private_pem: bytes, password: Optional[bytes] = None
  42. ) -> "GenericPrivateKey":
  43. key = serialization.load_pem_private_key(private_pem, password=password)
  44. return cls(key=key)
  45. def to_pem(self, password: Optional[bytes] = None) -> bytes:
  46. encryption_algorithm: serialization.KeySerializationEncryption
  47. if password:
  48. encryption_algorithm = serialization.BestAvailableEncryption(password)
  49. else:
  50. encryption_algorithm = serialization.NoEncryption()
  51. return self.key.private_bytes(
  52. encoding=serialization.Encoding.PEM,
  53. format=serialization.PrivateFormat.PKCS8,
  54. encryption_algorithm=encryption_algorithm,
  55. )