base.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. from abc import ABC, abstractmethod # pylint: disable=no-name-in-module
  2. from typing import Any, Optional, Type
  3. import dns.rdataclass
  4. import dns.rdatatype
  5. from dns.dnssectypes import Algorithm
  6. from dns.exception import AlgorithmKeyMismatch
  7. from dns.rdtypes.ANY.DNSKEY import DNSKEY
  8. from dns.rdtypes.dnskeybase import Flag
  9. class GenericPublicKey(ABC):
  10. algorithm: Algorithm
  11. @abstractmethod
  12. def __init__(self, key: Any) -> None:
  13. pass
  14. @abstractmethod
  15. def verify(self, signature: bytes, data: bytes) -> None:
  16. """Verify signed DNSSEC data"""
  17. @abstractmethod
  18. def encode_key_bytes(self) -> bytes:
  19. """Encode key as bytes for DNSKEY"""
  20. @classmethod
  21. def _ensure_algorithm_key_combination(cls, key: DNSKEY) -> None:
  22. if key.algorithm != cls.algorithm:
  23. raise AlgorithmKeyMismatch
  24. def to_dnskey(self, flags: int = Flag.ZONE, protocol: int = 3) -> DNSKEY:
  25. """Return public key as DNSKEY"""
  26. return DNSKEY(
  27. rdclass=dns.rdataclass.IN,
  28. rdtype=dns.rdatatype.DNSKEY,
  29. flags=flags,
  30. protocol=protocol,
  31. algorithm=self.algorithm,
  32. key=self.encode_key_bytes(),
  33. )
  34. @classmethod
  35. @abstractmethod
  36. def from_dnskey(cls, key: DNSKEY) -> "GenericPublicKey":
  37. """Create public key from DNSKEY"""
  38. @classmethod
  39. @abstractmethod
  40. def from_pem(cls, public_pem: bytes) -> "GenericPublicKey":
  41. """Create public key from PEM-encoded SubjectPublicKeyInfo as specified
  42. in RFC 5280"""
  43. @abstractmethod
  44. def to_pem(self) -> bytes:
  45. """Return public-key as PEM-encoded SubjectPublicKeyInfo as specified
  46. in RFC 5280"""
  47. class GenericPrivateKey(ABC):
  48. public_cls: Type[GenericPublicKey]
  49. @abstractmethod
  50. def __init__(self, key: Any) -> None:
  51. pass
  52. @abstractmethod
  53. def sign(
  54. self,
  55. data: bytes,
  56. verify: bool = False,
  57. deterministic: bool = True,
  58. ) -> bytes:
  59. """Sign DNSSEC data"""
  60. @abstractmethod
  61. def public_key(self) -> "GenericPublicKey":
  62. """Return public key instance"""
  63. @classmethod
  64. @abstractmethod
  65. def from_pem(
  66. cls, private_pem: bytes, password: Optional[bytes] = None
  67. ) -> "GenericPrivateKey":
  68. """Create private key from PEM-encoded PKCS#8"""
  69. @abstractmethod
  70. def to_pem(self, password: Optional[bytes] = None) -> bytes:
  71. """Return private key as PEM-encoded PKCS#8"""