diff options
Diffstat (limited to 'src/cryptography')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 22 | ||||
-rw-r--r-- | src/cryptography/hazmat/bindings/openssl/binding.py | 34 |
2 files changed, 43 insertions, 13 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index c3e1db66..c21d5427 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -648,7 +648,21 @@ class _PasswordUserdata(object): self.exception = None +@binding.ffi_callback("int (char *, int, int, void *)", + name="Cryptography_pem_password_cb") def _pem_password_cb(buf, size, writing, userdata_handle): + """ + A pem_password_cb function pointer that copied the password to + OpenSSL as required and returns the number of bytes copied. + + typedef int pem_password_cb(char *buf, int size, + int rwflag, void *userdata); + + Useful for decrypting PKCS8 files and so on. + + The userdata pointer must point to a cffi handle of a + _PasswordUserdata instance. + """ ud = _ffi.from_handle(userdata_handle) ud.called += 1 @@ -1143,13 +1157,7 @@ class Backend(object): # globally. The backend is passed in as userdata argument. userdata = _PasswordUserdata(password=password) - - pem_password_cb = self._ffi.callback( - "int (char *, int, int, void *)", - _pem_password_cb, - ) - - return pem_password_cb, userdata + return _pem_password_cb, userdata def _mgf1_hash_supported(self, algorithm): if self._lib.Cryptography_HAS_MGF1_MD: diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py index 8e419439..1cfe8162 100644 --- a/src/cryptography/hazmat/bindings/openssl/binding.py +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -14,7 +14,6 @@ from cryptography.exceptions import InternalError from cryptography.hazmat.bindings._openssl import ffi, lib from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES - _OpenSSLError = collections.namedtuple("_OpenSSLError", ["code", "lib", "func", "reason"]) @@ -45,7 +44,28 @@ def _openssl_assert(lib, ok): ) -@ffi.callback("int (*)(unsigned char *, int)", error=-1) +def ffi_callback(signature, name, **kwargs): + """Callback dispatcher + + The ffi_callback() dispatcher keeps callbacks compatible between dynamic + and static callbacks. + """ + def wrapper(func): + if lib.Cryptography_STATIC_CALLBACKS: + # def_extern() returns a decorator that sets the internal + # function pointer and returns the original function unmodified. + ffi.def_extern(name=name, **kwargs)(func) + callback = getattr(lib, name) + else: + # callback() wraps the function in a cdata function. + callback = ffi.callback(signature, **kwargs)(func) + return callback + return wrapper + + +@ffi_callback("int (*)(unsigned char *, int)", + name="Cryptography_rand_bytes", + error=-1) def _osrandom_rand_bytes(buf, size): signed = ffi.cast("char *", buf) result = os.urandom(size) @@ -53,7 +73,7 @@ def _osrandom_rand_bytes(buf, size): return 1 -@ffi.callback("int (*)(void)") +@ffi_callback("int (*)(void)", name="Cryptography_rand_status") def _osrandom_rand_status(): return 1 @@ -88,7 +108,8 @@ class Binding(object): _osrandom_engine_name = ffi.new("const char[]", b"osrandom_engine") _osrandom_method = ffi.new( "RAND_METHOD *", - dict(bytes=_osrandom_rand_bytes, pseudorand=_osrandom_rand_bytes, + dict(bytes=_osrandom_rand_bytes, + pseudorand=_osrandom_rand_bytes, status=_osrandom_rand_status) ) @@ -140,10 +161,11 @@ class Binding(object): cls._ensure_ffi_initialized() if not cls._lock_cb_handle: - cls._lock_cb_handle = cls.ffi.callback( + wrapper = ffi_callback( "void(int, int, const char *, int)", - cls._lock_cb + name="Cryptography_locking_cb", ) + cls._lock_cb_handle = wrapper(cls._lock_cb) # Use Python's implementation if available, importing _ssl triggers # the setup for this. |