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]
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
30 #include <security/cryptoki.h>
31 #include "pkcs11Global.h"
32 #include "pkcs11Slot.h"
33 #include "metaGlobal.h"
35 pkcs11_slottable_t
*slottable
= NULL
;
38 * pkcs11_slottable_initialize initizializes the global slottable.
39 * This slottable will contain information about the plugged in
40 * slots, including their mapped slotID. This function should only
41 * be called by C_Intialize.
44 pkcs11_slottable_initialize() {
47 pkcs11_slottable_t
*stmp
= malloc(sizeof (pkcs11_slottable_t
));
50 return (CKR_HOST_MEMORY
);
53 stmp
->st_cur_size
= 0;
55 stmp
->st_slots
= NULL
;
57 if (pthread_mutex_init(&stmp
->st_mutex
, NULL
) != 0) {
59 return (CKR_FUNCTION_FAILED
);
61 /* Set up for possible threads later */
62 stmp
->st_event_slot
= 0;
63 stmp
->st_thr_count
= 0;
64 stmp
->st_wfse_active
= B_FALSE
;
65 stmp
->st_blocking
= B_FALSE
;
66 stmp
->st_list_signaled
= B_FALSE
;
68 (void) pthread_cond_init(&stmp
->st_wait_cond
, NULL
);
69 (void) pthread_mutex_init(&stmp
->st_start_mutex
, NULL
);
70 (void) pthread_cond_init(&stmp
->st_start_cond
, NULL
);
79 * pkcs11_slottable_increase should only be called from C_Initialize().
80 * It is called after the first call to C_GetSlotList() and is used to
81 * increase the size of the slottable, as needed, to contain the next
82 * set of slots that C_Initialize() is currently mapping into the framework.
85 pkcs11_slottable_increase(ulong_t increment
) {
87 pkcs11_slot_t
**tmpslots
;
90 (void) pthread_mutex_lock(&slottable
->st_mutex
);
92 /* Add 1 to cover space for the metaslot */
93 newsize
= slottable
->st_last
+ increment
+ 1;
95 /* Check to see if we already have enough space */
96 if (slottable
->st_cur_size
>= newsize
) {
97 (void) pthread_mutex_unlock(&slottable
->st_mutex
);
101 tmpslots
= reallocarray(slottable
->st_slots
, newsize
,
102 sizeof (pkcs11_slot_t
*));
104 if (tmpslots
== NULL
) {
105 (void) pthread_mutex_unlock(&slottable
->st_mutex
);
106 return (CKR_HOST_MEMORY
);
109 slottable
->st_slots
= tmpslots
;
110 slottable
->st_cur_size
= newsize
;
112 (void) pthread_mutex_unlock(&slottable
->st_mutex
);
118 * pkcs11_slot_allocate should only be called from C_Initialize().
119 * We won't know if the metaslot will be used until after all of
120 * the other slots have been allocated.
123 pkcs11_slot_allocate(CK_SLOT_ID
*pslot_id
) {
125 pkcs11_slot_t
*tmpslot
;
127 tmpslot
= malloc(sizeof (pkcs11_slot_t
));
130 return (CKR_HOST_MEMORY
);
132 bzero(tmpslot
, sizeof (pkcs11_slot_t
));
134 tmpslot
->sl_wfse_state
= WFSE_CLEAR
;
135 tmpslot
->sl_enabledpol
= B_FALSE
;
136 tmpslot
->sl_no_wfse
= B_FALSE
;
138 /* Initialize this slot's mutex */
139 if (pthread_mutex_init(&tmpslot
->sl_mutex
, NULL
) != 0) {
141 return (CKR_FUNCTION_FAILED
);
144 (void) pthread_mutex_lock(&slottable
->st_mutex
);
146 slottable
->st_last
++;
148 *pslot_id
= slottable
->st_last
;
150 slottable
->st_slots
[*pslot_id
] = tmpslot
;
152 (void) pthread_mutex_unlock(&slottable
->st_mutex
);
159 * pkcs11_slottable_delete should only be called by C_Finalize(),
160 * or by C_Initialize() in error conditions.
163 pkcs11_slottable_delete() {
167 int32_t last_prov_id
= -1;
168 pkcs11_slot_t
*cur_slot
;
170 (void) pthread_mutex_lock(&slottable
->st_mutex
);
172 for (i
= slottable
->st_first
; i
<= slottable
->st_last
; i
++) {
174 if (slottable
->st_slots
[i
] != NULL
) {
176 cur_slot
= slottable
->st_slots
[i
];
177 prov_id
= cur_slot
->sl_prov_id
;
179 (void) pthread_mutex_lock(&cur_slot
->sl_mutex
);
182 * For the first slot from this provider, do
185 if (prov_id
!= last_prov_id
) {
187 if (cur_slot
->sl_wfse_state
== WFSE_ACTIVE
) {
188 (void) pthread_cancel
193 * Only call C_Finalize of plug-in if we
194 * get here from an explicit C_Finalize
195 * call from an application. Otherwise,
196 * there is a risk that the application may
197 * have directly dlopened this provider and
198 * we could interrupt their work. Plug-ins
199 * should have their own _fini function to
200 * clean up when they are no longer referenced.
202 if ((cur_slot
->sl_func_list
!= NULL
) &&
205 sl_func_list
->C_Finalize(NULL
);
208 /* metaslot won't have a sl_dldesc! */
209 if (cur_slot
->sl_dldesc
!= NULL
) {
210 (void) dlclose(cur_slot
->sl_dldesc
);
214 * Each provider maintains one disabled
215 * mechanism list for each of its slots to use.
217 free(cur_slot
->sl_pol_mechs
);
220 if (cur_slot
->sl_wfse_args
!= NULL
) {
221 free(cur_slot
->sl_wfse_args
);
224 (void) pthread_mutex_unlock(&cur_slot
->sl_mutex
);
227 * Cleanup the session list. This must
228 * happen after the mutext is unlocked
229 * because session_delete tries to lock it
232 pkcs11_sessionlist_delete(cur_slot
);
234 (void) pthread_mutex_destroy(&cur_slot
->sl_mutex
);
238 last_prov_id
= prov_id
;
242 (void) pthread_cond_destroy(&slottable
->st_wait_cond
);
243 (void) pthread_mutex_destroy(&slottable
->st_start_mutex
);
244 (void) pthread_cond_destroy(&slottable
->st_start_cond
);
246 free(slottable
->st_slots
);
248 (void) pthread_mutex_unlock(&slottable
->st_mutex
);
250 (void) pthread_mutex_destroy(&slottable
->st_mutex
);
261 * pkcs11_is_valid_slot verifies that the slot ID passed to the
262 * framework is valid.
265 pkcs11_is_valid_slot(CK_SLOT_ID slot_id
) {
267 if ((slot_id
< slottable
->st_first
) ||
268 (slot_id
> slottable
->st_last
)) {
269 return (CKR_SLOT_ID_INVALID
);
270 } else if (slottable
->st_slots
[slot_id
] != NULL
) {
273 return (CKR_SLOT_ID_INVALID
);
279 * pkcs11_validate_and_convert_slotid verifies whether the slot ID
280 * passed to the framework is valid, and convert it to the
281 * true slot ID maintained in the framework data structures
284 * This is necessary because when metaslot is enabled, the slot
285 * providing persistent object storage is "hidden".
287 * The real ID is returned in the "real_slot_id" argument regardless conversion
291 pkcs11_validate_and_convert_slotid(CK_SLOT_ID slot_id
,
292 CK_SLOT_ID
*real_slot_id
) {
294 if (!metaslot_enabled
) {
295 *real_slot_id
= slot_id
;
297 /* need to do conversion */
298 if (slot_id
>= metaslot_keystore_slotid
) {
299 *real_slot_id
= slot_id
+ 1;
301 *real_slot_id
= slot_id
;
304 return (pkcs11_is_valid_slot(*real_slot_id
));