You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

69 lines
2.4 KiB

  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. )