diff options
-rw-r--r-- | docs/development/test-vectors.rst | 14 | ||||
-rw-r--r-- | docs/hazmat/primitives/asymmetric/dh.rst | 64 | ||||
-rw-r--r-- | docs/hazmat/primitives/asymmetric/index.rst | 1 | ||||
-rw-r--r-- | docs/spelling_wordlist.txt | 1 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/asymmetric/dh.py | 101 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_dh.py | 113 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/requests/dsa_sha1.pem | 15 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/requests/ec_sha256.pem | 10 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/requests/rsa_md4.pem | 16 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/requests/rsa_sha1.pem | 16 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/requests/rsa_sha256.pem | 16 |
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----- |