Beispiel #1
0
/*
 * Free a functional reference to a engine type. This version is only used
 * internally.
 */
int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
{
    int to_return = 1;

    /*
     * Reduce the functional reference count here so if it's the terminating
     * case, we can release the lock safely and call the finish() handler
     * without risk of a race. We get a race if we leave the count until
     * after and something else is calling "finish" at the same time -
     * there's a chance that both threads will together take the count from 2
     * to 0 without either calling finish().
     */
    e->funct_ref--;
    engine_ref_debug(e, 1, -1);
    if ((e->funct_ref == 0) && e->finish) {
        if (unlock_for_handlers)
            CRYPTO_THREAD_unlock(global_engine_lock);
        to_return = e->finish(e);
        if (unlock_for_handlers)
            CRYPTO_THREAD_write_lock(global_engine_lock);
        if (!to_return)
            return 0;
    }
    REF_ASSERT_ISNT(e->funct_ref < 0);
    /* Release the structural reference too */
    if (!engine_free_util(e, 0)) {
        ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED);
        return 0;
    }
    return to_return;
}
Beispiel #2
0
/* These static functions starting with a lower case "engine_" always
 * take place when CRYPTO_LOCK_ENGINE has been locked up. */
static int engine_list_add(ENGINE *e)
	{
	int conflict = 0;
	ENGINE *iterator = NULL;

	if(e == NULL)
		{
		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
			ERR_R_PASSED_NULL_PARAMETER);
		return 0;
		}
	iterator = engine_list_head;
	while(iterator && !conflict)
		{
		conflict = (strcmp(iterator->id, e->id) == 0);
		iterator = iterator->next;
		}
	if(conflict)
		{
		ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
			ENGINE_R_CONFLICTING_ENGINE_ID);
		return 0;
		}
	if(engine_list_head == NULL)
		{
		/* We are adding to an empty list. */
		if(engine_list_tail)
			{
			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
				ENGINE_R_INTERNAL_LIST_ERROR);
			return 0;
			}
		engine_list_head = e;
		e->prev = NULL;
		/* The first time the list allocates, we should register the
		 * cleanup. */
		engine_cleanup_add_last(engine_list_cleanup);
		}
	else
		{
		/* We are adding to the tail of an existing list. */
		if((engine_list_tail == NULL) ||
				(engine_list_tail->next != NULL))
			{
			ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
				ENGINE_R_INTERNAL_LIST_ERROR);
			return 0;
			}
		engine_list_tail->next = e;
		e->prev = engine_list_tail;
		}
	/* Having the engine in the list assumes a structural
	 * reference. */
	e->struct_ref++;
	engine_ref_debug(e, 0, 1)
	/* However it came to be, e is the last item in the list. */
	engine_list_tail = e;
	e->next = NULL;
	return 1;
	}
Beispiel #3
0
ENGINE *ENGINE_get_last(void)
{
    ENGINE *ret;

    CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
    ret = engine_list_tail;
    if (ret) {
        ret->struct_ref++;
        engine_ref_debug(ret, 0, 1);
    }
    CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
    return ret;
}
Beispiel #4
0
/*
 * Initialise a engine type for use (or up its functional reference count if
 * it's already in use). This version is only used internally.
 */
int engine_unlocked_init(ENGINE *e)
{
    int to_return = 1;

    if ((e->funct_ref == 0) && e->init)
        /*
         * This is the first functional reference and the engine requires
         * initialisation so we do it now.
         */
        to_return = e->init(e);
    if (to_return) {
        /*
         * OK, we return a functional reference which is also a structural
         * reference.
         */
        e->struct_ref++;
        e->funct_ref++;
        engine_ref_debug(e, 0, 1);
        engine_ref_debug(e, 1, 1);
    }
    return to_return;
}
Beispiel #5
0
ENGINE *ENGINE_new(void)
{
    ENGINE *ret;

    ret = OPENSSL_zalloc(sizeof(*ret));
    if (ret == NULL) {
        ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ret->struct_ref = 1;
    engine_ref_debug(ret, 0, 1);
    CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
    return ret;
}
Beispiel #6
0
ENGINE *ENGINE_new(void)
{
    ENGINE *ret;

    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)
        || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
        ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ret->struct_ref = 1;
    engine_ref_debug(ret, 0, 1);
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data)) {
        OPENSSL_free(ret);
        return NULL;
    }
    return ret;
}
Beispiel #7
0
ENGINE *ENGINE_get_prev(ENGINE *e)
{
    ENGINE *ret = NULL;
    if (e == NULL) {
        ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
    ret = e->prev;
    if (ret) {
        /* Return a valid structural reference to the next ENGINE */
        ret->struct_ref++;
        engine_ref_debug(ret, 0, 1);
    }
    CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
    /* Release the structural reference to the previous ENGINE */
    ENGINE_free(e);
    return ret;
}
Beispiel #8
0
ENGINE *
ENGINE_new(void)
{
	ENGINE *ret;

	if (!OPENSSL_init_crypto(0, NULL))
		return NULL;

	ret = malloc(sizeof(ENGINE));
	if (ret == NULL) {
		ENGINEerror(ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	memset(ret, 0, sizeof(ENGINE));
	ret->struct_ref = 1;
	engine_ref_debug(ret, 0, 1)
	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
	return ret;
}
Beispiel #9
0
ENGINE *ENGINE_by_id(const char *id)
{
    ENGINE *iterator;
    char *load_dir = NULL;
    if (id == NULL) {
        ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }
    CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
    iterator = engine_list_head;
    while (iterator && (strcmp(id, iterator->id) != 0))
        iterator = iterator->next;
    if (iterator != NULL) {
        /*
         * We need to return a structural reference. If this is an ENGINE
         * type that returns copies, make a duplicate - otherwise increment
         * the existing ENGINE's reference count.
         */
        if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) {
            ENGINE *cp = ENGINE_new();
            if (cp == NULL)
                iterator = NULL;
            else {
                engine_cpy(cp, iterator);
                iterator = cp;
            }
        } else {
            iterator->struct_ref++;
            engine_ref_debug(iterator, 0, 1);
        }
    }
    CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
    if (iterator != NULL)
        return iterator;
    /*
     * Prevent infinite recursion if we're looking for the dynamic engine.
     */
    if (strcmp(id, "dynamic")) {
# ifdef OPENSSL_SYS_VMS
        if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
            load_dir = "SSLROOT:[ENGINES]";
# else
        if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
            load_dir = ENGINESDIR;
# endif
        iterator = ENGINE_by_id("dynamic");
        if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
            !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
            !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
                                    load_dir, 0) ||
            !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
            !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
            goto notfound;
        return iterator;
    }
 notfound:
    ENGINE_free(iterator);
    ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE);
    ERR_add_error_data(2, "id=", id);
    return NULL;
    /* EEK! Experimental code ends */
}