comparison nss/lib/ckfw/session.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 * session.c
7 *
8 * This file implements the NSSCKFWSession type and methods.
9 */
10
11 #ifndef CK_T
12 #include "ck.h"
13 #endif /* CK_T */
14
15 /*
16 * NSSCKFWSession
17 *
18 * -- create/destroy --
19 * nssCKFWSession_Create
20 * nssCKFWSession_Destroy
21 *
22 * -- public accessors --
23 * NSSCKFWSession_GetMDSession
24 * NSSCKFWSession_GetArena
25 * NSSCKFWSession_CallNotification
26 * NSSCKFWSession_IsRWSession
27 * NSSCKFWSession_IsSO
28 *
29 * -- implement public accessors --
30 * nssCKFWSession_GetMDSession
31 * nssCKFWSession_GetArena
32 * nssCKFWSession_CallNotification
33 * nssCKFWSession_IsRWSession
34 * nssCKFWSession_IsSO
35 *
36 * -- private accessors --
37 * nssCKFWSession_GetSlot
38 * nssCKFWSession_GetSessionState
39 * nssCKFWSession_SetFWFindObjects
40 * nssCKFWSession_GetFWFindObjects
41 * nssCKFWSession_SetMDSession
42 * nssCKFWSession_SetHandle
43 * nssCKFWSession_GetHandle
44 * nssCKFWSession_RegisterSessionObject
45 * nssCKFWSession_DeegisterSessionObject
46 *
47 * -- module fronts --
48 * nssCKFWSession_GetDeviceError
49 * nssCKFWSession_Login
50 * nssCKFWSession_Logout
51 * nssCKFWSession_InitPIN
52 * nssCKFWSession_SetPIN
53 * nssCKFWSession_GetOperationStateLen
54 * nssCKFWSession_GetOperationState
55 * nssCKFWSession_SetOperationState
56 * nssCKFWSession_CreateObject
57 * nssCKFWSession_CopyObject
58 * nssCKFWSession_FindObjectsInit
59 * nssCKFWSession_SeedRandom
60 * nssCKFWSession_GetRandom
61 */
62
63 struct NSSCKFWSessionStr {
64 NSSArena *arena;
65 NSSCKMDSession *mdSession;
66 NSSCKFWToken *fwToken;
67 NSSCKMDToken *mdToken;
68 NSSCKFWInstance *fwInstance;
69 NSSCKMDInstance *mdInstance;
70 CK_VOID_PTR pApplication;
71 CK_NOTIFY Notify;
72
73 /*
74 * Everything above is set at creation time, and then not modified.
75 * The items below are atomic. No locking required. If we fear
76 * about pointer-copies being nonatomic, we'll lock fwFindObjects.
77 */
78
79 CK_BBOOL rw;
80 NSSCKFWFindObjects *fwFindObjects;
81 NSSCKFWCryptoOperation *fwOperationArray[NSSCKFWCryptoOperationState_Max];
82 nssCKFWHash *sessionObjectHash;
83 CK_SESSION_HANDLE hSession;
84 };
85
86 #ifdef DEBUG
87 /*
88 * But first, the pointer-tracking stuff.
89 *
90 * NOTE: the pointer-tracking support in NSS/base currently relies
91 * upon NSPR's CallOnce support. That, however, relies upon NSPR's
92 * locking, which is tied into the runtime. We need a pointer-tracker
93 * implementation that uses the locks supplied through C_Initialize.
94 * That support, however, can be filled in later. So for now, I'll
95 * just do this routines as no-ops.
96 */
97
98 static CK_RV
99 session_add_pointer
100 (
101 const NSSCKFWSession *fwSession
102 )
103 {
104 return CKR_OK;
105 }
106
107 static CK_RV
108 session_remove_pointer
109 (
110 const NSSCKFWSession *fwSession
111 )
112 {
113 return CKR_OK;
114 }
115
116 NSS_IMPLEMENT CK_RV
117 nssCKFWSession_verifyPointer
118 (
119 const NSSCKFWSession *fwSession
120 )
121 {
122 return CKR_OK;
123 }
124
125 #endif /* DEBUG */
126
127 /*
128 * nssCKFWSession_Create
129 *
130 */
131 NSS_IMPLEMENT NSSCKFWSession *
132 nssCKFWSession_Create
133 (
134 NSSCKFWToken *fwToken,
135 CK_BBOOL rw,
136 CK_VOID_PTR pApplication,
137 CK_NOTIFY Notify,
138 CK_RV *pError
139 )
140 {
141 NSSArena *arena = (NSSArena *)NULL;
142 NSSCKFWSession *fwSession;
143 NSSCKFWSlot *fwSlot;
144
145 #ifdef NSSDEBUG
146 if (!pError) {
147 return (NSSCKFWSession *)NULL;
148 }
149
150 *pError = nssCKFWToken_verifyPointer(fwToken);
151 if( CKR_OK != *pError ) {
152 return (NSSCKFWSession *)NULL;
153 }
154 #endif /* NSSDEBUG */
155
156 arena = NSSArena_Create();
157 if (!arena) {
158 *pError = CKR_HOST_MEMORY;
159 return (NSSCKFWSession *)NULL;
160 }
161
162 fwSession = nss_ZNEW(arena, NSSCKFWSession);
163 if (!fwSession) {
164 *pError = CKR_HOST_MEMORY;
165 goto loser;
166 }
167
168 fwSession->arena = arena;
169 fwSession->mdSession = (NSSCKMDSession *)NULL; /* set later */
170 fwSession->fwToken = fwToken;
171 fwSession->mdToken = nssCKFWToken_GetMDToken(fwToken);
172
173 fwSlot = nssCKFWToken_GetFWSlot(fwToken);
174 fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
175 fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
176
177 fwSession->rw = rw;
178 fwSession->pApplication = pApplication;
179 fwSession->Notify = Notify;
180
181 fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
182
183 fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena, pError);
184 if (!fwSession->sessionObjectHash) {
185 if( CKR_OK == *pError ) {
186 *pError = CKR_GENERAL_ERROR;
187 }
188 goto loser;
189 }
190
191 #ifdef DEBUG
192 *pError = session_add_pointer(fwSession);
193 if( CKR_OK != *pError ) {
194 goto loser;
195 }
196 #endif /* DEBUG */
197
198 return fwSession;
199
200 loser:
201 if (arena) {
202 if (fwSession && fwSession->sessionObjectHash) {
203 (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash);
204 }
205 NSSArena_Destroy(arena);
206 }
207
208 return (NSSCKFWSession *)NULL;
209 }
210
211 static void
212 nss_ckfw_session_object_destroy_iterator
213 (
214 const void *key,
215 void *value,
216 void *closure
217 )
218 {
219 NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
220 nssCKFWObject_Finalize(fwObject, PR_TRUE);
221 }
222
223 /*
224 * nssCKFWSession_Destroy
225 *
226 */
227 NSS_IMPLEMENT CK_RV
228 nssCKFWSession_Destroy
229 (
230 NSSCKFWSession *fwSession,
231 CK_BBOOL removeFromTokenHash
232 )
233 {
234 CK_RV error = CKR_OK;
235 nssCKFWHash *sessionObjectHash;
236 NSSCKFWCryptoOperationState i;
237
238 #ifdef NSSDEBUG
239 error = nssCKFWSession_verifyPointer(fwSession);
240 if( CKR_OK != error ) {
241 return error;
242 }
243 #endif /* NSSDEBUG */
244
245 if( removeFromTokenHash ) {
246 error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
247 }
248
249 /*
250 * Invalidate session objects
251 */
252
253 sessionObjectHash = fwSession->sessionObjectHash;
254 fwSession->sessionObjectHash = (nssCKFWHash *)NULL;
255
256 nssCKFWHash_Iterate(sessionObjectHash,
257 nss_ckfw_session_object_destroy_iterator,
258 (void *)NULL);
259
260 for (i=0; i < NSSCKFWCryptoOperationState_Max; i++) {
261 if (fwSession->fwOperationArray[i]) {
262 nssCKFWCryptoOperation_Destroy(fwSession->fwOperationArray[i]);
263 }
264 }
265
266 #ifdef DEBUG
267 (void)session_remove_pointer(fwSession);
268 #endif /* DEBUG */
269 (void)nssCKFWHash_Destroy(sessionObjectHash);
270 NSSArena_Destroy(fwSession->arena);
271
272 return error;
273 }
274
275 /*
276 * nssCKFWSession_GetMDSession
277 *
278 */
279 NSS_IMPLEMENT NSSCKMDSession *
280 nssCKFWSession_GetMDSession
281 (
282 NSSCKFWSession *fwSession
283 )
284 {
285 #ifdef NSSDEBUG
286 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
287 return (NSSCKMDSession *)NULL;
288 }
289 #endif /* NSSDEBUG */
290
291 return fwSession->mdSession;
292 }
293
294 /*
295 * nssCKFWSession_GetArena
296 *
297 */
298 NSS_IMPLEMENT NSSArena *
299 nssCKFWSession_GetArena
300 (
301 NSSCKFWSession *fwSession,
302 CK_RV *pError
303 )
304 {
305 #ifdef NSSDEBUG
306 if (!pError) {
307 return (NSSArena *)NULL;
308 }
309
310 *pError = nssCKFWSession_verifyPointer(fwSession);
311 if( CKR_OK != *pError ) {
312 return (NSSArena *)NULL;
313 }
314 #endif /* NSSDEBUG */
315
316 return fwSession->arena;
317 }
318
319 /*
320 * nssCKFWSession_CallNotification
321 *
322 */
323 NSS_IMPLEMENT CK_RV
324 nssCKFWSession_CallNotification
325 (
326 NSSCKFWSession *fwSession,
327 CK_NOTIFICATION event
328 )
329 {
330 CK_RV error = CKR_OK;
331 CK_SESSION_HANDLE handle;
332
333 #ifdef NSSDEBUG
334 error = nssCKFWSession_verifyPointer(fwSession);
335 if( CKR_OK != error ) {
336 return error;
337 }
338 #endif /* NSSDEBUG */
339
340 if( (CK_NOTIFY)NULL == fwSession->Notify ) {
341 return CKR_OK;
342 }
343
344 handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession);
345 if( (CK_SESSION_HANDLE)0 == handle ) {
346 return CKR_GENERAL_ERROR;
347 }
348
349 error = fwSession->Notify(handle, event, fwSession->pApplication);
350
351 return error;
352 }
353
354 /*
355 * nssCKFWSession_IsRWSession
356 *
357 */
358 NSS_IMPLEMENT CK_BBOOL
359 nssCKFWSession_IsRWSession
360 (
361 NSSCKFWSession *fwSession
362 )
363 {
364 #ifdef NSSDEBUG
365 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
366 return CK_FALSE;
367 }
368 #endif /* NSSDEBUG */
369
370 return fwSession->rw;
371 }
372
373 /*
374 * nssCKFWSession_IsSO
375 *
376 */
377 NSS_IMPLEMENT CK_BBOOL
378 nssCKFWSession_IsSO
379 (
380 NSSCKFWSession *fwSession
381 )
382 {
383 CK_STATE state;
384
385 #ifdef NSSDEBUG
386 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
387 return CK_FALSE;
388 }
389 #endif /* NSSDEBUG */
390
391 state = nssCKFWToken_GetSessionState(fwSession->fwToken);
392 switch( state ) {
393 case CKS_RO_PUBLIC_SESSION:
394 case CKS_RO_USER_FUNCTIONS:
395 case CKS_RW_PUBLIC_SESSION:
396 case CKS_RW_USER_FUNCTIONS:
397 return CK_FALSE;
398 case CKS_RW_SO_FUNCTIONS:
399 return CK_TRUE;
400 default:
401 return CK_FALSE;
402 }
403 }
404
405 /*
406 * nssCKFWSession_GetFWSlot
407 *
408 */
409 NSS_IMPLEMENT NSSCKFWSlot *
410 nssCKFWSession_GetFWSlot
411 (
412 NSSCKFWSession *fwSession
413 )
414 {
415 #ifdef NSSDEBUG
416 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
417 return (NSSCKFWSlot *)NULL;
418 }
419 #endif /* NSSDEBUG */
420
421 return nssCKFWToken_GetFWSlot(fwSession->fwToken);
422 }
423
424 /*
425 * nssCFKWSession_GetSessionState
426 *
427 */
428 NSS_IMPLEMENT CK_STATE
429 nssCKFWSession_GetSessionState
430 (
431 NSSCKFWSession *fwSession
432 )
433 {
434 #ifdef NSSDEBUG
435 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
436 return CKS_RO_PUBLIC_SESSION; /* whatever */
437 }
438 #endif /* NSSDEBUG */
439
440 return nssCKFWToken_GetSessionState(fwSession->fwToken);
441 }
442
443 /*
444 * nssCKFWSession_SetFWFindObjects
445 *
446 */
447 NSS_IMPLEMENT CK_RV
448 nssCKFWSession_SetFWFindObjects
449 (
450 NSSCKFWSession *fwSession,
451 NSSCKFWFindObjects *fwFindObjects
452 )
453 {
454 #ifdef NSSDEBUG
455 CK_RV error = CKR_OK;
456 #endif /* NSSDEBUG */
457
458 #ifdef NSSDEBUG
459 error = nssCKFWSession_verifyPointer(fwSession);
460 if( CKR_OK != error ) {
461 return error;
462 }
463
464 /* fwFindObjects may be null */
465 #endif /* NSSDEBUG */
466
467 if ((fwSession->fwFindObjects) &&
468 (fwFindObjects)) {
469 return CKR_OPERATION_ACTIVE;
470 }
471
472 fwSession->fwFindObjects = fwFindObjects;
473
474 return CKR_OK;
475 }
476
477 /*
478 * nssCKFWSession_GetFWFindObjects
479 *
480 */
481 NSS_IMPLEMENT NSSCKFWFindObjects *
482 nssCKFWSession_GetFWFindObjects
483 (
484 NSSCKFWSession *fwSession,
485 CK_RV *pError
486 )
487 {
488 #ifdef NSSDEBUG
489 if (!pError) {
490 return (NSSCKFWFindObjects *)NULL;
491 }
492
493 *pError = nssCKFWSession_verifyPointer(fwSession);
494 if( CKR_OK != *pError ) {
495 return (NSSCKFWFindObjects *)NULL;
496 }
497 #endif /* NSSDEBUG */
498
499 if (!fwSession->fwFindObjects) {
500 *pError = CKR_OPERATION_NOT_INITIALIZED;
501 return (NSSCKFWFindObjects *)NULL;
502 }
503
504 return fwSession->fwFindObjects;
505 }
506
507 /*
508 * nssCKFWSession_SetMDSession
509 *
510 */
511 NSS_IMPLEMENT CK_RV
512 nssCKFWSession_SetMDSession
513 (
514 NSSCKFWSession *fwSession,
515 NSSCKMDSession *mdSession
516 )
517 {
518 #ifdef NSSDEBUG
519 CK_RV error = CKR_OK;
520 #endif /* NSSDEBUG */
521
522 #ifdef NSSDEBUG
523 error = nssCKFWSession_verifyPointer(fwSession);
524 if( CKR_OK != error ) {
525 return error;
526 }
527
528 if (!mdSession) {
529 return CKR_ARGUMENTS_BAD;
530 }
531 #endif /* NSSDEBUG */
532
533 if (fwSession->mdSession) {
534 return CKR_GENERAL_ERROR;
535 }
536
537 fwSession->mdSession = mdSession;
538
539 return CKR_OK;
540 }
541
542 /*
543 * nssCKFWSession_SetHandle
544 *
545 */
546 NSS_IMPLEMENT CK_RV
547 nssCKFWSession_SetHandle
548 (
549 NSSCKFWSession *fwSession,
550 CK_SESSION_HANDLE hSession
551 )
552 {
553 #ifdef NSSDEBUG
554 CK_RV error = CKR_OK;
555 #endif /* NSSDEBUG */
556
557 #ifdef NSSDEBUG
558 error = nssCKFWSession_verifyPointer(fwSession);
559 if( CKR_OK != error ) {
560 return error;
561 }
562 #endif /* NSSDEBUG */
563
564 if( (CK_SESSION_HANDLE)0 != fwSession->hSession ) {
565 return CKR_GENERAL_ERROR;
566 }
567
568 fwSession->hSession = hSession;
569
570 return CKR_OK;
571 }
572
573 /*
574 * nssCKFWSession_GetHandle
575 *
576 */
577 NSS_IMPLEMENT CK_SESSION_HANDLE
578 nssCKFWSession_GetHandle
579 (
580 NSSCKFWSession *fwSession
581 )
582 {
583 #ifdef NSSDEBUG
584 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
585 return NULL;
586 }
587 #endif /* NSSDEBUG */
588
589 return fwSession->hSession;
590 }
591
592 /*
593 * nssCKFWSession_RegisterSessionObject
594 *
595 */
596 NSS_IMPLEMENT CK_RV
597 nssCKFWSession_RegisterSessionObject
598 (
599 NSSCKFWSession *fwSession,
600 NSSCKFWObject *fwObject
601 )
602 {
603 CK_RV rv = CKR_OK;
604
605 #ifdef NSSDEBUG
606 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
607 return CKR_GENERAL_ERROR;
608 }
609 #endif /* NSSDEBUG */
610
611 if (fwSession->sessionObjectHash) {
612 rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
613 }
614
615 return rv;
616 }
617
618 /*
619 * nssCKFWSession_DeregisterSessionObject
620 *
621 */
622 NSS_IMPLEMENT CK_RV
623 nssCKFWSession_DeregisterSessionObject
624 (
625 NSSCKFWSession *fwSession,
626 NSSCKFWObject *fwObject
627 )
628 {
629 #ifdef NSSDEBUG
630 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
631 return CKR_GENERAL_ERROR;
632 }
633 #endif /* NSSDEBUG */
634
635 if (fwSession->sessionObjectHash) {
636 nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);
637 }
638
639 return CKR_OK;
640 }
641
642 /*
643 * nssCKFWSession_GetDeviceError
644 *
645 */
646 NSS_IMPLEMENT CK_ULONG
647 nssCKFWSession_GetDeviceError
648 (
649 NSSCKFWSession *fwSession
650 )
651 {
652 #ifdef NSSDEBUG
653 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
654 return (CK_ULONG)0;
655 }
656
657 if (!fwSession->mdSession) {
658 return (CK_ULONG)0;
659 }
660 #endif /* NSSDEBUG */
661
662 if (!fwSession->mdSession->GetDeviceError) {
663 return (CK_ULONG)0;
664 }
665
666 return fwSession->mdSession->GetDeviceError(fwSession->mdSession,
667 fwSession, fwSession->mdToken, fwSession->fwToken,
668 fwSession->mdInstance, fwSession->fwInstance);
669 }
670
671 /*
672 * nssCKFWSession_Login
673 *
674 */
675 NSS_IMPLEMENT CK_RV
676 nssCKFWSession_Login
677 (
678 NSSCKFWSession *fwSession,
679 CK_USER_TYPE userType,
680 NSSItem *pin
681 )
682 {
683 CK_RV error = CKR_OK;
684 CK_STATE oldState;
685 CK_STATE newState;
686
687 #ifdef NSSDEBUG
688 error = nssCKFWSession_verifyPointer(fwSession);
689 if( CKR_OK != error ) {
690 return error;
691 }
692
693 switch( userType ) {
694 case CKU_SO:
695 case CKU_USER:
696 break;
697 default:
698 return CKR_USER_TYPE_INVALID;
699 }
700
701 if (!pin) {
702 if( CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken) ) {
703 return CKR_ARGUMENTS_BAD;
704 }
705 }
706
707 if (!fwSession->mdSession) {
708 return CKR_GENERAL_ERROR;
709 }
710 #endif /* NSSDEBUG */
711
712 oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
713
714 /*
715 * It's not clear what happens when you're already logged in.
716 * I'll just fail; but if we decide to change, the logic is
717 * all right here.
718 */
719
720 if( CKU_SO == userType ) {
721 switch( oldState ) {
722 case CKS_RO_PUBLIC_SESSION:
723 /*
724 * There's no such thing as a read-only security officer
725 * session, so fail. The error should be CKR_SESSION_READ_ONLY,
726 * except that C_Login isn't defined to return that. So we'll
727 * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented.
728 */
729 return CKR_SESSION_READ_ONLY_EXISTS;
730 case CKS_RO_USER_FUNCTIONS:
731 return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
732 case CKS_RW_PUBLIC_SESSION:
733 newState = CKS_RW_SO_FUNCTIONS;
734 break;
735 case CKS_RW_USER_FUNCTIONS:
736 return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
737 case CKS_RW_SO_FUNCTIONS:
738 return CKR_USER_ALREADY_LOGGED_IN;
739 default:
740 return CKR_GENERAL_ERROR;
741 }
742 } else /* CKU_USER == userType */ {
743 switch( oldState ) {
744 case CKS_RO_PUBLIC_SESSION:
745 newState = CKS_RO_USER_FUNCTIONS;
746 break;
747 case CKS_RO_USER_FUNCTIONS:
748 return CKR_USER_ALREADY_LOGGED_IN;
749 case CKS_RW_PUBLIC_SESSION:
750 newState = CKS_RW_USER_FUNCTIONS;
751 break;
752 case CKS_RW_USER_FUNCTIONS:
753 return CKR_USER_ALREADY_LOGGED_IN;
754 case CKS_RW_SO_FUNCTIONS:
755 return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
756 default:
757 return CKR_GENERAL_ERROR;
758 }
759 }
760
761 /*
762 * So now we're in one of three cases:
763 *
764 * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS;
765 * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS;
766 * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS;
767 */
768
769 if (!fwSession->mdSession->Login) {
770 /*
771 * The Module doesn't want to be informed (or check the pin)
772 * it'll just rely on the Framework as needed.
773 */
774 ;
775 } else {
776 error = fwSession->mdSession->Login(fwSession->mdSession, fwSession,
777 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
778 fwSession->fwInstance, userType, pin, oldState, newState);
779 if( CKR_OK != error ) {
780 return error;
781 }
782 }
783
784 (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
785 return CKR_OK;
786 }
787
788 /*
789 * nssCKFWSession_Logout
790 *
791 */
792 NSS_IMPLEMENT CK_RV
793 nssCKFWSession_Logout
794 (
795 NSSCKFWSession *fwSession
796 )
797 {
798 CK_RV error = CKR_OK;
799 CK_STATE oldState;
800 CK_STATE newState;
801
802 #ifdef NSSDEBUG
803 error = nssCKFWSession_verifyPointer(fwSession);
804 if( CKR_OK != error ) {
805 return error;
806 }
807
808 if (!fwSession->mdSession) {
809 return CKR_GENERAL_ERROR;
810 }
811 #endif /* NSSDEBUG */
812
813 oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
814
815 switch( oldState ) {
816 case CKS_RO_PUBLIC_SESSION:
817 return CKR_USER_NOT_LOGGED_IN;
818 case CKS_RO_USER_FUNCTIONS:
819 newState = CKS_RO_PUBLIC_SESSION;
820 break;
821 case CKS_RW_PUBLIC_SESSION:
822 return CKR_USER_NOT_LOGGED_IN;
823 case CKS_RW_USER_FUNCTIONS:
824 newState = CKS_RW_PUBLIC_SESSION;
825 break;
826 case CKS_RW_SO_FUNCTIONS:
827 newState = CKS_RW_PUBLIC_SESSION;
828 break;
829 default:
830 return CKR_GENERAL_ERROR;
831 }
832
833 /*
834 * So now we're in one of three cases:
835 *
836 * Old == CKS_RW_SO_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
837 * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
838 * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION;
839 */
840
841 if (!fwSession->mdSession->Logout) {
842 /*
843 * The Module doesn't want to be informed. Okay.
844 */
845 ;
846 } else {
847 error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession,
848 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
849 fwSession->fwInstance, oldState, newState);
850 if( CKR_OK != error ) {
851 /*
852 * Now what?! A failure really should end up with the Framework
853 * considering it logged out, right?
854 */
855 ;
856 }
857 }
858
859 (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
860 return error;
861 }
862
863 /*
864 * nssCKFWSession_InitPIN
865 *
866 */
867 NSS_IMPLEMENT CK_RV
868 nssCKFWSession_InitPIN
869 (
870 NSSCKFWSession *fwSession,
871 NSSItem *pin
872 )
873 {
874 CK_RV error = CKR_OK;
875 CK_STATE state;
876
877 #ifdef NSSDEBUG
878 error = nssCKFWSession_verifyPointer(fwSession);
879 if( CKR_OK != error ) {
880 return error;
881 }
882
883 if (!fwSession->mdSession) {
884 return CKR_GENERAL_ERROR;
885 }
886 #endif /* NSSDEBUG */
887
888 state = nssCKFWToken_GetSessionState(fwSession->fwToken);
889 if( CKS_RW_SO_FUNCTIONS != state ) {
890 return CKR_USER_NOT_LOGGED_IN;
891 }
892
893 if (!pin) {
894 CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
895 if( CK_TRUE != has ) {
896 return CKR_ARGUMENTS_BAD;
897 }
898 }
899
900 if (!fwSession->mdSession->InitPIN) {
901 return CKR_TOKEN_WRITE_PROTECTED;
902 }
903
904 error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,
905 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
906 fwSession->fwInstance, pin);
907
908 return error;
909 }
910
911 /*
912 * nssCKFWSession_SetPIN
913 *
914 */
915 NSS_IMPLEMENT CK_RV
916 nssCKFWSession_SetPIN
917 (
918 NSSCKFWSession *fwSession,
919 NSSItem *newPin,
920 NSSItem *oldPin
921 )
922 {
923 CK_RV error = CKR_OK;
924
925 #ifdef NSSDEBUG
926 error = nssCKFWSession_verifyPointer(fwSession);
927 if( CKR_OK != error ) {
928 return error;
929 }
930
931 if (!fwSession->mdSession) {
932 return CKR_GENERAL_ERROR;
933 }
934 #endif /* NSSDEBUG */
935
936 if (!newPin) {
937 CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
938 if( CK_TRUE != has ) {
939 return CKR_ARGUMENTS_BAD;
940 }
941 }
942
943 if (!oldPin) {
944 CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
945 if( CK_TRUE != has ) {
946 return CKR_ARGUMENTS_BAD;
947 }
948 }
949
950 if (!fwSession->mdSession->SetPIN) {
951 return CKR_TOKEN_WRITE_PROTECTED;
952 }
953
954 error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,
955 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
956 fwSession->fwInstance, newPin, oldPin);
957
958 return error;
959 }
960
961 /*
962 * nssCKFWSession_GetOperationStateLen
963 *
964 */
965 NSS_IMPLEMENT CK_ULONG
966 nssCKFWSession_GetOperationStateLen
967 (
968 NSSCKFWSession *fwSession,
969 CK_RV *pError
970 )
971 {
972 CK_ULONG mdAmt;
973 CK_ULONG fwAmt;
974
975 #ifdef NSSDEBUG
976 if (!pError) {
977 return (CK_ULONG)0;
978 }
979
980 *pError = nssCKFWSession_verifyPointer(fwSession);
981 if( CKR_OK != *pError ) {
982 return (CK_ULONG)0;
983 }
984
985 if (!fwSession->mdSession) {
986 *pError = CKR_GENERAL_ERROR;
987 return (CK_ULONG)0;
988 }
989 #endif /* NSSDEBUG */
990
991 if (!fwSession->mdSession->GetOperationStateLen) {
992 *pError = CKR_STATE_UNSAVEABLE;
993 return (CK_ULONG)0;
994 }
995
996 /*
997 * We could check that the session is actually in some state..
998 */
999
1000 mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession,
1001 fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
1002 fwSession->fwInstance, pError);
1003
1004 if( ((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError) ) {
1005 return (CK_ULONG)0;
1006 }
1007
1008 /*
1009 * Add a bit of sanity-checking
1010 */
1011 fwAmt = mdAmt + 2*sizeof(CK_ULONG);
1012
1013 return fwAmt;
1014 }
1015
1016 /*
1017 * nssCKFWSession_GetOperationState
1018 *
1019 */
1020 NSS_IMPLEMENT CK_RV
1021 nssCKFWSession_GetOperationState
1022 (
1023 NSSCKFWSession *fwSession,
1024 NSSItem *buffer
1025 )
1026 {
1027 CK_RV error = CKR_OK;
1028 CK_ULONG fwAmt;
1029 CK_ULONG *ulBuffer;
1030 NSSItem i2;
1031 CK_ULONG n, i;
1032
1033 #ifdef NSSDEBUG
1034 error = nssCKFWSession_verifyPointer(fwSession);
1035 if( CKR_OK != error ) {
1036 return error;
1037 }
1038
1039 if (!buffer) {
1040 return CKR_ARGUMENTS_BAD;
1041 }
1042
1043 if (!buffer->data) {
1044 return CKR_ARGUMENTS_BAD;
1045 }
1046
1047 if (!fwSession->mdSession) {
1048 return CKR_GENERAL_ERROR;
1049 }
1050 #endif /* NSSDEBUG */
1051
1052 if (!fwSession->mdSession->GetOperationState) {
1053 return CKR_STATE_UNSAVEABLE;
1054 }
1055
1056 /*
1057 * Sanity-check the caller's buffer.
1058 */
1059
1060 error = CKR_OK;
1061 fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);
1062 if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) {
1063 return error;
1064 }
1065
1066 if( buffer->size < fwAmt ) {
1067 return CKR_BUFFER_TOO_SMALL;
1068 }
1069
1070 ulBuffer = (CK_ULONG *)buffer->data;
1071
1072 i2.size = buffer->size - 2*sizeof(CK_ULONG);
1073 i2.data = (void *)&ulBuffer[2];
1074
1075 error = fwSession->mdSession->GetOperationState(fwSession->mdSession,
1076 fwSession, fwSession->mdToken, fwSession->fwToken,
1077 fwSession->mdInstance, fwSession->fwInstance, &i2);
1078
1079 if( CKR_OK != error ) {
1080 return error;
1081 }
1082
1083 /*
1084 * Add a little integrety/identity check.
1085 * NOTE: right now, it's pretty stupid.
1086 * A CRC or something would be better.
1087 */
1088
1089 ulBuffer[0] = 0x434b4657; /* CKFW */
1090 ulBuffer[1] = 0;
1091 n = i2.size/sizeof(CK_ULONG);
1092 for( i = 0; i < n; i++ ) {
1093 ulBuffer[1] ^= ulBuffer[2+i];
1094 }
1095
1096 return CKR_OK;
1097 }
1098
1099 /*
1100 * nssCKFWSession_SetOperationState
1101 *
1102 */
1103 NSS_IMPLEMENT CK_RV
1104 nssCKFWSession_SetOperationState
1105 (
1106 NSSCKFWSession *fwSession,
1107 NSSItem *state,
1108 NSSCKFWObject *encryptionKey,
1109 NSSCKFWObject *authenticationKey
1110 )
1111 {
1112 CK_RV error = CKR_OK;
1113 CK_ULONG *ulBuffer;
1114 CK_ULONG n, i;
1115 CK_ULONG x;
1116 NSSItem s;
1117 NSSCKMDObject *mdek;
1118 NSSCKMDObject *mdak;
1119
1120 #ifdef NSSDEBUG
1121 error = nssCKFWSession_verifyPointer(fwSession);
1122 if( CKR_OK != error ) {
1123 return error;
1124 }
1125
1126 if (!state) {
1127 return CKR_ARGUMENTS_BAD;
1128 }
1129
1130 if (!state->data) {
1131 return CKR_ARGUMENTS_BAD;
1132 }
1133
1134 if (encryptionKey) {
1135 error = nssCKFWObject_verifyPointer(encryptionKey);
1136 if( CKR_OK != error ) {
1137 return error;
1138 }
1139 }
1140
1141 if (authenticationKey) {
1142 error = nssCKFWObject_verifyPointer(authenticationKey);
1143 if( CKR_OK != error ) {
1144 return error;
1145 }
1146 }
1147
1148 if (!fwSession->mdSession) {
1149 return CKR_GENERAL_ERROR;
1150 }
1151 #endif /* NSSDEBUG */
1152
1153 ulBuffer = (CK_ULONG *)state->data;
1154 if( 0x43b4657 != ulBuffer[0] ) {
1155 return CKR_SAVED_STATE_INVALID;
1156 }
1157 n = (state->size / sizeof(CK_ULONG)) - 2;
1158 x = (CK_ULONG)0;
1159 for( i = 0; i < n; i++ ) {
1160 x ^= ulBuffer[2+i];
1161 }
1162
1163 if( x != ulBuffer[1] ) {
1164 return CKR_SAVED_STATE_INVALID;
1165 }
1166
1167 if (!fwSession->mdSession->SetOperationState) {
1168 return CKR_GENERAL_ERROR;
1169 }
1170
1171 s.size = state->size - 2*sizeof(CK_ULONG);
1172 s.data = (void *)&ulBuffer[2];
1173
1174 if (encryptionKey) {
1175 mdek = nssCKFWObject_GetMDObject(encryptionKey);
1176 } else {
1177 mdek = (NSSCKMDObject *)NULL;
1178 }
1179
1180 if (authenticationKey) {
1181 mdak = nssCKFWObject_GetMDObject(authenticationKey);
1182 } else {
1183 mdak = (NSSCKMDObject *)NULL;
1184 }
1185
1186 error = fwSession->mdSession->SetOperationState(fwSession->mdSession,
1187 fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
1188 fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey);
1189
1190 if( CKR_OK != error ) {
1191 return error;
1192 }
1193
1194 /*
1195 * Here'd we restore any session data
1196 */
1197
1198 return CKR_OK;
1199 }
1200
1201 static CK_BBOOL
1202 nss_attributes_form_token_object
1203 (
1204 CK_ATTRIBUTE_PTR pTemplate,
1205 CK_ULONG ulAttributeCount
1206 )
1207 {
1208 CK_ULONG i;
1209 CK_BBOOL rv;
1210
1211 for( i = 0; i < ulAttributeCount; i++ ) {
1212 if( CKA_TOKEN == pTemplate[i].type ) {
1213 /* If we sanity-check, we can remove this sizeof check */
1214 if( sizeof(CK_BBOOL) == pTemplate[i].ulValueLen ) {
1215 (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL));
1216 return rv;
1217 } else {
1218 return CK_FALSE;
1219 }
1220 }
1221 }
1222
1223 return CK_FALSE;
1224 }
1225
1226 /*
1227 * nssCKFWSession_CreateObject
1228 *
1229 */
1230 NSS_IMPLEMENT NSSCKFWObject *
1231 nssCKFWSession_CreateObject
1232 (
1233 NSSCKFWSession *fwSession,
1234 CK_ATTRIBUTE_PTR pTemplate,
1235 CK_ULONG ulAttributeCount,
1236 CK_RV *pError
1237 )
1238 {
1239 NSSArena *arena;
1240 NSSCKMDObject *mdObject;
1241 NSSCKFWObject *fwObject;
1242 CK_BBOOL isTokenObject;
1243
1244 #ifdef NSSDEBUG
1245 if (!pError) {
1246 return (NSSCKFWObject *)NULL;
1247 }
1248
1249 *pError = nssCKFWSession_verifyPointer(fwSession);
1250 if( CKR_OK != pError ) {
1251 return (NSSCKFWObject *)NULL;
1252 }
1253
1254 if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
1255 *pError = CKR_ARGUMENTS_BAD;
1256 return (NSSCKFWObject *)NULL;
1257 }
1258
1259 if (!fwSession->mdSession) {
1260 *pError = CKR_GENERAL_ERROR;
1261 return (NSSCKFWObject *)NULL;
1262 }
1263 #endif /* NSSDEBUG */
1264
1265 /*
1266 * Here would be an excellent place to sanity-check the object.
1267 */
1268
1269 isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount);
1270 if( CK_TRUE == isTokenObject ) {
1271 /* === TOKEN OBJECT === */
1272
1273 if (!fwSession->mdSession->CreateObject) {
1274 *pError = CKR_TOKEN_WRITE_PROTECTED;
1275 return (NSSCKFWObject *)NULL;
1276 }
1277
1278 arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
1279 if (!arena) {
1280 if( CKR_OK == *pError ) {
1281 *pError = CKR_GENERAL_ERROR;
1282 }
1283 return (NSSCKFWObject *)NULL;
1284 }
1285
1286 goto callmdcreateobject;
1287 } else {
1288 /* === SESSION OBJECT === */
1289
1290 arena = nssCKFWSession_GetArena(fwSession, pError);
1291 if (!arena) {
1292 if( CKR_OK == *pError ) {
1293 *pError = CKR_GENERAL_ERROR;
1294 }
1295 return (NSSCKFWObject *)NULL;
1296 }
1297
1298 if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
1299 fwSession->fwInstance) ) {
1300 /* --- module handles the session object -- */
1301
1302 if (!fwSession->mdSession->CreateObject) {
1303 *pError = CKR_GENERAL_ERROR;
1304 return (NSSCKFWObject *)NULL;
1305 }
1306
1307 goto callmdcreateobject;
1308 } else {
1309 /* --- framework handles the session object -- */
1310 mdObject = nssCKMDSessionObject_Create(fwSession->fwToken,
1311 arena, pTemplate, ulAttributeCount, pError);
1312 goto gotmdobject;
1313 }
1314 }
1315
1316 callmdcreateobject:
1317 mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession,
1318 fwSession, fwSession->mdToken, fwSession->fwToken,
1319 fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate,
1320 ulAttributeCount, pError);
1321
1322 gotmdobject:
1323 if (!mdObject) {
1324 if( CKR_OK == *pError ) {
1325 *pError = CKR_GENERAL_ERROR;
1326 }
1327 return (NSSCKFWObject *)NULL;
1328 }
1329
1330 fwObject = nssCKFWObject_Create(arena, mdObject,
1331 isTokenObject ? NULL : fwSession,
1332 fwSession->fwToken, fwSession->fwInstance, pError);
1333 if (!fwObject) {
1334 if( CKR_OK == *pError ) {
1335 *pError = CKR_GENERAL_ERROR;
1336 }
1337
1338 if (mdObject->Destroy) {
1339 (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
1340 fwSession->mdSession, fwSession, fwSession->mdToken,
1341 fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
1342 }
1343
1344 return (NSSCKFWObject *)NULL;
1345 }
1346
1347 if( CK_FALSE == isTokenObject ) {
1348 if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, fwObject) ) {
1349 *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
1350 if( CKR_OK != *pError ) {
1351 nssCKFWObject_Finalize(fwObject, PR_TRUE);
1352 return (NSSCKFWObject *)NULL;
1353 }
1354 }
1355 }
1356
1357 return fwObject;
1358 }
1359
1360 /*
1361 * nssCKFWSession_CopyObject
1362 *
1363 */
1364 NSS_IMPLEMENT NSSCKFWObject *
1365 nssCKFWSession_CopyObject
1366 (
1367 NSSCKFWSession *fwSession,
1368 NSSCKFWObject *fwObject,
1369 CK_ATTRIBUTE_PTR pTemplate,
1370 CK_ULONG ulAttributeCount,
1371 CK_RV *pError
1372 )
1373 {
1374 CK_BBOOL oldIsToken;
1375 CK_BBOOL newIsToken;
1376 CK_ULONG i;
1377 NSSCKFWObject *rv;
1378
1379 #ifdef NSSDEBUG
1380 if (!pError) {
1381 return (NSSCKFWObject *)NULL;
1382 }
1383
1384 *pError = nssCKFWSession_verifyPointer(fwSession);
1385 if( CKR_OK != *pError ) {
1386 return (NSSCKFWObject *)NULL;
1387 }
1388
1389 *pError = nssCKFWObject_verifyPointer(fwObject);
1390 if( CKR_OK != *pError ) {
1391 return (NSSCKFWObject *)NULL;
1392 }
1393
1394 if (!fwSession->mdSession) {
1395 *pError = CKR_GENERAL_ERROR;
1396 return (NSSCKFWObject *)NULL;
1397 }
1398 #endif /* NSSDEBUG */
1399
1400 /*
1401 * Sanity-check object
1402 */
1403
1404 if (!fwObject) {
1405 *pError = CKR_ARGUMENTS_BAD;
1406 return (NSSCKFWObject *)NULL;
1407 }
1408
1409 oldIsToken = nssCKFWObject_IsTokenObject(fwObject);
1410
1411 newIsToken = oldIsToken;
1412 for( i = 0; i < ulAttributeCount; i++ ) {
1413 if( CKA_TOKEN == pTemplate[i].type ) {
1414 /* Since we sanity-checked the object, we know this is the right size. */
1415 (void)nsslibc_memcpy(&newIsToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
1416 break;
1417 }
1418 }
1419
1420 /*
1421 * If the Module handles its session objects, or if both the new
1422 * and old object are token objects, use CopyObject if it exists.
1423 */
1424
1425 if ((fwSession->mdSession->CopyObject) &&
1426 (((CK_TRUE == oldIsToken) && (CK_TRUE == newIsToken)) ||
1427 (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
1428 fwSession->fwInstance))) ) {
1429 /* use copy object */
1430 NSSArena *arena;
1431 NSSCKMDObject *mdOldObject;
1432 NSSCKMDObject *mdObject;
1433
1434 mdOldObject = nssCKFWObject_GetMDObject(fwObject);
1435
1436 if( CK_TRUE == newIsToken ) {
1437 arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
1438 } else {
1439 arena = nssCKFWSession_GetArena(fwSession, pError);
1440 }
1441 if (!arena) {
1442 if( CKR_OK == *pError ) {
1443 *pError = CKR_GENERAL_ERROR;
1444 }
1445 return (NSSCKFWObject *)NULL;
1446 }
1447
1448 mdObject = fwSession->mdSession->CopyObject(fwSession->mdSession,
1449 fwSession, fwSession->mdToken, fwSession->fwToken,
1450 fwSession->mdInstance, fwSession->fwInstance, mdOldObject,
1451 fwObject, arena, pTemplate, ulAttributeCount, pError);
1452 if (!mdObject) {
1453 if( CKR_OK == *pError ) {
1454 *pError = CKR_GENERAL_ERROR;
1455 }
1456 return (NSSCKFWObject *)NULL;
1457 }
1458
1459 rv = nssCKFWObject_Create(arena, mdObject,
1460 newIsToken ? NULL : fwSession,
1461 fwSession->fwToken, fwSession->fwInstance, pError);
1462
1463 if( CK_FALSE == newIsToken ) {
1464 if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, rv) ) {
1465 *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, rv, rv);
1466 if( CKR_OK != *pError ) {
1467 nssCKFWObject_Finalize(rv, PR_TRUE);
1468 return (NSSCKFWObject *)NULL;
1469 }
1470 }
1471 }
1472
1473 return rv;
1474 } else {
1475 /* use create object */
1476 NSSArena *tmpArena;
1477 CK_ATTRIBUTE_PTR newTemplate;
1478 CK_ULONG i, j, n, newLength, k;
1479 CK_ATTRIBUTE_TYPE_PTR oldTypes;
1480 NSSCKFWObject *rv;
1481
1482 n = nssCKFWObject_GetAttributeCount(fwObject, pError);
1483 if( (0 == n) && (CKR_OK != *pError) ) {
1484 return (NSSCKFWObject *)NULL;
1485 }
1486
1487 tmpArena = NSSArena_Create();
1488 if (!tmpArena) {
1489 *pError = CKR_HOST_MEMORY;
1490 return (NSSCKFWObject *)NULL;
1491 }
1492
1493 oldTypes = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE_TYPE, n);
1494 if( (CK_ATTRIBUTE_TYPE_PTR)NULL == oldTypes ) {
1495 NSSArena_Destroy(tmpArena);
1496 *pError = CKR_HOST_MEMORY;
1497 return (NSSCKFWObject *)NULL;
1498 }
1499
1500 *pError = nssCKFWObject_GetAttributeTypes(fwObject, oldTypes, n);
1501 if( CKR_OK != *pError ) {
1502 NSSArena_Destroy(tmpArena);
1503 return (NSSCKFWObject *)NULL;
1504 }
1505
1506 newLength = n;
1507 for( i = 0; i < ulAttributeCount; i++ ) {
1508 for( j = 0; j < n; j++ ) {
1509 if( oldTypes[j] == pTemplate[i].type ) {
1510 if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) {
1511 /* Removing the attribute */
1512 newLength--;
1513 }
1514 break;
1515 }
1516 }
1517 if( j == n ) {
1518 /* Not found */
1519 newLength++;
1520 }
1521 }
1522
1523 newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, newLength);
1524 if( (CK_ATTRIBUTE_PTR)NULL == newTemplate ) {
1525 NSSArena_Destroy(tmpArena);
1526 *pError = CKR_HOST_MEMORY;
1527 return (NSSCKFWObject *)NULL;
1528 }
1529
1530 k = 0;
1531 for( j = 0; j < n; j++ ) {
1532 for( i = 0; i < ulAttributeCount; i++ ) {
1533 if( oldTypes[j] == pTemplate[i].type ) {
1534 if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) {
1535 /* This attribute is being deleted */
1536 ;
1537 } else {
1538 /* This attribute is being replaced */
1539 newTemplate[k].type = pTemplate[i].type;
1540 newTemplate[k].pValue = pTemplate[i].pValue;
1541 newTemplate[k].ulValueLen = pTemplate[i].ulValueLen;
1542 k++;
1543 }
1544 break;
1545 }
1546 }
1547 if( i == ulAttributeCount ) {
1548 /* This attribute is being copied over from the old object */
1549 NSSItem item, *it;
1550 item.size = 0;
1551 item.data = (void *)NULL;
1552 it = nssCKFWObject_GetAttribute(fwObject, oldTypes[j],
1553 &item, tmpArena, pError);
1554 if (!it) {
1555 if( CKR_OK == *pError ) {
1556 *pError = CKR_GENERAL_ERROR;
1557 }
1558 NSSArena_Destroy(tmpArena);
1559 return (NSSCKFWObject *)NULL;
1560 }
1561 newTemplate[k].type = oldTypes[j];
1562 newTemplate[k].pValue = it->data;
1563 newTemplate[k].ulValueLen = it->size;
1564 k++;
1565 }
1566 }
1567 /* assert that k == newLength */
1568
1569 rv = nssCKFWSession_CreateObject(fwSession, newTemplate, newLength, pError);
1570 if (!rv) {
1571 if( CKR_OK == *pError ) {
1572 *pError = CKR_GENERAL_ERROR;
1573 }
1574 NSSArena_Destroy(tmpArena);
1575 return (NSSCKFWObject *)NULL;
1576 }
1577
1578 NSSArena_Destroy(tmpArena);
1579 return rv;
1580 }
1581 }
1582
1583 /*
1584 * nssCKFWSession_FindObjectsInit
1585 *
1586 */
1587 NSS_IMPLEMENT NSSCKFWFindObjects *
1588 nssCKFWSession_FindObjectsInit
1589 (
1590 NSSCKFWSession *fwSession,
1591 CK_ATTRIBUTE_PTR pTemplate,
1592 CK_ULONG ulAttributeCount,
1593 CK_RV *pError
1594 )
1595 {
1596 NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL;
1597 NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL;
1598
1599 #ifdef NSSDEBUG
1600 if (!pError) {
1601 return (NSSCKFWFindObjects *)NULL;
1602 }
1603
1604 *pError = nssCKFWSession_verifyPointer(fwSession);
1605 if( CKR_OK != *pError ) {
1606 return (NSSCKFWFindObjects *)NULL;
1607 }
1608
1609 if( ((CK_ATTRIBUTE_PTR)NULL == pTemplate) && (ulAttributeCount != 0) ) {
1610 *pError = CKR_ARGUMENTS_BAD;
1611 return (NSSCKFWFindObjects *)NULL;
1612 }
1613
1614 if (!fwSession->mdSession) {
1615 *pError = CKR_GENERAL_ERROR;
1616 return (NSSCKFWFindObjects *)NULL;
1617 }
1618 #endif /* NSSDEBUG */
1619
1620 if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
1621 fwSession->fwInstance) ) {
1622 CK_ULONG i;
1623
1624 /*
1625 * Does the search criteria restrict us to token or session
1626 * objects?
1627 */
1628
1629 for( i = 0; i < ulAttributeCount; i++ ) {
1630 if( CKA_TOKEN == pTemplate[i].type ) {
1631 /* Yes, it does. */
1632 CK_BBOOL isToken;
1633 if( sizeof(CK_BBOOL) != pTemplate[i].ulValueLen ) {
1634 *pError = CKR_ATTRIBUTE_VALUE_INVALID;
1635 return (NSSCKFWFindObjects *)NULL;
1636 }
1637 (void)nsslibc_memcpy(&isToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
1638
1639 if( CK_TRUE == isToken ) {
1640 /* Pass it on to the module's search routine */
1641 if (!fwSession->mdSession->FindObjectsInit) {
1642 goto wrap;
1643 }
1644
1645 mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
1646 fwSession, fwSession->mdToken, fwSession->fwToken,
1647 fwSession->mdInstance, fwSession->fwInstance,
1648 pTemplate, ulAttributeCount, pError);
1649 } else {
1650 /* Do the search ourselves */
1651 mdfo1 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
1652 pTemplate, ulAttributeCount, pError);
1653 }
1654
1655 if (!mdfo1) {
1656 if( CKR_OK == *pError ) {
1657 *pError = CKR_GENERAL_ERROR;
1658 }
1659 return (NSSCKFWFindObjects *)NULL;
1660 }
1661
1662 goto wrap;
1663 }
1664 }
1665
1666 if( i == ulAttributeCount ) {
1667 /* No, it doesn't. Do a hybrid search. */
1668 mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
1669 fwSession, fwSession->mdToken, fwSession->fwToken,
1670 fwSession->mdInstance, fwSession->fwInstance,
1671 pTemplate, ulAttributeCount, pError);
1672
1673 if (!mdfo1) {
1674 if( CKR_OK == *pError ) {
1675 *pError = CKR_GENERAL_ERROR;
1676 }
1677 return (NSSCKFWFindObjects *)NULL;
1678 }
1679
1680 mdfo2 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
1681 pTemplate, ulAttributeCount, pError);
1682 if (!mdfo2) {
1683 if( CKR_OK == *pError ) {
1684 *pError = CKR_GENERAL_ERROR;
1685 }
1686 if (mdfo1->Final) {
1687 mdfo1->Final(mdfo1, (NSSCKFWFindObjects *)NULL, fwSession->mdSession,
1688 fwSession, fwSession->mdToken, fwSession->fwToken,
1689 fwSession->mdInstance, fwSession->fwInstance);
1690 }
1691 return (NSSCKFWFindObjects *)NULL;
1692 }
1693
1694 goto wrap;
1695 }
1696 /*NOTREACHED*/
1697 } else {
1698 /* Module handles all its own objects. Pass on to module's search */
1699 mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
1700 fwSession, fwSession->mdToken, fwSession->fwToken,
1701 fwSession->mdInstance, fwSession->fwInstance,
1702 pTemplate, ulAttributeCount, pError);
1703
1704 if (!mdfo1) {
1705 if( CKR_OK == *pError ) {
1706 *pError = CKR_GENERAL_ERROR;
1707 }
1708 return (NSSCKFWFindObjects *)NULL;
1709 }
1710
1711 goto wrap;
1712 }
1713
1714 wrap:
1715 return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
1716 fwSession->fwInstance, mdfo1, mdfo2, pError);
1717 }
1718
1719 /*
1720 * nssCKFWSession_SeedRandom
1721 *
1722 */
1723 NSS_IMPLEMENT CK_RV
1724 nssCKFWSession_SeedRandom
1725 (
1726 NSSCKFWSession *fwSession,
1727 NSSItem *seed
1728 )
1729 {
1730 CK_RV error = CKR_OK;
1731
1732 #ifdef NSSDEBUG
1733 error = nssCKFWSession_verifyPointer(fwSession);
1734 if( CKR_OK != error ) {
1735 return error;
1736 }
1737
1738 if (!seed) {
1739 return CKR_ARGUMENTS_BAD;
1740 }
1741
1742 if (!seed->data) {
1743 return CKR_ARGUMENTS_BAD;
1744 }
1745
1746 if( 0 == seed->size ) {
1747 return CKR_ARGUMENTS_BAD;
1748 }
1749
1750 if (!fwSession->mdSession) {
1751 return CKR_GENERAL_ERROR;
1752 }
1753 #endif /* NSSDEBUG */
1754
1755 if (!fwSession->mdSession->SeedRandom) {
1756 return CKR_RANDOM_SEED_NOT_SUPPORTED;
1757 }
1758
1759 error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession,
1760 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
1761 fwSession->fwInstance, seed);
1762
1763 return error;
1764 }
1765
1766 /*
1767 * nssCKFWSession_GetRandom
1768 *
1769 */
1770 NSS_IMPLEMENT CK_RV
1771 nssCKFWSession_GetRandom
1772 (
1773 NSSCKFWSession *fwSession,
1774 NSSItem *buffer
1775 )
1776 {
1777 CK_RV error = CKR_OK;
1778
1779 #ifdef NSSDEBUG
1780 error = nssCKFWSession_verifyPointer(fwSession);
1781 if( CKR_OK != error ) {
1782 return error;
1783 }
1784
1785 if (!buffer) {
1786 return CKR_ARGUMENTS_BAD;
1787 }
1788
1789 if (!buffer->data) {
1790 return CKR_ARGUMENTS_BAD;
1791 }
1792
1793 if (!fwSession->mdSession) {
1794 return CKR_GENERAL_ERROR;
1795 }
1796 #endif /* NSSDEBUG */
1797
1798 if (!fwSession->mdSession->GetRandom) {
1799 if( CK_TRUE == nssCKFWToken_GetHasRNG(fwSession->fwToken) ) {
1800 return CKR_GENERAL_ERROR;
1801 } else {
1802 return CKR_RANDOM_NO_RNG;
1803 }
1804 }
1805
1806 if( 0 == buffer->size ) {
1807 return CKR_OK;
1808 }
1809
1810 error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
1811 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
1812 fwSession->fwInstance, buffer);
1813
1814 return error;
1815 }
1816
1817
1818 /*
1819 * nssCKFWSession_SetCurrentCryptoOperation
1820 */
1821 NSS_IMPLEMENT void
1822 nssCKFWSession_SetCurrentCryptoOperation
1823 (
1824 NSSCKFWSession *fwSession,
1825 NSSCKFWCryptoOperation * fwOperation,
1826 NSSCKFWCryptoOperationState state
1827 )
1828 {
1829 #ifdef NSSDEBUG
1830 CK_RV error = CKR_OK;
1831 error = nssCKFWSession_verifyPointer(fwSession);
1832 if( CKR_OK != error ) {
1833 return;
1834 }
1835
1836 if ( state >= NSSCKFWCryptoOperationState_Max) {
1837 return;
1838 }
1839
1840 if (!fwSession->mdSession) {
1841 return;
1842 }
1843 #endif /* NSSDEBUG */
1844 fwSession->fwOperationArray[state] = fwOperation;
1845 return;
1846 }
1847
1848 /*
1849 * nssCKFWSession_GetCurrentCryptoOperation
1850 */
1851 NSS_IMPLEMENT NSSCKFWCryptoOperation *
1852 nssCKFWSession_GetCurrentCryptoOperation
1853 (
1854 NSSCKFWSession *fwSession,
1855 NSSCKFWCryptoOperationState state
1856 )
1857 {
1858 #ifdef NSSDEBUG
1859 CK_RV error = CKR_OK;
1860 error = nssCKFWSession_verifyPointer(fwSession);
1861 if( CKR_OK != error ) {
1862 return (NSSCKFWCryptoOperation *)NULL;
1863 }
1864
1865 if ( state >= NSSCKFWCryptoOperationState_Max) {
1866 return (NSSCKFWCryptoOperation *)NULL;
1867 }
1868
1869 if (!fwSession->mdSession) {
1870 return (NSSCKFWCryptoOperation *)NULL;
1871 }
1872 #endif /* NSSDEBUG */
1873 return fwSession->fwOperationArray[state];
1874 }
1875
1876 /*
1877 * nssCKFWSession_Final
1878 */
1879 NSS_IMPLEMENT CK_RV
1880 nssCKFWSession_Final
1881 (
1882 NSSCKFWSession *fwSession,
1883 NSSCKFWCryptoOperationType type,
1884 NSSCKFWCryptoOperationState state,
1885 CK_BYTE_PTR outBuf,
1886 CK_ULONG_PTR outBufLen
1887 )
1888 {
1889 NSSCKFWCryptoOperation *fwOperation;
1890 NSSItem outputBuffer;
1891 CK_RV error = CKR_OK;
1892
1893 #ifdef NSSDEBUG
1894 error = nssCKFWSession_verifyPointer(fwSession);
1895 if( CKR_OK != error ) {
1896 return error;
1897 }
1898
1899 if (!fwSession->mdSession) {
1900 return CKR_GENERAL_ERROR;
1901 }
1902 #endif /* NSSDEBUG */
1903
1904 /* make sure we have a valid operation initialized */
1905 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
1906 if (!fwOperation) {
1907 return CKR_OPERATION_NOT_INITIALIZED;
1908 }
1909
1910 /* make sure it's the correct type */
1911 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
1912 return CKR_OPERATION_NOT_INITIALIZED;
1913 }
1914
1915 /* handle buffer issues, note for Verify, the type is an input buffer. */
1916 if (NSSCKFWCryptoOperationType_Verify == type) {
1917 if ((CK_BYTE_PTR)NULL == outBuf) {
1918 error = CKR_ARGUMENTS_BAD;
1919 goto done;
1920 }
1921 } else {
1922 CK_ULONG len = nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
1923 CK_ULONG maxBufLen = *outBufLen;
1924
1925 if (CKR_OK != error) {
1926 goto done;
1927 }
1928 *outBufLen = len;
1929 if ((CK_BYTE_PTR)NULL == outBuf) {
1930 return CKR_OK;
1931 }
1932
1933 if (len > maxBufLen) {
1934 return CKR_BUFFER_TOO_SMALL;
1935 }
1936 }
1937 outputBuffer.data = outBuf;
1938 outputBuffer.size = *outBufLen;
1939
1940 error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
1941 done:
1942 if (CKR_BUFFER_TOO_SMALL == error) {
1943 return error;
1944 }
1945 /* clean up our state */
1946 nssCKFWCryptoOperation_Destroy(fwOperation);
1947 nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
1948 return error;
1949 }
1950
1951 /*
1952 * nssCKFWSession_Update
1953 */
1954 NSS_IMPLEMENT CK_RV
1955 nssCKFWSession_Update
1956 (
1957 NSSCKFWSession *fwSession,
1958 NSSCKFWCryptoOperationType type,
1959 NSSCKFWCryptoOperationState state,
1960 CK_BYTE_PTR inBuf,
1961 CK_ULONG inBufLen,
1962 CK_BYTE_PTR outBuf,
1963 CK_ULONG_PTR outBufLen
1964 )
1965 {
1966 NSSCKFWCryptoOperation *fwOperation;
1967 NSSItem inputBuffer;
1968 NSSItem outputBuffer;
1969 CK_ULONG len;
1970 CK_ULONG maxBufLen;
1971 CK_RV error = CKR_OK;
1972
1973 #ifdef NSSDEBUG
1974 error = nssCKFWSession_verifyPointer(fwSession);
1975 if( CKR_OK != error ) {
1976 return error;
1977 }
1978
1979 if (!fwSession->mdSession) {
1980 return CKR_GENERAL_ERROR;
1981 }
1982 #endif /* NSSDEBUG */
1983
1984 /* make sure we have a valid operation initialized */
1985 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
1986 if (!fwOperation) {
1987 return CKR_OPERATION_NOT_INITIALIZED;
1988 }
1989
1990 /* make sure it's the correct type */
1991 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
1992 return CKR_OPERATION_NOT_INITIALIZED;
1993 }
1994
1995 inputBuffer.data = inBuf;
1996 inputBuffer.size = inBufLen;
1997
1998 /* handle buffer issues, note for Verify, the type is an input buffer. */
1999 len = nssCKFWCryptoOperation_GetOperationLength(fwOperation, &inputBuffer,
2000 &error);
2001 if (CKR_OK != error) {
2002 return error;
2003 }
2004 maxBufLen = *outBufLen;
2005
2006 *outBufLen = len;
2007 if ((CK_BYTE_PTR)NULL == outBuf) {
2008 return CKR_OK;
2009 }
2010
2011 if (len > maxBufLen) {
2012 return CKR_BUFFER_TOO_SMALL;
2013 }
2014 outputBuffer.data = outBuf;
2015 outputBuffer.size = *outBufLen;
2016
2017 return nssCKFWCryptoOperation_Update(fwOperation,
2018 &inputBuffer, &outputBuffer);
2019 }
2020
2021 /*
2022 * nssCKFWSession_DigestUpdate
2023 */
2024 NSS_IMPLEMENT CK_RV
2025 nssCKFWSession_DigestUpdate
2026 (
2027 NSSCKFWSession *fwSession,
2028 NSSCKFWCryptoOperationType type,
2029 NSSCKFWCryptoOperationState state,
2030 CK_BYTE_PTR inBuf,
2031 CK_ULONG inBufLen
2032 )
2033 {
2034 NSSCKFWCryptoOperation *fwOperation;
2035 NSSItem inputBuffer;
2036 CK_RV error = CKR_OK;
2037
2038 #ifdef NSSDEBUG
2039 error = nssCKFWSession_verifyPointer(fwSession);
2040 if( CKR_OK != error ) {
2041 return error;
2042 }
2043
2044 if (!fwSession->mdSession) {
2045 return CKR_GENERAL_ERROR;
2046 }
2047 #endif /* NSSDEBUG */
2048
2049 /* make sure we have a valid operation initialized */
2050 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
2051 if (!fwOperation) {
2052 return CKR_OPERATION_NOT_INITIALIZED;
2053 }
2054
2055 /* make sure it's the correct type */
2056 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
2057 return CKR_OPERATION_NOT_INITIALIZED;
2058 }
2059
2060 inputBuffer.data = inBuf;
2061 inputBuffer.size = inBufLen;
2062
2063
2064 error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
2065 return error;
2066 }
2067
2068 /*
2069 * nssCKFWSession_DigestUpdate
2070 */
2071 NSS_IMPLEMENT CK_RV
2072 nssCKFWSession_DigestKey
2073 (
2074 NSSCKFWSession *fwSession,
2075 NSSCKFWObject *fwKey
2076 )
2077 {
2078 NSSCKFWCryptoOperation *fwOperation;
2079 NSSItem *inputBuffer;
2080 CK_RV error = CKR_OK;
2081
2082 #ifdef NSSDEBUG
2083 error = nssCKFWSession_verifyPointer(fwSession);
2084 if( CKR_OK != error ) {
2085 return error;
2086 }
2087
2088 if (!fwSession->mdSession) {
2089 return CKR_GENERAL_ERROR;
2090 }
2091 #endif /* NSSDEBUG */
2092
2093 /* make sure we have a valid operation initialized */
2094 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
2095 NSSCKFWCryptoOperationState_Digest);
2096 if (!fwOperation) {
2097 return CKR_OPERATION_NOT_INITIALIZED;
2098 }
2099
2100 /* make sure it's the correct type */
2101 if (NSSCKFWCryptoOperationType_Digest !=
2102 nssCKFWCryptoOperation_GetType(fwOperation)) {
2103 return CKR_OPERATION_NOT_INITIALIZED;
2104 }
2105
2106 error = nssCKFWCryptoOperation_DigestKey(fwOperation, fwKey);
2107 if (CKR_FUNCTION_FAILED != error) {
2108 return error;
2109 }
2110
2111 /* no machine depended way for this to happen, do it by hand */
2112 inputBuffer=nssCKFWObject_GetAttribute(fwKey, CKA_VALUE, NULL, NULL, &error);
2113 if (!inputBuffer) {
2114 /* couldn't get the value, just fail then */
2115 return error;
2116 }
2117 error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, inputBuffer);
2118 nssItem_Destroy(inputBuffer);
2119 return error;
2120 }
2121
2122 /*
2123 * nssCKFWSession_UpdateFinal
2124 */
2125 NSS_IMPLEMENT CK_RV
2126 nssCKFWSession_UpdateFinal
2127 (
2128 NSSCKFWSession *fwSession,
2129 NSSCKFWCryptoOperationType type,
2130 NSSCKFWCryptoOperationState state,
2131 CK_BYTE_PTR inBuf,
2132 CK_ULONG inBufLen,
2133 CK_BYTE_PTR outBuf,
2134 CK_ULONG_PTR outBufLen
2135 )
2136 {
2137 NSSCKFWCryptoOperation *fwOperation;
2138 NSSItem inputBuffer;
2139 NSSItem outputBuffer;
2140 PRBool isEncryptDecrypt;
2141 CK_RV error = CKR_OK;
2142
2143 #ifdef NSSDEBUG
2144 error = nssCKFWSession_verifyPointer(fwSession);
2145 if( CKR_OK != error ) {
2146 return error;
2147 }
2148
2149 if (!fwSession->mdSession) {
2150 return CKR_GENERAL_ERROR;
2151 }
2152 #endif /* NSSDEBUG */
2153
2154 /* make sure we have a valid operation initialized */
2155 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
2156 if (!fwOperation) {
2157 return CKR_OPERATION_NOT_INITIALIZED;
2158 }
2159
2160 /* make sure it's the correct type */
2161 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
2162 return CKR_OPERATION_NOT_INITIALIZED;
2163 }
2164
2165 inputBuffer.data = inBuf;
2166 inputBuffer.size = inBufLen;
2167 isEncryptDecrypt = (PRBool) ((NSSCKFWCryptoOperationType_Encrypt == type) ||
2168 (NSSCKFWCryptoOperationType_Decrypt == type)) ;
2169
2170 /* handle buffer issues, note for Verify, the type is an input buffer. */
2171 if (NSSCKFWCryptoOperationType_Verify == type) {
2172 if ((CK_BYTE_PTR)NULL == outBuf) {
2173 error = CKR_ARGUMENTS_BAD;
2174 goto done;
2175 }
2176 } else {
2177 CK_ULONG maxBufLen = *outBufLen;
2178 CK_ULONG len;
2179
2180 len = (isEncryptDecrypt) ?
2181 nssCKFWCryptoOperation_GetOperationLength(fwOperation,
2182 &inputBuffer, &error) :
2183 nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
2184
2185 if (CKR_OK != error) {
2186 goto done;
2187 }
2188
2189 *outBufLen = len;
2190 if ((CK_BYTE_PTR)NULL == outBuf) {
2191 return CKR_OK;
2192 }
2193
2194 if (len > maxBufLen) {
2195 return CKR_BUFFER_TOO_SMALL;
2196 }
2197 }
2198 outputBuffer.data = outBuf;
2199 outputBuffer.size = *outBufLen;
2200
2201 error = nssCKFWCryptoOperation_UpdateFinal(fwOperation,
2202 &inputBuffer, &outputBuffer);
2203
2204 /* UpdateFinal isn't support, manually use Update and Final */
2205 if (CKR_FUNCTION_FAILED == error) {
2206 error = isEncryptDecrypt ?
2207 nssCKFWCryptoOperation_Update(fwOperation, &inputBuffer, &outputBuffer) :
2208 nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
2209
2210 if (CKR_OK == error) {
2211 error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
2212 }
2213 }
2214
2215
2216 done:
2217 if (CKR_BUFFER_TOO_SMALL == error) {
2218 /* if we return CKR_BUFFER_TOO_SMALL, we the caller is not expecting.
2219 * the crypto state to be freed */
2220 return error;
2221 }
2222
2223 /* clean up our state */
2224 nssCKFWCryptoOperation_Destroy(fwOperation);
2225 nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
2226 return error;
2227 }
2228
2229 NSS_IMPLEMENT CK_RV
2230 nssCKFWSession_UpdateCombo
2231 (
2232 NSSCKFWSession *fwSession,
2233 NSSCKFWCryptoOperationType encryptType,
2234 NSSCKFWCryptoOperationType digestType,
2235 NSSCKFWCryptoOperationState digestState,
2236 CK_BYTE_PTR inBuf,
2237 CK_ULONG inBufLen,
2238 CK_BYTE_PTR outBuf,
2239 CK_ULONG_PTR outBufLen
2240 )
2241 {
2242 NSSCKFWCryptoOperation *fwOperation;
2243 NSSCKFWCryptoOperation *fwPeerOperation;
2244 NSSItem inputBuffer;
2245 NSSItem outputBuffer;
2246 CK_ULONG maxBufLen = *outBufLen;
2247 CK_ULONG len;
2248 CK_RV error = CKR_OK;
2249
2250 #ifdef NSSDEBUG
2251 error = nssCKFWSession_verifyPointer(fwSession);
2252 if( CKR_OK != error ) {
2253 return error;
2254 }
2255
2256 if (!fwSession->mdSession) {
2257 return CKR_GENERAL_ERROR;
2258 }
2259 #endif /* NSSDEBUG */
2260
2261 /* make sure we have a valid operation initialized */
2262 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
2263 NSSCKFWCryptoOperationState_EncryptDecrypt);
2264 if (!fwOperation) {
2265 return CKR_OPERATION_NOT_INITIALIZED;
2266 }
2267
2268 /* make sure it's the correct type */
2269 if (encryptType != nssCKFWCryptoOperation_GetType(fwOperation)) {
2270 return CKR_OPERATION_NOT_INITIALIZED;
2271 }
2272 /* make sure we have a valid operation initialized */
2273 fwPeerOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
2274 digestState);
2275 if (!fwPeerOperation) {
2276 return CKR_OPERATION_NOT_INITIALIZED;
2277 }
2278
2279 /* make sure it's the correct type */
2280 if (digestType != nssCKFWCryptoOperation_GetType(fwOperation)) {
2281 return CKR_OPERATION_NOT_INITIALIZED;
2282 }
2283
2284 inputBuffer.data = inBuf;
2285 inputBuffer.size = inBufLen;
2286 len = nssCKFWCryptoOperation_GetOperationLength(fwOperation,
2287 &inputBuffer, &error);
2288 if (CKR_OK != error) {
2289 return error;
2290 }
2291
2292 *outBufLen = len;
2293 if ((CK_BYTE_PTR)NULL == outBuf) {
2294 return CKR_OK;
2295 }
2296
2297 if (len > maxBufLen) {
2298 return CKR_BUFFER_TOO_SMALL;
2299 }
2300
2301 outputBuffer.data = outBuf;
2302 outputBuffer.size = *outBufLen;
2303
2304 error = nssCKFWCryptoOperation_UpdateCombo(fwOperation, fwPeerOperation,
2305 &inputBuffer, &outputBuffer);
2306 if (CKR_FUNCTION_FAILED == error) {
2307 PRBool isEncrypt =
2308 (PRBool) (NSSCKFWCryptoOperationType_Encrypt == encryptType);
2309
2310 if (isEncrypt) {
2311 error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
2312 &inputBuffer);
2313 if (CKR_OK != error) {
2314 return error;
2315 }
2316 }
2317 error = nssCKFWCryptoOperation_Update(fwOperation,
2318 &inputBuffer, &outputBuffer);
2319 if (CKR_OK != error) {
2320 return error;
2321 }
2322 if (!isEncrypt) {
2323 error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
2324 &outputBuffer);
2325 }
2326 }
2327 return error;
2328 }
2329
2330
2331 /*
2332 * NSSCKFWSession_GetMDSession
2333 *
2334 */
2335
2336 NSS_IMPLEMENT NSSCKMDSession *
2337 NSSCKFWSession_GetMDSession
2338 (
2339 NSSCKFWSession *fwSession
2340 )
2341 {
2342 #ifdef DEBUG
2343 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
2344 return (NSSCKMDSession *)NULL;
2345 }
2346 #endif /* DEBUG */
2347
2348 return nssCKFWSession_GetMDSession(fwSession);
2349 }
2350
2351 /*
2352 * NSSCKFWSession_GetArena
2353 *
2354 */
2355
2356 NSS_IMPLEMENT NSSArena *
2357 NSSCKFWSession_GetArena
2358 (
2359 NSSCKFWSession *fwSession,
2360 CK_RV *pError
2361 )
2362 {
2363 #ifdef DEBUG
2364 if (!pError) {
2365 return (NSSArena *)NULL;
2366 }
2367
2368 *pError = nssCKFWSession_verifyPointer(fwSession);
2369 if( CKR_OK != *pError ) {
2370 return (NSSArena *)NULL;
2371 }
2372 #endif /* DEBUG */
2373
2374 return nssCKFWSession_GetArena(fwSession, pError);
2375 }
2376
2377 /*
2378 * NSSCKFWSession_CallNotification
2379 *
2380 */
2381
2382 NSS_IMPLEMENT CK_RV
2383 NSSCKFWSession_CallNotification
2384 (
2385 NSSCKFWSession *fwSession,
2386 CK_NOTIFICATION event
2387 )
2388 {
2389 #ifdef DEBUG
2390 CK_RV error = CKR_OK;
2391
2392 error = nssCKFWSession_verifyPointer(fwSession);
2393 if( CKR_OK != error ) {
2394 return error;
2395 }
2396 #endif /* DEBUG */
2397
2398 return nssCKFWSession_CallNotification(fwSession, event);
2399 }
2400
2401 /*
2402 * NSSCKFWSession_IsRWSession
2403 *
2404 */
2405
2406 NSS_IMPLEMENT CK_BBOOL
2407 NSSCKFWSession_IsRWSession
2408 (
2409 NSSCKFWSession *fwSession
2410 )
2411 {
2412 #ifdef DEBUG
2413 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
2414 return CK_FALSE;
2415 }
2416 #endif /* DEBUG */
2417
2418 return nssCKFWSession_IsRWSession(fwSession);
2419 }
2420
2421 /*
2422 * NSSCKFWSession_IsSO
2423 *
2424 */
2425
2426 NSS_IMPLEMENT CK_BBOOL
2427 NSSCKFWSession_IsSO
2428 (
2429 NSSCKFWSession *fwSession
2430 )
2431 {
2432 #ifdef DEBUG
2433 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
2434 return CK_FALSE;
2435 }
2436 #endif /* DEBUG */
2437
2438 return nssCKFWSession_IsSO(fwSession);
2439 }
2440
2441 NSS_IMPLEMENT NSSCKFWCryptoOperation *
2442 NSSCKFWSession_GetCurrentCryptoOperation
2443 (
2444 NSSCKFWSession *fwSession,
2445 NSSCKFWCryptoOperationState state
2446 )
2447 {
2448 #ifdef DEBUG
2449 CK_RV error = CKR_OK;
2450 error = nssCKFWSession_verifyPointer(fwSession);
2451 if( CKR_OK != error ) {
2452 return (NSSCKFWCryptoOperation *)NULL;
2453 }
2454
2455 if ( state >= NSSCKFWCryptoOperationState_Max) {
2456 return (NSSCKFWCryptoOperation *)NULL;
2457 }
2458 #endif /* DEBUG */
2459 return nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
2460 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)