Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: mozilla/security/nss/lib/ckfw/session.c

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

Powered by Google App Engine
This is Rietveld 408576698