Spaces:
Building
Building
from typing import Dict, Optional, Tuple, Type, Union | |
import dns.name | |
from dns.dnssecalgs.base import GenericPrivateKey | |
from dns.dnssectypes import Algorithm | |
from dns.exception import UnsupportedAlgorithm | |
from dns.rdtypes.ANY.DNSKEY import DNSKEY | |
if dns._features.have("dnssec"): | |
from dns.dnssecalgs.dsa import PrivateDSA, PrivateDSANSEC3SHA1 | |
from dns.dnssecalgs.ecdsa import PrivateECDSAP256SHA256, PrivateECDSAP384SHA384 | |
from dns.dnssecalgs.eddsa import PrivateED448, PrivateED25519 | |
from dns.dnssecalgs.rsa import ( | |
PrivateRSAMD5, | |
PrivateRSASHA1, | |
PrivateRSASHA1NSEC3SHA1, | |
PrivateRSASHA256, | |
PrivateRSASHA512, | |
) | |
_have_cryptography = True | |
else: | |
_have_cryptography = False | |
AlgorithmPrefix = Optional[Union[bytes, dns.name.Name]] | |
algorithms: Dict[Tuple[Algorithm, AlgorithmPrefix], Type[GenericPrivateKey]] = {} | |
if _have_cryptography: | |
algorithms.update( | |
{ | |
(Algorithm.RSAMD5, None): PrivateRSAMD5, | |
(Algorithm.DSA, None): PrivateDSA, | |
(Algorithm.RSASHA1, None): PrivateRSASHA1, | |
(Algorithm.DSANSEC3SHA1, None): PrivateDSANSEC3SHA1, | |
(Algorithm.RSASHA1NSEC3SHA1, None): PrivateRSASHA1NSEC3SHA1, | |
(Algorithm.RSASHA256, None): PrivateRSASHA256, | |
(Algorithm.RSASHA512, None): PrivateRSASHA512, | |
(Algorithm.ECDSAP256SHA256, None): PrivateECDSAP256SHA256, | |
(Algorithm.ECDSAP384SHA384, None): PrivateECDSAP384SHA384, | |
(Algorithm.ED25519, None): PrivateED25519, | |
(Algorithm.ED448, None): PrivateED448, | |
} | |
) | |
def get_algorithm_cls( | |
algorithm: Union[int, str], prefix: AlgorithmPrefix = None | |
) -> Type[GenericPrivateKey]: | |
"""Get Private Key class from Algorithm. | |
*algorithm*, a ``str`` or ``int`` specifying the DNSKEY algorithm. | |
Raises ``UnsupportedAlgorithm`` if the algorithm is unknown. | |
Returns a ``dns.dnssecalgs.GenericPrivateKey`` | |
""" | |
algorithm = Algorithm.make(algorithm) | |
cls = algorithms.get((algorithm, prefix)) | |
if cls: | |
return cls | |
raise UnsupportedAlgorithm( | |
'algorithm "%s" not supported by dnspython' % Algorithm.to_text(algorithm) | |
) | |
def get_algorithm_cls_from_dnskey(dnskey: DNSKEY) -> Type[GenericPrivateKey]: | |
"""Get Private Key class from DNSKEY. | |
*dnskey*, a ``DNSKEY`` to get Algorithm class for. | |
Raises ``UnsupportedAlgorithm`` if the algorithm is unknown. | |
Returns a ``dns.dnssecalgs.GenericPrivateKey`` | |
""" | |
prefix: AlgorithmPrefix = None | |
if dnskey.algorithm == Algorithm.PRIVATEDNS: | |
prefix, _ = dns.name.from_wire(dnskey.key, 0) | |
elif dnskey.algorithm == Algorithm.PRIVATEOID: | |
length = int(dnskey.key[0]) | |
prefix = dnskey.key[0 : length + 1] | |
return get_algorithm_cls(dnskey.algorithm, prefix) | |
def register_algorithm_cls( | |
algorithm: Union[int, str], | |
algorithm_cls: Type[GenericPrivateKey], | |
name: Optional[Union[dns.name.Name, str]] = None, | |
oid: Optional[bytes] = None, | |
) -> None: | |
"""Register Algorithm Private Key class. | |
*algorithm*, a ``str`` or ``int`` specifying the DNSKEY algorithm. | |
*algorithm_cls*: A `GenericPrivateKey` class. | |
*name*, an optional ``dns.name.Name`` or ``str``, for for PRIVATEDNS algorithms. | |
*oid*: an optional BER-encoded `bytes` for PRIVATEOID algorithms. | |
Raises ``ValueError`` if a name or oid is specified incorrectly. | |
""" | |
if not issubclass(algorithm_cls, GenericPrivateKey): | |
raise TypeError("Invalid algorithm class") | |
algorithm = Algorithm.make(algorithm) | |
prefix: AlgorithmPrefix = None | |
if algorithm == Algorithm.PRIVATEDNS: | |
if name is None: | |
raise ValueError("Name required for PRIVATEDNS algorithms") | |
if isinstance(name, str): | |
name = dns.name.from_text(name) | |
prefix = name | |
elif algorithm == Algorithm.PRIVATEOID: | |
if oid is None: | |
raise ValueError("OID required for PRIVATEOID algorithms") | |
prefix = bytes([len(oid)]) + oid | |
elif name: | |
raise ValueError("Name only supported for PRIVATEDNS algorithm") | |
elif oid: | |
raise ValueError("OID only supported for PRIVATEOID algorithm") | |
algorithms[(algorithm, prefix)] = algorithm_cls | |