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 * object.c
7 *
8 * This file implements the NSSCKFWObject type and methods.
9 */
10
11 #ifndef CK_T
12 #include "ck.h"
13 #endif /* CK_T */
14
15 /*
16 * NSSCKFWObject
17 *
18 * -- create/destroy --
19 * nssCKFWObject_Create
20 * nssCKFWObject_Finalize
21 * nssCKFWObject_Destroy
22 *
23 * -- public accessors --
24 * NSSCKFWObject_GetMDObject
25 * NSSCKFWObject_GetArena
26 * NSSCKFWObject_IsTokenObject
27 * NSSCKFWObject_GetAttributeCount
28 * NSSCKFWObject_GetAttributeTypes
29 * NSSCKFWObject_GetAttributeSize
30 * NSSCKFWObject_GetAttribute
31 * NSSCKFWObject_SetAttribute
32 * NSSCKFWObject_GetObjectSize
33 *
34 * -- implement public accessors --
35 * nssCKFWObject_GetMDObject
36 * nssCKFWObject_GetArena
37 *
38 * -- private accessors --
39 * nssCKFWObject_SetHandle
40 * nssCKFWObject_GetHandle
41 *
42 * -- module fronts --
43 * nssCKFWObject_IsTokenObject
44 * nssCKFWObject_GetAttributeCount
45 * nssCKFWObject_GetAttributeTypes
46 * nssCKFWObject_GetAttributeSize
47 * nssCKFWObject_GetAttribute
48 * nssCKFWObject_SetAttribute
49 * nssCKFWObject_GetObjectSize
50 */
51
52 struct NSSCKFWObjectStr {
53 NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
54 NSSArena *arena;
55 NSSArena *localArena;
56 NSSCKMDObject *mdObject;
57 NSSCKMDSession *mdSession;
58 NSSCKFWSession *fwSession;
59 NSSCKMDToken *mdToken;
60 NSSCKFWToken *fwToken;
61 NSSCKMDInstance *mdInstance;
62 NSSCKFWInstance *fwInstance;
63 CK_OBJECT_HANDLE hObject;
64 };
65
66 #ifdef DEBUG
67 /*
68 * But first, the pointer-tracking stuff.
69 *
70 * NOTE: the pointer-tracking support in NSS/base currently relies
71 * upon NSPR's CallOnce support. That, however, relies upon NSPR's
72 * locking, which is tied into the runtime. We need a pointer-tracker
73 * implementation that uses the locks supplied through C_Initialize.
74 * That support, however, can be filled in later. So for now, I'll
75 * just do this routines as no-ops.
76 */
77
78 static CK_RV
object_add_pointer(const NSSCKFWObject * fwObject)79 object_add_pointer(
80 const NSSCKFWObject *fwObject)
81 {
82 return CKR_OK;
83 }
84
85 static CK_RV
object_remove_pointer(const NSSCKFWObject * fwObject)86 object_remove_pointer(
87 const NSSCKFWObject *fwObject)
88 {
89 return CKR_OK;
90 }
91
92 NSS_IMPLEMENT CK_RV
nssCKFWObject_verifyPointer(const NSSCKFWObject * fwObject)93 nssCKFWObject_verifyPointer(
94 const NSSCKFWObject *fwObject)
95 {
96 return CKR_OK;
97 }
98
99 #endif /* DEBUG */
100
101 /*
102 * nssCKFWObject_Create
103 *
104 */
105 NSS_IMPLEMENT NSSCKFWObject *
nssCKFWObject_Create(NSSArena * arena,NSSCKMDObject * mdObject,NSSCKFWSession * fwSession,NSSCKFWToken * fwToken,NSSCKFWInstance * fwInstance,CK_RV * pError)106 nssCKFWObject_Create(
107 NSSArena *arena,
108 NSSCKMDObject *mdObject,
109 NSSCKFWSession *fwSession,
110 NSSCKFWToken *fwToken,
111 NSSCKFWInstance *fwInstance,
112 CK_RV *pError)
113 {
114 NSSArena *objArena = arena;
115 NSSArena *localArena = NULL;
116 NSSCKFWObject *fwObject;
117 nssCKFWHash *mdObjectHash;
118
119 #ifdef NSSDEBUG
120 if (!pError) {
121 return (NSSCKFWObject *)NULL;
122 }
123
124 if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
125 *pError = CKR_ARGUMENTS_BAD;
126 return (NSSCKFWObject *)NULL;
127 }
128 #endif /* NSSDEBUG */
129
130 if (!fwToken) {
131 *pError = CKR_ARGUMENTS_BAD;
132 return (NSSCKFWObject *)NULL;
133 }
134 mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
135 if (!mdObjectHash) {
136 *pError = CKR_GENERAL_ERROR;
137 return (NSSCKFWObject *)NULL;
138 }
139
140 if (nssCKFWHash_Exists(mdObjectHash, mdObject)) {
141 fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject);
142 return fwObject;
143 }
144
145 /* session objects should have their own arena so they can be destroyed in the end. */
146 if (arena == NULL) {
147 localArena = objArena = NSSArena_Create();
148 if (objArena == NULL) {
149 *pError = CKR_HOST_MEMORY;
150 return (NSSCKFWObject *)NULL;
151 }
152 }
153
154 fwObject = nss_ZNEW(objArena, NSSCKFWObject);
155 if (!fwObject) {
156 *pError = CKR_HOST_MEMORY;
157 return (NSSCKFWObject *)NULL;
158 }
159
160 fwObject->arena = objArena;
161 fwObject->localArena = localArena;
162 fwObject->mdObject = mdObject;
163 fwObject->fwSession = fwSession;
164
165 if (fwSession) {
166 fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession);
167 }
168
169 fwObject->fwToken = fwToken;
170 fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken);
171 fwObject->fwInstance = fwInstance;
172 fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
173 fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, objArena, pError);
174 if (!fwObject->mutex) {
175 if (CKR_OK == *pError) {
176 *pError = CKR_GENERAL_ERROR;
177 }
178 nss_ZFreeIf(fwObject);
179 if (localArena) {
180 NSSArena_Destroy(localArena);
181 }
182 return (NSSCKFWObject *)NULL;
183 }
184
185 *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject);
186 if (CKR_OK != *pError) {
187 nss_ZFreeIf(fwObject);
188 if (localArena) {
189 NSSArena_Destroy(localArena);
190 }
191 return (NSSCKFWObject *)NULL;
192 }
193
194 #ifdef DEBUG
195 *pError = object_add_pointer(fwObject);
196 if (CKR_OK != *pError) {
197 nssCKFWHash_Remove(mdObjectHash, mdObject);
198 nss_ZFreeIf(fwObject);
199 if (localArena) {
200 NSSArena_Destroy(localArena);
201 }
202 return (NSSCKFWObject *)NULL;
203 }
204 #endif /* DEBUG */
205
206 *pError = CKR_OK;
207 return fwObject;
208 }
209
210 /*
211 * nssCKFWObject_Finalize
212 *
213 */
214 NSS_IMPLEMENT void
nssCKFWObject_Finalize(NSSCKFWObject * fwObject,PRBool removeFromHash)215 nssCKFWObject_Finalize(
216 NSSCKFWObject *fwObject,
217 PRBool removeFromHash)
218 {
219 nssCKFWHash *mdObjectHash;
220 NSSArena *arena = NULL;
221
222 #ifdef NSSDEBUG
223 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
224 return;
225 }
226 #endif /* NSSDEBUG */
227
228 (void)nssCKFWMutex_Destroy(fwObject->mutex);
229
230 if (fwObject->mdObject->Finalize) {
231 fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
232 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
233 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
234 }
235
236 if (removeFromHash) {
237 mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
238 if (mdObjectHash) {
239 nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
240 }
241 }
242
243 if (fwObject->fwSession) {
244 nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
245 }
246 arena = fwObject->localArena;
247 nss_ZFreeIf(fwObject);
248 if (arena) {
249 NSSArena_Destroy(arena);
250 }
251
252 #ifdef DEBUG
253 (void)object_remove_pointer(fwObject);
254 #endif /* DEBUG */
255
256 return;
257 }
258
259 /*
260 * nssCKFWObject_Destroy
261 *
262 */
263 NSS_IMPLEMENT void
nssCKFWObject_Destroy(NSSCKFWObject * fwObject)264 nssCKFWObject_Destroy(
265 NSSCKFWObject *fwObject)
266 {
267 nssCKFWHash *mdObjectHash;
268 NSSArena *arena = NULL;
269
270 #ifdef NSSDEBUG
271 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
272 return;
273 }
274 #endif /* NSSDEBUG */
275
276 (void)nssCKFWMutex_Destroy(fwObject->mutex);
277
278 if (fwObject->mdObject->Destroy) {
279 fwObject->mdObject->Destroy(fwObject->mdObject, fwObject,
280 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
281 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
282 }
283
284 mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
285 if (mdObjectHash) {
286 nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
287 }
288
289 if (fwObject->fwSession) {
290 nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
291 }
292 arena = fwObject->localArena;
293 nss_ZFreeIf(fwObject);
294 if (arena) {
295 NSSArena_Destroy(arena);
296 }
297
298 #ifdef DEBUG
299 (void)object_remove_pointer(fwObject);
300 #endif /* DEBUG */
301
302 return;
303 }
304
305 /*
306 * nssCKFWObject_GetMDObject
307 *
308 */
309 NSS_IMPLEMENT NSSCKMDObject *
nssCKFWObject_GetMDObject(NSSCKFWObject * fwObject)310 nssCKFWObject_GetMDObject(
311 NSSCKFWObject *fwObject)
312 {
313 #ifdef NSSDEBUG
314 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
315 return (NSSCKMDObject *)NULL;
316 }
317 #endif /* NSSDEBUG */
318
319 return fwObject->mdObject;
320 }
321
322 /*
323 * nssCKFWObject_GetArena
324 *
325 */
326 NSS_IMPLEMENT NSSArena *
nssCKFWObject_GetArena(NSSCKFWObject * fwObject,CK_RV * pError)327 nssCKFWObject_GetArena(
328 NSSCKFWObject *fwObject,
329 CK_RV *pError)
330 {
331 #ifdef NSSDEBUG
332 if (!pError) {
333 return (NSSArena *)NULL;
334 }
335
336 *pError = nssCKFWObject_verifyPointer(fwObject);
337 if (CKR_OK != *pError) {
338 return (NSSArena *)NULL;
339 }
340 #endif /* NSSDEBUG */
341
342 return fwObject->arena;
343 }
344
345 /*
346 * nssCKFWObject_SetHandle
347 *
348 */
349 NSS_IMPLEMENT CK_RV
nssCKFWObject_SetHandle(NSSCKFWObject * fwObject,CK_OBJECT_HANDLE hObject)350 nssCKFWObject_SetHandle(
351 NSSCKFWObject *fwObject,
352 CK_OBJECT_HANDLE hObject)
353 {
354 #ifdef NSSDEBUG
355 CK_RV error = CKR_OK;
356 #endif /* NSSDEBUG */
357
358 #ifdef NSSDEBUG
359 error = nssCKFWObject_verifyPointer(fwObject);
360 if (CKR_OK != error) {
361 return error;
362 }
363 #endif /* NSSDEBUG */
364
365 if ((CK_OBJECT_HANDLE)0 != fwObject->hObject) {
366 return CKR_GENERAL_ERROR;
367 }
368
369 fwObject->hObject = hObject;
370
371 return CKR_OK;
372 }
373
374 /*
375 * nssCKFWObject_GetHandle
376 *
377 */
378 NSS_IMPLEMENT CK_OBJECT_HANDLE
nssCKFWObject_GetHandle(NSSCKFWObject * fwObject)379 nssCKFWObject_GetHandle(
380 NSSCKFWObject *fwObject)
381 {
382 #ifdef NSSDEBUG
383 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
384 return (CK_OBJECT_HANDLE)0;
385 }
386 #endif /* NSSDEBUG */
387
388 return fwObject->hObject;
389 }
390
391 /*
392 * nssCKFWObject_IsTokenObject
393 *
394 */
395 NSS_IMPLEMENT CK_BBOOL
nssCKFWObject_IsTokenObject(NSSCKFWObject * fwObject)396 nssCKFWObject_IsTokenObject(
397 NSSCKFWObject *fwObject)
398 {
399 CK_BBOOL b = CK_FALSE;
400
401 #ifdef NSSDEBUG
402 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
403 return CK_FALSE;
404 }
405 #endif /* NSSDEBUG */
406
407 if (!fwObject->mdObject->IsTokenObject) {
408 NSSItem item;
409 NSSItem *pItem;
410 CK_RV rv = CKR_OK;
411
412 item.data = (void *)&b;
413 item.size = sizeof(b);
414
415 pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item,
416 (NSSArena *)NULL, &rv);
417 if (!pItem) {
418 /* Error of some type */
419 b = CK_FALSE;
420 goto done;
421 }
422
423 goto done;
424 }
425
426 b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
427 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
428 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
429
430 done:
431 return b;
432 }
433
434 /*
435 * nssCKFWObject_GetAttributeCount
436 *
437 */
438 NSS_IMPLEMENT CK_ULONG
nssCKFWObject_GetAttributeCount(NSSCKFWObject * fwObject,CK_RV * pError)439 nssCKFWObject_GetAttributeCount(
440 NSSCKFWObject *fwObject,
441 CK_RV *pError)
442 {
443 CK_ULONG rv;
444
445 #ifdef NSSDEBUG
446 if (!pError) {
447 return (CK_ULONG)0;
448 }
449
450 *pError = nssCKFWObject_verifyPointer(fwObject);
451 if (CKR_OK != *pError) {
452 return (CK_ULONG)0;
453 }
454 #endif /* NSSDEBUG */
455
456 if (!fwObject->mdObject->GetAttributeCount) {
457 *pError = CKR_GENERAL_ERROR;
458 return (CK_ULONG)0;
459 }
460
461 *pError = nssCKFWMutex_Lock(fwObject->mutex);
462 if (CKR_OK != *pError) {
463 return (CK_ULONG)0;
464 }
465
466 rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject,
467 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
468 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
469 pError);
470
471 (void)nssCKFWMutex_Unlock(fwObject->mutex);
472 return rv;
473 }
474
475 /*
476 * nssCKFWObject_GetAttributeTypes
477 *
478 */
479 NSS_IMPLEMENT CK_RV
nssCKFWObject_GetAttributeTypes(NSSCKFWObject * fwObject,CK_ATTRIBUTE_TYPE_PTR typeArray,CK_ULONG ulCount)480 nssCKFWObject_GetAttributeTypes(
481 NSSCKFWObject *fwObject,
482 CK_ATTRIBUTE_TYPE_PTR typeArray,
483 CK_ULONG ulCount)
484 {
485 CK_RV error = CKR_OK;
486
487 #ifdef NSSDEBUG
488 error = nssCKFWObject_verifyPointer(fwObject);
489 if (CKR_OK != error) {
490 return error;
491 }
492
493 if ((CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray) {
494 return CKR_ARGUMENTS_BAD;
495 }
496 #endif /* NSSDEBUG */
497
498 if (!fwObject->mdObject->GetAttributeTypes) {
499 return CKR_GENERAL_ERROR;
500 }
501
502 error = nssCKFWMutex_Lock(fwObject->mutex);
503 if (CKR_OK != error) {
504 return error;
505 }
506
507 error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject,
508 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
509 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
510 typeArray, ulCount);
511
512 (void)nssCKFWMutex_Unlock(fwObject->mutex);
513 return error;
514 }
515
516 /*
517 * nssCKFWObject_GetAttributeSize
518 *
519 */
520 NSS_IMPLEMENT CK_ULONG
nssCKFWObject_GetAttributeSize(NSSCKFWObject * fwObject,CK_ATTRIBUTE_TYPE attribute,CK_RV * pError)521 nssCKFWObject_GetAttributeSize(
522 NSSCKFWObject *fwObject,
523 CK_ATTRIBUTE_TYPE attribute,
524 CK_RV *pError)
525 {
526 CK_ULONG rv;
527
528 if (!pError) {
529 return (CK_ULONG)0;
530 }
531
532 if (!fwObject || !fwObject->mdObject || !fwObject->mdObject->GetAttributeSize) {
533 *pError = CKR_GENERAL_ERROR;
534 return (CK_ULONG)0;
535 }
536
537 *pError = nssCKFWMutex_Lock(fwObject->mutex);
538 if (CKR_OK != *pError) {
539 return (CK_ULONG)0;
540 }
541
542 rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject,
543 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
544 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
545 attribute, pError);
546
547 (void)nssCKFWMutex_Unlock(fwObject->mutex);
548 return rv;
549 }
550
551 /*
552 * nssCKFWObject_GetAttribute
553 *
554 * Usual NSS allocation rules:
555 * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
556 * will be allocated. If itemOpt is not NULL but itemOpt->data is,
557 * the buffer will be allocated; otherwise, the buffer will be used.
558 * Any allocations will come from the optional arena, if one is
559 * specified.
560 */
561 NSS_IMPLEMENT NSSItem *
nssCKFWObject_GetAttribute(NSSCKFWObject * fwObject,CK_ATTRIBUTE_TYPE attribute,NSSItem * itemOpt,NSSArena * arenaOpt,CK_RV * pError)562 nssCKFWObject_GetAttribute(
563 NSSCKFWObject *fwObject,
564 CK_ATTRIBUTE_TYPE attribute,
565 NSSItem *itemOpt,
566 NSSArena *arenaOpt,
567 CK_RV *pError)
568 {
569 NSSItem *rv = (NSSItem *)NULL;
570 NSSCKFWItem mdItem;
571
572 #ifdef NSSDEBUG
573 if (!pError) {
574 return (NSSItem *)NULL;
575 }
576
577 *pError = nssCKFWObject_verifyPointer(fwObject);
578 if (CKR_OK != *pError) {
579 return (NSSItem *)NULL;
580 }
581 #endif /* NSSDEBUG */
582
583 if (!fwObject->mdObject->GetAttribute) {
584 *pError = CKR_GENERAL_ERROR;
585 return (NSSItem *)NULL;
586 }
587
588 *pError = nssCKFWMutex_Lock(fwObject->mutex);
589 if (CKR_OK != *pError) {
590 return (NSSItem *)NULL;
591 }
592
593 mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject,
594 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
595 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
596 attribute, pError);
597
598 if (!mdItem.item) {
599 if (CKR_OK == *pError) {
600 *pError = CKR_GENERAL_ERROR;
601 }
602
603 goto done;
604 }
605
606 if (!itemOpt) {
607 rv = nss_ZNEW(arenaOpt, NSSItem);
608 if (!rv) {
609 *pError = CKR_HOST_MEMORY;
610 goto done;
611 }
612 } else {
613 rv = itemOpt;
614 }
615
616 if (!rv->data) {
617 rv->size = mdItem.item->size;
618 rv->data = nss_ZAlloc(arenaOpt, rv->size);
619 if (!rv->data) {
620 *pError = CKR_HOST_MEMORY;
621 if (!itemOpt) {
622 nss_ZFreeIf(rv);
623 }
624 rv = (NSSItem *)NULL;
625 goto done;
626 }
627 } else {
628 if (rv->size >= mdItem.item->size) {
629 rv->size = mdItem.item->size;
630 } else {
631 *pError = CKR_BUFFER_TOO_SMALL;
632 /* Should we set rv->size to mdItem->size? */
633 /* rv can't have been allocated */
634 rv = (NSSItem *)NULL;
635 goto done;
636 }
637 }
638
639 (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size);
640
641 if (PR_TRUE == mdItem.needsFreeing) {
642 PR_ASSERT(fwObject->mdObject->FreeAttribute);
643 if (fwObject->mdObject->FreeAttribute) {
644 *pError = fwObject->mdObject->FreeAttribute(&mdItem);
645 }
646 }
647
648 done:
649 (void)nssCKFWMutex_Unlock(fwObject->mutex);
650 return rv;
651 }
652
653 /*
654 * nssCKFWObject_SetAttribute
655 *
656 */
657 NSS_IMPLEMENT CK_RV
nssCKFWObject_SetAttribute(NSSCKFWObject * fwObject,NSSCKFWSession * fwSession,CK_ATTRIBUTE_TYPE attribute,NSSItem * value)658 nssCKFWObject_SetAttribute(
659 NSSCKFWObject *fwObject,
660 NSSCKFWSession *fwSession,
661 CK_ATTRIBUTE_TYPE attribute,
662 NSSItem *value)
663 {
664 CK_RV error = CKR_OK;
665
666 #ifdef NSSDEBUG
667 error = nssCKFWObject_verifyPointer(fwObject);
668 if (CKR_OK != error) {
669 return error;
670 }
671 #endif /* NSSDEBUG */
672
673 if (CKA_TOKEN == attribute) {
674 /*
675 * We're changing from a session object to a token object or
676 * vice-versa.
677 */
678
679 CK_ATTRIBUTE a;
680 NSSCKFWObject *newFwObject;
681 NSSCKFWObject swab;
682
683 a.type = CKA_TOKEN;
684 a.pValue = value->data;
685 a.ulValueLen = value->size;
686
687 newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject,
688 &a, 1, &error);
689 if (!newFwObject) {
690 if (CKR_OK == error) {
691 error = CKR_GENERAL_ERROR;
692 }
693 return error;
694 }
695
696 /*
697 * Actually, I bet the locking is worse than this.. this part of
698 * the code could probably use some scrutiny and reworking.
699 */
700 error = nssCKFWMutex_Lock(fwObject->mutex);
701 if (CKR_OK != error) {
702 nssCKFWObject_Destroy(newFwObject);
703 return error;
704 }
705
706 error = nssCKFWMutex_Lock(newFwObject->mutex);
707 if (CKR_OK != error) {
708 nssCKFWMutex_Unlock(fwObject->mutex);
709 nssCKFWObject_Destroy(newFwObject);
710 return error;
711 }
712
713 /*
714 * Now, we have our new object, but it has a new fwObject pointer,
715 * while we have to keep the existing one. So quick swap the contents.
716 */
717 swab = *fwObject;
718 *fwObject = *newFwObject;
719 *newFwObject = swab;
720
721 /* But keep the mutexes the same */
722 swab.mutex = fwObject->mutex;
723 fwObject->mutex = newFwObject->mutex;
724 newFwObject->mutex = swab.mutex;
725
726 (void)nssCKFWMutex_Unlock(newFwObject->mutex);
727 (void)nssCKFWMutex_Unlock(fwObject->mutex);
728
729 /*
730 * Either remove or add this to the list of session objects
731 */
732
733 if (CK_FALSE == *(CK_BBOOL *)value->data) {
734 /*
735 * New one is a session object, except since we "stole" the fwObject, it's
736 * not in the list. Add it.
737 */
738 nssCKFWSession_RegisterSessionObject(fwSession, fwObject);
739 } else {
740 /*
741 * New one is a token object, except since we "stole" the fwObject, it's
742 * in the list. Remove it.
743 */
744 if (fwObject->fwSession) {
745 nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
746 }
747 }
748
749 /*
750 * Now delete the old object. Remember the names have changed.
751 */
752 nssCKFWObject_Destroy(newFwObject);
753
754 return CKR_OK;
755 } else {
756 /*
757 * An "ordinary" change.
758 */
759 if (!fwObject->mdObject->SetAttribute) {
760 /* We could fake it with copying, like above.. later */
761 return CKR_ATTRIBUTE_READ_ONLY;
762 }
763
764 error = nssCKFWMutex_Lock(fwObject->mutex);
765 if (CKR_OK != error) {
766 return error;
767 }
768
769 error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject,
770 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
771 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
772 attribute, value);
773
774 (void)nssCKFWMutex_Unlock(fwObject->mutex);
775
776 return error;
777 }
778 }
779
780 /*
781 * nssCKFWObject_GetObjectSize
782 *
783 */
784 NSS_IMPLEMENT CK_ULONG
nssCKFWObject_GetObjectSize(NSSCKFWObject * fwObject,CK_RV * pError)785 nssCKFWObject_GetObjectSize(
786 NSSCKFWObject *fwObject,
787 CK_RV *pError)
788 {
789 CK_ULONG rv;
790
791 #ifdef NSSDEBUG
792 if (!pError) {
793 return (CK_ULONG)0;
794 }
795
796 *pError = nssCKFWObject_verifyPointer(fwObject);
797 if (CKR_OK != *pError) {
798 return (CK_ULONG)0;
799 }
800 #endif /* NSSDEBUG */
801
802 if (!fwObject->mdObject->GetObjectSize) {
803 *pError = CKR_INFORMATION_SENSITIVE;
804 return (CK_ULONG)0;
805 }
806
807 *pError = nssCKFWMutex_Lock(fwObject->mutex);
808 if (CKR_OK != *pError) {
809 return (CK_ULONG)0;
810 }
811
812 rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject,
813 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
814 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
815 pError);
816
817 (void)nssCKFWMutex_Unlock(fwObject->mutex);
818 return rv;
819 }
820
821 /*
822 * NSSCKFWObject_GetMDObject
823 *
824 */
825 NSS_IMPLEMENT NSSCKMDObject *
NSSCKFWObject_GetMDObject(NSSCKFWObject * fwObject)826 NSSCKFWObject_GetMDObject(
827 NSSCKFWObject *fwObject)
828 {
829 #ifdef DEBUG
830 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
831 return (NSSCKMDObject *)NULL;
832 }
833 #endif /* DEBUG */
834
835 return nssCKFWObject_GetMDObject(fwObject);
836 }
837
838 /*
839 * NSSCKFWObject_GetArena
840 *
841 */
842 NSS_IMPLEMENT NSSArena *
NSSCKFWObject_GetArena(NSSCKFWObject * fwObject,CK_RV * pError)843 NSSCKFWObject_GetArena(
844 NSSCKFWObject *fwObject,
845 CK_RV *pError)
846 {
847 #ifdef DEBUG
848 if (!pError) {
849 return (NSSArena *)NULL;
850 }
851
852 *pError = nssCKFWObject_verifyPointer(fwObject);
853 if (CKR_OK != *pError) {
854 return (NSSArena *)NULL;
855 }
856 #endif /* DEBUG */
857
858 return nssCKFWObject_GetArena(fwObject, pError);
859 }
860
861 /*
862 * NSSCKFWObject_IsTokenObject
863 *
864 */
865 NSS_IMPLEMENT CK_BBOOL
NSSCKFWObject_IsTokenObject(NSSCKFWObject * fwObject)866 NSSCKFWObject_IsTokenObject(
867 NSSCKFWObject *fwObject)
868 {
869 #ifdef DEBUG
870 if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
871 return CK_FALSE;
872 }
873 #endif /* DEBUG */
874
875 return nssCKFWObject_IsTokenObject(fwObject);
876 }
877
878 /*
879 * NSSCKFWObject_GetAttributeCount
880 *
881 */
882 NSS_IMPLEMENT CK_ULONG
NSSCKFWObject_GetAttributeCount(NSSCKFWObject * fwObject,CK_RV * pError)883 NSSCKFWObject_GetAttributeCount(
884 NSSCKFWObject *fwObject,
885 CK_RV *pError)
886 {
887 #ifdef DEBUG
888 if (!pError) {
889 return (CK_ULONG)0;
890 }
891
892 *pError = nssCKFWObject_verifyPointer(fwObject);
893 if (CKR_OK != *pError) {
894 return (CK_ULONG)0;
895 }
896 #endif /* DEBUG */
897
898 return nssCKFWObject_GetAttributeCount(fwObject, pError);
899 }
900
901 /*
902 * NSSCKFWObject_GetAttributeTypes
903 *
904 */
905 NSS_IMPLEMENT CK_RV
NSSCKFWObject_GetAttributeTypes(NSSCKFWObject * fwObject,CK_ATTRIBUTE_TYPE_PTR typeArray,CK_ULONG ulCount)906 NSSCKFWObject_GetAttributeTypes(
907 NSSCKFWObject *fwObject,
908 CK_ATTRIBUTE_TYPE_PTR typeArray,
909 CK_ULONG ulCount)
910 {
911 #ifdef DEBUG
912 CK_RV error = CKR_OK;
913
914 error = nssCKFWObject_verifyPointer(fwObject);
915 if (CKR_OK != error) {
916 return error;
917 }
918
919 if ((CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray) {
920 return CKR_ARGUMENTS_BAD;
921 }
922 #endif /* DEBUG */
923
924 return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
925 }
926
927 /*
928 * NSSCKFWObject_GetAttributeSize
929 *
930 */
931 NSS_IMPLEMENT CK_ULONG
NSSCKFWObject_GetAttributeSize(NSSCKFWObject * fwObject,CK_ATTRIBUTE_TYPE attribute,CK_RV * pError)932 NSSCKFWObject_GetAttributeSize(
933 NSSCKFWObject *fwObject,
934 CK_ATTRIBUTE_TYPE attribute,
935 CK_RV *pError)
936 {
937 #ifdef DEBUG
938 if (!pError) {
939 return (CK_ULONG)0;
940 }
941
942 *pError = nssCKFWObject_verifyPointer(fwObject);
943 if (CKR_OK != *pError) {
944 return (CK_ULONG)0;
945 }
946 #endif /* DEBUG */
947
948 return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError);
949 }
950
951 /*
952 * NSSCKFWObject_GetAttribute
953 *
954 */
955 NSS_IMPLEMENT NSSItem *
NSSCKFWObject_GetAttribute(NSSCKFWObject * fwObject,CK_ATTRIBUTE_TYPE attribute,NSSItem * itemOpt,NSSArena * arenaOpt,CK_RV * pError)956 NSSCKFWObject_GetAttribute(
957 NSSCKFWObject *fwObject,
958 CK_ATTRIBUTE_TYPE attribute,
959 NSSItem *itemOpt,
960 NSSArena *arenaOpt,
961 CK_RV *pError)
962 {
963 #ifdef DEBUG
964 if (!pError) {
965 return (NSSItem *)NULL;
966 }
967
968 *pError = nssCKFWObject_verifyPointer(fwObject);
969 if (CKR_OK != *pError) {
970 return (NSSItem *)NULL;
971 }
972 #endif /* DEBUG */
973
974 return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError);
975 }
976
977 /*
978 * NSSCKFWObject_GetObjectSize
979 *
980 */
981 NSS_IMPLEMENT CK_ULONG
NSSCKFWObject_GetObjectSize(NSSCKFWObject * fwObject,CK_RV * pError)982 NSSCKFWObject_GetObjectSize(
983 NSSCKFWObject *fwObject,
984 CK_RV *pError)
985 {
986 #ifdef DEBUG
987 if (!pError) {
988 return (CK_ULONG)0;
989 }
990
991 *pError = nssCKFWObject_verifyPointer(fwObject);
992 if (CKR_OK != *pError) {
993 return (CK_ULONG)0;
994 }
995 #endif /* DEBUG */
996
997 return nssCKFWObject_GetObjectSize(fwObject, pError);
998 }
999