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" );
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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 );
        } );
}
Пример #6
0
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;
}
Пример #7
0
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 */
}
Пример #8
0
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;
}
Пример #9
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;
}