instance.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295
  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. * instance.c
  6. *
  7. * This file implements the NSSCKFWInstance type and methods.
  8. */
  9. #ifndef CK_T
  10. #include "ck.h"
  11. #endif /* CK_T */
  12. /*
  13. * NSSCKFWInstance
  14. *
  15. * -- create/destroy --
  16. * nssCKFWInstance_Create
  17. * nssCKFWInstance_Destroy
  18. *
  19. * -- public accessors --
  20. * NSSCKFWInstance_GetMDInstance
  21. * NSSCKFWInstance_GetArena
  22. * NSSCKFWInstance_MayCreatePthreads
  23. * NSSCKFWInstance_CreateMutex
  24. * NSSCKFWInstance_GetConfigurationData
  25. * NSSCKFWInstance_GetInitArgs
  26. * NSSCKFWInstance_DestroySessionHandle
  27. * NSSCKFWInstance_FindSessionHandle
  28. *
  29. * -- implement public accessors --
  30. * nssCKFWInstance_GetMDInstance
  31. * nssCKFWInstance_GetArena
  32. * nssCKFWInstance_MayCreatePthreads
  33. * nssCKFWInstance_CreateMutex
  34. * nssCKFWInstance_GetConfigurationData
  35. * nssCKFWInstance_GetInitArgs
  36. * nssCKFWInstance_DestroySessionHandle
  37. * nssCKFWInstance_FindSessionHandle
  38. *
  39. * -- private accessors --
  40. * nssCKFWInstance_CreateSessionHandle
  41. * nssCKFWInstance_ResolveSessionHandle
  42. * nssCKFWInstance_CreateObjectHandle
  43. * nssCKFWInstance_ResolveObjectHandle
  44. * nssCKFWInstance_DestroyObjectHandle
  45. *
  46. * -- module fronts --
  47. * nssCKFWInstance_GetNSlots
  48. * nssCKFWInstance_GetCryptokiVersion
  49. * nssCKFWInstance_GetManufacturerID
  50. * nssCKFWInstance_GetFlags
  51. * nssCKFWInstance_GetLibraryDescription
  52. * nssCKFWInstance_GetLibraryVersion
  53. * nssCKFWInstance_GetModuleHandlesSessionObjects
  54. * nssCKFWInstance_GetSlots
  55. * nssCKFWInstance_WaitForSlotEvent
  56. *
  57. * -- debugging versions only --
  58. * nssCKFWInstance_verifyPointer
  59. */
  60. struct NSSCKFWInstanceStr {
  61. NSSCKFWMutex *mutex;
  62. NSSArena *arena;
  63. NSSCKMDInstance *mdInstance;
  64. CK_C_INITIALIZE_ARGS_PTR pInitArgs;
  65. CK_C_INITIALIZE_ARGS initArgs;
  66. CryptokiLockingState LockingState;
  67. CK_BBOOL mayCreatePthreads;
  68. NSSUTF8 *configurationData;
  69. CK_ULONG nSlots;
  70. NSSCKFWSlot **fwSlotList;
  71. NSSCKMDSlot **mdSlotList;
  72. CK_BBOOL moduleHandlesSessionObjects;
  73. /*
  74. * Everything above is set at creation time, and then not modified.
  75. * The invariants the mutex protects are:
  76. *
  77. * 1) Each of the cached descriptions (versions, etc.) are in an
  78. * internally consistant state.
  79. *
  80. * 2) The session handle hashes and count are consistant
  81. *
  82. * 3) The object handle hashes and count are consistant.
  83. *
  84. * I could use multiple locks, but let's wait to see if that's
  85. * really necessary.
  86. *
  87. * Note that the calls accessing the cached descriptions will
  88. * call the NSSCKMDInstance methods with the mutex locked. Those
  89. * methods may then call the public NSSCKFWInstance routines.
  90. * Those public routines only access the constant data above, so
  91. * there's no problem. But be careful if you add to this object;
  92. * mutexes are in general not reentrant, so don't create deadlock
  93. * situations.
  94. */
  95. CK_VERSION cryptokiVersion;
  96. NSSUTF8 *manufacturerID;
  97. NSSUTF8 *libraryDescription;
  98. CK_VERSION libraryVersion;
  99. CK_ULONG lastSessionHandle;
  100. nssCKFWHash *sessionHandleHash;
  101. CK_ULONG lastObjectHandle;
  102. nssCKFWHash *objectHandleHash;
  103. };
  104. #ifdef DEBUG
  105. /*
  106. * But first, the pointer-tracking stuff.
  107. *
  108. * NOTE: the pointer-tracking support in NSS/base currently relies
  109. * upon NSPR's CallOnce support. That, however, relies upon NSPR's
  110. * locking, which is tied into the runtime. We need a pointer-tracker
  111. * implementation that uses the locks supplied through C_Initialize.
  112. * That support, however, can be filled in later. So for now, I'll
  113. * just do this routines as no-ops.
  114. */
  115. static CK_RV
  116. instance_add_pointer(
  117. const NSSCKFWInstance *fwInstance)
  118. {
  119. return CKR_OK;
  120. }
  121. static CK_RV
  122. instance_remove_pointer(
  123. const NSSCKFWInstance *fwInstance)
  124. {
  125. return CKR_OK;
  126. }
  127. NSS_IMPLEMENT CK_RV
  128. nssCKFWInstance_verifyPointer(
  129. const NSSCKFWInstance *fwInstance)
  130. {
  131. return CKR_OK;
  132. }
  133. #endif /* DEBUG */
  134. /*
  135. * nssCKFWInstance_Create
  136. *
  137. */
  138. NSS_IMPLEMENT NSSCKFWInstance *
  139. nssCKFWInstance_Create(
  140. CK_C_INITIALIZE_ARGS_PTR pInitArgs,
  141. CryptokiLockingState LockingState,
  142. NSSCKMDInstance *mdInstance,
  143. CK_RV *pError)
  144. {
  145. NSSCKFWInstance *fwInstance;
  146. NSSArena *arena = (NSSArena *)NULL;
  147. CK_ULONG i;
  148. CK_BBOOL called_Initialize = CK_FALSE;
  149. #ifdef NSSDEBUG
  150. if ((CK_RV)NULL == pError) {
  151. return (NSSCKFWInstance *)NULL;
  152. }
  153. if (!mdInstance) {
  154. *pError = CKR_ARGUMENTS_BAD;
  155. return (NSSCKFWInstance *)NULL;
  156. }
  157. #endif /* NSSDEBUG */
  158. arena = NSSArena_Create();
  159. if (!arena) {
  160. *pError = CKR_HOST_MEMORY;
  161. return (NSSCKFWInstance *)NULL;
  162. }
  163. fwInstance = nss_ZNEW(arena, NSSCKFWInstance);
  164. if (!fwInstance) {
  165. goto nomem;
  166. }
  167. fwInstance->arena = arena;
  168. fwInstance->mdInstance = mdInstance;
  169. fwInstance->LockingState = LockingState;
  170. if ((CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs) {
  171. fwInstance->initArgs = *pInitArgs;
  172. fwInstance->pInitArgs = &fwInstance->initArgs;
  173. if (pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
  174. fwInstance->mayCreatePthreads = CK_FALSE;
  175. } else {
  176. fwInstance->mayCreatePthreads = CK_TRUE;
  177. }
  178. fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved);
  179. } else {
  180. fwInstance->mayCreatePthreads = CK_TRUE;
  181. }
  182. fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, LockingState, arena,
  183. pError);
  184. if (!fwInstance->mutex) {
  185. if (CKR_OK == *pError) {
  186. *pError = CKR_GENERAL_ERROR;
  187. }
  188. goto loser;
  189. }
  190. if (mdInstance->Initialize) {
  191. *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData);
  192. if (CKR_OK != *pError) {
  193. goto loser;
  194. }
  195. called_Initialize = CK_TRUE;
  196. }
  197. if (mdInstance->ModuleHandlesSessionObjects) {
  198. fwInstance->moduleHandlesSessionObjects =
  199. mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);
  200. } else {
  201. fwInstance->moduleHandlesSessionObjects = CK_FALSE;
  202. }
  203. if (!mdInstance->GetNSlots) {
  204. /* That routine is required */
  205. *pError = CKR_GENERAL_ERROR;
  206. goto loser;
  207. }
  208. fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError);
  209. if ((CK_ULONG)0 == fwInstance->nSlots) {
  210. if (CKR_OK == *pError) {
  211. /* Zero is not a legitimate answer */
  212. *pError = CKR_GENERAL_ERROR;
  213. }
  214. goto loser;
  215. }
  216. fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots);
  217. if ((NSSCKFWSlot **)NULL == fwInstance->fwSlotList) {
  218. goto nomem;
  219. }
  220. fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots);
  221. if ((NSSCKMDSlot **)NULL == fwInstance->mdSlotList) {
  222. goto nomem;
  223. }
  224. fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance,
  225. fwInstance->arena, pError);
  226. if (!fwInstance->sessionHandleHash) {
  227. goto loser;
  228. }
  229. fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance,
  230. fwInstance->arena, pError);
  231. if (!fwInstance->objectHandleHash) {
  232. goto loser;
  233. }
  234. if (!mdInstance->GetSlots) {
  235. /* That routine is required */
  236. *pError = CKR_GENERAL_ERROR;
  237. goto loser;
  238. }
  239. *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList);
  240. if (CKR_OK != *pError) {
  241. goto loser;
  242. }
  243. for (i = 0; i < fwInstance->nSlots; i++) {
  244. NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i];
  245. if (!mdSlot) {
  246. *pError = CKR_GENERAL_ERROR;
  247. goto loser;
  248. }
  249. fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError);
  250. if (CKR_OK != *pError) {
  251. CK_ULONG j;
  252. for (j = 0; j < i; j++) {
  253. (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]);
  254. }
  255. for (j = i; j < fwInstance->nSlots; j++) {
  256. NSSCKMDSlot *mds = fwInstance->mdSlotList[j];
  257. if (mds->Destroy) {
  258. mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance);
  259. }
  260. }
  261. goto loser;
  262. }
  263. }
  264. #ifdef DEBUG
  265. *pError = instance_add_pointer(fwInstance);
  266. if (CKR_OK != *pError) {
  267. for (i = 0; i < fwInstance->nSlots; i++) {
  268. (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
  269. }
  270. goto loser;
  271. }
  272. #endif /* DEBUG */
  273. *pError = CKR_OK;
  274. return fwInstance;
  275. nomem:
  276. *pError = CKR_HOST_MEMORY;
  277. /*FALLTHROUGH*/
  278. loser:
  279. if (CK_TRUE == called_Initialize) {
  280. if (mdInstance->Finalize) {
  281. mdInstance->Finalize(mdInstance, fwInstance);
  282. }
  283. }
  284. if (fwInstance && fwInstance->mutex) {
  285. nssCKFWMutex_Destroy(fwInstance->mutex);
  286. }
  287. if (arena) {
  288. (void)NSSArena_Destroy(arena);
  289. }
  290. return (NSSCKFWInstance *)NULL;
  291. }
  292. /*
  293. * nssCKFWInstance_Destroy
  294. *
  295. */
  296. NSS_IMPLEMENT CK_RV
  297. nssCKFWInstance_Destroy(
  298. NSSCKFWInstance *fwInstance)
  299. {
  300. #ifdef NSSDEBUG
  301. CK_RV error = CKR_OK;
  302. #endif /* NSSDEBUG */
  303. CK_ULONG i;
  304. #ifdef NSSDEBUG
  305. error = nssCKFWInstance_verifyPointer(fwInstance);
  306. if (CKR_OK != error) {
  307. return error;
  308. }
  309. #endif /* NSSDEBUG */
  310. nssCKFWMutex_Destroy(fwInstance->mutex);
  311. for (i = 0; i < fwInstance->nSlots; i++) {
  312. (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
  313. }
  314. if (fwInstance->mdInstance->Finalize) {
  315. fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance);
  316. }
  317. if (fwInstance->sessionHandleHash) {
  318. nssCKFWHash_Destroy(fwInstance->sessionHandleHash);
  319. }
  320. if (fwInstance->objectHandleHash) {
  321. nssCKFWHash_Destroy(fwInstance->objectHandleHash);
  322. }
  323. #ifdef DEBUG
  324. (void)instance_remove_pointer(fwInstance);
  325. #endif /* DEBUG */
  326. (void)NSSArena_Destroy(fwInstance->arena);
  327. return CKR_OK;
  328. }
  329. /*
  330. * nssCKFWInstance_GetMDInstance
  331. *
  332. */
  333. NSS_IMPLEMENT NSSCKMDInstance *
  334. nssCKFWInstance_GetMDInstance(
  335. NSSCKFWInstance *fwInstance)
  336. {
  337. #ifdef NSSDEBUG
  338. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  339. return (NSSCKMDInstance *)NULL;
  340. }
  341. #endif /* NSSDEBUG */
  342. return fwInstance->mdInstance;
  343. }
  344. /*
  345. * nssCKFWInstance_GetArena
  346. *
  347. */
  348. NSS_IMPLEMENT NSSArena *
  349. nssCKFWInstance_GetArena(
  350. NSSCKFWInstance *fwInstance,
  351. CK_RV *pError)
  352. {
  353. #ifdef NSSDEBUG
  354. if (!pError) {
  355. return (NSSArena *)NULL;
  356. }
  357. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  358. if (CKR_OK != *pError) {
  359. return (NSSArena *)NULL;
  360. }
  361. #endif /* NSSDEBUG */
  362. *pError = CKR_OK;
  363. return fwInstance->arena;
  364. }
  365. /*
  366. * nssCKFWInstance_MayCreatePthreads
  367. *
  368. */
  369. NSS_IMPLEMENT CK_BBOOL
  370. nssCKFWInstance_MayCreatePthreads(
  371. NSSCKFWInstance *fwInstance)
  372. {
  373. #ifdef NSSDEBUG
  374. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  375. return CK_FALSE;
  376. }
  377. #endif /* NSSDEBUG */
  378. return fwInstance->mayCreatePthreads;
  379. }
  380. /*
  381. * nssCKFWInstance_CreateMutex
  382. *
  383. */
  384. NSS_IMPLEMENT NSSCKFWMutex *
  385. nssCKFWInstance_CreateMutex(
  386. NSSCKFWInstance *fwInstance,
  387. NSSArena *arena,
  388. CK_RV *pError)
  389. {
  390. NSSCKFWMutex *mutex;
  391. #ifdef NSSDEBUG
  392. if (!pError) {
  393. return (NSSCKFWMutex *)NULL;
  394. }
  395. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  396. if (CKR_OK != *pError) {
  397. return (NSSCKFWMutex *)NULL;
  398. }
  399. #endif /* NSSDEBUG */
  400. mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, fwInstance->LockingState,
  401. arena, pError);
  402. if (!mutex) {
  403. if (CKR_OK == *pError) {
  404. *pError = CKR_GENERAL_ERROR;
  405. }
  406. return (NSSCKFWMutex *)NULL;
  407. }
  408. return mutex;
  409. }
  410. /*
  411. * nssCKFWInstance_GetConfigurationData
  412. *
  413. */
  414. NSS_IMPLEMENT NSSUTF8 *
  415. nssCKFWInstance_GetConfigurationData(
  416. NSSCKFWInstance *fwInstance)
  417. {
  418. #ifdef NSSDEBUG
  419. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  420. return (NSSUTF8 *)NULL;
  421. }
  422. #endif /* NSSDEBUG */
  423. return fwInstance->configurationData;
  424. }
  425. /*
  426. * nssCKFWInstance_GetInitArgs
  427. *
  428. */
  429. CK_C_INITIALIZE_ARGS_PTR
  430. nssCKFWInstance_GetInitArgs(
  431. NSSCKFWInstance *fwInstance)
  432. {
  433. #ifdef NSSDEBUG
  434. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  435. return (CK_C_INITIALIZE_ARGS_PTR)NULL;
  436. }
  437. #endif /* NSSDEBUG */
  438. return fwInstance->pInitArgs;
  439. }
  440. /*
  441. * nssCKFWInstance_CreateSessionHandle
  442. *
  443. */
  444. NSS_IMPLEMENT CK_SESSION_HANDLE
  445. nssCKFWInstance_CreateSessionHandle(
  446. NSSCKFWInstance *fwInstance,
  447. NSSCKFWSession *fwSession,
  448. CK_RV *pError)
  449. {
  450. CK_SESSION_HANDLE hSession;
  451. #ifdef NSSDEBUG
  452. if (!pError) {
  453. return (CK_SESSION_HANDLE)0;
  454. }
  455. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  456. if (CKR_OK != *pError) {
  457. return (CK_SESSION_HANDLE)0;
  458. }
  459. #endif /* NSSDEBUG */
  460. *pError = nssCKFWMutex_Lock(fwInstance->mutex);
  461. if (CKR_OK != *pError) {
  462. return (CK_SESSION_HANDLE)0;
  463. }
  464. hSession = ++(fwInstance->lastSessionHandle);
  465. /* Alan would say I should unlock for this call. */
  466. *pError = nssCKFWSession_SetHandle(fwSession, hSession);
  467. if (CKR_OK != *pError) {
  468. goto done;
  469. }
  470. *pError = nssCKFWHash_Add(fwInstance->sessionHandleHash,
  471. (const void *)hSession, (const void *)fwSession);
  472. if (CKR_OK != *pError) {
  473. hSession = (CK_SESSION_HANDLE)0;
  474. goto done;
  475. }
  476. done:
  477. nssCKFWMutex_Unlock(fwInstance->mutex);
  478. return hSession;
  479. }
  480. /*
  481. * nssCKFWInstance_ResolveSessionHandle
  482. *
  483. */
  484. NSS_IMPLEMENT NSSCKFWSession *
  485. nssCKFWInstance_ResolveSessionHandle(
  486. NSSCKFWInstance *fwInstance,
  487. CK_SESSION_HANDLE hSession)
  488. {
  489. NSSCKFWSession *fwSession;
  490. #ifdef NSSDEBUG
  491. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  492. return (NSSCKFWSession *)NULL;
  493. }
  494. #endif /* NSSDEBUG */
  495. if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
  496. return (NSSCKFWSession *)NULL;
  497. }
  498. fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
  499. fwInstance->sessionHandleHash, (const void *)hSession);
  500. /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */
  501. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  502. return fwSession;
  503. }
  504. /*
  505. * nssCKFWInstance_DestroySessionHandle
  506. *
  507. */
  508. NSS_IMPLEMENT void
  509. nssCKFWInstance_DestroySessionHandle(
  510. NSSCKFWInstance *fwInstance,
  511. CK_SESSION_HANDLE hSession)
  512. {
  513. NSSCKFWSession *fwSession;
  514. #ifdef NSSDEBUG
  515. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  516. return;
  517. }
  518. #endif /* NSSDEBUG */
  519. if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
  520. return;
  521. }
  522. fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
  523. fwInstance->sessionHandleHash, (const void *)hSession);
  524. if (fwSession) {
  525. nssCKFWHash_Remove(fwInstance->sessionHandleHash, (const void *)hSession);
  526. nssCKFWSession_SetHandle(fwSession, (CK_SESSION_HANDLE)0);
  527. }
  528. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  529. return;
  530. }
  531. /*
  532. * nssCKFWInstance_FindSessionHandle
  533. *
  534. */
  535. NSS_IMPLEMENT CK_SESSION_HANDLE
  536. nssCKFWInstance_FindSessionHandle(
  537. NSSCKFWInstance *fwInstance,
  538. NSSCKFWSession *fwSession)
  539. {
  540. #ifdef NSSDEBUG
  541. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  542. return (CK_SESSION_HANDLE)0;
  543. }
  544. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  545. return (CK_SESSION_HANDLE)0;
  546. }
  547. #endif /* NSSDEBUG */
  548. return nssCKFWSession_GetHandle(fwSession);
  549. /* look it up and assert? */
  550. }
  551. /*
  552. * nssCKFWInstance_CreateObjectHandle
  553. *
  554. */
  555. NSS_IMPLEMENT CK_OBJECT_HANDLE
  556. nssCKFWInstance_CreateObjectHandle(
  557. NSSCKFWInstance *fwInstance,
  558. NSSCKFWObject *fwObject,
  559. CK_RV *pError)
  560. {
  561. CK_OBJECT_HANDLE hObject;
  562. #ifdef NSSDEBUG
  563. if (!pError) {
  564. return (CK_OBJECT_HANDLE)0;
  565. }
  566. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  567. if (CKR_OK != *pError) {
  568. return (CK_OBJECT_HANDLE)0;
  569. }
  570. #endif /* NSSDEBUG */
  571. *pError = nssCKFWMutex_Lock(fwInstance->mutex);
  572. if (CKR_OK != *pError) {
  573. return (CK_OBJECT_HANDLE)0;
  574. }
  575. hObject = ++(fwInstance->lastObjectHandle);
  576. *pError = nssCKFWObject_SetHandle(fwObject, hObject);
  577. if (CKR_OK != *pError) {
  578. hObject = (CK_OBJECT_HANDLE)0;
  579. goto done;
  580. }
  581. *pError = nssCKFWHash_Add(fwInstance->objectHandleHash,
  582. (const void *)hObject, (const void *)fwObject);
  583. if (CKR_OK != *pError) {
  584. hObject = (CK_OBJECT_HANDLE)0;
  585. goto done;
  586. }
  587. done:
  588. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  589. return hObject;
  590. }
  591. /*
  592. * nssCKFWInstance_ResolveObjectHandle
  593. *
  594. */
  595. NSS_IMPLEMENT NSSCKFWObject *
  596. nssCKFWInstance_ResolveObjectHandle(
  597. NSSCKFWInstance *fwInstance,
  598. CK_OBJECT_HANDLE hObject)
  599. {
  600. NSSCKFWObject *fwObject;
  601. #ifdef NSSDEBUG
  602. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  603. return (NSSCKFWObject *)NULL;
  604. }
  605. #endif /* NSSDEBUG */
  606. if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
  607. return (NSSCKFWObject *)NULL;
  608. }
  609. fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
  610. fwInstance->objectHandleHash, (const void *)hObject);
  611. /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */
  612. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  613. return fwObject;
  614. }
  615. /*
  616. * nssCKFWInstance_ReassignObjectHandle
  617. *
  618. */
  619. NSS_IMPLEMENT CK_RV
  620. nssCKFWInstance_ReassignObjectHandle(
  621. NSSCKFWInstance *fwInstance,
  622. CK_OBJECT_HANDLE hObject,
  623. NSSCKFWObject *fwObject)
  624. {
  625. CK_RV error = CKR_OK;
  626. NSSCKFWObject *oldObject;
  627. #ifdef NSSDEBUG
  628. error = nssCKFWInstance_verifyPointer(fwInstance);
  629. if (CKR_OK != error) {
  630. return error;
  631. }
  632. #endif /* NSSDEBUG */
  633. error = nssCKFWMutex_Lock(fwInstance->mutex);
  634. if (CKR_OK != error) {
  635. return error;
  636. }
  637. oldObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
  638. fwInstance->objectHandleHash, (const void *)hObject);
  639. if (oldObject) {
  640. /* Assert(hObject == nssCKFWObject_GetHandle(oldObject) */
  641. (void)nssCKFWObject_SetHandle(oldObject, (CK_SESSION_HANDLE)0);
  642. nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
  643. }
  644. error = nssCKFWObject_SetHandle(fwObject, hObject);
  645. if (CKR_OK != error) {
  646. goto done;
  647. }
  648. error = nssCKFWHash_Add(fwInstance->objectHandleHash,
  649. (const void *)hObject, (const void *)fwObject);
  650. done:
  651. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  652. return error;
  653. }
  654. /*
  655. * nssCKFWInstance_DestroyObjectHandle
  656. *
  657. */
  658. NSS_IMPLEMENT void
  659. nssCKFWInstance_DestroyObjectHandle(
  660. NSSCKFWInstance *fwInstance,
  661. CK_OBJECT_HANDLE hObject)
  662. {
  663. NSSCKFWObject *fwObject;
  664. #ifdef NSSDEBUG
  665. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  666. return;
  667. }
  668. #endif /* NSSDEBUG */
  669. if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
  670. return;
  671. }
  672. fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
  673. fwInstance->objectHandleHash, (const void *)hObject);
  674. if (fwObject) {
  675. /* Assert(hObject = nssCKFWObject_GetHandle(fwObject)) */
  676. nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
  677. (void)nssCKFWObject_SetHandle(fwObject, (CK_SESSION_HANDLE)0);
  678. }
  679. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  680. return;
  681. }
  682. /*
  683. * nssCKFWInstance_FindObjectHandle
  684. *
  685. */
  686. NSS_IMPLEMENT CK_OBJECT_HANDLE
  687. nssCKFWInstance_FindObjectHandle(
  688. NSSCKFWInstance *fwInstance,
  689. NSSCKFWObject *fwObject)
  690. {
  691. #ifdef NSSDEBUG
  692. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  693. return (CK_OBJECT_HANDLE)0;
  694. }
  695. if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
  696. return (CK_OBJECT_HANDLE)0;
  697. }
  698. #endif /* NSSDEBUG */
  699. return nssCKFWObject_GetHandle(fwObject);
  700. }
  701. /*
  702. * nssCKFWInstance_GetNSlots
  703. *
  704. */
  705. NSS_IMPLEMENT CK_ULONG
  706. nssCKFWInstance_GetNSlots(
  707. NSSCKFWInstance *fwInstance,
  708. CK_RV *pError)
  709. {
  710. #ifdef NSSDEBUG
  711. if (!pError) {
  712. return (CK_ULONG)0;
  713. }
  714. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  715. if (CKR_OK != *pError) {
  716. return (CK_ULONG)0;
  717. }
  718. #endif /* NSSDEBUG */
  719. *pError = CKR_OK;
  720. return fwInstance->nSlots;
  721. }
  722. /*
  723. * nssCKFWInstance_GetCryptokiVersion
  724. *
  725. */
  726. NSS_IMPLEMENT CK_VERSION
  727. nssCKFWInstance_GetCryptokiVersion(
  728. NSSCKFWInstance *fwInstance)
  729. {
  730. CK_VERSION rv;
  731. #ifdef NSSDEBUG
  732. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  733. rv.major = rv.minor = 0;
  734. return rv;
  735. }
  736. #endif /* NSSDEBUG */
  737. if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
  738. rv.major = rv.minor = 0;
  739. return rv;
  740. }
  741. if ((0 != fwInstance->cryptokiVersion.major) ||
  742. (0 != fwInstance->cryptokiVersion.minor)) {
  743. rv = fwInstance->cryptokiVersion;
  744. goto done;
  745. }
  746. if (fwInstance->mdInstance->GetCryptokiVersion) {
  747. fwInstance->cryptokiVersion = fwInstance->mdInstance->GetCryptokiVersion(
  748. fwInstance->mdInstance, fwInstance);
  749. } else {
  750. fwInstance->cryptokiVersion.major = 2;
  751. fwInstance->cryptokiVersion.minor = 1;
  752. }
  753. rv = fwInstance->cryptokiVersion;
  754. done:
  755. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  756. return rv;
  757. }
  758. /*
  759. * nssCKFWInstance_GetManufacturerID
  760. *
  761. */
  762. NSS_IMPLEMENT CK_RV
  763. nssCKFWInstance_GetManufacturerID(
  764. NSSCKFWInstance *fwInstance,
  765. CK_CHAR manufacturerID[32])
  766. {
  767. CK_RV error = CKR_OK;
  768. #ifdef NSSDEBUG
  769. if ((CK_CHAR_PTR)NULL == manufacturerID) {
  770. return CKR_ARGUMENTS_BAD;
  771. }
  772. error = nssCKFWInstance_verifyPointer(fwInstance);
  773. if (CKR_OK != error) {
  774. return error;
  775. }
  776. #endif /* NSSDEBUG */
  777. error = nssCKFWMutex_Lock(fwInstance->mutex);
  778. if (CKR_OK != error) {
  779. return error;
  780. }
  781. if (!fwInstance->manufacturerID) {
  782. if (fwInstance->mdInstance->GetManufacturerID) {
  783. fwInstance->manufacturerID = fwInstance->mdInstance->GetManufacturerID(
  784. fwInstance->mdInstance, fwInstance, &error);
  785. if ((!fwInstance->manufacturerID) && (CKR_OK != error)) {
  786. goto done;
  787. }
  788. } else {
  789. fwInstance->manufacturerID = (NSSUTF8 *)"";
  790. }
  791. }
  792. (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, (char *)manufacturerID, 32, ' ');
  793. error = CKR_OK;
  794. done:
  795. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  796. return error;
  797. }
  798. /*
  799. * nssCKFWInstance_GetFlags
  800. *
  801. */
  802. NSS_IMPLEMENT CK_ULONG
  803. nssCKFWInstance_GetFlags(
  804. NSSCKFWInstance *fwInstance)
  805. {
  806. #ifdef NSSDEBUG
  807. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  808. return (CK_ULONG)0;
  809. }
  810. #endif /* NSSDEBUG */
  811. /* No "instance flags" are yet defined by Cryptoki. */
  812. return (CK_ULONG)0;
  813. }
  814. /*
  815. * nssCKFWInstance_GetLibraryDescription
  816. *
  817. */
  818. NSS_IMPLEMENT CK_RV
  819. nssCKFWInstance_GetLibraryDescription(
  820. NSSCKFWInstance *fwInstance,
  821. CK_CHAR libraryDescription[32])
  822. {
  823. CK_RV error = CKR_OK;
  824. #ifdef NSSDEBUG
  825. if ((CK_CHAR_PTR)NULL == libraryDescription) {
  826. return CKR_ARGUMENTS_BAD;
  827. }
  828. error = nssCKFWInstance_verifyPointer(fwInstance);
  829. if (CKR_OK != error) {
  830. return error;
  831. }
  832. #endif /* NSSDEBUG */
  833. error = nssCKFWMutex_Lock(fwInstance->mutex);
  834. if (CKR_OK != error) {
  835. return error;
  836. }
  837. if (!fwInstance->libraryDescription) {
  838. if (fwInstance->mdInstance->GetLibraryDescription) {
  839. fwInstance->libraryDescription = fwInstance->mdInstance->GetLibraryDescription(
  840. fwInstance->mdInstance, fwInstance, &error);
  841. if ((!fwInstance->libraryDescription) && (CKR_OK != error)) {
  842. goto done;
  843. }
  844. } else {
  845. fwInstance->libraryDescription = (NSSUTF8 *)"";
  846. }
  847. }
  848. (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, (char *)libraryDescription, 32, ' ');
  849. error = CKR_OK;
  850. done:
  851. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  852. return error;
  853. }
  854. /*
  855. * nssCKFWInstance_GetLibraryVersion
  856. *
  857. */
  858. NSS_IMPLEMENT CK_VERSION
  859. nssCKFWInstance_GetLibraryVersion(
  860. NSSCKFWInstance *fwInstance)
  861. {
  862. CK_VERSION rv;
  863. #ifdef NSSDEBUG
  864. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  865. rv.major = rv.minor = 0;
  866. return rv;
  867. }
  868. #endif /* NSSDEBUG */
  869. if (CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex)) {
  870. rv.major = rv.minor = 0;
  871. return rv;
  872. }
  873. if ((0 != fwInstance->libraryVersion.major) ||
  874. (0 != fwInstance->libraryVersion.minor)) {
  875. rv = fwInstance->libraryVersion;
  876. goto done;
  877. }
  878. if (fwInstance->mdInstance->GetLibraryVersion) {
  879. fwInstance->libraryVersion = fwInstance->mdInstance->GetLibraryVersion(
  880. fwInstance->mdInstance, fwInstance);
  881. } else {
  882. fwInstance->libraryVersion.major = 0;
  883. fwInstance->libraryVersion.minor = 3;
  884. }
  885. rv = fwInstance->libraryVersion;
  886. done:
  887. (void)nssCKFWMutex_Unlock(fwInstance->mutex);
  888. return rv;
  889. }
  890. /*
  891. * nssCKFWInstance_GetModuleHandlesSessionObjects
  892. *
  893. */
  894. NSS_IMPLEMENT CK_BBOOL
  895. nssCKFWInstance_GetModuleHandlesSessionObjects(
  896. NSSCKFWInstance *fwInstance)
  897. {
  898. #ifdef NSSDEBUG
  899. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  900. return CK_FALSE;
  901. }
  902. #endif /* NSSDEBUG */
  903. return fwInstance->moduleHandlesSessionObjects;
  904. }
  905. /*
  906. * nssCKFWInstance_GetSlots
  907. *
  908. */
  909. NSS_IMPLEMENT NSSCKFWSlot **
  910. nssCKFWInstance_GetSlots(
  911. NSSCKFWInstance *fwInstance,
  912. CK_RV *pError)
  913. {
  914. #ifdef NSSDEBUG
  915. if (!pError) {
  916. return (NSSCKFWSlot **)NULL;
  917. }
  918. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  919. if (CKR_OK != *pError) {
  920. return (NSSCKFWSlot **)NULL;
  921. }
  922. #endif /* NSSDEBUG */
  923. return fwInstance->fwSlotList;
  924. }
  925. /*
  926. * nssCKFWInstance_WaitForSlotEvent
  927. *
  928. */
  929. NSS_IMPLEMENT NSSCKFWSlot *
  930. nssCKFWInstance_WaitForSlotEvent(
  931. NSSCKFWInstance *fwInstance,
  932. CK_BBOOL block,
  933. CK_RV *pError)
  934. {
  935. NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL;
  936. NSSCKMDSlot *mdSlot;
  937. CK_ULONG i, n;
  938. #ifdef NSSDEBUG
  939. if (!pError) {
  940. return (NSSCKFWSlot *)NULL;
  941. }
  942. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  943. if (CKR_OK != *pError) {
  944. return (NSSCKFWSlot *)NULL;
  945. }
  946. switch (block) {
  947. case CK_TRUE:
  948. case CK_FALSE:
  949. break;
  950. default:
  951. *pError = CKR_ARGUMENTS_BAD;
  952. return (NSSCKFWSlot *)NULL;
  953. }
  954. #endif /* NSSDEBUG */
  955. if (!fwInstance->mdInstance->WaitForSlotEvent) {
  956. *pError = CKR_NO_EVENT;
  957. return (NSSCKFWSlot *)NULL;
  958. }
  959. mdSlot = fwInstance->mdInstance->WaitForSlotEvent(
  960. fwInstance->mdInstance,
  961. fwInstance,
  962. block,
  963. pError);
  964. if (!mdSlot) {
  965. return (NSSCKFWSlot *)NULL;
  966. }
  967. n = nssCKFWInstance_GetNSlots(fwInstance, pError);
  968. if (((CK_ULONG)0 == n) && (CKR_OK != *pError)) {
  969. return (NSSCKFWSlot *)NULL;
  970. }
  971. for (i = 0; i < n; i++) {
  972. if (fwInstance->mdSlotList[i] == mdSlot) {
  973. fwSlot = fwInstance->fwSlotList[i];
  974. break;
  975. }
  976. }
  977. if (!fwSlot) {
  978. /* Internal error */
  979. *pError = CKR_GENERAL_ERROR;
  980. return (NSSCKFWSlot *)NULL;
  981. }
  982. return fwSlot;
  983. }
  984. /*
  985. * NSSCKFWInstance_GetMDInstance
  986. *
  987. */
  988. NSS_IMPLEMENT NSSCKMDInstance *
  989. NSSCKFWInstance_GetMDInstance(
  990. NSSCKFWInstance *fwInstance)
  991. {
  992. #ifdef DEBUG
  993. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  994. return (NSSCKMDInstance *)NULL;
  995. }
  996. #endif /* DEBUG */
  997. return nssCKFWInstance_GetMDInstance(fwInstance);
  998. }
  999. /*
  1000. * NSSCKFWInstance_GetArena
  1001. *
  1002. */
  1003. NSS_IMPLEMENT NSSArena *
  1004. NSSCKFWInstance_GetArena(
  1005. NSSCKFWInstance *fwInstance,
  1006. CK_RV *pError)
  1007. {
  1008. #ifdef DEBUG
  1009. if (!pError) {
  1010. return (NSSArena *)NULL;
  1011. }
  1012. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  1013. if (CKR_OK != *pError) {
  1014. return (NSSArena *)NULL;
  1015. }
  1016. #endif /* DEBUG */
  1017. return nssCKFWInstance_GetArena(fwInstance, pError);
  1018. }
  1019. /*
  1020. * NSSCKFWInstance_MayCreatePthreads
  1021. *
  1022. */
  1023. NSS_IMPLEMENT CK_BBOOL
  1024. NSSCKFWInstance_MayCreatePthreads(
  1025. NSSCKFWInstance *fwInstance)
  1026. {
  1027. #ifdef DEBUG
  1028. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  1029. return CK_FALSE;
  1030. }
  1031. #endif /* DEBUG */
  1032. return nssCKFWInstance_MayCreatePthreads(fwInstance);
  1033. }
  1034. /*
  1035. * NSSCKFWInstance_CreateMutex
  1036. *
  1037. */
  1038. NSS_IMPLEMENT NSSCKFWMutex *
  1039. NSSCKFWInstance_CreateMutex(
  1040. NSSCKFWInstance *fwInstance,
  1041. NSSArena *arena,
  1042. CK_RV *pError)
  1043. {
  1044. #ifdef DEBUG
  1045. if (!pError) {
  1046. return (NSSCKFWMutex *)NULL;
  1047. }
  1048. *pError = nssCKFWInstance_verifyPointer(fwInstance);
  1049. if (CKR_OK != *pError) {
  1050. return (NSSCKFWMutex *)NULL;
  1051. }
  1052. #endif /* DEBUG */
  1053. return nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
  1054. }
  1055. /*
  1056. * NSSCKFWInstance_GetConfigurationData
  1057. *
  1058. */
  1059. NSS_IMPLEMENT NSSUTF8 *
  1060. NSSCKFWInstance_GetConfigurationData(
  1061. NSSCKFWInstance *fwInstance)
  1062. {
  1063. #ifdef DEBUG
  1064. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  1065. return (NSSUTF8 *)NULL;
  1066. }
  1067. #endif /* DEBUG */
  1068. return nssCKFWInstance_GetConfigurationData(fwInstance);
  1069. }
  1070. /*
  1071. * NSSCKFWInstance_GetInitArgs
  1072. *
  1073. */
  1074. NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR
  1075. NSSCKFWInstance_GetInitArgs(
  1076. NSSCKFWInstance *fwInstance)
  1077. {
  1078. #ifdef DEBUG
  1079. if (CKR_OK != nssCKFWInstance_verifyPointer(fwInstance)) {
  1080. return (CK_C_INITIALIZE_ARGS_PTR)NULL;
  1081. }
  1082. #endif /* DEBUG */
  1083. return nssCKFWInstance_GetInitArgs(fwInstance);
  1084. }
  1085. /*
  1086. * nssCKFWInstance_DestroySessionHandle
  1087. *
  1088. */
  1089. NSS_IMPLEMENT void
  1090. NSSCKFWInstance_DestroySessionHandle(
  1091. NSSCKFWInstance *fwInstance,
  1092. CK_SESSION_HANDLE hSession)
  1093. {
  1094. nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
  1095. }
  1096. /*
  1097. * nssCKFWInstance_FindSessionHandle
  1098. *
  1099. */
  1100. NSS_IMPLEMENT CK_SESSION_HANDLE
  1101. NSSCKFWInstance_FindSessionHandle(
  1102. NSSCKFWInstance *fwInstance,
  1103. NSSCKFWSession *fwSession)
  1104. {
  1105. return nssCKFWInstance_FindSessionHandle(fwInstance, fwSession);
  1106. }