# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import abc
import typing
from cryptography.hazmat.primitives import _serialization, hashes
from cryptography.hazmat.primitives.asymmetric import (
AsymmetricSignatureContext,
AsymmetricVerificationContext,
utils as asym_utils,
)
class DSAParameters(metaclass=abc.ABCMeta):
@abc.abstractmethod
def generate_private_key(self) -> "DSAPrivateKey":
"""
Generates and returns a DSAPrivateKey.
"""
@abc.abstractmethod
def parameter_numbers(self) -> "DSAParameterNumbers":
"""
Returns a DSAParameterNumbers.
"""
DSAParametersWithNumbers = DSAParameters
class DSAPrivateKey(metaclass=abc.ABCMeta):
@abc.abstractproperty
def key_size(self) -> int:
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def public_key(self) -> "DSAPublicKey":
"""
The DSAPublicKey associated with this private key.
"""
@abc.abstractmethod
def parameters(self) -> DSAParameters:
"""
The DSAParameters object associated with this private key.
"""
@abc.abstractmethod
def signer(
self,
signature_algorithm: hashes.HashAlgorithm,
) -> AsymmetricSignatureContext:
"""
Returns an AsymmetricSignatureContext used for signing data.
"""
@abc.abstractmethod
def sign(
self,
data: bytes,
algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
) -> bytes:
"""
Signs the data
"""
@abc.abstractmethod
def private_numbers(self) -> "DSAPrivateNumbers":
"""
Returns a DSAPrivateNumbers.
"""
@abc.abstractmethod
def private_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PrivateFormat,
encryption_algorithm: _serialization.KeySerializationEncryption,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
DSAPrivateKeyWithSerialization = DSAPrivateKey
class DSAPublicKey(metaclass=abc.ABCMeta):
@abc.abstractproperty
def key_size(self) -> int:
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def parameters(self) -> DSAParameters:
"""
The DSAParameters object associated with this public key.
"""
@abc.abstractmethod
def verifier(
self,
signature: bytes,
signature_algorithm: hashes.HashAlgorithm,
) -> AsymmetricVerificationContext:
"""
Returns an AsymmetricVerificationContext used for signing data.
"""
@abc.abstractmethod
def public_numbers(self) -> "DSAPublicNumbers":
"""
Returns a DSAPublicNumbers.
"""
@abc.abstractmethod
def public_bytes(
self,
encoding: _serialization.Encoding,
format: _serialization.PublicFormat,
) -> bytes:
"""
Returns the key serialized as bytes.
"""
@abc.abstractmethod
def verify(
self,
signature: bytes,
data: bytes,
algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
) -> None:
"""
Verifies the signature of the data.
"""
DSAPublicKeyWithSerialization = DSAPublicKey
class DSAParameterNumbers(object):
def __init__(self, p: int, q: int, g: int):
if (
not isinstance(p, int)
or not isinstance(q, int)
or not isinstance(g, int)
):
raise TypeError(
"DSAParameterNumbers p, q, and g arguments must be integers."
)
self._p = p
self._q = q
self._g = g
p = property(lambda self: self._p)
q = property(lambda self: self._q)
g = property(lambda self: self._g)
def parameters(self, backend: typing.Any = None) -> DSAParameters:
from cryptography.hazmat.backends.openssl.backend import (
backend as ossl,
)
return ossl.load_dsa_parameter_numbers(self)
def __eq__(self, other):
if not isinstance(other, DSAParameterNumbers):
return NotImplemented
return self.p == other.p and self.q == other.q and self.g == other.g
def __ne__(self, other):
return not self == other
def __repr__(self):
return (
"