Blame src/p11_load.c

Packit Service 2ea82d
/* libp11, a simple layer on to of PKCS#11 API
Packit Service 2ea82d
 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
Packit Service 2ea82d
 *
Packit Service 2ea82d
 *  This library is free software; you can redistribute it and/or
Packit Service 2ea82d
 *  modify it under the terms of the GNU Lesser General Public
Packit Service 2ea82d
 *  License as published by the Free Software Foundation; either
Packit Service 2ea82d
 *  version 2.1 of the License, or (at your option) any later version.
Packit Service 2ea82d
 *
Packit Service 2ea82d
 *  This library is distributed in the hope that it will be useful,
Packit Service 2ea82d
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 2ea82d
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 2ea82d
 *  Lesser General Public License for more details.
Packit Service 2ea82d
 *
Packit Service 2ea82d
 *  You should have received a copy of the GNU Lesser General Public
Packit Service 2ea82d
 *  License along with this library; if not, write to the Free Software
Packit Service 2ea82d
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
Packit Service 2ea82d
 */
Packit Service 2ea82d
Packit Service 2ea82d
#include "libp11-int.h"
Packit Service 2ea82d
#include <string.h>
Packit Service 2ea82d
Packit Service 2ea82d
/*
Packit Service 2ea82d
 * Create a new context
Packit Service 2ea82d
 */
Packit Service 2ea82d
PKCS11_CTX *pkcs11_CTX_new(void)
Packit Service 2ea82d
{
Packit Service 2ea82d
	PKCS11_CTX_private *cpriv = NULL;
Packit Service 2ea82d
	PKCS11_CTX *ctx = NULL;
Packit Service 2ea82d
Packit Service 2ea82d
	/* Load error strings */
Packit Service 2ea82d
	ERR_load_PKCS11_strings();
Packit Service 2ea82d
Packit Service 2ea82d
	cpriv = OPENSSL_malloc(sizeof(PKCS11_CTX_private));
Packit Service 2ea82d
	if (cpriv == NULL)
Packit Service 2ea82d
		goto fail;
Packit Service 2ea82d
	memset(cpriv, 0, sizeof(PKCS11_CTX_private));
Packit Service 2ea82d
	ctx = OPENSSL_malloc(sizeof(PKCS11_CTX));
Packit Service 2ea82d
	if (ctx == NULL)
Packit Service 2ea82d
		goto fail;
Packit Service 2ea82d
	memset(ctx, 0, sizeof(PKCS11_CTX));
Packit Service 2ea82d
	ctx->_private = cpriv;
Packit Service 2ea82d
	cpriv->forkid = get_forkid();
Packit Service 2ea82d
	cpriv->rwlock = CRYPTO_THREAD_lock_new();
Packit Service 2ea82d
	cpriv->sign_initialized = 0;
Packit Service 2ea82d
	cpriv->decrypt_initialized = 0;
Packit Service 2ea82d
Packit Service 2ea82d
	return ctx;
Packit Service 2ea82d
fail:
Packit Service 2ea82d
	OPENSSL_free(cpriv);
Packit Service 2ea82d
	OPENSSL_free(ctx);
Packit Service 2ea82d
	return NULL;
Packit Service 2ea82d
}
Packit Service 2ea82d
Packit Service 2ea82d
/*
Packit Service 2ea82d
 * Set private init args for module
Packit Service 2ea82d
 */
Packit Service 2ea82d
void pkcs11_CTX_init_args(PKCS11_CTX *ctx, const char *init_args)
Packit Service 2ea82d
{
Packit Service 2ea82d
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
Packit Service 2ea82d
	/* Free previously duplicated string */
Packit Service 2ea82d
	if (cpriv->init_args) {
Packit Service 2ea82d
		OPENSSL_free(cpriv->init_args);
Packit Service 2ea82d
	}
Packit Service 2ea82d
	cpriv->init_args = init_args ? OPENSSL_strdup(init_args) : NULL;
Packit Service 2ea82d
}
Packit Service 2ea82d
Packit Service 2ea82d
/*
Packit Service 2ea82d
 * Load the shared library, and initialize it.
Packit Service 2ea82d
 */
Packit Service 2ea82d
int pkcs11_CTX_load(PKCS11_CTX *ctx, const char *name)
Packit Service 2ea82d
{
Packit Service 2ea82d
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
Packit Service 2ea82d
	CK_C_INITIALIZE_ARGS args;
Packit Service 2ea82d
	CK_INFO ck_info;
Packit Service 2ea82d
	int rv;
Packit Service 2ea82d
Packit Service 2ea82d
	cpriv->handle = C_LoadModule(name, &cpriv->method);
Packit Service 2ea82d
	if (cpriv->handle == NULL) {
Packit Service 2ea82d
		P11err(P11_F_PKCS11_CTX_LOAD, P11_R_LOAD_MODULE_ERROR);
Packit Service 2ea82d
		return -1;
Packit Service 2ea82d
	}
Packit Service 2ea82d
Packit Service 2ea82d
	/* Tell the PKCS11 to initialize itself */
Packit Service 2ea82d
	memset(&args, 0, sizeof(args));
Packit Service 2ea82d
	/* Unconditionally say using OS locking primitives is OK */
Packit Service 2ea82d
	args.flags |= CKF_OS_LOCKING_OK;
Packit Service 2ea82d
	args.pReserved = cpriv->init_args;
Packit Service 2ea82d
	rv = cpriv->method->C_Initialize(&args);
Packit Service 2ea82d
	if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
Packit Service 2ea82d
		C_UnloadModule(cpriv->handle);
Packit Service 2ea82d
		cpriv->handle = NULL;
Packit Service 2ea82d
		CKRerr(P11_F_PKCS11_CTX_LOAD, rv);
Packit Service 2ea82d
		return -1;
Packit Service 2ea82d
	}
