diff options
author | David Reid <dreid@dreid.org> | 2013-11-12 13:24:56 -0800 |
---|---|---|
committer | David Reid <dreid@dreid.org> | 2013-11-12 13:24:56 -0800 |
commit | 0bcbb41964014926c3c604efff68f2d11b592035 (patch) | |
tree | a7d47beb517277d4480fca85ac79f68060216ca0 | |
parent | 5e981fc4bad969750a1a8e109ee6391fb5d4bfbc (diff) | |
download | cryptography-0bcbb41964014926c3c604efff68f2d11b592035.tar.gz cryptography-0bcbb41964014926c3c604efff68f2d11b592035.tar.bz2 cryptography-0bcbb41964014926c3c604efff68f2d11b592035.zip |
Get a HashContext from the hmac backend like we do a CipherContext
-rw-r--r-- | cryptography/hazmat/bindings/openssl/backend.py | 80 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/hmac.py | 11 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_hmac.py | 5 |
3 files changed, 60 insertions, 36 deletions
diff --git a/cryptography/hazmat/bindings/openssl/backend.py b/cryptography/hazmat/bindings/openssl/backend.py index 1cb886dc..60d51305 100644 --- a/cryptography/hazmat/bindings/openssl/backend.py +++ b/cryptography/hazmat/bindings/openssl/backend.py @@ -312,44 +312,66 @@ class Hashes(object): return copied_ctx -class HMACs(object): - def __init__(self, backend): - super(HMACs, self).__init__() +@interfaces.register(interfaces.HashContext) +class _HMACContext(object): + def __init__(self, backend, key, algorithm, ctx=None): + self.algorithm = algorithm + self._backend = backend - def create_ctx(self, key, hash_cls): - ctx = self._backend.ffi.new("HMAC_CTX *") - self._backend.lib.HMAC_CTX_init(ctx) - ctx = self._backend.ffi.gc(ctx, self._backend.lib.HMAC_CTX_cleanup) - evp_md = self._backend.lib.EVP_get_digestbyname( - hash_cls.name.encode('ascii')) - assert evp_md != self._backend.ffi.NULL - res = self._backend.lib.Cryptography_HMAC_Init_ex( - ctx, key, len(key), evp_md, self._backend.ffi.NULL + if ctx is None: + ctx = self._backend.ffi.new("HMAC_CTX *") + self._backend.lib.HMAC_CTX_init(ctx) + ctx = self._backend.ffi.gc(ctx, self._backend.lib.HMAC_CTX_cleanup) + evp_md = self._backend.lib.EVP_get_digestbyname( + algorithm.name.encode('ascii')) + assert evp_md != self._backend.ffi.NULL + res = self._backend.lib.Cryptography_HMAC_Init_ex( + ctx, key, len(key), evp_md, self._backend.ffi.NULL + ) + assert res != 0 + + self._ctx = ctx + self._key = key + + def copy(self): + copied_ctx = self._backend.ffi.new("HMAC_CTX *") + self._backend.lib.HMAC_CTX_init(copied_ctx) + copied_ctx = self._backend.ffi.gc( + copied_ctx, self._backend.lib.HMAC_CTX_cleanup + ) + res = self._backend.lib.Cryptography_HMAC_CTX_copy( + copied_ctx, self._ctx ) assert res != 0 - return ctx + return self.__class__( + self._backend, self._key, self.algorithm, ctx=copied_ctx + ) - def update_ctx(self, ctx, data): - res = self._backend.lib.Cryptography_HMAC_Update(ctx, data, len(data)) + def update(self, data): + res = self._backend.lib.Cryptography_HMAC_Update( + self._ctx, data, len(data) + ) assert res != 0 - def finalize_ctx(self, ctx, digest_size): - buf = self._backend.ffi.new("unsigned char[]", digest_size) - buflen = self._backend.ffi.new("unsigned int *", digest_size) - res = self._backend.lib.Cryptography_HMAC_Final(ctx, buf, buflen) + def finalize(self): + buf = self._backend.ffi.new("unsigned char[]", + self.algorithm.digest_size) + buflen = self._backend.ffi.new("unsigned int *", + self.algorithm.digest_size) + res = self._backend.lib.Cryptography_HMAC_Final(self._ctx, buf, buflen) assert res != 0 - self._backend.lib.HMAC_CTX_cleanup(ctx) - return self._backend.ffi.buffer(buf)[:digest_size] + self._backend.lib.HMAC_CTX_cleanup(self._ctx) + return self._backend.ffi.buffer(buf)[:self.algorithm.digest_size] - def copy_ctx(self, ctx): - copied_ctx = self._backend.ffi.new("HMAC_CTX *") - self._backend.lib.HMAC_CTX_init(copied_ctx) - copied_ctx = self._backend.ffi.gc(copied_ctx, - self._backend.lib.HMAC_CTX_cleanup) - res = self._backend.lib.Cryptography_HMAC_CTX_copy(copied_ctx, ctx) - assert res != 0 - return copied_ctx + +class HMACs(object): + def __init__(self, backend): + super(HMACs, self).__init__() + self._backend = backend + + def create_ctx(self, key, algorithm): + return _HMACContext(self._backend, key, algorithm) backend = Backend() diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py index 1457ed78..27bc0fee 100644 --- a/cryptography/hazmat/primitives/hmac.py +++ b/cryptography/hazmat/primitives/hmac.py @@ -40,12 +40,13 @@ class HMAC(object): def update(self, msg): if isinstance(msg, six.text_type): raise TypeError("Unicode-objects must be encoded before hashing") - self._backend.hmacs.update_ctx(self._ctx, msg) + self._ctx.update(msg) def copy(self): - return self.__class__(self._key, self.algorithm, backend=self._backend, - ctx=self._backend.hmacs.copy_ctx(self._ctx)) + return self.__class__( + self._key, self.algorithm, ctx=self._ctx.copy(), + backend=self._backend + ) def finalize(self): - return self._backend.hmacs.finalize_ctx(self._ctx, - self.algorithm.digest_size) + return self._ctx.finalize() diff --git a/tests/hazmat/primitives/test_hmac.py b/tests/hazmat/primitives/test_hmac.py index a44838cf..0f627a10 100644 --- a/tests/hazmat/primitives/test_hmac.py +++ b/tests/hazmat/primitives/test_hmac.py @@ -37,9 +37,10 @@ class TestHMAC(object): h.update(six.u("\u00FC")) def test_copy_backend_object(self): - pretend_hmac = pretend.stub(copy_ctx=lambda a: True) + pretend_hmac = pretend.stub() pretend_backend = pretend.stub(hmacs=pretend_hmac) - pretend_ctx = pretend.stub() + copied_ctx = pretend.stub() + pretend_ctx = pretend.stub(copy=lambda: copied_ctx) h = hmac.HMAC(b"key", hashes.SHA1(), backend=pretend_backend, ctx=pretend_ctx) assert h._backend is pretend_backend |