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