summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-05-06 12:29:57 +0100
committerMatt Caswell <matt@openssl.org>2020-05-16 17:10:03 +0100
commitd40b42ab4c8a88740a2cc2a20c709fe869c4dd1e (patch)
tree0dfa4439f3de544d7e52abf56c578e10e5346458 /crypto
parent827f04d5105e9bec0af214c42b8ad799fba5bb0d (diff)
Maintain strict type discipline between the core and providers
A provider could be linked against a different version of libcrypto than the version of libcrypto that loaded the provider. Different versions of libcrypto could define opaque types differently. It must never occur that a type created in one libcrypto is used directly by the other libcrypto. This will cause crashes. We can "cheat" for "built-in" providers that are part of libcrypto itself, because we know that the two libcrypto versions are the same - but not for other providers. To ensure this does not occur we use different types names for the handful of opaque types that are passed between the core and providers. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11758)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/initthread.c2
-rw-r--r--crypto/provider_core.c52
-rw-r--r--crypto/serializer/serializer_pkey.c5
3 files changed, 42 insertions, 17 deletions
diff --git a/crypto/initthread.c b/crypto/initthread.c
index 8f0678970a..a97cf359af 100644
--- a/crypto/initthread.c
+++ b/crypto/initthread.c
@@ -360,7 +360,7 @@ int ossl_init_thread_start(const void *index, void *arg,
* libcrypto to tell us about later thread stop events. c_thread_start
* is a callback to libcrypto defined in fipsprov.c
*/
- if (!c_thread_start(FIPS_get_provider(ctx), ossl_ctx_thread_stop))
+ if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_ctx_thread_stop))
return 0;
}
#endif
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 1cbe369754..662576cd7b 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -488,8 +488,8 @@ static int provider_activate(OSSL_PROVIDER *prov)
/* Call the initialise function for the provider. */
if (prov->init_function == NULL
- || !prov->init_function(prov, core_dispatch, &provider_dispatch,
- &tmp_provctx)) {
+ || !prov->init_function((OSSL_CORE_HANDLE *)prov, core_dispatch,
+ &provider_dispatch, &tmp_provctx)) {
ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, NULL,
"name=%s", prov->name);
#ifndef FIPS_MODULE
@@ -818,15 +818,20 @@ static OSSL_core_clear_last_error_mark_fn core_clear_last_error_mark;
static OSSL_core_pop_error_to_mark_fn core_pop_error_to_mark;
#endif
-static const OSSL_PARAM *core_gettable_params(const OSSL_PROVIDER *prov)
+static const OSSL_PARAM *core_gettable_params(const OSSL_CORE_HANDLE *handle)
{
return param_types;
}
-static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
+static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[])
{
int i;
OSSL_PARAM *p;
+ /*
+ * We created this object originally and we know it is actually an
+ * OSSL_PROVIDER *, so the cast is safe
+ */
+ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle;
if ((p = OSSL_PARAM_locate(params, "openssl-version")) != NULL)
OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR);
@@ -850,14 +855,26 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
return 1;
}
-static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov)
+static OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle)
{
- return ossl_provider_library_context(prov);
+ /*
+ * We created this object originally and we know it is actually an
+ * OSSL_PROVIDER *, so the cast is safe
+ */
+ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle;
+
+ return (OPENSSL_CORE_CTX *)ossl_provider_library_context(prov);
}
-static int core_thread_start(const OSSL_PROVIDER *prov,
+static int core_thread_start(const OSSL_CORE_HANDLE *handle,
OSSL_thread_stop_handler_fn handfn)
{
+ /*
+ * We created this object originally and we know it is actually an
+ * OSSL_PROVIDER *, so the cast is safe
+ */
+ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle;
+
return ossl_init_thread_start(prov, prov->provctx, handfn);
}
@@ -868,27 +885,33 @@ static int core_thread_start(const OSSL_PROVIDER *prov,
*/
#ifndef FIPS_MODULE
/*
- * TODO(3.0) These error functions should use |prov| to select the proper
+ * TODO(3.0) These error functions should use |handle| to select the proper
* library context to report in the correct error stack, at least if error
* stacks become tied to the library context.
* We cannot currently do that since there's no support for it in the
* ERR subsystem.
*/
-static void core_new_error(const OSSL_PROVIDER *prov)
+static void core_new_error(const OSSL_CORE_HANDLE *handle)
{
ERR_new();
}
-static void core_set_error_debug(const OSSL_PROVIDER *prov,
+static void core_set_error_debug(const OSSL_CORE_HANDLE *handle,
const char *file, int line, const char *func)
{
ERR_set_debug(file, line, func);
}
-static void core_vset_error(const OSSL_PROVIDER *prov,
+static void core_vset_error(const OSSL_CORE_HANDLE *handle,
uint32_t reason, const char *fmt, va_list args)
{
/*
+ * We created this object originally and we know it is actually an
+ * OSSL_PROVIDER *, so the cast is safe
+ */
+ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle;
+
+ /*
* If the uppermost 8 bits are non-zero, it's an OpenSSL library
* error and will be treated as such. Otherwise, it's a new style
* provider error and will be treated as such.
@@ -900,17 +923,17 @@ static void core_vset_error(const OSSL_PROVIDER *prov,
}
}
-static int core_set_error_mark(const OSSL_PROVIDER *prov)
+static int core_set_error_mark(const OSSL_CORE_HANDLE *handle)
{
return ERR_set_mark();
}
-static int core_clear_last_error_mark(const OSSL_PROVIDER *prov)
+static int core_clear_last_error_mark(const OSSL_CORE_HANDLE *handle)
{
return ERR_clear_last_mark();
}
-static int core_pop_error_to_mark(const OSSL_PROVIDER *prov)
+static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
{
return ERR_pop_to_mark();
}
@@ -936,6 +959,7 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))BIO_new_file },
{ OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf },
{ OSSL_FUNC_BIO_READ_EX, (void (*)(void))BIO_read_ex },
+ { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))BIO_write_ex },
{ OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free },
{ OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf },
{ OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf },
diff --git a/crypto/serializer/serializer_pkey.c b/crypto/serializer/serializer_pkey.c
index 3750ea3df1..a3b854e5da 100644
--- a/crypto/serializer/serializer_pkey.c
+++ b/crypto/serializer/serializer_pkey.c
@@ -255,7 +255,7 @@ static int serializer_write_cb(const OSSL_PARAM params[], void *arg)
OSSL_SERIALIZER_CTX *ctx = write_data->ctx;
BIO *out = write_data->out;
- return ctx->ser->serialize_data(ctx->serctx, params, out,
+ return ctx->ser->serialize_data(ctx->serctx, params, (OSSL_CORE_BIO *)out,
serializer_passphrase_out_cb, ctx);
}
@@ -291,7 +291,8 @@ static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out)
&serializer_write_cb, &write_data);
}
- return ctx->ser->serialize_object(ctx->serctx, keydata, out,
+ return ctx->ser->serialize_object(ctx->serctx, keydata,
+ (OSSL_CORE_BIO *)out,
serializer_passphrase_out_cb, ctx);
}