Maintain strict type discipline between the core and providers
[openssl.git] / crypto / provider_core.c
index b100e5a15d542b9fa568ad9bb005a9126e26beb2..662576cd7b1dfff13e44832764438742a881ad5e 100644 (file)
@@ -418,6 +418,7 @@ int OSSL_PROVIDER_set_default_search_path(OPENSSL_CTX *libctx, const char *path)
 static int provider_activate(OSSL_PROVIDER *prov)
 {
     const OSSL_DISPATCH *provider_dispatch = NULL;
+    void *tmp_provctx = NULL;    /* safety measure */
 #ifndef OPENSSL_NO_ERR
 # ifndef FIPS_MODULE
     OSSL_provider_get_reason_strings_fn *p_get_reason_strings = NULL;
@@ -487,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,
-                                &prov->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
@@ -497,6 +498,7 @@ static int provider_activate(OSSL_PROVIDER *prov)
 #endif
         return 0;
     }
+    prov->provctx = tmp_provctx;
 
     for (; provider_dispatch->function_id != 0; provider_dispatch++) {
         switch (provider_dispatch->function_id) {
@@ -816,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);
@@ -848,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);
 }
 
@@ -866,26 +885,32 @@ 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
@@ -898,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();
 }
@@ -934,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 },