diff options
author | Donald Stufft <donald@stufft.io> | 2013-10-18 19:21:27 -0700 |
---|---|---|
committer | Donald Stufft <donald@stufft.io> | 2013-10-18 19:21:27 -0700 |
commit | a3011beae965fde326d4977d850b2aaa9c7b216e (patch) | |
tree | 59095660e7061e238847c3e076d2d115ac716b2f /cryptography | |
parent | 90d2a77af90e9ed68125668e59b4d1f250938aec (diff) | |
parent | 3b7730cf90c6a5114391d2d5a2ccc1cdb448da9e (diff) | |
download | cryptography-a3011beae965fde326d4977d850b2aaa9c7b216e.tar.gz cryptography-a3011beae965fde326d4977d850b2aaa9c7b216e.tar.bz2 cryptography-a3011beae965fde326d4977d850b2aaa9c7b216e.zip |
Merge pull request #123 from reaperhulk/hash-saga-sha1
Hash Saga Part 3 (API changes + SHA1)
Diffstat (limited to 'cryptography')
-rw-r--r-- | cryptography/bindings/openssl/api.py | 30 | ||||
-rw-r--r-- | cryptography/primitives/hashes.py | 48 |
2 files changed, 78 insertions, 0 deletions
diff --git a/cryptography/bindings/openssl/api.py b/cryptography/bindings/openssl/api.py index 2ad6c054..5eefcdb9 100644 --- a/cryptography/bindings/openssl/api.py +++ b/cryptography/bindings/openssl/api.py @@ -141,5 +141,35 @@ class API(object): assert res != 0 return self.ffi.buffer(buf)[:outlen[0]] + def supports_hash(self, hash_cls): + return (self.ffi.NULL != + self.lib.EVP_get_digestbyname(hash_cls.name.encode("ascii"))) + + def create_hash_context(self, hashobject): + ctx = self.lib.EVP_MD_CTX_create() + ctx = self.ffi.gc(ctx, self.lib.EVP_MD_CTX_destroy) + evp_md = self.lib.EVP_get_digestbyname(hashobject.name.encode("ascii")) + assert evp_md != self.ffi.NULL + res = self.lib.EVP_DigestInit_ex(ctx, evp_md, self.ffi.NULL) + assert res != 0 + return ctx + + def update_hash_context(self, ctx, data): + res = self.lib.EVP_DigestUpdate(ctx, data, len(data)) + assert res != 0 + + def finalize_hash_context(self, ctx, digest_size): + buf = self.ffi.new("unsigned char[]", digest_size) + res = self.lib.EVP_DigestFinal_ex(ctx, buf, self.ffi.NULL) + assert res != 0 + return self.ffi.buffer(buf)[:digest_size] + + def copy_hash_context(self, ctx): + copied_ctx = self.lib.EVP_MD_CTX_create() + copied_ctx = self.ffi.gc(copied_ctx, self.lib.EVP_MD_CTX_destroy) + res = self.lib.EVP_MD_CTX_copy_ex(copied_ctx, ctx) + assert res != 0 + return copied_ctx + api = API() diff --git a/cryptography/primitives/hashes.py b/cryptography/primitives/hashes.py new file mode 100644 index 00000000..d74287f9 --- /dev/null +++ b/cryptography/primitives/hashes.py @@ -0,0 +1,48 @@ +# 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 binascii + +from cryptography.bindings import _default_api + + +class BaseHash(object): + def __init__(self, api=None, ctx=None): + if api is None: + api = _default_api + self._api = api + self._ctx = self._api.create_hash_context(self) if ctx is None else ctx + + def update(self, string): + self._api.update_hash_context(self._ctx, string) + + def copy(self): + return self.__class__(ctx=self._copy_ctx()) + + def digest(self): + return self._api.finalize_hash_context(self._copy_ctx(), + self.digest_size) + + def hexdigest(self): + return binascii.hexlify(self.digest()).decode("ascii") + + def _copy_ctx(self): + return self._api.copy_hash_context(self._ctx) + + +class SHA1(BaseHash): + name = "sha1" + digest_size = 20 + block_size = 64 |