From 969f3a50c491b76a39261e3413277c3135050d97 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 6 Jul 2015 18:52:41 -0400 Subject: Fixed #2120 -- added __hash__ to x509.Cert --- src/cryptography/hazmat/backends/openssl/x509.py | 4 ++++ src/cryptography/x509.py | 6 ++++++ tests/test_x509.py | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 7bfeb2ce..5e42b8e4 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -226,6 +226,10 @@ class _Certificate(object): def __ne__(self, other): return not self == other + def __hash__(self): + # TODO: Using fingerprint() with SHA256 is way overkill. + return hash(self.fingerprint(hashes.SHA256())) + def fingerprint(self, algorithm): h = hashes.Hash(algorithm, self._backend) bio = self._backend._create_mem_bio() diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index afd28f20..8d28c35c 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -1323,6 +1323,12 @@ class Certificate(object): Checks not equal. """ + @abc.abstractmethod + def __hash__(self): + """ + Computes a hash. + """ + @abc.abstractmethod def public_bytes(self, encoding): """ diff --git a/tests/test_x509.py b/tests/test_x509.py index 90b3fe5f..d4a27bc3 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -347,6 +347,29 @@ class TestRSACertificate(object): assert cert != cert2 assert cert != object() + def test_hash(self, backend): + cert1 = _load_cert( + os.path.join("x509", "custom", "post2000utctime.pem"), + x509.load_pem_x509_certificate, + backend + ) + cert2 = _load_cert( + os.path.join("x509", "custom", "post2000utctime.pem"), + x509.load_pem_x509_certificate, + backend + ) + cert3 = _load_cert( + os.path.join( + "x509", "PKITS_data", "certs", + "ValidGeneralizedTimenotAfterDateTest8EE.crt" + ), + x509.load_der_x509_certificate, + backend + ) + + assert hash(cert1) == hash(cert2) + assert hash(cert1) != hash(cert3) + def test_version_1_cert(self, backend): cert = _load_cert( os.path.join("x509", "v1_cert.pem"), -- cgit v1.2.3 From 5119125467c7cfe68f052ad804ac6ba88635739c Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 7 Jul 2015 06:24:25 -0400 Subject: no need to hash it twice, also simplify fingerprint method --- src/cryptography/hazmat/backends/openssl/x509.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 5e42b8e4..4896e9fb 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -227,18 +227,11 @@ class _Certificate(object): return not self == other def __hash__(self): - # TODO: Using fingerprint() with SHA256 is way overkill. - return hash(self.fingerprint(hashes.SHA256())) + return hash(self.public_bytes(serialization.Encoding.DER)) def fingerprint(self, algorithm): h = hashes.Hash(algorithm, self._backend) - bio = self._backend._create_mem_bio() - res = self._backend._lib.i2d_X509_bio( - bio, self._x509 - ) - assert res == 1 - der = self._backend._read_mem_bio(bio) - h.update(der) + h.update(self.public_bytes(serialization.Encoding.DER)) return h.finalize() @property -- cgit v1.2.3