xref: /illumos-gate/usr/src/lib/pkcs11/libpkcs11/common/pkcs11General.c (revision 051aabe6136ff13e81542a427e9693ffe1503525)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <unistd.h>
29 #include <string.h>
30 #include <cryptoutil.h>
31 #include <pthread.h>
32 
33 #include <security/cryptoki.h>
34 #include "pkcs11Global.h"
35 #include "pkcs11Slot.h"
36 #include "pkcs11Conf.h"
37 #include "pkcs11Session.h"
38 #include "metaGlobal.h"
39 
40 #pragma fini(pkcs11_fini)
41 
42 static struct CK_FUNCTION_LIST functionList = {
43 	{ 2, 20 },	/* version */
44 	C_Initialize,
45 	C_Finalize,
46 	C_GetInfo,
47 	C_GetFunctionList,
48 	C_GetSlotList,
49 	C_GetSlotInfo,
50 	C_GetTokenInfo,
51 	C_GetMechanismList,
52 	C_GetMechanismInfo,
53 	C_InitToken,
54 	C_InitPIN,
55 	C_SetPIN,
56 	C_OpenSession,
57 	C_CloseSession,
58 	C_CloseAllSessions,
59 	C_GetSessionInfo,
60 	C_GetOperationState,
61 	C_SetOperationState,
62 	C_Login,
63 	C_Logout,
64 	C_CreateObject,
65 	C_CopyObject,
66 	C_DestroyObject,
67 	C_GetObjectSize,
68 	C_GetAttributeValue,
69 	C_SetAttributeValue,
70 	C_FindObjectsInit,
71 	C_FindObjects,
72 	C_FindObjectsFinal,
73 	C_EncryptInit,
74 	C_Encrypt,
75 	C_EncryptUpdate,
76 	C_EncryptFinal,
77 	C_DecryptInit,
78 	C_Decrypt,
79 	C_DecryptUpdate,
80 	C_DecryptFinal,
81 	C_DigestInit,
82 	C_Digest,
83 	C_DigestUpdate,
84 	C_DigestKey,
85 	C_DigestFinal,
86 	C_SignInit,
87 	C_Sign,
88 	C_SignUpdate,
89 	C_SignFinal,
90 	C_SignRecoverInit,
91 	C_SignRecover,
92 	C_VerifyInit,
93 	C_Verify,
94 	C_VerifyUpdate,
95 	C_VerifyFinal,
96 	C_VerifyRecoverInit,
97 	C_VerifyRecover,
98 	C_DigestEncryptUpdate,
99 	C_DecryptDigestUpdate,
100 	C_SignEncryptUpdate,
101 	C_DecryptVerifyUpdate,
102 	C_GenerateKey,
103 	C_GenerateKeyPair,
104 	C_WrapKey,
105 	C_UnwrapKey,
106 	C_DeriveKey,
107 	C_SeedRandom,
108 	C_GenerateRandom,
109 	C_GetFunctionStatus,
110 	C_CancelFunction,
111 	C_WaitForSlotEvent
112 };
113 
114 boolean_t pkcs11_initialized = B_FALSE;
115 boolean_t pkcs11_cant_create_threads = B_FALSE;
116 boolean_t fini_called = B_FALSE;
117 static boolean_t pkcs11_atfork_initialized = B_FALSE;
118 static pid_t pkcs11_pid = 0;
119 
120 /* protects pkcs11_[initialized|pid], and fastpath */
121 static pthread_mutex_t globalmutex = PTHREAD_MUTEX_INITIALIZER;
122 
123 static CK_RV finalize_common(CK_VOID_PTR pReserved);
124 static void pkcs11_fini();
125 
126 /*
127  * Ensure that before a fork, all mutexes are taken.
128  * Order:
129  * 1. globalmutex
130  * 2. slottable->st_mutex
131  * 3. all slottable->st_slots' mutexes
132  */
133 static void
134 pkcs11_fork_prepare(void)
135 {
136 	int i;
137 	(void) pthread_mutex_lock(&globalmutex);
138 	if (slottable != NULL) {
139 		(void) pthread_mutex_lock(&slottable->st_mutex);
140 
141 		/* Take the sl_mutex of all slots */
142 		for (i = slottable->st_first; i <= slottable->st_last; i++) {
143 			if (slottable->st_slots[i] != NULL) {
144 				(void) pthread_mutex_lock(
145 				    &slottable->st_slots[i]->sl_mutex);
146 			}
147 		}
148 	}
149 }
150 
151 
152 /*
153  * Ensure that after a fork, in the parent, all mutexes are released in opposite
154  * order to pkcs11_fork_prepare().
155  */
156 static void
157 pkcs11_fork_parent(void)
158 {
159 	int i;
160 	if (slottable != NULL) {
161 		/* Release the sl_mutex of all slots */
162 		for (i = slottable->st_first; i <= slottable->st_last; i++) {
163 			if (slottable->st_slots[i] != NULL) {
164 				(void) pthread_mutex_unlock(
165 				    &slottable->st_slots[i]->sl_mutex);
166 			}
167 		}
168 		(void) pthread_mutex_unlock(&slottable->st_mutex);
169 	}
170 	(void) pthread_mutex_unlock(&globalmutex);
171 }
172 
173 
174 /*
175  * Ensure that after a fork, in the child, all mutexes are released in opposite
176  * order to pkcs11_fork_prepare() and cleanup is done.
177  */
178 static void
179 pkcs11_fork_child(void)
180 {
181 	int i;
182 	if (slottable != NULL) {
183 		/* Release the sl_mutex of all slots */
184 		for (i = slottable->st_first; i <= slottable->st_last; i++) {
185 			if (slottable->st_slots[i] != NULL) {
186 				(void) pthread_mutex_unlock(
187 				    &slottable->st_slots[i]->sl_mutex);
188 			}
189 		}
190 		(void) pthread_mutex_unlock(&slottable->st_mutex);
191 	}
192 	(void) pthread_mutex_unlock(&globalmutex);
193 	pkcs11_fini();
194 }
195 
196 CK_RV
197 C_Initialize(CK_VOID_PTR pInitArgs)
198 {
199 	CK_RV rv;
200 	uentrylist_t *pliblist = NULL;
201 	int initialize_pid;
202 
203 	/*
204 	 * Grab lock to insure only one thread enters
205 	 * this function at a time.
206 	 */
207 	(void) pthread_mutex_lock(&globalmutex);
208 
209 	initialize_pid = getpid();
210 
211 	/* Make sure function hasn't been called twice */
212 	if (pkcs11_initialized) {
213 		if (initialize_pid == pkcs11_pid) {
214 			(void) pthread_mutex_unlock(&globalmutex);
215 			return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
216 		} else {
217 			/*
218 			 * A fork has happened and the child is
219 			 * reinitializing.  Do a finalize_common() to close
220 			 * out any state from the parent, and then
221 			 * continue on.
222 			 */
223 			(void) finalize_common(NULL);
224 		}
225 	}
226 
227 	/* Check if application has provided mutex-handling functions */
228 	if (pInitArgs != NULL) {
229 		CK_C_INITIALIZE_ARGS_PTR initargs =
230 		    (CK_C_INITIALIZE_ARGS_PTR) pInitArgs;
231 
232 		/* pReserved should not be set */
233 		if (initargs->pReserved != NULL) {
234 			rv = CKR_ARGUMENTS_BAD;
235 			goto errorexit;
236 		}
237 
238 		/*
239 		 * Make sure function pointers are either all NULL or
240 		 * all set.
241 		 */
242 		if (!(((initargs->CreateMutex   != NULL) &&
243 		    (initargs->LockMutex    != NULL) &&
244 		    (initargs->UnlockMutex  != NULL) &&
245 		    (initargs->DestroyMutex != NULL)) ||
246 		    ((initargs->CreateMutex == NULL) &&
247 		    (initargs->LockMutex    == NULL) &&
248 		    (initargs->UnlockMutex  == NULL) &&
249 		    (initargs->DestroyMutex == NULL)))) {
250 			rv = CKR_ARGUMENTS_BAD;
251 			goto errorexit;
252 		}
253 
254 		if (!(initargs->flags & CKF_OS_LOCKING_OK)) {
255 			if (initargs->CreateMutex != NULL) {
256 				/*
257 				 * Do not accept application supplied
258 				 * locking primitives.
259 				 */
260 				rv = CKR_CANT_LOCK;
261 				goto errorexit;
262 			}
263 
264 		}
265 		if (initargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
266 			/*
267 			 * Calling application does not want the library
268 			 * to create threads.  This will effect
269 			 * C_WaitForSlotEvent().
270 			 */
271 			pkcs11_cant_create_threads = B_TRUE;
272 		}
273 	}
274 
275 	/* Initialize slot table */
276 	rv = pkcs11_slottable_initialize();
277 
278 	if (rv != CKR_OK)
279 		goto errorexit;
280 
281 	/* Get the list of providers */
282 	if (get_pkcs11conf_info(&pliblist) != SUCCESS) {
283 		rv = CKR_FUNCTION_FAILED;
284 		goto errorexit;
285 	}
286 
287 	/*
288 	 * Load each provider, check for accessible slots,
289 	 * and populate slottable.  If metaslot is enabled,
290 	 * it will be initialized as well.
291 	 */
292 	rv = pkcs11_slot_mapping(pliblist, pInitArgs);
293 
294 	if (rv != CKR_OK)
295 		goto errorexit;
296 
297 	pkcs11_initialized = B_TRUE;
298 	pkcs11_pid = initialize_pid;
299 	/* Children inherit parent's atfork handlers */
300 	if (!pkcs11_atfork_initialized) {
301 		(void) pthread_atfork(pkcs11_fork_prepare,
302 		    pkcs11_fork_parent, pkcs11_fork_child);
303 		pkcs11_atfork_initialized = B_TRUE;
304 	}
305 	(void) pthread_mutex_unlock(&globalmutex);
306 
307 	/* Cleanup data structures no longer needed */
308 	free_uentrylist(pliblist);
309 
310 	return (CKR_OK);
311 
312 errorexit:
313 	/* Cleanup any data structures that have already been allocated */
314 	if (slottable)
315 		(void) pkcs11_slottable_delete();
316 	if (pliblist)
317 		(void) free_uentrylist(pliblist);
318 
319 	(void) pthread_mutex_unlock(&globalmutex);
320 	return (rv);
321 
322 }
323 
324 /*
325  * C_Finalize is a wrapper around finalize_common. The
326  * globalmutex should be locked by C_Finalize().
327  *
328  * When an explicit C_Finalize() call is received, all
329  * plugins currently in the slottable will also be
330  * finalized.  This must occur, even if libpkcs11(3lib)
331  * was not the first one to initialize the plugins, since it
332  * is the only way in PKCS#11 to force a refresh of the
333  * slot listings (ie to get new hardware devices).
334  */
335 CK_RV
336 C_Finalize(CK_VOID_PTR pReserved)
337 {
338 
339 	CK_RV rv;
340 
341 	(void) pthread_mutex_lock(&globalmutex);
342 
343 	rv = finalize_common(pReserved);
344 
345 	(void) pthread_mutex_unlock(&globalmutex);
346 
347 	return (rv);
348 }
349 
350 /*
351  * finalize_common() does the work for C_Finalize.  globalmutex
352  * must be held before calling this function.
353  */
354 static CK_RV
355 finalize_common(CK_VOID_PTR pReserved)
356 {
357 
358 	CK_RV rv;
359 
360 	if (!pkcs11_initialized) {
361 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
362 	}
363 
364 	if (pReserved != NULL) {
365 		return (CKR_ARGUMENTS_BAD);
366 	}
367 
368 	purefastpath = B_FALSE;
369 	policyfastpath = B_FALSE;
370 	fast_funcs = NULL;
371 	fast_slot = 0;
372 	pkcs11_initialized = B_FALSE;
373 	pkcs11_cant_create_threads = B_FALSE;
374 	pkcs11_pid = 0;
375 
376 	if (metaslot_enabled)
377 		rv = meta_Finalize(pReserved);
378 
379 	/* Check if C_WaitForSlotEvent() is currently active */
380 	(void) pthread_mutex_lock(&slottable->st_mutex);
381 	if (slottable->st_wfse_active) {
382 		/*
383 		 * Wait for this thread to proceed far enough to block or
384 		 * end on its own.  Otherwise, teardown of slottable may
385 		 * occurr before this active function completes.
386 		 */
387 		while (slottable->st_wfse_active) {
388 			/*
389 			 * If C_WaitForSlotEvent is blocking, wake it up and
390 			 * return error to calling application.
391 			 */
392 			if (slottable->st_blocking) {
393 				slottable->st_list_signaled = B_TRUE;
394 				(void) pthread_cond_signal(
395 				    &slottable->st_wait_cond);
396 				(void) pthread_mutex_unlock(
397 				    &slottable->st_mutex);
398 				(void) pthread_join(slottable->st_tid, NULL);
399 			}
400 		}
401 	} else {
402 		(void) pthread_mutex_unlock(&slottable->st_mutex);
403 	}
404 
405 	rv = pkcs11_slottable_delete();
406 
407 	return (rv);
408 }
409 
410 /*
411  * pkcs11_fini() function required to make sure complete cleanup
412  * is done of plugins if the framework is ever unloaded without
413  * a C_Finalize() call.  This would be common when applications
414  * load and unload other libraries that use libpkcs11(3lib), since
415  * shared libraries should not call C_Finalize().
416  *
417  * If pkcs11_fini() is used, we set fini_called to B_TRUE so that
418  * pkcs11_slottable_delete() will not call C_Finalize() on the plugins.
419  *
420  * This is to protect in cases where the application has dlopened
421  * an object (for example, dlobj) that links to libpkcs11(3lib), but
422  * the application is unaware that the object is doing PKCS#11 calls
423  * underneath.  This application may later directly dlopen one of the
424  * plugins (like pkcs11_softtoken.so, or any other 3rd party provided
425  * plugin) in order to directly perform PKCS#11 operations.
426  *
427  * While it is still actively using the PKCS#11 plugin directly,
428  * the application may finish with dlobj and dlclose it.  As the
429  * reference count for libpkcs11(3lib) has become 0, pkcs11_fini()
430  * will be run by the linker.  Even though libpkcs11(3lib) was the
431  * first to initialize the plugin in this case, it is not safe for
432  * libpkcs11(3lib) to finalize the plugin, as the application would
433  * lose state.
434  */
435 static void
436 pkcs11_fini()
437 {
438 	(void) pthread_mutex_lock(&globalmutex);
439 
440 	/* if we're not initilized, do not attempt to finalize */
441 	if (!pkcs11_initialized) {
442 		(void) pthread_mutex_unlock(&globalmutex);
443 		return;
444 	}
445 
446 	fini_called = B_TRUE;
447 
448 	(void) finalize_common(NULL_PTR);
449 
450 	(void) pthread_mutex_unlock(&globalmutex);
451 
452 }
453 
454 CK_RV
455 C_GetInfo(CK_INFO_PTR pInfo)
456 {
457 
458 	/* Check for a fastpath */
459 	if (purefastpath || policyfastpath) {
460 		return (fast_funcs->C_GetInfo(pInfo));
461 	}
462 
463 	if (!pkcs11_initialized)
464 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
465 
466 	if (pInfo == NULL) {
467 		return (CKR_ARGUMENTS_BAD);
468 	}
469 
470 	/*
471 	 * Copy data into the provided buffer, use strncpy() instead
472 	 * of strlcpy() so that the strings are NOT NULL terminated,
473 	 * as required by the PKCS#11 standard
474 	 */
475 	(void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID,
476 	    PKCS11_STRING_LENGTH);
477 	(void) strncpy((char *)pInfo->libraryDescription,
478 	    LIBRARY_DESCRIPTION, PKCS11_STRING_LENGTH);
479 
480 	pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
481 	pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
482 	pInfo->flags = 0;
483 	pInfo->libraryVersion.major = LIBRARY_VERSION_MAJOR;
484 	pInfo->libraryVersion.minor = LIBRARY_VERSION_MINOR;
485 
486 	return (CKR_OK);
487 }
488 
489 /*
490  * This function is unaffected by the fast-path, since it is likely
491  * called before C_Initialize is, so we will not yet know the status
492  * of the fast-path.  Additionally, policy will still need to be
493  * enforced if applicable.
494  */
495 CK_RV
496 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
497 {
498 	if (ppFunctionList == NULL) {
499 		return (CKR_ARGUMENTS_BAD);
500 	}
501 
502 	*ppFunctionList = &functionList;
503 
504 	return (CKR_OK);
505 }
506 
507 
508 /*
509  * This function is no longer supported in this revision of the PKCS#11
510  * standard.  It is maintained for backwards compatibility only.
511  */
512 /*ARGSUSED*/
513 CK_RV
514 C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
515 {
516 	return (CKR_FUNCTION_NOT_PARALLEL);
517 }
518 
519 
520 /*
521  * This function is no longer supported in this revision of the PKCS#11
522  * standard.  It is maintained for backwards compatibility only.
523  */
524 /*ARGSUSED*/
525 CK_RV
526 C_CancelFunction(CK_SESSION_HANDLE hSession)
527 {
528 	return (CKR_FUNCTION_NOT_PARALLEL);
529 }
530