1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 /*
6 * instance.c
7 *
8 * This file implements the NSSCKFWInstance type and methods.
9 */
10
11 #ifndef CK_T
12 #include "ck.h"
13 #endif /* CK_T */
14
15 /*
16 * NSSCKFWInstance
17 *
18 * -- create/destroy --
19 * nssCKFWInstance_Create
20 * nssCKFWInstance_Destroy
21 *
22 * -- public accessors --
23 * NSSCKFWInstance_GetMDInstance
24 * NSSCKFWInstance_GetArena
25 * NSSCKFWInstance_MayCreatePthreads
26 * NSSCKFWInstance_CreateMutex
27 * NSSCKFWInstance_GetConfigurationData
28 * NSSCKFWInstance_GetInitArgs
29 * NSSCKFWInstance_DestroySessionHandle
30 * NSSCKFWInstance_FindSessionHandle
31 *
32 * -- implement public accessors --
33 * nssCKFWInstance_GetMDInstance
34 * nssCKFWInstance_GetArena
35 * nssCKFWInstance_MayCreatePthreads
36 * nssCKFWInstance_CreateMutex
37 * nssCKFWInstance_GetConfigurationData
38 * nssCKFWInstance_GetInitArgs
39 * nssCKFWInstance_DestroySessionHandle
40 * nssCKFWInstance_FindSessionHandle
41 *
42 * -- private accessors --
43 * nssCKFWInstance_CreateSessionHandle
44 * nssCKFWInstance_ResolveSessionHandle
45 * nssCKFWInstance_CreateObjectHandle
46 * nssCKFWInstance_ResolveObjectHandle
47 * nssCKFWInstance_DestroyObjectHandle
48 *
49 * -- module fronts --
50 * nssCKFWInstance_GetNSlots
51 * nssCKFWInstance_GetCryptokiVersion
52 * nssCKFWInstance_GetManufacturerID
53 * nssCKFWInstance_GetFlags
54 * nssCKFWInstance_GetLibraryDescription
55 * nssCKFWInstance_GetLibraryVersion
56 * nssCKFWInstance_GetModuleHandlesSessionObjects
57 * nssCKFWInstance_GetSlots
58 * nssCKFWInstance_WaitForSlotEvent
59 *
60 * -- debugging versions only --
61 * nssCKFWInstance_verifyPointer
62 */
63
64 struct NSSCKFWInstanceStr {
65 NSSCKFWMutex *mutex;
66 NSSArena *arena;
67 NSSCKMDInstance *mdInstance;
68 CK_C_INITIALIZE_ARGS_PTR pInitArgs;
69 CK_C_INITIALIZE_ARGS initArgs;
70 CryptokiLockingState LockingState;
71 CK_BBOOL mayCreatePthreads;
72 NSSUTF8 *configurationData;
73 CK_ULONG nSlots;
74 NSSCKFWSlot **fwSlotList;
75 NSSCKMDSlot **mdSlotList;
76 CK_BBOOL moduleHandlesSessionObjects;
77
78 /*
79 * Everything above is set at creation time, and then not modified.
80 * The invariants the mutex protects are:
81 *
82 * 1) Each of the cached descriptions (versions, etc.) are in an
83 * internally consistant state.
84 *
85 * 2) The session handle hashes and count are consistant
86 *
87 * 3) The object handle hashes and count are consistant.
88 *
89 * I could use multiple locks, but let's wait to see if that's
90 * really necessary.
91 *
92 * Note that the calls accessing the cached descriptions will
93 * call the NSSCKMDInstance methods with the mutex locked. Those
94 * methods may then call the public NSSCKFWInstance routines.
95 * Those public routines only access the constant data above, so
96 * there's no problem. But be careful if you add to this object;
97 * mutexes are in general not reentrant, so don't create deadlock
98 * situations.
99 */
100
101 CK_VERSION cryptokiVersion;
102 NSSUTF8 *manufacturerID;
103 NSSUTF8 *libraryDescription;
104 CK_VERSION libraryVersion;
105
106 CK_ULONG lastSessionHandle;
107 nssCKFWHash *sessionHandleHash;
108
109 CK_ULONG lastObjectHandle;
110 nssCKFWHash *objectHandleHash;
111 };
112
113 #ifdef DEBUG
114 /*
115 * But first, the pointer-tracking stuff.
116 *
117 * NOTE: the pointer-tracking support in NSS/base currently relies
118 * upon NSPR's CallOnce support. That, however, relies upon NSPR's
119 * locking, which is tied into the runtime. We need a pointer-tracker
120 * implementation that uses the locks supplied through C_Initialize.
121 * That support, however, can be filled in later. So for now, I'll
122 * just do this routines as no-ops.
123 */
124
125 static CK_RV
instance_add_pointer(const NSSCKFWInstance * fwInstance)126 instance_add_pointer(
127 const NSSCKFWInstance *fwInstance)
128 {
129 return CKR_OK;
130 }
131
132 static CK_RV
instance_remove_pointer(const NSSCKFWInstance * fwInstance)133 instance_remove_pointer(
134 const NSSCKFWInstance *fwInstance)
135 {
136 return CKR_OK;
137 }
138
139 NSS_IMPLEMENT CK_RV
nssCKFWInstance_verifyPointer(const NSSCKFWInstance * fwInstance)140 nssCKFWInstance_verifyPointer(
141 const NSSCKFWInstance *fwInstance)
142 {
143 return CKR_OK;
144 }
145
146 #endif /* DEBUG */
147
148 /*
149 * nssCKFWInstance_Create
150 *
151 */
152 NSS_IMPLEMENT NSSCKFWInstance *
nssCKFWInstance_Create(CK_C_INITIALIZE_ARGS_PTR pInitArgs,CryptokiLockingState LockingState,NSSCKMDInstance * mdInstance,CK_RV * pError)153 nssCKFWInstance_Create(
154 CK_C_INITIALIZE_ARGS_PTR pInitArgs,
155 CryptokiLockingState LockingState,
156 NSSCKMDInstance *mdInstance,
157 CK_RV *pError)
158 {
159 NSSCKFWInstance *fwInstance;
160 NSSArena *arena = (NSSArena *)NULL;
161 CK_ULONG i;
162 CK_BBOOL called_Initialize = CK_FALSE;
163
164 #ifdef NSSDEBUG
165 if ((CK_RV)NULL == pError) {
166 return (NSSCKFWInstance *)NULL;
167 }
168
169 if (!mdInstance) {
170 *pError = CKR_ARGUMENTS_BAD;
171 return (NSSCKFWInstance *)NULL;
172 }
173 #endif /* NSSDEBUG */
174
175 arena = NSSArena_Create();
176 if (!arena) {
177 *pError = CKR_HOST_MEMORY;
178 return (NSSCKFWInstance *)NULL;
179 }
180
181 fwInstance = nss_ZNEW(arena, NSSCKFWInstance);
182 if (!fwInstance) {
183 goto nomem;
184 }
185
186 fwInstance->arena = arena;
187 fwInstance->mdInstance = mdInstance;
188
189 fwInstance->LockingState = LockingState;
190 if ((CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs) {
191 fwInstance->initArgs = *pInitArgs;
192 fwInstance->pInitArgs = &fwInstance->initArgs;
193 if (pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
194 fwInstance->mayCreatePthreads = CK_FALSE;
195 } else {
196 fwInstance->mayCreatePthreads = CK_TRUE;
197 }
198 fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved);
199 } else {
200 fwInstance->mayCreatePthreads = CK_TRUE;
201 }
202
203 fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, LockingState, arena,
204 pError);
205 if (!fwInstance->mutex) {
206 if (CKR_OK == *pError) {
207 *pError = CKR_GENERAL_ERROR;
208 }
209 goto loser;
210 }
211
212 if (mdInstance->Initialize) {
213 *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData);
214 if (CKR_OK != *pError) {
215 goto loser;
216 }
217
218 called_Initialize = CK_TRUE;
219 }
220
221 if (mdInstance->ModuleHandlesSessionObjects) {
222 fwInstance->moduleHandlesSessionObjects =
223 mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);
224 } else {
225 fwInstance->moduleHandlesSessionObjects = CK_FALSE;
226 }
227
228 if (!mdInstance->GetNSlots) {
229 /* That routine is required */
230 *pError = CKR_GENERAL_ERROR;
231 goto loser;
232 }
233
234 fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError);
235 if ((CK_ULONG)0 == fwInstance->nSlots) {
236 if (CKR_OK == *pError) {
237 /* Zero is not a legitimate answer */
238 *pError = CKR_GENERAL_ERROR;
239 }
240 goto loser;
241 }
242
243 fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots);
244 if ((NSSCKFWSlot **)NULL == fwInstance->fwSlotList) {
245 goto nomem;
246 }
247
248 fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots);
249 if ((NSSCKMDSlot **)NULL == fwInstance->mdSlotList) {
250 goto nomem;
251 }
252
253 fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance,
254 fwInstance->arena, pError);
255 if (!fwInstance->sessionHandleHash) {
256 goto loser;
257 }
258
259 fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance,
260 fwInstance->arena, pError);
261 if (!fwInstance->objectHandleHash) {
262 goto loser;
263 }
264
265 if (!mdInstance->GetSlots) {
266 /* That routine is required */
267 *pError = CKR_GENERAL_ERROR;
268 goto loser;
269 }
270
271 *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList);
272 if (CKR_OK != *pError) {
273 goto loser;
274 }
275
276 for (i = 0; i < fwInstance->nSlots; i++) {
277 NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i];
278
279 if (!mdSlot) {
280 *pError = CKR_GENERAL_ERROR;
281 goto loser;
282 }
283
284 fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError);
285 if (CKR_OK != *pError) {
286 CK_ULONG j;
287
288 for (j = 0; j < i; j++) {
289 (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]);
290 }
291
292 for (j = i; j < fwInstance->nSlots; j++) {
293 NSSCKMDSlot *mds = fwInstance->mdSlotList[j];
294 if (mds->Destroy) {
295 mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance);
296 }
297 }
298
299 goto loser;
300 }
301 }
302
303 #ifdef DEBUG
304 *pError = instance_add_pointer(fwInstance);
305 if (CKR_OK != *pError) {
306 for (i = 0; i < fwInstance->nSlots; i++) {
307 (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
308 }
309
310 goto loser;
311 }
312 #endif /* DEBUG */
313
314 *pError = CKR_OK;
315 return fwInstance;
316
317 nomem:
318 *pError = CKR_HOST_MEMORY;
319 /*FALLTHROUGH*/
320 loser:
321
322 if (CK_TRUE == called_Initialize) {
323 if (mdInstance->Finalize) {
324 mdInstance->Finalize(mdInstance, fwInstance);
325 }
326 }
327
328 if (fwInstance && fwInstance->mutex) {
329 nssCKFWMutex_Destroy(fwInstance->mutex);
330 }
331
332 if (arena) {
333 (void)NSSArena_Destroy(arena);
334 }
335 return (NSSCKFWInstance *)NULL;
336 }
337
338 /*
339 * nssCKFWInstance_Destroy
340 *
341 */
342 NSS_IMPLEMENT CK_RV
nssCKFWInstance_Destroy(NSSCKFWInstance * fwInstance)343 nssCKFWInstance_Destroy(
344 NSSCKFWInstance *fwInstance)
345 {
346 #ifdef NSSDEBUG
347 CK_RV error = CKR_OK;
348 #endif /* NSSDEBUG */
349 CK_ULONG i;
350
351 #ifdef NSSDEBUG
352 error = nssCKFWInstance_verifyPointer(fwInstance);
353 if (CKR_OK != error) {
354 return error;
355 }
356 #endif /* NSSDEBUG */
357
358 nssCKFWMutex_Destroy(fwInstance->mutex);
359
360 for (i = 0; i < fwInstance->nSlots; i++) {
361 (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
362 }
363
364 if (fwInstance->mdInstance->Finalize) {
365 fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance);
366 }
367
368 if (fwInstance->sessionHandleHash) {
369 nssCKFWHash_Destroy(fwInstance->sessionHandleHash);
370 }
371
372 if (fwInstance->objectHandleHash) {
373 nssCKFWHash_Destroy(fwInstance->objectHandleHash);
374 }
375
376 #ifdef DEBUG
377 (void)instance_remove_pointer(fwInstance);
378 #endif /* DEBUG */
379
380 (void)NSSArena_Destroy(fwInstance->arena);
381 return CKR_OK;
382 }
383
384 /*
385 * nssCKFWInstance_GetMDInstance
386 *
387 */
388 NSS_IMPLEMENT NSSCKMDInstance *
nssCKFWInstance_GetMDInstance(NSSCKFWInstance * fwInstance)389 nssCKFWInstance_GetMDInstance(
390 NSSCKFWInstance *fwInstance)
391 {
392 #ifdef NSSDEBUG
393 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
394 return (NSSCKMDInstance *)NULL;
395 }
396 #endif /* NSSDEBUG */
397
398 return fwInstance->mdInstance;
399 }
400
401 /*
402 * nssCKFWInstance_GetArena
403 *
404 */
405 NSS_IMPLEMENT NSSArena *
nssCKFWInstance_GetArena(NSSCKFWInstance * fwInstance,CK_RV * pError)406 nssCKFWInstance_GetArena(
407 NSSCKFWInstance *fwInstance,
408 CK_RV *pError)
409 {
410 #ifdef NSSDEBUG
411 if (!pError) {
412 return (NSSArena *)NULL;
413 }
414
415 *pError = nssCKFWInstance_verifyPointer(fwInstance);
416 if (CKR_OK != *pError) {
417 return (NSSArena *)NULL;
418 }
419 #endif /* NSSDEBUG */
420
421 *pError = CKR_OK;
422 return fwInstance->arena;
423 }
424
425 /*
426 * nssCKFWInstance_MayCreatePthreads
427 *
428 */
429 NSS_IMPLEMENT CK_BBOOL
nssCKFWInstance_MayCreatePthreads(NSSCKFWInstance * fwInstance)430 nssCKFWInstance_MayCreatePthreads(
431 NSSCKFWInstance *fwInstance)
432 {
433 #ifdef NSSDEBUG
434 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
435 return CK_FALSE;
436 }
437 #endif /* NSSDEBUG */
438
439 return fwInstance->mayCreatePthreads;
440 }
441
442 /*
443 * nssCKFWInstance_CreateMutex
444 *
445 */
446 NSS_IMPLEMENT NSSCKFWMutex *
nssCKFWInstance_CreateMutex(NSSCKFWInstance * fwInstance,NSSArena * arena,CK_RV * pError)447 nssCKFWInstance_CreateMutex(
448 NSSCKFWInstance *fwInstance,
449 NSSArena *arena,
450 CK_RV *pError)
451 {
452 NSSCKFWMutex *mutex;
453
454 #ifdef NSSDEBUG
455 if (!pError) {
456 return (NSSCKFWMutex *)NULL;
457 }
458
459 *pError = nssCKFWInstance_verifyPointer(fwInstance);
460 if (CKR_OK != *pError) {
461 return (NSSCKFWMutex *)NULL;
462 }
463 #endif /* NSSDEBUG */
464
465 mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, fwInstance->LockingState,
466 arena, pError);
467 if (!mutex) {
468 if (CKR_OK == *pError) {
469 *pError = CKR_GENERAL_ERROR;
470 }
471
472 return (NSSCKFWMutex *)NULL;
473 }
474
475 return mutex;
476 }
477
478 /*
479 * nssCKFWInstance_GetConfigurationData
480 *
481 */
482 NSS_IMPLEMENT NSSUTF8 *
nssCKFWInstance_GetConfigurationData(NSSCKFWInstance * fwInstance)483 nssCKFWInstance_GetConfigurationData(
484 NSSCKFWInstance *fwInstance)
485 {
486 #ifdef NSSDEBUG
487 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
488 return (NSSUTF8 *)NULL;
489 }
490 #endif /* NSSDEBUG */
491
492 return fwInstance->configurationData;
493 }
494
495 /*
496 * nssCKFWInstance_GetInitArgs
497 *
498 */
499 CK_C_INITIALIZE_ARGS_PTR
nssCKFWInstance_GetInitArgs(NSSCKFWInstance * fwInstance)500 nssCKFWInstance_GetInitArgs(
501 NSSCKFWInstance *fwInstance)
502 {
503 #ifdef NSSDEBUG
504 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
505 return (CK_C_INITIALIZE_ARGS_PTR)NULL;
506 }
507 #endif /* NSSDEBUG */
508
509 return fwInstance->pInitArgs;
510 }
511
512 /*
513 * nssCKFWInstance_CreateSessionHandle
514 *
515 */
516 NSS_IMPLEMENT CK_SESSION_HANDLE
nssCKFWInstance_CreateSessionHandle(NSSCKFWInstance * fwInstance,NSSCKFWSession * fwSession,CK_RV * pError)517 nssCKFWInstance_CreateSessionHandle(
518 NSSCKFWInstance *fwInstance,
519 NSSCKFWSession *fwSession,
520 CK_RV *pError)
521 {
522 CK_SESSION_HANDLE hSession;
523
524 #ifdef NSSDEBUG
525 if (!pError) {
526 return (CK_SESSION_HANDLE)0;
527 }
528
529 *pError = nssCKFWInstance_verifyPointer(fwInstance);
530 if (CKR_OK != *pError) {
531 return (CK_SESSION_HANDLE)0;
532 }
533 #endif /* NSSDEBUG */
534
535 *pError = nssCKFWMutex_Lock(fwInstance->mutex);
536 if (CKR_OK != *pError) {
537 return (CK_SESSION_HANDLE)0;
538 }
539
540 hSession = ++(fwInstance->lastSessionHandle);
541
542 /* Alan would say I should unlock for this call. */
543
544 *pError = nssCKFWSession_SetHandle(fwSession, hSession);
545 if (CKR_OK != *pError) {
546 goto done;
547 }
548
549 *pError = nssCKFWHash_Add(fwInstance->sessionHandleHash,
550 (const void *)hSession, (const void *)fwSession);
551 if (CKR_OK != *pError) {
552 hSession = (CK_SESSION_HANDLE)0;
553 goto done;
554 }
555
556 done:
557 nssCKFWMutex_Unlock(fwInstance->mutex);
558 return hSession;
559 }
560
561 /*
562 * nssCKFWInstance_ResolveSessionHandle
563 *
564 */
565 NSS_IMPLEMENT NSSCKFWSession *
nssCKFWInstance_ResolveSessionHandle(NSSCKFWInstance * fwInstance,CK_SESSION_HANDLE hSession)566 nssCKFWInstance_ResolveSessionHandle(
567 NSSCKFWInstance *fwInstance,
568 CK_SESSION_HANDLE hSession)
569 {
570 NSSCKFWSession *fwSession;
571
572 #ifdef NSSDEBUG
573 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
574 return (NSSCKFWSession *)NULL;
575 }
576 #endif /* NSSDEBUG */
577
578 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
579 return (NSSCKFWSession *)NULL;
580 }
581
582 fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
583 fwInstance->sessionHandleHash, (const void *)hSession);
584
585 /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */
586
587 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
588
589 return fwSession;
590 }
591
592 /*
593 * nssCKFWInstance_DestroySessionHandle
594 *
595 */
596 NSS_IMPLEMENT void
nssCKFWInstance_DestroySessionHandle(NSSCKFWInstance * fwInstance,CK_SESSION_HANDLE hSession)597 nssCKFWInstance_DestroySessionHandle(
598 NSSCKFWInstance *fwInstance,
599 CK_SESSION_HANDLE hSession)
600 {
601 NSSCKFWSession *fwSession;
602
603 #ifdef NSSDEBUG
604 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
605 return;
606 }
607 #endif /* NSSDEBUG */
608
609 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
610 return;
611 }
612
613 fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
614 fwInstance->sessionHandleHash, (const void *)hSession);
615 if (fwSession) {
616 nssCKFWHash_Remove(fwInstance->sessionHandleHash, (const void *)hSession);
617 nssCKFWSession_SetHandle(fwSession, (CK_SESSION_HANDLE)0);
618 }
619
620 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
621
622 return;
623 }
624
625 /*
626 * nssCKFWInstance_FindSessionHandle
627 *
628 */
629 NSS_IMPLEMENT CK_SESSION_HANDLE
nssCKFWInstance_FindSessionHandle(NSSCKFWInstance * fwInstance,NSSCKFWSession * fwSession)630 nssCKFWInstance_FindSessionHandle(
631 NSSCKFWInstance *fwInstance,
632 NSSCKFWSession *fwSession)
633 {
634 #ifdef NSSDEBUG
635 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
636 return (CK_SESSION_HANDLE)0;
637 }
638
639 if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
640 return (CK_SESSION_HANDLE)0;
641 }
642 #endif /* NSSDEBUG */
643
644 return nssCKFWSession_GetHandle(fwSession);
645 /* look it up and assert? */
646 }
647
648 /*
649 * nssCKFWInstance_CreateObjectHandle
650 *
651 */
652 NSS_IMPLEMENT CK_OBJECT_HANDLE
nssCKFWInstance_CreateObjectHandle(NSSCKFWInstance * fwInstance,NSSCKFWObject * fwObject,CK_RV * pError)653 nssCKFWInstance_CreateObjectHandle(
654 NSSCKFWInstance *fwInstance,
655 NSSCKFWObject *fwObject,
656 CK_RV *pError)
657 {
658 CK_OBJECT_HANDLE hObject;
659
660 #ifdef NSSDEBUG
661 if (!pError) {
662 return (CK_OBJECT_HANDLE)0;
663 }
664
665 *pError = nssCKFWInstance_verifyPointer(fwInstance);
666 if (CKR_OK != *pError) {
667 return (CK_OBJECT_HANDLE)0;
668 }
669 #endif /* NSSDEBUG */
670
671 *pError = nssCKFWMutex_Lock(fwInstance->mutex);
672 if (CKR_OK != *pError) {
673 return (CK_OBJECT_HANDLE)0;
674 }
675
676 hObject = ++(fwInstance->lastObjectHandle);
677
678 *pError = nssCKFWObject_SetHandle(fwObject, hObject);
679 if (CKR_OK != *pError) {
680 hObject = (CK_OBJECT_HANDLE)0;
681 goto done;
682 }
683
684 *pError = nssCKFWHash_Add(fwInstance->objectHandleHash,
685 (const void *)hObject, (const void *)fwObject);
686 if (CKR_OK != *pError) {
687 hObject = (CK_OBJECT_HANDLE)0;
688 goto done;
689 }
690
691 done:
692 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
693 return hObject;
694 }
695
696 /*
697 * nssCKFWInstance_ResolveObjectHandle
698 *
699 */
700 NSS_IMPLEMENT NSSCKFWObject *
nssCKFWInstance_ResolveObjectHandle(NSSCKFWInstance * fwInstance,CK_OBJECT_HANDLE hObject)701 nssCKFWInstance_ResolveObjectHandle(
702 NSSCKFWInstance *fwInstance,
703 CK_OBJECT_HANDLE hObject)
704 {
705 NSSCKFWObject *fwObject;
706
707 #ifdef NSSDEBUG
708 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
709 return (NSSCKFWObject *)NULL;
710 }
711 #endif /* NSSDEBUG */
712
713 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
714 return (NSSCKFWObject *)NULL;
715 }
716
717 fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
718 fwInstance->objectHandleHash, (const void *)hObject);
719
720 /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */
721
722 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
723 return fwObject;
724 }
725
726 /*
727 * nssCKFWInstance_ReassignObjectHandle
728 *
729 */
730 NSS_IMPLEMENT CK_RV
nssCKFWInstance_ReassignObjectHandle(NSSCKFWInstance * fwInstance,CK_OBJECT_HANDLE hObject,NSSCKFWObject * fwObject)731 nssCKFWInstance_ReassignObjectHandle(
732 NSSCKFWInstance *fwInstance,
733 CK_OBJECT_HANDLE hObject,
734 NSSCKFWObject *fwObject)
735 {
736 CK_RV error = CKR_OK;
737 NSSCKFWObject *oldObject;
738
739 #ifdef NSSDEBUG
740 error = nssCKFWInstance_verifyPointer(fwInstance);
741 if (CKR_OK != error) {
742 return error;
743 }
744 #endif /* NSSDEBUG */
745
746 error = nssCKFWMutex_Lock(fwInstance->mutex);
747 if (CKR_OK != error) {
748 return error;
749 }
750
751 oldObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
752 fwInstance->objectHandleHash, (const void *)hObject);
753 if (oldObject) {
754 /* Assert(hObject == nssCKFWObject_GetHandle(oldObject) */
755 (void)nssCKFWObject_SetHandle(oldObject, (CK_SESSION_HANDLE)0);
756 nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
757 }
758
759 error = nssCKFWObject_SetHandle(fwObject, hObject);
760 if (CKR_OK != error) {
761 goto done;
762 }
763 error = nssCKFWHash_Add(fwInstance->objectHandleHash,
764 (const void *)hObject, (const void *)fwObject);
765
766 done:
767 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
768 return error;
769 }
770
771 /*
772 * nssCKFWInstance_DestroyObjectHandle
773 *
774 */
775 NSS_IMPLEMENT void
nssCKFWInstance_DestroyObjectHandle(NSSCKFWInstance * fwInstance,CK_OBJECT_HANDLE hObject)776 nssCKFWInstance_DestroyObjectHandle(
777 NSSCKFWInstance *fwInstance,
778 CK_OBJECT_HANDLE hObject)
779 {
780 NSSCKFWObject *fwObject;
781
782 #ifdef NSSDEBUG
783 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
784 return;
785 }
786 #endif /* NSSDEBUG */
787
788 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
789 return;
790 }
791
792 fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
793 fwInstance->objectHandleHash, (const void *)hObject);
794 if (fwObject) {
795 /* Assert(hObject = nssCKFWObject_GetHandle(fwObject)) */
796 nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
797 (void)nssCKFWObject_SetHandle(fwObject, (CK_SESSION_HANDLE)0);
798 }
799
800 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
801 return;
802 }
803
804 /*
805 * nssCKFWInstance_FindObjectHandle
806 *
807 */
808 NSS_IMPLEMENT CK_OBJECT_HANDLE
nssCKFWInstance_FindObjectHandle(NSSCKFWInstance * fwInstance,NSSCKFWObject * fwObject)809 nssCKFWInstance_FindObjectHandle(
810 NSSCKFWInstance *fwInstance,
811 NSSCKFWObject *fwObject)
812 {
813 #ifdef NSSDEBUG
814 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
815 return (CK_OBJECT_HANDLE)0;
816 }
817
818 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
819 return (CK_OBJECT_HANDLE)0;
820 }
821 #endif /* NSSDEBUG */
822
823 return nssCKFWObject_GetHandle(fwObject);
824 }
825
826 /*
827 * nssCKFWInstance_GetNSlots
828 *
829 */
830 NSS_IMPLEMENT CK_ULONG
nssCKFWInstance_GetNSlots(NSSCKFWInstance * fwInstance,CK_RV * pError)831 nssCKFWInstance_GetNSlots(
832 NSSCKFWInstance *fwInstance,
833 CK_RV *pError)
834 {
835 #ifdef NSSDEBUG
836 if (!pError) {
837 return (CK_ULONG)0;
838 }
839
840 *pError = nssCKFWInstance_verifyPointer(fwInstance);
841 if (CKR_OK != *pError) {
842 return (CK_ULONG)0;
843 }
844 #endif /* NSSDEBUG */
845
846 *pError = CKR_OK;
847 return fwInstance->nSlots;
848 }
849
850 /*
851 * nssCKFWInstance_GetCryptokiVersion
852 *
853 */
854 NSS_IMPLEMENT CK_VERSION
nssCKFWInstance_GetCryptokiVersion(NSSCKFWInstance * fwInstance)855 nssCKFWInstance_GetCryptokiVersion(
856 NSSCKFWInstance *fwInstance)
857 {
858 CK_VERSION rv;
859
860 #ifdef NSSDEBUG
861 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
862 rv.major = rv.minor = 0;
863 return rv;
864 }
865 #endif /* NSSDEBUG */
866
867 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
868 rv.major = rv.minor = 0;
869 return rv;
870 }
871
872 if ((0 != fwInstance->cryptokiVersion.major) ||
873 (0 != fwInstance->cryptokiVersion.minor)) {
874 rv = fwInstance->cryptokiVersion;
875 goto done;
876 }
877
878 if (fwInstance->mdInstance->GetCryptokiVersion) {
879 fwInstance->cryptokiVersion = fwInstance->mdInstance->GetCryptokiVersion(
880 fwInstance->mdInstance, fwInstance);
881 } else {
882 fwInstance->cryptokiVersion.major = 2;
883 fwInstance->cryptokiVersion.minor = 1;
884 }
885
886 rv = fwInstance->cryptokiVersion;
887
888 done:
889 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
890 return rv;
891 }
892
893 /*
894 * nssCKFWInstance_GetManufacturerID
895 *
896 */
897 NSS_IMPLEMENT CK_RV
nssCKFWInstance_GetManufacturerID(NSSCKFWInstance * fwInstance,CK_CHAR manufacturerID[32])898 nssCKFWInstance_GetManufacturerID(
899 NSSCKFWInstance *fwInstance,
900 CK_CHAR manufacturerID[32])
901 {
902 CK_RV error = CKR_OK;
903
904 #ifdef NSSDEBUG
905 if ((CK_CHAR_PTR)NULL == manufacturerID) {
906 return CKR_ARGUMENTS_BAD;
907 }
908
909 error = nssCKFWInstance_verifyPointer(fwInstance);
910 if (CKR_OK != error) {
911 return error;
912 }
913 #endif /* NSSDEBUG */
914
915 error = nssCKFWMutex_Lock(fwInstance->mutex);
916 if (CKR_OK != error) {
917 return error;
918 }
919
920 if (!fwInstance->manufacturerID) {
921 if (fwInstance->mdInstance->GetManufacturerID) {
922 fwInstance->manufacturerID = fwInstance->mdInstance->GetManufacturerID(
923 fwInstance->mdInstance, fwInstance, &error);
924 if ((!fwInstance->manufacturerID) && (CKR_OK != error)) {
925 goto done;
926 }
927 } else {
928 fwInstance->manufacturerID = (NSSUTF8 *)"";
929 }
930 }
931
932 (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, (char *)manufacturerID, 32, ' ');
933 error = CKR_OK;
934
935 done:
936 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
937 return error;
938 }
939
940 /*
941 * nssCKFWInstance_GetFlags
942 *
943 */
944 NSS_IMPLEMENT CK_ULONG
nssCKFWInstance_GetFlags(NSSCKFWInstance * fwInstance)945 nssCKFWInstance_GetFlags(
946 NSSCKFWInstance *fwInstance)
947 {
948 #ifdef NSSDEBUG
949 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
950 return (CK_ULONG)0;
951 }
952 #endif /* NSSDEBUG */
953
954 /* No "instance flags" are yet defined by Cryptoki. */
955 return (CK_ULONG)0;
956 }
957
958 /*
959 * nssCKFWInstance_GetLibraryDescription
960 *
961 */
962 NSS_IMPLEMENT CK_RV
nssCKFWInstance_GetLibraryDescription(NSSCKFWInstance * fwInstance,CK_CHAR libraryDescription[32])963 nssCKFWInstance_GetLibraryDescription(
964 NSSCKFWInstance *fwInstance,
965 CK_CHAR libraryDescription[32])
966 {
967 CK_RV error = CKR_OK;
968
969 #ifdef NSSDEBUG
970 if ((CK_CHAR_PTR)NULL == libraryDescription) {
971 return CKR_ARGUMENTS_BAD;
972 }
973
974 error = nssCKFWInstance_verifyPointer(fwInstance);
975 if (CKR_OK != error) {
976 return error;
977 }
978 #endif /* NSSDEBUG */
979
980 error = nssCKFWMutex_Lock(fwInstance->mutex);
981 if (CKR_OK != error) {
982 return error;
983 }
984
985 if (!fwInstance->libraryDescription) {
986 if (fwInstance->mdInstance->GetLibraryDescription) {
987 fwInstance->libraryDescription = fwInstance->mdInstance->GetLibraryDescription(
988 fwInstance->mdInstance, fwInstance, &error);
989 if ((!fwInstance->libraryDescription) && (CKR_OK != error)) {
990 goto done;
991 }
992 } else {
993 fwInstance->libraryDescription = (NSSUTF8 *)"";
994 }
995 }
996
997 (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, (char *)libraryDescription, 32, ' ');
998 error = CKR_OK;
999
1000 done:
1001 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
1002 return error;
1003 }
1004
1005 /*
1006 * nssCKFWInstance_GetLibraryVersion
1007 *
1008 */
1009 NSS_IMPLEMENT CK_VERSION
nssCKFWInstance_GetLibraryVersion(NSSCKFWInstance * fwInstance)1010 nssCKFWInstance_GetLibraryVersion(
1011 NSSCKFWInstance *fwInstance)
1012 {
1013 CK_VERSION rv;
1014
1015 #ifdef NSSDEBUG
1016 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
1017 rv.major = rv.minor = 0;
1018 return rv;
1019 }
1020 #endif /* NSSDEBUG */
1021
1022 if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
1023 rv.major = rv.minor = 0;
1024 return rv;
1025 }
1026
1027 if ((0 != fwInstance->libraryVersion.major) ||
1028 (0 != fwInstance->libraryVersion.minor)) {
1029 rv = fwInstance->libraryVersion;
1030 goto done;
1031 }
1032
1033 if (fwInstance->mdInstance->GetLibraryVersion) {
1034 fwInstance->libraryVersion = fwInstance->mdInstance->GetLibraryVersion(
1035 fwInstance->mdInstance, fwInstance);
1036 } else {
1037 fwInstance->libraryVersion.major = 0;
1038 fwInstance->libraryVersion.minor = 3;
1039 }
1040
1041 rv = fwInstance->libraryVersion;
1042 done:
1043 (void)nssCKFWMutex_Unlock(fwInstance->mutex);
1044 return rv;
1045 }
1046
1047 /*
1048 * nssCKFWInstance_GetModuleHandlesSessionObjects
1049 *
1050 */
1051 NSS_IMPLEMENT CK_BBOOL
nssCKFWInstance_GetModuleHandlesSessionObjects(NSSCKFWInstance * fwInstance)1052 nssCKFWInstance_GetModuleHandlesSessionObjects(
1053 NSSCKFWInstance *fwInstance)
1054 {
1055 #ifdef NSSDEBUG
1056 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
1057 return CK_FALSE;
1058 }
1059 #endif /* NSSDEBUG */
1060
1061 return fwInstance->moduleHandlesSessionObjects;
1062 }
1063
1064 /*
1065 * nssCKFWInstance_GetSlots
1066 *
1067 */
1068 NSS_IMPLEMENT NSSCKFWSlot **
nssCKFWInstance_GetSlots(NSSCKFWInstance * fwInstance,CK_RV * pError)1069 nssCKFWInstance_GetSlots(
1070 NSSCKFWInstance *fwInstance,
1071 CK_RV *pError)
1072 {
1073 #ifdef NSSDEBUG
1074 if (!pError) {
1075 return (NSSCKFWSlot **)NULL;
1076 }
1077
1078 *pError = nssCKFWInstance_verifyPointer(fwInstance);
1079 if (CKR_OK != *pError) {
1080 return (NSSCKFWSlot **)NULL;
1081 }
1082 #endif /* NSSDEBUG */
1083
1084 return fwInstance->fwSlotList;
1085 }
1086
1087 /*
1088 * nssCKFWInstance_WaitForSlotEvent
1089 *
1090 */
1091 NSS_IMPLEMENT NSSCKFWSlot *
nssCKFWInstance_WaitForSlotEvent(NSSCKFWInstance * fwInstance,CK_BBOOL block,CK_RV * pError)1092 nssCKFWInstance_WaitForSlotEvent(
1093 NSSCKFWInstance *fwInstance,
1094 CK_BBOOL block,
1095 CK_RV *pError)
1096 {
1097 NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL;
1098 NSSCKMDSlot *mdSlot;
1099 CK_ULONG i, n;
1100
1101 #ifdef NSSDEBUG
1102 if (!pError) {
1103 return (NSSCKFWSlot *)NULL;
1104 }
1105
1106 *pError = nssCKFWInstance_verifyPointer(fwInstance);
1107 if (CKR_OK != *pError) {
1108 return (NSSCKFWSlot *)NULL;
1109 }
1110
1111 switch (block) {
1112 case CK_TRUE:
1113 case CK_FALSE:
1114 break;
1115 default:
1116 *pError = CKR_ARGUMENTS_BAD;
1117 return (NSSCKFWSlot *)NULL;
1118 }
1119 #endif /* NSSDEBUG */
1120
1121 if (!fwInstance->mdInstance->WaitForSlotEvent) {
1122 *pError = CKR_NO_EVENT;
1123 return (NSSCKFWSlot *)NULL;
1124 }
1125
1126 mdSlot = fwInstance->mdInstance->WaitForSlotEvent(
1127 fwInstance->mdInstance,
1128 fwInstance,
1129 block,
1130 pError);
1131
1132 if (!mdSlot) {
1133 return (NSSCKFWSlot *)NULL;
1134 }
1135
1136 n = nssCKFWInstance_GetNSlots(fwInstance, pError);
1137 if (((CK_ULONG)0 == n) && (CKR_OK != *pError)) {
1138 return (NSSCKFWSlot *)NULL;
1139 }
1140
1141 for (i = 0; i < n; i++) {
1142 if (fwInstance->mdSlotList[i] == mdSlot) {
1143 fwSlot = fwInstance->fwSlotList[i];
1144 break;
1145 }
1146 }
1147
1148 if (!fwSlot) {
1149 /* Internal error */
1150 *pError = CKR_GENERAL_ERROR;
1151 return (NSSCKFWSlot *)NULL;
1152 }
1153
1154 return fwSlot;
1155 }
1156
1157 /*
1158 * NSSCKFWInstance_GetMDInstance
1159 *
1160 */
1161 NSS_IMPLEMENT NSSCKMDInstance *
NSSCKFWInstance_GetMDInstance(NSSCKFWInstance * fwInstance)1162 NSSCKFWInstance_GetMDInstance(
1163 NSSCKFWInstance *fwInstance)
1164 {
1165 #ifdef DEBUG
1166 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
1167 return (NSSCKMDInstance *)NULL;
1168 }
1169 #endif /* DEBUG */
1170
1171 return nssCKFWInstance_GetMDInstance(fwInstance);
1172 }
1173
1174 /*
1175 * NSSCKFWInstance_GetArena
1176 *
1177 */
1178 NSS_IMPLEMENT NSSArena *
NSSCKFWInstance_GetArena(NSSCKFWInstance * fwInstance,CK_RV * pError)1179 NSSCKFWInstance_GetArena(
1180 NSSCKFWInstance *fwInstance,
1181 CK_RV *pError)
1182 {
1183 #ifdef DEBUG
1184 if (!pError) {
1185 return (NSSArena *)NULL;
1186 }
1187
1188 *pError = nssCKFWInstance_verifyPointer(fwInstance);
1189 if (CKR_OK != *pError) {
1190 return (NSSArena *)NULL;
1191 }
1192 #endif /* DEBUG */
1193
1194 return nssCKFWInstance_GetArena(fwInstance, pError);
1195 }
1196
1197 /*
1198 * NSSCKFWInstance_MayCreatePthreads
1199 *
1200 */
1201 NSS_IMPLEMENT CK_BBOOL
NSSCKFWInstance_MayCreatePthreads(NSSCKFWInstance * fwInstance)1202 NSSCKFWInstance_MayCreatePthreads(
1203 NSSCKFWInstance *fwInstance)
1204 {
1205 #ifdef DEBUG
1206 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
1207 return CK_FALSE;
1208 }
1209 #endif /* DEBUG */
1210
1211 return nssCKFWInstance_MayCreatePthreads(fwInstance);
1212 }
1213
1214 /*
1215 * NSSCKFWInstance_CreateMutex
1216 *
1217 */
1218 NSS_IMPLEMENT NSSCKFWMutex *
NSSCKFWInstance_CreateMutex(NSSCKFWInstance * fwInstance,NSSArena * arena,CK_RV * pError)1219 NSSCKFWInstance_CreateMutex(
1220 NSSCKFWInstance *fwInstance,
1221 NSSArena *arena,
1222 CK_RV *pError)
1223 {
1224 #ifdef DEBUG
1225 if (!pError) {
1226 return (NSSCKFWMutex *)NULL;
1227 }
1228
1229 *pError = nssCKFWInstance_verifyPointer(fwInstance);
1230 if (CKR_OK != *pError) {
1231 return (NSSCKFWMutex *)NULL;
1232 }
1233 #endif /* DEBUG */
1234
1235 return nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
1236 }
1237
1238 /*
1239 * NSSCKFWInstance_GetConfigurationData
1240 *
1241 */
1242 NSS_IMPLEMENT NSSUTF8 *
NSSCKFWInstance_GetConfigurationData(NSSCKFWInstance * fwInstance)1243 NSSCKFWInstance_GetConfigurationData(
1244 NSSCKFWInstance *fwInstance)
1245 {
1246 #ifdef DEBUG
1247 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
1248 return (NSSUTF8 *)NULL;
1249 }
1250 #endif /* DEBUG */
1251
1252 return nssCKFWInstance_GetConfigurationData(fwInstance);
1253 }
1254
1255 /*
1256 * NSSCKFWInstance_GetInitArgs
1257 *
1258 */
1259 NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR
NSSCKFWInstance_GetInitArgs(NSSCKFWInstance * fwInstance)1260 NSSCKFWInstance_GetInitArgs(
1261 NSSCKFWInstance *fwInstance)
1262 {
1263 #ifdef DEBUG
1264 if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
1265 return (CK_C_INITIALIZE_ARGS_PTR)NULL;
1266 }
1267 #endif /* DEBUG */
1268
1269 return nssCKFWInstance_GetInitArgs(fwInstance);
1270 }
1271
1272 /*
1273 * nssCKFWInstance_DestroySessionHandle
1274 *
1275 */
1276 NSS_IMPLEMENT void
NSSCKFWInstance_DestroySessionHandle(NSSCKFWInstance * fwInstance,CK_SESSION_HANDLE hSession)1277 NSSCKFWInstance_DestroySessionHandle(
1278 NSSCKFWInstance *fwInstance,
1279 CK_SESSION_HANDLE hSession)
1280 {
1281 nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
1282 }
1283
1284 /*
1285 * nssCKFWInstance_FindSessionHandle
1286 *
1287 */
1288 NSS_IMPLEMENT CK_SESSION_HANDLE
NSSCKFWInstance_FindSessionHandle(NSSCKFWInstance * fwInstance,NSSCKFWSession * fwSession)1289 NSSCKFWInstance_FindSessionHandle(
1290 NSSCKFWInstance *fwInstance,
1291 NSSCKFWSession *fwSession)
1292 {
1293 return nssCKFWInstance_FindSessionHandle(fwInstance, fwSession);
1294 }
1295