session.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390
  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. * session.c
  6. *
  7. * This file implements the NSSCKFWSession type and methods.
  8. */
  9. #ifndef CK_T
  10. #include "ck.h"
  11. #endif /* CK_T */
  12. /*
  13. * NSSCKFWSession
  14. *
  15. * -- create/destroy --
  16. * nssCKFWSession_Create
  17. * nssCKFWSession_Destroy
  18. *
  19. * -- public accessors --
  20. * NSSCKFWSession_GetMDSession
  21. * NSSCKFWSession_GetArena
  22. * NSSCKFWSession_CallNotification
  23. * NSSCKFWSession_IsRWSession
  24. * NSSCKFWSession_IsSO
  25. * NSSCKFWSession_GetFWSlot
  26. *
  27. * -- implement public accessors --
  28. * nssCKFWSession_GetMDSession
  29. * nssCKFWSession_GetArena
  30. * nssCKFWSession_CallNotification
  31. * nssCKFWSession_IsRWSession
  32. * nssCKFWSession_IsSO
  33. * nssCKFWSession_GetFWSlot
  34. *
  35. * -- private accessors --
  36. * nssCKFWSession_GetSessionState
  37. * nssCKFWSession_SetFWFindObjects
  38. * nssCKFWSession_GetFWFindObjects
  39. * nssCKFWSession_SetMDSession
  40. * nssCKFWSession_SetHandle
  41. * nssCKFWSession_GetHandle
  42. * nssCKFWSession_RegisterSessionObject
  43. * nssCKFWSession_DeegisterSessionObject
  44. *
  45. * -- module fronts --
  46. * nssCKFWSession_GetDeviceError
  47. * nssCKFWSession_Login
  48. * nssCKFWSession_Logout
  49. * nssCKFWSession_InitPIN
  50. * nssCKFWSession_SetPIN
  51. * nssCKFWSession_GetOperationStateLen
  52. * nssCKFWSession_GetOperationState
  53. * nssCKFWSession_SetOperationState
  54. * nssCKFWSession_CreateObject
  55. * nssCKFWSession_CopyObject
  56. * nssCKFWSession_FindObjectsInit
  57. * nssCKFWSession_SeedRandom
  58. * nssCKFWSession_GetRandom
  59. */
  60. struct NSSCKFWSessionStr {
  61. NSSArena *arena;
  62. NSSCKMDSession *mdSession;
  63. NSSCKFWToken *fwToken;
  64. NSSCKMDToken *mdToken;
  65. NSSCKFWInstance *fwInstance;
  66. NSSCKMDInstance *mdInstance;
  67. CK_VOID_PTR pApplication;
  68. CK_NOTIFY Notify;
  69. /*
  70. * Everything above is set at creation time, and then not modified.
  71. * The items below are atomic. No locking required. If we fear
  72. * about pointer-copies being nonatomic, we'll lock fwFindObjects.
  73. */
  74. CK_BBOOL rw;
  75. NSSCKFWFindObjects *fwFindObjects;
  76. NSSCKFWCryptoOperation *fwOperationArray[NSSCKFWCryptoOperationState_Max];
  77. nssCKFWHash *sessionObjectHash;
  78. CK_SESSION_HANDLE hSession;
  79. };
  80. #ifdef DEBUG
  81. /*
  82. * But first, the pointer-tracking stuff.
  83. *
  84. * NOTE: the pointer-tracking support in NSS/base currently relies
  85. * upon NSPR's CallOnce support. That, however, relies upon NSPR's
  86. * locking, which is tied into the runtime. We need a pointer-tracker
  87. * implementation that uses the locks supplied through C_Initialize.
  88. * That support, however, can be filled in later. So for now, I'll
  89. * just do this routines as no-ops.
  90. */
  91. static CK_RV
  92. session_add_pointer(
  93. const NSSCKFWSession *fwSession)
  94. {
  95. return CKR_OK;
  96. }
  97. static CK_RV
  98. session_remove_pointer(
  99. const NSSCKFWSession *fwSession)
  100. {
  101. return CKR_OK;
  102. }
  103. NSS_IMPLEMENT CK_RV
  104. nssCKFWSession_verifyPointer(
  105. const NSSCKFWSession *fwSession)
  106. {
  107. return CKR_OK;
  108. }
  109. #endif /* DEBUG */
  110. /*
  111. * nssCKFWSession_Create
  112. *
  113. */
  114. NSS_IMPLEMENT NSSCKFWSession *
  115. nssCKFWSession_Create(
  116. NSSCKFWToken *fwToken,
  117. CK_BBOOL rw,
  118. CK_VOID_PTR pApplication,
  119. CK_NOTIFY Notify,
  120. CK_RV *pError)
  121. {
  122. NSSArena *arena = (NSSArena *)NULL;
  123. NSSCKFWSession *fwSession;
  124. NSSCKFWSlot *fwSlot;
  125. #ifdef NSSDEBUG
  126. if (!pError) {
  127. return (NSSCKFWSession *)NULL;
  128. }
  129. *pError = nssCKFWToken_verifyPointer(fwToken);
  130. if (CKR_OK != *pError) {
  131. return (NSSCKFWSession *)NULL;
  132. }
  133. #endif /* NSSDEBUG */
  134. arena = NSSArena_Create();
  135. if (!arena) {
  136. *pError = CKR_HOST_MEMORY;
  137. return (NSSCKFWSession *)NULL;
  138. }
  139. fwSession = nss_ZNEW(arena, NSSCKFWSession);
  140. if (!fwSession) {
  141. *pError = CKR_HOST_MEMORY;
  142. goto loser;
  143. }
  144. fwSession->arena = arena;
  145. fwSession->mdSession = (NSSCKMDSession *)NULL; /* set later */
  146. fwSession->fwToken = fwToken;
  147. fwSession->mdToken = nssCKFWToken_GetMDToken(fwToken);
  148. fwSlot = nssCKFWToken_GetFWSlot(fwToken);
  149. fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
  150. fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
  151. fwSession->rw = rw;
  152. fwSession->pApplication = pApplication;
  153. fwSession->Notify = Notify;
  154. fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
  155. fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena, pError);
  156. if (!fwSession->sessionObjectHash) {
  157. if (CKR_OK == *pError) {
  158. *pError = CKR_GENERAL_ERROR;
  159. }
  160. goto loser;
  161. }
  162. #ifdef DEBUG
  163. *pError = session_add_pointer(fwSession);
  164. if (CKR_OK != *pError) {
  165. goto loser;
  166. }
  167. #endif /* DEBUG */
  168. return fwSession;
  169. loser:
  170. if (arena) {
  171. if (fwSession && fwSession->sessionObjectHash) {
  172. (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash);
  173. }
  174. NSSArena_Destroy(arena);
  175. }
  176. return (NSSCKFWSession *)NULL;
  177. }
  178. static void
  179. nss_ckfw_session_object_destroy_iterator(
  180. const void *key,
  181. void *value,
  182. void *closure)
  183. {
  184. NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
  185. nssCKFWObject_Finalize(fwObject, PR_TRUE);
  186. }
  187. /*
  188. * nssCKFWSession_Destroy
  189. *
  190. */
  191. NSS_IMPLEMENT CK_RV
  192. nssCKFWSession_Destroy(
  193. NSSCKFWSession *fwSession,
  194. CK_BBOOL removeFromTokenHash)
  195. {
  196. CK_RV error = CKR_OK;
  197. nssCKFWHash *sessionObjectHash;
  198. NSSCKFWCryptoOperationState i;
  199. #ifdef NSSDEBUG
  200. error = nssCKFWSession_verifyPointer(fwSession);
  201. if (CKR_OK != error) {
  202. return error;
  203. }
  204. #endif /* NSSDEBUG */
  205. if (removeFromTokenHash) {
  206. error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
  207. }
  208. /*
  209. * Invalidate session objects
  210. */
  211. sessionObjectHash = fwSession->sessionObjectHash;
  212. fwSession->sessionObjectHash = (nssCKFWHash *)NULL;
  213. nssCKFWHash_Iterate(sessionObjectHash,
  214. nss_ckfw_session_object_destroy_iterator,
  215. (void *)NULL);
  216. for (i = 0; i < NSSCKFWCryptoOperationState_Max; i++) {
  217. if (fwSession->fwOperationArray[i]) {
  218. nssCKFWCryptoOperation_Destroy(fwSession->fwOperationArray[i]);
  219. }
  220. }
  221. #ifdef DEBUG
  222. (void)session_remove_pointer(fwSession);
  223. #endif /* DEBUG */
  224. (void)nssCKFWHash_Destroy(sessionObjectHash);
  225. NSSArena_Destroy(fwSession->arena);
  226. return error;
  227. }
  228. /*
  229. * nssCKFWSession_GetMDSession
  230. *
  231. */
  232. NSS_IMPLEMENT NSSCKMDSession *
  233. nssCKFWSession_GetMDSession(
  234. NSSCKFWSession *fwSession)
  235. {
  236. #ifdef NSSDEBUG
  237. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  238. return (NSSCKMDSession *)NULL;
  239. }
  240. #endif /* NSSDEBUG */
  241. return fwSession->mdSession;
  242. }
  243. /*
  244. * nssCKFWSession_GetArena
  245. *
  246. */
  247. NSS_IMPLEMENT NSSArena *
  248. nssCKFWSession_GetArena(
  249. NSSCKFWSession *fwSession,
  250. CK_RV *pError)
  251. {
  252. #ifdef NSSDEBUG
  253. if (!pError) {
  254. return (NSSArena *)NULL;
  255. }
  256. *pError = nssCKFWSession_verifyPointer(fwSession);
  257. if (CKR_OK != *pError) {
  258. return (NSSArena *)NULL;
  259. }
  260. #endif /* NSSDEBUG */
  261. return fwSession->arena;
  262. }
  263. /*
  264. * nssCKFWSession_CallNotification
  265. *
  266. */
  267. NSS_IMPLEMENT CK_RV
  268. nssCKFWSession_CallNotification(
  269. NSSCKFWSession *fwSession,
  270. CK_NOTIFICATION event)
  271. {
  272. CK_RV error = CKR_OK;
  273. CK_SESSION_HANDLE handle;
  274. #ifdef NSSDEBUG
  275. error = nssCKFWSession_verifyPointer(fwSession);
  276. if (CKR_OK != error) {
  277. return error;
  278. }
  279. #endif /* NSSDEBUG */
  280. if ((CK_NOTIFY)NULL == fwSession->Notify) {
  281. return CKR_OK;
  282. }
  283. handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession);
  284. if ((CK_SESSION_HANDLE)0 == handle) {
  285. return CKR_GENERAL_ERROR;
  286. }
  287. error = fwSession->Notify(handle, event, fwSession->pApplication);
  288. return error;
  289. }
  290. /*
  291. * nssCKFWSession_IsRWSession
  292. *
  293. */
  294. NSS_IMPLEMENT CK_BBOOL
  295. nssCKFWSession_IsRWSession(
  296. NSSCKFWSession *fwSession)
  297. {
  298. #ifdef NSSDEBUG
  299. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  300. return CK_FALSE;
  301. }
  302. #endif /* NSSDEBUG */
  303. return fwSession->rw;
  304. }
  305. /*
  306. * nssCKFWSession_IsSO
  307. *
  308. */
  309. NSS_IMPLEMENT CK_BBOOL
  310. nssCKFWSession_IsSO(
  311. NSSCKFWSession *fwSession)
  312. {
  313. CK_STATE state;
  314. #ifdef NSSDEBUG
  315. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  316. return CK_FALSE;
  317. }
  318. #endif /* NSSDEBUG */
  319. state = nssCKFWToken_GetSessionState(fwSession->fwToken);
  320. switch (state) {
  321. case CKS_RO_PUBLIC_SESSION:
  322. case CKS_RO_USER_FUNCTIONS:
  323. case CKS_RW_PUBLIC_SESSION:
  324. case CKS_RW_USER_FUNCTIONS:
  325. return CK_FALSE;
  326. case CKS_RW_SO_FUNCTIONS:
  327. return CK_TRUE;
  328. default:
  329. return CK_FALSE;
  330. }
  331. }
  332. /*
  333. * nssCKFWSession_GetFWSlot
  334. *
  335. */
  336. NSS_IMPLEMENT NSSCKFWSlot *
  337. nssCKFWSession_GetFWSlot(
  338. NSSCKFWSession *fwSession)
  339. {
  340. #ifdef NSSDEBUG
  341. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  342. return (NSSCKFWSlot *)NULL;
  343. }
  344. #endif /* NSSDEBUG */
  345. return nssCKFWToken_GetFWSlot(fwSession->fwToken);
  346. }
  347. /*
  348. * nssCFKWSession_GetSessionState
  349. *
  350. */
  351. NSS_IMPLEMENT CK_STATE
  352. nssCKFWSession_GetSessionState(
  353. NSSCKFWSession *fwSession)
  354. {
  355. #ifdef NSSDEBUG
  356. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  357. return CKS_RO_PUBLIC_SESSION; /* whatever */
  358. }
  359. #endif /* NSSDEBUG */
  360. return nssCKFWToken_GetSessionState(fwSession->fwToken);
  361. }
  362. /*
  363. * nssCKFWSession_SetFWFindObjects
  364. *
  365. */
  366. NSS_IMPLEMENT CK_RV
  367. nssCKFWSession_SetFWFindObjects(
  368. NSSCKFWSession *fwSession,
  369. NSSCKFWFindObjects *fwFindObjects)
  370. {
  371. #ifdef NSSDEBUG
  372. CK_RV error = CKR_OK;
  373. #endif /* NSSDEBUG */
  374. #ifdef NSSDEBUG
  375. error = nssCKFWSession_verifyPointer(fwSession);
  376. if (CKR_OK != error) {
  377. return error;
  378. }
  379. /* fwFindObjects may be null */
  380. #endif /* NSSDEBUG */
  381. if ((fwSession->fwFindObjects) &&
  382. (fwFindObjects)) {
  383. return CKR_OPERATION_ACTIVE;
  384. }
  385. fwSession->fwFindObjects = fwFindObjects;
  386. return CKR_OK;
  387. }
  388. /*
  389. * nssCKFWSession_GetFWFindObjects
  390. *
  391. */
  392. NSS_IMPLEMENT NSSCKFWFindObjects *
  393. nssCKFWSession_GetFWFindObjects(
  394. NSSCKFWSession *fwSession,
  395. CK_RV *pError)
  396. {
  397. #ifdef NSSDEBUG
  398. if (!pError) {
  399. return (NSSCKFWFindObjects *)NULL;
  400. }
  401. *pError = nssCKFWSession_verifyPointer(fwSession);
  402. if (CKR_OK != *pError) {
  403. return (NSSCKFWFindObjects *)NULL;
  404. }
  405. #endif /* NSSDEBUG */
  406. if (!fwSession->fwFindObjects) {
  407. *pError = CKR_OPERATION_NOT_INITIALIZED;
  408. return (NSSCKFWFindObjects *)NULL;
  409. }
  410. return fwSession->fwFindObjects;
  411. }
  412. /*
  413. * nssCKFWSession_SetMDSession
  414. *
  415. */
  416. NSS_IMPLEMENT CK_RV
  417. nssCKFWSession_SetMDSession(
  418. NSSCKFWSession *fwSession,
  419. NSSCKMDSession *mdSession)
  420. {
  421. #ifdef NSSDEBUG
  422. CK_RV error = CKR_OK;
  423. #endif /* NSSDEBUG */
  424. #ifdef NSSDEBUG
  425. error = nssCKFWSession_verifyPointer(fwSession);
  426. if (CKR_OK != error) {
  427. return error;
  428. }
  429. if (!mdSession) {
  430. return CKR_ARGUMENTS_BAD;
  431. }
  432. #endif /* NSSDEBUG */
  433. if (fwSession->mdSession) {
  434. return CKR_GENERAL_ERROR;
  435. }
  436. fwSession->mdSession = mdSession;
  437. return CKR_OK;
  438. }
  439. /*
  440. * nssCKFWSession_SetHandle
  441. *
  442. */
  443. NSS_IMPLEMENT CK_RV
  444. nssCKFWSession_SetHandle(
  445. NSSCKFWSession *fwSession,
  446. CK_SESSION_HANDLE hSession)
  447. {
  448. #ifdef NSSDEBUG
  449. CK_RV error = CKR_OK;
  450. #endif /* NSSDEBUG */
  451. #ifdef NSSDEBUG
  452. error = nssCKFWSession_verifyPointer(fwSession);
  453. if (CKR_OK != error) {
  454. return error;
  455. }
  456. #endif /* NSSDEBUG */
  457. if ((CK_SESSION_HANDLE)0 != fwSession->hSession) {
  458. return CKR_GENERAL_ERROR;
  459. }
  460. fwSession->hSession = hSession;
  461. return CKR_OK;
  462. }
  463. /*
  464. * nssCKFWSession_GetHandle
  465. *
  466. */
  467. NSS_IMPLEMENT CK_SESSION_HANDLE
  468. nssCKFWSession_GetHandle(
  469. NSSCKFWSession *fwSession)
  470. {
  471. #ifdef NSSDEBUG
  472. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  473. return NULL;
  474. }
  475. #endif /* NSSDEBUG */
  476. return fwSession->hSession;
  477. }
  478. /*
  479. * nssCKFWSession_RegisterSessionObject
  480. *
  481. */
  482. NSS_IMPLEMENT CK_RV
  483. nssCKFWSession_RegisterSessionObject(
  484. NSSCKFWSession *fwSession,
  485. NSSCKFWObject *fwObject)
  486. {
  487. CK_RV rv = CKR_OK;
  488. #ifdef NSSDEBUG
  489. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  490. return CKR_GENERAL_ERROR;
  491. }
  492. #endif /* NSSDEBUG */
  493. if (fwSession->sessionObjectHash) {
  494. rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
  495. }
  496. return rv;
  497. }
  498. /*
  499. * nssCKFWSession_DeregisterSessionObject
  500. *
  501. */
  502. NSS_IMPLEMENT CK_RV
  503. nssCKFWSession_DeregisterSessionObject(
  504. NSSCKFWSession *fwSession,
  505. NSSCKFWObject *fwObject)
  506. {
  507. #ifdef NSSDEBUG
  508. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  509. return CKR_GENERAL_ERROR;
  510. }
  511. #endif /* NSSDEBUG */
  512. if (fwSession->sessionObjectHash) {
  513. nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);
  514. }
  515. return CKR_OK;
  516. }
  517. /*
  518. * nssCKFWSession_GetDeviceError
  519. *
  520. */
  521. NSS_IMPLEMENT CK_ULONG
  522. nssCKFWSession_GetDeviceError(
  523. NSSCKFWSession *fwSession)
  524. {
  525. #ifdef NSSDEBUG
  526. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  527. return (CK_ULONG)0;
  528. }
  529. if (!fwSession->mdSession) {
  530. return (CK_ULONG)0;
  531. }
  532. #endif /* NSSDEBUG */
  533. if (!fwSession->mdSession->GetDeviceError) {
  534. return (CK_ULONG)0;
  535. }
  536. return fwSession->mdSession->GetDeviceError(fwSession->mdSession,
  537. fwSession, fwSession->mdToken, fwSession->fwToken,
  538. fwSession->mdInstance, fwSession->fwInstance);
  539. }
  540. /*
  541. * nssCKFWSession_Login
  542. *
  543. */
  544. NSS_IMPLEMENT CK_RV
  545. nssCKFWSession_Login(
  546. NSSCKFWSession *fwSession,
  547. CK_USER_TYPE userType,
  548. NSSItem *pin)
  549. {
  550. CK_RV error = CKR_OK;
  551. CK_STATE oldState;
  552. CK_STATE newState;
  553. #ifdef NSSDEBUG
  554. error = nssCKFWSession_verifyPointer(fwSession);
  555. if (CKR_OK != error) {
  556. return error;
  557. }
  558. switch (userType) {
  559. case CKU_SO:
  560. case CKU_USER:
  561. break;
  562. default:
  563. return CKR_USER_TYPE_INVALID;
  564. }
  565. if (!pin) {
  566. if (CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken)) {
  567. return CKR_ARGUMENTS_BAD;
  568. }
  569. }
  570. if (!fwSession->mdSession) {
  571. return CKR_GENERAL_ERROR;
  572. }
  573. #endif /* NSSDEBUG */
  574. oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
  575. /*
  576. * It's not clear what happens when you're already logged in.
  577. * I'll just fail; but if we decide to change, the logic is
  578. * all right here.
  579. */
  580. if (CKU_SO == userType) {
  581. switch (oldState) {
  582. case CKS_RO_PUBLIC_SESSION:
  583. /*
  584. * There's no such thing as a read-only security officer
  585. * session, so fail. The error should be CKR_SESSION_READ_ONLY,
  586. * except that C_Login isn't defined to return that. So we'll
  587. * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented.
  588. */
  589. return CKR_SESSION_READ_ONLY_EXISTS;
  590. case CKS_RO_USER_FUNCTIONS:
  591. return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
  592. case CKS_RW_PUBLIC_SESSION:
  593. newState =
  594. CKS_RW_SO_FUNCTIONS;
  595. break;
  596. case CKS_RW_USER_FUNCTIONS:
  597. return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
  598. case CKS_RW_SO_FUNCTIONS:
  599. return CKR_USER_ALREADY_LOGGED_IN;
  600. default:
  601. return CKR_GENERAL_ERROR;
  602. }
  603. } else /* CKU_USER == userType */ {
  604. switch (oldState) {
  605. case CKS_RO_PUBLIC_SESSION:
  606. newState =
  607. CKS_RO_USER_FUNCTIONS;
  608. break;
  609. case CKS_RO_USER_FUNCTIONS:
  610. return CKR_USER_ALREADY_LOGGED_IN;
  611. case CKS_RW_PUBLIC_SESSION:
  612. newState =
  613. CKS_RW_USER_FUNCTIONS;
  614. break;
  615. case CKS_RW_USER_FUNCTIONS:
  616. return CKR_USER_ALREADY_LOGGED_IN;
  617. case CKS_RW_SO_FUNCTIONS:
  618. return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
  619. default:
  620. return CKR_GENERAL_ERROR;
  621. }
  622. }
  623. /*
  624. * So now we're in one of three cases:
  625. *
  626. * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS;
  627. * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS;
  628. * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS;
  629. */
  630. if (!fwSession->mdSession->Login) {
  631. /*
  632. * The Module doesn't want to be informed (or check the pin)
  633. * it'll just rely on the Framework as needed.
  634. */
  635. ;
  636. } else {
  637. error = fwSession->mdSession->Login(fwSession->mdSession, fwSession,
  638. fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  639. fwSession->fwInstance, userType, pin, oldState, newState);
  640. if (CKR_OK != error) {
  641. return error;
  642. }
  643. }
  644. (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
  645. return CKR_OK;
  646. }
  647. /*
  648. * nssCKFWSession_Logout
  649. *
  650. */
  651. NSS_IMPLEMENT CK_RV
  652. nssCKFWSession_Logout(
  653. NSSCKFWSession *fwSession)
  654. {
  655. CK_RV error = CKR_OK;
  656. CK_STATE oldState;
  657. CK_STATE newState;
  658. #ifdef NSSDEBUG
  659. error = nssCKFWSession_verifyPointer(fwSession);
  660. if (CKR_OK != error) {
  661. return error;
  662. }
  663. if (!fwSession->mdSession) {
  664. return CKR_GENERAL_ERROR;
  665. }
  666. #endif /* NSSDEBUG */
  667. oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
  668. switch (oldState) {
  669. case CKS_RO_PUBLIC_SESSION:
  670. return CKR_USER_NOT_LOGGED_IN;
  671. case CKS_RO_USER_FUNCTIONS:
  672. newState = CKS_RO_PUBLIC_SESSION;
  673. break;
  674. case CKS_RW_PUBLIC_SESSION:
  675. return CKR_USER_NOT_LOGGED_IN;
  676. case CKS_RW_USER_FUNCTIONS:
  677. newState = CKS_RW_PUBLIC_SESSION;
  678. break;
  679. case CKS_RW_SO_FUNCTIONS:
  680. newState = CKS_RW_PUBLIC_SESSION;
  681. break;
  682. default:
  683. return CKR_GENERAL_ERROR;
  684. }
  685. /*
  686. * So now we're in one of three cases:
  687. *
  688. * Old == CKS_RW_SO_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
  689. * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
  690. * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION;
  691. */
  692. if (!fwSession->mdSession->Logout) {
  693. /*
  694. * The Module doesn't want to be informed. Okay.
  695. */
  696. ;
  697. } else {
  698. error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession,
  699. fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  700. fwSession->fwInstance, oldState, newState);
  701. if (CKR_OK != error) {
  702. /*
  703. * Now what?! A failure really should end up with the Framework
  704. * considering it logged out, right?
  705. */
  706. ;
  707. }
  708. }
  709. (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
  710. return error;
  711. }
  712. /*
  713. * nssCKFWSession_InitPIN
  714. *
  715. */
  716. NSS_IMPLEMENT CK_RV
  717. nssCKFWSession_InitPIN(
  718. NSSCKFWSession *fwSession,
  719. NSSItem *pin)
  720. {
  721. CK_RV error = CKR_OK;
  722. CK_STATE state;
  723. #ifdef NSSDEBUG
  724. error = nssCKFWSession_verifyPointer(fwSession);
  725. if (CKR_OK != error) {
  726. return error;
  727. }
  728. if (!fwSession->mdSession) {
  729. return CKR_GENERAL_ERROR;
  730. }
  731. #endif /* NSSDEBUG */
  732. state = nssCKFWToken_GetSessionState(fwSession->fwToken);
  733. if (CKS_RW_SO_FUNCTIONS != state) {
  734. return CKR_USER_NOT_LOGGED_IN;
  735. }
  736. if (!pin) {
  737. CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
  738. if (CK_TRUE != has) {
  739. return CKR_ARGUMENTS_BAD;
  740. }
  741. }
  742. if (!fwSession->mdSession->InitPIN) {
  743. return CKR_TOKEN_WRITE_PROTECTED;
  744. }
  745. error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,
  746. fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  747. fwSession->fwInstance, pin);
  748. return error;
  749. }
  750. /*
  751. * nssCKFWSession_SetPIN
  752. *
  753. */
  754. NSS_IMPLEMENT CK_RV
  755. nssCKFWSession_SetPIN(
  756. NSSCKFWSession *fwSession,
  757. const NSSItem *oldPin,
  758. NSSItem *newPin)
  759. {
  760. CK_RV error = CKR_OK;
  761. #ifdef NSSDEBUG
  762. error = nssCKFWSession_verifyPointer(fwSession);
  763. if (CKR_OK != error) {
  764. return error;
  765. }
  766. if (!fwSession->mdSession) {
  767. return CKR_GENERAL_ERROR;
  768. }
  769. #endif /* NSSDEBUG */
  770. if (!newPin) {
  771. CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
  772. if (CK_TRUE != has) {
  773. return CKR_ARGUMENTS_BAD;
  774. }
  775. }
  776. if (!oldPin) {
  777. CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
  778. if (CK_TRUE != has) {
  779. return CKR_ARGUMENTS_BAD;
  780. }
  781. }
  782. if (!fwSession->mdSession->SetPIN) {
  783. return CKR_TOKEN_WRITE_PROTECTED;
  784. }
  785. error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,
  786. fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  787. fwSession->fwInstance, (NSSItem *)oldPin, newPin);
  788. return error;
  789. }
  790. /*
  791. * nssCKFWSession_GetOperationStateLen
  792. *
  793. */
  794. NSS_IMPLEMENT CK_ULONG
  795. nssCKFWSession_GetOperationStateLen(
  796. NSSCKFWSession *fwSession,
  797. CK_RV *pError)
  798. {
  799. CK_ULONG mdAmt;
  800. CK_ULONG fwAmt;
  801. #ifdef NSSDEBUG
  802. if (!pError) {
  803. return (CK_ULONG)0;
  804. }
  805. *pError = nssCKFWSession_verifyPointer(fwSession);
  806. if (CKR_OK != *pError) {
  807. return (CK_ULONG)0;
  808. }
  809. if (!fwSession->mdSession) {
  810. *pError = CKR_GENERAL_ERROR;
  811. return (CK_ULONG)0;
  812. }
  813. #endif /* NSSDEBUG */
  814. if (!fwSession->mdSession->GetOperationStateLen) {
  815. *pError = CKR_STATE_UNSAVEABLE;
  816. return (CK_ULONG)0;
  817. }
  818. /*
  819. * We could check that the session is actually in some state..
  820. */
  821. mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession,
  822. fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  823. fwSession->fwInstance, pError);
  824. if (((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError)) {
  825. return (CK_ULONG)0;
  826. }
  827. /*
  828. * Add a bit of sanity-checking
  829. */
  830. fwAmt = mdAmt + 2 * sizeof(CK_ULONG);
  831. return fwAmt;
  832. }
  833. /*
  834. * nssCKFWSession_GetOperationState
  835. *
  836. */
  837. NSS_IMPLEMENT CK_RV
  838. nssCKFWSession_GetOperationState(
  839. NSSCKFWSession *fwSession,
  840. NSSItem *buffer)
  841. {
  842. CK_RV error = CKR_OK;
  843. CK_ULONG fwAmt;
  844. CK_ULONG *ulBuffer;
  845. NSSItem i2;
  846. CK_ULONG n, i;
  847. #ifdef NSSDEBUG
  848. error = nssCKFWSession_verifyPointer(fwSession);
  849. if (CKR_OK != error) {
  850. return error;
  851. }
  852. if (!buffer) {
  853. return CKR_ARGUMENTS_BAD;
  854. }
  855. if (!buffer->data) {
  856. return CKR_ARGUMENTS_BAD;
  857. }
  858. if (!fwSession->mdSession) {
  859. return CKR_GENERAL_ERROR;
  860. }
  861. #endif /* NSSDEBUG */
  862. if (!fwSession->mdSession->GetOperationState) {
  863. return CKR_STATE_UNSAVEABLE;
  864. }
  865. /*
  866. * Sanity-check the caller's buffer.
  867. */
  868. error = CKR_OK;
  869. fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);
  870. if (((CK_ULONG)0 == fwAmt) && (CKR_OK != error)) {
  871. return error;
  872. }
  873. if (buffer->size < fwAmt) {
  874. return CKR_BUFFER_TOO_SMALL;
  875. }
  876. ulBuffer = (CK_ULONG *)buffer->data;
  877. i2.size = buffer->size - 2 * sizeof(CK_ULONG);
  878. i2.data = (void *)&ulBuffer[2];
  879. error = fwSession->mdSession->GetOperationState(fwSession->mdSession,
  880. fwSession, fwSession->mdToken, fwSession->fwToken,
  881. fwSession->mdInstance, fwSession->fwInstance, &i2);
  882. if (CKR_OK != error) {
  883. return error;
  884. }
  885. /*
  886. * Add a little integrety/identity check.
  887. * NOTE: right now, it's pretty stupid.
  888. * A CRC or something would be better.
  889. */
  890. ulBuffer[0] = 0x434b4657; /* CKFW */
  891. ulBuffer[1] = 0;
  892. n = i2.size / sizeof(CK_ULONG);
  893. for (i = 0; i < n; i++) {
  894. ulBuffer[1] ^= ulBuffer[2 + i];
  895. }
  896. return CKR_OK;
  897. }
  898. /*
  899. * nssCKFWSession_SetOperationState
  900. *
  901. */
  902. NSS_IMPLEMENT CK_RV
  903. nssCKFWSession_SetOperationState(
  904. NSSCKFWSession *fwSession,
  905. NSSItem *state,
  906. NSSCKFWObject *encryptionKey,
  907. NSSCKFWObject *authenticationKey)
  908. {
  909. CK_RV error = CKR_OK;
  910. CK_ULONG *ulBuffer;
  911. CK_ULONG n, i;
  912. CK_ULONG x;
  913. NSSItem s;
  914. NSSCKMDObject *mdek;
  915. NSSCKMDObject *mdak;
  916. #ifdef NSSDEBUG
  917. error = nssCKFWSession_verifyPointer(fwSession);
  918. if (CKR_OK != error) {
  919. return error;
  920. }
  921. if (!state) {
  922. return CKR_ARGUMENTS_BAD;
  923. }
  924. if (!state->data) {
  925. return CKR_ARGUMENTS_BAD;
  926. }
  927. if (encryptionKey) {
  928. error = nssCKFWObject_verifyPointer(encryptionKey);
  929. if (CKR_OK != error) {
  930. return error;
  931. }
  932. }
  933. if (authenticationKey) {
  934. error = nssCKFWObject_verifyPointer(authenticationKey);
  935. if (CKR_OK != error) {
  936. return error;
  937. }
  938. }
  939. if (!fwSession->mdSession) {
  940. return CKR_GENERAL_ERROR;
  941. }
  942. #endif /* NSSDEBUG */
  943. ulBuffer = (CK_ULONG *)state->data;
  944. if (0x43b4657 != ulBuffer[0]) {
  945. return CKR_SAVED_STATE_INVALID;
  946. }
  947. n = (state->size / sizeof(CK_ULONG)) - 2;
  948. x = (CK_ULONG)0;
  949. for (i = 0; i < n; i++) {
  950. x ^= ulBuffer[2 + i];
  951. }
  952. if (x != ulBuffer[1]) {
  953. return CKR_SAVED_STATE_INVALID;
  954. }
  955. if (!fwSession->mdSession->SetOperationState) {
  956. return CKR_GENERAL_ERROR;
  957. }
  958. s.size = state->size - 2 * sizeof(CK_ULONG);
  959. s.data = (void *)&ulBuffer[2];
  960. if (encryptionKey) {
  961. mdek = nssCKFWObject_GetMDObject(encryptionKey);
  962. } else {
  963. mdek = (NSSCKMDObject *)NULL;
  964. }
  965. if (authenticationKey) {
  966. mdak = nssCKFWObject_GetMDObject(authenticationKey);
  967. } else {
  968. mdak = (NSSCKMDObject *)NULL;
  969. }
  970. error = fwSession->mdSession->SetOperationState(fwSession->mdSession,
  971. fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  972. fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey);
  973. if (CKR_OK != error) {
  974. return error;
  975. }
  976. /*
  977. * Here'd we restore any session data
  978. */
  979. return CKR_OK;
  980. }
  981. static CK_BBOOL
  982. nss_attributes_form_token_object(
  983. CK_ATTRIBUTE_PTR pTemplate,
  984. CK_ULONG ulAttributeCount)
  985. {
  986. CK_ULONG i;
  987. CK_BBOOL rv;
  988. for (i = 0; i < ulAttributeCount; i++) {
  989. if (CKA_TOKEN == pTemplate[i].type) {
  990. /* If we sanity-check, we can remove this sizeof check */
  991. if (sizeof(CK_BBOOL) == pTemplate[i].ulValueLen) {
  992. (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL));
  993. return rv;
  994. } else {
  995. return CK_FALSE;
  996. }
  997. }
  998. }
  999. return CK_FALSE;
  1000. }
  1001. /*
  1002. * nssCKFWSession_CreateObject
  1003. *
  1004. */
  1005. NSS_IMPLEMENT NSSCKFWObject *
  1006. nssCKFWSession_CreateObject(
  1007. NSSCKFWSession *fwSession,
  1008. CK_ATTRIBUTE_PTR pTemplate,
  1009. CK_ULONG ulAttributeCount,
  1010. CK_RV *pError)
  1011. {
  1012. NSSArena *arena;
  1013. NSSCKMDObject *mdObject;
  1014. NSSCKFWObject *fwObject;
  1015. CK_BBOOL isTokenObject;
  1016. #ifdef NSSDEBUG
  1017. if (!pError) {
  1018. return (NSSCKFWObject *)NULL;
  1019. }
  1020. *pError = nssCKFWSession_verifyPointer(fwSession);
  1021. if (CKR_OK != pError) {
  1022. return (NSSCKFWObject *)NULL;
  1023. }
  1024. if ((CK_ATTRIBUTE_PTR)NULL == pTemplate) {
  1025. *pError = CKR_ARGUMENTS_BAD;
  1026. return (NSSCKFWObject *)NULL;
  1027. }
  1028. if (!fwSession->mdSession) {
  1029. *pError = CKR_GENERAL_ERROR;
  1030. return (NSSCKFWObject *)NULL;
  1031. }
  1032. #endif /* NSSDEBUG */
  1033. /*
  1034. * Here would be an excellent place to sanity-check the object.
  1035. */
  1036. isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount);
  1037. if (CK_TRUE == isTokenObject) {
  1038. /* === TOKEN OBJECT === */
  1039. if (!fwSession->mdSession->CreateObject) {
  1040. *pError = CKR_TOKEN_WRITE_PROTECTED;
  1041. return (NSSCKFWObject *)NULL;
  1042. }
  1043. arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
  1044. if (!arena) {
  1045. if (CKR_OK == *pError) {
  1046. *pError = CKR_GENERAL_ERROR;
  1047. }
  1048. return (NSSCKFWObject *)NULL;
  1049. }
  1050. goto callmdcreateobject;
  1051. } else {
  1052. /* === SESSION OBJECT === */
  1053. arena = nssCKFWSession_GetArena(fwSession, pError);
  1054. if (!arena) {
  1055. if (CKR_OK == *pError) {
  1056. *pError = CKR_GENERAL_ERROR;
  1057. }
  1058. return (NSSCKFWObject *)NULL;
  1059. }
  1060. if (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
  1061. fwSession->fwInstance)) {
  1062. /* --- module handles the session object -- */
  1063. if (!fwSession->mdSession->CreateObject) {
  1064. *pError = CKR_GENERAL_ERROR;
  1065. return (NSSCKFWObject *)NULL;
  1066. }
  1067. goto callmdcreateobject;
  1068. } else {
  1069. /* --- framework handles the session object -- */
  1070. mdObject = nssCKMDSessionObject_Create(fwSession->fwToken,
  1071. arena, pTemplate, ulAttributeCount, pError);
  1072. goto gotmdobject;
  1073. }
  1074. }
  1075. callmdcreateobject:
  1076. mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession,
  1077. fwSession, fwSession->mdToken, fwSession->fwToken,
  1078. fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate,
  1079. ulAttributeCount, pError);
  1080. gotmdobject:
  1081. if (!mdObject) {
  1082. if (CKR_OK == *pError) {
  1083. *pError = CKR_GENERAL_ERROR;
  1084. }
  1085. return (NSSCKFWObject *)NULL;
  1086. }
  1087. fwObject = nssCKFWObject_Create(isTokenObject ? arena : NULL, mdObject,
  1088. isTokenObject ? NULL
  1089. : fwSession,
  1090. fwSession->fwToken, fwSession->fwInstance, pError);
  1091. if (!fwObject) {
  1092. if (CKR_OK == *pError) {
  1093. *pError = CKR_GENERAL_ERROR;
  1094. }
  1095. if (mdObject->Destroy) {
  1096. (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
  1097. fwSession->mdSession, fwSession, fwSession->mdToken,
  1098. fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
  1099. }
  1100. return (NSSCKFWObject *)NULL;
  1101. }
  1102. if (CK_FALSE == isTokenObject) {
  1103. if (CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, fwObject)) {
  1104. *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
  1105. if (CKR_OK != *pError) {
  1106. nssCKFWObject_Finalize(fwObject, PR_TRUE);
  1107. return (NSSCKFWObject *)NULL;
  1108. }
  1109. }
  1110. }
  1111. return fwObject;
  1112. }
  1113. /*
  1114. * nssCKFWSession_CopyObject
  1115. *
  1116. */
  1117. NSS_IMPLEMENT NSSCKFWObject *
  1118. nssCKFWSession_CopyObject(
  1119. NSSCKFWSession *fwSession,
  1120. NSSCKFWObject *fwObject,
  1121. CK_ATTRIBUTE_PTR pTemplate,
  1122. CK_ULONG ulAttributeCount,
  1123. CK_RV *pError)
  1124. {
  1125. CK_BBOOL oldIsToken;
  1126. CK_BBOOL newIsToken;
  1127. CK_ULONG i;
  1128. NSSCKFWObject *rv;
  1129. #ifdef NSSDEBUG
  1130. if (!pError) {
  1131. return (NSSCKFWObject *)NULL;
  1132. }
  1133. *pError = nssCKFWSession_verifyPointer(fwSession);
  1134. if (CKR_OK != *pError) {
  1135. return (NSSCKFWObject *)NULL;
  1136. }
  1137. *pError = nssCKFWObject_verifyPointer(fwObject);
  1138. if (CKR_OK != *pError) {
  1139. return (NSSCKFWObject *)NULL;
  1140. }
  1141. if (!fwSession->mdSession) {
  1142. *pError = CKR_GENERAL_ERROR;
  1143. return (NSSCKFWObject *)NULL;
  1144. }
  1145. #endif /* NSSDEBUG */
  1146. /*
  1147. * Sanity-check object
  1148. */
  1149. if (!fwObject) {
  1150. *pError = CKR_ARGUMENTS_BAD;
  1151. return (NSSCKFWObject *)NULL;
  1152. }
  1153. oldIsToken = nssCKFWObject_IsTokenObject(fwObject);
  1154. newIsToken = oldIsToken;
  1155. for (i = 0; i < ulAttributeCount; i++) {
  1156. if (CKA_TOKEN == pTemplate[i].type) {
  1157. /* Since we sanity-checked the object, we know this is the right size. */
  1158. (void)nsslibc_memcpy(&newIsToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
  1159. break;
  1160. }
  1161. }
  1162. /*
  1163. * If the Module handles its session objects, or if both the new
  1164. * and old object are token objects, use CopyObject if it exists.
  1165. */
  1166. if ((fwSession->mdSession->CopyObject) &&
  1167. (((CK_TRUE == oldIsToken) && (CK_TRUE == newIsToken)) ||
  1168. (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
  1169. fwSession->fwInstance)))) {
  1170. /* use copy object */
  1171. NSSArena *arena;
  1172. NSSCKMDObject *mdOldObject;
  1173. NSSCKMDObject *mdObject;
  1174. mdOldObject = nssCKFWObject_GetMDObject(fwObject);
  1175. if (CK_TRUE == newIsToken) {
  1176. arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
  1177. } else {
  1178. arena = nssCKFWSession_GetArena(fwSession, pError);
  1179. }
  1180. if (!arena) {
  1181. if (CKR_OK == *pError) {
  1182. *pError = CKR_GENERAL_ERROR;
  1183. }
  1184. return (NSSCKFWObject *)NULL;
  1185. }
  1186. mdObject = fwSession->mdSession->CopyObject(fwSession->mdSession,
  1187. fwSession, fwSession->mdToken, fwSession->fwToken,
  1188. fwSession->mdInstance, fwSession->fwInstance, mdOldObject,
  1189. fwObject, arena, pTemplate, ulAttributeCount, pError);
  1190. if (!mdObject) {
  1191. if (CKR_OK == *pError) {
  1192. *pError = CKR_GENERAL_ERROR;
  1193. }
  1194. return (NSSCKFWObject *)NULL;
  1195. }
  1196. rv = nssCKFWObject_Create(newIsToken ? arena : NULL, mdObject,
  1197. newIsToken ? NULL
  1198. : fwSession,
  1199. fwSession->fwToken, fwSession->fwInstance, pError);
  1200. if (CK_FALSE == newIsToken) {
  1201. if (CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, rv)) {
  1202. *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, rv, rv);
  1203. if (CKR_OK != *pError) {
  1204. nssCKFWObject_Finalize(rv, PR_TRUE);
  1205. return (NSSCKFWObject *)NULL;
  1206. }
  1207. }
  1208. }
  1209. return rv;
  1210. } else {
  1211. /* use create object */
  1212. NSSArena *tmpArena;
  1213. CK_ATTRIBUTE_PTR newTemplate;
  1214. CK_ULONG j, n, newLength, k;
  1215. CK_ATTRIBUTE_TYPE_PTR oldTypes;
  1216. n = nssCKFWObject_GetAttributeCount(fwObject, pError);
  1217. if ((0 == n) && (CKR_OK != *pError)) {
  1218. return (NSSCKFWObject *)NULL;
  1219. }
  1220. tmpArena = NSSArena_Create();
  1221. if (!tmpArena) {
  1222. *pError = CKR_HOST_MEMORY;
  1223. return (NSSCKFWObject *)NULL;
  1224. }
  1225. oldTypes = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE_TYPE, n);
  1226. if ((CK_ATTRIBUTE_TYPE_PTR)NULL == oldTypes) {
  1227. NSSArena_Destroy(tmpArena);
  1228. *pError = CKR_HOST_MEMORY;
  1229. return (NSSCKFWObject *)NULL;
  1230. }
  1231. *pError = nssCKFWObject_GetAttributeTypes(fwObject, oldTypes, n);
  1232. if (CKR_OK != *pError) {
  1233. NSSArena_Destroy(tmpArena);
  1234. return (NSSCKFWObject *)NULL;
  1235. }
  1236. newLength = n;
  1237. for (i = 0; i < ulAttributeCount; i++) {
  1238. for (j = 0; j < n; j++) {
  1239. if (oldTypes[j] == pTemplate[i].type) {
  1240. if ((CK_VOID_PTR)NULL ==
  1241. pTemplate[i].pValue) {
  1242. /* Removing the attribute */
  1243. newLength--;
  1244. }
  1245. break;
  1246. }
  1247. }
  1248. if (j == n) {
  1249. /* Not found */
  1250. newLength++;
  1251. }
  1252. }
  1253. newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, newLength);
  1254. if ((CK_ATTRIBUTE_PTR)NULL == newTemplate) {
  1255. NSSArena_Destroy(tmpArena);
  1256. *pError = CKR_HOST_MEMORY;
  1257. return (NSSCKFWObject *)NULL;
  1258. }
  1259. k = 0;
  1260. for (j = 0; j < n; j++) {
  1261. for (i = 0; i < ulAttributeCount; i++) {
  1262. if (oldTypes[j] == pTemplate[i].type) {
  1263. if ((CK_VOID_PTR)NULL ==
  1264. pTemplate[i].pValue) {
  1265. /* This attribute is being deleted */
  1266. ;
  1267. } else {
  1268. /* This attribute is being replaced */
  1269. newTemplate[k].type =
  1270. pTemplate[i].type;
  1271. newTemplate[k].pValue =
  1272. pTemplate[i].pValue;
  1273. newTemplate[k].ulValueLen =
  1274. pTemplate[i].ulValueLen;
  1275. k++;
  1276. }
  1277. break;
  1278. }
  1279. }
  1280. if (i == ulAttributeCount) {
  1281. /* This attribute is being copied over from the old object */
  1282. NSSItem item, *it;
  1283. item.size = 0;
  1284. item.data = (void *)NULL;
  1285. it = nssCKFWObject_GetAttribute(fwObject, oldTypes[j],
  1286. &item, tmpArena, pError);
  1287. if (!it) {
  1288. if (CKR_OK ==
  1289. *pError) {
  1290. *pError =
  1291. CKR_GENERAL_ERROR;
  1292. }
  1293. NSSArena_Destroy(tmpArena);
  1294. return (NSSCKFWObject *)NULL;
  1295. }
  1296. newTemplate[k].type = oldTypes[j];
  1297. newTemplate[k].pValue = it->data;
  1298. newTemplate[k].ulValueLen = it->size;
  1299. k++;
  1300. }
  1301. }
  1302. /* assert that k == newLength */
  1303. rv = nssCKFWSession_CreateObject(fwSession, newTemplate, newLength, pError);
  1304. if (!rv) {
  1305. if (CKR_OK == *pError) {
  1306. *pError = CKR_GENERAL_ERROR;
  1307. }
  1308. NSSArena_Destroy(tmpArena);
  1309. return (NSSCKFWObject *)NULL;
  1310. }
  1311. NSSArena_Destroy(tmpArena);
  1312. return rv;
  1313. }
  1314. }
  1315. /*
  1316. * nssCKFWSession_FindObjectsInit
  1317. *
  1318. */
  1319. NSS_IMPLEMENT NSSCKFWFindObjects *
  1320. nssCKFWSession_FindObjectsInit(
  1321. NSSCKFWSession *fwSession,
  1322. CK_ATTRIBUTE_PTR pTemplate,
  1323. CK_ULONG ulAttributeCount,
  1324. CK_RV *pError)
  1325. {
  1326. NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL;
  1327. NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL;
  1328. #ifdef NSSDEBUG
  1329. if (!pError) {
  1330. return (NSSCKFWFindObjects *)NULL;
  1331. }
  1332. *pError = nssCKFWSession_verifyPointer(fwSession);
  1333. if (CKR_OK != *pError) {
  1334. return (NSSCKFWFindObjects *)NULL;
  1335. }
  1336. if (((CK_ATTRIBUTE_PTR)NULL == pTemplate) && (ulAttributeCount != 0)) {
  1337. *pError = CKR_ARGUMENTS_BAD;
  1338. return (NSSCKFWFindObjects *)NULL;
  1339. }
  1340. if (!fwSession->mdSession) {
  1341. *pError = CKR_GENERAL_ERROR;
  1342. return (NSSCKFWFindObjects *)NULL;
  1343. }
  1344. #endif /* NSSDEBUG */
  1345. if (CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
  1346. fwSession->fwInstance)) {
  1347. CK_ULONG i;
  1348. /*
  1349. * Does the search criteria restrict us to token or session
  1350. * objects?
  1351. */
  1352. for (i = 0; i < ulAttributeCount; i++) {
  1353. if (CKA_TOKEN == pTemplate[i].type) {
  1354. /* Yes, it does. */
  1355. CK_BBOOL isToken;
  1356. if (sizeof(CK_BBOOL) != pTemplate[i].ulValueLen) {
  1357. *pError =
  1358. CKR_ATTRIBUTE_VALUE_INVALID;
  1359. return (NSSCKFWFindObjects *)NULL;
  1360. }
  1361. (void)nsslibc_memcpy(&isToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
  1362. if (CK_TRUE == isToken) {
  1363. /* Pass it on to the module's search routine */
  1364. if (!fwSession->mdSession->FindObjectsInit) {
  1365. goto wrap;
  1366. }
  1367. mdfo1 =
  1368. fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
  1369. fwSession, fwSession->mdToken, fwSession->fwToken,
  1370. fwSession->mdInstance, fwSession->fwInstance,
  1371. pTemplate, ulAttributeCount, pError);
  1372. } else {
  1373. /* Do the search ourselves */
  1374. mdfo1 =
  1375. nssCKMDFindSessionObjects_Create(fwSession->fwToken,
  1376. pTemplate, ulAttributeCount, pError);
  1377. }
  1378. if (!mdfo1) {
  1379. if (CKR_OK ==
  1380. *pError) {
  1381. *pError =
  1382. CKR_GENERAL_ERROR;
  1383. }
  1384. return (NSSCKFWFindObjects *)NULL;
  1385. }
  1386. goto wrap;
  1387. }
  1388. }
  1389. if (i == ulAttributeCount) {
  1390. /* No, it doesn't. Do a hybrid search. */
  1391. mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
  1392. fwSession, fwSession->mdToken, fwSession->fwToken,
  1393. fwSession->mdInstance, fwSession->fwInstance,
  1394. pTemplate, ulAttributeCount, pError);
  1395. if (!mdfo1) {
  1396. if (CKR_OK == *pError) {
  1397. *pError =
  1398. CKR_GENERAL_ERROR;
  1399. }
  1400. return (NSSCKFWFindObjects *)NULL;
  1401. }
  1402. mdfo2 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
  1403. pTemplate, ulAttributeCount, pError);
  1404. if (!mdfo2) {
  1405. if (CKR_OK == *pError) {
  1406. *pError =
  1407. CKR_GENERAL_ERROR;
  1408. }
  1409. if (mdfo1->Final) {
  1410. mdfo1->Final(mdfo1, (NSSCKFWFindObjects *)NULL, fwSession->mdSession,
  1411. fwSession, fwSession->mdToken, fwSession->fwToken,
  1412. fwSession->mdInstance, fwSession->fwInstance);
  1413. }
  1414. return (NSSCKFWFindObjects *)NULL;
  1415. }
  1416. goto wrap;
  1417. }
  1418. /*NOTREACHED*/
  1419. } else {
  1420. /* Module handles all its own objects. Pass on to module's search */
  1421. mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
  1422. fwSession, fwSession->mdToken, fwSession->fwToken,
  1423. fwSession->mdInstance, fwSession->fwInstance,
  1424. pTemplate, ulAttributeCount, pError);
  1425. if (!mdfo1) {
  1426. if (CKR_OK == *pError) {
  1427. *pError = CKR_GENERAL_ERROR;
  1428. }
  1429. return (NSSCKFWFindObjects *)NULL;
  1430. }
  1431. goto wrap;
  1432. }
  1433. wrap:
  1434. return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
  1435. fwSession->fwInstance, mdfo1, mdfo2, pError);
  1436. }
  1437. /*
  1438. * nssCKFWSession_SeedRandom
  1439. *
  1440. */
  1441. NSS_IMPLEMENT CK_RV
  1442. nssCKFWSession_SeedRandom(
  1443. NSSCKFWSession *fwSession,
  1444. NSSItem *seed)
  1445. {
  1446. CK_RV error = CKR_OK;
  1447. #ifdef NSSDEBUG
  1448. error = nssCKFWSession_verifyPointer(fwSession);
  1449. if (CKR_OK != error) {
  1450. return error;
  1451. }
  1452. if (!seed) {
  1453. return CKR_ARGUMENTS_BAD;
  1454. }
  1455. if (!seed->data) {
  1456. return CKR_ARGUMENTS_BAD;
  1457. }
  1458. if (0 == seed->size) {
  1459. return CKR_ARGUMENTS_BAD;
  1460. }
  1461. if (!fwSession->mdSession) {
  1462. return CKR_GENERAL_ERROR;
  1463. }
  1464. #endif /* NSSDEBUG */
  1465. if (!fwSession->mdSession->SeedRandom) {
  1466. return CKR_RANDOM_SEED_NOT_SUPPORTED;
  1467. }
  1468. error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession,
  1469. fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  1470. fwSession->fwInstance, seed);
  1471. return error;
  1472. }
  1473. /*
  1474. * nssCKFWSession_GetRandom
  1475. *
  1476. */
  1477. NSS_IMPLEMENT CK_RV
  1478. nssCKFWSession_GetRandom(
  1479. NSSCKFWSession *fwSession,
  1480. NSSItem *buffer)
  1481. {
  1482. CK_RV error = CKR_OK;
  1483. #ifdef NSSDEBUG
  1484. error = nssCKFWSession_verifyPointer(fwSession);
  1485. if (CKR_OK != error) {
  1486. return error;
  1487. }
  1488. if (!buffer) {
  1489. return CKR_ARGUMENTS_BAD;
  1490. }
  1491. if (!buffer->data) {
  1492. return CKR_ARGUMENTS_BAD;
  1493. }
  1494. if (!fwSession->mdSession) {
  1495. return CKR_GENERAL_ERROR;
  1496. }
  1497. #endif /* NSSDEBUG */
  1498. if (!fwSession->mdSession->GetRandom) {
  1499. if (CK_TRUE == nssCKFWToken_GetHasRNG(fwSession->fwToken)) {
  1500. return CKR_GENERAL_ERROR;
  1501. } else {
  1502. return CKR_RANDOM_NO_RNG;
  1503. }
  1504. }
  1505. if (0 == buffer->size) {
  1506. return CKR_OK;
  1507. }
  1508. error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
  1509. fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
  1510. fwSession->fwInstance, buffer);
  1511. return error;
  1512. }
  1513. /*
  1514. * nssCKFWSession_SetCurrentCryptoOperation
  1515. */
  1516. NSS_IMPLEMENT void
  1517. nssCKFWSession_SetCurrentCryptoOperation(
  1518. NSSCKFWSession *fwSession,
  1519. NSSCKFWCryptoOperation *fwOperation,
  1520. NSSCKFWCryptoOperationState state)
  1521. {
  1522. #ifdef NSSDEBUG
  1523. CK_RV error = CKR_OK;
  1524. error = nssCKFWSession_verifyPointer(fwSession);
  1525. if (CKR_OK != error) {
  1526. return;
  1527. }
  1528. if (state >= NSSCKFWCryptoOperationState_Max) {
  1529. return;
  1530. }
  1531. if (!fwSession->mdSession) {
  1532. return;
  1533. }
  1534. #endif /* NSSDEBUG */
  1535. fwSession->fwOperationArray[state] = fwOperation;
  1536. return;
  1537. }
  1538. /*
  1539. * nssCKFWSession_GetCurrentCryptoOperation
  1540. */
  1541. NSS_IMPLEMENT NSSCKFWCryptoOperation *
  1542. nssCKFWSession_GetCurrentCryptoOperation(
  1543. NSSCKFWSession *fwSession,
  1544. NSSCKFWCryptoOperationState state)
  1545. {
  1546. #ifdef NSSDEBUG
  1547. CK_RV error = CKR_OK;
  1548. error = nssCKFWSession_verifyPointer(fwSession);
  1549. if (CKR_OK != error) {
  1550. return (NSSCKFWCryptoOperation *)NULL;
  1551. }
  1552. if (state >= NSSCKFWCryptoOperationState_Max) {
  1553. return (NSSCKFWCryptoOperation *)NULL;
  1554. }
  1555. if (!fwSession->mdSession) {
  1556. return (NSSCKFWCryptoOperation *)NULL;
  1557. }
  1558. #endif /* NSSDEBUG */
  1559. return fwSession->fwOperationArray[state];
  1560. }
  1561. /*
  1562. * nssCKFWSession_Final
  1563. */
  1564. NSS_IMPLEMENT CK_RV
  1565. nssCKFWSession_Final(
  1566. NSSCKFWSession *fwSession,
  1567. NSSCKFWCryptoOperationType type,
  1568. NSSCKFWCryptoOperationState state,
  1569. CK_BYTE_PTR outBuf,
  1570. CK_ULONG_PTR outBufLen)
  1571. {
  1572. NSSCKFWCryptoOperation *fwOperation;
  1573. NSSItem outputBuffer;
  1574. CK_RV error = CKR_OK;
  1575. #ifdef NSSDEBUG
  1576. error = nssCKFWSession_verifyPointer(fwSession);
  1577. if (CKR_OK != error) {
  1578. return error;
  1579. }
  1580. if (!fwSession->mdSession) {
  1581. return CKR_GENERAL_ERROR;
  1582. }
  1583. #endif /* NSSDEBUG */
  1584. /* make sure we have a valid operation initialized */
  1585. fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
  1586. if (!fwOperation) {
  1587. return CKR_OPERATION_NOT_INITIALIZED;
  1588. }
  1589. /* make sure it's the correct type */
  1590. if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
  1591. return CKR_OPERATION_NOT_INITIALIZED;
  1592. }
  1593. /* handle buffer issues, note for Verify, the type is an input buffer. */
  1594. if (NSSCKFWCryptoOperationType_Verify == type) {
  1595. if ((CK_BYTE_PTR)NULL == outBuf) {
  1596. error = CKR_ARGUMENTS_BAD;
  1597. goto done;
  1598. }
  1599. } else {
  1600. CK_ULONG len = nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
  1601. CK_ULONG maxBufLen = *outBufLen;
  1602. if (CKR_OK != error) {
  1603. goto done;
  1604. }
  1605. *outBufLen = len;
  1606. if ((CK_BYTE_PTR)NULL == outBuf) {
  1607. return CKR_OK;
  1608. }
  1609. if (len > maxBufLen) {
  1610. return CKR_BUFFER_TOO_SMALL;
  1611. }
  1612. }
  1613. outputBuffer.data = outBuf;
  1614. outputBuffer.size = *outBufLen;
  1615. error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
  1616. done:
  1617. if (CKR_BUFFER_TOO_SMALL == error) {
  1618. return error;
  1619. }
  1620. /* clean up our state */
  1621. nssCKFWCryptoOperation_Destroy(fwOperation);
  1622. nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
  1623. return error;
  1624. }
  1625. /*
  1626. * nssCKFWSession_Update
  1627. */
  1628. NSS_IMPLEMENT CK_RV
  1629. nssCKFWSession_Update(
  1630. NSSCKFWSession *fwSession,
  1631. NSSCKFWCryptoOperationType type,
  1632. NSSCKFWCryptoOperationState state,
  1633. CK_BYTE_PTR inBuf,
  1634. CK_ULONG inBufLen,
  1635. CK_BYTE_PTR outBuf,
  1636. CK_ULONG_PTR outBufLen)
  1637. {
  1638. NSSCKFWCryptoOperation *fwOperation;
  1639. NSSItem inputBuffer;
  1640. NSSItem outputBuffer;
  1641. CK_ULONG len;
  1642. CK_ULONG maxBufLen;
  1643. CK_RV error = CKR_OK;
  1644. #ifdef NSSDEBUG
  1645. error = nssCKFWSession_verifyPointer(fwSession);
  1646. if (CKR_OK != error) {
  1647. return error;
  1648. }
  1649. if (!fwSession->mdSession) {
  1650. return CKR_GENERAL_ERROR;
  1651. }
  1652. #endif /* NSSDEBUG */
  1653. /* make sure we have a valid operation initialized */
  1654. fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
  1655. if (!fwOperation) {
  1656. return CKR_OPERATION_NOT_INITIALIZED;
  1657. }
  1658. /* make sure it's the correct type */
  1659. if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
  1660. return CKR_OPERATION_NOT_INITIALIZED;
  1661. }
  1662. inputBuffer.data = inBuf;
  1663. inputBuffer.size = inBufLen;
  1664. /* handle buffer issues, note for Verify, the type is an input buffer. */
  1665. len = nssCKFWCryptoOperation_GetOperationLength(fwOperation, &inputBuffer,
  1666. &error);
  1667. if (CKR_OK != error) {
  1668. return error;
  1669. }
  1670. maxBufLen = *outBufLen;
  1671. *outBufLen = len;
  1672. if ((CK_BYTE_PTR)NULL == outBuf) {
  1673. return CKR_OK;
  1674. }
  1675. if (len > maxBufLen) {
  1676. return CKR_BUFFER_TOO_SMALL;
  1677. }
  1678. outputBuffer.data = outBuf;
  1679. outputBuffer.size = *outBufLen;
  1680. return nssCKFWCryptoOperation_Update(fwOperation,
  1681. &inputBuffer, &outputBuffer);
  1682. }
  1683. /*
  1684. * nssCKFWSession_DigestUpdate
  1685. */
  1686. NSS_IMPLEMENT CK_RV
  1687. nssCKFWSession_DigestUpdate(
  1688. NSSCKFWSession *fwSession,
  1689. NSSCKFWCryptoOperationType type,
  1690. NSSCKFWCryptoOperationState state,
  1691. CK_BYTE_PTR inBuf,
  1692. CK_ULONG inBufLen)
  1693. {
  1694. NSSCKFWCryptoOperation *fwOperation;
  1695. NSSItem inputBuffer;
  1696. CK_RV error = CKR_OK;
  1697. #ifdef NSSDEBUG
  1698. error = nssCKFWSession_verifyPointer(fwSession);
  1699. if (CKR_OK != error) {
  1700. return error;
  1701. }
  1702. if (!fwSession->mdSession) {
  1703. return CKR_GENERAL_ERROR;
  1704. }
  1705. #endif /* NSSDEBUG */
  1706. /* make sure we have a valid operation initialized */
  1707. fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
  1708. if (!fwOperation) {
  1709. return CKR_OPERATION_NOT_INITIALIZED;
  1710. }
  1711. /* make sure it's the correct type */
  1712. if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
  1713. return CKR_OPERATION_NOT_INITIALIZED;
  1714. }
  1715. inputBuffer.data = inBuf;
  1716. inputBuffer.size = inBufLen;
  1717. error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
  1718. return error;
  1719. }
  1720. /*
  1721. * nssCKFWSession_DigestUpdate
  1722. */
  1723. NSS_IMPLEMENT CK_RV
  1724. nssCKFWSession_DigestKey(
  1725. NSSCKFWSession *fwSession,
  1726. NSSCKFWObject *fwKey)
  1727. {
  1728. NSSCKFWCryptoOperation *fwOperation;
  1729. NSSItem *inputBuffer;
  1730. CK_RV error = CKR_OK;
  1731. #ifdef NSSDEBUG
  1732. error = nssCKFWSession_verifyPointer(fwSession);
  1733. if (CKR_OK != error) {
  1734. return error;
  1735. }
  1736. if (!fwSession->mdSession) {
  1737. return CKR_GENERAL_ERROR;
  1738. }
  1739. #endif /* NSSDEBUG */
  1740. /* make sure we have a valid operation initialized */
  1741. fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
  1742. NSSCKFWCryptoOperationState_Digest);
  1743. if (!fwOperation) {
  1744. return CKR_OPERATION_NOT_INITIALIZED;
  1745. }
  1746. /* make sure it's the correct type */
  1747. if (NSSCKFWCryptoOperationType_Digest !=
  1748. nssCKFWCryptoOperation_GetType(fwOperation)) {
  1749. return CKR_OPERATION_NOT_INITIALIZED;
  1750. }
  1751. error = nssCKFWCryptoOperation_DigestKey(fwOperation, fwKey);
  1752. if (CKR_FUNCTION_FAILED != error) {
  1753. return error;
  1754. }
  1755. /* no machine depended way for this to happen, do it by hand */
  1756. inputBuffer = nssCKFWObject_GetAttribute(fwKey, CKA_VALUE, NULL, NULL, &error);
  1757. if (!inputBuffer) {
  1758. /* couldn't get the value, just fail then */
  1759. return error;
  1760. }
  1761. error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, inputBuffer);
  1762. nssItem_Destroy(inputBuffer);
  1763. return error;
  1764. }
  1765. /*
  1766. * nssCKFWSession_UpdateFinal
  1767. */
  1768. NSS_IMPLEMENT CK_RV
  1769. nssCKFWSession_UpdateFinal(
  1770. NSSCKFWSession *fwSession,
  1771. NSSCKFWCryptoOperationType type,
  1772. NSSCKFWCryptoOperationState state,
  1773. CK_BYTE_PTR inBuf,
  1774. CK_ULONG inBufLen,
  1775. CK_BYTE_PTR outBuf,
  1776. CK_ULONG_PTR outBufLen)
  1777. {
  1778. NSSCKFWCryptoOperation *fwOperation;
  1779. NSSItem inputBuffer;
  1780. NSSItem outputBuffer;
  1781. PRBool isEncryptDecrypt;
  1782. CK_RV error = CKR_OK;
  1783. #ifdef NSSDEBUG
  1784. error = nssCKFWSession_verifyPointer(fwSession);
  1785. if (CKR_OK != error) {
  1786. return error;
  1787. }
  1788. if (!fwSession->mdSession) {
  1789. return CKR_GENERAL_ERROR;
  1790. }
  1791. #endif /* NSSDEBUG */
  1792. /* make sure we have a valid operation initialized */
  1793. fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
  1794. if (!fwOperation) {
  1795. return CKR_OPERATION_NOT_INITIALIZED;
  1796. }
  1797. /* make sure it's the correct type */
  1798. if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
  1799. return CKR_OPERATION_NOT_INITIALIZED;
  1800. }
  1801. inputBuffer.data = inBuf;
  1802. inputBuffer.size = inBufLen;
  1803. isEncryptDecrypt = (PRBool)((NSSCKFWCryptoOperationType_Encrypt == type) ||
  1804. (NSSCKFWCryptoOperationType_Decrypt == type));
  1805. /* handle buffer issues, note for Verify, the type is an input buffer. */
  1806. if (NSSCKFWCryptoOperationType_Verify == type) {
  1807. if ((CK_BYTE_PTR)NULL == outBuf) {
  1808. error = CKR_ARGUMENTS_BAD;
  1809. goto done;
  1810. }
  1811. } else {
  1812. CK_ULONG maxBufLen = *outBufLen;
  1813. CK_ULONG len;
  1814. len = (isEncryptDecrypt) ? nssCKFWCryptoOperation_GetOperationLength(fwOperation,
  1815. &inputBuffer, &error)
  1816. : nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
  1817. if (CKR_OK != error) {
  1818. goto done;
  1819. }
  1820. *outBufLen = len;
  1821. if ((CK_BYTE_PTR)NULL == outBuf) {
  1822. return CKR_OK;
  1823. }
  1824. if (len > maxBufLen) {
  1825. return CKR_BUFFER_TOO_SMALL;
  1826. }
  1827. }
  1828. outputBuffer.data = outBuf;
  1829. outputBuffer.size = *outBufLen;
  1830. error = nssCKFWCryptoOperation_UpdateFinal(fwOperation,
  1831. &inputBuffer, &outputBuffer);
  1832. /* UpdateFinal isn't support, manually use Update and Final */
  1833. if (CKR_FUNCTION_FAILED == error) {
  1834. error = isEncryptDecrypt ? nssCKFWCryptoOperation_Update(fwOperation, &inputBuffer, &outputBuffer)
  1835. : nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
  1836. if (CKR_OK == error) {
  1837. error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
  1838. }
  1839. }
  1840. done:
  1841. if (CKR_BUFFER_TOO_SMALL == error) {
  1842. /* if we return CKR_BUFFER_TOO_SMALL, we the caller is not expecting.
  1843. * the crypto state to be freed */
  1844. return error;
  1845. }
  1846. /* clean up our state */
  1847. nssCKFWCryptoOperation_Destroy(fwOperation);
  1848. nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
  1849. return error;
  1850. }
  1851. NSS_IMPLEMENT CK_RV
  1852. nssCKFWSession_UpdateCombo(
  1853. NSSCKFWSession *fwSession,
  1854. NSSCKFWCryptoOperationType encryptType,
  1855. NSSCKFWCryptoOperationType digestType,
  1856. NSSCKFWCryptoOperationState digestState,
  1857. CK_BYTE_PTR inBuf,
  1858. CK_ULONG inBufLen,
  1859. CK_BYTE_PTR outBuf,
  1860. CK_ULONG_PTR outBufLen)
  1861. {
  1862. NSSCKFWCryptoOperation *fwOperation;
  1863. NSSCKFWCryptoOperation *fwPeerOperation;
  1864. NSSItem inputBuffer;
  1865. NSSItem outputBuffer;
  1866. CK_ULONG maxBufLen = *outBufLen;
  1867. CK_ULONG len;
  1868. CK_RV error = CKR_OK;
  1869. #ifdef NSSDEBUG
  1870. error = nssCKFWSession_verifyPointer(fwSession);
  1871. if (CKR_OK != error) {
  1872. return error;
  1873. }
  1874. if (!fwSession->mdSession) {
  1875. return CKR_GENERAL_ERROR;
  1876. }
  1877. #endif /* NSSDEBUG */
  1878. /* make sure we have a valid operation initialized */
  1879. fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
  1880. NSSCKFWCryptoOperationState_EncryptDecrypt);
  1881. if (!fwOperation) {
  1882. return CKR_OPERATION_NOT_INITIALIZED;
  1883. }
  1884. /* make sure it's the correct type */
  1885. if (encryptType != nssCKFWCryptoOperation_GetType(fwOperation)) {
  1886. return CKR_OPERATION_NOT_INITIALIZED;
  1887. }
  1888. /* make sure we have a valid operation initialized */
  1889. fwPeerOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
  1890. digestState);
  1891. if (!fwPeerOperation) {
  1892. return CKR_OPERATION_NOT_INITIALIZED;
  1893. }
  1894. /* make sure it's the correct type */
  1895. if (digestType != nssCKFWCryptoOperation_GetType(fwOperation)) {
  1896. return CKR_OPERATION_NOT_INITIALIZED;
  1897. }
  1898. inputBuffer.data = inBuf;
  1899. inputBuffer.size = inBufLen;
  1900. len = nssCKFWCryptoOperation_GetOperationLength(fwOperation,
  1901. &inputBuffer, &error);
  1902. if (CKR_OK != error) {
  1903. return error;
  1904. }
  1905. *outBufLen = len;
  1906. if ((CK_BYTE_PTR)NULL == outBuf) {
  1907. return CKR_OK;
  1908. }
  1909. if (len > maxBufLen) {
  1910. return CKR_BUFFER_TOO_SMALL;
  1911. }
  1912. outputBuffer.data = outBuf;
  1913. outputBuffer.size = *outBufLen;
  1914. error = nssCKFWCryptoOperation_UpdateCombo(fwOperation, fwPeerOperation,
  1915. &inputBuffer, &outputBuffer);
  1916. if (CKR_FUNCTION_FAILED == error) {
  1917. PRBool isEncrypt =
  1918. (PRBool)(NSSCKFWCryptoOperationType_Encrypt == encryptType);
  1919. if (isEncrypt) {
  1920. error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
  1921. &inputBuffer);
  1922. if (CKR_OK != error) {
  1923. return error;
  1924. }
  1925. }
  1926. error = nssCKFWCryptoOperation_Update(fwOperation,
  1927. &inputBuffer, &outputBuffer);
  1928. if (CKR_OK != error) {
  1929. return error;
  1930. }
  1931. if (!isEncrypt) {
  1932. error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
  1933. &outputBuffer);
  1934. }
  1935. }
  1936. return error;
  1937. }
  1938. /*
  1939. * NSSCKFWSession_GetMDSession
  1940. *
  1941. */
  1942. NSS_IMPLEMENT NSSCKMDSession *
  1943. NSSCKFWSession_GetMDSession(
  1944. NSSCKFWSession *fwSession)
  1945. {
  1946. #ifdef DEBUG
  1947. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  1948. return (NSSCKMDSession *)NULL;
  1949. }
  1950. #endif /* DEBUG */
  1951. return nssCKFWSession_GetMDSession(fwSession);
  1952. }
  1953. /*
  1954. * NSSCKFWSession_GetArena
  1955. *
  1956. */
  1957. NSS_IMPLEMENT NSSArena *
  1958. NSSCKFWSession_GetArena(
  1959. NSSCKFWSession *fwSession,
  1960. CK_RV *pError)
  1961. {
  1962. #ifdef DEBUG
  1963. if (!pError) {
  1964. return (NSSArena *)NULL;
  1965. }
  1966. *pError = nssCKFWSession_verifyPointer(fwSession);
  1967. if (CKR_OK != *pError) {
  1968. return (NSSArena *)NULL;
  1969. }
  1970. #endif /* DEBUG */
  1971. return nssCKFWSession_GetArena(fwSession, pError);
  1972. }
  1973. /*
  1974. * NSSCKFWSession_CallNotification
  1975. *
  1976. */
  1977. NSS_IMPLEMENT CK_RV
  1978. NSSCKFWSession_CallNotification(
  1979. NSSCKFWSession *fwSession,
  1980. CK_NOTIFICATION event)
  1981. {
  1982. #ifdef DEBUG
  1983. CK_RV error = CKR_OK;
  1984. error = nssCKFWSession_verifyPointer(fwSession);
  1985. if (CKR_OK != error) {
  1986. return error;
  1987. }
  1988. #endif /* DEBUG */
  1989. return nssCKFWSession_CallNotification(fwSession, event);
  1990. }
  1991. /*
  1992. * NSSCKFWSession_IsRWSession
  1993. *
  1994. */
  1995. NSS_IMPLEMENT CK_BBOOL
  1996. NSSCKFWSession_IsRWSession(
  1997. NSSCKFWSession *fwSession)
  1998. {
  1999. #ifdef DEBUG
  2000. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  2001. return CK_FALSE;
  2002. }
  2003. #endif /* DEBUG */
  2004. return nssCKFWSession_IsRWSession(fwSession);
  2005. }
  2006. /*
  2007. * NSSCKFWSession_IsSO
  2008. *
  2009. */
  2010. NSS_IMPLEMENT CK_BBOOL
  2011. NSSCKFWSession_IsSO(
  2012. NSSCKFWSession *fwSession)
  2013. {
  2014. #ifdef DEBUG
  2015. if (CKR_OK != nssCKFWSession_verifyPointer(fwSession)) {
  2016. return CK_FALSE;
  2017. }
  2018. #endif /* DEBUG */
  2019. return nssCKFWSession_IsSO(fwSession);
  2020. }
  2021. NSS_IMPLEMENT NSSCKFWCryptoOperation *
  2022. NSSCKFWSession_GetCurrentCryptoOperation(
  2023. NSSCKFWSession *fwSession,
  2024. NSSCKFWCryptoOperationState state)
  2025. {
  2026. #ifdef DEBUG
  2027. CK_RV error = CKR_OK;
  2028. error = nssCKFWSession_verifyPointer(fwSession);
  2029. if (CKR_OK != error) {
  2030. return (NSSCKFWCryptoOperation *)NULL;
  2031. }
  2032. if (state >= NSSCKFWCryptoOperationState_Max) {
  2033. return (NSSCKFWCryptoOperation *)NULL;
  2034. }
  2035. #endif /* DEBUG */
  2036. return nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
  2037. }
  2038. /*
  2039. * NSSCKFWSession_GetFWSlot
  2040. *
  2041. */
  2042. NSS_IMPLEMENT NSSCKFWSlot *
  2043. NSSCKFWSession_GetFWSlot(
  2044. NSSCKFWSession *fwSession)
  2045. {
  2046. return nssCKFWSession_GetFWSlot(fwSession);
  2047. }