summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2020-07-05 20:19:39 -0500
committerGitHub <noreply@github.com>2020-07-05 21:19:39 -0400
commit7a233b9a602d76684e17d509d9a5378eeee6a362 (patch)
treed60808a532177952e8abe2b3185bce4eda54bd2d
parentc8689610332ff444580f1cdf08d50909290af008 (diff)
downloadcryptography-7a233b9a602d76684e17d509d9a5378eeee6a362.tar.gz
support 4096 bit DSA parsing from numbers classes (#5301)
* support 4096 bit DSA parsing from numbers classes * need to get local linting fixed. * reorder * add a link to more reasons why DSA sucks
-rw-r--r--docs/development/test-vectors.rst2
-rw-r--r--docs/hazmat/primitives/asymmetric/dsa.rst34
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py6
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/dsa.py6
-rw-r--r--tests/hazmat/primitives/test_dsa.py22
-rw-r--r--vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem36
6 files changed, 92 insertions, 14 deletions
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index 48f7bb3a9..2e3acaab4 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -78,6 +78,8 @@ Custom asymmetric vectors
* ``asymmetric/PEM_Serialization/rsa_public_key.pem`` and
``asymmetric/DER_Serialization/rsa_public_key.der``- Contains an RSA 2048
bit public generated using OpenSSL from ``rsa_private_key.pem``.
+* ``asymmetric/PEM_Serialization/dsa_4096.pem`` - Contains a 4096-bit DSA
+ private key generated using OpenSSL.
* ``asymmetric/PEM_Serialization/dsaparam.pem`` - Contains 2048-bit DSA
parameters generated using OpenSSL; contains no keys.
* ``asymmetric/PEM_Serialization/dsa_private_key.pem`` - Contains a DSA 2048
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 1456de454..142ce1aeb 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -5,6 +5,13 @@ DSA
.. module:: cryptography.hazmat.primitives.asymmetric.dsa
+.. note::
+
+ DSA is a **legacy algorithm** and should generally be avoided in favor of
+ choices like
+ :doc:`EdDSA using curve25519</hazmat/primitives/asymmetric/ed25519>` or
+ :doc:`ECDSA</hazmat/primitives/asymmetric/ec>`.
+
`DSA`_ is a `public-key`_ algorithm for signing messages.
Generation
@@ -14,15 +21,18 @@ Generation
.. versionadded:: 0.5
+ .. versionchanged:: 3.0
+
+ Added support for 4096-bit keys for some legacy applications that
+ continue to use DSA despite the wider cryptographic community's
+ `ongoing protestations`_.
+
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 :term:`bits`. It should
- be either 1024, 2048 or 3072. For keys generated in 2015 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.
+ be either 1024, 2048, 3072, or 4096. For keys generated in 2015 this
+ should be `at least 2048`_ (See page 41).
:param backend: An instance of
:class:`~cryptography.hazmat.backends.interfaces.DSABackend`.
@@ -38,14 +48,17 @@ Generation
.. versionadded:: 0.5
+ .. versionchanged:: 3.0
+
+ Added support for 4096-bit keys for some legacy applications that
+ continue to use DSA despite the wider cryptographic community's
+ `ongoing protestations`_.
+
Generate DSA parameters using the provided ``backend``.
:param int key_size: The length of :attr:`~DSAParameterNumbers.q`. It
- should be either 1024, 2048 or 3072. For keys generated in 2015 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.
+ should be either 1024, 2048, 3072, or 4096. For keys generated in 2015
+ this should be `at least 2048`_ (See page 41).
:param backend: An instance of
:class:`~cryptography.hazmat.backends.interfaces.DSABackend`.
@@ -446,3 +459,4 @@ Key interfaces
.. _`public-key`: https://en.wikipedia.org/wiki/Public-key_cryptography
.. _`FIPS 186-4`: https://csrc.nist.gov/publications/detail/fips/186/4/final
.. _`at least 2048`: https://www.cosic.esat.kuleuven.be/ecrypt/ecrypt2/documents/D.SPA.20.pdf
+.. _`ongoing protestations`: https://buttondown.email/cryptography-dispatches/archive/cryptography-dispatches-dsa-is-past-its-prime/
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 9ca75d8b9..83b64411d 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -626,8 +626,10 @@ class Backend(object):
return False
def generate_dsa_parameters(self, key_size):
- if key_size not in (1024, 2048, 3072):
- raise ValueError("Key size must be 1024 or 2048 or 3072 bits.")
+ if key_size not in (1024, 2048, 3072, 4096):
+ raise ValueError(
+ "Key size must be 1024, 2048, 3072, or 4096 bits."
+ )
ctx = self._lib.DSA_new()
self.openssl_assert(ctx != self._ffi.NULL)
diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
index e380a441f..678b9d494 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -128,8 +128,10 @@ def generate_private_key(key_size, backend):
def _check_dsa_parameters(parameters):
- if parameters.p.bit_length() not in [1024, 2048, 3072]:
- raise ValueError("p must be exactly 1024, 2048, or 3072 bits long")
+ if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]:
+ raise ValueError(
+ "p must be exactly 1024, 2048, 3072, or 4096 bits long"
+ )
if parameters.q.bit_length() not in [160, 224, 256]:
raise ValueError("q must be exactly 160, 224, or 256 bits long")
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 9e1acf935..4287ad2a0 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -349,6 +349,28 @@ class TestDSA(object):
y=y
).public_key(backend)
+ def test_large_p(self, backend):
+ key = load_vectors_from_file(
+ os.path.join("asymmetric", "PEM_Serialization", "dsa_4096.pem"),
+ lambda pemfile: serialization.load_pem_private_key(
+ pemfile.read(), None, backend
+ ), mode="rb"
+ )
+ pn = key.private_numbers()
+ assert pn.public_numbers.parameter_numbers.p.bit_length() == 4096
+ # Turn it back into a key to confirm that values this large pass
+ # verification
+ dsa.DSAPrivateNumbers(
+ public_numbers=dsa.DSAPublicNumbers(
+ parameter_numbers=dsa.DSAParameterNumbers(
+ p=pn.public_numbers.parameter_numbers.p,
+ q=pn.public_numbers.parameter_numbers.q,
+ g=pn.public_numbers.parameter_numbers.g,
+ ),
+ y=pn.public_numbers.y
+ ), x=pn.x
+ ).private_key(backend)
+
@pytest.mark.requires_backend_interface(interface=DSABackend)
class TestDSAVerification(object):
diff --git a/vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem b/vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem
new file mode 100644
index 000000000..af14d247b
--- /dev/null
+++ b/vectors/cryptography_vectors/asymmetric/PEM_Serialization/dsa_4096.pem
@@ -0,0 +1,36 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIGVQIBAAKCAgEAy8x5LsdCM2fSykikHtoZZPXcZIRm6ZQQTdpkOHyX9AAqVVpc
+kXqUltbd1rLCPLrii/Syg1XBwsna7fUEci13xUHDk/97TLG9Z0qIH7NgdBQSFGTL
+GWLRbp83nE1Hc+/b0htaABTT5AV5q54xoDED8AuP1b2l7SxrgJz/uDsvZcmHM0y3
+AxTiFkPCqNM+nHN7w3A5NJmFlvm3pl/8B9DCvLXILqiFYpKwewa4f3RUIqCuKlgJ
+y1Yj5BtjiWzJV6153vuAuFaD86G7Pck6VQDEpaY8u0LrjAAgzjaUvD45uDgkw2HT
+/sJDAkIWjpyPEEvXNUmgC8Eh52GCeJkT5iG04a83k67VPbbS3dENRgzrfYpmRIlJ
+lfoxtIpFEkDT8jpioDIzven7JNIhNND0Y/bs3pxnkIjrs3jPGpW9dtoeP2RYSlle
+QGqhu/B8lIEpruy94/Ujz7nVYnNSHZGY/Xk2pLR78B1tzk/mojcgTGtq76GHuY4+
+p2I49qThgWOGBT8b9ysYgI2momHcDkauYDq+l0dLg6h6XPPsXU/8qHL2e5bCW1ub
+uMb0T4NwbLwl9rHc2gcKxfdqnK0S4hgfWR5nhDsLyBl04mBqnZaoQ/1Re5Kp1ZPU
+a8/CR0oktwh8ZP0TmUbExSd8s/kAUJl49Fp2EGxFX3pF2u+mucbd7iDLVzMCIQC8
+2B6GLZaBrH0OZX2UWz8A10CuSHAqib45GIwrcEqVawKCAgALNtzq+Ap3IPQrjnsv
+H9VLVoLx2X37UF6DQbX9ZMcnKNwooVNxkLPXokMIbVPcsegavw1ECgiCu/Ung+aM
+Whd5w4iMMxq82I9nd8M2GUvg2QYYz5WOLsbJTk1kcV0WF+MzMrWCAuXiuCfYj90X
+/TT4Dhd037fVfktjwzJFtox/NKKAM96/wm1MHfwy4s7L1cTe1IZZocZDB/4l9Ciw
+zNAc/VlNfmheAp2RlrdY2waHVCdU/AJt3SNghUqLAn5dJELKyY37Kl9OHxlnWhTl
+dTBzC6VFo4Gkro28/C2kY/PYkShEXPT1c8D63lbYdUt5dgnfkDpddjRvgXGLOltJ
+1/iogrMq2EKYECoXtNzM7xXu4vxMNERjbyuhWg9qw0mczFgel1R7UWeMAz5a7J5S
+fHs2p94/iyQZPHHzR4DEXC/dcuUer5koPJvdIO6hbqMtfcWEusOEdOxRapjrzaLN
+bCaL4c33j8y7FOK2JC+FAz4ljI9AIsomt73tyrRK0PFUrlh147cuOKZAGYHQJlaX
+z6R/W8z71vO00/VvIZuzHOYiGZQdQ9FUiilQfrhGTF+SOyjBMSSantUUVUoYRC7E
+Tc83vQEQnpe5VjX+naSCk/zv1JFGSSpmWn45aDSswmA9EjyKxg1Ae0MrshB8a80M
+eqRrfGtlLuGT0KiYKse9z90VTAKCAgBFBTIdD1g7KRadTcyhoXw5+zMv9vVb4kDx
+UAyuqPulh3xadD1FUMukQWjCzJDtx8xDSOj1U9Tal/DsUBtzS+MyPAQdsXhs4oYq
+ska/OWc8287dtX2U511de2bd5GS9rI++HKLHES9RBkAhuo7l5cc+TGJ8XeFgbmdF
+DStjyLy4ABLG0Fkk70nMHIIGal/axBz0kYhSf1W1XO2y2PAY8/sNwdHwI7TimEcL
+qxakgneBjLn7L+SO3N5IRI1eLwl/0sj6ZUoaV6ZpPuTNDTo+7PQlMP+OqIL77R/M
+2rsJSE186CI8IR99K7PylS2Gk+RWv6NcYnZCOcP4UdXEg7/cECjWaSKqn20q2Jrs
+ZuVrRoVF4XsHmcItYj8JyeFcGUgUSlPVNMvO9L11IMvvgo9EQ5OU0UHiBZRoWWu6
+GWx7VqqNU078z2jL+q8MFcqNzqXM64DtVDc1sjdZSLcNzKRWiMrnek4MB+aL1l7G
+hXdDRkj3qTRrkvzHBfxDm2u4lpMInFci1Lu0oxgqLEISYAGdyb1we+OMeqR12YUr
+QP5/DtJdntE0hKMIWGkAYHvIowu2ZOUPs6mdgJZ/IL3qJsvLG2ZFpe3aBnbL8qj7
+/ezCts5E509IwRiVhvEik6ZKUjSYojkcWL88p4PGZsP1/iG8KQgMnCrPIOjYVTVM
+Qs3D7GFsYAIgAhium9LrIx3luKDOsxS4nX9f8xChr+Z1Ej8xgaqp96Y=
+-----END DSA PRIVATE KEY-----