aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-06-27 09:15:07 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-06-27 09:15:07 -0600
commitdacb5f9951064d19ac69c1198985af136f71a6db (patch)
treef40e491487856a46a2fd93167ab24fdaf07412c8
parenta44338b355a628ba7d732063551650cd9f8b2cb8 (diff)
downloadcryptography-dacb5f9951064d19ac69c1198985af136f71a6db.tar.gz
cryptography-dacb5f9951064d19ac69c1198985af136f71a6db.tar.bz2
cryptography-dacb5f9951064d19ac69c1198985af136f71a6db.zip
add generate_private_key to DSAParameters + add a new function to dsa
dsa.generate_private_key(key_size, backend) will allow you to generate a new DSA key and implicitly generate new parameters. This streamlines the common case and will be an avenue to support future backends that don't allow independent generation of DSAParameters (e.g. CommonCrypto)
-rw-r--r--cryptography/hazmat/backends/interfaces.py6
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py4
-rw-r--r--cryptography/hazmat/backends/openssl/dsa.py3
-rw-r--r--cryptography/hazmat/primitives/asymmetric/dsa.py4
-rw-r--r--cryptography/hazmat/primitives/interfaces.py6
-rw-r--r--docs/hazmat/primitives/asymmetric/dsa.rst32
-rw-r--r--docs/hazmat/primitives/interfaces.rst11
-rw-r--r--tests/hazmat/primitives/test_dsa.py13
8 files changed, 62 insertions, 17 deletions
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index e4faf32c..70168a01 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -171,6 +171,12 @@ class DSABackend(object):
"""
@abc.abstractmethod
+ def generate_dsa_private_key_with_key_size(self, key_size):
+ """
+ Generate an DSAPrivateKey instance using key size only.
+ """
+
+ @abc.abstractmethod
def create_dsa_signature_ctx(self, private_key, algorithm):
"""
Returns an object conforming to the AsymmetricSignatureContext
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 6245e8e4..82bdd7cd 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -626,6 +626,10 @@ class Backend(object):
return _DSAPrivateKey(self, ctx)
+ def generate_dsa_private_key_with_key_size(self, key_size):
+ parameters = self.generate_dsa_parameters(key_size)
+ return self.generate_dsa_private_key(parameters)
+
def create_dsa_signature_ctx(self, private_key, algorithm):
dsa_cdata = self._dsa_cdata_from_private_key(private_key)
key = _DSAPrivateKey(self, dsa_cdata)
diff --git a/cryptography/hazmat/backends/openssl/dsa.py b/cryptography/hazmat/backends/openssl/dsa.py
index d492372f..5e7a26ff 100644
--- a/cryptography/hazmat/backends/openssl/dsa.py
+++ b/cryptography/hazmat/backends/openssl/dsa.py
@@ -97,6 +97,9 @@ class _DSAParameters(object):
g=self._backend._bn_to_int(self._dsa_cdata.g)
)
+ def generate_private_key(self):
+ return self._backend.generate_dsa_private_key(self)
+
@utils.register_interface(DSAPrivateKeyWithNumbers)
class _DSAPrivateKey(object):
diff --git a/cryptography/hazmat/primitives/asymmetric/dsa.py b/cryptography/hazmat/primitives/asymmetric/dsa.py
index 527b6bbc..08bdad3e 100644
--- a/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -25,8 +25,8 @@ def generate_parameters(key_size, backend):
return backend.generate_dsa_parameters(key_size)
-def generate_private_key(parameters):
- return parameters._backend.generate_dsa_private_key(parameters)
+def generate_private_key(key_size, backend):
+ return backend.generate_dsa_private_key_with_key_size(key_size)
def _check_dsa_parameters(parameters):
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index ef8640c2..d60f9e0e 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -251,7 +251,11 @@ class RSAPublicKeyWithNumbers(RSAPublicKey):
@six.add_metaclass(abc.ABCMeta)
class DSAParameters(object):
- pass
+ @abc.abstractmethod
+ def generate_private_key(self):
+ """
+ Generates and returns a DSAPrivateKey.
+ """
@six.add_metaclass(abc.ABCMeta)
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 42e3af2e..095c49b9 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -7,11 +7,12 @@ DSA
`DSA`_ is a `public-key`_ algorithm for signing messages.
-.. function:: generate_parameters(key_size, backend)
+.. function:: generate_private_key(key_size, backend)
.. versionadded:: 0.5
- Generate DSA parameters using the provided ``backend``.
+ Generate a DSA private key from the given key size. This function will
+ generate a new set of parameters and key in one step.
:param int key_size: The length of the modulus in bits. It should be
either 1024, 2048 or 3072. For keys generated in 2014 this should
@@ -24,26 +25,33 @@ DSA
:class:`~cryptography.hazmat.backends.interfaces.DSABackend`
provider.
- :return: A :class:`~cryptography.hazmat.primitives.interfaces.DSAParameters`
+ :return: A :class:`~cryptography.hazmat.primitives.interfaces.DSAPrivateKey`
provider.
- :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if
- the provided ``backend`` does not implement
- :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
-
-.. function:: generate_private_key(parameters)
+.. function:: generate_parameters(key_size, backend)
.. versionadded:: 0.5
- Generate an DSA private key using the provided parameters.
+ Generate DSA parameters using the provided ``backend``.
- :param parameters: A
- :class:`~cryptography.hazmat.primitives.interfaces.DSAParameters`
+ :param int key_size: The length of the modulus in bits. It should be
+ either 1024, 2048 or 3072. For keys generated in 2014 this should
+ be `at least 2048`_ (See page 41). Note that some applications
+ (such as SSH) have not yet gained support for larger key sizes
+ specified in FIPS 186-3 and are still restricted to only the
+ 1024-bit keys specified in FIPS 186-2.
+
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
provider.
- :return: A :class:`~cryptography.hazmat.primitives.interfaces.DSAPrivateKey`
+ :return: A :class:`~cryptography.hazmat.primitives.interfaces.DSAParameters`
provider.
+ :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if
+ the provided ``backend`` does not implement
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend`
+
.. class:: DSAParameters(modulus, subgroup_order, generator)
.. versionadded:: 0.4
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index 755cef41..ac47c1e1 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -282,6 +282,17 @@ DSA
`DSA`_ parameters.
+ .. method:: generate_private_key()
+
+ .. versionadded:: 0.5
+
+ Generate a DSA private key. This method can be used to generate many
+ new private keys from a single set of parameters.
+
+ :return: A
+ :class:`~cryptography.hazmat.primitives.interfaces.DSAPrivateKey`
+ provider.
+
.. class:: DSAParametersWithNumbers
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 76436f79..531b448f 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -77,7 +77,6 @@ class TestDSA(object):
def test_generate_dsa_parameters(self, backend):
parameters = dsa.generate_parameters(1024, backend)
assert isinstance(parameters, interfaces.DSAParameters)
- # TODO: withnumbers check like RSA
def test_generate_invalid_dsa_parameters(self, backend):
with pytest.raises(ValueError):
@@ -97,7 +96,7 @@ class TestDSA(object):
q=vector['q'],
g=vector['g']
).parameters(backend)
- skey = dsa.generate_private_key(parameters)
+ skey = parameters.generate_private_key()
if isinstance(skey, interfaces.DSAPrivateKeyWithNumbers):
numbers = skey.private_numbers()
skey_parameters = numbers.public_numbers.parameter_numbers
@@ -118,6 +117,16 @@ class TestDSA(object):
skey_parameters.g, numbers.x, skey_parameters.p
)
+ def test_generate_dsa_private_key_and_parameters(self, backend):
+ skey = dsa.generate_private_key(1024, backend)
+ assert skey
+ if isinstance(skey, interfaces.DSAPrivateKeyWithNumbers):
+ numbers = skey.private_numbers()
+ skey_parameters = numbers.public_numbers.parameter_numbers
+ assert numbers.public_numbers.y == pow(
+ skey_parameters.g, numbers.x, skey_parameters.p
+ )
+
def test_invalid_parameters_argument_types(self):
with pytest.raises(TypeError):
dsa.DSAParameters(None, None, None)