/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Functions for dealing with provider sessions
*/
#include <string.h>
#include <cryptoutil.h>
#include "metaGlobal.h"
#include "pkcs11Session.h"
#include "pkcs11Global.h"
/*
* This is just a **WILD** guess for the maximum idle sessions to
* keep for each slot. This number should probably be adjusted
* when there's more data from actual application use
*/
/*
* The following 5 variables are initialized at the time metaslot
* is initialized. They are not modified after they are initialized
*
* During initialization time, they are protected by the "initmutex"
* defined in metaGeneral.c
*/
/* protects the "metaslotLoggedIn" variable */
/*
* meta_slotManager_initialize
*
* Called from C_Initialize. Allocates and initializes the storage needed
* by the slot manager.
*/
CK_SLOT_ID i;
/* Initialize the static variables */
/*
* Count the number of slots in the framework.
* We start at ((slottable->st_first) + 1) instead of
* slottable->st_first because when we are here, metaslot is
* enabled, and st_first is always metaslot, which doesn't
* need to be counted.
*/
slot_count++;
}
/*
* This shouldn't happen, because there should at least
* be 1 other slot besides metaslot.
*/
if (slot_count < 1) {
goto clean_exit;
}
goto clean_exit;
}
/*
* Store the slot IDs. Adjust for the fact that the first slot is
* actually us (metaslot).
*/
for (i = 0; i < slot_count; i++) {
(void) pthread_rwlock_init(
}
return (CKR_OK);
if (slots) {
}
num_slots = 0;
return (rv);
}
/*
* meta_slotManager_finalize
*
* Called from C_Finalize. Deallocates any storage held by the slot manager.
*/
void
/* If no slots to free, return */
return;
/*
* No need to lock pool, we assume all meta sessions are closed.
*
* Close all sessions in the idle and persist list.
* The active list is empty. It doesn't need to be checked.
*/
/*
* The slotobjects associated with the session should have
* been closed when the metaobjects were closed. Thus, no
* need to do anything here.
*/
while (session) {
(void) pthread_rwlock_destroy(
}
while (session) {
(void) pthread_rwlock_destroy(
}
(void) pthread_rwlock_destroy(
}
num_slots = 0;
}
/*
* meta_slotManager_find_object_token()
*
* Called from meta_Initialize. Searches for the "object token," which is used
* for storing token objects and loging into.
*
* We do the search using the following algorithm.
*
* If either ${METASLOT_OBJECTSTORE_SLOT} or ${METASLOT_OBJECTSTORE_TOKEN}
* environment variable is defined, the value of the defined variable(s)
* will be used for the match. All token and slot values defined system-wide
* will be ignored.
*
* If neither variables above are defined, the system-wide values defined
* in pkcs11.conf are used.
*
* If neither environment variables or system-wide values are defined,
* values, the first slot after metaslot will be used as the default.
*
*/
void
unsigned int num_match_needed = 0;
}
}
if (num_match_needed == 0) {
goto skip_search;
}
unsigned int num_matched = 0;
&slotinfo);
continue;
if (strncmp((char *)SOFT_SLOT_DESCRIPTION,
(char *)slotinfo.slotDescription,
SLOT_DESCRIPTION_SIZE) == 0) {
}
unsigned char *slot;
&slotinfo);
continue;
/*
* with spaces
*/
/*
* The PKCS#11 strings are not null-terminated, so,
* we just compare SLOT_DESCRIPTION_SIZE bytes
*/
(char *)slotinfo.slotDescription,
SLOT_DESCRIPTION_SIZE) == 0) {
num_matched++;
}
}
unsigned char *token;
&tokeninfo);
continue;
}
/*
* with spaces
*/
/*
* The PKCS#11 strings are not null-terminated.
* So, just compare TOKEN_LABEL_SIZE bytes
*/
TOKEN_LABEL_SIZE) == 0) {
num_matched++;
}
}
if (num_match_needed == num_matched) {
/* match is found */
if (!have_tokeninfo) {
&tokeninfo);
continue;
}
}
/*
* Currently this is the only time that
* the write_protected state is set, and
* it is never cleared. The token could
* clear (or set!) this flag later on.
* We might want to adjust the state
* of metaslot, but there's know way to know
* when a token changes this flag.
*/
}
break;
}
}
if (found) {
} else {
/*
* just use the first available slot as keystore
*/
objtok_slotnum = 0;
}
}
{
return (objtok_slotnum);
}
{
return (softtoken_slotnum);
}
{
/*
* This is only used internally, and so the slotnum should always
* be valid.
*/
}
{
return (num_slots);
}
{
return (write_protected);
}
/*
* Find a session in the given list that matches the specified flags.
* If such a session is found, it will be removed from the list, and
* returned to the caller. If such a session is not found, will
* return NULL
*/
static slot_session_t *
{
while (tmp_session != NULL) {
break;
} else {
}
}
if (tmp_session == NULL) {
/* no match */
return (NULL);
}
/* Remove from list */
return (tmp_session);
}
/*
* meta_get_slot_session
*
*
* NOTE - We assume the slot allows an unlimited number of sessions. We
* could look at what's reported in the token info, but that information is
* not always set. It's also unclear when we should (A) wait for one to become
* available, (B) skip the slot for now or (C) return a fatal error. The
* extra complexity is not worth it.
*
*/
return (CKR_SLOT_ID_INVALID);
}
/*
* Try to reuse an existing session.
*/
if (tmp_session != NULL) {
/* Add to active list */
*session = tmp_session;
return (CKR_OK);
}
}
if (tmp_session != NULL) {
/* Add to active list */
*session = tmp_session;
return (CKR_OK);
}
}
if (new_session == NULL) {
return (CKR_HOST_MEMORY);
}
/* initialize slotsession */
&new_session->hSession);
if (rv == CKR_TOKEN_WRITE_PROTECTED) {
/* Retry with a RO session. */
&new_session->hSession);
}
return (CKR_FUNCTION_FAILED);
}
/* Insert session into active list */
*session = new_session;
return (CKR_OK);
}
/*
* meta_release_slot_session
*
* Call to release a session obtained via meta_get_slot_session()
*/
void
/* Note that the active_list must have >= 1 entry (this session) */
/*
* If the session has session objects, we need to retain it. Also
* retain it if it's the only session holding login state (or handles
* to public token objects)
*/
}
/* remove from active list */
if (must_retain) {
/* insert into persist list */
return;
} else if (!can_close) {
/* insert into idle list */
return;
}
}
/*
* Returns whether metaslot has directly logged in
*/
{
return (metaslotLoggedIn);
}
void
{
(void) pthread_mutex_lock(&metaslotLoggedIn_mutex);
(void) pthread_mutex_unlock(&metaslotLoggedIn_mutex);
}