aboutsummaryrefslogtreecommitdiffstats
path: root/src/cryptography/hazmat/primitives/asymmetric
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptography/hazmat/primitives/asymmetric')
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/dsa.py32
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/ec.py26
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/rsa.py26
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/utils.py46
4 files changed, 130 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
index 5d942e04..9b06f3e6 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -59,6 +59,15 @@ class DSAParameterNumbers(object):
def parameters(self, backend):
return backend.load_dsa_parameter_numbers(self)
+ def __eq__(self, other):
+ if not isinstance(other, DSAParameterNumbers):
+ return NotImplemented
+
+ return self.p == other.p and self.q == other.q and self.g == other.g
+
+ def __ne__(self, other):
+ return not self == other
+
class DSAPublicNumbers(object):
def __init__(self, y, parameter_numbers):
@@ -79,6 +88,18 @@ class DSAPublicNumbers(object):
def public_key(self, backend):
return backend.load_dsa_public_numbers(self)
+ def __eq__(self, other):
+ if not isinstance(other, DSAPublicNumbers):
+ return NotImplemented
+
+ return (
+ self.y == other.y and
+ self.parameter_numbers == other.parameter_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
class DSAPrivateNumbers(object):
def __init__(self, x, public_numbers):
@@ -97,3 +118,14 @@ class DSAPrivateNumbers(object):
def private_key(self, backend):
return backend.load_dsa_private_numbers(self)
+
+ def __eq__(self, other):
+ if not isinstance(other, DSAPrivateNumbers):
+ return NotImplemented
+
+ return (
+ self.x == other.x and self.public_numbers == other.public_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
index d9c41c19..202f1c97 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -161,6 +161,20 @@ class EllipticCurvePublicNumbers(object):
x = utils.read_only_property("_x")
y = utils.read_only_property("_y")
+ def __eq__(self, other):
+ if not isinstance(other, EllipticCurvePublicNumbers):
+ return NotImplemented
+
+ return (
+ self.x == other.x and
+ self.y == other.y and
+ self.curve.name == other.curve.name and
+ self.curve.key_size == other.curve.key_size
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
class EllipticCurvePrivateNumbers(object):
def __init__(self, private_value, public_numbers):
@@ -184,3 +198,15 @@ class EllipticCurvePrivateNumbers(object):
private_value = utils.read_only_property("_private_value")
public_numbers = utils.read_only_property("_public_numbers")
+
+ def __eq__(self, other):
+ if not isinstance(other, EllipticCurvePrivateNumbers):
+ return NotImplemented
+
+ return (
+ self.private_value == other.private_value and
+ self.public_numbers == other.public_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
index 6aeed006..0cc6b22b 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
@@ -160,6 +160,23 @@ class RSAPrivateNumbers(object):
def private_key(self, backend):
return backend.load_rsa_private_numbers(self)
+ def __eq__(self, other):
+ if not isinstance(other, RSAPrivateNumbers):
+ return NotImplemented
+
+ return (
+ self.p == other.p and
+ self.q == other.q and
+ self.d == other.d and
+ self.dmp1 == other.dmp1 and
+ self.dmq1 == other.dmq1 and
+ self.iqmp == other.iqmp and
+ self.public_numbers == other.public_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
class RSAPublicNumbers(object):
def __init__(self, e, n):
@@ -180,3 +197,12 @@ class RSAPublicNumbers(object):
def __repr__(self):
return "<RSAPublicNumbers(e={0}, n={1})>".format(self._e, self._n)
+
+ def __eq__(self, other):
+ if not isinstance(other, RSAPublicNumbers):
+ return NotImplemented
+
+ return self.e == other.e and self.n == other.n
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/src/cryptography/hazmat/primitives/asymmetric/utils.py b/src/cryptography/hazmat/primitives/asymmetric/utils.py
new file mode 100644
index 00000000..71f4ff8e
--- /dev/null
+++ b/src/cryptography/hazmat/primitives/asymmetric/utils.py
@@ -0,0 +1,46 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+from pyasn1.codec.der import decoder, encoder
+from pyasn1.error import PyAsn1Error
+from pyasn1.type import namedtype, univ
+
+import six
+
+
+class _DSSSigValue(univ.Sequence):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('r', univ.Integer()),
+ namedtype.NamedType('s', univ.Integer())
+ )
+
+
+def decode_rfc6979_signature(signature):
+ try:
+ data, remaining = decoder.decode(signature, asn1Spec=_DSSSigValue())
+ except PyAsn1Error:
+ raise ValueError("Invalid signature data. Unable to decode ASN.1")
+
+ if remaining:
+ raise ValueError(
+ "The signature contains bytes after the end of the ASN.1 sequence."
+ )
+ r = int(data.getComponentByName('r'))
+ s = int(data.getComponentByName('s'))
+ return (r, s)
+
+
+def encode_rfc6979_signature(r, s):
+ if (
+ not isinstance(r, six.integer_types) or
+ not isinstance(s, six.integer_types)
+ ):
+ raise ValueError("Both r and s must be integers")
+
+ sig = _DSSSigValue()
+ sig.setComponentByName('r', r)
+ sig.setComponentByName('s', s)
+ return encoder.encode(sig)