8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / pkcs11 / libpkcs11 / common / pkcs11General.c
blob2daa5c63818bfefde7909df890dffa5f53019d9d
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <unistd.h>
27 #include <string.h>
28 #include <cryptoutil.h>
29 #include <pthread.h>
31 #include <security/cryptoki.h>
32 #include "pkcs11Global.h"
33 #include "pkcs11Slot.h"
34 #include "pkcs11Conf.h"
35 #include "pkcs11Session.h"
36 #include "metaGlobal.h"
38 #pragma init(pkcs11_init)
39 #pragma fini(pkcs11_fini)
41 static struct CK_FUNCTION_LIST functionList = {
42 { 2, 20 }, /* version */
43 C_Initialize,
44 C_Finalize,
45 C_GetInfo,
46 C_GetFunctionList,
47 C_GetSlotList,
48 C_GetSlotInfo,
49 C_GetTokenInfo,
50 C_GetMechanismList,
51 C_GetMechanismInfo,
52 C_InitToken,
53 C_InitPIN,
54 C_SetPIN,
55 C_OpenSession,
56 C_CloseSession,
57 C_CloseAllSessions,
58 C_GetSessionInfo,
59 C_GetOperationState,
60 C_SetOperationState,
61 C_Login,
62 C_Logout,
63 C_CreateObject,
64 C_CopyObject,
65 C_DestroyObject,
66 C_GetObjectSize,
67 C_GetAttributeValue,
68 C_SetAttributeValue,
69 C_FindObjectsInit,
70 C_FindObjects,
71 C_FindObjectsFinal,
72 C_EncryptInit,
73 C_Encrypt,
74 C_EncryptUpdate,
75 C_EncryptFinal,
76 C_DecryptInit,
77 C_Decrypt,
78 C_DecryptUpdate,
79 C_DecryptFinal,
80 C_DigestInit,
81 C_Digest,
82 C_DigestUpdate,
83 C_DigestKey,
84 C_DigestFinal,
85 C_SignInit,
86 C_Sign,
87 C_SignUpdate,
88 C_SignFinal,
89 C_SignRecoverInit,
90 C_SignRecover,
91 C_VerifyInit,
92 C_Verify,
93 C_VerifyUpdate,
94 C_VerifyFinal,
95 C_VerifyRecoverInit,
96 C_VerifyRecover,
97 C_DigestEncryptUpdate,
98 C_DecryptDigestUpdate,
99 C_SignEncryptUpdate,
100 C_DecryptVerifyUpdate,
101 C_GenerateKey,
102 C_GenerateKeyPair,
103 C_WrapKey,
104 C_UnwrapKey,
105 C_DeriveKey,
106 C_SeedRandom,
107 C_GenerateRandom,
108 C_GetFunctionStatus,
109 C_CancelFunction,
110 C_WaitForSlotEvent
113 boolean_t pkcs11_initialized = B_FALSE;
114 boolean_t pkcs11_cant_create_threads = B_FALSE;
115 boolean_t fini_called = B_FALSE;
116 static boolean_t pkcs11_atfork_initialized = B_FALSE;
117 static pid_t pkcs11_pid = 0;
119 /* protects pkcs11_[initialized|pid], and fastpath */
120 static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER;
122 static CK_RV finalize_common(CK_VOID_PTR pReserved);
123 static void pkcs11_init();
124 static void pkcs11_fini();
127 * Ensure that before a fork, all mutexes are taken.
128 * We cannot acquire globalmutex, because it can cause deadlock when
129 * atfork() and fork() are called in parallel. It can happen when
130 * C_Ininitialize() tries to dlopen() a provider. The dlopen() operation
131 * is protected by globalmutex and when another thread calls fork()
132 * pkcs11_fork_prepare cannot acquire the mutex again and thus it must wait.
133 * When a provider tries to register its atfork handler, atfork() must
134 * wait on fork(). See the comment in fork() libc function for more details.
136 * Order:
137 * 1. slottable->st_mutex
138 * 2. all slottable->st_slots' mutexes
140 static void
141 pkcs11_fork_prepare(void)
143 int i;
144 if (pkcs11_initialized) {
145 if (slottable != NULL) {
146 (void) pthread_mutex_lock(&slottable->st_mutex);
148 /* Take the sl_mutex of all slots */
149 for (i = slottable->st_first;
150 i <= slottable->st_last; i++) {
151 if (slottable->st_slots[i] != NULL) {
152 (void) pthread_mutex_lock(
153 &slottable->st_slots[i]->sl_mutex);
162 * Ensure that after a fork, in the parent, all mutexes are released in opposite
163 * order to pkcs11_fork_prepare().
165 static void
166 pkcs11_fork_parent(void)
168 int i;
169 if (pkcs11_initialized) {
170 if (slottable != NULL) {
171 /* Release the sl_mutex of all slots */
172 for (i = slottable->st_first;
173 i <= slottable->st_last; i++) {
174 if (slottable->st_slots[i] != NULL) {
175 (void) pthread_mutex_unlock(
176 &slottable->st_slots[i]->sl_mutex);
180 (void) pthread_mutex_unlock(&slottable->st_mutex);
186 * Ensure that after a fork, in the child, all mutexes are released in opposite
187 * order to pkcs11_fork_prepare() and cleanup is done.
188 * Because we need to handle fork correctly before library is initialized two
189 * handlers are necessary.
191 * 1) pkcs11_fork_child() - unlock mutexes
192 * 2) pkcs11_fork_child_fini() - cleanup library after fork, it is registered in
193 * C_Initialize() after providers initialization.
195 static void
196 pkcs11_fork_child(void)
198 int i;
199 if (pkcs11_initialized) {
200 if (slottable != NULL) {
201 /* Release the sl_mutex of all slots */
202 for (i = slottable->st_first;
203 i <= slottable->st_last; i++) {
204 if (slottable->st_slots[i] != NULL) {
205 (void) pthread_mutex_unlock(
206 &slottable->st_slots[i]->sl_mutex);
210 (void) pthread_mutex_unlock(&slottable->st_mutex);
213 (void) pthread_mutex_destroy(&globalmutex);
214 (void) pthread_mutex_init(&globalmutex, NULL);
217 /* Library cleanup have to be last afterfork child handler. */
218 static void
219 pkcs11_fork_child_fini(void)
221 pkcs11_fini();
224 CK_RV
225 C_Initialize(CK_VOID_PTR pInitArgs)
227 CK_RV rv;
228 uentrylist_t *pliblist = NULL;
229 int initialize_pid;
232 * Grab lock to insure only one thread enters
233 * this function at a time.
235 (void) pthread_mutex_lock(&globalmutex);
237 initialize_pid = getpid();
239 /* Make sure function hasn't been called twice */
240 if (pkcs11_initialized) {
241 if (initialize_pid == pkcs11_pid) {
242 (void) pthread_mutex_unlock(&globalmutex);
243 return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
244 } else {
246 * A fork has happened and the child is
247 * reinitializing. Do a finalize_common() to close
248 * out any state from the parent, and then
249 * continue on.
251 (void) finalize_common(NULL);
255 /* Check if application has provided mutex-handling functions */
256 if (pInitArgs != NULL) {
257 CK_C_INITIALIZE_ARGS_PTR initargs =
258 (CK_C_INITIALIZE_ARGS_PTR) pInitArgs;
260 /* pReserved should not be set */
261 if (initargs->pReserved != NULL) {
262 rv = CKR_ARGUMENTS_BAD;
263 goto errorexit;
267 * Make sure function pointers are either all NULL or
268 * all set.
270 if (!(((initargs->CreateMutex != NULL) &&
271 (initargs->LockMutex != NULL) &&
272 (initargs->UnlockMutex != NULL) &&
273 (initargs->DestroyMutex != NULL)) ||
274 ((initargs->CreateMutex == NULL) &&
275 (initargs->LockMutex == NULL) &&
276 (initargs->UnlockMutex == NULL) &&
277 (initargs->DestroyMutex == NULL)))) {
278 rv = CKR_ARGUMENTS_BAD;
279 goto errorexit;
282 if (!(initargs->flags & CKF_OS_LOCKING_OK)) {
283 if (initargs->CreateMutex != NULL) {
285 * Do not accept application supplied
286 * locking primitives.
288 rv = CKR_CANT_LOCK;
289 goto errorexit;
293 if (initargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
295 * Calling application does not want the library
296 * to create threads. This will effect
297 * C_WaitForSlotEvent().
299 pkcs11_cant_create_threads = B_TRUE;
303 /* Initialize slot table */
304 rv = pkcs11_slottable_initialize();
306 if (rv != CKR_OK)
307 goto errorexit;
309 /* Get the list of providers */
310 if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
311 rv = CKR_FUNCTION_FAILED;
312 goto errorexit;
316 * Load each provider, check for accessible slots,
317 * and populate slottable. If metaslot is enabled,
318 * it will be initialized as well.
320 rv = pkcs11_slot_mapping(pliblist, pInitArgs);
322 if (rv != CKR_OK)
323 goto errorexit;
325 pkcs11_initialized = B_TRUE;
326 pkcs11_pid = initialize_pid;
327 /* Children inherit parent's atfork handlers */
328 if (!pkcs11_atfork_initialized) {
329 (void) pthread_atfork(NULL, NULL, pkcs11_fork_child_fini);
330 pkcs11_atfork_initialized = B_TRUE;
333 (void) pthread_mutex_unlock(&globalmutex);
335 /* Cleanup data structures no longer needed */
336 free_uentrylist(pliblist);
338 return (CKR_OK);
340 errorexit:
341 /* Cleanup any data structures that have already been allocated */
342 if (slottable)
343 (void) pkcs11_slottable_delete();
344 if (pliblist)
345 (void) free_uentrylist(pliblist);
347 (void) pthread_mutex_unlock(&globalmutex);
348 return (rv);
353 * C_Finalize is a wrapper around finalize_common. The
354 * globalmutex should be locked by C_Finalize().
356 * When an explicit C_Finalize() call is received, all
357 * plugins currently in the slottable will also be
358 * finalized. This must occur, even if libpkcs11(3lib)
359 * was not the first one to initialize the plugins, since it
360 * is the only way in PKCS#11 to force a refresh of the
361 * slot listings (ie to get new hardware devices).
363 CK_RV
364 C_Finalize(CK_VOID_PTR pReserved)
367 CK_RV rv;
369 (void) pthread_mutex_lock(&globalmutex);
371 rv = finalize_common(pReserved);
373 (void) pthread_mutex_unlock(&globalmutex);
375 return (rv);
379 * finalize_common() does the work for C_Finalize. globalmutex
380 * must be held before calling this function.
382 static CK_RV
383 finalize_common(CK_VOID_PTR pReserved)
386 CK_RV rv;
388 if (!pkcs11_initialized) {
389 return (CKR_CRYPTOKI_NOT_INITIALIZED);
392 if (pReserved != NULL) {
393 return (CKR_ARGUMENTS_BAD);
396 purefastpath = B_FALSE;
397 policyfastpath = B_FALSE;
398 fast_funcs = NULL;
399 fast_slot = 0;
400 pkcs11_initialized = B_FALSE;
401 pkcs11_cant_create_threads = B_FALSE;
402 pkcs11_pid = 0;
404 /* Check if C_WaitForSlotEvent() is currently active */
405 (void) pthread_mutex_lock(&slottable->st_mutex);
406 if (slottable->st_wfse_active) {
408 * Wait for this thread to proceed far enough to block or
409 * end on its own. Otherwise, teardown of slottable may
410 * occurr before this active function completes.
412 while (slottable->st_wfse_active) {
414 * If C_WaitForSlotEvent is blocking, wake it up and
415 * return error to calling application.
417 if (slottable->st_blocking) {
418 slottable->st_list_signaled = B_TRUE;
419 (void) pthread_cond_signal(
420 &slottable->st_wait_cond);
421 (void) pthread_mutex_unlock(
422 &slottable->st_mutex);
423 (void) pthread_join(slottable->st_tid, NULL);
426 } else {
427 (void) pthread_mutex_unlock(&slottable->st_mutex);
430 rv = pkcs11_slottable_delete();
432 return (rv);
435 static void
436 pkcs11_init()
438 (void) pthread_atfork(pkcs11_fork_prepare,
439 pkcs11_fork_parent, pkcs11_fork_child);
443 * pkcs11_fini() function required to make sure complete cleanup
444 * is done of plugins if the framework is ever unloaded without
445 * a C_Finalize() call. This would be common when applications
446 * load and unload other libraries that use libpkcs11(3lib), since
447 * shared libraries should not call C_Finalize().
449 * If pkcs11_fini() is used, we set fini_called to B_TRUE so that
450 * pkcs11_slottable_delete() will not call C_Finalize() on the plugins.
452 * This is to protect in cases where the application has dlopened
453 * an object (for example, dlobj) that links to libpkcs11(3lib), but
454 * the application is unaware that the object is doing PKCS#11 calls
455 * underneath. This application may later directly dlopen one of the
456 * plugins (like pkcs11_softtoken.so, or any other 3rd party provided
457 * plugin) in order to directly perform PKCS#11 operations.
459 * While it is still actively using the PKCS#11 plugin directly,
460 * the application may finish with dlobj and dlclose it. As the
461 * reference count for libpkcs11(3lib) has become 0, pkcs11_fini()
462 * will be run by the linker. Even though libpkcs11(3lib) was the
463 * first to initialize the plugin in this case, it is not safe for
464 * libpkcs11(3lib) to finalize the plugin, as the application would
465 * lose state.
467 static void
468 pkcs11_fini()
470 (void) pthread_mutex_lock(&globalmutex);
472 /* if we're not initilized, do not attempt to finalize */
473 if (!pkcs11_initialized) {
474 (void) pthread_mutex_unlock(&globalmutex);
475 return;
478 fini_called = B_TRUE;
480 (void) finalize_common(NULL_PTR);
482 (void) pthread_mutex_unlock(&globalmutex);
486 CK_RV
487 C_GetInfo(CK_INFO_PTR pInfo)
490 /* Check for a fastpath */
491 if (purefastpath || policyfastpath) {
492 return (fast_funcs->C_GetInfo(pInfo));
495 if (!pkcs11_initialized)
496 return (CKR_CRYPTOKI_NOT_INITIALIZED);
498 if (pInfo == NULL) {
499 return (CKR_ARGUMENTS_BAD);
503 * Copy data into the provided buffer, use strncpy() instead
504 * of strlcpy() so that the strings are NOT NULL terminated,
505 * as required by the PKCS#11 standard
507 (void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID,
508 PKCS11_STRING_LENGTH);
509 (void) strncpy((char *)pInfo->libraryDescription,
510 LIBRARY_DESCRIPTION, PKCS11_STRING_LENGTH);
512 pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
513 pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
514 pInfo->flags = 0;
515 pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR;
516 pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR;
518 return (CKR_OK);
522 * This function is unaffected by the fast-path, since it is likely
523 * called before C_Initialize is, so we will not yet know the status
524 * of the fast-path. Additionally, policy will still need to be
525 * enforced if applicable.
527 CK_RV
528 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
530 if (ppFunctionList == NULL) {
531 return (CKR_ARGUMENTS_BAD);
534 *ppFunctionList = &functionList;
536 return (CKR_OK);
541 * This function is no longer supported in this revision of the PKCS#11
542 * standard. It is maintained for backwards compatibility only.
544 /*ARGSUSED*/
545 CK_RV
546 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
548 return (CKR_FUNCTION_NOT_PARALLEL);
553 * This function is no longer supported in this revision of the PKCS#11
554 * standard. It is maintained for backwards compatibility only.
556 /*ARGSUSED*/
557 CK_RV
558 C_CancelFunction(CK_SESSION_HANDLE hSession)
560 return (CKR_FUNCTION_NOT_PARALLEL);