diff options
-rw-r--r-- | cryptography/hazmat/backends/interfaces.py | 6 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py | 4 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/dsa.py | 3 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/asymmetric/dsa.py | 4 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/interfaces.py | 6 | ||||
-rw-r--r-- | docs/hazmat/primitives/asymmetric/dsa.rst | 32 | ||||
-rw-r--r-- | docs/hazmat/primitives/interfaces.rst | 11 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_dsa.py | 13 |
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) |