xref: /illumos-gate/usr/src/lib/pkcs11/libpkcs11/common/pkcs11General.c (revision 83140133e013ea231c89c64244af78d841303f44)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <unistd.h>
27 #include <string.h>
28 #include <cryptoutil.h>
29 #include <pthread.h>
30 
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"
37 
38 #pragma init(pkcs11_init)
39 #pragma fini(pkcs11_fini)
40 
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
111 };
112 
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;
118 
119 /* protects pkcs11_[initialized|pid], and fastpath */
120 static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER;
121 
122 static CK_RV finalize_common(CK_VOID_PTR pReserved);
123 static void pkcs11_init();
124 static void pkcs11_fini();
125 
126 /*
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.
135  *
136  * Order:
137  * 1. slottable->st_mutex
138  * 2. all slottable->st_slots' mutexes
139  */
140 static void
pkcs11_fork_prepare(void)141 pkcs11_fork_prepare(void)
142 {
143 	int i;
144 	if (pkcs11_initialized) {
145 		if (slottable != NULL) {
146 			(void) pthread_mutex_lock(&slottable->st_mutex);
147 
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);
154 				}
155 			}
156 		}
157 	}
158 }
159 
160 
161 /*
162  * Ensure that after a fork, in the parent, all mutexes are released in opposite
163  * order to pkcs11_fork_prepare().
164  */
165 static void
pkcs11_fork_parent(void)166 pkcs11_fork_parent(void)
167 {
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);
177 				}
178 			}
179 		}
180 		(void) pthread_mutex_unlock(&slottable->st_mutex);
181 	}
182 }
183 
184 
185 /*
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.
190  *
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.
194  */
195 static void
pkcs11_fork_child(void)196 pkcs11_fork_child(void)
197 {
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);
207 				}
208 			}
209 		}
210 		(void) pthread_mutex_unlock(&slottable->st_mutex);
211 	}
212 
213 	(void) pthread_mutex_destroy(&globalmutex);
214 	(void) pthread_mutex_init(&globalmutex, NULL);
215 }
216 
217 /* Library cleanup have to be last afterfork child handler. */
218 static void
pkcs11_fork_child_fini(void)219 pkcs11_fork_child_fini(void)
220 {
221 	pkcs11_fini();
222 }
223 
224 CK_RV
C_Initialize(CK_VOID_PTR pInitArgs)225 C_Initialize(CK_VOID_PTR pInitArgs)
226 {
227 	CK_RV rv;
228 	uentrylist_t *pliblist = NULL;
229 	int initialize_pid;
230 
231 	/*
232 	 * Grab lock to insure only one thread enters
233 	 * this function at a time.
234 	 */
235 	(void) pthread_mutex_lock(&globalmutex);
236 
237 	initialize_pid = getpid();
238 
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 {
245 			/*
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.
250 			 */
251 			(void) finalize_common(NULL);
252 		}
253 	}
254 
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;
259 
260 		/* pReserved should not be set */
261 		if (initargs->pReserved != NULL) {
262 			rv = CKR_ARGUMENTS_BAD;
263 			goto errorexit;
264 		}
265 
266 		/*
267 		 * Make sure function pointers are either all NULL or
268 		 * all set.
269 		 */
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;
280 		}
281 
282 		if (!(initargs->flags & CKF_OS_LOCKING_OK)) {
283 			if (initargs->CreateMutex != NULL) {
284 				/*
285 				 * Do not accept application supplied
286 				 * locking primitives.
287 				 */
288 				rv = CKR_CANT_LOCK;
289 				goto errorexit;
290 			}
291 
292 		}
293 		if (initargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
294 			/*
295 			 * Calling application does not want the library
296 			 * to create threads.  This will effect
297 			 * C_WaitForSlotEvent().
298 			 */
299 			pkcs11_cant_create_threads = B_TRUE;
300 		}
301 	}
302 
303 	/* Initialize slot table */
304 	rv = pkcs11_slottable_initialize();
305 
306 	if (rv != CKR_OK)
307 		goto errorexit;
308 
309 	/* Get the list of providers */
310 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
311 		rv = CKR_FUNCTION_FAILED;
312 		goto errorexit;
313 	}
314 
315 	/*
316 	 * Load each provider, check for accessible slots,
317 	 * and populate slottable.  If metaslot is enabled,
318 	 * it will be initialized as well.
319 	 */
320 	rv = pkcs11_slot_mapping(pliblist, pInitArgs);
321 
322 	if (rv != CKR_OK)
323 		goto errorexit;
324 
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;
331 	}
332 
333 	(void) pthread_mutex_unlock(&globalmutex);
334 
335 	/* Cleanup data structures no longer needed */
336 	free_uentrylist(pliblist);
337 
338 	return (CKR_OK);
339 
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);
346 
347 	(void) pthread_mutex_unlock(&globalmutex);
348 	return (rv);
349 
350 }
351 
352 /*
353  * C_Finalize is a wrapper around finalize_common. The
354  * globalmutex should be locked by C_Finalize().
355  *
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).
362  */
363 CK_RV
C_Finalize(CK_VOID_PTR pReserved)364 C_Finalize(CK_VOID_PTR pReserved)
365 {
366 
367 	CK_RV rv;
368 
369 	(void) pthread_mutex_lock(&globalmutex);
370 
371 	rv = finalize_common(pReserved);
372 
373 	(void) pthread_mutex_unlock(&globalmutex);
374 
375 	return (rv);
376 }
377 
378 /*
379  * finalize_common() does the work for C_Finalize.  globalmutex
380  * must be held before calling this function.
381  */
382 static CK_RV
finalize_common(CK_VOID_PTR pReserved)383 finalize_common(CK_VOID_PTR pReserved)
384 {
385 
386 	CK_RV rv;
387 
388 	if (!pkcs11_initialized) {
389 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
390 	}
391 
392 	if (pReserved != NULL) {
393 		return (CKR_ARGUMENTS_BAD);
394 	}
395 
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;
403 
404 	/* Check if C_WaitForSlotEvent() is currently active */
405 	(void) pthread_mutex_lock(&slottable->st_mutex);
406 	if (slottable->st_wfse_active) {
407 		/*
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.
411 		 */
412 		while (slottable->st_wfse_active) {
413 			/*
414 			 * If C_WaitForSlotEvent is blocking, wake it up and
415 			 * return error to calling application.
416 			 */
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);
424 			}
425 		}
426 	} else {
427 		(void) pthread_mutex_unlock(&slottable->st_mutex);
428 	}
429 
430 	rv = pkcs11_slottable_delete();
431 
432 	return (rv);
433 }
434 
435 static void
pkcs11_init()436 pkcs11_init()
437 {
438 	(void) pthread_atfork(pkcs11_fork_prepare,
439 	    pkcs11_fork_parent, pkcs11_fork_child);
440 }
441 
442 /*
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().
448  *
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.
451  *
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.
458  *
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.
466  */
467 static void
pkcs11_fini()468 pkcs11_fini()
469 {
470 	(void) pthread_mutex_lock(&globalmutex);
471 
472 	/* if we're not initilized, do not attempt to finalize */
473 	if (!pkcs11_initialized) {
474 		(void) pthread_mutex_unlock(&globalmutex);
475 		return;
476 	}
477 
478 	fini_called = B_TRUE;
479 
480 	(void) finalize_common(NULL_PTR);
481 
482 	(void) pthread_mutex_unlock(&globalmutex);
483 
484 }
485 
486 CK_RV
C_GetInfo(CK_INFO_PTR pInfo)487 C_GetInfo(CK_INFO_PTR pInfo)
488 {
489 
490 	/* Check for a fastpath */
491 	if (purefastpath || policyfastpath) {
492 		return (fast_funcs->C_GetInfo(pInfo));
493 	}
494 
495 	if (!pkcs11_initialized)
496 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
497 
498 	if (pInfo == NULL) {
499 		return (CKR_ARGUMENTS_BAD);
500 	}
501 
502 	/*
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
506 	 */
507 	(void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID,
508 	    PKCS11_STRING_LENGTH);
509 	(void) strncpy((char *)pInfo->libraryDescription,
510 	    LIBRARY_DESCRIPTION, PKCS11_STRING_LENGTH);
511 
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;
517 
518 	return (CKR_OK);
519 }
520 
521 /*
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.
526  */
527 CK_RV
C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)528 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
529 {
530 	if (ppFunctionList == NULL) {
531 		return (CKR_ARGUMENTS_BAD);
532 	}
533 
534 	*ppFunctionList = &functionList;
535 
536 	return (CKR_OK);
537 }
538 
539 
540 /*
541  * This function is no longer supported in this revision of the PKCS#11
542  * standard.  It is maintained for backwards compatibility only.
543  */
544 /*ARGSUSED*/
545 CK_RV
C_GetFunctionStatus(CK_SESSION_HANDLE hSession)546 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
547 {
548 	return (CKR_FUNCTION_NOT_PARALLEL);
549 }
550 
551 
552 /*
553  * This function is no longer supported in this revision of the PKCS#11
554  * standard.  It is maintained for backwards compatibility only.
555  */
556 /*ARGSUSED*/
557 CK_RV
C_CancelFunction(CK_SESSION_HANDLE hSession)558 C_CancelFunction(CK_SESSION_HANDLE hSession)
559 {
560 	return (CKR_FUNCTION_NOT_PARALLEL);
561 }
562