|
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 * find.c |
|
7 * |
|
8 * This file implements the nssCKFWFindObjects type and methods. |
|
9 */ |
|
10 |
|
11 #ifndef CK_H |
|
12 #include "ck.h" |
|
13 #endif /* CK_H */ |
|
14 |
|
15 /* |
|
16 * NSSCKFWFindObjects |
|
17 * |
|
18 * -- create/destroy -- |
|
19 * nssCKFWFindObjects_Create |
|
20 * nssCKFWFindObjects_Destroy |
|
21 * |
|
22 * -- public accessors -- |
|
23 * NSSCKFWFindObjects_GetMDFindObjects |
|
24 * |
|
25 * -- implement public accessors -- |
|
26 * nssCKFWFindObjects_GetMDFindObjects |
|
27 * |
|
28 * -- private accessors -- |
|
29 * |
|
30 * -- module fronts -- |
|
31 * nssCKFWFindObjects_Next |
|
32 */ |
|
33 |
|
34 struct NSSCKFWFindObjectsStr { |
|
35 NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */ |
|
36 NSSCKMDFindObjects *mdfo1; |
|
37 NSSCKMDFindObjects *mdfo2; |
|
38 NSSCKFWSession *fwSession; |
|
39 NSSCKMDSession *mdSession; |
|
40 NSSCKFWToken *fwToken; |
|
41 NSSCKMDToken *mdToken; |
|
42 NSSCKFWInstance *fwInstance; |
|
43 NSSCKMDInstance *mdInstance; |
|
44 |
|
45 NSSCKMDFindObjects *mdFindObjects; /* varies */ |
|
46 }; |
|
47 |
|
48 #ifdef DEBUG |
|
49 /* |
|
50 * But first, the pointer-tracking stuff. |
|
51 * |
|
52 * NOTE: the pointer-tracking support in NSS/base currently relies |
|
53 * upon NSPR's CallOnce support. That, however, relies upon NSPR's |
|
54 * locking, which is tied into the runtime. We need a pointer-tracker |
|
55 * implementation that uses the locks supplied through C_Initialize. |
|
56 * That support, however, can be filled in later. So for now, I'll |
|
57 * just do these routines as no-ops. |
|
58 */ |
|
59 |
|
60 static CK_RV |
|
61 findObjects_add_pointer |
|
62 ( |
|
63 const NSSCKFWFindObjects *fwFindObjects |
|
64 ) |
|
65 { |
|
66 return CKR_OK; |
|
67 } |
|
68 |
|
69 static CK_RV |
|
70 findObjects_remove_pointer |
|
71 ( |
|
72 const NSSCKFWFindObjects *fwFindObjects |
|
73 ) |
|
74 { |
|
75 return CKR_OK; |
|
76 } |
|
77 |
|
78 NSS_IMPLEMENT CK_RV |
|
79 nssCKFWFindObjects_verifyPointer |
|
80 ( |
|
81 const NSSCKFWFindObjects *fwFindObjects |
|
82 ) |
|
83 { |
|
84 return CKR_OK; |
|
85 } |
|
86 |
|
87 #endif /* DEBUG */ |
|
88 |
|
89 /* |
|
90 * nssCKFWFindObjects_Create |
|
91 * |
|
92 */ |
|
93 NSS_EXTERN NSSCKFWFindObjects * |
|
94 nssCKFWFindObjects_Create |
|
95 ( |
|
96 NSSCKFWSession *fwSession, |
|
97 NSSCKFWToken *fwToken, |
|
98 NSSCKFWInstance *fwInstance, |
|
99 NSSCKMDFindObjects *mdFindObjects1, |
|
100 NSSCKMDFindObjects *mdFindObjects2, |
|
101 CK_RV *pError |
|
102 ) |
|
103 { |
|
104 NSSCKFWFindObjects *fwFindObjects = NULL; |
|
105 NSSCKMDSession *mdSession; |
|
106 NSSCKMDToken *mdToken; |
|
107 NSSCKMDInstance *mdInstance; |
|
108 |
|
109 mdSession = nssCKFWSession_GetMDSession(fwSession); |
|
110 mdToken = nssCKFWToken_GetMDToken(fwToken); |
|
111 mdInstance = nssCKFWInstance_GetMDInstance(fwInstance); |
|
112 |
|
113 fwFindObjects = nss_ZNEW(NULL, NSSCKFWFindObjects); |
|
114 if (!fwFindObjects) { |
|
115 *pError = CKR_HOST_MEMORY; |
|
116 goto loser; |
|
117 } |
|
118 |
|
119 fwFindObjects->mdfo1 = mdFindObjects1; |
|
120 fwFindObjects->mdfo2 = mdFindObjects2; |
|
121 fwFindObjects->fwSession = fwSession; |
|
122 fwFindObjects->mdSession = mdSession; |
|
123 fwFindObjects->fwToken = fwToken; |
|
124 fwFindObjects->mdToken = mdToken; |
|
125 fwFindObjects->fwInstance = fwInstance; |
|
126 fwFindObjects->mdInstance = mdInstance; |
|
127 |
|
128 fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, NULL, pError); |
|
129 if (!fwFindObjects->mutex) { |
|
130 goto loser; |
|
131 } |
|
132 |
|
133 #ifdef DEBUG |
|
134 *pError = findObjects_add_pointer(fwFindObjects); |
|
135 if( CKR_OK != *pError ) { |
|
136 goto loser; |
|
137 } |
|
138 #endif /* DEBUG */ |
|
139 |
|
140 return fwFindObjects; |
|
141 |
|
142 loser: |
|
143 if( fwFindObjects ) { |
|
144 if( NULL != mdFindObjects1 ) { |
|
145 if( NULL != mdFindObjects1->Final ) { |
|
146 fwFindObjects->mdFindObjects = mdFindObjects1; |
|
147 mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, |
|
148 fwSession, mdToken, fwToken, mdInstance, fwInstance); |
|
149 } |
|
150 } |
|
151 |
|
152 if( NULL != mdFindObjects2 ) { |
|
153 if( NULL != mdFindObjects2->Final ) { |
|
154 fwFindObjects->mdFindObjects = mdFindObjects2; |
|
155 mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, |
|
156 fwSession, mdToken, fwToken, mdInstance, fwInstance); |
|
157 } |
|
158 } |
|
159 |
|
160 nss_ZFreeIf(fwFindObjects); |
|
161 } |
|
162 |
|
163 if( CKR_OK == *pError ) { |
|
164 *pError = CKR_GENERAL_ERROR; |
|
165 } |
|
166 |
|
167 return (NSSCKFWFindObjects *)NULL; |
|
168 } |
|
169 |
|
170 |
|
171 /* |
|
172 * nssCKFWFindObjects_Destroy |
|
173 * |
|
174 */ |
|
175 NSS_EXTERN void |
|
176 nssCKFWFindObjects_Destroy |
|
177 ( |
|
178 NSSCKFWFindObjects *fwFindObjects |
|
179 ) |
|
180 { |
|
181 #ifdef NSSDEBUG |
|
182 if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) { |
|
183 return; |
|
184 } |
|
185 #endif /* NSSDEBUG */ |
|
186 |
|
187 (void)nssCKFWMutex_Destroy(fwFindObjects->mutex); |
|
188 |
|
189 if (fwFindObjects->mdfo1) { |
|
190 if (fwFindObjects->mdfo1->Final) { |
|
191 fwFindObjects->mdFindObjects = fwFindObjects->mdfo1; |
|
192 fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects, |
|
193 fwFindObjects->mdSession, fwFindObjects->fwSession, |
|
194 fwFindObjects->mdToken, fwFindObjects->fwToken, |
|
195 fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
|
196 } |
|
197 } |
|
198 |
|
199 if (fwFindObjects->mdfo2) { |
|
200 if (fwFindObjects->mdfo2->Final) { |
|
201 fwFindObjects->mdFindObjects = fwFindObjects->mdfo2; |
|
202 fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects, |
|
203 fwFindObjects->mdSession, fwFindObjects->fwSession, |
|
204 fwFindObjects->mdToken, fwFindObjects->fwToken, |
|
205 fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
|
206 } |
|
207 } |
|
208 |
|
209 nss_ZFreeIf(fwFindObjects); |
|
210 |
|
211 #ifdef DEBUG |
|
212 (void)findObjects_remove_pointer(fwFindObjects); |
|
213 #endif /* DEBUG */ |
|
214 |
|
215 return; |
|
216 } |
|
217 |
|
218 /* |
|
219 * nssCKFWFindObjects_GetMDFindObjects |
|
220 * |
|
221 */ |
|
222 NSS_EXTERN NSSCKMDFindObjects * |
|
223 nssCKFWFindObjects_GetMDFindObjects |
|
224 ( |
|
225 NSSCKFWFindObjects *fwFindObjects |
|
226 ) |
|
227 { |
|
228 #ifdef NSSDEBUG |
|
229 if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) { |
|
230 return (NSSCKMDFindObjects *)NULL; |
|
231 } |
|
232 #endif /* NSSDEBUG */ |
|
233 |
|
234 return fwFindObjects->mdFindObjects; |
|
235 } |
|
236 |
|
237 /* |
|
238 * nssCKFWFindObjects_Next |
|
239 * |
|
240 */ |
|
241 NSS_EXTERN NSSCKFWObject * |
|
242 nssCKFWFindObjects_Next |
|
243 ( |
|
244 NSSCKFWFindObjects *fwFindObjects, |
|
245 NSSArena *arenaOpt, |
|
246 CK_RV *pError |
|
247 ) |
|
248 { |
|
249 NSSCKMDObject *mdObject; |
|
250 NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL; |
|
251 NSSArena *objArena; |
|
252 |
|
253 #ifdef NSSDEBUG |
|
254 if (!pError) { |
|
255 return (NSSCKFWObject *)NULL; |
|
256 } |
|
257 |
|
258 *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects); |
|
259 if( CKR_OK != *pError ) { |
|
260 return (NSSCKFWObject *)NULL; |
|
261 } |
|
262 #endif /* NSSDEBUG */ |
|
263 |
|
264 *pError = nssCKFWMutex_Lock(fwFindObjects->mutex); |
|
265 if( CKR_OK != *pError ) { |
|
266 return (NSSCKFWObject *)NULL; |
|
267 } |
|
268 |
|
269 if (fwFindObjects->mdfo1) { |
|
270 if (fwFindObjects->mdfo1->Next) { |
|
271 fwFindObjects->mdFindObjects = fwFindObjects->mdfo1; |
|
272 mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1, |
|
273 fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession, |
|
274 fwFindObjects->mdToken, fwFindObjects->fwToken, |
|
275 fwFindObjects->mdInstance, fwFindObjects->fwInstance, |
|
276 arenaOpt, pError); |
|
277 if (!mdObject) { |
|
278 if( CKR_OK != *pError ) { |
|
279 goto done; |
|
280 } |
|
281 |
|
282 /* All done. */ |
|
283 fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects, |
|
284 fwFindObjects->mdSession, fwFindObjects->fwSession, |
|
285 fwFindObjects->mdToken, fwFindObjects->fwToken, |
|
286 fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
|
287 fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL; |
|
288 } else { |
|
289 goto wrap; |
|
290 } |
|
291 } |
|
292 } |
|
293 |
|
294 if (fwFindObjects->mdfo2) { |
|
295 if (fwFindObjects->mdfo2->Next) { |
|
296 fwFindObjects->mdFindObjects = fwFindObjects->mdfo2; |
|
297 mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2, |
|
298 fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession, |
|
299 fwFindObjects->mdToken, fwFindObjects->fwToken, |
|
300 fwFindObjects->mdInstance, fwFindObjects->fwInstance, |
|
301 arenaOpt, pError); |
|
302 if (!mdObject) { |
|
303 if( CKR_OK != *pError ) { |
|
304 goto done; |
|
305 } |
|
306 |
|
307 /* All done. */ |
|
308 fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects, |
|
309 fwFindObjects->mdSession, fwFindObjects->fwSession, |
|
310 fwFindObjects->mdToken, fwFindObjects->fwToken, |
|
311 fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
|
312 fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL; |
|
313 } else { |
|
314 goto wrap; |
|
315 } |
|
316 } |
|
317 } |
|
318 |
|
319 /* No more objects */ |
|
320 *pError = CKR_OK; |
|
321 goto done; |
|
322 |
|
323 wrap: |
|
324 /* |
|
325 * This seems is less than ideal-- we should determine if it's a token |
|
326 * object or a session object, and use the appropriate arena. |
|
327 * But that duplicates logic in nssCKFWObject_IsTokenObject. |
|
328 * Also we should lookup the real session the object was created on |
|
329 * if the object was a session object... however this code is actually |
|
330 * correct because nssCKFWObject_Create will return a cached version of |
|
331 * the object from it's hash. This is necessary because 1) we don't want |
|
332 * to create an arena style leak (where our arena grows with every search), |
|
333 * and 2) we want the same object to always have the same ID. This means |
|
334 * the only case the nssCKFWObject_Create() will need the objArena and the |
|
335 * Session is in the case of token objects (session objects should already |
|
336 * exist in the cache from their initial creation). So this code is correct, |
|
337 * but it depends on nssCKFWObject_Create caching all objects. |
|
338 */ |
|
339 objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError); |
|
340 if (!objArena) { |
|
341 if( CKR_OK == *pError ) { |
|
342 *pError = CKR_HOST_MEMORY; |
|
343 } |
|
344 goto done; |
|
345 } |
|
346 |
|
347 fwObject = nssCKFWObject_Create(objArena, mdObject, |
|
348 NULL, fwFindObjects->fwToken, |
|
349 fwFindObjects->fwInstance, pError); |
|
350 if (!fwObject) { |
|
351 if( CKR_OK == *pError ) { |
|
352 *pError = CKR_GENERAL_ERROR; |
|
353 } |
|
354 } |
|
355 |
|
356 done: |
|
357 (void)nssCKFWMutex_Unlock(fwFindObjects->mutex); |
|
358 return fwObject; |
|
359 } |
|
360 |
|
361 /* |
|
362 * NSSCKFWFindObjects_GetMDFindObjects |
|
363 * |
|
364 */ |
|
365 |
|
366 NSS_EXTERN NSSCKMDFindObjects * |
|
367 NSSCKFWFindObjects_GetMDFindObjects |
|
368 ( |
|
369 NSSCKFWFindObjects *fwFindObjects |
|
370 ) |
|
371 { |
|
372 #ifdef DEBUG |
|
373 if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) { |
|
374 return (NSSCKMDFindObjects *)NULL; |
|
375 } |
|
376 #endif /* DEBUG */ |
|
377 |
|
378 return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects); |
|
379 } |