comparison nss/lib/ckfw/token.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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 * token.c
7 *
8 * This file implements the NSSCKFWToken type and methods.
9 */
10
11 #ifndef CK_T
12 #include "ck.h"
13 #endif /* CK_T */
14
15 /*
16 * NSSCKFWToken
17 *
18 * -- create/destroy --
19 * nssCKFWToken_Create
20 * nssCKFWToken_Destroy
21 *
22 * -- public accessors --
23 * NSSCKFWToken_GetMDToken
24 * NSSCKFWToken_GetFWSlot
25 * NSSCKFWToken_GetMDSlot
26 * NSSCKFWToken_GetSessionState
27 *
28 * -- implement public accessors --
29 * nssCKFWToken_GetMDToken
30 * nssCKFWToken_GetFWSlot
31 * nssCKFWToken_GetMDSlot
32 * nssCKFWToken_GetSessionState
33 * nssCKFWToken_SetSessionState
34 *
35 * -- private accessors --
36 * nssCKFWToken_SetSessionState
37 * nssCKFWToken_RemoveSession
38 * nssCKFWToken_CloseAllSessions
39 * nssCKFWToken_GetSessionCount
40 * nssCKFWToken_GetRwSessionCount
41 * nssCKFWToken_GetRoSessionCount
42 * nssCKFWToken_GetSessionObjectHash
43 * nssCKFWToken_GetMDObjectHash
44 * nssCKFWToken_GetObjectHandleHash
45 *
46 * -- module fronts --
47 * nssCKFWToken_InitToken
48 * nssCKFWToken_GetLabel
49 * nssCKFWToken_GetManufacturerID
50 * nssCKFWToken_GetModel
51 * nssCKFWToken_GetSerialNumber
52 * nssCKFWToken_GetHasRNG
53 * nssCKFWToken_GetIsWriteProtected
54 * nssCKFWToken_GetLoginRequired
55 * nssCKFWToken_GetUserPinInitialized
56 * nssCKFWToken_GetRestoreKeyNotNeeded
57 * nssCKFWToken_GetHasClockOnToken
58 * nssCKFWToken_GetHasProtectedAuthenticationPath
59 * nssCKFWToken_GetSupportsDualCryptoOperations
60 * nssCKFWToken_GetMaxSessionCount
61 * nssCKFWToken_GetMaxRwSessionCount
62 * nssCKFWToken_GetMaxPinLen
63 * nssCKFWToken_GetMinPinLen
64 * nssCKFWToken_GetTotalPublicMemory
65 * nssCKFWToken_GetFreePublicMemory
66 * nssCKFWToken_GetTotalPrivateMemory
67 * nssCKFWToken_GetFreePrivateMemory
68 * nssCKFWToken_GetHardwareVersion
69 * nssCKFWToken_GetFirmwareVersion
70 * nssCKFWToken_GetUTCTime
71 * nssCKFWToken_OpenSession
72 * nssCKFWToken_GetMechanismCount
73 * nssCKFWToken_GetMechanismTypes
74 * nssCKFWToken_GetMechanism
75 */
76
77 struct NSSCKFWTokenStr {
78 NSSCKFWMutex *mutex;
79 NSSArena *arena;
80 NSSCKMDToken *mdToken;
81 NSSCKFWSlot *fwSlot;
82 NSSCKMDSlot *mdSlot;
83 NSSCKFWInstance *fwInstance;
84 NSSCKMDInstance *mdInstance;
85
86 /*
87 * Everything above is set at creation time, and then not modified.
88 * The invariants the mutex protects are:
89 *
90 * 1) Each of the cached descriptions (versions, etc.) are in an
91 * internally consistant state.
92 *
93 * 2) The session counts and hashes are consistant.
94 *
95 * 3) The object hashes are consistant.
96 *
97 * Note that the calls accessing the cached descriptions will call
98 * the NSSCKMDToken methods with the mutex locked. Those methods
99 * may then call the public NSSCKFWToken routines. Those public
100 * routines only access the constant data above and the atomic
101 * CK_STATE session state variable below, so there's no problem.
102 * But be careful if you add to this object; mutexes are in
103 * general not reentrant, so don't create deadlock situations.
104 */
105
106 NSSUTF8 *label;
107 NSSUTF8 *manufacturerID;
108 NSSUTF8 *model;
109 NSSUTF8 *serialNumber;
110 CK_VERSION hardwareVersion;
111 CK_VERSION firmwareVersion;
112
113 CK_ULONG sessionCount;
114 CK_ULONG rwSessionCount;
115 nssCKFWHash *sessions;
116 nssCKFWHash *sessionObjectHash;
117 nssCKFWHash *mdObjectHash;
118 nssCKFWHash *mdMechanismHash;
119
120 CK_STATE state;
121 };
122
123 #ifdef DEBUG
124 /*
125 * But first, the pointer-tracking stuff.
126 *
127 * NOTE: the pointer-tracking support in NSS/base currently relies
128 * upon NSPR's CallOnce support. That, however, relies upon NSPR's
129 * locking, which is tied into the runtime. We need a pointer-tracker
130 * implementation that uses the locks supplied through C_Initialize.
131 * That support, however, can be filled in later. So for now, I'll
132 * just do this routines as no-ops.
133 */
134
135 static CK_RV
136 token_add_pointer
137 (
138 const NSSCKFWToken *fwToken
139 )
140 {
141 return CKR_OK;
142 }
143
144 static CK_RV
145 token_remove_pointer
146 (
147 const NSSCKFWToken *fwToken
148 )
149 {
150 return CKR_OK;
151 }
152
153 NSS_IMPLEMENT CK_RV
154 nssCKFWToken_verifyPointer
155 (
156 const NSSCKFWToken *fwToken
157 )
158 {
159 return CKR_OK;
160 }
161
162 #endif /* DEBUG */
163
164 /*
165 * nssCKFWToken_Create
166 *
167 */
168 NSS_IMPLEMENT NSSCKFWToken *
169 nssCKFWToken_Create
170 (
171 NSSCKFWSlot *fwSlot,
172 NSSCKMDToken *mdToken,
173 CK_RV *pError
174 )
175 {
176 NSSArena *arena = (NSSArena *)NULL;
177 NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
178 CK_BBOOL called_setup = CK_FALSE;
179
180 /*
181 * We have already verified the arguments in nssCKFWSlot_GetToken.
182 */
183
184 arena = NSSArena_Create();
185 if (!arena) {
186 *pError = CKR_HOST_MEMORY;
187 goto loser;
188 }
189
190 fwToken = nss_ZNEW(arena, NSSCKFWToken);
191 if (!fwToken) {
192 *pError = CKR_HOST_MEMORY;
193 goto loser;
194 }
195
196 fwToken->arena = arena;
197 fwToken->mdToken = mdToken;
198 fwToken->fwSlot = fwSlot;
199 fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
200 fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
201 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
202 fwToken->sessionCount = 0;
203 fwToken->rwSessionCount = 0;
204
205 fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
206 if (!fwToken->mutex) {
207 if( CKR_OK == *pError ) {
208 *pError = CKR_GENERAL_ERROR;
209 }
210 goto loser;
211 }
212
213 fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
214 if (!fwToken->sessions) {
215 if( CKR_OK == *pError ) {
216 *pError = CKR_GENERAL_ERROR;
217 }
218 goto loser;
219 }
220
221 if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
222 fwToken->fwInstance) ) {
223 fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
224 arena, pError);
225 if (!fwToken->sessionObjectHash) {
226 if( CKR_OK == *pError ) {
227 *pError = CKR_GENERAL_ERROR;
228 }
229 goto loser;
230 }
231 }
232
233 fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
234 arena, pError);
235 if (!fwToken->mdObjectHash) {
236 if( CKR_OK == *pError ) {
237 *pError = CKR_GENERAL_ERROR;
238 }
239 goto loser;
240 }
241
242 fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance,
243 arena, pError);
244 if (!fwToken->mdMechanismHash) {
245 if( CKR_OK == *pError ) {
246 *pError = CKR_GENERAL_ERROR;
247 }
248 goto loser;
249 }
250
251 /* More here */
252
253 if (mdToken->Setup) {
254 *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
255 if( CKR_OK != *pError ) {
256 goto loser;
257 }
258 }
259
260 called_setup = CK_TRUE;
261
262 #ifdef DEBUG
263 *pError = token_add_pointer(fwToken);
264 if( CKR_OK != *pError ) {
265 goto loser;
266 }
267 #endif /* DEBUG */
268
269 *pError = CKR_OK;
270 return fwToken;
271
272 loser:
273
274 if( CK_TRUE == called_setup ) {
275 if (mdToken->Invalidate) {
276 mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
277 }
278 }
279
280 if (arena) {
281 (void)NSSArena_Destroy(arena);
282 }
283
284 return (NSSCKFWToken *)NULL;
285 }
286
287 static void
288 nss_ckfwtoken_session_iterator
289 (
290 const void *key,
291 void *value,
292 void *closure
293 )
294 {
295 /*
296 * Remember that the fwToken->mutex is locked
297 */
298 NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
299 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
300 return;
301 }
302
303 static void
304 nss_ckfwtoken_object_iterator
305 (
306 const void *key,
307 void *value,
308 void *closure
309 )
310 {
311 /*
312 * Remember that the fwToken->mutex is locked
313 */
314 NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
315 (void)nssCKFWObject_Finalize(fwObject, CK_FALSE);
316 return;
317 }
318
319 /*
320 * nssCKFWToken_Destroy
321 *
322 */
323 NSS_IMPLEMENT CK_RV
324 nssCKFWToken_Destroy
325 (
326 NSSCKFWToken *fwToken
327 )
328 {
329 CK_RV error = CKR_OK;
330
331 #ifdef NSSDEBUG
332 error = nssCKFWToken_verifyPointer(fwToken);
333 if( CKR_OK != error ) {
334 return error;
335 }
336 #endif /* NSSDEBUG */
337
338 (void)nssCKFWMutex_Destroy(fwToken->mutex);
339
340 if (fwToken->mdToken->Invalidate) {
341 fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
342 fwToken->mdInstance, fwToken->fwInstance);
343 }
344 /* we can destroy the list without locking now because no one else is
345 * referencing us (or _Destroy was invalidly called!)
346 */
347 nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator,
348 (void *)NULL);
349 nssCKFWHash_Destroy(fwToken->sessions);
350
351 /* session objects go away when their sessions are removed */
352 if (fwToken->sessionObjectHash) {
353 nssCKFWHash_Destroy(fwToken->sessionObjectHash);
354 }
355
356 /* free up the token objects */
357 if (fwToken->mdObjectHash) {
358 nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator,
359 (void *)NULL);
360 nssCKFWHash_Destroy(fwToken->mdObjectHash);
361 }
362 if (fwToken->mdMechanismHash) {
363 nssCKFWHash_Destroy(fwToken->mdMechanismHash);
364 }
365
366 nssCKFWSlot_ClearToken(fwToken->fwSlot);
367
368 #ifdef DEBUG
369 error = token_remove_pointer(fwToken);
370 #endif /* DEBUG */
371
372 (void)NSSArena_Destroy(fwToken->arena);
373 return error;
374 }
375
376 /*
377 * nssCKFWToken_GetMDToken
378 *
379 */
380 NSS_IMPLEMENT NSSCKMDToken *
381 nssCKFWToken_GetMDToken
382 (
383 NSSCKFWToken *fwToken
384 )
385 {
386 #ifdef NSSDEBUG
387 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
388 return (NSSCKMDToken *)NULL;
389 }
390 #endif /* NSSDEBUG */
391
392 return fwToken->mdToken;
393 }
394
395 /*
396 * nssCKFWToken_GetArena
397 *
398 */
399 NSS_IMPLEMENT NSSArena *
400 nssCKFWToken_GetArena
401 (
402 NSSCKFWToken *fwToken,
403 CK_RV *pError
404 )
405 {
406 #ifdef NSSDEBUG
407 if (!pError) {
408 return (NSSArena *)NULL;
409 }
410
411 *pError = nssCKFWToken_verifyPointer(fwToken);
412 if( CKR_OK != *pError ) {
413 return (NSSArena *)NULL;
414 }
415 #endif /* NSSDEBUG */
416
417 return fwToken->arena;
418 }
419
420 /*
421 * nssCKFWToken_GetFWSlot
422 *
423 */
424 NSS_IMPLEMENT NSSCKFWSlot *
425 nssCKFWToken_GetFWSlot
426 (
427 NSSCKFWToken *fwToken
428 )
429 {
430 #ifdef NSSDEBUG
431 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
432 return (NSSCKFWSlot *)NULL;
433 }
434 #endif /* NSSDEBUG */
435
436 return fwToken->fwSlot;
437 }
438
439 /*
440 * nssCKFWToken_GetMDSlot
441 *
442 */
443 NSS_IMPLEMENT NSSCKMDSlot *
444 nssCKFWToken_GetMDSlot
445 (
446 NSSCKFWToken *fwToken
447 )
448 {
449 #ifdef NSSDEBUG
450 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
451 return (NSSCKMDSlot *)NULL;
452 }
453 #endif /* NSSDEBUG */
454
455 return fwToken->mdSlot;
456 }
457
458 /*
459 * nssCKFWToken_GetSessionState
460 *
461 */
462 NSS_IMPLEMENT CK_STATE
463 nssCKFWToken_GetSessionState
464 (
465 NSSCKFWToken *fwToken
466 )
467 {
468 #ifdef NSSDEBUG
469 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
470 return CKS_RO_PUBLIC_SESSION; /* whatever */
471 }
472 #endif /* NSSDEBUG */
473
474 /*
475 * BTW, do not lock the token in this method.
476 */
477
478 /*
479 * Theoretically, there is no state if there aren't any
480 * sessions open. But then we'd need to worry about
481 * reporting an error, etc. What the heck-- let's just
482 * revert to CKR_RO_PUBLIC_SESSION as the "default."
483 */
484
485 return fwToken->state;
486 }
487
488 /*
489 * nssCKFWToken_InitToken
490 *
491 */
492 NSS_IMPLEMENT CK_RV
493 nssCKFWToken_InitToken
494 (
495 NSSCKFWToken *fwToken,
496 NSSItem *pin,
497 NSSUTF8 *label
498 )
499 {
500 CK_RV error;
501
502 #ifdef NSSDEBUG
503 error = nssCKFWToken_verifyPointer(fwToken);
504 if( CKR_OK != error ) {
505 return CKR_ARGUMENTS_BAD;
506 }
507 #endif /* NSSDEBUG */
508
509 error = nssCKFWMutex_Lock(fwToken->mutex);
510 if( CKR_OK != error ) {
511 return error;
512 }
513
514 if( fwToken->sessionCount > 0 ) {
515 error = CKR_SESSION_EXISTS;
516 goto done;
517 }
518
519 if (!fwToken->mdToken->InitToken) {
520 error = CKR_DEVICE_ERROR;
521 goto done;
522 }
523
524 if (!pin) {
525 if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
526 ; /* okay */
527 } else {
528 error = CKR_PIN_INCORRECT;
529 goto done;
530 }
531 }
532
533 if (!label) {
534 label = (NSSUTF8 *) "";
535 }
536
537 error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
538 fwToken->mdInstance, fwToken->fwInstance, pin, label);
539
540 done:
541 (void)nssCKFWMutex_Unlock(fwToken->mutex);
542 return error;
543 }
544
545 /*
546 * nssCKFWToken_GetLabel
547 *
548 */
549 NSS_IMPLEMENT CK_RV
550 nssCKFWToken_GetLabel
551 (
552 NSSCKFWToken *fwToken,
553 CK_CHAR label[32]
554 )
555 {
556 CK_RV error = CKR_OK;
557
558 #ifdef NSSDEBUG
559 if( (CK_CHAR_PTR)NULL == label ) {
560 return CKR_ARGUMENTS_BAD;
561 }
562
563 error = nssCKFWToken_verifyPointer(fwToken);
564 if( CKR_OK != error ) {
565 return error;
566 }
567 #endif /* NSSDEBUG */
568
569 error = nssCKFWMutex_Lock(fwToken->mutex);
570 if( CKR_OK != error ) {
571 return error;
572 }
573
574 if (!fwToken->label) {
575 if (fwToken->mdToken->GetLabel) {
576 fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
577 fwToken->mdInstance, fwToken->fwInstance, &error);
578 if ((!fwToken->label) && (CKR_OK != error)) {
579 goto done;
580 }
581 } else {
582 fwToken->label = (NSSUTF8 *) "";
583 }
584 }
585
586 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
587 error = CKR_OK;
588
589 done:
590 (void)nssCKFWMutex_Unlock(fwToken->mutex);
591 return error;
592 }
593
594 /*
595 * nssCKFWToken_GetManufacturerID
596 *
597 */
598 NSS_IMPLEMENT CK_RV
599 nssCKFWToken_GetManufacturerID
600 (
601 NSSCKFWToken *fwToken,
602 CK_CHAR manufacturerID[32]
603 )
604 {
605 CK_RV error = CKR_OK;
606
607 #ifdef NSSDEBUG
608 if( (CK_CHAR_PTR)NULL == manufacturerID ) {
609 return CKR_ARGUMENTS_BAD;
610 }
611
612 error = nssCKFWToken_verifyPointer(fwToken);
613 if( CKR_OK != error ) {
614 return error;
615 }
616 #endif /* NSSDEBUG */
617
618 error = nssCKFWMutex_Lock(fwToken->mutex);
619 if( CKR_OK != error ) {
620 return error;
621 }
622
623 if (!fwToken->manufacturerID) {
624 if (fwToken->mdToken->GetManufacturerID) {
625 fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
626 fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
627 if ((!fwToken->manufacturerID) && (CKR_OK != error)) {
628 goto done;
629 }
630 } else {
631 fwToken->manufacturerID = (NSSUTF8 *)"";
632 }
633 }
634
635 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
636 error = CKR_OK;
637
638 done:
639 (void)nssCKFWMutex_Unlock(fwToken->mutex);
640 return error;
641 }
642
643 /*
644 * nssCKFWToken_GetModel
645 *
646 */
647 NSS_IMPLEMENT CK_RV
648 nssCKFWToken_GetModel
649 (
650 NSSCKFWToken *fwToken,
651 CK_CHAR model[16]
652 )
653 {
654 CK_RV error = CKR_OK;
655
656 #ifdef NSSDEBUG
657 if( (CK_CHAR_PTR)NULL == model ) {
658 return CKR_ARGUMENTS_BAD;
659 }
660
661 error = nssCKFWToken_verifyPointer(fwToken);
662 if( CKR_OK != error ) {
663 return error;
664 }
665 #endif /* NSSDEBUG */
666
667 error = nssCKFWMutex_Lock(fwToken->mutex);
668 if( CKR_OK != error ) {
669 return error;
670 }
671
672 if (!fwToken->model) {
673 if (fwToken->mdToken->GetModel) {
674 fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
675 fwToken->mdInstance, fwToken->fwInstance, &error);
676 if ((!fwToken->model) && (CKR_OK != error)) {
677 goto done;
678 }
679 } else {
680 fwToken->model = (NSSUTF8 *)"";
681 }
682 }
683
684 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
685 error = CKR_OK;
686
687 done:
688 (void)nssCKFWMutex_Unlock(fwToken->mutex);
689 return error;
690 }
691
692 /*
693 * nssCKFWToken_GetSerialNumber
694 *
695 */
696 NSS_IMPLEMENT CK_RV
697 nssCKFWToken_GetSerialNumber
698 (
699 NSSCKFWToken *fwToken,
700 CK_CHAR serialNumber[16]
701 )
702 {
703 CK_RV error = CKR_OK;
704
705 #ifdef NSSDEBUG
706 if( (CK_CHAR_PTR)NULL == serialNumber ) {
707 return CKR_ARGUMENTS_BAD;
708 }
709
710 error = nssCKFWToken_verifyPointer(fwToken);
711 if( CKR_OK != error ) {
712 return error;
713 }
714 #endif /* NSSDEBUG */
715
716 error = nssCKFWMutex_Lock(fwToken->mutex);
717 if( CKR_OK != error ) {
718 return error;
719 }
720
721 if (!fwToken->serialNumber) {
722 if (fwToken->mdToken->GetSerialNumber) {
723 fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken,
724 fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
725 if ((!fwToken->serialNumber) && (CKR_OK != error)) {
726 goto done;
727 }
728 } else {
729 fwToken->serialNumber = (NSSUTF8 *)"";
730 }
731 }
732
733 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
734 error = CKR_OK;
735
736 done:
737 (void)nssCKFWMutex_Unlock(fwToken->mutex);
738 return error;
739 }
740
741
742 /*
743 * nssCKFWToken_GetHasRNG
744 *
745 */
746 NSS_IMPLEMENT CK_BBOOL
747 nssCKFWToken_GetHasRNG
748 (
749 NSSCKFWToken *fwToken
750 )
751 {
752 #ifdef NSSDEBUG
753 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
754 return CK_FALSE;
755 }
756 #endif /* NSSDEBUG */
757
758 if (!fwToken->mdToken->GetHasRNG) {
759 return CK_FALSE;
760 }
761
762 return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken,
763 fwToken->mdInstance, fwToken->fwInstance);
764 }
765
766 /*
767 * nssCKFWToken_GetIsWriteProtected
768 *
769 */
770 NSS_IMPLEMENT CK_BBOOL
771 nssCKFWToken_GetIsWriteProtected
772 (
773 NSSCKFWToken *fwToken
774 )
775 {
776 #ifdef NSSDEBUG
777 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
778 return CK_FALSE;
779 }
780 #endif /* NSSDEBUG */
781
782 if (!fwToken->mdToken->GetIsWriteProtected) {
783 return CK_FALSE;
784 }
785
786 return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken,
787 fwToken->mdInstance, fwToken->fwInstance);
788 }
789
790 /*
791 * nssCKFWToken_GetLoginRequired
792 *
793 */
794 NSS_IMPLEMENT CK_BBOOL
795 nssCKFWToken_GetLoginRequired
796 (
797 NSSCKFWToken *fwToken
798 )
799 {
800 #ifdef NSSDEBUG
801 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
802 return CK_FALSE;
803 }
804 #endif /* NSSDEBUG */
805
806 if (!fwToken->mdToken->GetLoginRequired) {
807 return CK_FALSE;
808 }
809
810 return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken,
811 fwToken->mdInstance, fwToken->fwInstance);
812 }
813
814 /*
815 * nssCKFWToken_GetUserPinInitialized
816 *
817 */
818 NSS_IMPLEMENT CK_BBOOL
819 nssCKFWToken_GetUserPinInitialized
820 (
821 NSSCKFWToken *fwToken
822 )
823 {
824 #ifdef NSSDEBUG
825 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
826 return CK_FALSE;
827 }
828 #endif /* NSSDEBUG */
829
830 if (!fwToken->mdToken->GetUserPinInitialized) {
831 return CK_FALSE;
832 }
833
834 return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken,
835 fwToken->mdInstance, fwToken->fwInstance);
836 }
837
838 /*
839 * nssCKFWToken_GetRestoreKeyNotNeeded
840 *
841 */
842 NSS_IMPLEMENT CK_BBOOL
843 nssCKFWToken_GetRestoreKeyNotNeeded
844 (
845 NSSCKFWToken *fwToken
846 )
847 {
848 #ifdef NSSDEBUG
849 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
850 return CK_FALSE;
851 }
852 #endif /* NSSDEBUG */
853
854 if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
855 return CK_FALSE;
856 }
857
858 return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken,
859 fwToken->mdInstance, fwToken->fwInstance);
860 }
861
862 /*
863 * nssCKFWToken_GetHasClockOnToken
864 *
865 */
866 NSS_IMPLEMENT CK_BBOOL
867 nssCKFWToken_GetHasClockOnToken
868 (
869 NSSCKFWToken *fwToken
870 )
871 {
872 #ifdef NSSDEBUG
873 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
874 return CK_FALSE;
875 }
876 #endif /* NSSDEBUG */
877
878 if (!fwToken->mdToken->GetHasClockOnToken) {
879 return CK_FALSE;
880 }
881
882 return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken,
883 fwToken->mdInstance, fwToken->fwInstance);
884 }
885
886 /*
887 * nssCKFWToken_GetHasProtectedAuthenticationPath
888 *
889 */
890 NSS_IMPLEMENT CK_BBOOL
891 nssCKFWToken_GetHasProtectedAuthenticationPath
892 (
893 NSSCKFWToken *fwToken
894 )
895 {
896 #ifdef NSSDEBUG
897 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
898 return CK_FALSE;
899 }
900 #endif /* NSSDEBUG */
901
902 if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
903 return CK_FALSE;
904 }
905
906 return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken,
907 fwToken, fwToken->mdInstance, fwToken->fwInstance);
908 }
909
910 /*
911 * nssCKFWToken_GetSupportsDualCryptoOperations
912 *
913 */
914 NSS_IMPLEMENT CK_BBOOL
915 nssCKFWToken_GetSupportsDualCryptoOperations
916 (
917 NSSCKFWToken *fwToken
918 )
919 {
920 #ifdef NSSDEBUG
921 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
922 return CK_FALSE;
923 }
924 #endif /* NSSDEBUG */
925
926 if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
927 return CK_FALSE;
928 }
929
930 return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken,
931 fwToken, fwToken->mdInstance, fwToken->fwInstance);
932 }
933
934 /*
935 * nssCKFWToken_GetMaxSessionCount
936 *
937 */
938 NSS_IMPLEMENT CK_ULONG
939 nssCKFWToken_GetMaxSessionCount
940 (
941 NSSCKFWToken *fwToken
942 )
943 {
944 #ifdef NSSDEBUG
945 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
946 return CK_UNAVAILABLE_INFORMATION;
947 }
948 #endif /* NSSDEBUG */
949
950 if (!fwToken->mdToken->GetMaxSessionCount) {
951 return CK_UNAVAILABLE_INFORMATION;
952 }
953
954 return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken,
955 fwToken->mdInstance, fwToken->fwInstance);
956 }
957
958 /*
959 * nssCKFWToken_GetMaxRwSessionCount
960 *
961 */
962 NSS_IMPLEMENT CK_ULONG
963 nssCKFWToken_GetMaxRwSessionCount
964 (
965 NSSCKFWToken *fwToken
966 )
967 {
968 #ifdef NSSDEBUG
969 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
970 return CK_UNAVAILABLE_INFORMATION;
971 }
972 #endif /* NSSDEBUG */
973
974 if (!fwToken->mdToken->GetMaxRwSessionCount) {
975 return CK_UNAVAILABLE_INFORMATION;
976 }
977
978 return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken,
979 fwToken->mdInstance, fwToken->fwInstance);
980 }
981
982 /*
983 * nssCKFWToken_GetMaxPinLen
984 *
985 */
986 NSS_IMPLEMENT CK_ULONG
987 nssCKFWToken_GetMaxPinLen
988 (
989 NSSCKFWToken *fwToken
990 )
991 {
992 #ifdef NSSDEBUG
993 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
994 return CK_UNAVAILABLE_INFORMATION;
995 }
996 #endif /* NSSDEBUG */
997
998 if (!fwToken->mdToken->GetMaxPinLen) {
999 return CK_UNAVAILABLE_INFORMATION;
1000 }
1001
1002 return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken,
1003 fwToken->mdInstance, fwToken->fwInstance);
1004 }
1005
1006 /*
1007 * nssCKFWToken_GetMinPinLen
1008 *
1009 */
1010 NSS_IMPLEMENT CK_ULONG
1011 nssCKFWToken_GetMinPinLen
1012 (
1013 NSSCKFWToken *fwToken
1014 )
1015 {
1016 #ifdef NSSDEBUG
1017 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1018 return CK_UNAVAILABLE_INFORMATION;
1019 }
1020 #endif /* NSSDEBUG */
1021
1022 if (!fwToken->mdToken->GetMinPinLen) {
1023 return CK_UNAVAILABLE_INFORMATION;
1024 }
1025
1026 return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken,
1027 fwToken->mdInstance, fwToken->fwInstance);
1028 }
1029
1030 /*
1031 * nssCKFWToken_GetTotalPublicMemory
1032 *
1033 */
1034 NSS_IMPLEMENT CK_ULONG
1035 nssCKFWToken_GetTotalPublicMemory
1036 (
1037 NSSCKFWToken *fwToken
1038 )
1039 {
1040 #ifdef NSSDEBUG
1041 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1042 return CK_UNAVAILABLE_INFORMATION;
1043 }
1044 #endif /* NSSDEBUG */
1045
1046 if (!fwToken->mdToken->GetTotalPublicMemory) {
1047 return CK_UNAVAILABLE_INFORMATION;
1048 }
1049
1050 return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken,
1051 fwToken->mdInstance, fwToken->fwInstance);
1052 }
1053
1054 /*
1055 * nssCKFWToken_GetFreePublicMemory
1056 *
1057 */
1058 NSS_IMPLEMENT CK_ULONG
1059 nssCKFWToken_GetFreePublicMemory
1060 (
1061 NSSCKFWToken *fwToken
1062 )
1063 {
1064 #ifdef NSSDEBUG
1065 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1066 return CK_UNAVAILABLE_INFORMATION;
1067 }
1068 #endif /* NSSDEBUG */
1069
1070 if (!fwToken->mdToken->GetFreePublicMemory) {
1071 return CK_UNAVAILABLE_INFORMATION;
1072 }
1073
1074 return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken,
1075 fwToken->mdInstance, fwToken->fwInstance);
1076 }
1077
1078 /*
1079 * nssCKFWToken_GetTotalPrivateMemory
1080 *
1081 */
1082 NSS_IMPLEMENT CK_ULONG
1083 nssCKFWToken_GetTotalPrivateMemory
1084 (
1085 NSSCKFWToken *fwToken
1086 )
1087 {
1088 #ifdef NSSDEBUG
1089 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1090 return CK_UNAVAILABLE_INFORMATION;
1091 }
1092 #endif /* NSSDEBUG */
1093
1094 if (!fwToken->mdToken->GetTotalPrivateMemory) {
1095 return CK_UNAVAILABLE_INFORMATION;
1096 }
1097
1098 return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken,
1099 fwToken->mdInstance, fwToken->fwInstance);
1100 }
1101
1102 /*
1103 * nssCKFWToken_GetFreePrivateMemory
1104 *
1105 */
1106 NSS_IMPLEMENT CK_ULONG
1107 nssCKFWToken_GetFreePrivateMemory
1108 (
1109 NSSCKFWToken *fwToken
1110 )
1111 {
1112 #ifdef NSSDEBUG
1113 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1114 return CK_UNAVAILABLE_INFORMATION;
1115 }
1116 #endif /* NSSDEBUG */
1117
1118 if (!fwToken->mdToken->GetFreePrivateMemory) {
1119 return CK_UNAVAILABLE_INFORMATION;
1120 }
1121
1122 return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken,
1123 fwToken->mdInstance, fwToken->fwInstance);
1124 }
1125
1126 /*
1127 * nssCKFWToken_GetHardwareVersion
1128 *
1129 */
1130 NSS_IMPLEMENT CK_VERSION
1131 nssCKFWToken_GetHardwareVersion
1132 (
1133 NSSCKFWToken *fwToken
1134 )
1135 {
1136 CK_VERSION rv;
1137
1138 #ifdef NSSDEBUG
1139 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1140 rv.major = rv.minor = 0;
1141 return rv;
1142 }
1143 #endif /* NSSDEBUG */
1144
1145 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
1146 rv.major = rv.minor = 0;
1147 return rv;
1148 }
1149
1150 if( (0 != fwToken->hardwareVersion.major) ||
1151 (0 != fwToken->hardwareVersion.minor) ) {
1152 rv = fwToken->hardwareVersion;
1153 goto done;
1154 }
1155
1156 if (fwToken->mdToken->GetHardwareVersion) {
1157 fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
1158 fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
1159 } else {
1160 fwToken->hardwareVersion.major = 0;
1161 fwToken->hardwareVersion.minor = 1;
1162 }
1163
1164 rv = fwToken->hardwareVersion;
1165
1166 done:
1167 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1168 return rv;
1169 }
1170
1171 /*
1172 * nssCKFWToken_GetFirmwareVersion
1173 *
1174 */
1175 NSS_IMPLEMENT CK_VERSION
1176 nssCKFWToken_GetFirmwareVersion
1177 (
1178 NSSCKFWToken *fwToken
1179 )
1180 {
1181 CK_VERSION rv;
1182
1183 #ifdef NSSDEBUG
1184 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1185 rv.major = rv.minor = 0;
1186 return rv;
1187 }
1188 #endif /* NSSDEBUG */
1189
1190 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
1191 rv.major = rv.minor = 0;
1192 return rv;
1193 }
1194
1195 if( (0 != fwToken->firmwareVersion.major) ||
1196 (0 != fwToken->firmwareVersion.minor) ) {
1197 rv = fwToken->firmwareVersion;
1198 goto done;
1199 }
1200
1201 if (fwToken->mdToken->GetFirmwareVersion) {
1202 fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
1203 fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
1204 } else {
1205 fwToken->firmwareVersion.major = 0;
1206 fwToken->firmwareVersion.minor = 1;
1207 }
1208
1209 rv = fwToken->firmwareVersion;
1210
1211 done:
1212 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1213 return rv;
1214 }
1215
1216 /*
1217 * nssCKFWToken_GetUTCTime
1218 *
1219 */
1220 NSS_IMPLEMENT CK_RV
1221 nssCKFWToken_GetUTCTime
1222 (
1223 NSSCKFWToken *fwToken,
1224 CK_CHAR utcTime[16]
1225 )
1226 {
1227 CK_RV error = CKR_OK;
1228
1229 #ifdef NSSDEBUG
1230 error = nssCKFWToken_verifyPointer(fwToken);
1231 if( CKR_OK != error ) {
1232 return error;
1233 }
1234
1235 if( (CK_CHAR_PTR)NULL == utcTime ) {
1236 return CKR_ARGUMENTS_BAD;
1237 }
1238 #endif /* DEBUG */
1239
1240 if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) {
1241 /* return CKR_DEVICE_ERROR; */
1242 (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
1243 return CKR_OK;
1244 }
1245
1246 if (!fwToken->mdToken->GetUTCTime) {
1247 /* It said it had one! */
1248 return CKR_GENERAL_ERROR;
1249 }
1250
1251 error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken,
1252 fwToken->mdInstance, fwToken->fwInstance, utcTime);
1253 if( CKR_OK != error ) {
1254 return error;
1255 }
1256
1257 /* Sanity-check the data */
1258 {
1259 /* Format is YYYYMMDDhhmmss00 */
1260 int i;
1261 int Y, M, D, h, m, s, z;
1262 static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1263
1264 for( i = 0; i < 16; i++ ) {
1265 if( (utcTime[i] < '0') || (utcTime[i] > '9') ) {
1266 goto badtime;
1267 }
1268 }
1269
1270 Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
1271 ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0');
1272 M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0');
1273 D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0');
1274 h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0');
1275 m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
1276 s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
1277 z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0');
1278
1279 if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem. heh heh heh */
1280 if( (M < 1) || (M > 12) ) goto badtime;
1281 if( (D < 1) || (D > 31) ) goto badtime;
1282
1283 if( D > dims[M-1] ) goto badtime; /* per-month check */
1284 if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /* leap years */
1285
1286 if( (h < 0) || (h > 23) ) goto badtime;
1287 if( (m < 0) || (m > 60) ) goto badtime;
1288 if( (s < 0) || (s > 61) ) goto badtime;
1289
1290 /* 60m and 60 or 61s is only allowed for leap seconds. */
1291 if( (60 == m) || (s >= 60) ) {
1292 if( (23 != h) || (60 != m) || (s < 60) ) goto badtime;
1293 /* leap seconds can only happen on June 30 or Dec 31.. I think */
1294 /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
1295 }
1296 }
1297
1298 return CKR_OK;
1299
1300 badtime:
1301 return CKR_GENERAL_ERROR;
1302 }
1303
1304 /*
1305 * nssCKFWToken_OpenSession
1306 *
1307 */
1308 NSS_IMPLEMENT NSSCKFWSession *
1309 nssCKFWToken_OpenSession
1310 (
1311 NSSCKFWToken *fwToken,
1312 CK_BBOOL rw,
1313 CK_VOID_PTR pApplication,
1314 CK_NOTIFY Notify,
1315 CK_RV *pError
1316 )
1317 {
1318 NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
1319 NSSCKMDSession *mdSession;
1320
1321 #ifdef NSSDEBUG
1322 if (!pError) {
1323 return (NSSCKFWSession *)NULL;
1324 }
1325
1326 *pError = nssCKFWToken_verifyPointer(fwToken);
1327 if( CKR_OK != *pError ) {
1328 return (NSSCKFWSession *)NULL;
1329 }
1330
1331 switch( rw ) {
1332 case CK_TRUE:
1333 case CK_FALSE:
1334 break;
1335 default:
1336 *pError = CKR_ARGUMENTS_BAD;
1337 return (NSSCKFWSession *)NULL;
1338 }
1339 #endif /* NSSDEBUG */
1340
1341 *pError = nssCKFWMutex_Lock(fwToken->mutex);
1342 if( CKR_OK != *pError ) {
1343 return (NSSCKFWSession *)NULL;
1344 }
1345
1346 if( CK_TRUE == rw ) {
1347 /* Read-write session desired */
1348 if( CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken) ) {
1349 *pError = CKR_TOKEN_WRITE_PROTECTED;
1350 goto done;
1351 }
1352 } else {
1353 /* Read-only session desired */
1354 if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {
1355 *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
1356 goto done;
1357 }
1358 }
1359
1360 /* We could compare sesion counts to any limits we know of, I guess.. */
1361
1362 if (!fwToken->mdToken->OpenSession) {
1363 /*
1364 * I'm not sure that the Module actually needs to implement
1365 * mdSessions -- the Framework can keep track of everything
1366 * needed, really. But I'll sort out that detail later..
1367 */
1368 *pError = CKR_GENERAL_ERROR;
1369 goto done;
1370 }
1371
1372 fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
1373 if (!fwSession) {
1374 if( CKR_OK == *pError ) {
1375 *pError = CKR_GENERAL_ERROR;
1376 }
1377 goto done;
1378 }
1379
1380 mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
1381 fwToken->mdInstance, fwToken->fwInstance, fwSession,
1382 rw, pError);
1383 if (!mdSession) {
1384 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
1385 if( CKR_OK == *pError ) {
1386 *pError = CKR_GENERAL_ERROR;
1387 }
1388 goto done;
1389 }
1390
1391 *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);
1392 if( CKR_OK != *pError ) {
1393 if (mdSession->Close) {
1394 mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
1395 fwToken->mdInstance, fwToken->fwInstance);
1396 }
1397 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
1398 goto done;
1399 }
1400
1401 *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
1402 if( CKR_OK != *pError ) {
1403 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
1404 fwSession = (NSSCKFWSession *)NULL;
1405 goto done;
1406 }
1407
1408 done:
1409 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1410 return fwSession;
1411 }
1412
1413 /*
1414 * nssCKFWToken_GetMechanismCount
1415 *
1416 */
1417 NSS_IMPLEMENT CK_ULONG
1418 nssCKFWToken_GetMechanismCount
1419 (
1420 NSSCKFWToken *fwToken
1421 )
1422 {
1423 #ifdef NSSDEBUG
1424 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1425 return 0;
1426 }
1427 #endif /* NSSDEBUG */
1428
1429 if (!fwToken->mdToken->GetMechanismCount) {
1430 return 0;
1431 }
1432
1433 return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
1434 fwToken->mdInstance, fwToken->fwInstance);
1435 }
1436
1437 /*
1438 * nssCKFWToken_GetMechanismTypes
1439 *
1440 */
1441 NSS_IMPLEMENT CK_RV
1442 nssCKFWToken_GetMechanismTypes
1443 (
1444 NSSCKFWToken *fwToken,
1445 CK_MECHANISM_TYPE types[]
1446 )
1447 {
1448 #ifdef NSSDEBUG
1449 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1450 return CKR_ARGUMENTS_BAD;
1451 }
1452
1453 if (!types) {
1454 return CKR_ARGUMENTS_BAD;
1455 }
1456 #endif /* NSSDEBUG */
1457
1458 if (!fwToken->mdToken->GetMechanismTypes) {
1459 /*
1460 * This should only be called with a sufficiently-large
1461 * "types" array, which can only be done if GetMechanismCount
1462 * is implemented. If that's implemented (and returns nonzero),
1463 * then this should be too. So return an error.
1464 */
1465 return CKR_GENERAL_ERROR;
1466 }
1467
1468 return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
1469 fwToken->mdInstance, fwToken->fwInstance, types);
1470 }
1471
1472
1473 /*
1474 * nssCKFWToken_GetMechanism
1475 *
1476 */
1477 NSS_IMPLEMENT NSSCKFWMechanism *
1478 nssCKFWToken_GetMechanism
1479 (
1480 NSSCKFWToken *fwToken,
1481 CK_MECHANISM_TYPE which,
1482 CK_RV *pError
1483 )
1484 {
1485 NSSCKMDMechanism *mdMechanism;
1486 if (!fwToken->mdMechanismHash) {
1487 *pError = CKR_GENERAL_ERROR;
1488 return (NSSCKFWMechanism *)NULL;
1489 }
1490
1491 if (!fwToken->mdToken->GetMechanism) {
1492 /*
1493 * If we don't implement any GetMechanism function, then we must
1494 * not support any.
1495 */
1496 *pError = CKR_MECHANISM_INVALID;
1497 return (NSSCKFWMechanism *)NULL;
1498 }
1499
1500 /* lookup in hash table */
1501 mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken,
1502 fwToken->mdInstance, fwToken->fwInstance, which, pError);
1503 if (!mdMechanism) {
1504 return (NSSCKFWMechanism *) NULL;
1505 }
1506 /* store in hash table */
1507 return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken,
1508 fwToken->mdInstance, fwToken->fwInstance);
1509 }
1510
1511 NSS_IMPLEMENT CK_RV
1512 nssCKFWToken_SetSessionState
1513 (
1514 NSSCKFWToken *fwToken,
1515 CK_STATE newState
1516 )
1517 {
1518 CK_RV error = CKR_OK;
1519
1520 #ifdef NSSDEBUG
1521 error = nssCKFWToken_verifyPointer(fwToken);
1522 if( CKR_OK != error ) {
1523 return error;
1524 }
1525
1526 switch( newState ) {
1527 case CKS_RO_PUBLIC_SESSION:
1528 case CKS_RO_USER_FUNCTIONS:
1529 case CKS_RW_PUBLIC_SESSION:
1530 case CKS_RW_USER_FUNCTIONS:
1531 case CKS_RW_SO_FUNCTIONS:
1532 break;
1533 default:
1534 return CKR_ARGUMENTS_BAD;
1535 }
1536 #endif /* NSSDEBUG */
1537
1538 error = nssCKFWMutex_Lock(fwToken->mutex);
1539 if( CKR_OK != error ) {
1540 return error;
1541 }
1542
1543 fwToken->state = newState;
1544 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1545 return CKR_OK;
1546 }
1547
1548 /*
1549 * nssCKFWToken_RemoveSession
1550 *
1551 */
1552 NSS_IMPLEMENT CK_RV
1553 nssCKFWToken_RemoveSession
1554 (
1555 NSSCKFWToken *fwToken,
1556 NSSCKFWSession *fwSession
1557 )
1558 {
1559 CK_RV error = CKR_OK;
1560
1561 #ifdef NSSDEBUG
1562 error = nssCKFWToken_verifyPointer(fwToken);
1563 if( CKR_OK != error ) {
1564 return error;
1565 }
1566
1567 error = nssCKFWSession_verifyPointer(fwSession);
1568 if( CKR_OK != error ) {
1569 return error;
1570 }
1571 #endif /* NSSDEBUG */
1572
1573 error = nssCKFWMutex_Lock(fwToken->mutex);
1574 if( CKR_OK != error ) {
1575 return error;
1576 }
1577
1578 if( CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) {
1579 error = CKR_SESSION_HANDLE_INVALID;
1580 goto done;
1581 }
1582
1583 nssCKFWHash_Remove(fwToken->sessions, fwSession);
1584 fwToken->sessionCount--;
1585
1586 if( nssCKFWSession_IsRWSession(fwSession) ) {
1587 fwToken->rwSessionCount--;
1588 }
1589
1590 if( 0 == fwToken->sessionCount ) {
1591 fwToken->rwSessionCount = 0; /* sanity */
1592 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
1593 }
1594
1595 error = CKR_OK;
1596
1597 done:
1598 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1599 return error;
1600 }
1601
1602
1603 /*
1604 * nssCKFWToken_CloseAllSessions
1605 *
1606 */
1607 NSS_IMPLEMENT CK_RV
1608 nssCKFWToken_CloseAllSessions
1609 (
1610 NSSCKFWToken *fwToken
1611 )
1612 {
1613 CK_RV error = CKR_OK;
1614
1615 #ifdef NSSDEBUG
1616 error = nssCKFWToken_verifyPointer(fwToken);
1617 if( CKR_OK != error ) {
1618 return error;
1619 }
1620 #endif /* NSSDEBUG */
1621
1622 error = nssCKFWMutex_Lock(fwToken->mutex);
1623 if( CKR_OK != error ) {
1624 return error;
1625 }
1626
1627 nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
1628
1629 nssCKFWHash_Destroy(fwToken->sessions);
1630
1631 fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
1632 if (!fwToken->sessions) {
1633 if( CKR_OK == error ) {
1634 error = CKR_GENERAL_ERROR;
1635 }
1636 goto done;
1637 }
1638
1639 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
1640 fwToken->sessionCount = 0;
1641 fwToken->rwSessionCount = 0;
1642
1643 error = CKR_OK;
1644
1645 done:
1646 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1647 return error;
1648 }
1649
1650 /*
1651 * nssCKFWToken_GetSessionCount
1652 *
1653 */
1654 NSS_IMPLEMENT CK_ULONG
1655 nssCKFWToken_GetSessionCount
1656 (
1657 NSSCKFWToken *fwToken
1658 )
1659 {
1660 CK_ULONG rv;
1661
1662 #ifdef NSSDEBUG
1663 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1664 return (CK_ULONG)0;
1665 }
1666 #endif /* NSSDEBUG */
1667
1668 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
1669 return (CK_ULONG)0;
1670 }
1671
1672 rv = fwToken->sessionCount;
1673 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1674 return rv;
1675 }
1676
1677 /*
1678 * nssCKFWToken_GetRwSessionCount
1679 *
1680 */
1681 NSS_IMPLEMENT CK_ULONG
1682 nssCKFWToken_GetRwSessionCount
1683 (
1684 NSSCKFWToken *fwToken
1685 )
1686 {
1687 CK_ULONG rv;
1688
1689 #ifdef NSSDEBUG
1690 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1691 return (CK_ULONG)0;
1692 }
1693 #endif /* NSSDEBUG */
1694
1695 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
1696 return (CK_ULONG)0;
1697 }
1698
1699 rv = fwToken->rwSessionCount;
1700 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1701 return rv;
1702 }
1703
1704 /*
1705 * nssCKFWToken_GetRoSessionCount
1706 *
1707 */
1708 NSS_IMPLEMENT CK_ULONG
1709 nssCKFWToken_GetRoSessionCount
1710 (
1711 NSSCKFWToken *fwToken
1712 )
1713 {
1714 CK_ULONG rv;
1715
1716 #ifdef NSSDEBUG
1717 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1718 return (CK_ULONG)0;
1719 }
1720 #endif /* NSSDEBUG */
1721
1722 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
1723 return (CK_ULONG)0;
1724 }
1725
1726 rv = fwToken->sessionCount - fwToken->rwSessionCount;
1727 (void)nssCKFWMutex_Unlock(fwToken->mutex);
1728 return rv;
1729 }
1730
1731 /*
1732 * nssCKFWToken_GetSessionObjectHash
1733 *
1734 */
1735 NSS_IMPLEMENT nssCKFWHash *
1736 nssCKFWToken_GetSessionObjectHash
1737 (
1738 NSSCKFWToken *fwToken
1739 )
1740 {
1741 #ifdef NSSDEBUG
1742 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1743 return (nssCKFWHash *)NULL;
1744 }
1745 #endif /* NSSDEBUG */
1746
1747 return fwToken->sessionObjectHash;
1748 }
1749
1750 /*
1751 * nssCKFWToken_GetMDObjectHash
1752 *
1753 */
1754 NSS_IMPLEMENT nssCKFWHash *
1755 nssCKFWToken_GetMDObjectHash
1756 (
1757 NSSCKFWToken *fwToken
1758 )
1759 {
1760 #ifdef NSSDEBUG
1761 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1762 return (nssCKFWHash *)NULL;
1763 }
1764 #endif /* NSSDEBUG */
1765
1766 return fwToken->mdObjectHash;
1767 }
1768
1769 /*
1770 * nssCKFWToken_GetObjectHandleHash
1771 *
1772 */
1773 NSS_IMPLEMENT nssCKFWHash *
1774 nssCKFWToken_GetObjectHandleHash
1775 (
1776 NSSCKFWToken *fwToken
1777 )
1778 {
1779 #ifdef NSSDEBUG
1780 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1781 return (nssCKFWHash *)NULL;
1782 }
1783 #endif /* NSSDEBUG */
1784
1785 return fwToken->mdObjectHash;
1786 }
1787
1788 /*
1789 * NSSCKFWToken_GetMDToken
1790 *
1791 */
1792
1793 NSS_IMPLEMENT NSSCKMDToken *
1794 NSSCKFWToken_GetMDToken
1795 (
1796 NSSCKFWToken *fwToken
1797 )
1798 {
1799 #ifdef DEBUG
1800 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1801 return (NSSCKMDToken *)NULL;
1802 }
1803 #endif /* DEBUG */
1804
1805 return nssCKFWToken_GetMDToken(fwToken);
1806 }
1807
1808 /*
1809 * NSSCKFWToken_GetArena
1810 *
1811 */
1812
1813 NSS_IMPLEMENT NSSArena *
1814 NSSCKFWToken_GetArena
1815 (
1816 NSSCKFWToken *fwToken,
1817 CK_RV *pError
1818 )
1819 {
1820 #ifdef DEBUG
1821 if (!pError) {
1822 return (NSSArena *)NULL;
1823 }
1824
1825 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1826 *pError = CKR_ARGUMENTS_BAD;
1827 return (NSSArena *)NULL;
1828 }
1829 #endif /* DEBUG */
1830
1831 return nssCKFWToken_GetArena(fwToken, pError);
1832 }
1833
1834 /*
1835 * NSSCKFWToken_GetFWSlot
1836 *
1837 */
1838
1839 NSS_IMPLEMENT NSSCKFWSlot *
1840 NSSCKFWToken_GetFWSlot
1841 (
1842 NSSCKFWToken *fwToken
1843 )
1844 {
1845 #ifdef DEBUG
1846 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1847 return (NSSCKFWSlot *)NULL;
1848 }
1849 #endif /* DEBUG */
1850
1851 return nssCKFWToken_GetFWSlot(fwToken);
1852 }
1853
1854 /*
1855 * NSSCKFWToken_GetMDSlot
1856 *
1857 */
1858
1859 NSS_IMPLEMENT NSSCKMDSlot *
1860 NSSCKFWToken_GetMDSlot
1861 (
1862 NSSCKFWToken *fwToken
1863 )
1864 {
1865 #ifdef DEBUG
1866 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1867 return (NSSCKMDSlot *)NULL;
1868 }
1869 #endif /* DEBUG */
1870
1871 return nssCKFWToken_GetMDSlot(fwToken);
1872 }
1873
1874 /*
1875 * NSSCKFWToken_GetSessionState
1876 *
1877 */
1878
1879 NSS_IMPLEMENT CK_STATE
1880 NSSCKFWSession_GetSessionState
1881 (
1882 NSSCKFWToken *fwToken
1883 )
1884 {
1885 #ifdef DEBUG
1886 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
1887 return CKS_RO_PUBLIC_SESSION;
1888 }
1889 #endif /* DEBUG */
1890
1891 return nssCKFWToken_GetSessionState(fwToken);
1892 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)