sessobj.c 23 KB

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