Beispiel #1
0
static void pkcs11_destroy_token(PKCS11_TOKEN * token)
{
	pkcs11_destroy_keys(token, CKO_PRIVATE_KEY);
	pkcs11_destroy_keys(token, CKO_PUBLIC_KEY);
	pkcs11_destroy_certs(token);

	OPENSSL_free(token->label);
	OPENSSL_free(token->manufacturer);
	OPENSSL_free(token->model);
	OPENSSL_free(token->serialnr);
	OPENSSL_free(token->_private);
	memset(token, 0, sizeof(*token));
}
Beispiel #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;
}
Beispiel #3
0
/*
 * Authenticate with the card. relogin should be set if we automatically
 * relogin after a fork.
 */
static
int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin)
{
	PKCS11_SLOT_private *priv = PRIVSLOT(slot);
	PKCS11_CTX *ctx = priv->parent;
	int rv;

	if (relogin == 0) {
		CHECK_SLOT_FORK(slot);

		/* Calling PKCS11_login invalidates all cached
		 * keys we have */
		if (slot->token) {
			pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY);
			pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY);
		}
		if (priv->loggedIn) {
			/* already logged in, log out first */
			if (PKCS11_logout(slot))
				return -1;
		}
	}
	if (!priv->haveSession) {
		/* SO gets a r/w session by default,
		 * user gets a r/o session by default. */
		if (pkcs11_open_session(slot, so, relogin))
			return -1;
	}

	rv = CRYPTOKI_call(ctx,
		C_Login(priv->session, so ? CKU_SO : CKU_USER,
			(CK_UTF8CHAR *) pin, pin ? strlen(pin) : 0));
	if (rv && rv != CKR_USER_ALREADY_LOGGED_IN)  /* logged in -> OK   */
		CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv);
	priv->loggedIn = 1;

	if (priv->prev_pin != pin) {
		if (priv->prev_pin) {
			OPENSSL_cleanse(priv->prev_pin, strlen(priv->prev_pin));
			OPENSSL_free(priv->prev_pin);
		}
		priv->prev_pin = BUF_strdup(pin);
	}
	priv->prev_so = so;
	return 0;
}
Beispiel #4
0
/*
 * Log out
 */
int PKCS11_logout(PKCS11_SLOT * slot)
{
	PKCS11_SLOT_private *priv = PRIVSLOT(slot);
	PKCS11_CTX *ctx = priv->parent;
	int rv;

	CHECK_SLOT_FORK(slot);

	/* Calling PKCS11_logout invalidates all cached
	 * keys we have */
	if (slot->token) {
		pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY);
		pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY);
	}
	if (!priv->haveSession) {
		PKCS11err(PKCS11_F_PKCS11_LOGOUT, PKCS11_NO_SESSION);
		return -1;
	}

	rv = CRYPTOKI_call(ctx, C_Logout(priv->session));
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGOUT, rv);
	priv->loggedIn = 0;
	return 0;
}