<commit_before>/*
 * Copyright (C) 2008 <NAME>
 * Copyright (C) 2011 Collabora Ltd.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above
 *       copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the
 *       above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or
 *       other materials provided with the distribution.
 *     * The names of contributors to this software may not be
 *       used to endorse or promote products derived from this
 *       software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include "config.h"

#include "compat.h"
#define P11_DEBUG_FLAG P11_DEBUG_PROXY
#define CRYPTOKI_EXPORTS

#include "debug.h"
#include "dict.h"
#include "library.h"
#include "message.h"
#include "modules.h"
#include "pkcs11.h"
#include "pkcs11x.h"
#include "p11-kit.h"
#include "private.h"
#include "proxy.h"
#include "virtual.h"

#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Start wrap slots slightly higher for testing */
#define MAPPING_OFFSET 0x10
#define FIRST_HANDLE   0x10

typedef struct _Mapping {
	CK_SLOT_ID wrap_slot;
	CK_SLOT_ID real_slot;
	CK_FUNCTION_LIST_PTR funcs;
} Mapping;

typedef struct _Session {
	CK_SESSION_HANDLE wrap_session;
	CK_SESSION_HANDLE real_session;
	CK_SLOT_ID wrap_slot;
} Session;

typedef struct {
	int refs;
	Mapping *mappings;
	unsigned int n_mappings;
	p11_dict *sessions;
	CK_FUNCTION_LIST **modules;
} Proxy;

typedef struct _State {
	p11_virtual virt;
	struct _State *next;
	CK_FUNCTION_LIST *wrapped;
	CK_ULONG last_handle;
	Proxy *px;
} State;

static State *all_instances = NULL;
static State global = { { { { -1, -1 }, NULL, }, }, NULL, NULL, FIRST_HANDLE, NULL };

#define MANUFACTURER_ID         "PKCS#11 Kit                     "
#define LIBRARY_DESCRIPTION     "PKCS#11 Kit Proxy Module        "
#define LIBRARY_VERSION_MAJOR   1
#define LIBRARY_VERSION_MINOR   1

/* -----------------------------------------------------------------------------
 * PKCS#11 PROXY MODULE
 */

static CK_RV
map_slot_unlocked (Proxy *px,
                   CK_SLOT_ID slot,
                   Mapping *mapping)
{
	assert (px != NULL);
	assert (mapping != NULL);

	if (slot < MAPPING_OFFSET)
		return CKR_SLOT_ID_INVALID;
	slot -= MAPPING_OFFSET;

	if (slot > px->n_mappings) {
		return CKR_SLOT_ID_INVALID;
	} else {
		assert (px->mappings);
		memcpy (mapping, &px->mappings[slot], sizeof (Mapping));
		return CKR_OK;
	}
}

static CK_RV
map_slot_to_real (Proxy *px,
                  CK_SLOT_ID_PTR slot,
                  Mapping *mapping)
{
	CK_RV rv;

	assert (px != NULL);
	assert (mapping != NULL);

	p11_lock ();

		if (!px)
			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
		else
			rv = map_slot_unlocked (px, *slot, mapping);
		if (rv == CKR_OK)
			*slot = mapping->real_slot;

	p11_unlock ();

	return rv;
}

