aboutsummaryrefslogtreecommitdiffstats
path: root/src/cryptography
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptography')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py22
-rw-r--r--src/cryptography/hazmat/bindings/openssl/binding.py34
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.