token.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  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. * token.c
  6. *
  7. * This file implements the NSSCKFWToken type and methods.
  8. */
  9. #ifndef CK_T
  10. #include "ck.h"
  11. #endif /* CK_T */
  12. /*
  13. * NSSCKFWToken
  14. *
  15. * -- create/destroy --
  16. * nssCKFWToken_Create
  17. * nssCKFWToken_Destroy
  18. *
  19. * -- public accessors --
  20. * NSSCKFWToken_GetMDToken
  21. * NSSCKFWToken_GetFWSlot
  22. * NSSCKFWToken_GetMDSlot
  23. * NSSCKFWToken_GetSessionState
  24. *
  25. * -- implement public accessors --
  26. * nssCKFWToken_GetMDToken
  27. * nssCKFWToken_GetFWSlot
  28. * nssCKFWToken_GetMDSlot
  29. * nssCKFWToken_GetSessionState
  30. * nssCKFWToken_SetSessionState
  31. *
  32. * -- private accessors --
  33. * nssCKFWToken_SetSessionState
  34. * nssCKFWToken_RemoveSession
  35. * nssCKFWToken_CloseAllSessions
  36. * nssCKFWToken_GetSessionCount
  37. * nssCKFWToken_GetRwSessionCount
  38. * nssCKFWToken_GetRoSessionCount
  39. * nssCKFWToken_GetSessionObjectHash
  40. * nssCKFWToken_GetMDObjectHash
  41. * nssCKFWToken_GetObjectHandleHash
  42. *
  43. * -- module fronts --
  44. * nssCKFWToken_InitToken
  45. * nssCKFWToken_GetLabel
  46. * nssCKFWToken_GetManufacturerID
  47. * nssCKFWToken_GetModel
  48. * nssCKFWToken_GetSerialNumber
  49. * nssCKFWToken_GetHasRNG
  50. * nssCKFWToken_GetIsWriteProtected
  51. * nssCKFWToken_GetLoginRequired
  52. * nssCKFWToken_GetUserPinInitialized
  53. * nssCKFWToken_GetRestoreKeyNotNeeded
  54. * nssCKFWToken_GetHasClockOnToken
  55. * nssCKFWToken_GetHasProtectedAuthenticationPath
  56. * nssCKFWToken_GetSupportsDualCryptoOperations
  57. * nssCKFWToken_GetMaxSessionCount
  58. * nssCKFWToken_GetMaxRwSessionCount
  59. * nssCKFWToken_GetMaxPinLen
  60. * nssCKFWToken_GetMinPinLen
  61. * nssCKFWToken_GetTotalPublicMemory
  62. * nssCKFWToken_GetFreePublicMemory
  63. * nssCKFWToken_GetTotalPrivateMemory
  64. * nssCKFWToken_GetFreePrivateMemory
  65. * nssCKFWToken_GetHardwareVersion
  66. * nssCKFWToken_GetFirmwareVersion
  67. * nssCKFWToken_GetUTCTime
  68. * nssCKFWToken_OpenSession
  69. * nssCKFWToken_GetMechanismCount
  70. * nssCKFWToken_GetMechanismTypes
  71. * nssCKFWToken_GetMechanism
  72. */
  73. struct NSSCKFWTokenStr {
  74. NSSCKFWMutex *mutex;
  75. NSSArena *arena;
  76. NSSCKMDToken *mdToken;
  77. NSSCKFWSlot *fwSlot;
  78. NSSCKMDSlot *mdSlot;
  79. NSSCKFWInstance *fwInstance;
  80. NSSCKMDInstance *mdInstance;
  81. /*
  82. * Everything above is set at creation time, and then not modified.
  83. * The invariants the mutex protects are:
  84. *
  85. * 1) Each of the cached descriptions (versions, etc.) are in an
  86. * internally consistant state.
  87. *
  88. * 2) The session counts and hashes are consistant.
  89. *
  90. * 3) The object hashes are consistant.
  91. *
  92. * Note that the calls accessing the cached descriptions will call
  93. * the NSSCKMDToken methods with the mutex locked. Those methods
  94. * may then call the public NSSCKFWToken routines. Those public
  95. * routines only access the constant data above and the atomic
  96. * CK_STATE session state variable below, so there's no problem.
  97. * But be careful if you add to this object; mutexes are in
  98. * general not reentrant, so don't create deadlock situations.
  99. */
  100. NSSUTF8 *label;
  101. NSSUTF8 *manufacturerID;
  102. NSSUTF8 *model;
  103. NSSUTF8 *serialNumber;
  104. CK_VERSION hardwareVersion;
  105. CK_VERSION firmwareVersion;
  106. CK_ULONG sessionCount;
  107. CK_ULONG rwSessionCount;
  108. nssCKFWHash *sessions;
  109. nssCKFWHash *sessionObjectHash;
  110. nssCKFWHash *mdObjectHash;
  111. nssCKFWHash *mdMechanismHash;
  112. CK_STATE state;
  113. };
  114. #ifdef DEBUG
  115. /*
  116. * But first, the pointer-tracking stuff.
  117. *
  118. * NOTE: the pointer-tracking support in NSS/base currently relies
  119. * upon NSPR's CallOnce support. That, however, relies upon NSPR's
  120. * locking, which is tied into the runtime. We need a pointer-tracker
  121. * implementation that uses the locks supplied through C_Initialize.
  122. * That support, however, can be filled in later. So for now, I'll
  123. * just do this routines as no-ops.
  124. */
  125. static CK_RV
  126. token_add_pointer(
  127. const NSSCKFWToken *fwToken)
  128. {
  129. return CKR_OK;
  130. }
  131. static CK_RV
  132. token_remove_pointer(
  133. const NSSCKFWToken *fwToken)
  134. {
  135. return CKR_OK;
  136. }
  137. NSS_IMPLEMENT CK_RV
  138. nssCKFWToken_verifyPointer(
  139. const NSSCKFWToken *fwToken)
  140. {
  141. return CKR_OK;
  142. }
  143. #endif /* DEBUG */
  144. /*
  145. * nssCKFWToken_Create
  146. *
  147. */
  148. NSS_IMPLEMENT NSSCKFWToken *
  149. nssCKFWToken_Create(
  150. NSSCKFWSlot *fwSlot,
  151. NSSCKMDToken *mdToken,
  152. CK_RV *pError)
  153. {
  154. NSSArena *arena = (NSSArena *)NULL;
  155. NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
  156. CK_BBOOL called_setup = CK_FALSE;
  157. /*
  158. * We have already verified the arguments in nssCKFWSlot_GetToken.
  159. */
  160. arena = NSSArena_Create();
  161. if (!arena) {
  162. *pError = CKR_HOST_MEMORY;
  163. goto loser;
  164. }
  165. fwToken = nss_ZNEW(arena, NSSCKFWToken);
  166. if (!fwToken) {
  167. *pError = CKR_HOST_MEMORY;
  168. goto loser;
  169. }
  170. fwToken->arena = arena;
  171. fwToken->mdToken = mdToken;
  172. fwToken->fwSlot = fwSlot;
  173. fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
  174. fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
  175. fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  176. fwToken->sessionCount = 0;
  177. fwToken->rwSessionCount = 0;
  178. fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
  179. if (!fwToken->mutex) {
  180. if (CKR_OK == *pError) {
  181. *pError = CKR_GENERAL_ERROR;
  182. }
  183. goto loser;
  184. }
  185. fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
  186. if (!fwToken->sessions) {
  187. if (CKR_OK == *pError) {
  188. *pError = CKR_GENERAL_ERROR;
  189. }
  190. goto loser;
  191. }
  192. if (CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
  193. fwToken->fwInstance)) {
  194. fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
  195. arena, pError);
  196. if (!fwToken->sessionObjectHash) {
  197. if (CKR_OK == *pError) {
  198. *pError = CKR_GENERAL_ERROR;
  199. }
  200. goto loser;
  201. }
  202. }
  203. fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
  204. arena, pError);
  205. if (!fwToken->mdObjectHash) {
  206. if (CKR_OK == *pError) {
  207. *pError = CKR_GENERAL_ERROR;
  208. }
  209. goto loser;
  210. }
  211. fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance,
  212. arena, pError);
  213. if (!fwToken->mdMechanismHash) {
  214. if (CKR_OK == *pError) {
  215. *pError = CKR_GENERAL_ERROR;
  216. }
  217. goto loser;
  218. }
  219. /* More here */
  220. if (mdToken->Setup) {
  221. *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  222. if (CKR_OK != *pError) {
  223. goto loser;
  224. }
  225. }
  226. called_setup = CK_TRUE;
  227. #ifdef DEBUG
  228. *pError = token_add_pointer(fwToken);
  229. if (CKR_OK != *pError) {
  230. goto loser;
  231. }
  232. #endif /* DEBUG */
  233. *pError = CKR_OK;
  234. return fwToken;
  235. loser:
  236. if (CK_TRUE == called_setup) {
  237. if (mdToken->Invalidate) {
  238. mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  239. }
  240. }
  241. if (arena) {
  242. (void)NSSArena_Destroy(arena);
  243. }
  244. return (NSSCKFWToken *)NULL;
  245. }
  246. static void
  247. nss_ckfwtoken_session_iterator(
  248. const void *key,
  249. void *value,
  250. void *closure)
  251. {
  252. /*
  253. * Remember that the fwToken->mutex is locked
  254. */
  255. NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
  256. (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  257. return;
  258. }
  259. static void
  260. nss_ckfwtoken_object_iterator(
  261. const void *key,
  262. void *value,
  263. void *closure)
  264. {
  265. /*
  266. * Remember that the fwToken->mutex is locked
  267. */
  268. NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
  269. (void)nssCKFWObject_Finalize(fwObject, CK_FALSE);
  270. return;
  271. }
  272. /*
  273. * nssCKFWToken_Destroy
  274. *
  275. */
  276. NSS_IMPLEMENT CK_RV
  277. nssCKFWToken_Destroy(
  278. NSSCKFWToken *fwToken)
  279. {
  280. CK_RV error = CKR_OK;
  281. #ifdef NSSDEBUG
  282. error = nssCKFWToken_verifyPointer(fwToken);
  283. if (CKR_OK != error) {
  284. return error;
  285. }
  286. #endif /* NSSDEBUG */
  287. (void)nssCKFWMutex_Destroy(fwToken->mutex);
  288. if (fwToken->mdToken->Invalidate) {
  289. fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
  290. fwToken->mdInstance, fwToken->fwInstance);
  291. }
  292. /* we can destroy the list without locking now because no one else is
  293. * referencing us (or _Destroy was invalidly called!)
  294. */
  295. nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator,
  296. (void *)NULL);
  297. nssCKFWHash_Destroy(fwToken->sessions);
  298. /* session objects go away when their sessions are removed */
  299. if (fwToken->sessionObjectHash) {
  300. nssCKFWHash_Destroy(fwToken->sessionObjectHash);
  301. }
  302. /* free up the token objects */
  303. if (fwToken->mdObjectHash) {
  304. nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator,
  305. (void *)NULL);
  306. nssCKFWHash_Destroy(fwToken->mdObjectHash);
  307. }
  308. if (fwToken->mdMechanismHash) {
  309. nssCKFWHash_Destroy(fwToken->mdMechanismHash);
  310. }
  311. nssCKFWSlot_ClearToken(fwToken->fwSlot);
  312. #ifdef DEBUG
  313. error = token_remove_pointer(fwToken);
  314. #endif /* DEBUG */
  315. (void)NSSArena_Destroy(fwToken->arena);
  316. return error;
  317. }
  318. /*
  319. * nssCKFWToken_GetMDToken
  320. *
  321. */
  322. NSS_IMPLEMENT NSSCKMDToken *
  323. nssCKFWToken_GetMDToken(
  324. NSSCKFWToken *fwToken)
  325. {
  326. #ifdef NSSDEBUG
  327. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  328. return (NSSCKMDToken *)NULL;
  329. }
  330. #endif /* NSSDEBUG */
  331. return fwToken->mdToken;
  332. }
  333. /*
  334. * nssCKFWToken_GetArena
  335. *
  336. */
  337. NSS_IMPLEMENT NSSArena *
  338. nssCKFWToken_GetArena(
  339. NSSCKFWToken *fwToken,
  340. CK_RV *pError)
  341. {
  342. #ifdef NSSDEBUG
  343. if (!pError) {
  344. return (NSSArena *)NULL;
  345. }
  346. *pError = nssCKFWToken_verifyPointer(fwToken);
  347. if (CKR_OK != *pError) {
  348. return (NSSArena *)NULL;
  349. }
  350. #endif /* NSSDEBUG */
  351. return fwToken->arena;
  352. }
  353. /*
  354. * nssCKFWToken_GetFWSlot
  355. *
  356. */
  357. NSS_IMPLEMENT NSSCKFWSlot *
  358. nssCKFWToken_GetFWSlot(
  359. NSSCKFWToken *fwToken)
  360. {
  361. #ifdef NSSDEBUG
  362. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  363. return (NSSCKFWSlot *)NULL;
  364. }
  365. #endif /* NSSDEBUG */
  366. return fwToken->fwSlot;
  367. }
  368. /*
  369. * nssCKFWToken_GetMDSlot
  370. *
  371. */
  372. NSS_IMPLEMENT NSSCKMDSlot *
  373. nssCKFWToken_GetMDSlot(
  374. NSSCKFWToken *fwToken)
  375. {
  376. #ifdef NSSDEBUG
  377. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  378. return (NSSCKMDSlot *)NULL;
  379. }
  380. #endif /* NSSDEBUG */
  381. return fwToken->mdSlot;
  382. }
  383. /*
  384. * nssCKFWToken_GetSessionState
  385. *
  386. */
  387. NSS_IMPLEMENT CK_STATE
  388. nssCKFWToken_GetSessionState(
  389. NSSCKFWToken *fwToken)
  390. {
  391. #ifdef NSSDEBUG
  392. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  393. return CKS_RO_PUBLIC_SESSION; /* whatever */
  394. }
  395. #endif /* NSSDEBUG */
  396. /*
  397. * BTW, do not lock the token in this method.
  398. */
  399. /*
  400. * Theoretically, there is no state if there aren't any
  401. * sessions open. But then we'd need to worry about
  402. * reporting an error, etc. What the heck-- let's just
  403. * revert to CKR_RO_PUBLIC_SESSION as the "default."
  404. */
  405. return fwToken->state;
  406. }
  407. /*
  408. * nssCKFWToken_InitToken
  409. *
  410. */
  411. NSS_IMPLEMENT CK_RV
  412. nssCKFWToken_InitToken(
  413. NSSCKFWToken *fwToken,
  414. NSSItem *pin,
  415. NSSUTF8 *label)
  416. {
  417. CK_RV error;
  418. #ifdef NSSDEBUG
  419. error = nssCKFWToken_verifyPointer(fwToken);
  420. if (CKR_OK != error) {
  421. return CKR_ARGUMENTS_BAD;
  422. }
  423. #endif /* NSSDEBUG */
  424. error = nssCKFWMutex_Lock(fwToken->mutex);
  425. if (CKR_OK != error) {
  426. return error;
  427. }
  428. if (fwToken->sessionCount > 0) {
  429. error = CKR_SESSION_EXISTS;
  430. goto done;
  431. }
  432. if (!fwToken->mdToken->InitToken) {
  433. error = CKR_DEVICE_ERROR;
  434. goto done;
  435. }
  436. if (!pin) {
  437. if (nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken)) {
  438. ; /* okay */
  439. } else {
  440. error = CKR_PIN_INCORRECT;
  441. goto done;
  442. }
  443. }
  444. if (!label) {
  445. label = (NSSUTF8 *)"";
  446. }
  447. error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
  448. fwToken->mdInstance, fwToken->fwInstance, pin, label);
  449. done:
  450. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  451. return error;
  452. }
  453. /*
  454. * nssCKFWToken_GetLabel
  455. *
  456. */
  457. NSS_IMPLEMENT CK_RV
  458. nssCKFWToken_GetLabel(
  459. NSSCKFWToken *fwToken,
  460. CK_CHAR label[32])
  461. {
  462. CK_RV error = CKR_OK;
  463. #ifdef NSSDEBUG
  464. if ((CK_CHAR_PTR)NULL == label) {
  465. return CKR_ARGUMENTS_BAD;
  466. }
  467. error = nssCKFWToken_verifyPointer(fwToken);
  468. if (CKR_OK != error) {
  469. return error;
  470. }
  471. #endif /* NSSDEBUG */
  472. error = nssCKFWMutex_Lock(fwToken->mutex);
  473. if (CKR_OK != error) {
  474. return error;
  475. }
  476. if (!fwToken->label) {
  477. if (fwToken->mdToken->GetLabel) {
  478. fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
  479. fwToken->mdInstance, fwToken->fwInstance, &error);
  480. if ((!fwToken->label) && (CKR_OK != error)) {
  481. goto done;
  482. }
  483. } else {
  484. fwToken->label = (NSSUTF8 *)"";
  485. }
  486. }
  487. (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
  488. error = CKR_OK;
  489. done:
  490. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  491. return error;
  492. }
  493. /*
  494. * nssCKFWToken_GetManufacturerID
  495. *
  496. */
  497. NSS_IMPLEMENT CK_RV
  498. nssCKFWToken_GetManufacturerID(
  499. NSSCKFWToken *fwToken,
  500. CK_CHAR manufacturerID[32])
  501. {
  502. CK_RV error = CKR_OK;
  503. #ifdef NSSDEBUG
  504. if ((CK_CHAR_PTR)NULL == manufacturerID) {
  505. return CKR_ARGUMENTS_BAD;
  506. }
  507. error = nssCKFWToken_verifyPointer(fwToken);
  508. if (CKR_OK != error) {
  509. return error;
  510. }
  511. #endif /* NSSDEBUG */
  512. error = nssCKFWMutex_Lock(fwToken->mutex);
  513. if (CKR_OK != error) {
  514. return error;
  515. }
  516. if (!fwToken->manufacturerID) {
  517. if (fwToken->mdToken->GetManufacturerID) {
  518. fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
  519. fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
  520. if ((!fwToken->manufacturerID) && (CKR_OK != error)) {
  521. goto done;
  522. }
  523. } else {
  524. fwToken->manufacturerID = (NSSUTF8 *)"";
  525. }
  526. }
  527. (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
  528. error = CKR_OK;
  529. done:
  530. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  531. return error;
  532. }
  533. /*
  534. * nssCKFWToken_GetModel
  535. *
  536. */
  537. NSS_IMPLEMENT CK_RV
  538. nssCKFWToken_GetModel(
  539. NSSCKFWToken *fwToken,
  540. CK_CHAR model[16])
  541. {
  542. CK_RV error = CKR_OK;
  543. #ifdef NSSDEBUG
  544. if ((CK_CHAR_PTR)NULL == model) {
  545. return CKR_ARGUMENTS_BAD;
  546. }
  547. error = nssCKFWToken_verifyPointer(fwToken);
  548. if (CKR_OK != error) {
  549. return error;
  550. }
  551. #endif /* NSSDEBUG */
  552. error = nssCKFWMutex_Lock(fwToken->mutex);
  553. if (CKR_OK != error) {
  554. return error;
  555. }
  556. if (!fwToken->model) {
  557. if (fwToken->mdToken->GetModel) {
  558. fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
  559. fwToken->mdInstance, fwToken->fwInstance, &error);
  560. if ((!fwToken->model) && (CKR_OK != error)) {
  561. goto done;
  562. }
  563. } else {
  564. fwToken->model = (NSSUTF8 *)"";
  565. }
  566. }
  567. (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
  568. error = CKR_OK;
  569. done:
  570. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  571. return error;
  572. }
  573. /*
  574. * nssCKFWToken_GetSerialNumber
  575. *
  576. */
  577. NSS_IMPLEMENT CK_RV
  578. nssCKFWToken_GetSerialNumber(
  579. NSSCKFWToken *fwToken,
  580. CK_CHAR serialNumber[16])
  581. {
  582. CK_RV error = CKR_OK;
  583. #ifdef NSSDEBUG
  584. if ((CK_CHAR_PTR)NULL == serialNumber) {
  585. return CKR_ARGUMENTS_BAD;
  586. }
  587. error = nssCKFWToken_verifyPointer(fwToken);
  588. if (CKR_OK != error) {
  589. return error;
  590. }
  591. #endif /* NSSDEBUG */
  592. error = nssCKFWMutex_Lock(fwToken->mutex);
  593. if (CKR_OK != error) {
  594. return error;
  595. }
  596. if (!fwToken->serialNumber) {
  597. if (fwToken->mdToken->GetSerialNumber) {
  598. fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken,
  599. fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
  600. if ((!fwToken->serialNumber) && (CKR_OK != error)) {
  601. goto done;
  602. }
  603. } else {
  604. fwToken->serialNumber = (NSSUTF8 *)"";
  605. }
  606. }
  607. (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
  608. error = CKR_OK;
  609. done:
  610. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  611. return error;
  612. }
  613. /*
  614. * nssCKFWToken_GetHasRNG
  615. *
  616. */
  617. NSS_IMPLEMENT CK_BBOOL
  618. nssCKFWToken_GetHasRNG(
  619. NSSCKFWToken *fwToken)
  620. {
  621. #ifdef NSSDEBUG
  622. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  623. return CK_FALSE;
  624. }
  625. #endif /* NSSDEBUG */
  626. if (!fwToken->mdToken->GetHasRNG) {
  627. return CK_FALSE;
  628. }
  629. return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken,
  630. fwToken->mdInstance, fwToken->fwInstance);
  631. }
  632. /*
  633. * nssCKFWToken_GetIsWriteProtected
  634. *
  635. */
  636. NSS_IMPLEMENT CK_BBOOL
  637. nssCKFWToken_GetIsWriteProtected(
  638. NSSCKFWToken *fwToken)
  639. {
  640. #ifdef NSSDEBUG
  641. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  642. return CK_FALSE;
  643. }
  644. #endif /* NSSDEBUG */
  645. if (!fwToken->mdToken->GetIsWriteProtected) {
  646. return CK_FALSE;
  647. }
  648. return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken,
  649. fwToken->mdInstance, fwToken->fwInstance);
  650. }
  651. /*
  652. * nssCKFWToken_GetLoginRequired
  653. *
  654. */
  655. NSS_IMPLEMENT CK_BBOOL
  656. nssCKFWToken_GetLoginRequired(
  657. NSSCKFWToken *fwToken)
  658. {
  659. #ifdef NSSDEBUG
  660. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  661. return CK_FALSE;
  662. }
  663. #endif /* NSSDEBUG */
  664. if (!fwToken->mdToken->GetLoginRequired) {
  665. return CK_FALSE;
  666. }
  667. return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken,
  668. fwToken->mdInstance, fwToken->fwInstance);
  669. }
  670. /*
  671. * nssCKFWToken_GetUserPinInitialized
  672. *
  673. */
  674. NSS_IMPLEMENT CK_BBOOL
  675. nssCKFWToken_GetUserPinInitialized(
  676. NSSCKFWToken *fwToken)
  677. {
  678. #ifdef NSSDEBUG
  679. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  680. return CK_FALSE;
  681. }
  682. #endif /* NSSDEBUG */
  683. if (!fwToken->mdToken->GetUserPinInitialized) {
  684. return CK_FALSE;
  685. }
  686. return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken,
  687. fwToken->mdInstance, fwToken->fwInstance);
  688. }
  689. /*
  690. * nssCKFWToken_GetRestoreKeyNotNeeded
  691. *
  692. */
  693. NSS_IMPLEMENT CK_BBOOL
  694. nssCKFWToken_GetRestoreKeyNotNeeded(
  695. NSSCKFWToken *fwToken)
  696. {
  697. #ifdef NSSDEBUG
  698. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  699. return CK_FALSE;
  700. }
  701. #endif /* NSSDEBUG */
  702. if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
  703. return CK_FALSE;
  704. }
  705. return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken,
  706. fwToken->mdInstance, fwToken->fwInstance);
  707. }
  708. /*
  709. * nssCKFWToken_GetHasClockOnToken
  710. *
  711. */
  712. NSS_IMPLEMENT CK_BBOOL
  713. nssCKFWToken_GetHasClockOnToken(
  714. NSSCKFWToken *fwToken)
  715. {
  716. #ifdef NSSDEBUG
  717. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  718. return CK_FALSE;
  719. }
  720. #endif /* NSSDEBUG */
  721. if (!fwToken->mdToken->GetHasClockOnToken) {
  722. return CK_FALSE;
  723. }
  724. return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken,
  725. fwToken->mdInstance, fwToken->fwInstance);
  726. }
  727. /*
  728. * nssCKFWToken_GetHasProtectedAuthenticationPath
  729. *
  730. */
  731. NSS_IMPLEMENT CK_BBOOL
  732. nssCKFWToken_GetHasProtectedAuthenticationPath(
  733. NSSCKFWToken *fwToken)
  734. {
  735. #ifdef NSSDEBUG
  736. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  737. return CK_FALSE;
  738. }
  739. #endif /* NSSDEBUG */
  740. if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
  741. return CK_FALSE;
  742. }
  743. return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken,
  744. fwToken, fwToken->mdInstance, fwToken->fwInstance);
  745. }
  746. /*
  747. * nssCKFWToken_GetSupportsDualCryptoOperations
  748. *
  749. */
  750. NSS_IMPLEMENT CK_BBOOL
  751. nssCKFWToken_GetSupportsDualCryptoOperations(
  752. NSSCKFWToken *fwToken)
  753. {
  754. #ifdef NSSDEBUG
  755. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  756. return CK_FALSE;
  757. }
  758. #endif /* NSSDEBUG */
  759. if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
  760. return CK_FALSE;
  761. }
  762. return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken,
  763. fwToken, fwToken->mdInstance, fwToken->fwInstance);
  764. }
  765. /*
  766. * nssCKFWToken_GetMaxSessionCount
  767. *
  768. */
  769. NSS_IMPLEMENT CK_ULONG
  770. nssCKFWToken_GetMaxSessionCount(
  771. NSSCKFWToken *fwToken)
  772. {
  773. #ifdef NSSDEBUG
  774. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  775. return CK_UNAVAILABLE_INFORMATION;
  776. }
  777. #endif /* NSSDEBUG */
  778. if (!fwToken->mdToken->GetMaxSessionCount) {
  779. return CK_UNAVAILABLE_INFORMATION;
  780. }
  781. return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken,
  782. fwToken->mdInstance, fwToken->fwInstance);
  783. }
  784. /*
  785. * nssCKFWToken_GetMaxRwSessionCount
  786. *
  787. */
  788. NSS_IMPLEMENT CK_ULONG
  789. nssCKFWToken_GetMaxRwSessionCount(
  790. NSSCKFWToken *fwToken)
  791. {
  792. #ifdef NSSDEBUG
  793. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  794. return CK_UNAVAILABLE_INFORMATION;
  795. }
  796. #endif /* NSSDEBUG */
  797. if (!fwToken->mdToken->GetMaxRwSessionCount) {
  798. return CK_UNAVAILABLE_INFORMATION;
  799. }
  800. return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken,
  801. fwToken->mdInstance, fwToken->fwInstance);
  802. }
  803. /*
  804. * nssCKFWToken_GetMaxPinLen
  805. *
  806. */
  807. NSS_IMPLEMENT CK_ULONG
  808. nssCKFWToken_GetMaxPinLen(
  809. NSSCKFWToken *fwToken)
  810. {
  811. #ifdef NSSDEBUG
  812. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  813. return CK_UNAVAILABLE_INFORMATION;
  814. }
  815. #endif /* NSSDEBUG */
  816. if (!fwToken->mdToken->GetMaxPinLen) {
  817. return CK_UNAVAILABLE_INFORMATION;
  818. }
  819. return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken,
  820. fwToken->mdInstance, fwToken->fwInstance);
  821. }
  822. /*
  823. * nssCKFWToken_GetMinPinLen
  824. *
  825. */
  826. NSS_IMPLEMENT CK_ULONG
  827. nssCKFWToken_GetMinPinLen(
  828. NSSCKFWToken *fwToken)
  829. {
  830. #ifdef NSSDEBUG
  831. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  832. return CK_UNAVAILABLE_INFORMATION;
  833. }
  834. #endif /* NSSDEBUG */
  835. if (!fwToken->mdToken->GetMinPinLen) {
  836. return CK_UNAVAILABLE_INFORMATION;
  837. }
  838. return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken,
  839. fwToken->mdInstance, fwToken->fwInstance);
  840. }
  841. /*
  842. * nssCKFWToken_GetTotalPublicMemory
  843. *
  844. */
  845. NSS_IMPLEMENT CK_ULONG
  846. nssCKFWToken_GetTotalPublicMemory(
  847. NSSCKFWToken *fwToken)
  848. {
  849. #ifdef NSSDEBUG
  850. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  851. return CK_UNAVAILABLE_INFORMATION;
  852. }
  853. #endif /* NSSDEBUG */
  854. if (!fwToken->mdToken->GetTotalPublicMemory) {
  855. return CK_UNAVAILABLE_INFORMATION;
  856. }
  857. return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken,
  858. fwToken->mdInstance, fwToken->fwInstance);
  859. }
  860. /*
  861. * nssCKFWToken_GetFreePublicMemory
  862. *
  863. */
  864. NSS_IMPLEMENT CK_ULONG
  865. nssCKFWToken_GetFreePublicMemory(
  866. NSSCKFWToken *fwToken)
  867. {
  868. #ifdef NSSDEBUG
  869. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  870. return CK_UNAVAILABLE_INFORMATION;
  871. }
  872. #endif /* NSSDEBUG */
  873. if (!fwToken->mdToken->GetFreePublicMemory) {
  874. return CK_UNAVAILABLE_INFORMATION;
  875. }
  876. return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken,
  877. fwToken->mdInstance, fwToken->fwInstance);
  878. }
  879. /*
  880. * nssCKFWToken_GetTotalPrivateMemory
  881. *
  882. */
  883. NSS_IMPLEMENT CK_ULONG
  884. nssCKFWToken_GetTotalPrivateMemory(
  885. NSSCKFWToken *fwToken)
  886. {
  887. #ifdef NSSDEBUG
  888. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  889. return CK_UNAVAILABLE_INFORMATION;
  890. }
  891. #endif /* NSSDEBUG */
  892. if (!fwToken->mdToken->GetTotalPrivateMemory) {
  893. return CK_UNAVAILABLE_INFORMATION;
  894. }
  895. return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken,
  896. fwToken->mdInstance, fwToken->fwInstance);
  897. }
  898. /*
  899. * nssCKFWToken_GetFreePrivateMemory
  900. *
  901. */
  902. NSS_IMPLEMENT CK_ULONG
  903. nssCKFWToken_GetFreePrivateMemory(
  904. NSSCKFWToken *fwToken)
  905. {
  906. #ifdef NSSDEBUG
  907. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  908. return CK_UNAVAILABLE_INFORMATION;
  909. }
  910. #endif /* NSSDEBUG */
  911. if (!fwToken->mdToken->GetFreePrivateMemory) {
  912. return CK_UNAVAILABLE_INFORMATION;
  913. }
  914. return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken,
  915. fwToken->mdInstance, fwToken->fwInstance);
  916. }
  917. /*
  918. * nssCKFWToken_GetHardwareVersion
  919. *
  920. */
  921. NSS_IMPLEMENT CK_VERSION
  922. nssCKFWToken_GetHardwareVersion(
  923. NSSCKFWToken *fwToken)
  924. {
  925. CK_VERSION rv;
  926. #ifdef NSSDEBUG
  927. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  928. rv.major = rv.minor = 0;
  929. return rv;
  930. }
  931. #endif /* NSSDEBUG */
  932. if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
  933. rv.major = rv.minor = 0;
  934. return rv;
  935. }
  936. if ((0 != fwToken->hardwareVersion.major) ||
  937. (0 != fwToken->hardwareVersion.minor)) {
  938. rv = fwToken->hardwareVersion;
  939. goto done;
  940. }
  941. if (fwToken->mdToken->GetHardwareVersion) {
  942. fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
  943. fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  944. } else {
  945. fwToken->hardwareVersion.major = 0;
  946. fwToken->hardwareVersion.minor = 1;
  947. }
  948. rv = fwToken->hardwareVersion;
  949. done:
  950. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  951. return rv;
  952. }
  953. /*
  954. * nssCKFWToken_GetFirmwareVersion
  955. *
  956. */
  957. NSS_IMPLEMENT CK_VERSION
  958. nssCKFWToken_GetFirmwareVersion(
  959. NSSCKFWToken *fwToken)
  960. {
  961. CK_VERSION rv;
  962. #ifdef NSSDEBUG
  963. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  964. rv.major = rv.minor = 0;
  965. return rv;
  966. }
  967. #endif /* NSSDEBUG */
  968. if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
  969. rv.major = rv.minor = 0;
  970. return rv;
  971. }
  972. if ((0 != fwToken->firmwareVersion.major) ||
  973. (0 != fwToken->firmwareVersion.minor)) {
  974. rv = fwToken->firmwareVersion;
  975. goto done;
  976. }
  977. if (fwToken->mdToken->GetFirmwareVersion) {
  978. fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
  979. fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  980. } else {
  981. fwToken->firmwareVersion.major = 0;
  982. fwToken->firmwareVersion.minor = 1;
  983. }
  984. rv = fwToken->firmwareVersion;
  985. done:
  986. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  987. return rv;
  988. }
  989. /*
  990. * nssCKFWToken_GetUTCTime
  991. *
  992. */
  993. NSS_IMPLEMENT CK_RV
  994. nssCKFWToken_GetUTCTime(
  995. NSSCKFWToken *fwToken,
  996. CK_CHAR utcTime[16])
  997. {
  998. CK_RV error = CKR_OK;
  999. #ifdef NSSDEBUG
  1000. error = nssCKFWToken_verifyPointer(fwToken);
  1001. if (CKR_OK != error) {
  1002. return error;
  1003. }
  1004. if ((CK_CHAR_PTR)NULL == utcTime) {
  1005. return CKR_ARGUMENTS_BAD;
  1006. }
  1007. #endif /* DEBUG */
  1008. if (CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken)) {
  1009. /* return CKR_DEVICE_ERROR; */
  1010. (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
  1011. return CKR_OK;
  1012. }
  1013. if (!fwToken->mdToken->GetUTCTime) {
  1014. /* It said it had one! */
  1015. return CKR_GENERAL_ERROR;
  1016. }
  1017. error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken,
  1018. fwToken->mdInstance, fwToken->fwInstance, utcTime);
  1019. if (CKR_OK != error) {
  1020. return error;
  1021. }
  1022. /* Sanity-check the data */
  1023. {
  1024. /* Format is YYYYMMDDhhmmss00 */
  1025. int i;
  1026. int Y, M, D, h, m, s;
  1027. static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1028. for (i = 0; i < 16; i++) {
  1029. if ((utcTime[i] < '0') || (utcTime[i] > '9')) {
  1030. goto badtime;
  1031. }
  1032. }
  1033. Y = ((utcTime[0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
  1034. ((utcTime[2] - '0') * 10) + (utcTime[3] - '0');
  1035. M = ((utcTime[4] - '0') * 10) + (utcTime[5] - '0');
  1036. D = ((utcTime[6] - '0') * 10) + (utcTime[7] - '0');
  1037. h = ((utcTime[8] - '0') * 10) + (utcTime[9] - '0');
  1038. m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
  1039. s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
  1040. if ((Y < 1990) || (Y > 3000))
  1041. goto badtime; /* Y3K problem. heh heh heh */
  1042. if ((M < 1) || (M > 12))
  1043. goto badtime;
  1044. if ((D < 1) || (D > 31))
  1045. goto badtime;
  1046. if (D > dims[M - 1])
  1047. goto badtime; /* per-month check */
  1048. if ((2 == M) && (((Y % 4) || !(Y % 100)) &&
  1049. (Y % 400)) &&
  1050. (D > 28))
  1051. goto badtime; /* leap years */
  1052. if ((h < 0) || (h > 23))
  1053. goto badtime;
  1054. if ((m < 0) || (m > 60))
  1055. goto badtime;
  1056. if ((s < 0) || (s > 61))
  1057. goto badtime;
  1058. /* 60m and 60 or 61s is only allowed for leap seconds. */
  1059. if ((60 == m) || (s >= 60)) {
  1060. if ((23 != h) || (60 != m) || (s < 60))
  1061. goto badtime;
  1062. /* leap seconds can only happen on June 30 or Dec 31.. I think */
  1063. /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
  1064. }
  1065. }
  1066. return CKR_OK;
  1067. badtime:
  1068. return CKR_GENERAL_ERROR;
  1069. }
  1070. /*
  1071. * nssCKFWToken_OpenSession
  1072. *
  1073. */
  1074. NSS_IMPLEMENT NSSCKFWSession *
  1075. nssCKFWToken_OpenSession(
  1076. NSSCKFWToken *fwToken,
  1077. CK_BBOOL rw,
  1078. CK_VOID_PTR pApplication,
  1079. CK_NOTIFY Notify,
  1080. CK_RV *pError)
  1081. {
  1082. NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
  1083. NSSCKMDSession *mdSession;
  1084. #ifdef NSSDEBUG
  1085. if (!pError) {
  1086. return (NSSCKFWSession *)NULL;
  1087. }
  1088. *pError = nssCKFWToken_verifyPointer(fwToken);
  1089. if (CKR_OK != *pError) {
  1090. return (NSSCKFWSession *)NULL;
  1091. }
  1092. switch (rw) {
  1093. case CK_TRUE:
  1094. case CK_FALSE:
  1095. break;
  1096. default:
  1097. *pError = CKR_ARGUMENTS_BAD;
  1098. return (NSSCKFWSession *)NULL;
  1099. }
  1100. #endif /* NSSDEBUG */
  1101. *pError = nssCKFWMutex_Lock(fwToken->mutex);
  1102. if (CKR_OK != *pError) {
  1103. return (NSSCKFWSession *)NULL;
  1104. }
  1105. if (CK_TRUE == rw) {
  1106. /* Read-write session desired */
  1107. if (CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken)) {
  1108. *pError = CKR_TOKEN_WRITE_PROTECTED;
  1109. goto done;
  1110. }
  1111. } else {
  1112. /* Read-only session desired */
  1113. if (CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken)) {
  1114. *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
  1115. goto done;
  1116. }
  1117. }
  1118. /* We could compare sesion counts to any limits we know of, I guess.. */
  1119. if (!fwToken->mdToken->OpenSession) {
  1120. /*
  1121. * I'm not sure that the Module actually needs to implement
  1122. * mdSessions -- the Framework can keep track of everything
  1123. * needed, really. But I'll sort out that detail later..
  1124. */
  1125. *pError = CKR_GENERAL_ERROR;
  1126. goto done;
  1127. }
  1128. fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
  1129. if (!fwSession) {
  1130. if (CKR_OK == *pError) {
  1131. *pError = CKR_GENERAL_ERROR;
  1132. }
  1133. goto done;
  1134. }
  1135. mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
  1136. fwToken->mdInstance, fwToken->fwInstance, fwSession,
  1137. rw, pError);
  1138. if (!mdSession) {
  1139. (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1140. if (CKR_OK == *pError) {
  1141. *pError = CKR_GENERAL_ERROR;
  1142. }
  1143. goto done;
  1144. }
  1145. *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);
  1146. if (CKR_OK != *pError) {
  1147. if (mdSession->Close) {
  1148. mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
  1149. fwToken->mdInstance, fwToken->fwInstance);
  1150. }
  1151. (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1152. goto done;
  1153. }
  1154. *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
  1155. if (CKR_OK != *pError) {
  1156. (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1157. fwSession = (NSSCKFWSession *)NULL;
  1158. goto done;
  1159. }
  1160. done:
  1161. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1162. return fwSession;
  1163. }
  1164. /*
  1165. * nssCKFWToken_GetMechanismCount
  1166. *
  1167. */
  1168. NSS_IMPLEMENT CK_ULONG
  1169. nssCKFWToken_GetMechanismCount(
  1170. NSSCKFWToken *fwToken)
  1171. {
  1172. #ifdef NSSDEBUG
  1173. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1174. return 0;
  1175. }
  1176. #endif /* NSSDEBUG */
  1177. if (!fwToken->mdToken->GetMechanismCount) {
  1178. return 0;
  1179. }
  1180. return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
  1181. fwToken->mdInstance, fwToken->fwInstance);
  1182. }
  1183. /*
  1184. * nssCKFWToken_GetMechanismTypes
  1185. *
  1186. */
  1187. NSS_IMPLEMENT CK_RV
  1188. nssCKFWToken_GetMechanismTypes(
  1189. NSSCKFWToken *fwToken,
  1190. CK_MECHANISM_TYPE types[])
  1191. {
  1192. #ifdef NSSDEBUG
  1193. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1194. return CKR_ARGUMENTS_BAD;
  1195. }
  1196. if (!types) {
  1197. return CKR_ARGUMENTS_BAD;
  1198. }
  1199. #endif /* NSSDEBUG */
  1200. if (!fwToken->mdToken->GetMechanismTypes) {
  1201. /*
  1202. * This should only be called with a sufficiently-large
  1203. * "types" array, which can only be done if GetMechanismCount
  1204. * is implemented. If that's implemented (and returns nonzero),
  1205. * then this should be too. So return an error.
  1206. */
  1207. return CKR_GENERAL_ERROR;
  1208. }
  1209. return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
  1210. fwToken->mdInstance, fwToken->fwInstance, types);
  1211. }
  1212. /*
  1213. * nssCKFWToken_GetMechanism
  1214. *
  1215. */
  1216. NSS_IMPLEMENT NSSCKFWMechanism *
  1217. nssCKFWToken_GetMechanism(
  1218. NSSCKFWToken *fwToken,
  1219. CK_MECHANISM_TYPE which,
  1220. CK_RV *pError)
  1221. {
  1222. NSSCKMDMechanism *mdMechanism;
  1223. if (!fwToken->mdMechanismHash) {
  1224. *pError = CKR_GENERAL_ERROR;
  1225. return (NSSCKFWMechanism *)NULL;
  1226. }
  1227. if (!fwToken->mdToken->GetMechanism) {
  1228. /*
  1229. * If we don't implement any GetMechanism function, then we must
  1230. * not support any.
  1231. */
  1232. *pError = CKR_MECHANISM_INVALID;
  1233. return (NSSCKFWMechanism *)NULL;
  1234. }
  1235. /* lookup in hash table */
  1236. mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken,
  1237. fwToken->mdInstance, fwToken->fwInstance, which, pError);
  1238. if (!mdMechanism) {
  1239. return (NSSCKFWMechanism *)NULL;
  1240. }
  1241. /* store in hash table */
  1242. return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken,
  1243. fwToken->mdInstance, fwToken->fwInstance);
  1244. }
  1245. NSS_IMPLEMENT CK_RV
  1246. nssCKFWToken_SetSessionState(
  1247. NSSCKFWToken *fwToken,
  1248. CK_STATE newState)
  1249. {
  1250. CK_RV error = CKR_OK;
  1251. #ifdef NSSDEBUG
  1252. error = nssCKFWToken_verifyPointer(fwToken);
  1253. if (CKR_OK != error) {
  1254. return error;
  1255. }
  1256. switch (newState) {
  1257. case CKS_RO_PUBLIC_SESSION:
  1258. case CKS_RO_USER_FUNCTIONS:
  1259. case CKS_RW_PUBLIC_SESSION:
  1260. case CKS_RW_USER_FUNCTIONS:
  1261. case CKS_RW_SO_FUNCTIONS:
  1262. break;
  1263. default:
  1264. return CKR_ARGUMENTS_BAD;
  1265. }
  1266. #endif /* NSSDEBUG */
  1267. error = nssCKFWMutex_Lock(fwToken->mutex);
  1268. if (CKR_OK != error) {
  1269. return error;
  1270. }
  1271. fwToken->state = newState;
  1272. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1273. return CKR_OK;
  1274. }
  1275. /*
  1276. * nssCKFWToken_RemoveSession
  1277. *
  1278. */
  1279. NSS_IMPLEMENT CK_RV
  1280. nssCKFWToken_RemoveSession(
  1281. NSSCKFWToken *fwToken,
  1282. NSSCKFWSession *fwSession)
  1283. {
  1284. CK_RV error = CKR_OK;
  1285. #ifdef NSSDEBUG
  1286. error = nssCKFWToken_verifyPointer(fwToken);
  1287. if (CKR_OK != error) {
  1288. return error;
  1289. }
  1290. error = nssCKFWSession_verifyPointer(fwSession);
  1291. if (CKR_OK != error) {
  1292. return error;
  1293. }
  1294. #endif /* NSSDEBUG */
  1295. error = nssCKFWMutex_Lock(fwToken->mutex);
  1296. if (CKR_OK != error) {
  1297. return error;
  1298. }
  1299. if (CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession)) {
  1300. error = CKR_SESSION_HANDLE_INVALID;
  1301. goto done;
  1302. }
  1303. nssCKFWHash_Remove(fwToken->sessions, fwSession);
  1304. fwToken->sessionCount--;
  1305. if (nssCKFWSession_IsRWSession(fwSession)) {
  1306. fwToken->rwSessionCount--;
  1307. }
  1308. if (0 == fwToken->sessionCount) {
  1309. fwToken->rwSessionCount = 0; /* sanity */
  1310. fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1311. }
  1312. error = CKR_OK;
  1313. done:
  1314. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1315. return error;
  1316. }
  1317. /*
  1318. * nssCKFWToken_CloseAllSessions
  1319. *
  1320. */
  1321. NSS_IMPLEMENT CK_RV
  1322. nssCKFWToken_CloseAllSessions(
  1323. NSSCKFWToken *fwToken)
  1324. {
  1325. CK_RV error = CKR_OK;
  1326. #ifdef NSSDEBUG
  1327. error = nssCKFWToken_verifyPointer(fwToken);
  1328. if (CKR_OK != error) {
  1329. return error;
  1330. }
  1331. #endif /* NSSDEBUG */
  1332. error = nssCKFWMutex_Lock(fwToken->mutex);
  1333. if (CKR_OK != error) {
  1334. return error;
  1335. }
  1336. nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
  1337. nssCKFWHash_Destroy(fwToken->sessions);
  1338. fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
  1339. if (!fwToken->sessions) {
  1340. if (CKR_OK == error) {
  1341. error = CKR_GENERAL_ERROR;
  1342. }
  1343. goto done;
  1344. }
  1345. fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1346. fwToken->sessionCount = 0;
  1347. fwToken->rwSessionCount = 0;
  1348. error = CKR_OK;
  1349. done:
  1350. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1351. return error;
  1352. }
  1353. /*
  1354. * nssCKFWToken_GetSessionCount
  1355. *
  1356. */
  1357. NSS_IMPLEMENT CK_ULONG
  1358. nssCKFWToken_GetSessionCount(
  1359. NSSCKFWToken *fwToken)
  1360. {
  1361. CK_ULONG rv;
  1362. #ifdef NSSDEBUG
  1363. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1364. return (CK_ULONG)0;
  1365. }
  1366. #endif /* NSSDEBUG */
  1367. if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
  1368. return (CK_ULONG)0;
  1369. }
  1370. rv = fwToken->sessionCount;
  1371. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1372. return rv;
  1373. }
  1374. /*
  1375. * nssCKFWToken_GetRwSessionCount
  1376. *
  1377. */
  1378. NSS_IMPLEMENT CK_ULONG
  1379. nssCKFWToken_GetRwSessionCount(
  1380. NSSCKFWToken *fwToken)
  1381. {
  1382. CK_ULONG rv;
  1383. #ifdef NSSDEBUG
  1384. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1385. return (CK_ULONG)0;
  1386. }
  1387. #endif /* NSSDEBUG */
  1388. if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
  1389. return (CK_ULONG)0;
  1390. }
  1391. rv = fwToken->rwSessionCount;
  1392. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1393. return rv;
  1394. }
  1395. /*
  1396. * nssCKFWToken_GetRoSessionCount
  1397. *
  1398. */
  1399. NSS_IMPLEMENT CK_ULONG
  1400. nssCKFWToken_GetRoSessionCount(
  1401. NSSCKFWToken *fwToken)
  1402. {
  1403. CK_ULONG rv;
  1404. #ifdef NSSDEBUG
  1405. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1406. return (CK_ULONG)0;
  1407. }
  1408. #endif /* NSSDEBUG */
  1409. if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) {
  1410. return (CK_ULONG)0;
  1411. }
  1412. rv = fwToken->sessionCount - fwToken->rwSessionCount;
  1413. (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1414. return rv;
  1415. }
  1416. /*
  1417. * nssCKFWToken_GetSessionObjectHash
  1418. *
  1419. */
  1420. NSS_IMPLEMENT nssCKFWHash *
  1421. nssCKFWToken_GetSessionObjectHash(
  1422. NSSCKFWToken *fwToken)
  1423. {
  1424. #ifdef NSSDEBUG
  1425. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1426. return (nssCKFWHash *)NULL;
  1427. }
  1428. #endif /* NSSDEBUG */
  1429. return fwToken->sessionObjectHash;
  1430. }
  1431. /*
  1432. * nssCKFWToken_GetMDObjectHash
  1433. *
  1434. */
  1435. NSS_IMPLEMENT nssCKFWHash *
  1436. nssCKFWToken_GetMDObjectHash(
  1437. NSSCKFWToken *fwToken)
  1438. {
  1439. #ifdef NSSDEBUG
  1440. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1441. return (nssCKFWHash *)NULL;
  1442. }
  1443. #endif /* NSSDEBUG */
  1444. return fwToken->mdObjectHash;
  1445. }
  1446. /*
  1447. * nssCKFWToken_GetObjectHandleHash
  1448. *
  1449. */
  1450. NSS_IMPLEMENT nssCKFWHash *
  1451. nssCKFWToken_GetObjectHandleHash(
  1452. NSSCKFWToken *fwToken)
  1453. {
  1454. #ifdef NSSDEBUG
  1455. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1456. return (nssCKFWHash *)NULL;
  1457. }
  1458. #endif /* NSSDEBUG */
  1459. return fwToken->mdObjectHash;
  1460. }
  1461. /*
  1462. * NSSCKFWToken_GetMDToken
  1463. *
  1464. */
  1465. NSS_IMPLEMENT NSSCKMDToken *
  1466. NSSCKFWToken_GetMDToken(
  1467. NSSCKFWToken *fwToken)
  1468. {
  1469. #ifdef DEBUG
  1470. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1471. return (NSSCKMDToken *)NULL;
  1472. }
  1473. #endif /* DEBUG */
  1474. return nssCKFWToken_GetMDToken(fwToken);
  1475. }
  1476. /*
  1477. * NSSCKFWToken_GetArena
  1478. *
  1479. */
  1480. NSS_IMPLEMENT NSSArena *
  1481. NSSCKFWToken_GetArena(
  1482. NSSCKFWToken *fwToken,
  1483. CK_RV *pError)
  1484. {
  1485. #ifdef DEBUG
  1486. if (!pError) {
  1487. return (NSSArena *)NULL;
  1488. }
  1489. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1490. *pError = CKR_ARGUMENTS_BAD;
  1491. return (NSSArena *)NULL;
  1492. }
  1493. #endif /* DEBUG */
  1494. return nssCKFWToken_GetArena(fwToken, pError);
  1495. }
  1496. /*
  1497. * NSSCKFWToken_GetFWSlot
  1498. *
  1499. */
  1500. NSS_IMPLEMENT NSSCKFWSlot *
  1501. NSSCKFWToken_GetFWSlot(
  1502. NSSCKFWToken *fwToken)
  1503. {
  1504. #ifdef DEBUG
  1505. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1506. return (NSSCKFWSlot *)NULL;
  1507. }
  1508. #endif /* DEBUG */
  1509. return nssCKFWToken_GetFWSlot(fwToken);
  1510. }
  1511. /*
  1512. * NSSCKFWToken_GetMDSlot
  1513. *
  1514. */
  1515. NSS_IMPLEMENT NSSCKMDSlot *
  1516. NSSCKFWToken_GetMDSlot(
  1517. NSSCKFWToken *fwToken)
  1518. {
  1519. #ifdef DEBUG
  1520. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1521. return (NSSCKMDSlot *)NULL;
  1522. }
  1523. #endif /* DEBUG */
  1524. return nssCKFWToken_GetMDSlot(fwToken);
  1525. }
  1526. /*
  1527. * NSSCKFWToken_GetSessionState
  1528. *
  1529. */
  1530. NSS_IMPLEMENT CK_STATE
  1531. NSSCKFWSession_GetSessionState(
  1532. NSSCKFWToken *fwToken)
  1533. {
  1534. #ifdef DEBUG
  1535. if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) {
  1536. return CKS_RO_PUBLIC_SESSION;
  1537. }
  1538. #endif /* DEBUG */
  1539. return nssCKFWToken_GetSessionState(fwToken);
  1540. }