Packit Service 2ea82d
Packit Service 2ea82d
	/* Get info on the library */
Packit Service 2ea82d
	rv = cpriv->method->C_GetInfo(&ck_info);
Packit Service 2ea82d
	if (rv) {
Packit Service 2ea82d
		cpriv->method->C_Finalize(NULL);
Packit Service 2ea82d
		C_UnloadModule(cpriv->handle);
Packit Service 2ea82d
		cpriv->handle = NULL;
Packit Service 2ea82d
		CKRerr(P11_F_PKCS11_CTX_LOAD, rv);
Packit Service 2ea82d
		return -1;
Packit Service 2ea82d
	}
Packit Service 2ea82d
Packit Service 2ea82d
	ctx->manufacturer = PKCS11_DUP(ck_info.manufacturerID);
Packit Service 2ea82d
	ctx->description = PKCS11_DUP(ck_info.libraryDescription);
Packit Service 2ea82d
Packit Service 2ea82d
	return 0;
Packit Service 2ea82d
}
Packit Service 2ea82d
Packit Service 2ea82d
/*
Packit Service 2ea82d
 * Reinitialize (e.g., after a fork).
Packit Service 2ea82d
 */
Packit Service 2ea82d
int pkcs11_CTX_reload(PKCS11_CTX *ctx)
Packit Service 2ea82d
{
Packit Service 2ea82d
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
Packit Service 2ea82d
	CK_C_INITIALIZE_ARGS _args;
Packit Service 2ea82d
	CK_C_INITIALIZE_ARGS *args = NULL;
Packit Service 2ea82d
	int rv;
Packit Service 2ea82d
Packit Service 2ea82d
	if (cpriv->method == NULL) /* Module not loaded */
Packit Service 2ea82d
		return 0;
Packit Service 2ea82d
Packit Service 2ea82d
	/* Tell the PKCS11 to initialize itself */
Packit Service 2ea82d
	if (cpriv->init_args != NULL) {
Packit Service 2ea82d
		memset(&_args, 0, sizeof(_args));
Packit Service 2ea82d
		args = &_args;
Packit Service 2ea82d
		args->pReserved = cpriv->init_args;
Packit Service 2ea82d
	}
Packit Service 2ea82d
	rv = cpriv->method->C_Initialize(args);
Packit Service 2ea82d
	if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
Packit Service 2ea82d
		CKRerr(P11_F_PKCS11_CTX_RELOAD, rv);
Packit Service 2ea82d
		return -1;
Packit Service 2ea82d
	}
Packit Service 2ea82d
Packit Service 2ea82d
	return 0;
Packit Service 2ea82d
}
Packit Service 2ea82d
Packit Service 2ea82d
/*
Packit Service 2ea82d
 * Unload the shared library
Packit Service 2ea82d
 */
Packit Service 2ea82d
void pkcs11_CTX_unload(PKCS11_CTX *ctx)
Packit Service 2ea82d
{
Packit Service 2ea82d
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
Packit Service 2ea82d
Packit Service 2ea82d
	/* Tell the PKCS11 library to shut down */
Packit Service 2ea82d
	if (cpriv->forkid == get_forkid())
Packit Service 2ea82d
		cpriv->method->C_Finalize(NULL);
Packit Service 2ea82d
Packit Service 2ea82d
	/* Unload the module */
Packit Service 2ea82d
	C_UnloadModule(cpriv->handle);
Packit Service 2ea82d
	cpriv->handle = NULL;
Packit Service 2ea82d
}
Packit Service 2ea82d
Packit Service 2ea82d
/*
Packit Service 2ea82d
 * Free a context
Packit Service 2ea82d
 */
Packit Service 2ea82d
void pkcs11_CTX_free(PKCS11_CTX *ctx)
Packit Service 2ea82d
{
Packit Service 2ea82d
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
Packit Service 2ea82d
Packit Service 2ea82d
	/* TODO: Move the global methods and ex_data indexes into
Packit Service 2ea82d
	 * the ctx structure, so they can be safely deallocated here:
Packit Service 2ea82d
	PKCS11_rsa_method_free(ctx);
Packit Service 2ea82d
	PKCS11_ecdsa_method_free(ctx);
Packit Service 2ea82d
	*/
Packit Service 2ea82d
	if (cpriv->init_args) {
Packit Service 2ea82d
		OPENSSL_free(cpriv->init_args);
Packit Service 2ea82d
	}
Packit Service 2ea82d
	if (cpriv->handle) {
Packit Service 2ea82d
		OPENSSL_free(cpriv->handle);
Packit Service 2ea82d
	}
Packit Service 2ea82d
	CRYPTO_THREAD_lock_free(cpriv->rwlock);
Packit Service 2ea82d
	OPENSSL_free(ctx->manufacturer);
Packit Service 2ea82d
	OPENSSL_free(ctx->description);
Packit Service 2ea82d
	OPENSSL_free(ctx->_private);
Packit Service 2ea82d
	OPENSSL_free(ctx);
Packit Service 2ea82d
}
Packit Service 2ea82d
Packit Service 2ea82d
/* vim: set noexpandtab: */