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