diff options
-rw-r--r-- | cryptography/bindings/openssl/api.py | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/cryptography/bindings/openssl/api.py b/cryptography/bindings/openssl/api.py index 20a85cad..ec6b923a 100644 --- a/cryptography/bindings/openssl/api.py +++ b/cryptography/bindings/openssl/api.py @@ -14,6 +14,17 @@ import cffi +class OpenSSLError(Exception): + def __init__(self, api): + e = api._lib.ERR_get_error() + if e == 0: + raise SystemError("Tried to create an OpenSSLError when there was " + "None") + msg = api._ffi.new("char[]", 120) + api._lib.ERR_error_string(e, msg) + super(OpenSSLError, self).__init__(api._ffi.string(msg)) + + class API(object): """ OpenSSL API wrapper. @@ -43,6 +54,8 @@ class API(object): unsigned char *, int); int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *); int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *); + + unsigned long ERR_get_error(); """) def create_block_cipher_context(self, cipher, mode): @@ -51,13 +64,11 @@ class API(object): ciphername = b"AES-{}-CBC".format(len(cipher.key) * 8) evp_cipher = self._lib.EVP_get_cipherbyname(ciphername) if evp_cipher == self._ffi.NULL: - # TODO: figure out openssl errors - raise Exception + raise OpenSSLError(self) # TODO: only use the key and initialization_vector as needed res = self._lib.EVP_EncryptInit_ex(ctx, evp_cipher, self._ffi.NULL, cipher.key, mode.initialization_vector) if res == 0: - # TODO: figure out openssl errors - raise Exception + raise OpenSSLError(self) # TODO: this should depend on mode.padding self._lib.EVP_CIPHER_CTX_set_padding(ctx, 0) return ctx @@ -67,8 +78,7 @@ class API(object): outlen = self._ffi.new("int *") res = self._lib.EVP_EncryptUpdate(ctx, buf, outlen, plaintext, len(plaintext)) if res == 0: - # TODO: figure out openssl errors - raise Exception + raise OpenSSLError(self) return self._ffi.buffer(buf)[:outlen[0]] def finalize_encrypt_context(self, ctx): @@ -77,13 +87,11 @@ class API(object): outlen = self._ffi.new("int *") res = self._lib.EVP_EncryptFinal_ex(ctx, buf, outlen) if res == 0: - # TODO: figure out openssl errors - raise Exception + raise OpenSSLError(self) # TODO: this should also be called if the cipher isn't finalized. res = self._lib.EVP_CIPHER_CTX_cleanup(ctx) if res == 0: - # TODO: figure out openssl errors - raise Exception + raise OpenSSLError(self) return self._ffi.buffer(buf)[:outlen[0]] |