aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/primitives/asymmetric/dsa.py71
-rw-r--r--docs/hazmat/primitives/asymmetric/dsa.rst67
-rw-r--r--docs/hazmat/primitives/interfaces.rst89
-rw-r--r--tests/hazmat/primitives/test_dsa.py60
4 files changed, 247 insertions, 40 deletions
diff --git a/cryptography/hazmat/primitives/asymmetric/dsa.py b/cryptography/hazmat/primitives/asymmetric/dsa.py
index a9ae9ecb..4d78679e 100644
--- a/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -181,3 +181,74 @@ class DSAPublicKey(object):
def parameters(self):
return DSAParameters(self._modulus, self._subgroup_order,
self._generator)
+
+
+class DSAParameterNumbers(object):
+ def __init__(self, p, q, g):
+ if (
+ not isinstance(p, six.integer_types) or
+ not isinstance(q, six.integer_types) or
+ not isinstance(g, six.integer_types)
+ ):
+ raise TypeError(
+ "DSAParameterNumbers p, q, and g arguments must be integers."
+ )
+
+ self._p = p
+ self._q = q
+ self._g = g
+
+ @property
+ def p(self):
+ return self._p
+
+ @property
+ def q(self):
+ return self._q
+
+ @property
+ def g(self):
+ return self._g
+
+
+class DSAPublicNumbers(object):
+ def __init__(self, y, parameter_numbers):
+ if not isinstance(y, six.integer_types):
+ raise TypeError("DSAPublicNumbers y argument must be an integer.")
+
+ if not isinstance(parameter_numbers, DSAParameterNumbers):
+ raise TypeError(
+ "parameter_numbers must be a DSAParameterNumbers instance."
+ )
+
+ self._y = y
+ self._parameter_numbers = parameter_numbers
+
+ @property
+ def y(self):
+ return self._y
+
+ @property
+ def parameter_numbers(self):
+ return self._parameter_numbers
+
+
+class DSAPrivateNumbers(object):
+ def __init__(self, x, public_numbers):
+ if not isinstance(x, six.integer_types):
+ raise TypeError("DSAPrivateNumbers x argument must be an integer.")
+
+ if not isinstance(public_numbers, DSAPublicNumbers):
+ raise TypeError(
+ "public_numbers must be a DSAPublicNumbers instance."
+ )
+ self._public_numbers = public_numbers
+ self._x = x
+
+ @property
+ def x(self):
+ return self._x
+
+ @property
+ def public_numbers(self):
+ return self._public_numbers
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 6848d84c..2167e528 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -210,6 +210,73 @@ DSA
:returns:
:class:`~cryptography.hazmat.primitives.interfaces.AsymmetricVerificationContext`
+.. class:: DSAParameterNumbers(p, q, g)
+
+ .. versionadded:: 0.5
+
+ The collection of integers that make up a set of DSA parameters.
+
+ .. attribute:: p
+
+ :type: int
+
+ The public modulus.
+
+ .. attribute:: q
+
+ :type: int
+
+ The sub-group order.
+
+ .. attribute:: g
+
+ :type: int
+
+ The generator.
+
+.. class:: DSAPublicNumbers(y, parameter_numbers)
+
+ .. versionadded:: 0.5
+
+ The collection of integers that make up a DSA public key.
+
+ .. attribute:: y
+
+ :type: int
+
+ The public value ``y``.
+
+ .. attribute:: parameter_numbers
+
+ :type: :class:`~cryptography.hazmat.primitives.dsa.DSAParameterNumbers`
+
+ The :class:`~cryptography.hazmat.primitives.dsa.DSAParameterNumbers`
+ associated with the public key.
+
+.. class:: DSAPrivateNumbers(x, public_numbers)
+
+ .. versionadded:: 0.5
+
+ The collection of integers that make up a DSA private key.
+
+ .. warning::
+
+ Revealing the value of ``x`` will compromise the security of any
+ cryptographic operations performed.
+
+ .. attribute:: x
+
+ :type: int
+
+ The private value ``x``.
+
+ .. attribute:: public_numbers
+
+ :type: :class:`~cryptography.hazmat.primitives.dsa.DSAPublicNumbers`
+
+ The :class:`~cryptography.hazmat.primitives.dsa.DSAPublicNumbers`
+ associated with the private key.
+
.. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
.. _`FIPS 186-4`: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index 029c4c1f..7d02839a 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -13,7 +13,7 @@ to document argument and return types.
Symmetric ciphers
-~~~~~~~~~~~~~~~~~
+-----------------
.. currentmodule:: cryptography.hazmat.primitives.interfaces
@@ -48,7 +48,7 @@ Symmetric ciphers
Cipher modes
-------------
+~~~~~~~~~~~~
Interfaces used by the symmetric cipher modes described in
:ref:`Symmetric Encryption Modes <symmetric-encryption-modes>`.
@@ -104,7 +104,44 @@ Interfaces used by the symmetric cipher modes described in
individual modes.
Asymmetric interfaces
-~~~~~~~~~~~~~~~~~~~~~
+---------------------
+
+.. class:: AsymmetricSignatureContext
+
+ .. versionadded:: 0.2
+
+ .. method:: update(data)
+
+ :param bytes data: The data you want to sign.
+
+ .. method:: finalize()
+
+ :return bytes signature: The signature.
+
+
+.. class:: AsymmetricVerificationContext
+
+ .. versionadded:: 0.2
+
+ .. method:: update(data)
+
+ :param bytes data: The data you wish to verify using the signature.
+
+ .. method:: verify()
+
+ :raises cryptography.exceptions.InvalidSignature: If the signature does
+ not validate.
+
+
+.. class:: AsymmetricPadding
+
+ .. versionadded:: 0.2
+
+ .. attribute:: name
+
+
+RSA
+~~~
.. class:: RSAPrivateKey
@@ -236,6 +273,9 @@ Asymmetric interfaces
instance.
+DSA
+~~~
+
.. class:: DSAParameters
.. versionadded:: 0.3
@@ -407,6 +447,9 @@ Asymmetric interfaces
The bit length of the curve's base point.
+Elliptic Curve
+~~~~~~~~~~~~~~
+
.. class:: EllipticCurveSignatureAlgorithm
.. versionadded:: 0.5
@@ -475,42 +518,8 @@ Asymmetric interfaces
The elliptic curve for this key.
-.. class:: AsymmetricSignatureContext
-
- .. versionadded:: 0.2
-
- .. method:: update(data)
-
- :param bytes data: The data you want to sign.
-
- .. method:: finalize()
-
- :return bytes signature: The signature.
-
-
-.. class:: AsymmetricVerificationContext
-
- .. versionadded:: 0.2
-
- .. method:: update(data)
-
- :param bytes data: The data you wish to verify using the signature.
-
- .. method:: verify()
-
- :raises cryptography.exceptions.InvalidSignature: If the signature does
- not validate.
-
-
-.. class:: AsymmetricPadding
-
- .. versionadded:: 0.2
-
- .. attribute:: name
-
-
Hash algorithms
-~~~~~~~~~~~~~~~
+---------------
.. class:: HashAlgorithm
@@ -556,7 +565,7 @@ Hash algorithms
Key derivation functions
-~~~~~~~~~~~~~~~~~~~~~~~~
+------------------------
.. class:: KeyDerivationFunction
@@ -601,7 +610,7 @@ Key derivation functions
`CMAC`_
-~~~~~~~
+-------
.. class:: CMACContext
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index cbe10e9c..51a03c48 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -872,3 +872,63 @@ def test_dsa_generate_invalid_backend():
with raises_unsupported_algorithm(
_Reasons.BACKEND_MISSING_INTERFACE):
dsa.DSAPrivateKey.generate(pretend_parameters, pretend_backend)
+
+
+class TestDSANumbers(object):
+ def test_dsa_parameter_numbers(self):
+ parameter_numbers = dsa.DSAParameterNumbers(p=1, q=2, g=3)
+ assert parameter_numbers.p == 1
+ assert parameter_numbers.q == 2
+ assert parameter_numbers.g == 3
+
+ def test_dsa_parameter_numbers_invalid_types(self):
+ with pytest.raises(TypeError):
+ dsa.DSAParameterNumbers(p=None, q=2, g=3)
+
+ with pytest.raises(TypeError):
+ dsa.DSAParameterNumbers(p=1, q=None, g=3)
+
+ with pytest.raises(TypeError):
+ dsa.DSAParameterNumbers(p=1, q=2, g=None)
+
+ def test_dsa_public_numbers(self):
+ parameter_numbers = dsa.DSAParameterNumbers(p=1, q=2, g=3)
+ public_numbers = dsa.DSAPublicNumbers(
+ y=4,
+ parameter_numbers=parameter_numbers
+ )
+ assert public_numbers.y == 4
+ assert public_numbers.parameter_numbers == parameter_numbers
+
+ def test_dsa_public_numbers_invalid_types(self):
+ with pytest.raises(TypeError):
+ dsa.DSAPublicNumbers(y=4, parameter_numbers=None)
+
+ with pytest.raises(TypeError):
+ parameter_numbers = dsa.DSAParameterNumbers(p=1, q=2, g=3)
+ dsa.DSAPublicNumbers(y=None, parameter_numbers=parameter_numbers)
+
+ def test_dsa_private_numbers(self):
+ parameter_numbers = dsa.DSAParameterNumbers(p=1, q=2, g=3)
+ public_numbers = dsa.DSAPublicNumbers(
+ y=4,
+ parameter_numbers=parameter_numbers
+ )
+ private_numbers = dsa.DSAPrivateNumbers(
+ x=5,
+ public_numbers=public_numbers
+ )
+ assert private_numbers.x == 5
+ assert private_numbers.public_numbers == public_numbers
+
+ def test_dsa_private_numbers_invalid_types(self):
+ parameter_numbers = dsa.DSAParameterNumbers(p=1, q=2, g=3)
+ public_numbers = dsa.DSAPublicNumbers(
+ y=4,
+ parameter_numbers=parameter_numbers
+ )
+ with pytest.raises(TypeError):
+ dsa.DSAPrivateNumbers(x=4, public_numbers=None)
+
+ with pytest.raises(TypeError):
+ dsa.DSAPrivateNumbers(x=None, public_numbers=public_numbers)