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 <strings.h>
27 #include <errno.h>
28 #include <cryptoutil.h>
29 #include <unistd.h> /* for pid_t */
30 #include <pthread.h>
31 #include <security/cryptoki.h>
32 #include "softGlobal.h"
33 #include "softSession.h"
34 #include "softObject.h"
35 #include "softKeystore.h"
36 #include "softKeystoreUtil.h"
37
38 #pragma init(softtoken_init)
39 #pragma fini(softtoken_fini)
40
41 extern soft_session_t token_session; /* for fork handler */
42
43 static struct CK_FUNCTION_LIST functionList = {
111 C_CancelFunction,
112 C_WaitForSlotEvent
113 };
114
115 boolean_t softtoken_initialized = B_FALSE;
116
117 static pid_t softtoken_pid = 0;
118
119 /* This mutex protects soft_session_list, all_sessions_closing */
120 pthread_mutex_t soft_sessionlist_mutex;
121 soft_session_t *soft_session_list = NULL;
122
123 int all_sessions_closing = 0;
124
125 slot_t soft_slot;
126 obj_to_be_freed_list_t obj_delay_freed;
127 ses_to_be_freed_list_t ses_delay_freed;
128
129 /* protects softtoken_initialized and access to C_Initialize/C_Finalize */
130 pthread_mutex_t soft_giant_mutex = PTHREAD_MUTEX_INITIALIZER;
131
132 static CK_RV finalize_common(boolean_t force, CK_VOID_PTR pReserved);
133 static void softtoken_init();
134 static void softtoken_fini();
135 static void softtoken_fork_prepare();
136 static void softtoken_fork_after();
137
138 CK_RV
139 C_Initialize(CK_VOID_PTR pInitArgs)
140 {
141
142 int initialize_pid;
143 boolean_t supplied_ok;
144 CK_RV rv;
145
146 /*
147 * Get lock to insure only one thread enters this
148 * function at a time.
149 */
150 (void) pthread_mutex_lock(&soft_giant_mutex);
151
152 initialize_pid = getpid();
153
154 if (softtoken_initialized) {
155 if (initialize_pid == softtoken_pid) {
156 /*
394 (void) pthread_mutex_destroy(&ses_delay_freed.ses_to_be_free_mutex);
395
396 return (rv);
397 }
398
399 static void
400 softtoken_init()
401 {
402 /* Children inherit parent's atfork handlers */
403 (void) pthread_atfork(softtoken_fork_prepare,
404 softtoken_fork_after, softtoken_fork_after);
405 }
406
407 /*
408 * softtoken_fini() function required to make sure complete cleanup
409 * is done if softtoken is ever unloaded without a C_Finalize() call.
410 */
411 static void
412 softtoken_fini()
413 {
414 (void) pthread_mutex_lock(&soft_giant_mutex);
415
416 /* if we're not initilized, do not attempt to finalize */
417 if (!softtoken_initialized) {
418 (void) pthread_mutex_unlock(&soft_giant_mutex);
419 return;
420 }
421
422 (void) finalize_common(B_TRUE, NULL_PTR);
423
424 (void) pthread_mutex_unlock(&soft_giant_mutex);
425 }
426
427 CK_RV
428 C_GetInfo(CK_INFO_PTR pInfo)
429 {
430 if (!softtoken_initialized)
431 return (CKR_CRYPTOKI_NOT_INITIALIZED);
432
433 if (pInfo == NULL) {
434 return (CKR_ARGUMENTS_BAD);
435 }
436
437 /* Provide general information in the provided buffer */
438 pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
439 pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
440 (void) strncpy((char *)pInfo->manufacturerID,
441 SOFT_MANUFACTURER_ID, 32);
442 pInfo->flags = 0;
443 (void) strncpy((char *)pInfo->libraryDescription,
479 CK_RV
480 C_CancelFunction(CK_SESSION_HANDLE hSession)
481 {
482 return (CKR_FUNCTION_NOT_PARALLEL);
483 }
484
485 /*
486 * Take out all mutexes before fork.
487 *
488 * Order:
489 * 1. soft_giant_mutex
490 * 2. soft_sessionlist_mutex
491 * 3. soft_slot.slot_mutex
492 * 4. soft_slot.keystore_mutex
493 * 5. token_session mutexes via soft_acquire_all_session_mutexes()
494 * 6. all soft_session_list mutexes via soft_acquire_all_session_mutexes()
495 * 7. obj_delay_freed.obj_to_be_free_mutex;
496 * 8. ses_delay_freed.ses_to_be_free_mutex
497 */
498 void
499 softtoken_fork_prepare()
500 {
501 (void) pthread_mutex_lock(&soft_giant_mutex);
502 if (softtoken_initialized) {
503 (void) pthread_mutex_lock(&soft_sessionlist_mutex);
504 (void) pthread_mutex_lock(&soft_slot.slot_mutex);
505 (void) pthread_mutex_lock(&soft_slot.keystore_mutex);
506 soft_acquire_all_session_mutexes(&token_session);
507 soft_acquire_all_session_mutexes(soft_session_list);
508 (void) pthread_mutex_lock(
509 &obj_delay_freed.obj_to_be_free_mutex);
510 (void) pthread_mutex_lock(
511 &ses_delay_freed.ses_to_be_free_mutex);
512 }
513 }
514
515 /*
516 * Release in opposite order to softtoken_fork_prepare().
517 * Function is used for parent and child.
518 */
519 void
520 softtoken_fork_after()
521 {
522 if (softtoken_initialized) {
523 (void) pthread_mutex_unlock(
524 &ses_delay_freed.ses_to_be_free_mutex);
525 (void) pthread_mutex_unlock(
526 &obj_delay_freed.obj_to_be_free_mutex);
527 soft_release_all_session_mutexes(soft_session_list);
528 soft_release_all_session_mutexes(&token_session);
529 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
530 (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
531 (void) pthread_mutex_unlock(&soft_sessionlist_mutex);
532 }
533 (void) pthread_mutex_unlock(&soft_giant_mutex);
534 }
|
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 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
26 */
27
28 #include <strings.h>
29 #include <errno.h>
30 #include <cryptoutil.h>
31 #include <unistd.h> /* for pid_t */
32 #include <pthread.h>
33 #include <security/cryptoki.h>
34 #include "softGlobal.h"
35 #include "softSession.h"
36 #include "softObject.h"
37 #include "softKeystore.h"
38 #include "softKeystoreUtil.h"
39
40 #pragma init(softtoken_init)
41 #pragma fini(softtoken_fini)
42
43 extern soft_session_t token_session; /* for fork handler */
44
45 static struct CK_FUNCTION_LIST functionList = {
113 C_CancelFunction,
114 C_WaitForSlotEvent
115 };
116
117 boolean_t softtoken_initialized = B_FALSE;
118
119 static pid_t softtoken_pid = 0;
120
121 /* This mutex protects soft_session_list, all_sessions_closing */
122 pthread_mutex_t soft_sessionlist_mutex;
123 soft_session_t *soft_session_list = NULL;
124
125 int all_sessions_closing = 0;
126
127 slot_t soft_slot;
128 obj_to_be_freed_list_t obj_delay_freed;
129 ses_to_be_freed_list_t ses_delay_freed;
130
131 /* protects softtoken_initialized and access to C_Initialize/C_Finalize */
132 pthread_mutex_t soft_giant_mutex = PTHREAD_MUTEX_INITIALIZER;
133 /*
134 * ONLY SET TO TRUE BY softtoken_fork_prepare().
135 * ONLY SET TO FALSE BY softtoken_fork_after().
136 */
137 boolean_t fork_prepared = B_FALSE;
138
139 static CK_RV finalize_common(boolean_t force, CK_VOID_PTR pReserved);
140 static void softtoken_init();
141 static void softtoken_fini();
142 static void softtoken_fork_prepare();
143 static void softtoken_fork_after();
144 static void softtoken_fork_after_droplocks(void);
145
146 CK_RV
147 C_Initialize(CK_VOID_PTR pInitArgs)
148 {
149
150 int initialize_pid;
151 boolean_t supplied_ok;
152 CK_RV rv;
153
154 /*
155 * Get lock to insure only one thread enters this
156 * function at a time.
157 */
158 (void) pthread_mutex_lock(&soft_giant_mutex);
159
160 initialize_pid = getpid();
161
162 if (softtoken_initialized) {
163 if (initialize_pid == softtoken_pid) {
164 /*
402 (void) pthread_mutex_destroy(&ses_delay_freed.ses_to_be_free_mutex);
403
404 return (rv);
405 }
406
407 static void
408 softtoken_init()
409 {
410 /* Children inherit parent's atfork handlers */
411 (void) pthread_atfork(softtoken_fork_prepare,
412 softtoken_fork_after, softtoken_fork_after);
413 }
414
415 /*
416 * softtoken_fini() function required to make sure complete cleanup
417 * is done if softtoken is ever unloaded without a C_Finalize() call.
418 */
419 static void
420 softtoken_fini()
421 {
422 int rc;
423
424 rc = pthread_mutex_trylock(&soft_giant_mutex);
425 /*
426 * Check to see if it was acquired by softtoken_fork_prepare().
427 */
428 if (rc == EBUSY && fork_prepared)
429 rc = 0;
430
431 if (rc != 0) {
432 /*
433 * I don't know WHAT just happened, but it's pretty bad. Grab
434 * the lock for real, even if it means deadlocking here.
435 */
436 (void) pthread_mutex_lock(&soft_giant_mutex);
437 } /* Else we acquired the lock and life is good. */
438
439 /* Only finalize if we're initialized. */
440 if (softtoken_initialized) {
441 /*
442 * We also have to DROP all of the other locks that
443 * softtoken_fork_prepare did IF it was prepared, because
444 * finalize_common() is going to pick them right back up.
445 */
446 if (fork_prepared)
447 softtoken_fork_after_droplocks();
448 (void) finalize_common(B_TRUE, NULL_PTR);
449 /* ASSERT(!softtoken_initialized); */
450 }
451
452 /*
453 * If we don't want to drop the lock, we assume softtoken_fork_after()
454 * will get called.
455 */
456 if (!fork_prepared)
457 (void) pthread_mutex_unlock(&soft_giant_mutex);
458 }
459
460 CK_RV
461 C_GetInfo(CK_INFO_PTR pInfo)
462 {
463 if (!softtoken_initialized)
464 return (CKR_CRYPTOKI_NOT_INITIALIZED);
465
466 if (pInfo == NULL) {
467 return (CKR_ARGUMENTS_BAD);
468 }
469
470 /* Provide general information in the provided buffer */
471 pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
472 pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
473 (void) strncpy((char *)pInfo->manufacturerID,
474 SOFT_MANUFACTURER_ID, 32);
475 pInfo->flags = 0;
476 (void) strncpy((char *)pInfo->libraryDescription,
512 CK_RV
513 C_CancelFunction(CK_SESSION_HANDLE hSession)
514 {
515 return (CKR_FUNCTION_NOT_PARALLEL);
516 }
517
518 /*
519 * Take out all mutexes before fork.
520 *
521 * Order:
522 * 1. soft_giant_mutex
523 * 2. soft_sessionlist_mutex
524 * 3. soft_slot.slot_mutex
525 * 4. soft_slot.keystore_mutex
526 * 5. token_session mutexes via soft_acquire_all_session_mutexes()
527 * 6. all soft_session_list mutexes via soft_acquire_all_session_mutexes()
528 * 7. obj_delay_freed.obj_to_be_free_mutex;
529 * 8. ses_delay_freed.ses_to_be_free_mutex
530 */
531 void
532 softtoken_fork_prepare(void)
533 {
534 (void) pthread_mutex_lock(&soft_giant_mutex);
535 if (softtoken_initialized) {
536 (void) pthread_mutex_lock(&soft_sessionlist_mutex);
537 (void) pthread_mutex_lock(&soft_slot.slot_mutex);
538 (void) pthread_mutex_lock(&soft_slot.keystore_mutex);
539 soft_acquire_all_session_mutexes(&token_session);
540 soft_acquire_all_session_mutexes(soft_session_list);
541 (void) pthread_mutex_lock(
542 &obj_delay_freed.obj_to_be_free_mutex);
543 (void) pthread_mutex_lock(
544 &ses_delay_freed.ses_to_be_free_mutex);
545 }
546 fork_prepared = B_TRUE;
547 }
548
549 static void
550 softtoken_fork_after_droplocks(void)
551 {
552 /* ASSERT(softtoken_initialized); */
553 (void) pthread_mutex_unlock(&ses_delay_freed.ses_to_be_free_mutex);
554 (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex);
555 soft_release_all_session_mutexes(soft_session_list);
556 soft_release_all_session_mutexes(&token_session);
557 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
558 (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
559 (void) pthread_mutex_unlock(&soft_sessionlist_mutex);
560 }
561
562 /*
563 * Release in opposite order to softtoken_fork_prepare().
564 * Function is used for parent and child.
565 */
566 void
567 softtoken_fork_after(void)
568 {
569 if (softtoken_initialized)
570 softtoken_fork_after_droplocks();
571 fork_prepared = B_FALSE;
572 (void) pthread_mutex_unlock(&soft_giant_mutex);
573 }
|