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.
path_sep_char()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     const NSSCKFWFindObjects *fwFindObjects)
63 {
64     return CKR_OK;
65 }
66 
67 static CK_RV
errHandler(const std::string & str)68 findObjects_remove_pointer(
69     const NSSCKFWFindObjects *fwFindObjects)
70 {
71     return CKR_OK;
72 }
logHandler(const std::string & str)73 
74 NSS_IMPLEMENT CK_RV
75 nssCKFWFindObjects_verifyPointer(
76     const NSSCKFWFindObjects *fwFindObjects)
77 {
78     return CKR_OK;
79 }
80 
81 #endif /* DEBUG */
82 
83 /*
84  * nssCKFWFindObjects_Create
85  *
86  */
87 NSS_EXTERN NSSCKFWFindObjects *
88 nssCKFWFindObjects_Create(
89     NSSCKFWSession *fwSession,
90     NSSCKFWToken *fwToken,
91     NSSCKFWInstance *fwInstance,
92     NSSCKMDFindObjects *mdFindObjects1,
93     NSSCKMDFindObjects *mdFindObjects2,
94     CK_RV *pError)
95 {
96     NSSCKFWFindObjects *fwFindObjects = NULL;
97     NSSCKMDSession *mdSession;
98     NSSCKMDToken *mdToken;
99     NSSCKMDInstance *mdInstance;
100 
101     mdSession = nssCKFWSession_GetMDSession(fwSession);
102     mdToken = nssCKFWToken_GetMDToken(fwToken);
103     mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
104 
105     fwFindObjects = nss_ZNEW(NULL, NSSCKFWFindObjects);
106     if (!fwFindObjects) {
107         *pError = CKR_HOST_MEMORY;
write(std::vector<SpvWord> & spv,const std::string & outFile,int verbosity)108         goto loser;
109     }
110 
111     fwFindObjects->mdfo1 = mdFindObjects1;
112     fwFindObjects->mdfo2 = mdFindObjects2;
113     fwFindObjects->fwSession = fwSession;
114     fwFindObjects->mdSession = mdSession;
115     fwFindObjects->fwToken = fwToken;
116     fwFindObjects->mdToken = mdToken;
117     fwFindObjects->fwInstance = fwInstance;
118     fwFindObjects->mdInstance = mdInstance;
119 
120     fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, NULL, pError);
121     if (!fwFindObjects->mutex) {
122         goto loser;
123     }
124 
125 #ifdef DEBUG
126     *pError = findObjects_add_pointer(fwFindObjects);
127     if (CKR_OK != *pError) {
128         goto loser;
129     }
130 #endif /* DEBUG */
131 
132     return fwFindObjects;
133 
usage(const char * const name,const char * const msg=0)134 loser:
135     if (fwFindObjects) {
136         if (NULL != mdFindObjects1) {
137             if (NULL != mdFindObjects1->Final) {
138                 fwFindObjects->mdFindObjects = mdFindObjects1;
139                 mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession,
140                                       fwSession, mdToken, fwToken, mdInstance, fwInstance);
141             }
142         }
143 
144         if (NULL != mdFindObjects2) {
145             if (NULL != mdFindObjects2->Final) {
146                 fwFindObjects->mdFindObjects = mdFindObjects2;
147                 mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession,
148                                       fwSession, mdToken, fwToken, mdInstance, fwInstance);
149             }
150         }
151 
152         nss_ZFreeIf(fwFindObjects);
153     }
154 
155     if (CKR_OK == *pError) {
156         *pError = CKR_GENERAL_ERROR;
157     }
execute(const std::vector<std::string> & inputFile,const std::string & outputDir,int opts,int verbosity)158 
159     return (NSSCKFWFindObjects *)NULL;
160 }
161 
162 /*
163  * nssCKFWFindObjects_Destroy
164  *
165  */
166 NSS_EXTERN void
167 nssCKFWFindObjects_Destroy(
168     NSSCKFWFindObjects *fwFindObjects)
169 {
170 #ifdef NSSDEBUG
171     if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) {
172         return;
173     }
174 #endif /* NSSDEBUG */
175 
176     (void)nssCKFWMutex_Destroy(fwFindObjects->mutex);
parseCmdLine(int argc,char ** argv,std::vector<std::string> & inputFile,std::string & outputDir,int & options,int & verbosity)177 
178     if (fwFindObjects->mdfo1) {
179         if (fwFindObjects->mdfo1->Final) {
180             fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
181             fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
182                                         fwFindObjects->mdSession, fwFindObjects->fwSession,
183                                         fwFindObjects->mdToken, fwFindObjects->fwToken,
184                                         fwFindObjects->mdInstance, fwFindObjects->fwInstance);
185         }
186     }
187 
188     if (fwFindObjects->mdfo2) {
189         if (fwFindObjects->mdfo2->Final) {
190             fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
191             fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
192                                         fwFindObjects->mdSession, fwFindObjects->fwSession,
193                                         fwFindObjects->mdToken, fwFindObjects->fwToken,
194                                         fwFindObjects->mdInstance, fwFindObjects->fwInstance);
195         }
196     }
197 
198     nss_ZFreeIf(fwFindObjects);
199 
200 #ifdef DEBUG
201     (void)findObjects_remove_pointer(fwFindObjects);
202 #endif /* DEBUG */
203 
204     return;
205 }
206 
207 /*
208  * nssCKFWFindObjects_GetMDFindObjects
209  *
210  */
211 NSS_EXTERN NSSCKMDFindObjects *
212 nssCKFWFindObjects_GetMDFindObjects(
213     NSSCKFWFindObjects *fwFindObjects)
214 {
215 #ifdef NSSDEBUG
216     if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) {
217         return (NSSCKMDFindObjects *)NULL;
218     }
219 #endif /* NSSDEBUG */
220 
221     return fwFindObjects->mdFindObjects;
222 }
223 
224 /*
225  * nssCKFWFindObjects_Next
226  *
227  */
228 NSS_EXTERN NSSCKFWObject *
229 nssCKFWFindObjects_Next(
230     NSSCKFWFindObjects *fwFindObjects,
231     NSSArena *arenaOpt,
232     CK_RV *pError)
233 {
234     NSSCKMDObject *mdObject;
235     NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL;
236     NSSArena *objArena;
237 
238 #ifdef NSSDEBUG
239     if (!pError) {
240         return (NSSCKFWObject *)NULL;
241     }
242 
243     *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects);
244     if (CKR_OK != *pError) {
245         return (NSSCKFWObject *)NULL;
246     }
247 #endif /* NSSDEBUG */
248 
249     *pError = nssCKFWMutex_Lock(fwFindObjects->mutex);
250     if (CKR_OK != *pError) {
251         return (NSSCKFWObject *)NULL;
252     }
253 
254     if (fwFindObjects->mdfo1) {
255         if (fwFindObjects->mdfo1->Next) {
256             fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
257             mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1,
258                                                   fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
259                                                   fwFindObjects->mdToken, fwFindObjects->fwToken,
260                                                   fwFindObjects->mdInstance, fwFindObjects->fwInstance,
261                                                   arenaOpt, pError);
262             if (!mdObject) {
263                 if (CKR_OK != *pError) {
264                     goto done;
265                 }
266 
267                 /* All done. */
268                 fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
269                                             fwFindObjects->mdSession, fwFindObjects->fwSession,
270                                             fwFindObjects->mdToken, fwFindObjects->fwToken,
271                                             fwFindObjects->mdInstance, fwFindObjects->fwInstance);
272                 fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL;
273             } else {
274                 goto wrap;
275             }
276         }
277     }
278 
279     if (fwFindObjects->mdfo2) {
280         if (fwFindObjects->mdfo2->Next) {
281             fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
282             mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2,
283                                                   fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
284                                                   fwFindObjects->mdToken, fwFindObjects->fwToken,
285                                                   fwFindObjects->mdInstance, fwFindObjects->fwInstance,
286                                                   arenaOpt, pError);
287             if (!mdObject) {
288                 if (CKR_OK != *pError) {
289                     goto done;
290                 }
291 
292                 /* All done. */
293                 fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
294                                             fwFindObjects->mdSession, fwFindObjects->fwSession,
295                                             fwFindObjects->mdToken, fwFindObjects->fwToken,
296                                             fwFindObjects->mdInstance, fwFindObjects->fwInstance);
297                 fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL;
298             } else {
299                 goto wrap;
300             }
301         }
302     }
303 
304     /* No more objects */
305     *pError = CKR_OK;
306     goto done;
307 
308 wrap:
309     /*
310    * This seems is less than ideal-- we should determine if it's a token
311    * object or a session object, and use the appropriate arena.
312    * But that duplicates logic in nssCKFWObject_IsTokenObject.
313    * Also we should lookup the real session the object was created on
main(int argc,char ** argv)314    * if the object was a session object... however this code is actually
315    * correct because nssCKFWObject_Create will return a cached version of
316    * the object from it's hash. This is necessary because 1) we don't want
317    * to create an arena style leak (where our arena grows with every search),
318    * and 2) we want the same object to always have the same ID. This means
319    * the only case the nssCKFWObject_Create() will need the objArena and the
320    * Session is in the case of token objects (session objects should already
321    * exist in the cache from their initial creation). So this code is correct,
322    * but it depends on nssCKFWObject_Create caching all objects.
323    */
324     objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError);
325     if (!objArena) {
326         if (CKR_OK == *pError) {
327             *pError = CKR_HOST_MEMORY;
328         }
329         goto done;
330     }
331 
332     fwObject = nssCKFWObject_Create(objArena, mdObject,
333                                     NULL, fwFindObjects->fwToken,
334                                     fwFindObjects->fwInstance, pError);
335     if (!fwObject) {
336         if (CKR_OK == *pError) {
337             *pError = CKR_GENERAL_ERROR;
338         }
339     }
340 
341 done:
342     (void)nssCKFWMutex_Unlock(fwFindObjects->mutex);
343     return fwObject;
344 }
345 
346 /*
347  * NSSCKFWFindObjects_GetMDFindObjects
348  *
349  */
350 
351 NSS_EXTERN NSSCKMDFindObjects *
352 NSSCKFWFindObjects_GetMDFindObjects(
353     NSSCKFWFindObjects *fwFindObjects)
354 {
355 #ifdef DEBUG
356     if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) {
357         return (NSSCKMDFindObjects *)NULL;
358     }
359 #endif /* DEBUG */
360 
361     return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects);
362 }
363