Пример #1
0
/* No padding or other stuff needed.  We can call PKCS11 from here */
static int pkcs11_ecdsa_sign(const unsigned char *msg, unsigned int msg_len,
		unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *key)
{
	int rv;
	PKCS11_SLOT *slot = KEY2SLOT(key);
	PKCS11_CTX *ctx = KEY2CTX(key);
	PKCS11_KEY_private *kpriv = PRIVKEY(key);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	CK_MECHANISM mechanism;
	CK_ULONG ck_sigsize;

	ck_sigsize = *siglen;

	memset(&mechanism, 0, sizeof(mechanism));
	mechanism.mechanism = CKM_ECDSA;

	CRYPTO_THREAD_write_lock(PRIVCTX(ctx)->rwlock);
	rv = CRYPTOKI_call(ctx,
		C_SignInit(spriv->session, &mechanism, kpriv->object));
	if (!rv && kpriv->always_authenticate == CK_TRUE)
		rv = pkcs11_authenticate(key);
	if (!rv)
		rv = CRYPTOKI_call(ctx,
			C_Sign(spriv->session, (CK_BYTE *)msg, msg_len, sigret, &ck_sigsize));
	CRYPTO_THREAD_unlock(PRIVCTX(ctx)->rwlock);

	if (rv) {
		CKRerr(CKR_F_PKCS11_ECDSA_SIGN, rv);
		return -1;
	}
	*siglen = ck_sigsize;

	return ck_sigsize;
}
Пример #2
0
/*
 * Return keys of a given type (public or private)
 * Use the cached values if available
 */
int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type,
		PKCS11_KEY ** keyp, unsigned int *countp)
{
	PKCS11_SLOT *slot = TOKEN2SLOT(token);
	PKCS11_CTX *ctx = TOKEN2CTX(token);
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
	int rv;

	if (keys->num < 0) { /* No cache was built for the specified type */
		/* Make sure we have a session */
		if (!spriv->haveSession && PKCS11_open_session(slot, 0))
			return -1;
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
		rv = pkcs11_find_keys(token, type);
		CRYPTO_THREAD_unlock(cpriv->rwlock);
		if (rv < 0) {
			pkcs11_destroy_keys(token, type);
			return -1;
		}
	}
	if (keyp)
		*keyp = keys->keys;
	if (countp)
		*countp = keys->num;
	return 0;
}
Пример #3
0
/*
 * Helper functions
 */
static int pkcs11_init_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot, CK_SLOT_ID id)
{
	PKCS11_SLOT_private *priv;
	CK_SLOT_INFO info;
	int rv;

	rv = CRYPTOKI_call(ctx, C_GetSlotInfo(id, &info));
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);

	priv = OPENSSL_malloc(sizeof(PKCS11_SLOT_private));
	if (priv == NULL)
		return -1;
	memset(priv, 0, sizeof(PKCS11_SLOT_private));

	priv->parent = ctx;
	priv->id = id;
	priv->forkid = PRIVCTX(ctx)->forkid;
	priv->prev_rw = 0;
	priv->prev_pin = NULL;
	priv->prev_so = 0;
	priv->lockid = CRYPTO_get_new_dynlockid();

	slot->description = PKCS11_DUP(info.slotDescription);
	slot->manufacturer = PKCS11_DUP(info.manufacturerID);
	slot->removable = (info.flags & CKF_REMOVABLE_DEVICE) ? 1 : 0;
	slot->_private = priv;

	if ((info.flags & CKF_TOKEN_PRESENT) && pkcs11_check_token(ctx, slot))
		return -1;

	return 0;
}
Пример #4
0
/*
 * Enumerate all certs on the card
 */
int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
		PKCS11_CERT **certp, unsigned int *countp)
{
	PKCS11_SLOT *slot = TOKEN2SLOT(token);
	PKCS11_CTX *ctx = SLOT2CTX(slot);
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	int rv;

	if (tpriv->ncerts < 0) {
		/* Make sure we have a session */
		if (!spriv->haveSession && PKCS11_open_session(slot, 0))
			return -1;
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
		rv = pkcs11_find_certs(token);
		CRYPTO_THREAD_unlock(cpriv->rwlock);
		if (rv < 0) {
			pkcs11_destroy_certs(token);
			return -1;
		}
	}
	if (certp)
		*certp = tpriv->certs;
	if (countp)
		*countp = tpriv->ncerts;
	return 0;
}
Пример #5
0
/*
 * Reinitialize (e.g., after a fork).
 */
int pkcs11_CTX_reload(PKCS11_CTX * ctx)
{
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	CK_C_INITIALIZE_ARGS _args;
	CK_C_INITIALIZE_ARGS *args = NULL;
	int rv;

	if (cpriv->method == NULL) /* Module not loaded */
		return 0;

	/* Tell the PKCS11 to initialize itself */
	if (cpriv->init_args != NULL) {
		memset(&_args, 0, sizeof(_args));
		args = &_args;
		args->pReserved = cpriv->init_args;
	}
	rv = cpriv->method->C_Initialize(args);
	if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
		PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, rv);
		return -1;
	}

	/* Reinitialize the PKCS11 internal slot table */
	return pkcs11_enumerate_slots(ctx, NULL, NULL);
}
Пример #6
0
/*
 * Load the shared library, and initialize it.
 */
