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