DynamicEngine::DynamicEngine( const string & id, const StringList & engineLibPaths ) { DEBUG( "dynamic: ctor: loading and configuring dynamic engine" ); ENGINE_load_dynamic(); ENGINE * dyn = ENGINE_by_id( "dynamic" ); if ( ! dyn ) throw Exception( "dynamic: load failed" ); m_pEngine = dyn; const string engineLibPath( findFirstExisting( engineLibPaths ) ); if ( engineLibPath.empty() ) throw Exception( "dynamic: unable to find engine lib path" ); DEBUG( "dynamic: ctor: so_path=" << QS( engineLibPath ) ); if ( 1 != ENGINE_ctrl_cmd_string( dyn, "SO_PATH", engineLibPath.c_str(), CMD_MANDATORY ) ) throw Exception( "dynamic: setting so_path <= " + QS( engineLibPath ) ); DEBUG( "dynamic: ctor: id=" << QS( id ) ); if ( 1 != ENGINE_ctrl_cmd_string( dyn, "ID", id.c_str(), CMD_MANDATORY ) ) throw Exception( "dynamic: setting id <= " + QS( id ) ); DEBUG( "dynamic: ctor: list_add=1" ); if ( 1 != ENGINE_ctrl_cmd( dyn, "LIST_ADD", 1, NULL, NULL, CMD_MANDATORY ) ) throw Exception( "dynamic: setting list_add <= 1" ); DEBUG( "dynamic: ctor: load=1" ); if ( 1 != ENGINE_ctrl_cmd( dyn, "LOAD", 1, NULL, NULL, CMD_MANDATORY ) ) throw Exception( "dynamic: setting load <= 1" ); DEBUG( "dynamic: ctor: done" ); }
static int openssl_engine_ctrl(lua_State*L){ ENGINE* eng = CHECK_OBJECT(1,ENGINE,"openssl.engine"); if(lua_isnumber(L, 2)){ int cmd = luaL_checkint(L, 2); if(lua_isnoneornil(L, 3)){ int ret = ENGINE_cmd_is_executable(eng, cmd); lua_pushboolean(L, ret); }else{ long i = (long)luaL_checknumber(L, 3); void* p = lua_touserdata(L, 4); int ret = ENGINE_ctrl(eng, cmd, i, p, NULL); lua_pushboolean(L, ret); } }else{ const char* cmd = luaL_checkstring(L, 2); if(lua_isnumber(L, 3)) { long i = (long)luaL_checknumber(L, 3); void* p = lua_touserdata(L, 4); int opt = luaL_optint(L, 5, 0); int ret = ENGINE_ctrl_cmd(eng, cmd, i, p, NULL, opt); lua_pushboolean(L, ret); }else{ const char* arg = luaL_optstring(L, 3, NULL); int opt = luaL_optint(L, 4, 0); int ret = ENGINE_ctrl_cmd_string(eng, cmd, arg, opt); lua_pushboolean(L, ret); } } return 1; }
ENGINE* dnssec_loadengine(const char* engine_name_const) { ENGINE* engine; char* token_pointer = NULL; char* engine_name = strdup(engine_name_const); char* token = strtok_r(engine_name, ENGINE_COMMAND_DELIMITER, &token_pointer); if(token == NULL) { engine = ENGINE_by_id(engine_name); } else { engine = ENGINE_by_id(token); token = strtok_r(NULL, ENGINE_COMMAND_DELIMITER, &token_pointer); } if(engine == NULL) { log_err("ENGINE %s not available", engine_name); DIE(DNSSEC_ERROR_NOENGINE); } while(token != NULL) { char* command_pointer; char* command = strtok_r(token, "=", &command_pointer); if(command == NULL) { log_err("bad command %s", command); DIE(DNSSEC_ERROR_INVALIDENGINE); } char* command_value = strtok_r(NULL, "=", &command_pointer); if(command_value == NULL) { log_err("bad command value %s", command_value); DIE(DNSSEC_ERROR_INVALIDENGINE); } ENGINE_ctrl_cmd((ENGINE*)engine, command, atoi(command_value), NULL, NULL, 0); token = strtok_r(NULL, ENGINE_COMMAND_DELIMITER, &token_pointer); } if(ENGINE_init((ENGINE*)engine) == 0) { log_err("ENGINE_init failed"); ENGINE_free((ENGINE*)engine); /* cfr: http://www.openssl.org/docs/crypto/engine.html */ DIE(DNSSEC_ERROR_INVALIDENGINE); } free(engine_name); return engine; }
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; }
TokenEngine::PKeyPtr TokenEngine::getPrivKey( const string & label ) { const string keyId( "label_" + label ); EVP_PKEY * pkey = ENGINE_load_private_key( m_pEngine, keyId.c_str(), NULL, NULL ); DEBUG( "token: got pkey=" << pkey ); if ( ! pkey ) throw Exception( "token: unable to find private key" " with label=" + QS( label ) ); return PKeyPtr( pkey, [=]( EVP_PKEY * p ){ DEBUG( "gpk: releasing key " << keyId << " @" << p ); ENGINE_ctrl_cmd( m_pEngine, "RELEASE_KEY", 0, static_cast< void * >( p ), NULL, CMD_MANDATORY ); } ); }
static X509 *load_cert_pkcs11(const gchar *url, GError **error) { X509 *res = NULL; unsigned long err; const gchar *data; GError *ierror = NULL; int flags; ENGINE *e; /* this is defined in libp11 src/eng_back.c ctx_ctrl_load_cert() */ struct { const char *url; X509 *cert; } parms; g_return_val_if_fail(url != NULL, NULL); g_return_val_if_fail(error == NULL || *error == NULL, NULL); e = get_pkcs11_engine(&ierror); if (e == NULL) { g_propagate_error(error, ierror); goto out; } parms.url = url; parms.cert = NULL; if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 0) || (parms.cert == NULL)) { err = ERR_get_error_line_data(NULL, NULL, &data, &flags); g_set_error( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_PARSE_ERROR, "failed to load PKCS11 certificate for '%s': %s", url, (flags & ERR_TXT_STRING) ? data : ERR_error_string(err, NULL)); goto out; } res = parms.cert; out: return res; }
NOEXPORT int load_cert_engine(SERVICE_OPTIONS *section) { struct { const char *id; X509 *cert; } parms; s_log(LOG_INFO, "Loading certificate from engine ID: %s", section->cert); parms.id=section->cert; parms.cert=NULL; ENGINE_ctrl_cmd(section->engine, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); if(!parms.cert) { sslerror("ENGINE_ctrl_cmd"); return 1; /* FAILED */ } if(!SSL_CTX_use_certificate(section->ctx, parms.cert)) { sslerror("SSL_CTX_use_certificate"); return 1; /* FAILED */ } s_log(LOG_INFO, "Certificate loaded from engine ID: %s", section->cert); return 0; /* OK */ }
int main(int argc, char **argv) { char *cert_src; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); ERR_clear_error(); kbuild_verbose = atoi(getenv("KBUILD_VERBOSE")?:"0"); key_pass = getenv("KBUILD_SIGN_PIN"); if (argc != 3) format(); cert_src = argv[1]; cert_dst = argv[2]; if (!cert_src[0]) { /* Invoked with no input; create empty file */ FILE *f = fopen(cert_dst, "wb"); ERR(!f, "%s", cert_dst); fclose(f); exit(0); } else if (!strncmp(cert_src, "pkcs11:", 7)) { ENGINE *e; struct { const char *cert_id; X509 *cert; } parms; parms.cert_id = cert_src; parms.cert = NULL; ENGINE_load_builtin_engines(); drain_openssl_errors(); e = ENGINE_by_id("pkcs11"); ERR(!e, "Load PKCS#11 ENGINE"); if (ENGINE_init(e)) drain_openssl_errors(); else ERR(1, "ENGINE_init"); if (key_pass) ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1); ERR(!parms.cert, "Get X.509 from PKCS#11"); write_cert(parms.cert); } else { BIO *b; X509 *x509; b = BIO_new_file(cert_src, "rb"); ERR(!b, "%s", cert_src); while (1) { x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); if (wb && !x509) { unsigned long err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) { ERR_clear_error(); break; } } ERR(!x509, "%s", cert_src); write_cert(x509); } } BIO_free(wb); return 0; }
int main(int argc, char *argv[]) { const EVP_MD *digest_algo = NULL; EVP_PKEY *pkey = NULL; EVP_MD_CTX *md_ctx = NULL; ENGINE *engine = NULL; unsigned char random[RANDOM_SIZE], signature[MAX_SIGSIZE]; unsigned int siglen = MAX_SIGSIZE; int ret, num_processes = 2; pid_t pid; int rv = 1; /* Check arguments */ if (argc < 2) { fprintf(stderr, "Missing required arguments\n"); usage(argv[0]); goto failed; } if (argc > 4) { fprintf(stderr, "Too many arguments\n"); usage(argv[0]); goto failed; } /* Check PKCS#11 URL */ if (strncmp(argv[1], "pkcs11:", 7)) { fprintf(stderr, "fatal: invalid PKCS#11 URL\n"); usage(argv[0]); goto failed; } pid = getpid(); printf("pid %d is the parent\n", pid); /* Load configuration file, if provided */ if (argc >= 3) { ret = CONF_modules_load_file(argv[2], "engines", 0); if (ret <= 0) { fprintf(stderr, "cannot load %s\n", argv[2]); error_queue("CONF_modules_load_file", pid); goto failed; } ENGINE_add_conf_module(); } ENGINE_add_conf_module(); #if OPENSSL_VERSION_NUMBER>=0x10100000 OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ | OPENSSL_INIT_ADD_ALL_DIGESTS \ | OPENSSL_INIT_LOAD_CONFIG, NULL); #else OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); #endif ERR_clear_error(); ENGINE_load_builtin_engines(); /* Get structural reference */ engine = ENGINE_by_id("pkcs11"); if (engine == NULL) { fprintf(stderr, "fatal: engine \"pkcs11\" not available\n"); error_queue("ENGINE_by_id", pid); goto failed; } /* Set the used */ if (argc >= 4) { ENGINE_ctrl_cmd(engine, "MODULE_PATH", 0, argv[3], NULL, 1); } /* Initialize to get the engine functional reference */ if (ENGINE_init(engine)) { pkey = ENGINE_load_private_key(engine, argv[1], 0, 0); if (pkey == NULL) { error_queue("ENGINE_load_private_key", pid); goto failed; } ENGINE_free(engine); engine = NULL; } else { error_queue("ENGINE_init", pid); goto failed; } /* Spawn processes and check child return */ if (spawn_processes(num_processes)) { goto failed; } pid = getpid(); /* Generate random data */ if (!RAND_bytes(random, RANDOM_SIZE)){ error_queue("RAND_bytes", pid); goto failed; } /* Create context to sign the random data */ digest_algo = EVP_get_digestbyname("sha256"); md_ctx = EVP_MD_CTX_create(); if (EVP_DigestInit(md_ctx, digest_algo) <= 0) { error_queue("EVP_DigestInit", pid); goto failed; } EVP_SignInit(md_ctx, digest_algo); if (EVP_SignUpdate(md_ctx, random, RANDOM_SIZE) <= 0) { error_queue("EVP_SignUpdate", pid); goto failed; } if (EVP_SignFinal(md_ctx, signature, &siglen, pkey) <= 0) { error_queue("EVP_SignFinal", pid); goto failed; } EVP_MD_CTX_destroy(md_ctx); printf("pid %d: %u-byte signature created\n", pid, siglen); /* Now verify the result */ md_ctx = EVP_MD_CTX_create(); if (EVP_DigestInit(md_ctx, digest_algo) <= 0) { error_queue("EVP_DigestInit", pid); goto failed; } EVP_VerifyInit(md_ctx, digest_algo); if (EVP_VerifyUpdate(md_ctx, random, RANDOM_SIZE) <= 0) { error_queue("EVP_VerifyUpdate", pid); goto failed; } if (EVP_VerifyFinal(md_ctx, signature, siglen, pkey) <= 0) { error_queue("EVP_VerifyFinal", pid); goto failed; } printf("pid %d: Signature matched\n", pid); rv = 0; failed: if (md_ctx != NULL) EVP_MD_CTX_destroy(md_ctx); if (pkey != NULL) EVP_PKEY_free(pkey); if (engine != NULL) ENGINE_free(engine); return rv; }