static CK_RV
map_session_to_real (Proxy *px,
                     CK_SESSION_HANDLE_PTR handle,
                     Mapping *mapping,
                     Session *session)
{
	CK_RV rv = CKR_OK;
	Session *sess;

	assert (px != NULL);
	assert (handle != NULL);
	assert (mapping != NULL);

	p11_lock ();

		if (!px) {
			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
		} else {
			assert (px->sessions);
			sess = p11_dict_get (px->sessions, handle);
			if (sess != NULL) {
				*handle = sess->real_session;
				rv = map_slot_unlocked (px, sess->wrap_slot, mapping);
				if (session != NULL)
					memcpy (session, sess, sizeof (Session));
			} else {
				rv = CKR_SESSION_HANDLE_INVALID;
			}
		}
<commit_msg>proxy: Remove assertions when module is not initialized<commit_after>/*
 * Copyright (C) 2008 <NAME>
 * Copyright (C) 2011 Collabora Ltd.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above
 *       copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the
 *       above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or
 *       other materials provided with the distribution.
 *     * The names of contributors to this software may not be
 *       used to endorse or promote products derived from this
 *       software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * Author: <NAME> <<EMAIL>>
 */

#include "config.h"

#include "compat.h"
#define P11_DEBUG_FLAG P11_DEBUG_PROXY
#define CRYPTOKI_EXPORTS

#include "debug.h"
#include "dict.h"
#include "library.h"
#include "message.h"
#include "modules.h"
#include "pkcs11.h"
#include "pkcs11x.h"
#include "p11-kit.h"
#include "private.h"
#include "proxy.h"
#include "virtual.h"

#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Start wrap slots slightly higher for testing */
#define MAPPING_OFFSET 0x10
#define FIRST_HANDLE   0x10

typedef struct _Mapping {
	CK_SLOT_ID wrap_slot;
	CK_SLOT_ID real_slot;
	CK_FUNCTION_LIST_PTR funcs;
} Mapping;

typedef struct _Session {
	CK_SESSION_HANDLE wrap_session;
	CK_SESSION_HANDLE real_session;
	CK_SLOT_ID wrap_slot;
} Session;

typedef struct {
	int refs;
	Mapping *mappings;
	unsigned int n_mappings;
	p11_dict *sessions;
	CK_FUNCTION_LIST **modules;
} Proxy;

typedef struct _State {
	p11_virtual virt;
	struct _State *next;
	CK_FUNCTION_LIST *wrapped;
	CK_ULONG last_handle;
	Proxy *px;
} State;

static State *all_instances = NULL;
static State global = { { { { -1, -1 }, NULL, }, }, NULL, NULL, FIRST_HANDLE, NULL };

#define MANUFACTURER_ID         "PKCS#11 Kit                     "
#define LIBRARY_DESCRIPTION     "PKCS#11 Kit Proxy Module        "
#define LIBRARY_VERSION_MAJOR   1
#define LIBRARY_VERSION_MINOR   1

/* -----------------------------------------------------------------------------
 * PKCS#11 PROXY MODULE
 */

static CK_RV
map_slot_unlocked (Proxy *px,
                   CK_SLOT_ID slot,
                   Mapping *mapping)
{
	assert (px != NULL);
	assert (mapping != NULL);

	if (slot < MAPPING_OFFSET)
		return CKR_SLOT_ID_INVALID;
	slot -= MAPPING_OFFSET;

	if (slot > px->n_mappings) {
		return CKR_SLOT_ID_INVALID;
	} else {
		assert (px->mappings);
		memcpy (mapping, &px->mappings[slot], sizeof (Mapping));
		return CKR_OK;
	}
}

static CK_RV
map_slot_to_real (Proxy *px,
                  CK_SLOT_ID_PTR slot,
                  Mapping *mapping)
{
	CK_RV rv;

	assert (mapping != NULL);

	p11_lock ();

		if (!px)
			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
		else
			rv = map_slot_unlocked (px, *slot, mapping);
		if (rv == CKR_OK)
			*slot = mapping->real_slot;

	p11_unlock ();

	return rv;
}

static CK_RV
map_session_to_real (Proxy *px,
                     CK_SESSION_HANDLE_PTR handle,
                     Mapping *mapping,
                     Session *session)
{
	CK_RV rv = CKR_OK;
	Session *sess;

	assert (handle != NULL);
	assert (mapping != NULL);

	p11_lock ();

		if (!px) {
			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
		} else {
			assert (px->sessions);
			sess = p11_dict_get (px->sessions, handle);
			if (sess != NULL) {
				*handle = sess->real_session;
				rv = map_slot_unlocked (px, sess->wrap_slot, mapping);
				if (session != NULL)
					memcpy (session, sess, sizeof (Session));
			} else {
				rv = CKR_SESSION_HANDLE_INVALID;
			}
		}

{'fraction_non_alphanumeric': 0.10994263862332695, 'fraction_numerical': 0.009772678988740175, 'mean_word_length': 3.195632798573975, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1405178', 'n_tokens_mistral': 3330, 'n_tokens_neox': 2968, 'n_words': 989}