find.c 11 KB

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