4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 #include <security/cryptoki.h>
31 #include <cryptoutil.h>
32 #include "kernelGlobal.h"
33 #include "kernelObject.h"
34 #include "kernelSession.h"
35 #include "kernelSlot.h"
38 * Add an object to the session's object list.
40 * This function will acquire the lock on the session, and release
41 * that lock after adding the object to the session's object list.
44 kernel_add_object_to_session(kernel_object_t
*objp
, kernel_session_t
*sp
)
46 /* Acquire the session lock. */
47 (void) pthread_mutex_lock(&sp
->session_mutex
);
49 /* Insert the new object in front of session's object list. */
50 if (sp
->object_list
== NULL
) {
51 sp
->object_list
= objp
;
55 sp
->object_list
->prev
= objp
;
56 objp
->next
= sp
->object_list
;
58 sp
->object_list
= objp
;
61 /* Release the session lock. */
62 (void) pthread_mutex_unlock(&sp
->session_mutex
);
66 * Clean up and release the storage allocated to the object.
68 * The function is called either with the object lock being held
69 * (by caller kernel_delete_object()), or there is no object lock
70 * yet (by kernel_build_XXX_object() during creating an object).
73 kernel_cleanup_object(kernel_object_t
*objp
)
76 * Free the storage allocated to a secret key object.
78 if (objp
->class == CKO_SECRET_KEY
) {
79 if (OBJ_SEC(objp
) != NULL
&& OBJ_SEC_VALUE(objp
) != NULL
) {
80 bzero(OBJ_SEC_VALUE(objp
), OBJ_SEC_VALUE_LEN(objp
));
81 free(OBJ_SEC_VALUE(objp
));
82 OBJ_SEC_VALUE(objp
) = NULL
;
83 OBJ_SEC_VALUE_LEN(objp
) = 0;
88 kernel_cleanup_object_bigint_attrs(objp
);
92 * Free the storage allocated to the extra attribute list.
94 kernel_cleanup_extra_attr(objp
);
98 * Create a new object. Copy the attributes that can be modified
99 * (in the boolean attribute mask field and extra attribute list)
100 * from the old object to the new object.
102 * The caller of this function holds the lock on the old object.
105 kernel_copy_object(kernel_object_t
*old_object
, kernel_object_t
**new_object
,
106 boolean_t copy_everything
, kernel_session_t
*sp
)
109 kernel_object_t
*new_objp
= NULL
;
110 CK_ATTRIBUTE_INFO_PTR attrp
;
112 /* Allocate new object. */
113 new_objp
= calloc(1, sizeof (kernel_object_t
));
114 if (new_objp
== NULL
)
115 return (CKR_HOST_MEMORY
);
117 new_objp
->class = old_object
->class;
118 new_objp
->bool_attr_mask
= old_object
->bool_attr_mask
;
120 attrp
= old_object
->extra_attrlistp
;
123 * Copy the attribute_info struct from the old
124 * object to a new attribute_info struct, and add
125 * that new struct to the extra attribute list
128 rv
= kernel_copy_extra_attr(attrp
, new_objp
);
130 kernel_cleanup_extra_attr(new_objp
);
137 *new_object
= new_objp
;
139 if (!copy_everything
) {
140 /* done with copying all information that can be modified */
145 * Copy the rest of the object.
146 * Certain fields that are not appropriate for coping will be
149 new_objp
->key_type
= old_object
->key_type
;
150 new_objp
->magic_marker
= old_object
->magic_marker
;
151 new_objp
->mechanism
= old_object
->mechanism
;
152 new_objp
->session_handle
= (CK_SESSION_HANDLE
)sp
;
153 (void) pthread_mutex_init(&(new_objp
->object_mutex
), NULL
);
154 /* copy key related information */
155 switch (new_objp
->class) {
157 rv
= kernel_copy_public_key_attr(OBJ_PUB(old_object
),
158 &(OBJ_PUB(new_objp
)), new_objp
->key_type
);
160 case CKO_PRIVATE_KEY
:
161 rv
= kernel_copy_private_key_attr(OBJ_PRI(old_object
),
162 &(OBJ_PRI(new_objp
)), new_objp
->key_type
);
165 rv
= kernel_copy_secret_key_attr(OBJ_SEC(old_object
),
166 &(OBJ_SEC(new_objp
)));
169 /* should never be this case */
174 * don't need to cleanup the memory from failure of copying
175 * any key related stuff. Each individual function for
176 * copying key attr will free the memory if it fails
178 kernel_cleanup_extra_attr(new_objp
);
185 * Copy the attributes (in the boolean attribute mask field and
186 * extra attribute list) from the new object back to the original
187 * object. Also, clean up and release all the storage in the extra
188 * attribute list of the original object.
190 * The caller of this function holds the lock on the old object.
193 kernel_merge_object(kernel_object_t
*old_object
, kernel_object_t
*new_object
)
196 old_object
->bool_attr_mask
= new_object
->bool_attr_mask
;
197 kernel_cleanup_extra_attr(old_object
);
198 old_object
->extra_attrlistp
= new_object
->extra_attrlistp
;
203 * Create a new object struct. If it is a session object, add the object to
204 * the session's object list. If it is a token object, add it to the slot's
205 * token object list. The caller does not hold the slot lock.
208 kernel_add_object(CK_ATTRIBUTE_PTR pTemplate
, CK_ULONG ulCount
,
209 CK_ULONG
*objecthandle_p
, kernel_session_t
*sp
)
212 kernel_object_t
*new_objp
= NULL
;
213 kernel_slot_t
*pslot
;
214 crypto_object_create_t objc
;
216 CK_BBOOL is_token_obj
= B_FALSE
;
219 new_objp
= calloc(1, sizeof (kernel_object_t
));
220 if (new_objp
== NULL
) {
221 rv
= CKR_HOST_MEMORY
;
225 new_objp
->extra_attrlistp
= NULL
;
226 new_objp
->is_lib_obj
= B_TRUE
;
229 * If the HW provider supports object creation, create the object
230 * in the HW provider by calling the CRYPTO_OBJECT_CREATE ioctl.
231 * Otherwise, create the object in the library.
233 pslot
= slot_table
[sp
->ses_slotid
];
234 if (pslot
->sl_func_list
.fl_object_create
) {
235 new_objp
->is_lib_obj
= B_FALSE
;
236 objc
.oc_session
= sp
->k_session
;
237 objc
.oc_count
= ulCount
;
238 rv
= process_object_attributes(pTemplate
, ulCount
,
239 &objc
.oc_attributes
, &is_token_obj
);
244 /* Cannot create a token object with a READ-ONLY session */
245 if (is_token_obj
&& sp
->ses_RO
) {
246 free_object_attributes(objc
.oc_attributes
, ulCount
);
247 rv
= CKR_SESSION_READ_ONLY
;
251 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_CREATE
,
257 rv
= CKR_FUNCTION_FAILED
;
259 rv
= crypto2pkcs11_error_number(objc
.oc_return_value
);
262 free_object_attributes(objc
.oc_attributes
, ulCount
);
268 /* Get the CKA_PRIVATE value of this object. */
269 new_objp
->k_handle
= objc
.oc_handle
;
270 rv
= get_cka_private_value(sp
, new_objp
->k_handle
,
276 /* Set the PRIVATE_BOOL_ON and TOKEN_BOOL_ON attributes */
278 new_objp
->bool_attr_mask
|= PRIVATE_BOOL_ON
;
280 new_objp
->bool_attr_mask
&= ~PRIVATE_BOOL_ON
;
283 new_objp
->bool_attr_mask
|= TOKEN_BOOL_ON
;
285 new_objp
->bool_attr_mask
&= ~TOKEN_BOOL_ON
;
289 * Create the object in the library.
290 * Validate attribute template and fill in the attributes
291 * in the kernel_object_t.
293 rv
= kernel_build_object(pTemplate
, ulCount
, new_objp
, sp
,
300 /* Initialize the rest of stuffs in kernel_object_t. */
301 (void) pthread_mutex_init(&new_objp
->object_mutex
, NULL
);
302 new_objp
->magic_marker
= KERNELTOKEN_OBJECT_MAGIC
;
303 new_objp
->session_handle
= (CK_SESSION_HANDLE
)sp
;
306 /* Add the new object to the slot's token object list. */
307 pslot
= slot_table
[sp
->ses_slotid
];
308 kernel_add_token_object_to_slot(new_objp
, pslot
);
310 /* Add the new object to the session's object list. */
311 kernel_add_object_to_session(new_objp
, sp
);
314 /* Type casting the address of an object struct to an object handle. */
315 *objecthandle_p
= (CK_ULONG
)new_objp
;
322 * If the object is created in the HW provider, the storage
323 * allocated for the ioctl call is always cleaned up after
324 * the call. If the object is created in the library,
325 * the storage allocated inside of this object should
326 * have been cleaned up in the kernel_build_object()
327 * after an error occurred. Therefore, we can safely
337 * Remove an object from the session's object list.
339 * The caller of this function holds the session lock.
342 kernel_remove_object_from_session(kernel_object_t
*objp
, kernel_session_t
*sp
)
344 kernel_object_t
*tmp_objp
;
345 boolean_t found
= B_FALSE
;
348 * Remove the object from the session's object list.
351 (sp
->magic_marker
!= KERNELTOKEN_SESSION_MAGIC
)) {
352 return (CKR_SESSION_HANDLE_INVALID
);
355 if ((sp
->object_list
== NULL
) || (objp
== NULL
) ||
356 (objp
->magic_marker
!= KERNELTOKEN_OBJECT_MAGIC
)) {
357 return (CKR_OBJECT_HANDLE_INVALID
);
360 tmp_objp
= sp
->object_list
;
362 if (tmp_objp
== objp
) {
366 tmp_objp
= tmp_objp
->next
;
369 return (CKR_OBJECT_HANDLE_INVALID
);
371 if (sp
->object_list
== objp
) {
372 /* Object is the first one in the list. */
374 sp
->object_list
= objp
->next
;
375 objp
->next
->prev
= NULL
;
377 /* Object is the only one in the list. */
378 sp
->object_list
= NULL
;
381 /* Object is not the first one in the list. */
383 /* Object is in the middle of the list. */
384 objp
->prev
->next
= objp
->next
;
385 objp
->next
->prev
= objp
->prev
;
387 /* Object is the last one in the list. */
388 objp
->prev
->next
= NULL
;
395 kernel_delete_object_cleanup(kernel_object_t
*objp
, boolean_t wrapper_only
)
397 /* Acquire the lock on the object. */
398 (void) pthread_mutex_lock(&objp
->object_mutex
);
401 * Make sure another thread hasn't freed the object.
403 if (objp
->magic_marker
!= KERNELTOKEN_OBJECT_MAGIC
) {
404 (void) pthread_mutex_unlock(&objp
->object_mutex
);
409 * The deletion of an object must be blocked when the object
410 * reference count is not zero. This means if any object related
411 * operation starts prior to the delete object operation gets in,
412 * the object deleting thread must wait for the non-deleting
413 * operation to be completed before it can proceed the delete
416 * Unless we are being forced to shut everything down, this only
417 * happens if the library's _fini() is running not if someone
418 * explicitly called C_Finalize().
421 objp
->obj_refcnt
= 0;
424 while (objp
->obj_refcnt
!= 0) {
426 * We set the OBJECT_REFCNT_WAITING flag before we put
427 * this deleting thread in a wait state, so other non-deleting
428 * operation thread will signal to wake it up only when
429 * the object reference count becomes zero and this flag
432 objp
->obj_delete_sync
|= OBJECT_REFCNT_WAITING
;
433 (void) pthread_cond_wait(&objp
->obj_free_cond
,
434 &objp
->object_mutex
);
437 objp
->obj_delete_sync
&= ~OBJECT_REFCNT_WAITING
;
439 /* Mark object as no longer valid. */
440 objp
->magic_marker
= 0;
442 (void) pthread_cond_destroy(&objp
->obj_free_cond
);
446 * Delete a session object:
447 * - Remove the object from the session's object list.
448 * - Release the storage allocated to the object.
450 * The boolean argument ses_lock_held is used to indicate that whether
451 * the caller holds the session lock or not.
452 * - When called by kernel_delete_all_objects_in_session() or
453 * kernel_delete_pri_objects_in_slot() -- ses_lock_held = TRUE.
455 * The boolean argument wrapper_only is used to indicate that whether
456 * the caller only wants to clean up the object wrapper from the library and
457 * needs not to make an ioctl call.
458 * - This argument only applies to the object created in the provider level.
459 * - When called by kernel_cleanup_pri_objects_in_slot(), wrapper_only is TRUE.
460 * - When called by C_DestroyObject(), wrapper_only is FALSE.
461 * - When called by kernel_delete_all_objects_in_session(), the value of
462 * wrapper_only depends on its caller.
465 kernel_delete_session_object(kernel_session_t
*sp
, kernel_object_t
*objp
,
466 boolean_t ses_lock_held
, boolean_t wrapper_only
)
469 crypto_object_destroy_t obj_destroy
;
472 * Check to see if the caller holds the lock on the session.
473 * If not, we need to acquire that lock in order to proceed.
475 if (!ses_lock_held
) {
476 /* Acquire the session lock. */
477 (void) pthread_mutex_lock(&sp
->session_mutex
);
480 /* Remove the object from the session's object list first. */
481 rv
= kernel_remove_object_from_session(objp
, sp
);
482 if (!ses_lock_held
) {
484 * If the session lock is obtained by this function,
485 * then release that lock after removing the object
486 * from session's object list.
487 * We want the releasing of the object storage to
488 * be done without holding the session lock.
490 (void) pthread_mutex_unlock(&sp
->session_mutex
);
496 kernel_delete_object_cleanup(objp
, wrapper_only
);
498 /* Destroy the object. */
499 if (objp
->is_lib_obj
) {
501 * If this object is created in the library, cleanup the
502 * contents of this object such as free all the storage
503 * allocated for this object.
505 kernel_cleanup_object(objp
);
508 * This object is created in the HW provider. If wrapper_only
509 * is FALSE, make an ioctl call to destroy it in kernel.
512 obj_destroy
.od_session
= sp
->k_session
;
513 obj_destroy
.od_handle
= objp
->k_handle
;
515 while (ioctl(kernel_fd
, CRYPTO_OBJECT_DESTROY
,
522 * Ignore ioctl return codes for a session object.
523 * If the kernel can not delete a session object, it
524 * is likely caused by the HW provider. There's not
525 * much that can be done. The library will still
526 * cleanup the object wrapper in the library. The HW
527 * provider will destroy all session objects when
528 * the application exits.
533 /* Reset OBJECT_IS_DELETING flag. */
534 objp
->obj_delete_sync
&= ~OBJECT_IS_DELETING
;
536 (void) pthread_mutex_unlock(&objp
->object_mutex
);
537 /* Destroy the object lock */
538 (void) pthread_mutex_destroy(&objp
->object_mutex
);
539 /* Free the object itself */
540 kernel_object_delay_free(objp
);
546 * Delete all the objects in a session. The caller holds the lock
547 * on the session. If the wrapper_only argument is TRUE, the caller only
548 * want to clean up object wrappers in the library.
551 kernel_delete_all_objects_in_session(kernel_session_t
*sp
,
552 boolean_t wrapper_only
)
554 kernel_object_t
*objp
= sp
->object_list
;
555 kernel_object_t
*objp1
;
557 /* Delete all the objects in the session. */
562 * Delete an session object by calling
563 * kernel_delete_session_object():
564 * - The 3rd TRUE boolean argument indicates that the caller
565 * holds the session lock.
566 * - The 4th boolean argument indicates whether we only want
567 * clean up object wrappers in the library.
569 (void) kernel_delete_session_object(sp
, objp
, B_TRUE
,
577 add_to_search_result(kernel_object_t
*obj
, find_context_t
*fcontext
,
578 CK_ULONG
*num_result_alloc
)
581 * allocate space for storing results if the currently
582 * allocated space is not enough
584 if (*num_result_alloc
<= fcontext
->num_results
) {
585 fcontext
->objs_found
= reallocarray(fcontext
->objs_found
,
586 *num_result_alloc
+ BUFSIZ
, sizeof (kernel_object_t
*));
587 if (fcontext
->objs_found
== NULL
) {
588 return (CKR_HOST_MEMORY
);
590 *num_result_alloc
+= BUFSIZ
;
593 (fcontext
->objs_found
)[(fcontext
->num_results
)++] = obj
;
598 search_for_objects(kernel_session_t
*sp
, CK_ATTRIBUTE_PTR pTemplate
,
599 CK_ULONG ulCount
, find_context_t
*fcontext
)
601 kernel_session_t
*session_p
;
602 kernel_object_t
*obj
;
603 CK_OBJECT_CLASS pclasses
[6]; /* classes attrs possibly exist */
604 CK_ULONG num_pclasses
; /* number of possible classes */
605 CK_ULONG num_result_alloc
= 0; /* spaces allocated for results */
607 kernel_slot_t
*pslot
;
610 /* there are some search requirement */
611 kernel_process_find_attr(pclasses
, &num_pclasses
,
615 /* Acquire the slot lock */
616 pslot
= slot_table
[sp
->ses_slotid
];
617 (void) pthread_mutex_lock(&pslot
->sl_mutex
);
620 * Go through all objects in each session.
621 * Acquire individual session lock for the session
624 session_p
= pslot
->sl_sess_list
;
626 (void) pthread_mutex_lock(&session_p
->session_mutex
);
627 obj
= session_p
->object_list
;
629 (void) pthread_mutex_lock(&obj
->object_mutex
);
631 if (kernel_find_match_attrs(obj
, pclasses
,
632 num_pclasses
, pTemplate
, ulCount
)) {
633 rv
= add_to_search_result(
634 obj
, fcontext
, &num_result_alloc
);
637 /* no search criteria, just record the object */
638 rv
= add_to_search_result(obj
, fcontext
,
641 (void) pthread_mutex_unlock(&obj
->object_mutex
);
643 (void) pthread_mutex_unlock(
644 &session_p
->session_mutex
);
649 (void) pthread_mutex_unlock(&session_p
->session_mutex
);
650 session_p
= session_p
->next
;
654 /* Release the slot lock */
655 (void) pthread_mutex_unlock(&pslot
->sl_mutex
);
660 * Initialize the context for C_FindObjects() calls
663 kernel_find_objects_init(kernel_session_t
*sp
, CK_ATTRIBUTE_PTR pTemplate
,
667 CK_OBJECT_CLASS
class; /* for kernel_validate_attr(). Value unused */
668 find_context_t
*fcontext
;
671 rv
= kernel_validate_attr(pTemplate
, ulCount
, &class);
672 /* Make sure all attributes in template are valid */
678 /* prepare the find context */
679 fcontext
= calloc(1, sizeof (find_context_t
));
680 if (fcontext
== NULL
) {
681 return (CKR_HOST_MEMORY
);
684 rv
= search_for_objects(sp
, pTemplate
, ulCount
, fcontext
);
690 /* store the find_context in the session */
691 sp
->find_objects
.context
= (CK_VOID_PTR
)fcontext
;
697 kernel_find_objects_final(kernel_session_t
*sp
)
699 find_context_t
*fcontext
;
701 fcontext
= sp
->find_objects
.context
;
702 sp
->find_objects
.context
= NULL
;
703 sp
->find_objects
.flags
= 0;
704 if (fcontext
->objs_found
!= NULL
) {
705 free(fcontext
->objs_found
);
712 kernel_find_objects(kernel_session_t
*sp
, CK_OBJECT_HANDLE
*obj_found
,
713 CK_ULONG max_obj_requested
, CK_ULONG
*found_obj_count
)
715 find_context_t
*fcontext
;
716 CK_ULONG num_obj_found
= 0;
718 kernel_object_t
*obj
;
720 fcontext
= sp
->find_objects
.context
;
722 for (i
= fcontext
->next_result_index
;
723 ((num_obj_found
< max_obj_requested
) &&
724 (i
< fcontext
->num_results
));
726 obj
= fcontext
->objs_found
[i
];
728 (void) pthread_mutex_lock(&obj
->object_mutex
);
729 /* a sanity check to make sure the obj is still valid */
730 if (obj
->magic_marker
== KERNELTOKEN_OBJECT_MAGIC
) {
731 obj_found
[num_obj_found
] =
732 (CK_OBJECT_HANDLE
)obj
;
735 (void) pthread_mutex_unlock(&obj
->object_mutex
);
738 fcontext
->next_result_index
= i
;
739 *found_obj_count
= num_obj_found
;
743 * Add an token object to the token object list in slot.
745 * This function will acquire the lock on the slot, and release
746 * that lock after adding the object to the slot's token object list.
749 kernel_add_token_object_to_slot(kernel_object_t
*objp
, kernel_slot_t
*pslot
)
751 /* Acquire the slot lock. */
752 (void) pthread_mutex_lock(&pslot
->sl_mutex
);
754 /* Insert the new object in front of slot's token object list. */
755 if (pslot
->sl_tobj_list
== NULL
) {
756 pslot
->sl_tobj_list
= objp
;
760 pslot
->sl_tobj_list
->prev
= objp
;
761 objp
->next
= pslot
->sl_tobj_list
;
763 pslot
->sl_tobj_list
= objp
;
766 /* Release the slot lock. */
767 (void) pthread_mutex_unlock(&pslot
->sl_mutex
);
771 * Remove an token object from the slot's token object list.
772 * This routine is called by kernel_delete_token_object().
773 * The caller of this function hold the slot lock.
776 kernel_remove_token_object_from_slot(kernel_slot_t
*pslot
,
777 kernel_object_t
*objp
)
780 if (pslot
->sl_tobj_list
== objp
) {
781 /* Object is the first one in the list */
783 pslot
->sl_tobj_list
= objp
->next
;
784 objp
->next
->prev
= NULL
;
786 /* Object is the only one in the list. */
787 pslot
->sl_tobj_list
= NULL
;
790 /* Object is not the first one in the list. */
792 /* Object is in the middle of the list. */
793 objp
->prev
->next
= objp
->next
;
794 objp
->next
->prev
= objp
->prev
;
796 /* Object is the last one in the list. */
797 objp
->prev
->next
= NULL
;
803 * Delete a token object:
804 * - Remove the object from the slot's token object list.
805 * - Release the storage allocated to the object.
807 * The boolean argument slot_lock_held is used to indicate that whether
808 * the caller holds the slot lock or not. When the caller does not hold
809 * the slot lock, this function will acquire that lock in order to proceed,
810 * and also release that lock before returning to caller.
812 * The boolean argument wrapper_only is used to indicate that whether
813 * the caller only wants to the object wrapper from library.
816 kernel_delete_token_object(kernel_slot_t
*pslot
, kernel_session_t
*sp
,
817 kernel_object_t
*objp
, boolean_t slot_lock_held
, boolean_t wrapper_only
)
820 crypto_object_destroy_t obj_destroy
;
824 * Check to see if the caller holds the lock on the slot.
825 * If not, we need to acquire that lock in order to proceed.
827 if (!slot_lock_held
) {
828 (void) pthread_mutex_lock(&pslot
->sl_mutex
);
831 /* Remove the object from the slot's token object list first. */
832 kernel_remove_token_object_from_slot(pslot
, objp
);
834 /* Release the slot lock if the call doesn't hold the lock. */
835 if (!slot_lock_held
) {
836 (void) pthread_mutex_unlock(&pslot
->sl_mutex
);
839 kernel_delete_object_cleanup(objp
, wrapper_only
);
842 obj_destroy
.od_session
= sp
->k_session
;
843 obj_destroy
.od_handle
= objp
->k_handle
;
845 while ((r
= ioctl(kernel_fd
, CRYPTO_OBJECT_DESTROY
,
846 &obj_destroy
)) < 0) {
851 rv
= CKR_FUNCTION_FAILED
;
853 rv
= crypto2pkcs11_error_number(
854 obj_destroy
.od_return_value
);
858 * Could not destroy an object from kernel. Write a warning
859 * in syslog, but we still clean up the object wrapper in
863 cryptoerror(LOG_ERR
, "pkcs11_kernel: Could not "
864 "destroy an object in kernel.");
868 (void) pthread_mutex_unlock(&objp
->object_mutex
);
869 /* Destroy the object lock */
870 (void) pthread_mutex_destroy(&objp
->object_mutex
);
871 /* Free the object itself */
872 kernel_object_delay_free(objp
);
878 * Clean up private object wrappers in this slot. The caller holds the slot
882 kernel_cleanup_pri_objects_in_slot(kernel_slot_t
*pslot
,
883 kernel_session_t
*cur_sp
)
885 kernel_session_t
*session_p
;
886 kernel_object_t
*objp
;
887 kernel_object_t
*objp1
;
890 * Delete every private token object from the slot' token object list
892 objp
= pslot
->sl_tobj_list
;
896 * The first TRUE boolean argument indicates that the caller
897 * hold the slot lock. The second TRUE boolean argument
898 * indicates that the caller just wants to clean up the object
899 * wrapper from the library only.
901 if (objp
->bool_attr_mask
& PRIVATE_BOOL_ON
) {
902 (void) kernel_delete_token_object(pslot
, cur_sp
, objp
,
909 * Walk through all the sessions in this slot and delete every
912 session_p
= pslot
->sl_sess_list
;
915 /* Delete all the objects in the session. */
916 objp
= session_p
->object_list
;
920 * The FALSE boolean argument indicates that the
921 * caller does not hold the session lock. The TRUE
922 * boolean argument indicates that the caller just
923 * want to clean upt the object wrapper from the
926 if (objp
->bool_attr_mask
& PRIVATE_BOOL_ON
) {
927 (void) kernel_delete_session_object(session_p
,
928 objp
, B_FALSE
, B_TRUE
);
934 session_p
= session_p
->next
;
939 * Get the object size in bytes for the objects created in the library.
942 kernel_get_object_size(kernel_object_t
*obj
, CK_ULONG_PTR pulSize
)
948 obj_size
= sizeof (kernel_object_t
);
950 switch (obj
->class) {
952 if (obj
->key_type
== CKK_RSA
) {
953 big
= OBJ_PUB_RSA_PUBEXPO(obj
);
954 obj_size
+= big
->big_value_len
;
955 big
= OBJ_PUB_RSA_MOD(obj
);
956 obj_size
+= big
->big_value_len
;
958 } else if (obj
->key_type
== CKK_DSA
) {
959 big
= OBJ_PUB_DSA_PRIME(obj
);
960 obj_size
+= big
->big_value_len
;
961 big
= OBJ_PUB_DSA_SUBPRIME(obj
);
962 obj_size
+= big
->big_value_len
;
963 big
= OBJ_PUB_DSA_BASE(obj
);
964 obj_size
+= big
->big_value_len
;
965 big
= OBJ_PUB_DSA_VALUE(obj
);
966 obj_size
+= big
->big_value_len
;
968 } else if (obj
->key_type
== CKK_EC
) {
969 big
= OBJ_PUB_EC_POINT(obj
);
970 obj_size
+= big
->big_value_len
;
973 rv
= CKR_OBJECT_HANDLE_INVALID
;
977 case CKO_PRIVATE_KEY
:
978 if (obj
->key_type
== CKK_RSA
) {
979 big
= OBJ_PRI_RSA_MOD(obj
);
980 obj_size
+= big
->big_value_len
;
982 big
= OBJ_PRI_RSA_PUBEXPO(obj
); /* optional */
984 obj_size
+= big
->big_value_len
;
987 big
= OBJ_PRI_RSA_PRIEXPO(obj
);
988 obj_size
+= big
->big_value_len
;
990 big
= OBJ_PRI_RSA_PRIME1(obj
); /* optional */
992 obj_size
+= big
->big_value_len
;
995 big
= OBJ_PRI_RSA_PRIME2(obj
); /* optional */
997 obj_size
+= big
->big_value_len
;
1000 big
= OBJ_PRI_RSA_EXPO1(obj
); /* optional */
1002 obj_size
+= big
->big_value_len
;
1005 big
= OBJ_PRI_RSA_EXPO2(obj
); /* optional */
1007 obj_size
+= big
->big_value_len
;
1010 big
= OBJ_PRI_RSA_COEF(obj
); /* optional */
1012 obj_size
+= big
->big_value_len
;
1015 } else if (obj
->key_type
== CKK_DSA
) {
1016 big
= OBJ_PRI_DSA_PRIME(obj
);
1017 obj_size
+= big
->big_value_len
;
1018 big
= OBJ_PRI_DSA_SUBPRIME(obj
);
1019 obj_size
+= big
->big_value_len
;
1020 big
= OBJ_PRI_DSA_BASE(obj
);
1021 obj_size
+= big
->big_value_len
;
1022 big
= OBJ_PRI_DSA_VALUE(obj
);
1023 obj_size
+= big
->big_value_len
;
1025 } else if (obj
->key_type
== CKK_EC
) {
1026 big
= OBJ_PRI_EC_VALUE(obj
);
1027 obj_size
+= big
->big_value_len
;
1030 rv
= CKR_OBJECT_HANDLE_INVALID
;
1034 case CKO_SECRET_KEY
:
1035 obj_size
+= OBJ_SEC_VALUE_LEN(obj
);
1039 rv
= CKR_OBJECT_HANDLE_INVALID
;
1043 *pulSize
= obj_size
;
1050 * This function adds the to-be-freed session object to a linked list.
1051 * When the number of objects queued in the linked list reaches the
1052 * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first
1053 * object (FIFO) in the list.
1056 kernel_object_delay_free(kernel_object_t
*objp
)
1058 kernel_object_t
*tmp
;
1060 (void) pthread_mutex_lock(&obj_delay_freed
.obj_to_be_free_mutex
);
1062 /* Add the newly deleted object at the end of the list */
1064 if (obj_delay_freed
.first
== NULL
) {
1065 obj_delay_freed
.last
= objp
;
1066 obj_delay_freed
.first
= objp
;
1068 obj_delay_freed
.last
->next
= objp
;
1069 obj_delay_freed
.last
= objp
;
1072 if (++obj_delay_freed
.count
>= MAX_OBJ_TO_BE_FREED
) {
1074 * Free the first object in the list only if
1075 * the total count reaches maximum threshold.
1077 obj_delay_freed
.count
--;
1078 tmp
= obj_delay_freed
.first
->next
;
1079 free(obj_delay_freed
.first
);
1080 obj_delay_freed
.first
= tmp
;
1082 (void) pthread_mutex_unlock(&obj_delay_freed
.obj_to_be_free_mutex
);