static int openssl_engine_set_default(lua_State*L){ ENGINE* eng = CHECK_OBJECT(1,ENGINE,"openssl.engine"); int ret = 0; int first = 3; int top = lua_gettop(L); if(top==2){ if(lua_isnumber(L, 2)) { int methods = luaL_checkint(L, 2); ret = ENGINE_set_default(eng, methods); }else if(lua_isstring(L,2)){ const char* s = luaL_checkstring(L, 2); ret = ENGINE_set_default_string(eng, s); }else luaL_error(L, "#2 must be a number or string"); lua_pushboolean(L, ret); return 1; } while(first<=top){ int c = luaL_checkoption(L, first, "RSA",list); switch(c){ case 0: ret = ENGINE_set_default_RSA(eng); break; case 1: ret = ENGINE_set_default_DSA(eng); break; case 2: ret = ENGINE_set_default_ECDH(eng); break; case 3: ret = ENGINE_set_default_ECDSA(eng); break; case 4: ret = ENGINE_set_default_DH(eng); break; case 5: ret = ENGINE_set_default_RAND(eng); break; case 7: ret = ENGINE_set_default_ciphers(eng); break; case 8: ret = ENGINE_set_default_digests(eng); break; case 6: default: luaL_error(L,"not support %d for %s",c, list[c]); break; } first++; if(ret!=1){ lua_pushboolean(L, 0); return 1; } } lua_pushboolean(L, ret); return 1; };
int ENGINE_set_default(ENGINE *e, unsigned int flags) { if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) return 0; if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) return 0; #ifndef OPENSSL_NO_RSA if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) return 0; #endif #ifndef OPENSSL_NO_DSA if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) return 0; #endif #ifndef OPENSSL_NO_DH if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) return 0; #endif #ifndef OPENSSL_NO_ECDH if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e)) return 0; #endif #ifndef OPENSSL_NO_ECDSA if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e)) return 0; #endif if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) return 0; return 1; }
static int load_tpm_certificate(struct openconnect_info *vpninfo) { ENGINE *e; EVP_PKEY *key; UI_METHOD *meth = NULL; int ret = 0; ENGINE_load_builtin_engines(); e = ENGINE_by_id("tpm"); if (!e) { vpn_progress(vpninfo, PRG_ERR, _("Can't load TPM engine.\n")); openconnect_report_ssl_errors(vpninfo); return -EINVAL; } if (!ENGINE_init(e) || !ENGINE_set_default_RSA(e) || !ENGINE_set_default_RAND(e)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to init TPM engine\n")); openconnect_report_ssl_errors(vpninfo); ENGINE_free(e); return -EINVAL; } if (vpninfo->cert_password) { if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->cert_password), vpninfo->cert_password, NULL, 0)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to set TPM SRK password\n")); openconnect_report_ssl_errors(vpninfo); } vpninfo->cert_password = NULL; free(vpninfo->cert_password); } else { /* Provide our own UI method to handle the PIN callback. */ meth = create_openssl_ui(vpninfo); } key = ENGINE_load_private_key(e, vpninfo->sslkey, meth, NULL); if (meth) UI_destroy_method(meth); if (!key) { vpn_progress(vpninfo, PRG_ERR, _("Failed to load TPM private key\n")); openconnect_report_ssl_errors(vpninfo); ret = -EINVAL; goto out; } if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) { vpn_progress(vpninfo, PRG_ERR, _("Add key from TPM failed\n")); openconnect_report_ssl_errors(vpninfo); ret = -EINVAL; } EVP_PKEY_free(key); out: ENGINE_finish(e); ENGINE_free(e); return ret; }
isc_result_t dst__openssl_init(const char *engine) { isc_result_t result; #ifdef USE_ENGINE ENGINE *re; #else UNUSED(engine); #endif #ifdef DNS_CRYPTO_LEAKS CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #endif CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free); nlocks = CRYPTO_num_locks(); locks = mem_alloc(sizeof(isc_mutex_t) * nlocks); if (locks == NULL) return (ISC_R_NOMEMORY); result = isc_mutexblock_init(locks, nlocks); if (result != ISC_R_SUCCESS) goto cleanup_mutexalloc; CRYPTO_set_locking_callback(lock_callback); #if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_set_id_callback(id_callback); #endif ERR_load_crypto_strings(); rm = mem_alloc(sizeof(RAND_METHOD)); if (rm == NULL) { result = ISC_R_NOMEMORY; goto cleanup_mutexinit; } rm->seed = NULL; rm->bytes = entropy_get; rm->cleanup = NULL; rm->add = entropy_add; rm->pseudorand = entropy_getpseudo; rm->status = entropy_status; #ifdef USE_ENGINE OPENSSL_config(NULL); if (engine != NULL && *engine == '\0') engine = NULL; if (engine != NULL) { e = ENGINE_by_id(engine); if (e == NULL) { result = DST_R_NOENGINE; goto cleanup_rm; } /* This will init the engine. */ if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { result = DST_R_NOENGINE; goto cleanup_rm; } } re = ENGINE_get_default_RAND(); if (re == NULL) { re = ENGINE_new(); if (re == NULL) { result = ISC_R_NOMEMORY; goto cleanup_rm; } ENGINE_set_RAND(re, rm); ENGINE_set_default_RAND(re); ENGINE_free(re); } else ENGINE_finish(re); #else RAND_set_rand_method(rm); #endif /* USE_ENGINE */ return (ISC_R_SUCCESS); #ifdef USE_ENGINE cleanup_rm: if (e != NULL) ENGINE_free(e); e = NULL; mem_free(rm); rm = NULL; #endif cleanup_mutexinit: CRYPTO_set_locking_callback(NULL); DESTROYMUTEXBLOCK(locks, nlocks); cleanup_mutexalloc: mem_free(locks); locks = NULL; return (result); }
isc_result_t dst__openssl_init() { isc_result_t result; #ifdef USE_ENGINE /* const char *name; */ ENGINE *re; #endif #ifdef DNS_CRYPTO_LEAKS CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #endif CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free); nlocks = CRYPTO_num_locks(); locks = mem_alloc(sizeof(isc_mutex_t) * nlocks); if (locks == NULL) return (ISC_R_NOMEMORY); result = isc_mutexblock_init(locks, nlocks); if (result != ISC_R_SUCCESS) goto cleanup_mutexalloc; CRYPTO_set_locking_callback(lock_callback); CRYPTO_set_id_callback(id_callback); rm = mem_alloc(sizeof(RAND_METHOD)); if (rm == NULL) { result = ISC_R_NOMEMORY; goto cleanup_mutexinit; } rm->seed = NULL; rm->bytes = entropy_get; rm->cleanup = NULL; rm->add = entropy_add; rm->pseudorand = entropy_getpseudo; rm->status = entropy_status; #ifdef USE_ENGINE OPENSSL_config(NULL); #ifdef USE_PKCS11 #ifndef PKCS11_SO_PATH #define PKCS11_SO_PATH "/usr/local/lib/engines/engine_pkcs11.so" #endif #ifndef PKCS11_MODULE_PATH #define PKCS11_MODULE_PATH "/usr/lib/libpkcs11.so" #endif { /* * to use this to config the PIN, add in openssl.cnf: * - at the beginning: "openssl_conf = openssl_def" * - at any place these sections: * [ openssl_def ] * engines = engine_section * [ engine_section ] * pkcs11 = pkcs11_section * [ pkcs11_section ] * PIN = my___pin */ const char *pre_cmds[] = { "SO_PATH", PKCS11_SO_PATH, "LOAD", NULL, "MODULE_PATH", PKCS11_MODULE_PATH }; const char *post_cmds[] = { /* "PIN", "my___pin" */ }; result = dst__openssl_load_engine("pkcs11", "pkcs11", pre_cmds, 0, post_cmds, /*1*/ 0); if (result != ISC_R_SUCCESS) goto cleanup_rm; } #endif /* USE_PKCS11 */ if (engine_id != NULL) { e = ENGINE_by_id(engine_id); if (e == NULL) { result = ISC_R_NOTFOUND; goto cleanup_rm; } if (!ENGINE_init(e)) { result = ISC_R_FAILURE; ENGINE_free(e); goto cleanup_rm; } ENGINE_set_default(e, ENGINE_METHOD_ALL); ENGINE_free(e); } else { ENGINE_register_all_complete(); for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) { /* * Something weird here. If we call ENGINE_finish() * ENGINE_get_default_RAND() will fail. */ if (ENGINE_init(e)) { if (he == NULL) he = e; } } } re = ENGINE_get_default_RAND(); if (re == NULL) { re = ENGINE_new(); if (re == NULL) { result = ISC_R_NOMEMORY; goto cleanup_rm; } ENGINE_set_RAND(re, rm); ENGINE_set_default_RAND(re); ENGINE_free(re); } else ENGINE_finish(re); #else RAND_set_rand_method(rm); #endif /* USE_ENGINE */ return (ISC_R_SUCCESS); #ifdef USE_ENGINE cleanup_rm: mem_free(rm); #endif cleanup_mutexinit: CRYPTO_set_locking_callback(NULL); DESTROYMUTEXBLOCK(locks, nlocks); cleanup_mutexalloc: mem_free(locks); return (result); }