aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/development/test-vectors.rst14
-rw-r--r--docs/hazmat/primitives/asymmetric/dh.rst64
-rw-r--r--docs/hazmat/primitives/asymmetric/index.rst1
-rw-r--r--docs/spelling_wordlist.txt1
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/dh.py101
-rw-r--r--tests/hazmat/primitives/test_dh.py113
-rw-r--r--vectors/cryptography_vectors/x509/requests/dsa_sha1.pem15
-rw-r--r--vectors/cryptography_vectors/x509/requests/ec_sha256.pem10
-rw-r--r--vectors/cryptography_vectors/x509/requests/rsa_md4.pem16
-rw-r--r--vectors/cryptography_vectors/x509/requests/rsa_sha1.pem16
-rw-r--r--vectors/cryptography_vectors/x509/requests/rsa_sha256.pem16
11 files changed, 367 insertions, 0 deletions
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index 2cd9faa6..a0849a40 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -104,6 +104,20 @@ Custom X.509 Vectors
generated using OpenSSL that contains a UTF8String common name with the value
"We heart UTF8!™".
+Custom X.509 Request Vectors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* ``dsa_sha1.pem`` - Contains a certificate request using 1024-bit DSA
+ parameters and SHA1 generated using OpenSSL.
+* ``rsa_md4.pem`` - Contains a certificate request using 2048 bit RSA and MD4
+ generated using OpenSSL.
+* ``rsa_sha1.pem`` - Contains a certificate request using 2048 bit RSA and
+ SHA1 generated using OpenSSL.
+* ``rsa_sha256.pem`` - Contains a certificate request using 2048 bit RSA and
+ SHA256 generated using OpenSSL.
+* ``ec_sha256.pem`` - Contains a certificate request using EC (``secp384r1``)
+ and SHA256 generated using OpenSSL.
+
Hashes
~~~~~~
diff --git a/docs/hazmat/primitives/asymmetric/dh.rst b/docs/hazmat/primitives/asymmetric/dh.rst
new file mode 100644
index 00000000..fdf113f7
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/dh.rst
@@ -0,0 +1,64 @@
+.. hazmat::
+
+Diffie-Hellman key exchange
+===========================
+
+.. currentmodule:: cryptography.hazmat.primitives.asymmetric.dh
+
+
+.. class:: DHPrivateNumbers(x, public_numbers)
+
+ .. versionadded:: 0.8
+
+ The collection of integers that make up a Diffie-Hellman private key.
+
+ .. attribute:: public_numbers
+
+ :type: :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicNumbers`
+
+ The :class:`DHPublicNumbers` which makes up the DH public
+ key associated with this DH private key.
+
+ .. attribute:: x
+
+ :type: int
+
+ The private value.
+
+
+.. class:: DHPublicNumbers(parameters, y)
+
+ .. versionadded:: 0.8
+
+ The collection of integers that make up a Diffie-Hellman public key.
+
+ .. attribute:: parameter_numbers
+
+ :type: :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHParameterNumbers`
+
+ The parameters for this DH group.
+
+ .. attribute:: y
+
+ :type: int
+
+ The public value.
+
+
+.. class:: DHParameterNumbers(p, g)
+
+ .. versionadded:: 0.8
+
+ The collection of integers that define a Diffie-Hellman group.
+
+ .. attribute:: p
+
+ :type: int
+
+ The prime modulus value.
+
+ .. attribute:: g
+
+ :type: int
+
+ The generator value.
diff --git a/docs/hazmat/primitives/asymmetric/index.rst b/docs/hazmat/primitives/asymmetric/index.rst
index 59f00c5d..4242a0bd 100644
--- a/docs/hazmat/primitives/asymmetric/index.rst
+++ b/docs/hazmat/primitives/asymmetric/index.rst
@@ -29,6 +29,7 @@ and Elliptic Curve.
dsa
ec
rsa
+ dh
serialization
interfaces
utils
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 6e545370..81310d2d 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -14,6 +14,7 @@ crypto
cryptographic
cryptographically
Debian
+Diffie
decrypt
decrypted
decrypting
diff --git a/src/cryptography/hazmat/primitives/asymmetric/dh.py b/src/cryptography/hazmat/primitives/asymmetric/dh.py
new file mode 100644
index 00000000..61556efb
--- /dev/null
+++ b/src/cryptography/hazmat/primitives/asymmetric/dh.py
@@ -0,0 +1,101 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+import six
+
+from cryptography import utils
+
+
+class DHPrivateNumbers(object):
+ def __init__(self, x, public_numbers):
+ if not isinstance(x, six.integer_types):
+ raise TypeError("x must be an integer.")
+
+ if not isinstance(public_numbers, DHPublicNumbers):
+ raise TypeError("public_numbers must be an instance of "
+ "DHPublicNumbers.")
+
+ self._x = x
+ self._public_numbers = public_numbers
+
+ def __eq__(self, other):
+ if not isinstance(other, DHPrivateNumbers):
+ return NotImplemented
+
+ return (
+ self._x == other._x and
+ self._public_numbers == other._public_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ public_numbers = utils.read_only_property("_public_numbers")
+ x = utils.read_only_property("_x")
+
+
+class DHPublicNumbers(object):
+ def __init__(self, y, parameter_numbers):
+ if not isinstance(y, six.integer_types):
+ raise TypeError("y must be an integer.")
+
+ if not isinstance(parameter_numbers, DHParameterNumbers):
+ raise TypeError(
+ "parameters must be an instance of DHParameterNumbers.")
+
+ self._y = y
+ self._parameter_numbers = parameter_numbers
+
+ def __eq__(self, other):
+ if not isinstance(other, DHPublicNumbers):
+ return NotImplemented
+
+ return (
+ self._y == other._y and
+ self._parameter_numbers == other._parameter_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ y = utils.read_only_property("_y")
+ parameter_numbers = utils.read_only_property("_parameter_numbers")
+
+
+class DHParameterNumbers(object):
+ def __init__(self, p, g):
+ if (
+ not isinstance(p, six.integer_types) or
+ not isinstance(g, six.integer_types)
+ ):
+ raise TypeError("p and g must be integers")
+
+ self._p = p
+ self._g = g
+
+ def __eq__(self, other):
+ if not isinstance(other, DHParameterNumbers):
+ return NotImplemented
+
+ return (
+ self._p == other._p and
+ self._g == other._g
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ p = utils.read_only_property("_p")
+ g = utils.read_only_property("_g")
diff --git a/tests/hazmat/primitives/test_dh.py b/tests/hazmat/primitives/test_dh.py
new file mode 100644
index 00000000..115f3d8c
--- /dev/null
+++ b/tests/hazmat/primitives/test_dh.py
@@ -0,0 +1,113 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+import pytest
+
+from cryptography.hazmat.primitives.asymmetric import dh
+
+
+def test_dh_parameternumbers():
+ params = dh.DHParameterNumbers(
+ 65537, 3
+ )
+
+ assert params.p == 65537
+ assert params.g == 3
+
+ with pytest.raises(TypeError):
+ dh.DHParameterNumbers(
+ None, 3
+ )
+
+ with pytest.raises(TypeError):
+ dh.DHParameterNumbers(
+ 65537, None
+ )
+
+ with pytest.raises(TypeError):
+ dh.DHParameterNumbers(
+ None, None
+ )
+
+
+def test_dh_numbers():
+ params = dh.DHParameterNumbers(
+ 65537, 3
+ )
+
+ public = dh.DHPublicNumbers(
+ 1, params
+ )
+
+ assert public.parameter_numbers is params
+ assert public.y == 1
+
+ with pytest.raises(TypeError):
+ dh.DHPublicNumbers(
+ 1, None
+ )
+
+ with pytest.raises(TypeError):
+ dh.DHPublicNumbers(
+ None, params
+ )
+
+ private = dh.DHPrivateNumbers(
+ 1, public
+ )
+
+ assert private.public_numbers is public
+ assert private.x == 1
+
+ with pytest.raises(TypeError):
+ dh.DHPrivateNumbers(
+ 1, None
+ )
+
+ with pytest.raises(TypeError):
+ dh.DHPrivateNumbers(
+ None, public
+ )
+
+
+def test_dh_parameter_numbers_equality():
+ assert dh.DHParameterNumbers(65537, 3) == dh.DHParameterNumbers(65537, 3)
+ assert dh.DHParameterNumbers(6, 3) != dh.DHParameterNumbers(65537, 3)
+ assert dh.DHParameterNumbers(65537, 0) != dh.DHParameterNumbers(65537, 3)
+ assert dh.DHParameterNumbers(65537, 0) != object()
+
+
+def test_dh_private_numbers_equality():
+ params = dh.DHParameterNumbers(65537, 3)
+ public = dh.DHPublicNumbers(1, params)
+ private = dh.DHPrivateNumbers(2, public)
+
+ assert private == dh.DHPrivateNumbers(2, public)
+ assert private != dh.DHPrivateNumbers(0, public)
+ assert private != dh.DHPrivateNumbers(2, dh.DHPublicNumbers(0, params))
+ assert private != dh.DHPrivateNumbers(
+ 2, dh.DHPublicNumbers(1, dh.DHParameterNumbers(65537, 0))
+ )
+ assert private != object()
+
+
+def test_dh_public_numbers_equality():
+ params = dh.DHParameterNumbers(65537, 3)
+ public = dh.DHPublicNumbers(1, params)
+
+ assert public == dh.DHPublicNumbers(1, params)
+ assert public != dh.DHPublicNumbers(0, params)
+ assert public != dh.DHPublicNumbers(1, dh.DHParameterNumbers(65537, 0))
+ assert public != object()
diff --git a/vectors/cryptography_vectors/x509/requests/dsa_sha1.pem b/vectors/cryptography_vectors/x509/requests/dsa_sha1.pem
new file mode 100644
index 00000000..11688dbb
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/requests/dsa_sha1.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICWDCCAhgCAQAwVzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMQ0wCwYDVQQK
+DARQeUNBMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1
+c3RpbjCCAbYwggErBgcqhkjOOAQBMIIBHgKBgQCNf628CeKEqvppFUzqJBdwBJCe
+UZ+LNdaFzeW07NyVg+dNNwoPiK2pjwJvJ3Yvs9XaeDb5ht/Ns1ieW5Jb6hFN78A+
++B2uMMJLvG3z1YjpNCe7pkID1KWxaHsrXjtkPUxhSXb4n5WjjT5MiQZfupdRTCLF
+Ctu/KJFjp0tUhZs1twIVAINd5WvQfPf4LiAy/niUmu0ReqLvAoGAH3F7Wgd4L8Lk
+5o4xH+qRpU7dNrhqxjTRTwWmipfq6dLvMfse895Cw9EA35ymT1vcKux7/ftHTPgx
+/qBYU7XgWfLSSYCgrEY/HoGK81I+PLeaOdRfqScxiXdShCRpz4VAsBSRAk6q+85g
+GOih9GWMND9Lp8CyHlN2oh9L64SRlh4DgYQAAoGABxPwdkH2Npu1qVRSdKLUwBmY
+Nn+zcbueE0NjY2cu1o+CF0wt4FyOg5vG3laN1QuijY2dhxlCOq7FVX3xDXc6si1t
+Zcu4eASml7yP2WW5Uvn36FDt8TyKzbXXU7bRDlngtXMuPIK6+hQDQrxKO7oWvQaB
+yKai27t+/mziuEY7FwugADAJBgcqhkjOOAQDAy8AMCwCFGHVjcAo0BEIGKfYF9dC
+NXJ8Ss/fAhQJe1LhmOzpXeFyc/CpJN8jzp2BiA==
+-----END CERTIFICATE REQUEST-----
diff --git a/vectors/cryptography_vectors/x509/requests/ec_sha256.pem b/vectors/cryptography_vectors/x509/requests/ec_sha256.pem
new file mode 100644
index 00000000..9497ae3c
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/requests/ec_sha256.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBTzCB1gIBADBXMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8xDTALBgNVBAoM
+BFB5Q0ExCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVz
+dGluMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3hm1FMCzw66bOY6j4mtegWvc+RAs
+rY8S/gL55MkkhySzkpftdYLgTYsypVEDjQkIaAOm0/uRoaEWfsAhWLAO+tOck5ZG
+L6zP8P+vcVWBKQnTcmvVn94AHP9LubL1r4y6oAAwCgYIKoZIzj0EAwIDaAAwZQIw
+LBqffejBeHMy0jB6iGtHalnxcrmw4lAmLzI4sbRe4RK7brNbD7VqEjuSlushLf/D
+AjEAlM9EDJXFKCfVVq5tdlAOMAglXUfCn37ngu11WOUb/XaqRd9tmZ7VxGM0f+I4
+LRdR
+-----END CERTIFICATE REQUEST-----
diff --git a/vectors/cryptography_vectors/x509/requests/rsa_md4.pem b/vectors/cryptography_vectors/x509/requests/rsa_md4.pem
new file mode 100644
index 00000000..f62c8ef8
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/requests/rsa_md4.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICnDCCAYQCAQAwVzEYMBYGA1UEAwwPY3J5cHRvZ3JhcGh5LmlvMQ0wCwYDVQQK
+DARQeUNBMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1
+c3RpbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMpZCKiob1IpjL+4
+S/J9Jgcm0ewZ/TbgJw9MB2sTQu7Ljmad9MttNeMyd9wa9fQIhenlpKjJWPSBekSX
+P0uvbAKkY00eCM/mi5Deb2lZaXkfpFC2DlsOKm4uyzmyd/ob2/rSeml7+u+xnGSM
+1MeYjuS5R7KrQUX+HJyw53cxkEHykXcsAvu3WxpnpZzLSFBNiE6lJZUl4vH86aUl
+qrB4C87c150uT01ouEqpon8KfwCnuH1Zqw1e+XVoW6sMqvkoqx2uSJxlMzlWpXhI
+rd3bMXHJ+mJyuDP5UVhQU0WuWXPO1JzEfVwVKigbpy8heHare/6tFHXp3V98fhEO
+qJGaArUCAwEAAaAAMA0GCSqGSIb3DQEBAwUAA4IBAQCp9f8iBtvibyoBB5W+h9RS
+IsbL/bY46MzfjkWaCr1GACC3FefO88qsQYZJNsnqrHKwl8BJUNxf5bLMyFmyLW9D
+jBah8wfo3ftjos1u1F1Bt31FcL7UlDoDLZ1LA3cP/JodSbUVZ8ByVI1bj0MRdAx5
+16YNJvCtzXQtoRZxr940u+S10G6E8sSwfGjqJIgOTiF3oYmS1hSBsIGJzrJ4HOp/
+FAN5pxYW3C0sAM4Aq7qSRHQdFoIXovgRxB4XFedIveEidralOe1K0ShV675jmjwa
+zoO/bTZGCIISD3KoIaCdkJjKoN0r2ckwhBTxsQsC6iO/FU5rBS4DG7369Y7FNIJ6
+-----END CERTIFICATE REQUEST-----
diff --git a/vectors/cryptography_vectors/x509/requests/rsa_sha1.pem b/vectors/cryptography_vectors/x509/requests/rsa_sha1.pem
new file mode 100644
index 00000000..0656c316
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/requests/rsa_sha1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICnDCCAYQCAQAwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVRleGFzMQ8wDQYD
+VQQHEwZBdXN0aW4xDTALBgNVBAoTBFB5Q0ExGDAWBgNVBAMTD2NyeXB0b2dyYXBo
+eS5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKhAp4Rgy4YQZt+j
+BFqUumzxt6udJMdhz/3cwstePx3D5L4lPnA57xT+nW0jBPUNny4VhMUVMKt1CG81
+cTi/97hU0GfR1fOE8fLyw5zDsVQV4mOFVO+EAmSK4+8IM28it+zG1DMcKyHDCRp/
+epUYGAdUpkZkC2BBnkzG9ceYEQp/Awpjn+h+M7R3bfzZk5QOx3arV6GBrYWYhXl2
+3DA/mlc8phmrP+WWMo6SgGuChoPtwXzCVrQZSKK/qNBH0hWNPY4GmqBfqFsycqux
+xLRCK2Nm87cOZCN3sUXNYlnl0+fbBI1Rkh5Qdmo3sbEw7msR9QfSCoNAAejeFqks
+FPLpZKMCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4IBAQCDZMhv+7/gv8miH4MSVmWM
+qJiXQbgFdtNvCKk0YDpDsYNyRtABZ6UYq7Hee1Gh5bfr6hSUSACBixqSPIBPEgoN
+Yk9jEO956GEnVcKwHcx/Wd/bzg2z8mMPGF9QS4wXr4DL02T6X9poM3FTkwlIImzU
+Y4KHoK7WUk0wBohcGQKKHuL1qR1ud9uqC0mZbuCgxgtVthvQgKCLs0qn8+B+kfN/
+ahFkW+LYZUwVcNzaFF7XzJIBf31TIl1/KD80Wexb2kHPbdddQ2dsVDSDOFImt+T6
+KchznxsOrxmWE1k5kZeYYuNhgejEwnDDVLf1LBKNsbcGOYIzJMfqJHkbe8PXAF87
+-----END CERTIFICATE REQUEST-----
diff --git a/vectors/cryptography_vectors/x509/requests/rsa_sha256.pem b/vectors/cryptography_vectors/x509/requests/rsa_sha256.pem
new file mode 100644
index 00000000..06393d23
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/requests/rsa_sha256.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICnDCCAYQCAQAwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYD
+VQQHDAZBdXN0aW4xDTALBgNVBAoMBFB5Q0ExGDAWBgNVBAMMD2NyeXB0b2dyYXBo
+eS5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWsaWBzupTPnC9A
+xS2dbZtOCRgERIKL+SVOxaFdXko/TsmbUCY2GQ8xhLvhD0R1kEnpzI+wQ/3OQraq
+XysouWEVJp07L7AW14tkAwuo+Jy8/Or7NUrOCtOTN2fEO+hT81ihaocG5CwbEUUE
+QGSzX9XJjuyVUBRpou8muv0ZRcrJG08AP9pss4MMjkvTEfX6ldht9NWXlTz2AnOL
+MR4WSLS1H/Imv9OtO+nFkLUkedrV5eJasW5N2c6YkuHrEOK/Nv28WavULyBpUAJu
+k5iHQ1+/5A4spmarX3pvoqxMIeJ/Snju8Xn2T6MDSI4Y+9LbqplRDhl5LKo53RZi
+z4JKq8kCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCgpYRnfdC9BjlohcdiUjqz
+jzzQgRs8+29YFRyQHfHHT0K0YYEeiblvdNExXVD2s3ppP/C/X2lhs5Nif8YaHI1d
+wU0VDIeY55qMv1uhvnK34GkISl3U4v4VLm7bSoPHYmzNgtFQTKs3bZVSz2EtNGAJ
+xRfSWcRYmcyJNvTmFStmsqa4NFvCU7PrPraxMJn5tRFJOEiN25qqgEehHwC+mEL4
+700bmos0oF3IiWa5iTByAA2rv+Z8vlpTjJe9bwVrXi7tBLQRV5Kb6EfXPn4jLd+q
+Qj3uFk6RyV3DyyM93L8bUSaX2gN/LC55sOnCaGR2t5MrvcrfRDe2EbrnqJsoOSu8
+-----END CERTIFICATE REQUEST-----