aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rwxr-xr-x.travis/install.sh6
-rwxr-xr-x.travis/openssl_config.sh13
-rwxr-xr-x.travis/run.sh11
-rw-r--r--CHANGELOG.rst5
-rw-r--r--src/_cffi_src/openssl/engine.py68
-rw-r--r--src/_cffi_src/openssl/ssl.py1
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py17
-rw-r--r--src/cryptography/hazmat/bindings/openssl/_conditional.py42
-rw-r--r--src/cryptography/hazmat/bindings/openssl/binding.py5
-rw-r--r--tests/hazmat/backends/test_openssl.py3
11 files changed, 155 insertions, 18 deletions
diff --git a/.travis.yml b/.travis.yml
index 7ed660a8..fa45f134 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -52,6 +52,8 @@ matrix:
- python: 3.7
env: TOXENV=py37 OPENSSL=1.1.1a
- python: 3.7
+ env: TOXENV=py37 OPENSSL=1.1.1a OPENSSL_CONFIG_FLAGS=no-engine
+ - python: 3.7
env: TOXENV=py37 LIBRESSL=2.6.5
- python: 3.7
env: TOXENV=py37 LIBRESSL=2.7.5
diff --git a/.travis/install.sh b/.travis/install.sh
index a4bc3c97..ed69e468 100755
--- a/.travis/install.sh
+++ b/.travis/install.sh
@@ -3,6 +3,8 @@
set -e
set -x
+SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
+
shlib_sed() {
# modify the shlib version to a unique one to make sure the dynamic
# linker doesn't load the system one.
@@ -14,12 +16,12 @@ shlib_sed() {
# download, compile, and install if it's not already present via travis
# cache
if [ -n "${OPENSSL}" ]; then
- OPENSSL_DIR="ossl-2/${OPENSSL}"
+ . "$SCRIPT_DIR/openssl_config.sh"
if [[ ! -f "$HOME/$OPENSSL_DIR/bin/openssl" ]]; then
curl -O "https://www.openssl.org/source/openssl-${OPENSSL}.tar.gz"
tar zxf "openssl-${OPENSSL}.tar.gz"
pushd "openssl-${OPENSSL}"
- ./config shared no-ssl2 no-ssl3 -fPIC --prefix="$HOME/$OPENSSL_DIR"
+ ./config $OPENSSL_CONFIG_FLAGS -fPIC --prefix="$HOME/$OPENSSL_DIR"
shlib_sed
make depend
make -j"$(nproc)"
diff --git a/.travis/openssl_config.sh b/.travis/openssl_config.sh
new file mode 100755
index 00000000..83f16d2b
--- /dev/null
+++ b/.travis/openssl_config.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -e
+set -x
+
+DEFAULT_CONFIG_FLAGS="shared no-ssl2 no-ssl3"
+if [ -n "${OPENSSL_CONFIG_FLAGS}" ]; then
+ OPENSSL_CONFIG_FLAGS="$DEFAULT_CONFIG_FLAGS $OPENSSL_CONFIG_FLAGS"
+else
+ OPENSSL_CONFIG_FLAGS=$DEFAULT_CONFIG_FLAGS
+fi
+CONFIG_HASH=$(echo "$OPENSSL_CONFIG_FLAGS" | sha1sum | sed 's/ .*$//')
+OPENSSL_DIR="ossl-2/${OPENSSL}${CONFIG_HASH}"
diff --git a/.travis/run.sh b/.travis/run.sh
index 8f8dd687..ab12ac3c 100755
--- a/.travis/run.sh
+++ b/.travis/run.sh
@@ -1,18 +1,21 @@
#!/bin/bash -ex
+SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
+
if [[ "${TOXENV}" == "pypy" ]]; then
PYENV_ROOT="$HOME/.pyenv"
PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
fi
if [ -n "${LIBRESSL}" ]; then
- OPENSSL=$LIBRESSL
- export CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=discarded-qualifiers -Wno-error=unused-function"
+ LIBRESSL_DIR="ossl-2/${LIBRESSL}"
+ export CFLAGS="-Werror -Wno-error=deprecated-declarations -Wno-error=discarded-qualifiers -Wno-error=unused-function -I$HOME/$LIBRESSL_DIR/include"
+ export PATH="$HOME/$LIBRESSL_DIR/bin:$PATH"
+ export LDFLAGS="-L$HOME/$LIBRESSL_DIR/lib -Wl,-rpath=$HOME/$LIBRESSL_DIR/lib"
fi
if [ -n "${OPENSSL}" ]; then
- OPENSSL_DIR="ossl-2/${OPENSSL}"
-
+ . "$SCRIPT_DIR/openssl_config.sh"
export PATH="$HOME/$OPENSSL_DIR/bin:$PATH"
export CFLAGS="${CFLAGS} -I$HOME/$OPENSSL_DIR/include"
# rpath on linux will cause it to use an absolute path so we don't need to
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e4c747c8..7c3f3bfe 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -21,7 +21,10 @@ Changelog
which had been deprecated for nearly 3 years. Use
:attr:`~cryptography.x509.Certificate.serial_number` instead.
* Add support for easily mapping an object identifier to its elliptic curve
- class via :func:`~cryptography.hazmat.primitives.asymmetric.ec.get_curve_for_oid`.
+ class via
+ :func:`~cryptography.hazmat.primitives.asymmetric.ec.get_curve_for_oid`.
+* Add support for OpenSSL when compiled with the ``no-engine``
+ (``OPENSSL_NO_ENGINE``) flag.
.. _v2-5:
diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py
index c255bbbc..8996f0c8 100644
--- a/src/_cffi_src/openssl/engine.py
+++ b/src/_cffi_src/openssl/engine.py
@@ -27,6 +27,7 @@ typedef ... UI_METHOD;
static const unsigned int ENGINE_METHOD_RAND;
static const int ENGINE_R_CONFLICTING_ENGINE_ID;
+static const long Cryptography_HAS_ENGINE;
"""
FUNCTIONS = """
@@ -69,4 +70,71 @@ void ENGINE_cleanup(void);
"""
CUSTOMIZATIONS = """
+#ifdef OPENSSL_NO_ENGINE
+static const long Cryptography_HAS_ENGINE = 0;
+typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
+typedef void *ENGINE_CTRL_FUNC_PTR;
+typedef void *ENGINE_LOAD_KEY_PTR;
+typedef void *ENGINE_CIPHERS_PTR;
+typedef void *ENGINE_DIGESTS_PTR;
+typedef struct ENGINE_CMD_DEFN_st {
+ unsigned int cmd_num;
+ const char *cmd_name;
+ const char *cmd_desc;
+ unsigned int cmd_flags;
+} ENGINE_CMD_DEFN;
+
+/* This section is so osrandom_engine.c can successfully compile even
+ when engine support is disabled */
+#define ENGINE_CMD_BASE 0
+#define ENGINE_CMD_FLAG_NO_INPUT 0
+#define ENGINE_F_ENGINE_CTRL 0
+#define ENGINE_R_INVALID_ARGUMENT 0
+#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 0
+int (*ENGINE_set_cmd_defns)(ENGINE *, const ENGINE_CMD_DEFN *) = NULL;
+
+static const unsigned int ENGINE_METHOD_RAND = 0;
+static const int ENGINE_R_CONFLICTING_ENGINE_ID = 0;
+
+ENGINE *(*ENGINE_get_first)(void) = NULL;
+ENGINE *(*ENGINE_get_last)(void) = NULL;
+int (*ENGINE_add)(ENGINE *) = NULL;
+int (*ENGINE_remove)(ENGINE *) = NULL;
+ENGINE *(*ENGINE_by_id)(const char *) = NULL;
+int (*ENGINE_init)(ENGINE *) = NULL;
+int (*ENGINE_finish)(ENGINE *) = NULL;
+void (*ENGINE_load_builtin_engines)(void) = NULL;
+ENGINE *(*ENGINE_get_default_RAND)(void) = NULL;
+int (*ENGINE_set_default_RAND)(ENGINE *) = NULL;
+int (*ENGINE_register_RAND)(ENGINE *) = NULL;
+void (*ENGINE_unregister_RAND)(ENGINE *) = NULL;
+void (*ENGINE_register_all_RAND)(void) = NULL;
+int (*ENGINE_ctrl)(ENGINE *, int, long, void *, void (*)(void)) = NULL;
+int (*ENGINE_ctrl_cmd)(ENGINE *, const char *, long, void *,
+ void (*)(void), int) = NULL;
+int (*ENGINE_ctrl_cmd_string)(ENGINE *, const char *, const char *,
+ int) = NULL;
+
+ENGINE *(*ENGINE_new)(void) = NULL;
+int (*ENGINE_free)(ENGINE *) = NULL;
+int (*ENGINE_up_ref)(ENGINE *) = NULL;
+int (*ENGINE_set_id)(ENGINE *, const char *) = NULL;
+int (*ENGINE_set_name)(ENGINE *, const char *) = NULL;
+int (*ENGINE_set_RAND)(ENGINE *, const RAND_METHOD *) = NULL;
+int (*ENGINE_set_destroy_function)(ENGINE *, ENGINE_GEN_INT_FUNC_PTR) = NULL;
+int (*ENGINE_set_init_function)(ENGINE *, ENGINE_GEN_INT_FUNC_PTR) = NULL;
+int (*ENGINE_set_finish_function)(ENGINE *, ENGINE_GEN_INT_FUNC_PTR) = NULL;
+int (*ENGINE_set_ctrl_function)(ENGINE *, ENGINE_CTRL_FUNC_PTR) = NULL;
+const char *(*ENGINE_get_id)(const ENGINE *) = NULL;
+const char *(*ENGINE_get_name)(const ENGINE *) = NULL;
+const RAND_METHOD *(*ENGINE_get_RAND)(const ENGINE *) = NULL;
+
+void (*ENGINE_add_conf_module)(void) = NULL;
+/* these became macros in 1.1.0 */
+void (*ENGINE_load_openssl)(void) = NULL;
+void (*ENGINE_load_dynamic)(void) = NULL;
+void (*ENGINE_cleanup)(void) = NULL;
+#else
+static const long Cryptography_HAS_ENGINE = 1;
+#endif
"""
diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
index 2218095c..92fd1e3e 100644
--- a/src/_cffi_src/openssl/ssl.py
+++ b/src/_cffi_src/openssl/ssl.py
@@ -334,7 +334,6 @@ int SSL_SESSION_print(BIO *, const SSL_SESSION *);
const COMP_METHOD *SSL_get_current_compression(SSL *);
const COMP_METHOD *SSL_get_current_expansion(SSL *);
const char *SSL_COMP_get_name(const COMP_METHOD *);
-int SSL_CTX_set_client_cert_engine(SSL_CTX *, ENGINE *);
unsigned long SSL_set_mode(SSL *, unsigned long);
unsigned long SSL_get_mode(SSL *);
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 73491726..d7bba224 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -150,14 +150,15 @@ class Backend(object):
self.openssl_assert(res == 1)
def activate_osrandom_engine(self):
- # Unregister and free the current engine.
- self.activate_builtin_random()
- with self._get_osurandom_engine() as e:
- # Set the engine as the default RAND provider.
- res = self._lib.ENGINE_set_default_RAND(e)
- self.openssl_assert(res == 1)
- # Reset the RNG to use the new engine.
- self._lib.RAND_cleanup()
+ if self._lib.Cryptography_HAS_ENGINE:
+ # Unregister and free the current engine.
+ self.activate_builtin_random()
+ with self._get_osurandom_engine() as e:
+ # Set the engine as the default RAND provider.
+ res = self._lib.ENGINE_set_default_RAND(e)
+ self.openssl_assert(res == 1)
+ # Reset the RNG to use the new engine.
+ self._lib.RAND_cleanup()
def osrandom_engine_implementation(self):
buf = self._ffi.new("char[]", 64)
diff --git a/src/cryptography/hazmat/bindings/openssl/_conditional.py b/src/cryptography/hazmat/bindings/openssl/_conditional.py
index c0238dcc..3fecfe59 100644
--- a/src/cryptography/hazmat/bindings/openssl/_conditional.py
+++ b/src/cryptography/hazmat/bindings/openssl/_conditional.py
@@ -341,6 +341,47 @@ def cryptography_has_evp_r_memory_limit_exceeded():
]
+def cryptography_has_engine():
+ return [
+ "ENGINE_get_first",
+ "ENGINE_get_last",
+ "ENGINE_add",
+ "ENGINE_remove",
+ "ENGINE_by_id",
+ "ENGINE_init",
+ "ENGINE_finish",
+ "ENGINE_load_builtin_engines",
+ "ENGINE_get_default_RAND",
+ "ENGINE_set_default_RAND",
+ "ENGINE_register_RAND",
+ "ENGINE_unregister_RAND",
+ "ENGINE_register_all_RAND",
+ "ENGINE_ctrl",
+ "ENGINE_ctrl_cmd",
+ "ENGINE_ctrl_cmd_string",
+ "ENGINE_new",
+ "ENGINE_free",
+ "ENGINE_up_ref",
+ "ENGINE_set_id",
+ "ENGINE_set_name",
+ "ENGINE_set_RAND",
+ "ENGINE_set_destroy_function",
+ "ENGINE_set_init_function",
+ "ENGINE_set_finish_function",
+ "ENGINE_set_ctrl_function",
+ "ENGINE_get_id",
+ "ENGINE_get_name",
+ "ENGINE_get_RAND",
+ "ENGINE_add_conf_module",
+ "ENGINE_load_openssl",
+ "ENGINE_load_dynamic",
+ "ENGINE_cleanup",
+ "ENGINE_METHOD_RAND",
+ "ENGINE_R_CONFLICTING_ENGINE_ID",
+ "Cryptography_add_osrandom_engine",
+ ]
+
+
# This is a mapping of
# {condition: function-returning-names-dependent-on-that-condition} so we can
# loop over them and delete unsupported names at runtime. It will be removed
@@ -412,4 +453,5 @@ CONDITIONAL_NAMES = {
"Cryptography_HAS_EVP_R_MEMORY_LIMIT_EXCEEDED": (
cryptography_has_evp_r_memory_limit_exceeded
),
+ "Cryptography_HAS_ENGINE": cryptography_has_engine,
}
diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py
index c937afd4..ca4e33fa 100644
--- a/src/cryptography/hazmat/bindings/openssl/binding.py
+++ b/src/cryptography/hazmat/bindings/openssl/binding.py
@@ -115,8 +115,9 @@ class Binding(object):
# reliably clear the error queue. Once we clear it here we will
# error on any subsequent unexpected item in the stack.
cls.lib.ERR_clear_error()
- result = cls.lib.Cryptography_add_osrandom_engine()
- _openssl_assert(cls.lib, result in (1, 2))
+ if cls.lib.Cryptography_HAS_ENGINE:
+ result = cls.lib.Cryptography_add_osrandom_engine()
+ _openssl_assert(cls.lib, result in (1, 2))
@classmethod
def _ensure_ffi_initialized(cls):
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 6768e70f..20923792 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -170,6 +170,9 @@ class TestOpenSSL(object):
assert backend._bn_to_int(bn) == 0
+@pytest.mark.skipif(
+ backend._lib.Cryptography_HAS_ENGINE == 0,
+ reason="Requires OpenSSL with ENGINE support")
class TestOpenSSLRandomEngine(object):
def setup(self):
# The default RAND engine is global and shared between