ERL_NIF_TERM engine_add_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Engine) */ #ifdef HAS_ENGINE_SUPPORT struct engine_ctx *ctx; // Get Engine ASSERT(argc == 1); if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)) goto bad_arg; if (!ENGINE_add(ctx->engine)) goto failed; return atom_ok; bad_arg: return enif_make_badarg(env); failed: return ERROR_Atom(env, "add_engine_failed"); #else return atom_notsup; #endif }
static int openssl_engine_add(lua_State*L) { ENGINE* eng = CHECK_OBJECT(1, ENGINE, "openssl.engine"); int ret = ENGINE_add(eng); lua_pushboolean(L, ret); return 1; }
void ENGINE_load_gost(void) { ENGINE *toadd =engine_gost(); if (!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
void ENGINE_load_4758cca(void) { ENGINE *e_4758 = engine_4758_cca(); if (!e_4758) return; ENGINE_add(e_4758); ENGINE_free(e_4758); ERR_clear_error(); }
void ENGINE_load_ubsec(void) { /* Copied from eng_[openssl|dyn].c */ ENGINE *toadd = engine_ubsec(); if(!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
void engine_load_dasync_int(void) { ENGINE *toadd = engine_dasync(); if (!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
static ENGINE* LoadEngine() { // This function creates an engine for PKCS#11 and inspired by // the "ENGINE_load_dynamic" function from OpenSSL, in file // "crypto/engine/eng_dyn.c" ENGINE* engine = ENGINE_new(); if (!engine) { LOG(ERROR) << "Cannot create an OpenSSL engine for PKCS#11"; throw OrthancException(ErrorCode_InternalError); } // Create a PKCS#11 context using libp11 context_ = pkcs11_new(); if (!context_) { LOG(ERROR) << "Cannot create a libp11 context for PKCS#11"; ENGINE_free(engine); throw OrthancException(ErrorCode_InternalError); } if (!ENGINE_set_id(engine, PKCS11_ENGINE_ID) || !ENGINE_set_name(engine, PKCS11_ENGINE_NAME) || !ENGINE_set_cmd_defns(engine, PKCS11_ENGINE_COMMANDS) || // Register the callback functions !ENGINE_set_init_function(engine, EngineInitialize) || !ENGINE_set_finish_function(engine, EngineFinalize) || !ENGINE_set_destroy_function(engine, EngineDestroy) || !ENGINE_set_ctrl_function(engine, EngineControl) || !ENGINE_set_load_pubkey_function(engine, EngineLoadPublicKey) || !ENGINE_set_load_privkey_function(engine, EngineLoadPrivateKey) || !ENGINE_set_RSA(engine, PKCS11_get_rsa_method()) || !ENGINE_set_ECDSA(engine, PKCS11_get_ecdsa_method()) || !ENGINE_set_ECDH(engine, PKCS11_get_ecdh_method()) || #if OPENSSL_VERSION_NUMBER >= 0x10100002L !ENGINE_set_EC(engine, PKCS11_get_ec_key_method()) || #endif // Make OpenSSL know about our PKCS#11 engine !ENGINE_add(engine)) { LOG(ERROR) << "Cannot initialize the OpenSSL engine for PKCS#11"; pkcs11_finish(context_); ENGINE_free(engine); throw OrthancException(ErrorCode_InternalError); } // If the "ENGINE_add" worked, it gets a structural // reference. We release our just-created reference. ENGINE_free(engine); return ENGINE_by_id(PKCS11_ENGINE_ID); }
void ENGINE_load_test(void) { fprintf(stderr, "arrive at ENGINE_load_test\n"); /* Copied from eng_[openssl|dyn].c */ ENGINE *toadd = engine_hwdev(); if(!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
void ENGINE_load_openssl(void) { ENGINE *toadd = engine_openssl(); if(!toadd) return; ENGINE_add(toadd); /* If the "add" worked, it gets a structural reference. So either way, * we release our just-created reference. */ ENGINE_free(toadd); ERR_clear_error(); }
void ENGINE_load_padlock (void) { /* On non-x86 CPUs it just returns. */ #ifdef COMPILE_HW_PADLOCK ENGINE *toadd = ENGINE_padlock (); if (!toadd) return; ENGINE_add (toadd); ENGINE_free (toadd); ERR_clear_error (); #endif }
static #endif void ENGINE_load_ibmca(void) { /* Copied from eng_[openssl|dyn].c */ ENGINE *toadd = engine_ibmca(); if(!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
void ENGINE_load_gost(void) { ENGINE *toadd; if (pmeth_GostR3410_94) return; toadd = engine_gost(); if (!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
static #endif void ENGINE_load_cluster_labs(void) { ENGINE *cluster_labs = engine_cluster_labs(); if(!cluster_labs) return; ENGINE_add(cluster_labs); ENGINE_free(cluster_labs); ERR_clear_error(); }
void ENGINE_load_aesni (void) { /* On non-x86 CPUs it just returns. */ #ifdef COMPILE_HW_AESNI ENGINE *toadd = ENGINE_aesni(); if (!toadd) return; ENGINE_add (toadd); ENGINE_free (toadd); ERR_clear_error (); #endif }
void ENGINE_load_rdrand (void) { extern unsigned int OPENSSL_ia32cap_P[]; if (OPENSSL_ia32cap_P[1] & (1<<(62-32))) { ENGINE *toadd = ENGINE_rdrand(); if(!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); } }
void ENGINE_load_dynamic(void) { ENGINE *toadd = engine_dynamic(); if(!toadd) return; ENGINE_add(toadd); /* If the "add" worked, it gets a structural reference. So either way, * we release our just-created reference. */ ENGINE_free(toadd); /* If the "add" didn't work, it was probably a conflict because it was * already added (eg. someone calling ENGINE_load_blah then calling * ENGINE_load_builtin_engines() perhaps). */ ERR_clear_error(); }
void ENGINE_load_HCSP(void) { ENGINE* toadd = engine_HCSP(); /* Copied from eng_[openssl|dyn].c */ if (!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); #ifndef OPENSSL_NO_ERR ERR_clear_error(); #endif }
void engine_load_afalg_int(void) { ENGINE *toadd; if (!afalg_chk_platform()) return; toadd = engine_afalg(); if (toadd == NULL) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
/* * this function does not exist in OpenSSL yet... or ever?. * a future version may break this function. * tested on 0.9.7d. */ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in) { memcpy(out, in, sizeof(EVP_CIPHER_CTX)); #if defined(HAVE_ENGINE_ADD) && defined(HAVE_ST_ENGINE) if (in->engine) ENGINE_add(out->engine); if (in->cipher_data) { out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); } #endif return 1; }
/* * This makes the engine "built-in" with OpenSSL. * On non-T4 CPUs this just returns. * Called by ENGINE_load_builtin_engines(). */ void ENGINE_load_t4(void) { #ifdef COMPILE_HW_T4 ENGINE *toadd = ENGINE_new(); if (toadd != NULL) { if (t4_bind_helper(toadd, ENGINE_T4_ID) != 0) { (void) ENGINE_add(toadd); (void) ENGINE_free(toadd); ERR_clear_error(); } else { (void) ENGINE_free(toadd); } } #endif }
/* * In case this engine is built into libcrypto, then it doesn't offer any * ability to be dynamically loadable. */ void engine_load_devcrypto_int(void) { ENGINE *e = NULL; if (!open_devcrypto()) return; if ((e = ENGINE_new()) == NULL || !bind_devcrypto(e)) { close_devcrypto(); ENGINE_free(e); return; } ENGINE_add(e); ENGINE_free(e); /* Loose our local reference */ ERR_clear_error(); }
void ENGINE_load_qat(void) { ENGINE *toadd = engine_qat(); int error = 0; char error_string[120] = { 0 }; DEBUG("[%s] engine_load_qat\n", __func__); if (toadd == NULL) { error = ERR_get_error(); ERR_error_string(error, error_string); fprintf(stderr, "Error reported by engine load: %s\n", error_string); return; } DEBUG("[%s] engine_load_qat adding\n", __func__); ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
void ENGINE_load_qat(void) { ENGINE *toadd; int error = 0; char error_string[QAT_MAX_ERROR_STRING] = { 0 }; QAT_DEBUG_LOG_INIT(); DEBUG("- Starting\n"); toadd = engine_qat(); if (toadd == NULL) { error = ERR_peek_error(); ERR_error_string_n(error, error_string, QAT_MAX_ERROR_STRING); WARN("Error reported by engine load: %s\n", error_string); return; } DEBUG("adding engine\n"); ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); }
/* Returns 1 if successfully added, 2 if engine has previously been added, and 0 for error. */ int Cryptography_add_osrandom_engine(void) { ENGINE *e; ERR_load_Cryptography_OSRandom_strings(); e = ENGINE_by_id(Cryptography_osrandom_engine_id); if (e != NULL) { ENGINE_free(e); return 2; } else { ERR_clear_error(); } e = ENGINE_new(); if (e == NULL) { return 0; } if (!ENGINE_set_id(e, Cryptography_osrandom_engine_id) || !ENGINE_set_name(e, Cryptography_osrandom_engine_name) || !ENGINE_set_RAND(e, &osrandom_rand) || !ENGINE_set_init_function(e, osrandom_init) || !ENGINE_set_finish_function(e, osrandom_finish) || !ENGINE_set_cmd_defns(e, osrandom_cmd_defns) || !ENGINE_set_ctrl_function(e, osrandom_ctrl)) { ENGINE_free(e); return 0; } if (!ENGINE_add(e)) { ENGINE_free(e); return 0; } if (!ENGINE_free(e)) { return 0; } return 1; }
int64_t s2n_public_random(int64_t max) { uint64_t r; gt_check(max, 0); while(1) { struct s2n_blob blob = { .data = (void *) &r, sizeof(r) }; GUARD(s2n_get_public_random_data(&blob)); /* Imagine an int was one byte and UINT_MAX was 256. If the * caller asked for s2n_random(129, ...) we'd end up in * trouble. Each number in the range 0...127 would be twice * as likely as 128. That's because r == 0 % 129 -> 0, and * r == 129 % 129 -> 0, but only r == 128 returns 128, * r == 257 is out of range. * * To de-bias the dice, we discard values of r that are higher * that the highest multiple of 'max' an int can support. If * max is a uint, then in the worst case we discard 50% - 1 r's. * But since 'max' is an int and INT_MAX is <= UINT_MAX / 2, * in the worst case we discard 25% - 1 r's. */ if (r < (UINT64_MAX - (UINT64_MAX % max))) { return r % max; } } return -1; } #ifndef OPENSSL_IS_BORINGSSL int s2n_openssl_compat_rand(unsigned char *buf, int num) { struct s2n_blob out = {.data = buf, .size = num}; if(s2n_get_private_random_data(&out) < 0) { return 0; } return 1; } int s2n_openssl_compat_status(void) { return 1; } int s2n_openssl_compat_init(ENGINE *unused) { return 1; } RAND_METHOD s2n_openssl_rand_method = { .seed = NULL, .bytes = s2n_openssl_compat_rand, .cleanup = NULL, .add = NULL, .pseudorand = s2n_openssl_compat_rand, .status = s2n_openssl_compat_status }; #endif int s2n_init(void) { GUARD(s2n_mem_init()); OPEN: entropy_fd = open(ENTROPY_SOURCE, O_RDONLY); if (entropy_fd == -1) { if (errno == EINTR) { goto OPEN; } S2N_ERROR(S2N_ERR_OPEN_RANDOM); } #if defined(MAP_INHERIT_ZERO) if ((zero_if_forked_ptr = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { S2N_ERROR(S2N_ERR_OPEN_RANDOM); } if (minherit(zero_if_forked_ptr, sizeof(int), MAP_INHERIT_ZERO) == -1) { S2N_ERROR(S2N_ERR_OPEN_RANDOM); } #else if (pthread_atfork(NULL, NULL, s2n_on_fork) != 0) { S2N_ERROR(S2N_ERR_OPEN_RANDOM); } #endif GUARD(s2n_check_fork()); #ifndef OPENSSL_IS_BORINGSSL /* Create an engine */ ENGINE *e = ENGINE_new(); if (e == NULL || ENGINE_set_id(e, "s2n") != 1 || ENGINE_set_name(e, "s2n entropy generator") != 1 || ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) != 1 || ENGINE_set_init_function(e, s2n_openssl_compat_init) != 1 || ENGINE_set_RAND(e, &s2n_openssl_rand_method) != 1 || ENGINE_add(e) != 1 || ENGINE_free(e) != 1) { S2N_ERROR(S2N_ERR_OPEN_RANDOM); } /* Use that engine for rand() */ e = ENGINE_by_id("s2n"); if (e == NULL || ENGINE_init(e) != 1 || ENGINE_set_default(e, ENGINE_METHOD_RAND) != 1) { S2N_ERROR(S2N_ERR_OPEN_RANDOM); } #endif return 0; }
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; }
void ENGINE_load_cryptodev(void) { ENGINE *engine = ENGINE_new(); int fd; if (engine == NULL) return; if ((fd = get_dev_crypto()) < 0) { ENGINE_free(engine); return; } /* * find out what asymmetric crypto algorithms we support */ if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { close(fd); ENGINE_free(engine); return; } close(fd); if (!ENGINE_set_id(engine, "cryptodev") || !ENGINE_set_name(engine, "BSD cryptodev engine") || !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || !ENGINE_set_digests(engine, cryptodev_engine_digests) || !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { ENGINE_free(engine); return; } if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; if (cryptodev_asymfeat & CRF_MOD_EXP) { cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; else cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; } } if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { const DSA_METHOD *meth = DSA_OpenSSL(); memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); if (cryptodev_asymfeat & CRF_DSA_SIGN) cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; if (cryptodev_asymfeat & CRF_MOD_EXP) { cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; } if (cryptodev_asymfeat & CRF_DSA_VERIFY) cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; } if (ENGINE_set_DH(engine, &cryptodev_dh)){ const DH_METHOD *dh_meth = DH_OpenSSL(); cryptodev_dh.generate_key = dh_meth->generate_key; cryptodev_dh.compute_key = dh_meth->compute_key; cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; if (cryptodev_asymfeat & CRF_MOD_EXP) { cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) cryptodev_dh.compute_key = cryptodev_dh_compute_key; } } ENGINE_add(engine); ENGINE_free(engine); ERR_clear_error(); }
int main(int argc, char *argv[]) { ENGINE *block[512]; char buf[256]; const char *id, *name, *p; ENGINE *ptr; int loop; int to_return = 1; ENGINE *new_h1 = NULL; ENGINE *new_h2 = NULL; ENGINE *new_h3 = NULL; ENGINE *new_h4 = NULL; p = getenv("OPENSSL_DEBUG_MEMORY"); if (p != NULL && strcmp(p, "on") == 0) CRYPTO_set_mem_debug(1); memset(block, 0, sizeof(block)); if (((new_h1 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h1, "test_id0") || !ENGINE_set_name(new_h1, "First test item") || ((new_h2 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h2, "test_id1") || !ENGINE_set_name(new_h2, "Second test item") || ((new_h3 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h3, "test_id2") || !ENGINE_set_name(new_h3, "Third test item") || ((new_h4 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h4, "test_id3") || !ENGINE_set_name(new_h4, "Fourth test item")) { printf("Couldn't set up test ENGINE structures\n"); goto end; } printf("\nenginetest beginning\n\n"); display_engine_list(); if (!ENGINE_add(new_h1)) { printf("Add failed!\n"); goto end; } display_engine_list(); ptr = ENGINE_get_first(); if (!ENGINE_remove(ptr)) { printf("Remove failed!\n"); goto end; } ENGINE_free(ptr); display_engine_list(); if (!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) { printf("Add failed!\n"); goto end; } display_engine_list(); if (!ENGINE_remove(new_h2)) { printf("Remove failed!\n"); goto end; } display_engine_list(); if (!ENGINE_add(new_h4)) { printf("Add failed!\n"); goto end; } display_engine_list(); if (ENGINE_add(new_h3)) { printf("Add *should* have failed but didn't!\n"); goto end; } else printf("Add that should fail did.\n"); ERR_clear_error(); if (ENGINE_remove(new_h2)) { printf("Remove *should* have failed but didn't!\n"); goto end; } else printf("Remove that should fail did.\n"); ERR_clear_error(); if (!ENGINE_remove(new_h3)) { printf("Remove failed!\n"); goto end; } display_engine_list(); if (!ENGINE_remove(new_h4)) { printf("Remove failed!\n"); goto end; } display_engine_list(); /* * Depending on whether there's any hardware support compiled in, this * remove may be destined to fail. */ ptr = ENGINE_get_first(); if (ptr) if (!ENGINE_remove(ptr)) printf("Remove failed!i - probably no hardware " "support present.\n"); ENGINE_free(ptr); display_engine_list(); if (!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) { printf("Couldn't add and remove to an empty list!\n"); goto end; } else printf("Successfully added and removed to an empty list!\n"); printf("About to beef up the engine-type list\n"); for (loop = 0; loop < 512; loop++) { sprintf(buf, "id%i", loop); id = OPENSSL_strdup(buf); sprintf(buf, "Fake engine type %i", loop); name = OPENSSL_strdup(buf); if (((block[loop] = ENGINE_new()) == NULL) || !ENGINE_set_id(block[loop], id) || !ENGINE_set_name(block[loop], name)) { printf("Couldn't create block of ENGINE structures.\n" "I'll probably also core-dump now, damn.\n"); goto end; } } for (loop = 0; loop < 512; loop++) { if (!ENGINE_add(block[loop])) { printf("\nAdding stopped at %i, (%s,%s)\n", loop, ENGINE_get_id(block[loop]), ENGINE_get_name(block[loop])); goto cleanup_loop; } else printf("."); fflush(stdout); } cleanup_loop: printf("\nAbout to empty the engine-type list\n"); while ((ptr = ENGINE_get_first()) != NULL) { if (!ENGINE_remove(ptr)) { printf("\nRemove failed!\n"); goto end; } ENGINE_free(ptr); printf("."); fflush(stdout); } for (loop = 0; loop < 512; loop++) { OPENSSL_free((void *)ENGINE_get_id(block[loop])); OPENSSL_free((void *)ENGINE_get_name(block[loop])); } printf("\nTests completed happily\n"); to_return = 0; end: if (to_return) ERR_print_errors_fp(stderr); ENGINE_free(new_h1); ENGINE_free(new_h2); ENGINE_free(new_h3); ENGINE_free(new_h4); for (loop = 0; loop < 512; loop++) ENGINE_free(block[loop]); #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) to_return = 1; #endif return to_return; }
int neverbleed_init(neverbleed_t *nb, char *errbuf) { int pipe_fds[2] = {-1, -1}, listen_fd = -1; char *tempdir = NULL; const RSA_METHOD *default_method = RSA_PKCS1_SSLeay(); rsa_method.rsa_pub_enc = default_method->rsa_pub_enc; rsa_method.rsa_pub_dec = default_method->rsa_pub_dec; rsa_method.rsa_verify = default_method->rsa_verify; /* setup the daemon */ if (pipe(pipe_fds) != 0) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "pipe(2) failed:%s", strerror(errno)); goto Fail; } fcntl(pipe_fds[1], F_SETFD, O_CLOEXEC); if ((tempdir = strdup("/tmp/openssl-privsep.XXXXXX")) == NULL) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "no memory"); goto Fail; } if (mkdtemp(tempdir) == NULL) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to create temporary directory under /tmp:%s", strerror(errno)); goto Fail; } memset(&nb->sun_, 0, sizeof(nb->sun_)); nb->sun_.sun_family = AF_UNIX; snprintf(nb->sun_.sun_path, sizeof(nb->sun_.sun_path), "%s/_", tempdir); RAND_bytes(nb->auth_token, sizeof(nb->auth_token)); if ((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "socket(2) failed:%s", strerror(errno)); goto Fail; } if (bind(listen_fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to bind to %s:%s", nb->sun_.sun_path, strerror(errno)); goto Fail; } if (listen(listen_fd, SOMAXCONN) != 0) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "listen(2) failed:%s", strerror(errno)); goto Fail; } switch (fork()) { case -1: snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "fork(2) failed:%s", strerror(errno)); goto Fail; case 0: close(pipe_fds[1]); #ifdef __linux__ prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); #endif memcpy(daemon_auth_token, nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE); daemon_main(listen_fd, pipe_fds[0], tempdir); break; default: break; } close(listen_fd); listen_fd = -1; close(pipe_fds[0]); pipe_fds[0] = -1; /* setup engine */ if ((nb->engine = ENGINE_new()) == NULL || !ENGINE_set_id(nb->engine, "neverbleed") || !ENGINE_set_name(nb->engine, "privilege separation software engine") || !ENGINE_set_RSA(nb->engine, &rsa_method)) { snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to initialize the OpenSSL engine"); goto Fail; } ENGINE_add(nb->engine); /* setup thread key */ pthread_key_create(&nb->thread_key, dispose_thread_data); free(tempdir); return 0; Fail: if (pipe_fds[0] != -1) close(pipe_fds[0]); if (pipe_fds[1] != -1) close(pipe_fds[1]); if (tempdir != NULL) { unlink_dir(tempdir); free(tempdir); } if (listen_fd != -1) close(listen_fd); if (nb->engine != NULL) { ENGINE_free(nb->engine); nb->engine = NULL; } return -1; }
int main(int argc, char *argv[]) { ENGINE *block[512]; char buf[256]; const char *id, *name; ENGINE *ptr; int loop; int to_return = 1; ENGINE *new_h1 = NULL; ENGINE *new_h2 = NULL; ENGINE *new_h3 = NULL; ENGINE *new_h4 = NULL; /* enable memory leak checking unless explicitly disabled */ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { /* OPENSSL_DEBUG_MEMORY=off */ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); ERR_load_crypto_strings(); memset(block, 0, 512 * sizeof(ENGINE *)); if(((new_h1 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h1, "test_id0") || !ENGINE_set_name(new_h1, "First test item") || ((new_h2 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h2, "test_id1") || !ENGINE_set_name(new_h2, "Second test item") || ((new_h3 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h3, "test_id2") || !ENGINE_set_name(new_h3, "Third test item") || ((new_h4 = ENGINE_new()) == NULL) || !ENGINE_set_id(new_h4, "test_id3") || !ENGINE_set_name(new_h4, "Fourth test item")) { printf("Couldn't set up test ENGINE structures\n"); goto end; } printf("\nenginetest beginning\n\n"); display_engine_list(); if(!ENGINE_add(new_h1)) { printf("Add failed!\n"); goto end; } display_engine_list(); ptr = ENGINE_get_first(); if(!ENGINE_remove(ptr)) { printf("Remove failed!\n"); goto end; } if (ptr) ENGINE_free(ptr); display_engine_list(); if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) { printf("Add failed!\n"); goto end; } display_engine_list(); if(!ENGINE_remove(new_h2)) { printf("Remove failed!\n"); goto end; } display_engine_list(); if(!ENGINE_add(new_h4)) { printf("Add failed!\n"); goto end; } display_engine_list(); if(ENGINE_add(new_h3)) { printf("Add *should* have failed but didn't!\n"); goto end; } else printf("Add that should fail did.\n"); ERR_clear_error(); if(ENGINE_remove(new_h2)) { printf("Remove *should* have failed but didn't!\n"); goto end; } else printf("Remove that should fail did.\n"); ERR_clear_error(); if(!ENGINE_remove(new_h3)) { printf("Remove failed!\n"); goto end; } display_engine_list(); if(!ENGINE_remove(new_h4)) { printf("Remove failed!\n"); goto end; } display_engine_list(); /* Depending on whether there's any hardware support compiled * in, this remove may be destined to fail. */ ptr = ENGINE_get_first(); if(ptr) if(!ENGINE_remove(ptr)) printf("Remove failed!i - probably no hardware " "support present.\n"); if (ptr) ENGINE_free(ptr); display_engine_list(); if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) { printf("Couldn't add and remove to an empty list!\n"); goto end; } else printf("Successfully added and removed to an empty list!\n"); printf("About to beef up the engine-type list\n"); for(loop = 0; loop < 512; loop++) { sprintf(buf, "id%i", loop); id = BUF_strdup(buf); sprintf(buf, "Fake engine type %i", loop); name = BUF_strdup(buf); if(((block[loop] = ENGINE_new()) == NULL) || !ENGINE_set_id(block[loop], id) || !ENGINE_set_name(block[loop], name)) { printf("Couldn't create block of ENGINE structures.\n" "I'll probably also core-dump now, damn.\n"); goto end; } } for(loop = 0; loop < 512; loop++) { if(!ENGINE_add(block[loop])) { printf("\nAdding stopped at %i, (%s,%s)\n", loop, ENGINE_get_id(block[loop]), ENGINE_get_name(block[loop])); goto cleanup_loop; } else printf("."); fflush(stdout); } cleanup_loop: printf("\nAbout to empty the engine-type list\n"); while((ptr = ENGINE_get_first()) != NULL) { if(!ENGINE_remove(ptr)) { printf("\nRemove failed!\n"); goto end; } ENGINE_free(ptr); printf("."); fflush(stdout); } for(loop = 0; loop < 512; loop++) { OPENSSL_free((void *)ENGINE_get_id(block[loop])); OPENSSL_free((void *)ENGINE_get_name(block[loop])); } printf("\nTests completed happily\n"); to_return = 0; end: if(to_return) ERR_print_errors_fp(stderr); if(new_h1) ENGINE_free(new_h1); if(new_h2) ENGINE_free(new_h2); if(new_h3) ENGINE_free(new_h3); if(new_h4) ENGINE_free(new_h4); for(loop = 0; loop < 512; loop++) if(block[loop]) ENGINE_free(block[loop]); ENGINE_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); ERR_remove_thread_state(NULL); CRYPTO_mem_leaks_fp(stderr); return to_return; }