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