int PKCS11_CTX_load(PKCS11_CTX * ctx, const char *name)
{
    PKCS11_CTX_private *priv = PRIVCTX(ctx);
    CK_C_INITIALIZE_ARGS args;
    CK_INFO ck_info;
    int rv;

    if (priv->libinfo != NULL) {
        PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_MODULE_LOADED_ERROR);
        return -1;
    }
    handle = C_LoadModule(name, &priv->method);
    if (!handle) {
        PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_LOAD_MODULE_ERROR);
        return -1;
    }

    /* Tell the PKCS11 to initialize itself */
    memset(&args, 0, sizeof(args));
    args.pReserved = priv->init_args;
    rv = priv->method->C_Initialize(&args);
    if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
        PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, rv);
        return -1;
    }

    /* Get info on the library */
    rv = priv->method->C_GetInfo(&ck_info);
    CRYPTOKI_checkerr(PKCS11_F_PKCS11_CTX_LOAD, rv);

    ctx->manufacturer = PKCS11_DUP(ck_info.manufacturerID);
    ctx->description = PKCS11_DUP(ck_info.libraryDescription);

    return 0;
}
Пример #7
0
/*
 * Set private init args for module
 */
void pkcs11_CTX_init_args(PKCS11_CTX * ctx, const char *init_args)
{
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	/* Free previously duplicated string */
	if (cpriv->init_args) {
		OPENSSL_free(cpriv->init_args);
	}
	cpriv->init_args = init_args ? OPENSSL_strdup(init_args) : NULL;
}
Пример #8
0
/*
 * Unload the shared library
 */
void PKCS11_CTX_unload(PKCS11_CTX * ctx)
{
    PKCS11_CTX_private *priv;
    priv = PRIVCTX(ctx);

    /* Tell the PKCS11 library to shut down */
    priv->method->C_Finalize(NULL);

    /* Unload the module */
    C_UnloadModule(handle);
}
Пример #9
0
/*
 * Unload the shared library
 */
void pkcs11_CTX_unload(PKCS11_CTX * ctx)
{
	PKCS11_CTX_private *cpriv;
	cpriv = PRIVCTX(ctx);

	/* Tell the PKCS11 library to shut down */
	if (cpriv->forkid == _P11_get_forkid())
		cpriv->method->C_Finalize(NULL);

	/* Unload the module */
	C_UnloadModule(cpriv->handle);
}
Пример #10
0
/*
 * Free a context
 */
void pkcs11_CTX_free(PKCS11_CTX * ctx)
{
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);

	/* TODO: Move the global methods and ex_data indexes into
	 * the ctx structure, so they can be safely deallocated here:
	PKCS11_rsa_method_free(ctx);
	PKCS11_ecdsa_method_free(ctx);
	*/
	if (cpriv->init_args) {
		OPENSSL_free(cpriv->init_args);
	}
	CRYPTO_THREAD_lock_free(cpriv->rwlock);
	OPENSSL_free(ctx->manufacturer);
	OPENSSL_free(ctx->description);
	OPENSSL_free(ctx->_private);
	OPENSSL_free(ctx);
}
Пример #11
0
int
pkcs11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT ** slotp, unsigned int *countp)
{
	PKCS11_CTX_private *priv;
	CK_SLOT_ID *slotid;
	CK_ULONG nslots, n;
	PKCS11_SLOT *slots;
	int rv;

	priv = PRIVCTX(ctx);

	rv = priv->method->C_GetSlotList(FALSE, NULL_PTR, &nslots);
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);

	slotid = OPENSSL_malloc(nslots * sizeof(CK_SLOT_ID));
	if (slotid == NULL)
		return -1;

	rv = priv->method->C_GetSlotList(FALSE, slotid, &nslots);
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);

	slots = OPENSSL_malloc(nslots * sizeof(PKCS11_SLOT));
	if (slots == NULL)
		return -1;
	memset(slots, 0, nslots * sizeof(PKCS11_SLOT));
	for (n = 0; n < nslots; n++) {
		if (pkcs11_init_slot(ctx, &slots[n], slotid[n])) {
			while (n--)
				pkcs11_release_slot(ctx, slots + n);
			OPENSSL_free(slotid);
			OPENSSL_free(slots);
			return -1;
		}
	}

	if (slotp)
		*slotp = slots;
	else
		OPENSSL_free(slots);
	if (countp)
		*countp = nslots;
	OPENSSL_free(slotid);
	return 0;
}
Пример #12
0
/*
 * Load the shared library, and initialize it.
 */
int pkcs11_CTX_load(PKCS11_CTX * ctx, const char *name)
{
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	CK_C_INITIALIZE_ARGS _args;
	CK_C_INITIALIZE_ARGS *args = NULL;
	CK_INFO ck_info;
	int rv;

	cpriv->handle = C_LoadModule(name, &cpriv->method);
	if (cpriv->handle == NULL) {
		PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_LOAD_MODULE_ERROR);
		return -1;
	}

	/* Tell the PKCS11 to initialize itself */
	if (cpriv->init_args != NULL) {
		memset(&_args, 0, sizeof(_args));
		args = &_args;
		/* Unconditionally say using OS locking primitives is OK */
		args->flags |= CKF_OS_LOCKING_OK;
		args->pReserved = cpriv->init_args;
	}
	rv = cpriv->method->C_Initialize(args);
	if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
		PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, rv);
		return -1;
	}

	/* Get info on the library */
	rv = cpriv->method->C_GetInfo(&ck_info);
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_CTX_LOAD, rv);

	ctx->manufacturer = PKCS11_DUP(ck_info.manufacturerID);
	ctx->description = PKCS11_DUP(ck_info.libraryDescription);

	return 0;
}
Пример #13
0
/*
 * Set private init args for module
 */
void PKCS11_CTX_init_args(PKCS11_CTX * ctx, const char *init_args)
{
    PKCS11_CTX_private *priv = PRIVCTX(ctx);
    priv->init_args = init_args ? strdup(init_args) : NULL;
}