/*
* 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
*/
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <security/cryptoki.h>
#include <cryptoutil.h>
#include "kmsGlobal.h"
#include "kmsObject.h"
#include "kmsSession.h"
#include "kmsSlot.h"
#include "kmsKeystoreUtil.h"
{
return (NULL);
return (obj);
}
/*
* Add an object to the session's object list.
*
* This function will acquire the lock on the session, and release
* that lock after adding the object to the session's object list.
*/
void
{
/* Acquire the session lock. */
/* Insert the new object in front of session's object list. */
} else {
}
/* Release the session lock. */
}
/*
* Clean up and release the storage allocated to the object.
*
* The function is called either with the object lock being held
* (by caller kms_delete_object()), or there is no object lock
* yet (by kms_build_XXX_object() during creating an object).
*/
void
{
/*
* Free the storage allocated to a secret key object.
*/
OBJ_SEC_VALUE_LEN(objp) = 0;
}
}
/*
* Free the storage allocated to the extra attribute list.
*/
}
void
{
}
/*
* Create a new object. Copy the attributes that can be modified
* (in the boolean attribute mask field and extra attribute list)
* from the old object to the new object.
*
* The caller of this function holds the lock on the old object.
*/
{
/* Allocate new object. */
new_objp = kms_new_object();
return (CKR_HOST_MEMORY);
while (attrp) {
/*
* Copy the attribute_info struct from the old
* object to a new attribute_info struct, and add
* that new struct to the extra attribute list
* of the new object.
*/
return (rv);
}
}
*new_object = new_objp;
if (!copy_everything) {
/* done with copying all information that can be modified */
return (CKR_OK);
}
/*
* Copy the rest of the object.
* Certain fields that are not appropriate for coping will be
* initialized.
*/
/* copy key related information */
case CKO_SECRET_KEY:
break;
default:
/* should never be this case */
break;
}
*new_object = NULL;
}
return (rv);
}
/*
* Copy the attributes (in the boolean attribute mask field and
* extra attribute list) from the new object back to the original
* object. Also, clean up and release all the storage in the extra
* attribute list of the original object.
*
* The caller of this function holds the lock on the old object.
*/
void
{
}
/*
* Create a new object struct. If it is a session object, add the object to
* the session's object list. If it is a token object, add it to the slot's
* token object list. The caller does not hold the slot lock.
*/
{
new_objp = kms_new_object();
return (CKR_HOST_MEMORY);
goto fail_cleanup;
/* Cannot create a token object with a READ-ONLY session */
goto fail_cleanup;
goto fail_cleanup;
}
/*
* If the KMS supports object creation, create the object
* in the KMS. Otherwise, create the object in the library.
*/
/* Get the CKA_PRIVATE value of this object. */
goto fail_cleanup;
}
/* Set the PRIVATE_BOOL_ON and TOKEN_BOOL_ON attributes */
if (is_pri_obj)
else
if (is_token_obj)
else
if (is_token_obj) {
/* Add the new object to the slot's token object list. */
pslot = get_slotinfo();
} else {
/* Add the new object to the session's object list. */
}
/* Type casting the address of an object struct to an object handle. */
}
return (rv);
}
/*
* Remove an object from the session's object list.
*
* The caller of this function holds the session lock.
*/
{
/*
* Remove the object from the session's object list.
*/
return (CKR_SESSION_HANDLE_INVALID);
}
return (CKR_OBJECT_HANDLE_INVALID);
}
while (tmp_objp) {
break;
}
}
if (!found)
return (CKR_OBJECT_HANDLE_INVALID);
/* Object is the first one in the list. */
} else {
/* Object is the only one in the list. */
}
} else {
/* Object is not the first one in the list. */
/* Object is in the middle of the list. */
} else {
/* Object is the last one in the list. */
}
}
return (CKR_OK);
}
/*
* This function adds the to-be-freed session object to a linked list.
* When the number of objects queued in the linked list reaches the
* maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first
* object (FIFO) in the list.
*/
void
{
/* Add the newly deleted object at the end of the list */
} else {
}
/*
* Free the first object in the list only if
* the total count reaches maximum threshold.
*/
}
}
static void
{
/* Acquire the lock on the object. */
/*
* Make sure another thread hasn't freed the object.
*/
return;
}
/*
* The deletion of an object must be blocked when the object
* reference count is not zero. This means if any object related
* operation starts prior to the delete object operation gets in,
* the object deleting thread must wait for the non-deleting
* operation to be completed before it can proceed the delete
* operation.
*
* Unless we are being forced to shut everything down, this only
* happens if the library's _fini() is running not if someone
* explicitly called C_Finalize().
*/
if (force) {
objp->obj_refcnt = 0;
}
while (objp->obj_refcnt != 0) {
/*
* We set the OBJECT_REFCNT_WAITING flag before we put
* this deleting thread in a wait state, so other non-deleting
* operation thread will signal to wake it up only when
* the object reference count becomes zero and this flag
* is set.
*/
&objp->object_mutex);
}
/* Mark object as no longer valid. */
objp->magic_marker = 0;
else
}
/*
* Delete a session object:
* - Remove the object from the session's object list.
* - Release the storage allocated to the object.
*
* The boolean argument ses_lock_held is used to indicate that whether
* the caller holds the session lock or not.
* - When called by kms_delete_all_objects_in_session() or
* kms_delete_pri_objects_in_slot() -- ses_lock_held = TRUE.
*
* The boolean argument wrapper_only is used to indicate that whether
* the caller only wants to clean up the object wrapper from the library and
* needs not to make an call to KMS.
* - This argument only applies to the object created in the provider level.
* - When called by kms_cleanup_pri_objects_in_slot(), wrapper_only is TRUE.
* - When called by C_DestroyObject(), wrapper_only is FALSE.
* - When called by kms_delete_all_objects_in_session(), the value of
* wrapper_only depends on its caller.
*/
{
/*
* Check to see if the caller holds the lock on the session.
* If not, we need to acquire that lock in order to proceed.
*/
if (!ses_lock_held) {
/* Acquire the session lock. */
}
/* Remove the object from the session's object list first. */
if (!ses_lock_held)
return (rv);
}
if (!wrapper_only)
return (rv);
}
/*
* Delete all the objects in a session. The caller holds the lock
* on the session. If the wrapper_only argument is TRUE, the caller only
* want to clean up object wrappers in the library.
*/
void
{
/* Delete all the objects in the session. */
while (objp) {
}
}
static CK_RV
{
/*
* allocate space for storing results if the currently
* allocated space is not enough
*/
return (CKR_HOST_MEMORY);
}
*num_result_alloc += BUFSIZ;
}
return (CKR_OK);
}
static CK_RV
{
int i;
if (ulCount > 0) {
/* there are some search requirement */
}
/*
* Look through template and see if it explicitly specifies
* whether we need to look for token objects and also to see
* if a specific label was specified.
*/
for (i = 0; i < ulCount; i++) {
}
}
}
}
pslot = get_slotinfo();
/* Acquire the slot lock */
if (token_flag_val || !token_specified) {
int found = 0;
/*
* Make sure the object list is current.
*/
return (rv);
}
while (obj) {
((!token_specified) && (ulCount > 0))) {
found++;
}
} else {
/* no search criteria, just record the object */
found++;
}
goto cleanup;
}
}
/*
* If the caller specified a label but it was not found,
* query the KMS to see if it exists there but is not in the
* local list.
*/
/*
* If we DID find the object, add it to the
* slot token object list and label list.
*/
goto token_done;
}
goto token_done;
}
/*
* If all went well, add it to the head of
* the token object list.
*/
} else {
/*
* This just means the wrong label was used
* and the key really doesn't exist in the
* KMS.
*/
}
}
}
return (rv);
}
/*
* Go through all objects in each session.
* Acquire individual session lock for the session
* we are searching.
*/
while (session_p) {
while (obj) {
if (ulCount > 0) {
}
} else {
/* no search criteria, just record the object */
}
(void) pthread_mutex_unlock(
goto cleanup;
}
}
}
return (rv);
}
/*
* Initialize the context for C_FindObjects() calls
*/
{
if (ulCount) {
/* Make sure all attributes in template are valid */
return (rv);
}
}
/* prepare the find context */
return (CKR_HOST_MEMORY);
}
return (rv);
}
/* store the find_context in the session */
return (rv);
}
void
{
}
}
{
CK_ULONG i;
for (i = fcontext->next_result_index;
((num_obj_found < max_obj_requested) &&
(i < fcontext->num_results));
i++) {
/* a sanity check to make sure the obj is still valid */
}
}
}
fcontext->next_result_index = i;
return (CKR_OK);
}
/*
* Add an token object to the token object list in slot.
*
* This function will acquire the lock on the slot, and release
* that lock after adding the object to the slot's token object list.
*/
void
{
/* Acquire the slot lock. */
/* Insert the new object in front of slot's token object list. */
} else {
}
/* Release the slot lock. */
}
/*
* Remove an token object from the slot's token object list.
* This routine is called by kms_delete_token_object().
* The caller of this function hold the slot lock.
*/
void
{
/* Object is the first one in the list */
} else {
/* Object is the only one in the list. */
}
} else {
/* Object is not the first one in the list. */
/* Object is in the middle of the list. */
/* Object is the last one in the list. */
}
}
}
/*
* Delete a token object:
* - Remove the object from the slot's token object list.
* - Release the storage allocated to the object.
*
* The boolean argument slot_lock_held is used to indicate that whether
* the caller holds the slot lock or not. When the caller does not hold
* the slot lock, this function will acquire that lock in order to proceed,
* and also release that lock before returning to caller.
*
* The boolean argument wrapper_only is used to indicate that whether
* the caller only wants to the object wrapper from library.
*/
{
if (!slot_lock_held) {
}
/* Delete from KMS */
}
/* Remove the object from the slot's token object list first. */
/* Release the slot lock if the call doesn't hold the lock. */
if (!slot_lock_held) {
}
return (rv);
}
/*
* Clean up private object wrappers in this slot. The caller holds the slot
* lock.
*/
void
{
/*
* Delete every private token object from
* the slot token object list.
*/
while (objp) {
/*
* The first TRUE boolean argument indicates that the caller
* hold the slot lock. The second TRUE boolean argument
* indicates that the caller just wants to clean up the object
* wrapper from the library only.
*/
}
}
/*
* Walk through all the sessions in this slot and delete every
* private object.
*/
while (session_p) {
/* Delete all the objects in the session. */
while (objp) {
/*
* The FALSE boolean argument indicates that the
* caller does not hold the session lock. The TRUE
* boolean argument indicates that the caller just
* want to clean upt the object wrapper from the
* library only.
*/
(void) kms_delete_object(session_p,
}
}
}
}
/*
* Get the object size in bytes for the objects created in the library.
*/
{
obj_size = sizeof (kms_object_t);
case CKO_SECRET_KEY:
break;
default:
}
}
return (rv);
}