int CRYPTO_THREAD_lock_new() { int i; if (CRYPTO_get_dynlock_create_callback() == NULL || CRYPTO_get_dynlock_lock_callback() == NULL || CRYPTO_get_dynlock_destroy_callback() == NULL) return 0; /* Dynamic callbacks not set */ i = CRYPTO_get_new_dynlockid(); if (i == 0) ERR_clear_error(); /* Dynamic locks are optional -> ignore */ return i; }
void start() { Platform::ThirdParty::start(); if (!RAND_status()) { // should be always inited in all modern OS char buf[16]; memcpy(buf, &_msStart, 8); memcpy(buf + 8, &_msFreq, 8); uchar sha256Buffer[32]; RAND_seed(hashSha256(buf, 16, sha256Buffer), 32); if (!RAND_status()) { LOG(("MTP Error: Could not init OpenSSL rand, RAND_status() is 0...")); } } // Force OpenSSL loading if it is linked in Qt, // so that we won't mess with our OpenSSL locking with Qt OpenSSL locking. auto sslSupported = QSslSocket::supportsSsl(); if (!sslSupported) { LOG(("Error: current Qt build doesn't support SSL requests.")); } if (!CRYPTO_get_locking_callback()) { // Qt didn't initialize OpenSSL, so we will. auto numLocks = CRYPTO_num_locks(); if (numLocks) { _sslLocks = new QMutex[numLocks]; CRYPTO_set_locking_callback(_sslLockingCallback); } else { LOG(("MTP Error: Could not init OpenSSL threads, CRYPTO_num_locks() returned zero!")); } CRYPTO_THREADID_set_callback(_sslThreadId); } if (!CRYPTO_get_dynlock_create_callback()) { CRYPTO_set_dynlock_create_callback(_sslCreateFunction); CRYPTO_set_dynlock_lock_callback(_sslLockFunction); CRYPTO_set_dynlock_destroy_callback(_sslDestroyFunction); } else if (!CRYPTO_get_dynlock_lock_callback()) { LOG(("MTP Error: dynlock_create callback is set without dynlock_lock callback!")); } av_register_all(); avcodec_register_all(); av_lockmgr_register(_ffmpegLockManager); _sslInited = true; }
static BOOL _winpr_openssl_cleanup_locking(void) { /* undo our static locking modifications */ if (CRYPTO_get_locking_callback() == _winpr_openssl_locking) { int i; CRYPTO_set_locking_callback(NULL); for (i = 0; i < g_winpr_openssl_num_locks; i++) { CloseHandle(g_winpr_openssl_locks[i]); } g_winpr_openssl_num_locks = 0; free(g_winpr_openssl_locks); g_winpr_openssl_locks = NULL; } /* unset our dynamic locking callbacks */ if (CRYPTO_get_dynlock_create_callback() == _winpr_openssl_dynlock_create) { CRYPTO_set_dynlock_create_callback(NULL); } if (CRYPTO_get_dynlock_lock_callback() == _winpr_openssl_dynlock_lock) { CRYPTO_set_dynlock_lock_callback(NULL); } if (CRYPTO_get_dynlock_destroy_callback() == _winpr_openssl_dynlock_destroy) { CRYPTO_set_dynlock_destroy_callback(NULL); } #if (OPENSSL_VERSION_NUMBER < 0x10000000L) if (CRYPTO_get_id_callback() == _winpr_openssl_id) { CRYPTO_set_id_callback(NULL); } #endif return TRUE; }
/* Function called from ENGINE_init() */ int pkcs11_init(ENGINE_CTX *ctx) { /* OpenSC implicitly locks CRYPTO_LOCK_ENGINE during C_GetSlotList(). * OpenSSL also locks CRYPTO_LOCK_ENGINE in ENGINE_init(). * Double-locking a non-recursive rwlock causes the application to * crash or hang, depending on the locking library implementation. */ /* Only attempt initialization when dynamic locks are unavailable. * This likely also indicates a single-threaded application, * so temporarily unlocking CRYPTO_LOCK_ENGINE should be safe. */ #if OPENSSL_VERSION_NUMBER < 0x10100004L if (CRYPTO_get_dynlock_create_callback() == NULL || CRYPTO_get_dynlock_lock_callback() == NULL || CRYPTO_get_dynlock_destroy_callback() == NULL) { CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); pkcs11_init_libp11_unlocked(ctx); CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); return ctx->pkcs11_ctx && ctx->slot_list ? 1 : 0; } #endif return 1; }
static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) { ENGINE cpy; dynamic_fns fns; if (ctx->dynamic_dso == NULL) ctx->dynamic_dso = DSO_new(); if (ctx->dynamic_dso == NULL) return 0; if (!ctx->DYNAMIC_LIBNAME) { if (!ctx->engine_id) return 0; ctx->DYNAMIC_LIBNAME = DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); } if (!int_load(ctx)) { ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND); DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; return 0; } /* We have to find a bind function otherwise it'll always end badly */ if (! (ctx->bind_engine = (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso, ctx->DYNAMIC_F2))) { ctx->bind_engine = NULL; DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE); return 0; } /* Do we perform version checking? */ if (!ctx->no_vcheck) { unsigned long vcheck_res = 0; /* * Now we try to find a version checking function and decide how to * cope with failure if/when it fails. */ ctx->v_check = (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso, ctx->DYNAMIC_F1); if (ctx->v_check) vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); /* * We fail if the version checker veto'd the load *or* if it is * deferring to us (by returning its version) and we think it is too * old. */ if (vcheck_res < OSSL_DYNAMIC_OLDEST) { /* Fail */ ctx->bind_engine = NULL; ctx->v_check = NULL; DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_VERSION_INCOMPATIBILITY); return 0; } } /* * First binary copy the ENGINE structure so that we can roll back if the * hand-over fails */ memcpy(&cpy, e, sizeof(ENGINE)); /* * Provide the ERR, "ex_data", memory, and locking callbacks so the * loaded library uses our state rather than its own. FIXME: As noted in * engine.h, much of this would be simplified if each area of code * provided its own "summary" structure of all related callbacks. It * would also increase opaqueness. */ fns.static_state = ENGINE_get_static_state(); fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback(); fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback(); /* * Now that we've loaded the dynamic engine, make sure no "dynamic" * ENGINE elements will show through. */ engine_set_all_null(e); /* Try to bind the ENGINE onto our own ENGINE structure */ if (!ctx->bind_engine(e, ctx->engine_id, &fns)) { ctx->bind_engine = NULL; ctx->v_check = NULL; DSO_free(ctx->dynamic_dso); ctx->dynamic_dso = NULL; ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED); /* Copy the original ENGINE structure back */ memcpy(e, &cpy, sizeof(ENGINE)); return 0; } /* Do we try to add this ENGINE to the internal list too? */ if (ctx->list_add_value > 0) { if (!ENGINE_add(e)) { /* Do we tolerate this or fail? */ if (ctx->list_add_value > 1) { /* * Fail - NB: By this time, it's too late to rollback, and * trying to do so allows the bind_engine() code to have * created leaks. We just have to fail where we are, after * the ENGINE has changed. */ ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_CONFLICTING_ENGINE_ID); return 0; } /* Tolerate */ ERR_clear_error(); } } return 1; }
static BOOL _winpr_openssl_initialize_locking(void) { int i, count; /* OpenSSL static locking */ if (CRYPTO_get_locking_callback()) { WLog_WARN(TAG, "OpenSSL static locking callback is already set"); } else { if ((count = CRYPTO_num_locks()) > 0) { HANDLE* locks; if (!(locks = calloc(count, sizeof(HANDLE)))) { WLog_ERR(TAG, "error allocating lock table"); return FALSE; } for (i = 0; i < count; i++) { if (!(locks[i] = CreateMutex(NULL, FALSE, NULL))) { WLog_ERR(TAG, "error creating lock #%d", i); while (i--) { if (locks[i]) CloseHandle(locks[i]); } free(locks); return FALSE; } } g_winpr_openssl_locks = locks; g_winpr_openssl_num_locks = count; CRYPTO_set_locking_callback(_winpr_openssl_locking); } } /* OpenSSL dynamic locking */ if (CRYPTO_get_dynlock_create_callback() || CRYPTO_get_dynlock_lock_callback() || CRYPTO_get_dynlock_destroy_callback()) { WLog_WARN(TAG, "dynamic locking callbacks are already set"); } else { CRYPTO_set_dynlock_create_callback(_winpr_openssl_dynlock_create); CRYPTO_set_dynlock_lock_callback(_winpr_openssl_dynlock_lock); CRYPTO_set_dynlock_destroy_callback(_winpr_openssl_dynlock_destroy); } /* Use the deprecated CRYPTO_get_id_callback() if building against OpenSSL < 1.0.0 */ #if (OPENSSL_VERSION_NUMBER < 0x10000000L) if (CRYPTO_get_id_callback()) { WLog_WARN(TAG, "OpenSSL id_callback is already set"); } else { CRYPTO_set_id_callback(_winpr_openssl_id); } #endif return TRUE; }
/* (de)initialisation functions. */ static int hwcrhk_init(ENGINE *e) { HWCryptoHook_Init_t *p1; HWCryptoHook_Finish_t *p2; HWCryptoHook_ModExp_t *p3; #ifndef OPENSSL_NO_RSA HWCryptoHook_RSA_t *p4; HWCryptoHook_RSALoadKey_t *p5; HWCryptoHook_RSAGetPublicKey_t *p6; HWCryptoHook_RSAUnloadKey_t *p7; #endif HWCryptoHook_RandomBytes_t *p8; HWCryptoHook_ModExpCRT_t *p9; if(hwcrhk_dso != NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED); goto err; } /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0); if(hwcrhk_dso == NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } if(!(p1 = (HWCryptoHook_Init_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) || !(p2 = (HWCryptoHook_Finish_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || !(p3 = (HWCryptoHook_ModExp_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || #ifndef OPENSSL_NO_RSA !(p4 = (HWCryptoHook_RSA_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || !(p5 = (HWCryptoHook_RSALoadKey_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) || !(p6 = (HWCryptoHook_RSAGetPublicKey_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || !(p7 = (HWCryptoHook_RSAUnloadKey_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || #endif !(p8 = (HWCryptoHook_RandomBytes_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || !(p9 = (HWCryptoHook_ModExpCRT_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } /* Copy the pointers */ p_hwcrhk_Init = p1; p_hwcrhk_Finish = p2; p_hwcrhk_ModExp = p3; #ifndef OPENSSL_NO_RSA p_hwcrhk_RSA = p4; p_hwcrhk_RSALoadKey = p5; p_hwcrhk_RSAGetPublicKey = p6; p_hwcrhk_RSAUnloadKey = p7; #endif p_hwcrhk_RandomBytes = p8; p_hwcrhk_ModExpCRT = p9; /* Check if the application decided to support dynamic locks, and if it does, use them. */ if (disable_mutex_callbacks == 0) { if (CRYPTO_get_dynlock_create_callback() != NULL && CRYPTO_get_dynlock_lock_callback() != NULL && CRYPTO_get_dynlock_destroy_callback() != NULL) { hwcrhk_globals.mutex_init = hwcrhk_mutex_init; hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; } } /* Try and get a context - if not, we may have a DSO but no * accelerator! */ if(!get_context(&hwcrhk_context, &password_context)) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE); goto err; } /* Everything's fine. */ #ifndef OPENSSL_NO_RSA if (hndidx_rsa == -1) hndidx_rsa = RSA_get_ex_new_index(0, "nFast HWCryptoHook RSA key handle", NULL, NULL, NULL); #endif return 1; err: if(hwcrhk_dso) DSO_free(hwcrhk_dso); hwcrhk_dso = NULL; p_hwcrhk_Init = NULL; p_hwcrhk_Finish = NULL; p_hwcrhk_ModExp = NULL; #ifndef OPENSSL_NO_RSA p_hwcrhk_RSA = NULL; p_hwcrhk_RSALoadKey = NULL; p_hwcrhk_RSAGetPublicKey = NULL; p_hwcrhk_RSAUnloadKey = NULL; #endif p_hwcrhk_ModExpCRT = NULL; p_hwcrhk_RandomBytes = NULL; return 0; }