Mercurial > trustbridge > nss-cmake-static
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 } |