diff options
author | David Reid <dreid@dreid.org> | 2013-11-12 11:25:43 -0800 |
---|---|---|
committer | David Reid <dreid@dreid.org> | 2013-11-12 11:25:43 -0800 |
commit | ee6f8cec48028aeab213404dbce04bb6441a473c (patch) | |
tree | 2c0319db853393dfa3bb84101d579185e09e87af | |
parent | 1d75bfa060ff55c4e415a8d34f8e55025fed9a86 (diff) | |
download | cryptography-ee6f8cec48028aeab213404dbce04bb6441a473c.tar.gz cryptography-ee6f8cec48028aeab213404dbce04bb6441a473c.tar.bz2 cryptography-ee6f8cec48028aeab213404dbce04bb6441a473c.zip |
Get a HashContext from the backend like we do a CipherContext
-rw-r--r-- | cryptography/hazmat/bindings/openssl/backend.py | 74 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/hashes.py | 9 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_hashes.py | 6 |
3 files changed, 51 insertions, 38 deletions
diff --git a/cryptography/hazmat/bindings/openssl/backend.py b/cryptography/hazmat/bindings/openssl/backend.py index 1cb886dc..86c6f660 100644 --- a/cryptography/hazmat/bindings/openssl/backend.py +++ b/cryptography/hazmat/bindings/openssl/backend.py @@ -269,47 +269,61 @@ class Ciphers(object): _CipherContext._DECRYPT) -class Hashes(object): - def __init__(self, backend): - super(Hashes, self).__init__() +@interfaces.register(interfaces.HashContext) +class _HashContext(object): + def __init__(self, backend, algorithm, ctx=None): + self.algorithm = algorithm + self._backend = backend - def supported(self, hash_cls): - return (self._backend.ffi.NULL != - self._backend.lib.EVP_get_digestbyname( - hash_cls.name.encode("ascii"))) + if ctx is None: + ctx = self._backend.lib.EVP_MD_CTX_create() + ctx = self._backend.ffi.gc(ctx, + self._backend.lib.EVP_MD_CTX_destroy) + evp_md = self._backend.lib.EVP_get_digestbyname( + algorithm.name.encode("ascii")) + assert evp_md != self._backend.ffi.NULL + res = self._backend.lib.EVP_DigestInit_ex(ctx, evp_md, + self._backend.ffi.NULL) + assert res != 0 - def create_ctx(self, hashobject): - ctx = self._backend.lib.EVP_MD_CTX_create() - ctx = self._backend.ffi.gc(ctx, self._backend.lib.EVP_MD_CTX_destroy) - evp_md = self._backend.lib.EVP_get_digestbyname( - hashobject.name.encode("ascii")) - assert evp_md != self._backend.ffi.NULL - res = self._backend.lib.EVP_DigestInit_ex(ctx, evp_md, - self._backend.ffi.NULL) + self._ctx = ctx + + def copy(self): + copied_ctx = self._backend.lib.EVP_MD_CTX_create() + copied_ctx = self._backend.ffi.gc(copied_ctx, + self._backend.lib.EVP_MD_CTX_destroy) + res = self._backend.lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx) assert res != 0 - return ctx + return _HashContext(self._backend, self.algorithm, ctx=copied_ctx) - def update_ctx(self, ctx, data): - res = self._backend.lib.EVP_DigestUpdate(ctx, data, len(data)) + def update(self, data): + res = self._backend.lib.EVP_DigestUpdate(self._ctx, data, len(data)) assert res != 0 - def finalize_ctx(self, ctx, digest_size): - buf = self._backend.ffi.new("unsigned char[]", digest_size) - res = self._backend.lib.EVP_DigestFinal_ex(ctx, buf, + def finalize(self): + buf = self._backend.ffi.new("unsigned char[]", + self.algorithm.digest_size) + res = self._backend.lib.EVP_DigestFinal_ex(self._ctx, buf, self._backend.ffi.NULL) assert res != 0 - res = self._backend.lib.EVP_MD_CTX_cleanup(ctx) + res = self._backend.lib.EVP_MD_CTX_cleanup(self._ctx) assert res == 1 - return self._backend.ffi.buffer(buf)[:digest_size] + return self._backend.ffi.buffer(buf)[:self.algorithm.digest_size] - def copy_ctx(self, ctx): - copied_ctx = self._backend.lib.EVP_MD_CTX_create() - copied_ctx = self._backend.ffi.gc(copied_ctx, - self._backend.lib.EVP_MD_CTX_destroy) - res = self._backend.lib.EVP_MD_CTX_copy_ex(copied_ctx, ctx) - assert res != 0 - return copied_ctx + +class Hashes(object): + def __init__(self, backend): + super(Hashes, self).__init__() + self._backend = backend + + def supported(self, algorithm): + return (self._backend.ffi.NULL != + self._backend.lib.EVP_get_digestbyname( + algorithm.name.encode("ascii"))) + + def create_ctx(self, algorithm): + return _HashContext(self._backend, algorithm) class HMACs(object): diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py index bdad5e16..c14d0437 100644 --- a/cryptography/hazmat/primitives/hashes.py +++ b/cryptography/hazmat/primitives/hashes.py @@ -34,20 +34,19 @@ class Hash(object): if ctx is None: self._ctx = self._backend.hashes.create_ctx(self.algorithm) else: - self._ctx = None + self._ctx = ctx def update(self, data): if isinstance(data, six.text_type): raise TypeError("Unicode-objects must be encoded before hashing") - self._backend.hashes.update_ctx(self._ctx, data) + self._ctx.update(data) def copy(self): return self.__class__(self.algorithm, backend=self._backend, - ctx=self._backend.hashes.copy_ctx(self._ctx)) + ctx=self._ctx.copy()) def finalize(self): - return self._backend.hashes.finalize_ctx(self._ctx, - self.algorithm.digest_size) + return self._ctx.finalize() @interfaces.register(interfaces.HashAlgorithm) diff --git a/tests/hazmat/primitives/test_hashes.py b/tests/hazmat/primitives/test_hashes.py index 07ab2489..6cdb0a07 100644 --- a/tests/hazmat/primitives/test_hashes.py +++ b/tests/hazmat/primitives/test_hashes.py @@ -32,9 +32,9 @@ class TestHashContext(object): m.update(six.u("\u00FC")) def test_copy_backend_object(self): - pretend_hashes = pretend.stub(copy_ctx=lambda a: "copiedctx") - pretend_backend = pretend.stub(hashes=pretend_hashes) - pretend_ctx = pretend.stub() + pretend_backend = pretend.stub() + copied_ctx = pretend.stub() + pretend_ctx = pretend.stub(copy=lambda: copied_ctx) h = hashes.Hash(hashes.SHA1(), backend=pretend_backend, ctx=pretend_ctx) assert h._backend is pretend_backend |