fortpk11.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:130k
源码类别:

CA认证

开发平台:

WINDOWS

  1.       PORT_Memcpy (pInfo, &mechanisms[i].domestic, sizeof (CK_MECHANISM_INFO));
  2.       FORT11_RETURN (CKR_OK);
  3.     }
  4.   }
  5.   FORT11_RETURN (CKR_MECHANISM_INVALID);
  6. }
  7. /* C_InitToken initializes a token. */
  8. PR_PUBLIC_API(CK_RV) C_InitToken(CK_SLOT_ID  slotID,
  9.  CK_CHAR_PTR pPin,
  10.  CK_ULONG    ulPinLen,
  11.  CK_CHAR_PTR pLabel) {
  12.   /* For functions that don't access globals, we don't have to worry about the
  13.    * stack.
  14.    */
  15.   return CKR_FUNCTION_NOT_SUPPORTED;
  16. }
  17. /* C_InitPIN initializes the normal user's PIN. */
  18. PR_PUBLIC_API(CK_RV) C_InitPIN(CK_SESSION_HANDLE hSession,
  19.        CK_CHAR_PTR       pPin, 
  20.        CK_ULONG          ulPinLen) {
  21.   /* For functions that don't access globals, we don't have to worry about the
  22.    * stack.
  23.    */
  24.   return CKR_FUNCTION_NOT_SUPPORTED;
  25. }
  26. /* C_SetPIN modifies the PIN of user that is currently logged in. */
  27. /* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
  28. PR_PUBLIC_API(CK_RV) C_SetPIN(CK_SESSION_HANDLE hSession, 
  29.       CK_CHAR_PTR       pOldPin,
  30.       CK_ULONG          ulOldLen, 
  31.       CK_CHAR_PTR       pNewPin, 
  32.       CK_ULONG          ulNewLen) {
  33.   FORT11_ENTER()
  34. #ifndef SWFORT
  35.   CI_PIN       ciOldPin, ciNewPin;
  36. #endif
  37.   PK11Session *session;
  38.   PK11Slot    *slot;
  39.   int          rv;
  40.   session = fort11_SessionFromHandle (hSession, PR_FALSE);
  41.   slot = fort11_SlotFromSession (session);
  42.   SLOT_OK(slot->slotID)
  43.   if (session == NULL) {
  44.       session = fort11_SessionFromHandle (hSession, PR_TRUE);
  45.       fort11_TokenRemoved(slot, session);
  46.       FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  47.   }
  48.   rv = MACI_Select (fortezzaSockets[slot->slotID-1].maciSession, slot->slotID);
  49.   CARD_OK (rv)
  50.   
  51.   if (slot->needLogin && session->info.state != CKS_RW_USER_FUNCTIONS) {
  52.     fort11_FreeSession (session);
  53.     FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  54.   }
  55.   fort11_FreeSession (session);
  56.   if (ulNewLen > CI_PIN_SIZE || ulOldLen > CI_PIN_SIZE) 
  57.     FORT11_RETURN (CKR_PIN_LEN_RANGE);
  58. #ifndef SWFORT
  59.   fort11_convertToCIPin (ciOldPin,pOldPin, ulOldLen);
  60.   fort11_convertToCIPin (ciNewPin,pNewPin, ulNewLen);
  61.   rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession, 
  62.        CI_USER_PIN, ciOldPin, ciNewPin);
  63. #else
  64.   rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession, 
  65.        CI_USER_PIN,  pOldPin, pNewPin);
  66. #endif
  67.   if (rv != CI_OK) {
  68.     switch (rv) {
  69.     case CI_FAIL:
  70.       FORT11_RETURN (CKR_PIN_INCORRECT);
  71.     default:
  72.       FORT11_RETURN (CKR_DEVICE_ERROR);
  73.     }
  74.   } 
  75.   FORT11_RETURN (CKR_OK);
  76. }
  77. /* C_OpenSession opens a session between an application and a token. */
  78. PR_PUBLIC_API(CK_RV) C_OpenSession(CK_SLOT_ID            slotID, 
  79.    CK_FLAGS              flags,
  80.    CK_VOID_PTR           pApplication,
  81.    CK_NOTIFY             Notify,
  82.    CK_SESSION_HANDLE_PTR phSession) {
  83.   FORT11_ENTER()
  84.   PK11Slot          *slot;
  85.   CK_SESSION_HANDLE  sessionID;
  86.   PK11Session       *session;
  87.   FortezzaSocket    *socket;
  88.   SLOT_OK (slotID)
  89.   slot = &fort11_slot[slotID-1];
  90.   socket = &fortezzaSockets[slotID-1];
  91.   if (!socket->isOpen) {
  92.       if (InitSocket(socket, slotID) != SOCKET_SUCCESS) {
  93.   FORT11_RETURN (CKR_TOKEN_NOT_PRESENT);
  94.       }
  95.   }
  96.   session = fort11_NewSession (slotID, Notify, pApplication, 
  97.        flags | CKF_SERIAL_SESSION);
  98.   if (session == NULL) FORT11_RETURN (CKR_HOST_MEMORY);
  99.   FMUTEX_Lock(slot->sessionLock);
  100.   slot->sessionIDCount += ADD_NEXT_SESS_ID;
  101.   sessionID = slot->sessionIDCount;
  102.   fort11_update_state (slot, session);
  103.   pk11queue_add (session, sessionID, slot->head, SESSION_HASH_SIZE);
  104.   slot->sessionCount++;
  105.   if (session->info.flags & CKF_RW_SESSION) {
  106.     slot->rwSessionCount++;
  107.   }
  108.   session->handle = sessionID;
  109.   session->info.ulDeviceError = 0;
  110.   FMUTEX_Unlock(slot->sessionLock);
  111.   
  112.   *phSession = sessionID;
  113.   FORT11_RETURN (CKR_OK);
  114. }
  115. /* C_CloseSession closes a session between an application and a token. */
  116. PR_PUBLIC_API(CK_RV) C_CloseSession(CK_SESSION_HANDLE hSession) {
  117.   FORT11_ENTER()
  118.   PK11Slot    *slot;
  119.   PK11Session *session;
  120.   
  121.   session = fort11_SessionFromHandle  (hSession, PR_TRUE);
  122.   slot = fort11_SlotFromSessionHandle (hSession);
  123.   if (session == NULL) {
  124.       FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  125.   }
  126.   
  127.   FMUTEX_Lock(slot->sessionLock);
  128.   if (session->next || session->prev) {
  129.     session->refCount--;
  130.     if (session->info.flags & CKF_RW_SESSION) {
  131.       slot->rwSessionCount--;
  132.     }
  133.     if (slot->sessionCount == 0) {
  134.       slot->isLoggedIn = PR_FALSE;
  135.       slot->password = NULL;
  136.     }
  137.   }
  138.   FMUTEX_Unlock(slot->sessionLock);
  139.   
  140.   fort11_FreeSession (session);
  141.   FORT11_RETURN (CKR_OK);
  142. }
  143. /* C_CloseAllSessions closes all sessions with a token. */
  144. PR_PUBLIC_API(CK_RV) C_CloseAllSessions (CK_SLOT_ID slotID) {
  145.   FORT11_ENTER()
  146.   PK11Slot *slot;
  147.   PK11Session *session;
  148.   int i;
  149.   
  150.   
  151.   slot = fort11_SlotFromID(slotID);
  152.   if (slot == NULL) FORT11_RETURN (CKR_SLOT_ID_INVALID);
  153.   
  154.   /* first log out the card */
  155.   FMUTEX_Lock(slot->sessionLock);
  156.   slot->isLoggedIn = PR_FALSE;
  157.   slot->password = NULL;
  158.   FMUTEX_Unlock(slot->sessionLock);
  159.   
  160.   /* now close all the current sessions */
  161.   /* NOTE: If you try to open new sessions before C_CloseAllSessions
  162.    * completes, some of those new sessions may or may not be closed by
  163.    * C_CloseAllSessions... but any session running when this code starts
  164.    * will guarrenteed be close, and no session will be partially closed */
  165.   for (i=0; i < SESSION_HASH_SIZE; i++) {
  166.     do {
  167.       FMUTEX_Lock(slot->sessionLock);
  168.       session = slot->head[i];
  169.       /* hand deque */
  170.       /* this duplicates much of C_close session functionality, but because
  171.        * we know that we are freeing all the sessions, we and do some
  172.        * more efficient processing */
  173.       if (session) {
  174. slot->head[i] = session->next;
  175. if (session->next) session->next->prev = NULL;
  176. session->next = session->prev = NULL;
  177. slot->sessionCount--;
  178. if (session->info.flags & CKF_RW_SESSION) {
  179.   slot->rwSessionCount--;
  180. }
  181.       }
  182.       FMUTEX_Unlock(slot->sessionLock);
  183.       if (session) fort11_FreeSession(session);
  184.     } while (session != NULL);
  185.   }
  186.   FORT11_RETURN (CKR_OK);
  187. }
  188. /* C_GetSessionInfo obtains information about the session. */
  189. PR_PUBLIC_API(CK_RV) C_GetSessionInfo(CK_SESSION_HANDLE   hSession,
  190.       CK_SESSION_INFO_PTR pInfo) {
  191.     FORT11_ENTER()
  192.     PK11Session    *session;
  193.     PK11Slot       *slot;
  194.     CI_STATE        cardState;
  195.     FortezzaSocket *socket;
  196.     int             ciRV;
  197.     
  198.     session = fort11_SessionFromHandle (hSession, PR_FALSE);
  199.     slot    = fort11_SlotFromSessionHandle(hSession);
  200.     socket  = &fortezzaSockets[slot->slotID-1];
  201.     if (session == NULL) {
  202.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  203. fort11_TokenRemoved(slot, session);
  204. fort11_FreeSession(session);
  205. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  206.     }
  207.     PORT_Memcpy (pInfo, &session->info, sizeof (CK_SESSION_INFO));
  208.     fort11_FreeSession(session);
  209.     ciRV = MACI_Select(socket->maciSession, slot->slotID);
  210.     CARD_OK(ciRV)
  211.     ciRV = MACI_GetState(socket->maciSession, &cardState);
  212.     CARD_OK(ciRV)
  213.     if (socket->isLoggedIn) { 
  214.         switch (cardState) {
  215. case CI_POWER_UP:
  216. case CI_UNINITIALIZED:
  217. case CI_INITIALIZED:
  218. case CI_SSO_INITIALIZED:
  219. case CI_LAW_INITIALIZED:
  220. case CI_USER_INITIALIZED:
  221.   pInfo->state = CKS_RO_PUBLIC_SESSION;
  222.   break;
  223. case CI_STANDBY:
  224. case CI_READY:
  225.   pInfo->state = CKS_RO_USER_FUNCTIONS;
  226.   break;
  227. default:
  228.   pInfo->state = CKS_RO_PUBLIC_SESSION;
  229.   break;
  230. }
  231.     } else {
  232.         pInfo->state = CKS_RO_PUBLIC_SESSION;
  233.     }
  234.     FORT11_RETURN (CKR_OK);
  235. }
  236. /* C_Login logs a user into a token. */
  237. PR_PUBLIC_API(CK_RV) C_Login(CK_SESSION_HANDLE hSession,
  238.      CK_USER_TYPE      userType,
  239.      CK_CHAR_PTR       pPin, 
  240.      CK_ULONG          ulPinLen) {
  241.   FORT11_ENTER()
  242.   PK11Slot    *slot;
  243.   PK11Session *session;
  244. #ifndef SWFORT
  245.   CI_PIN       ciPin;
  246. #endif
  247.   int          rv, ciUserType;
  248.   slot = fort11_SlotFromSessionHandle (hSession);
  249.   session = fort11_SessionFromHandle(hSession, PR_FALSE);
  250.   if (session == NULL) {
  251.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  252. fort11_TokenRemoved(slot, session);
  253. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  254.   }
  255.   fort11_FreeSession(session);
  256.   if (slot->isLoggedIn) FORT11_RETURN (CKR_USER_ALREADY_LOGGED_IN);
  257.   slot->ssoLoggedIn = PR_FALSE;
  258. #ifndef SWFORT
  259.   if (ulPinLen > CI_PIN_SIZE) FORT11_RETURN (CKR_PIN_LEN_RANGE);
  260.   fort11_convertToCIPin (ciPin, pPin, ulPinLen);
  261. #endif
  262.   switch (userType) {
  263.   case CKU_SO:
  264.     ciUserType = CI_SSO_PIN;
  265.     break;
  266.   case CKU_USER:
  267.     ciUserType = CI_USER_PIN;
  268.     break;
  269.   default:
  270.     FORT11_RETURN (CKR_USER_TYPE_INVALID);
  271.   }
  272.   
  273. #ifndef SWFORT
  274.   rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, ciPin);
  275. #else
  276.   rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, pPin);
  277. #endif
  278.   switch (rv) {
  279.   case SOCKET_SUCCESS:
  280.     break;
  281.   case CI_FAIL:
  282.     FORT11_RETURN (CKR_PIN_INCORRECT);
  283.   default:
  284.     FORT11_RETURN (CKR_DEVICE_ERROR);
  285.   }
  286.   FMUTEX_Lock(slot->sessionLock);
  287.   slot->isLoggedIn = PR_TRUE;
  288.   if (userType == CKU_SO) {
  289.     slot->ssoLoggedIn = PR_TRUE;
  290.   }
  291.   FMUTEX_Unlock(slot->sessionLock);
  292.   
  293.   fort11_update_all_states(slot);
  294.   FORT11_RETURN (CKR_OK);
  295. }
  296. /* C_Logout logs a user out from a token. */
  297. PR_PUBLIC_API(CK_RV) C_Logout(CK_SESSION_HANDLE hSession) {
  298.     FORT11_ENTER()
  299.     PK11Slot    *slot    = fort11_SlotFromSessionHandle(hSession);
  300.     PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
  301.     
  302.     if (session == NULL) {
  303.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  304. fort11_TokenRemoved(slot, session);
  305. fort11_FreeSession(session);
  306. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  307.     }
  308.     if (!slot->isLoggedIn)
  309.       FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  310.     
  311.     FMUTEX_Lock(slot->sessionLock);
  312.     slot->isLoggedIn  = PR_FALSE;
  313.     slot->ssoLoggedIn = PR_FALSE;
  314.     slot->password    = NULL;
  315.     LogoutFromSocket  (&fortezzaSockets[slot->slotID-1]);
  316.     FMUTEX_Unlock(slot->sessionLock);
  317.       
  318.     fort11_update_all_states(slot);
  319.     FORT11_RETURN (CKR_OK);
  320. }
  321. /* C_CreateObject creates a new object. */
  322. PR_PUBLIC_API(CK_RV) C_CreateObject(CK_SESSION_HANDLE    hSession,
  323.     CK_ATTRIBUTE_PTR     pTemplate, 
  324.     CK_ULONG             ulCount, 
  325.     CK_OBJECT_HANDLE_PTR phObject) {
  326.   /* For functions that don't access globals, we don't have to worry about the
  327.    * stack.
  328.    */
  329.   return CKR_FUNCTION_NOT_SUPPORTED;
  330. }
  331. /* C_CopyObject copies an object, creating a new object for the copy. */
  332. PR_PUBLIC_API(CK_RV) C_CopyObject(CK_SESSION_HANDLE    hSession,
  333.   CK_OBJECT_HANDLE     hObject, 
  334.   CK_ATTRIBUTE_PTR     pTemplate, 
  335.   CK_ULONG             ulCount,
  336.   CK_OBJECT_HANDLE_PTR phNewObject) {
  337.   /* For functions that don't access globals, we don't have to worry about the
  338.    * stack.
  339.    */
  340.   return CKR_FUNCTION_NOT_SUPPORTED;
  341. }
  342. /* C_DestroyObject destroys an object. */
  343. PR_PUBLIC_API(CK_RV) C_DestroyObject(CK_SESSION_HANDLE hSession,
  344.      CK_OBJECT_HANDLE  hObject) {
  345.     FORT11_ENTER()
  346.     PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
  347.     PK11Session *session;
  348.     PK11Object *object;
  349.     PK11FreeStatus status;
  350.     /*
  351.      * This whole block just makes sure we really can destroy the
  352.      * requested object.
  353.      */
  354.     session = fort11_SessionFromHandle(hSession, PR_FALSE);
  355.     if (session == NULL) {
  356.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  357. fort11_TokenRemoved(slot, session);
  358. fort11_FreeSession(session);
  359.         FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  360.     }
  361.     object = fort11_ObjectFromHandle(hObject,session);
  362.     if (object == NULL) {
  363. fort11_FreeSession(session);
  364. FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID);
  365.     }
  366.     /* don't destroy a private object if we aren't logged in */
  367.     if ((!slot->isLoggedIn) && (slot->needLogin) &&
  368. (fort11_isTrue(object,CKA_PRIVATE))) {
  369. fort11_FreeSession(session);
  370. fort11_FreeObject(object);
  371. FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  372.     }
  373.     /* don't destroy a token object if we aren't in a rw session */
  374.     if (((session->info.flags & CKF_RW_SESSION) == 0) &&
  375. (fort11_isTrue(object,CKA_TOKEN))) {
  376. fort11_FreeSession(session);
  377. fort11_FreeObject(object);
  378. FORT11_RETURN (CKR_SESSION_READ_ONLY);
  379.     }
  380.     /* ACTUALLY WE NEED TO DEAL WITH TOKEN OBJECTS AS WELL */
  381.     FMUTEX_Lock(session->objectLock);
  382.     fort11_DeleteObject(session,object);
  383.     FMUTEX_Unlock(session->objectLock);
  384.     fort11_FreeSession(session);
  385.     /*
  386.      * get some indication if the object is destroyed. Note: this is not
  387.      * 100%. Someone may have an object reference outstanding (though that
  388.      * should not be the case by here. Also now that the object is "half"
  389.      * destroyed. Our internal representation is destroyed, but it is still
  390.      * in the data base.
  391.      */
  392.     status = fort11_FreeObject(object);
  393.     FORT11_RETURN ((status != PK11_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR);
  394. }
  395. /* C_GetObjectSize gets the size of an object in bytes. */
  396. PR_PUBLIC_API(CK_RV) C_GetObjectSize(CK_SESSION_HANDLE hSession,
  397.      CK_OBJECT_HANDLE  hObject, 
  398.      CK_ULONG_PTR      pulSize) {
  399. /* For functions that don't access globals, we don't have to worry about the
  400.      * stack.
  401.      */
  402.     *pulSize = 0;
  403.     return CKR_OK;
  404. }
  405. /* C_GetAttributeValue obtains the value of one or more object attributes. */
  406. PR_PUBLIC_API(CK_RV) C_GetAttributeValue(CK_SESSION_HANDLE hSession,
  407.  CK_OBJECT_HANDLE  hObject,
  408.  CK_ATTRIBUTE_PTR  pTemplate,
  409.  CK_ULONG          ulCount) {
  410.     FORT11_ENTER()
  411.     PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
  412.     PK11Session *session;
  413.     PK11Object *object;
  414.     PK11Attribute *attribute;
  415.     PRBool sensitive;
  416.     int i;
  417.     /*
  418.      * make sure we're allowed
  419.      */
  420.     session = fort11_SessionFromHandle(hSession, PR_FALSE);
  421.     if (session == NULL) {
  422.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  423. fort11_TokenRemoved(slot, session);
  424. fort11_FreeSession(session);
  425.         FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  426.     }
  427.     object = fort11_ObjectFromHandle(hObject,session);
  428.     fort11_FreeSession(session);
  429.     if (object == NULL) {
  430. FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID);
  431.     }
  432.     /* don't read a private object if we aren't logged in */
  433.     if ((!slot->isLoggedIn) && (slot->needLogin) &&
  434. (fort11_isTrue(object,CKA_PRIVATE))) {
  435. fort11_FreeObject(object);
  436. FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  437.     }
  438.     sensitive = fort11_isTrue(object,CKA_SENSITIVE);
  439.     for (i=0; i <  (int)ulCount; i++) {
  440. /* Make sure that this attribute is retrievable */
  441. if (sensitive && fort11_isSensitive(pTemplate[i].type,object->objclass)) {
  442.     fort11_FreeObject(object);
  443.     FORT11_RETURN (CKR_ATTRIBUTE_SENSITIVE);
  444. }
  445. attribute = fort11_FindAttribute(object,pTemplate[i].type);
  446. if (attribute == NULL) {
  447.     fort11_FreeObject(object);
  448.     FORT11_RETURN (CKR_ATTRIBUTE_TYPE_INVALID);
  449. }
  450. if (pTemplate[i].pValue != NULL) {
  451.     PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue,
  452. attribute->attrib.ulValueLen);
  453. }
  454. pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
  455. fort11_FreeAttribute(attribute);
  456.     }
  457.     fort11_FreeObject(object);
  458.     FORT11_RETURN (CKR_OK);
  459. }
  460. /* C_SetAttributeValue modifies the value of one or more object attributes */
  461. PR_PUBLIC_API(CK_RV) C_SetAttributeValue (CK_SESSION_HANDLE hSession,
  462.   CK_OBJECT_HANDLE  hObject,
  463.   CK_ATTRIBUTE_PTR  pTemplate,
  464.   CK_ULONG          ulCount) {
  465.   /* For functions that don't access globals, we don't have to worry about the
  466.    * stack.
  467.    */
  468.   return CKR_FUNCTION_NOT_SUPPORTED;
  469. }
  470. /* C_FindObjectsInit initializes a search for token and session objects 
  471.  * that match a template. */
  472. PR_PUBLIC_API(CK_RV) C_FindObjectsInit(CK_SESSION_HANDLE hSession,
  473.        CK_ATTRIBUTE_PTR  pTemplate,
  474.        CK_ULONG          ulCount) {
  475.     FORT11_ENTER()
  476.     PK11Slot              *slot = fort11_SlotFromSessionHandle(hSession);
  477.     PK11Session           *session;
  478.     PK11ObjectListElement *objectList = NULL;
  479.     PK11ObjectListElement *olp;
  480.     PK11SearchResults     *search, *freeSearch;
  481.     FortezzaSocket        *currSocket;
  482.     int                    rv, count, i;
  483.     if (slot == NULL) {
  484. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  485.     }
  486.     
  487.     if ((!slot->isLoggedIn) && (slot->needLogin)) 
  488.         FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  489.     session = fort11_SessionFromHandle(hSession, PR_FALSE);
  490.     if (session == NULL) {
  491.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  492. fort11_TokenRemoved(slot, session);
  493. fort11_FreeSession(session);
  494.         FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  495.     }
  496.     currSocket = &fortezzaSockets[slot->slotID-1];
  497.     if (currSocket->personalityList == NULL) {
  498.         rv = FetchPersonalityList(currSocket);
  499. if (rv != SOCKET_SUCCESS) {
  500.     fort11_FreeSession(session);
  501.     FORT11_RETURN (CKR_DEVICE_ERROR);
  502. }
  503. rv = fort11_BuildCertObjects(currSocket, slot, session);
  504. if (rv != CKR_OK) {
  505.     fort11_FreeSession(session);
  506.     FORT11_RETURN (rv);
  507. }
  508.     }
  509.     rv = fort11_searchObjectList(&objectList, slot->tokObjects, 
  510. slot->objectLock, pTemplate, ulCount);
  511.     if (rv != CKR_OK) {
  512.       fort11_FreeObjectList(objectList);
  513.       fort11_FreeSession(session);
  514.       FORT11_RETURN (rv);
  515.     }
  516.     /*copy list to session*/
  517.     count = 0;
  518.     for(olp = objectList; olp != NULL; olp = olp->next) {
  519.       count++;
  520.     } 
  521.     search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults));
  522.     if (search != NULL) {
  523. search->handles = (CK_OBJECT_HANDLE *)
  524. PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count);
  525. if (search->handles != NULL) {
  526.     for (i=0; i < count; i++) {
  527. search->handles[i] = objectList->object->handle;
  528. objectList = fort11_FreeObjectListElement(objectList);
  529.     }
  530. } else {
  531.     PORT_Free(search);
  532.     search = NULL;
  533. }
  534.     }
  535.     if (search == NULL) {
  536. fort11_FreeObjectList(objectList);
  537. fort11_FreeSession(session);
  538. FORT11_RETURN (CKR_OK);
  539.     }
  540.     /* store the search info */
  541.     search->index = 0;
  542.     search->size = count;
  543.     if ((freeSearch = session->search) != NULL) {
  544. session->search = NULL;
  545. fort11_FreeSearch(freeSearch);
  546.     }
  547.     session->search = search;
  548.     fort11_FreeSession(session);
  549.     FORT11_RETURN (CKR_OK);
  550. }
  551. /* C_FindObjects continues a search for token and session objects 
  552.  * that match a template, obtaining additional object handles. */
  553. PR_PUBLIC_API(CK_RV) C_FindObjects(CK_SESSION_HANDLE    hSession,
  554.    CK_OBJECT_HANDLE_PTR phObject,
  555.    CK_ULONG             ulMaxObjectCount,
  556.    CK_ULONG_PTR         pulObjectCount) {
  557.     FORT11_ENTER()
  558.     PK11Session       *session;
  559.     PK11SearchResults *search;
  560.     PK11Slot          *slot;
  561.     int transfer;
  562.     unsigned long left;
  563.     *pulObjectCount = 0;
  564.     session = fort11_SessionFromHandle(hSession,PR_FALSE);
  565.     slot    = fort11_SlotFromSessionHandle(hSession);
  566.     if (session == NULL) {
  567.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  568. fort11_TokenRemoved(slot, session);
  569. fort11_FreeSession(session);
  570. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  571.     }
  572.     if (session->search == NULL) {
  573. fort11_FreeSession(session);
  574. FORT11_RETURN (CKR_OK);
  575.     }
  576.     search = session->search;
  577.     left = session->search->size - session->search->index;
  578.     transfer = (ulMaxObjectCount > left) ? left : ulMaxObjectCount;
  579.     PORT_Memcpy(phObject,&search->handles[search->index],
  580. transfer*sizeof(CK_OBJECT_HANDLE_PTR));
  581.     search->index += transfer;
  582.     if (search->index == search->size) {
  583. session->search = NULL;
  584. fort11_FreeSearch(search);
  585.     }
  586.     fort11_FreeSession(session);
  587.     *pulObjectCount = transfer;
  588.     FORT11_RETURN (CKR_OK);
  589. }
  590. /* C_FindObjectsFinal finishes a search for token and session objects. */
  591. PR_PUBLIC_API(CK_RV) C_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
  592.     FORT11_ENTER()
  593.     PK11Session       *session;
  594.     PK11SearchResults *search;
  595.     PK11Slot          *slot;
  596.     session = fort11_SessionFromHandle(hSession, PR_FALSE);
  597.     slot    = fort11_SlotFromSessionHandle(hSession);
  598.     if (session == NULL) {
  599.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  600. fort11_TokenRemoved(slot, session);
  601. fort11_FreeSession(session);
  602. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  603.     }
  604.     search = session->search;
  605.     session->search = NULL;
  606.     if (search == NULL) {
  607. fort11_FreeSession(session);
  608. FORT11_RETURN (CKR_OK);
  609.     }
  610.     fort11_FreeSearch(search);
  611.     /* UnloadPersonalityList(&fortezzaSockets[session->slot->slotID-1]); */
  612.     fort11_FreeSession(session);
  613.     FORT11_RETURN (CKR_OK);
  614. }
  615. /* C_EncryptInit initializes an encryption operation. */
  616. PR_PUBLIC_API(CK_RV) C_EncryptInit(CK_SESSION_HANDLE hSession,
  617.    CK_MECHANISM_PTR  pMechanism, 
  618.    CK_OBJECT_HANDLE  hKey) {
  619.     FORT11_ENTER()
  620.     PK11Session     *session   = fort11_SessionFromHandle(hSession, PR_FALSE);
  621.     PK11Slot        *slot      = fort11_SlotFromSessionHandle(hSession);
  622.     PK11Object      *keyObject;
  623.     FortezzaSocket  *socket    = &fortezzaSockets[slot->slotID-1];
  624.     FortezzaContext *context;
  625.     HSESSION         hs        = socket->maciSession;
  626.     FortezzaKey     *fortezzaKey;
  627.     CI_IV            fortezzaIV;
  628.     int              ciRV, registerIndex;
  629.     
  630.     if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) {
  631.         if (session) {
  632.     fort11_FreeSession(session);
  633. }
  634.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  635.     }
  636.     if (session == NULL) {
  637.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  638. fort11_TokenRemoved(slot, session);
  639. fort11_FreeSession(session);
  640. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  641.     }
  642.     
  643.     keyObject = fort11_ObjectFromHandle (hKey, session);
  644.     if (keyObject == NULL) {
  645.         fort11_FreeSession(session);
  646.         FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  647.     }
  648.     ciRV = MACI_Select (hs, slot->slotID);
  649.     if (ciRV != CI_OK) {
  650.         fort11_FreeSession(session);
  651. FORT11_RETURN (CKR_DEVICE_ERROR);
  652.     }
  653.     ciRV = MACI_SetMode(hs, CI_ENCRYPT_TYPE, CI_CBC64_MODE);
  654.     if (ciRV != CI_OK) {
  655.         fort11_FreeSession(session);
  656. FORT11_RETURN (CKR_DEVICE_ERROR);
  657.     }
  658.     /*Load the correct key into a key register*/
  659.     fortezzaKey = (FortezzaKey*)keyObject->objectInfo;
  660.     fort11_FreeObject (keyObject);
  661.     if (fortezzaKey == NULL) {
  662.         fort11_FreeSession(session);
  663.         FORT11_RETURN (CKR_GENERAL_ERROR);
  664.     }
  665.     if (fortezzaKey->keyRegister == KeyNotLoaded) {
  666.         registerIndex = LoadKeyIntoRegister (fortezzaKey);
  667.     } else {
  668.         registerIndex = fortezzaKey->keyRegister;
  669.     }
  670.     if (registerIndex == KeyNotLoaded) {
  671.         fort11_FreeSession(session);
  672.         FORT11_RETURN (CKR_DEVICE_ERROR);
  673.     }
  674.     ciRV = MACI_SetKey (hs,registerIndex);
  675.     if (ciRV != CI_OK) {
  676.         fort11_FreeSession(session);
  677. FORT11_RETURN (CKR_DEVICE_ERROR);
  678.     }
  679.     ciRV = MACI_GenerateIV(hs, fortezzaIV);
  680.     if (ciRV != CI_OK) {
  681.         fort11_FreeSession(session);
  682. FORT11_RETURN (CKR_DEVICE_ERROR);
  683.     }
  684.     context = &session->fortezzaContext;
  685.     InitContext(context, socket, hKey);
  686.     ciRV = SaveState(context, fortezzaIV, session, fortezzaKey, 
  687.      CI_ENCRYPT_EXT_TYPE, pMechanism->mechanism);
  688.     if (ciRV != SOCKET_SUCCESS) {
  689.         fort11_FreeSession(session);
  690.         FORT11_RETURN (CKR_GENERAL_ERROR);
  691.     }
  692.     if (pMechanism->pParameter != NULL && 
  693. pMechanism->ulParameterLen >= sizeof(CI_IV)) {
  694.         PORT_Memcpy (pMechanism->pParameter, fortezzaIV, sizeof(CI_IV));
  695.     }
  696.     InitCryptoOperation(context, Encrypt);
  697.     fort11_FreeSession(session);
  698.     FORT11_RETURN (CKR_OK);
  699. }
  700. /* C_Encrypt encrypts single-part data. */
  701. PR_PUBLIC_API(CK_RV) C_Encrypt (CK_SESSION_HANDLE hSession, 
  702. CK_BYTE_PTR       pData,
  703. CK_ULONG          ulDataLen, 
  704. CK_BYTE_PTR       pEncryptedData,
  705. CK_ULONG_PTR      pulEncryptedDataLen) {
  706.     FORT11_ENTER()
  707.     PK11Session     *session = fort11_SessionFromHandle (hSession, PR_FALSE);
  708.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  709.     FortezzaSocket  *socket  = &fortezzaSockets[slot->slotID-1];
  710.     FortezzaContext *context;
  711.     HSESSION         hs;
  712.     CK_RV            rv;
  713.     
  714.     if (session == NULL) {
  715.         session = fort11_SessionFromHandle (hSession , PR_TRUE);
  716. fort11_TokenRemoved(slot, session);
  717. fort11_FreeSession(session);
  718. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  719.     }
  720.     context = &session->fortezzaContext;
  721.     if (GetCryptoOperation(context) != Encrypt) {
  722.         fort11_FreeSession(session);
  723.         FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
  724.     }
  725.     *pulEncryptedDataLen = ulDataLen;
  726.     if (pEncryptedData == NULL) {
  727. fort11_FreeSession(session);
  728. FORT11_RETURN (CKR_OK);
  729.     }
  730.     hs = socket->maciSession;
  731.     FMUTEX_Lock(socket->registersLock);
  732.     MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
  733.     rv = EncryptData (context, pData, ulDataLen, 
  734.       pEncryptedData, *pulEncryptedDataLen);
  735.     MACI_Unlock(hs);
  736.     FMUTEX_Unlock(socket->registersLock);
  737.     if (rv != SOCKET_SUCCESS) {
  738.         fort11_FreeSession(session);
  739.         FORT11_RETURN (CKR_GENERAL_ERROR);
  740.     }
  741.     EndCryptoOperation(context, Encrypt);
  742.     fort11_FreeSession(session);       
  743.     FORT11_RETURN (CKR_OK);
  744. }
  745. /* C_EncryptUpdate continues a multiple-part encryption operation. */
  746. PR_PUBLIC_API(CK_RV) C_EncryptUpdate(CK_SESSION_HANDLE hSession,
  747.      CK_BYTE_PTR       pPart, 
  748.      CK_ULONG          ulPartLen, 
  749.      CK_BYTE_PTR       pEncryptedPart,
  750.      CK_ULONG_PTR      pulEncryptedPartLen) {
  751.     FORT11_ENTER()
  752.     PK11Session     *session = fort11_SessionFromHandle(hSession,PR_FALSE);
  753.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  754.     FortezzaSocket  *socket  = &fortezzaSockets[slot->slotID-1];
  755.     FortezzaContext *context;
  756.     int              rv;
  757.     if (session == NULL) {
  758.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  759. fort11_TokenRemoved (slot, session);
  760. fort11_FreeSession(session);
  761. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  762.     }
  763.     context = &session->fortezzaContext;
  764.     
  765.     if (GetCryptoOperation(context) != Encrypt) {
  766.         fort11_FreeSession(session);
  767.         FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
  768.     }
  769.     
  770.     if (pEncryptedPart == NULL) {
  771.         *pulEncryptedPartLen = ulPartLen;
  772. fort11_FreeSession(session);
  773. FORT11_RETURN (CKR_OK);
  774.     }
  775.     if (*pulEncryptedPartLen < ulPartLen) {
  776.         fort11_FreeSession(session);
  777.         FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
  778.     }
  779.     *pulEncryptedPartLen = ulPartLen;
  780.     
  781.     FMUTEX_Lock(socket->registersLock);
  782.     MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG);
  783.     rv = EncryptData(context,pPart, ulPartLen, pEncryptedPart, 
  784.      *pulEncryptedPartLen);
  785.     MACI_Unlock(socket->maciSession);
  786.     FMUTEX_Unlock(socket->registersLock);
  787.     fort11_FreeSession(session);
  788.     if (rv != SOCKET_SUCCESS) {
  789.         FORT11_RETURN (CKR_GENERAL_ERROR);
  790.     }
  791.     FORT11_RETURN (CKR_OK);
  792. }
  793. /* C_EncryptFinal finishes a multiple-part encryption operation. */
  794. PR_PUBLIC_API(CK_RV) C_EncryptFinal(CK_SESSION_HANDLE hSession,
  795.     CK_BYTE_PTR       pLastEncryptedPart, 
  796.     CK_ULONG_PTR      pulLastEncryptedPartLen){
  797.     FORT11_ENTER()
  798.     PK11Session     *session = fort11_SessionFromHandle(hSession, PR_FALSE);
  799.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  800.     FortezzaContext *context;
  801.     int              rv;
  802.     if (session == NULL) {
  803.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  804. fort11_TokenRemoved(slot, session);
  805. fort11_FreeSession(session);
  806. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  807.     }
  808.   
  809.     context = &session->fortezzaContext;
  810.     rv = EndCryptoOperation(context, Encrypt);
  811.     fort11_FreeSession(session);
  812.     FORT11_RETURN (CKR_OK);
  813. }
  814. /* C_DecryptInit initializes a decryption operation. */
  815. PR_PUBLIC_API(CK_RV) C_DecryptInit( CK_SESSION_HANDLE hSession,
  816.     CK_MECHANISM_PTR  pMechanism, 
  817.     CK_OBJECT_HANDLE  hKey) {
  818.     FORT11_ENTER()
  819.     PK11Session     *session   = fort11_SessionFromHandle(hSession, PR_FALSE);
  820.     PK11Slot        *slot      = fort11_SlotFromSessionHandle(hSession);
  821.     PK11Object      *keyObject;
  822.     FortezzaSocket  *socket    = &fortezzaSockets[slot->slotID-1];
  823.     FortezzaContext *context;
  824.     HSESSION         hs        = socket->maciSession;
  825.     FortezzaKey     *fortezzaKey;
  826.     CI_IV            fortezzaIV;
  827.     int              ciRV, registerIndex;
  828.     if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) {
  829.         if (session) fort11_FreeSession(session);
  830.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  831.     }
  832.     if (session == NULL) {
  833.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  834. fort11_TokenRemoved(slot, session);
  835. fort11_FreeSession(session);
  836. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);        
  837.     }
  838.     keyObject = fort11_ObjectFromHandle (hKey, session);
  839.     if (keyObject == NULL) {
  840.         fort11_FreeSession(session);
  841.         FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  842.     }
  843.     fortezzaKey = (FortezzaKey*)keyObject->objectInfo;
  844.     fort11_FreeObject(keyObject);
  845.     if (fortezzaKey == NULL) {
  846.         fort11_FreeSession(session);
  847.         FORT11_RETURN (CKR_GENERAL_ERROR);
  848.     }
  849.     ciRV = MACI_Select (hs, slot->slotID);
  850.     if (ciRV != CI_OK) {
  851.         fort11_FreeSession(session);
  852. FORT11_RETURN (CKR_DEVICE_ERROR);
  853.     }
  854.     ciRV = MACI_SetMode(hs, CI_DECRYPT_TYPE, CI_CBC64_MODE);
  855.     if (ciRV != CI_OK) {
  856.         fort11_FreeSession(session);
  857. FORT11_RETURN (CKR_DEVICE_ERROR);
  858.     }
  859.     FMUTEX_Lock(socket->registersLock);
  860.     if (fortezzaKey->keyRegister == KeyNotLoaded) {
  861.         registerIndex = LoadKeyIntoRegister(fortezzaKey);
  862.     } else {
  863.         registerIndex = fortezzaKey->keyRegister;
  864.     }
  865.     if (registerIndex == KeyNotLoaded) {
  866.         FMUTEX_Unlock(socket->registersLock);
  867. FORT11_RETURN (CKR_DEVICE_ERROR);
  868.     }
  869.     if (pMechanism->pParameter == NULL ||
  870. pMechanism->ulParameterLen < sizeof (CI_IV)) {
  871.         FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID);
  872.     }
  873.     PORT_Memcpy (fortezzaIV, pMechanism->pParameter, sizeof(CI_IV));
  874.     ciRV = MACI_SetKey (hs, registerIndex);
  875.     if (ciRV != CI_OK) {
  876.         FMUTEX_Unlock(socket->registersLock);
  877.         fort11_FreeSession(session);
  878. FORT11_RETURN (CKR_DEVICE_ERROR);
  879.     }
  880.     ciRV = MACI_LoadIV (hs, fortezzaIV);
  881.     if (ciRV != CI_OK) {
  882.         FMUTEX_Unlock(socket->registersLock);
  883.         fort11_FreeSession(session);
  884. FORT11_RETURN (CKR_DEVICE_ERROR);
  885.     }
  886.     context = &session->fortezzaContext;
  887.     InitContext(context, socket, hKey);
  888.     ciRV = SaveState (context, fortezzaIV, session, fortezzaKey, 
  889.       CI_DECRYPT_EXT_TYPE, pMechanism->mechanism);
  890.     FMUTEX_Unlock(socket->registersLock);
  891.     if (ciRV != SOCKET_SUCCESS) {
  892.         FORT11_RETURN (CKR_GENERAL_ERROR);
  893.     }
  894.     InitCryptoOperation (context, Decrypt);
  895.     fort11_FreeSession (session);
  896.     FORT11_RETURN (CKR_OK);
  897. }
  898. /* C_Decrypt decrypts encrypted data in a single part. */
  899. PR_PUBLIC_API(CK_RV) C_Decrypt(CK_SESSION_HANDLE hSession,
  900.        CK_BYTE_PTR       pEncryptedData,
  901.        CK_ULONG          ulEncryptedDataLen,
  902.        CK_BYTE_PTR       pData, 
  903.        CK_ULONG_PTR      pulDataLen) {
  904.     FORT11_ENTER()
  905.     PK11Session     *session = fort11_SessionFromHandle (hSession, PR_FALSE);
  906.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  907.     FortezzaSocket  *socket  = &fortezzaSockets[slot->slotID-1];
  908.     FortezzaContext *context;
  909.     HSESSION         hs;
  910.     CK_RV            rv;
  911.     if (session == NULL) {
  912.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  913. fort11_TokenRemoved(slot, session);
  914. fort11_FreeSession(session);
  915. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  916.     }
  917.     context = &session->fortezzaContext;
  918.     if (GetCryptoOperation(context) != Decrypt) {
  919.         fort11_FreeSession(session);
  920.         FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
  921.     }
  922.     *pulDataLen = ulEncryptedDataLen;
  923.     if (pData == NULL) {
  924.         fort11_FreeSession(session);
  925. FORT11_RETURN (CKR_OK);
  926.     }
  927.     hs = socket->maciSession;
  928.     FMUTEX_Lock(socket->registersLock);
  929.     MACI_Lock(hs, CI_NULL_FLAG);
  930.     rv = DecryptData (context, pEncryptedData, ulEncryptedDataLen, 
  931.       pData, *pulDataLen);
  932.     MACI_Unlock(hs);
  933.     FMUTEX_Unlock(socket->registersLock);
  934.     if (rv != SOCKET_SUCCESS) {
  935.         fort11_FreeSession(session);
  936.         FORT11_RETURN (CKR_GENERAL_ERROR);
  937.     }
  938.     EndCryptoOperation (context, Decrypt);
  939.     fort11_FreeSession(session);
  940.     FORT11_RETURN (CKR_OK);
  941. }
  942. /* C_DecryptUpdate continues a multiple-part decryption operation. */
  943. PR_PUBLIC_API(CK_RV) C_DecryptUpdate(CK_SESSION_HANDLE hSession, 
  944.      CK_BYTE_PTR       pEncryptedPart, 
  945.      CK_ULONG          ulEncryptedPartLen,
  946.      CK_BYTE_PTR       pPart, 
  947.      CK_ULONG_PTR      pulPartLen) {
  948.     FORT11_ENTER()
  949.     PK11Session     *session = fort11_SessionFromHandle(hSession,PR_FALSE);
  950.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  951.     FortezzaSocket  *socket  = &fortezzaSockets[slot->slotID-1];
  952.     FortezzaContext *context;
  953.     HSESSION         hs;
  954.     int              rv;
  955.     if (session == NULL) {
  956.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  957. fort11_TokenRemoved (slot, session);
  958. fort11_FreeSession (session);
  959.         FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  960.     }
  961.     context = &session->fortezzaContext;
  962.     hs = socket->maciSession;
  963.     if (GetCryptoOperation(context) != Decrypt) {
  964.         fort11_FreeSession(session);
  965.         FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
  966.     }
  967.     if (pPart == NULL) {
  968.         *pulPartLen = ulEncryptedPartLen;
  969. fort11_FreeSession(session);
  970. FORT11_RETURN (CKR_OK);
  971.     }
  972.     *pulPartLen = ulEncryptedPartLen;
  973.     
  974.     FMUTEX_Lock(socket->registersLock);
  975.     MACI_Lock (hs, CI_NULL_FLAG);
  976.     rv = DecryptData (context, pEncryptedPart, ulEncryptedPartLen, pPart, 
  977.       *pulPartLen);
  978.     MACI_Unlock(hs);
  979.     FMUTEX_Unlock(socket->registersLock);
  980.     fort11_FreeSession(session);
  981.     if (rv != SOCKET_SUCCESS) {
  982.         FORT11_RETURN (CKR_GENERAL_ERROR);
  983.     }
  984.     FORT11_RETURN (CKR_OK);
  985. }
  986. /* C_DecryptFinal finishes a multiple-part decryption operation. */
  987. PR_PUBLIC_API(CK_RV) C_DecryptFinal(CK_SESSION_HANDLE hSession, 
  988.     CK_BYTE_PTR       pLastPart, 
  989.     CK_ULONG_PTR      pulLastPartLen) {
  990.     FORT11_ENTER()
  991.     PK11Session     *session = fort11_SessionFromHandle(hSession, PR_FALSE);
  992.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  993.     FortezzaContext *context;
  994.     if (session == NULL) {
  995.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  996. fort11_TokenRemoved (slot, session);
  997. fort11_FreeSession(session);
  998. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  999.     }
  1000.     context = &session->fortezzaContext;
  1001.     EndCryptoOperation (context, Decrypt);
  1002.     fort11_FreeSession(session);
  1003.     FORT11_RETURN (CKR_OK);
  1004. }
  1005. /*
  1006.  ************** Crypto Functions:     Digest (HASH)  ************************
  1007.  */
  1008. /* C_DigestInit initializes a message-digesting operation. */
  1009. PR_PUBLIC_API(CK_RV) C_DigestInit(CK_SESSION_HANDLE hSession,
  1010.   CK_MECHANISM_PTR  pMechanism) {
  1011.   /* For functions that don't access globals, we don't have to worry about the
  1012.    * stack.
  1013.    */
  1014.   return CKR_FUNCTION_NOT_SUPPORTED;
  1015. }
  1016. /* C_Digest digests data in a single part. */
  1017. PR_PUBLIC_API(CK_RV) C_Digest(CK_SESSION_HANDLE hSession, 
  1018.       CK_BYTE_PTR       pData, 
  1019.       CK_ULONG          ulDataLen, 
  1020.       CK_BYTE_PTR       pDigest,
  1021.       CK_ULONG_PTR      pulDigestLen) {
  1022.   /* For functions that don't access globals, we don't have to worry about the
  1023.    * stack.
  1024.    */
  1025.   return CKR_FUNCTION_NOT_SUPPORTED;
  1026. }
  1027. /* C_DigestUpdate continues a multiple-part message-digesting operation. */
  1028. PR_PUBLIC_API(CK_RV) C_DigestUpdate(CK_SESSION_HANDLE hSession,
  1029.     CK_BYTE_PTR       pPart,
  1030.     CK_ULONG          ulPartLen) {
  1031.   /* For functions that don't access globals, we don't have to worry about the
  1032.    * stack.
  1033.    */
  1034.   return CKR_FUNCTION_NOT_SUPPORTED;
  1035. }
  1036. /* C_DigestFinal finishes a multiple-part message-digesting operation. */
  1037. PR_PUBLIC_API(CK_RV) C_DigestFinal(CK_SESSION_HANDLE hSession,
  1038.    CK_BYTE_PTR       pDigest,
  1039.    CK_ULONG_PTR      pulDigestLen) {
  1040.   /* For functions that don't access globals, we don't have to worry about the
  1041.    * stack.
  1042.    */
  1043.   return CKR_FUNCTION_NOT_SUPPORTED;
  1044. }
  1045. /*
  1046.  ************** Crypto Functions:     Sign  ************************
  1047.  */
  1048. /* C_SignInit initializes a signature (private key encryption) operation,
  1049.  * where the signature is (will be) an appendix to the data, 
  1050.  * and plaintext cannot be recovered from the signature */
  1051. PR_PUBLIC_API(CK_RV) C_SignInit(CK_SESSION_HANDLE hSession,
  1052. CK_MECHANISM_PTR  pMechanism, 
  1053. CK_OBJECT_HANDLE  hKey) {
  1054.     FORT11_ENTER()
  1055.     PK11Session     *session   = fort11_SessionFromHandle (hSession, PR_FALSE);
  1056.     PK11Slot        *slot      = fort11_SlotFromSessionHandle(hSession);
  1057.     PK11Object      *keyObject;
  1058.     FortezzaSocket  *socket    = &fortezzaSockets[slot->slotID-1]; 
  1059.     FortezzaContext *context;
  1060.     PK11Attribute   *idAttribute;
  1061.     int              personalityIndex;
  1062.     HSESSION         hs = socket->maciSession;
  1063.     if (session == NULL) {
  1064.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  1065. fort11_TokenRemoved(slot, session);
  1066. fort11_FreeSession(session);
  1067. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1068.     }
  1069.     if (pMechanism->mechanism != CKM_DSA) {
  1070.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  1071.     }
  1072.     keyObject = fort11_ObjectFromHandle (hKey, session);
  1073.     if (keyObject == NULL) {
  1074.         fort11_FreeSession(session);
  1075.         FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  1076.     }
  1077.     context = &session->fortezzaContext;
  1078.     InitContext(context, socket, hKey);
  1079.     InitCryptoOperation (context, Sign);
  1080.     fort11_FreeSession(session);
  1081.     idAttribute = fort11_FindAttribute(keyObject, CKA_ID);
  1082.     fort11_FreeObject(keyObject);
  1083.     if (idAttribute == NULL) {
  1084.         FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  1085.     }
  1086.     personalityIndex = *(int*)(idAttribute->attrib.pValue);
  1087.     fort11_FreeAttribute(idAttribute);
  1088.     
  1089.     MACI_Select (hs, slot->slotID);
  1090.     if (MACI_SetPersonality (hs,personalityIndex) != CI_OK) {
  1091.         FORT11_RETURN (CKR_GENERAL_ERROR);
  1092.     }
  1093.     FORT11_RETURN (CKR_OK);
  1094. }
  1095. /* C_Sign signs (encrypts with private key) data in a single part,
  1096.  * where the signature is (will be) an appendix to the data, 
  1097.  * and plaintext cannot be recovered from the signature */
  1098. PR_PUBLIC_API(CK_RV) C_Sign(CK_SESSION_HANDLE hSession, 
  1099.     CK_BYTE_PTR       pData,
  1100.     CK_ULONG          ulDataLen,
  1101.     CK_BYTE_PTR       pSignature,
  1102.     CK_ULONG_PTR      pulSignatureLen) {
  1103.     FORT11_ENTER()
  1104.     PK11Session     *session   = fort11_SessionFromHandle(hSession, PR_FALSE);
  1105.     PK11Slot        *slot      = fort11_SlotFromSessionHandle(hSession);
  1106.     FortezzaContext *context;
  1107.     FortezzaSocket  *socket    = &fortezzaSockets[slot->slotID-1];
  1108.     HSESSION         hs        = socket->maciSession;
  1109.     PK11Object      *keyObject;
  1110.     PK11Attribute   *idAttribute;
  1111.     int              ciRV, personalityIndex;
  1112.     if (session == NULL) {
  1113.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  1114. fort11_TokenRemoved (slot, session);
  1115. fort11_FreeSession(session);
  1116. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1117.     }
  1118.     context = &session->fortezzaContext;
  1119.     if (GetCryptoOperation(context) != Sign) {
  1120.         fort11_FreeSession(session);
  1121.         FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
  1122.     }
  1123.     if (pSignature == NULL) {
  1124.         *pulSignatureLen = 40;
  1125.         fort11_FreeSession(session);
  1126. FORT11_RETURN (CKR_OK);
  1127.     }
  1128.     if (ulDataLen > 20) {
  1129.         FORT11_RETURN (CKR_DATA_LEN_RANGE);
  1130.     }
  1131.     if (*pulSignatureLen < 40) {
  1132.         fort11_FreeSession(session);
  1133.         FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
  1134.     }
  1135.     *pulSignatureLen = 40;
  1136.     keyObject = fort11_ObjectFromHandle(context->hKey, session);
  1137.     if (keyObject == NULL) {
  1138.         fort11_FreeSession(session);
  1139. FORT11_RETURN(CKR_GENERAL_ERROR);
  1140.     }
  1141.     idAttribute = fort11_FindAttribute(keyObject, CKA_ID);
  1142.     fort11_FreeObject(keyObject);
  1143.     personalityIndex = *(int*)(idAttribute->attrib.pValue);
  1144.     fort11_FreeAttribute(idAttribute);
  1145.     MACI_Select(hs, slot->slotID);
  1146.     MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
  1147.     ciRV = MACI_SetPersonality(hs, personalityIndex);
  1148.     if (ciRV != CI_OK) {
  1149.         MACI_Unlock(hs);
  1150.         fort11_FreeSession(session);
  1151. FORT11_RETURN(CKR_DEVICE_ERROR);
  1152.     }
  1153.     ciRV = MACI_Sign (hs, pData, pSignature);
  1154.     if (ciRV != CI_OK) {
  1155.         MACI_Unlock(hs);
  1156.         fort11_FreeSession(session);
  1157. FORT11_RETURN (CKR_DEVICE_ERROR);
  1158.     }
  1159.     MACI_Unlock(hs);
  1160.     EndCryptoOperation (context, Sign);
  1161.     fort11_FreeSession(session);
  1162.     FORT11_RETURN (CKR_OK);
  1163. }
  1164. /* C_SignUpdate continues a multiple-part signature operation,
  1165.  * where the signature is (will be) an appendix to the data, 
  1166.  * and plaintext cannot be recovered from the signature */
  1167. PR_PUBLIC_API(CK_RV) C_SignUpdate(CK_SESSION_HANDLE hSession,
  1168.   CK_BYTE_PTR       pPart,
  1169.   CK_ULONG          ulPartLen) {
  1170.   /* For functions that don't access globals, we don't have to worry about the
  1171.    * stack.
  1172.    */
  1173.   return CKR_FUNCTION_NOT_SUPPORTED;
  1174. }
  1175. /* C_SignFinal finishes a multiple-part signature operation, 
  1176.  * FORT11_RETURNing the signature. */
  1177. PR_PUBLIC_API(CK_RV) C_SignFinal(CK_SESSION_HANDLE hSession,
  1178.  CK_BYTE_PTR       pSignature,
  1179.  CK_ULONG_PTR      pulSignatureLen) {
  1180.   /* For functions that don't access globals, we don't have to worry about the
  1181.    * stack.
  1182.    */
  1183.   return CKR_FUNCTION_NOT_SUPPORTED;
  1184. }
  1185. /*
  1186.  ************** Crypto Functions:     Sign Recover  ************************
  1187.  */
  1188. /* C_SignRecoverInit initializes a signature operation,
  1189.  * where the (digest) data can be recovered from the signature. 
  1190.  * E.g. encryption with the user's private key */
  1191. PR_PUBLIC_API(CK_RV) C_SignRecoverInit(CK_SESSION_HANDLE hSession,
  1192.        CK_MECHANISM_PTR  pMechanism,
  1193.        CK_OBJECT_HANDLE  hKey) {
  1194.   /* For functions that don't access globals, we don't have to worry about the
  1195.    * stack.
  1196.    */
  1197.   return CKR_FUNCTION_NOT_SUPPORTED;
  1198. }
  1199. /* C_SignRecover signs data in a single operation
  1200.  * where the (digest) data can be recovered from the signature. 
  1201.  * E.g. encryption with the user's private key */
  1202. PR_PUBLIC_API(CK_RV) C_SignRecover(CK_SESSION_HANDLE hSession,
  1203.    CK_BYTE_PTR       pData,
  1204.    CK_ULONG          ulDataLen, 
  1205.    CK_BYTE_PTR       pSignature, 
  1206.    CK_ULONG_PTR      pulSignatureLen) {
  1207.   /* For functions that don't access globals, we don't have to worry about the
  1208.    * stack.
  1209.    */
  1210.   return CKR_FUNCTION_NOT_SUPPORTED;
  1211. }
  1212. /*
  1213.  ************** Crypto Functions:     verify  ************************
  1214.  */
  1215. /* C_VerifyInit initializes a verification operation, 
  1216.  * where the signature is an appendix to the data, 
  1217.  * and plaintext cannot be recovered from the signature (e.g. DSA) */
  1218. PR_PUBLIC_API(CK_RV) C_VerifyInit(CK_SESSION_HANDLE hSession,
  1219.   CK_MECHANISM_PTR  pMechanism,
  1220.   CK_OBJECT_HANDLE  hKey) {
  1221.   /* For functions that don't access globals, we don't have to worry about the
  1222.    * stack.
  1223.    */
  1224.   return CKR_FUNCTION_NOT_SUPPORTED;
  1225. }
  1226. /* C_Verify verifies a signature in a single-part operation, 
  1227.  * where the signature is an appendix to the data, 
  1228.  * and plaintext cannot be recovered from the signature */
  1229. PR_PUBLIC_API(CK_RV) C_Verify(CK_SESSION_HANDLE hSession, 
  1230.       CK_BYTE_PTR       pData,
  1231.       CK_ULONG          ulDataLen, 
  1232.       CK_BYTE_PTR       pSignature, 
  1233.       CK_ULONG          ulSignatureLen) {
  1234.   /* For functions that don't access globals, we don't have to worry about the
  1235.    * stack.
  1236.    */
  1237.   return CKR_FUNCTION_NOT_SUPPORTED;
  1238. }
  1239. /* C_VerifyUpdate continues a multiple-part verification operation, 
  1240.  * where the signature is an appendix to the data, 
  1241.  * and plaintext cannot be recovered from the signature */
  1242. PR_PUBLIC_API(CK_RV) C_VerifyUpdate( CK_SESSION_HANDLE hSession, 
  1243.      CK_BYTE_PTR       pPart,
  1244.      CK_ULONG          ulPartLen) {
  1245.    return CKR_FUNCTION_NOT_SUPPORTED;
  1246. }
  1247. /* C_VerifyFinal finishes a multiple-part verification operation, 
  1248.  * checking the signature. */
  1249. PR_PUBLIC_API(CK_RV) C_VerifyFinal(CK_SESSION_HANDLE hSession,
  1250.    CK_BYTE_PTR       pSignature,
  1251.    CK_ULONG          ulSignatureLen) {
  1252.   /* For functions that don't access globals, we don't have to worry about the
  1253.    * stack.
  1254.    */
  1255.   return CKR_FUNCTION_NOT_SUPPORTED;
  1256. }
  1257. /*
  1258.  ************** Crypto Functions:     Verify  Recover ************************
  1259.  */
  1260. /* C_VerifyRecoverInit initializes a signature verification operation, 
  1261.  * where the data is recovered from the signature. 
  1262.  * E.g. Decryption with the user's public key */
  1263. PR_PUBLIC_API(CK_RV) C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
  1264.  CK_MECHANISM_PTR  pMechanism,
  1265.  CK_OBJECT_HANDLE  hKey) {
  1266.   /* For functions that don't access globals, we don't have to worry about the
  1267.    * stack.
  1268.    */
  1269.   return CKR_FUNCTION_NOT_SUPPORTED;
  1270. }
  1271. /* C_VerifyRecover verifies a signature in a single-part operation, 
  1272.  * where the data is recovered from the signature. 
  1273.  * E.g. Decryption with the user's public key */
  1274. PR_PUBLIC_API(CK_RV) C_VerifyRecover(CK_SESSION_HANDLE hSession,
  1275.      CK_BYTE_PTR       pSignature,
  1276.      CK_ULONG          ulSignatureLen,
  1277.      CK_BYTE_PTR       pData,
  1278.      CK_ULONG_PTR      pulDataLen) {
  1279.   return CKR_FUNCTION_NOT_SUPPORTED;
  1280. }
  1281. /*
  1282.  **************************** Key Functions:  ************************
  1283.  */
  1284. #define MAX_KEY_LEN 256
  1285. /* C_GenerateKey generates a secret key, creating a new key object. */
  1286. PR_PUBLIC_API(CK_RV) C_GenerateKey(CK_SESSION_HANDLE    hSession, 
  1287.    CK_MECHANISM_PTR     pMechanism,
  1288.    CK_ATTRIBUTE_PTR     pTemplate,
  1289.    CK_ULONG             ulCount,
  1290.    CK_OBJECT_HANDLE_PTR phKey) {
  1291.     FORT11_ENTER()
  1292.     PK11Session    *session = fort11_SessionFromHandle(hSession, PR_FALSE);
  1293.     PK11Slot       *slot    = fort11_SlotFromSessionHandle(hSession);
  1294.     FortezzaSocket *socket  = &fortezzaSockets[slot->slotID-1];
  1295.     PK11Object     *key;
  1296.     FortezzaKey    *newKey;
  1297.     int             i, keyRegister;
  1298.     CK_ULONG        key_length = 0;
  1299.     CK_RV           crv        = CKR_OK;
  1300.     CK_OBJECT_CLASS secretKey  = CKO_SECRET_KEY;
  1301.     CK_BBOOL        False      = FALSE;
  1302.     CK_BBOOL        cktrue     = TRUE;
  1303.     if (session == NULL) {
  1304.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  1305.         fort11_TokenRemoved (slot, session);
  1306. fort11_FreeSession(session);
  1307. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1308.     }
  1309.     if (pMechanism->mechanism != CKM_SKIPJACK_KEY_GEN) {
  1310.         fort11_FreeSession(session);
  1311.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  1312.     }
  1313.     key = fort11_NewObject(slot);
  1314.     if (key == NULL) {
  1315.         fort11_FreeSession(session);
  1316.         FORT11_RETURN (CKR_HOST_MEMORY);
  1317.     }
  1318.     for (i=0; i < (int) ulCount; i++) {
  1319.         if (pTemplate[i].type == CKA_VALUE_LEN) {
  1320.     key_length = *(CK_ULONG *)pTemplate[i].pValue;
  1321.     continue;
  1322. }
  1323. crv = fort11_AddAttributeType (key, pk11_attr_expand (&pTemplate[i]));
  1324. if (crv != CKR_OK) 
  1325.   break;
  1326.     } 
  1327.     if (crv != CKR_OK) {
  1328.         fort11_FreeObject(key);
  1329. fort11_FreeSession(session);
  1330. FORT11_RETURN (crv);
  1331.     }
  1332.     /* make sure we don't have any class, key_type, or value fields */
  1333.     fort11_DeleteAttributeType(key,CKA_CLASS);
  1334.     fort11_DeleteAttributeType(key,CKA_KEY_TYPE);
  1335.     fort11_DeleteAttributeType(key,CKA_VALUE);
  1336.     if (MAX_KEY_LEN < key_length) {
  1337.         crv = CKR_TEMPLATE_INCONSISTENT;
  1338.     }
  1339.     if (crv != CKR_OK) {
  1340.         fort11_FreeObject(key);
  1341. fort11_FreeSession(session);
  1342. FORT11_RETURN (crv);
  1343.     }
  1344.     
  1345.     if (fort11_AddAttributeType(key, CKA_CLASS,&secretKey,
  1346.       sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
  1347.         fort11_FreeObject(key);
  1348. fort11_FreeSession(session);
  1349.         FORT11_RETURN (CKR_GENERAL_ERROR);
  1350.     }
  1351.     if (fort11_AddAttributeType(key, CKA_TOKEN, &False,
  1352.       sizeof(CK_BBOOL)) != CKR_OK) {
  1353.         fort11_FreeObject(key);
  1354. fort11_FreeSession(session);
  1355.         FORT11_RETURN (CKR_GENERAL_ERROR);
  1356.     }
  1357.  
  1358.     if (fort11_isTrue(key,CKA_SENSITIVE)) {
  1359. fort11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,
  1360.       sizeof(CK_BBOOL));
  1361.     }
  1362.     if (!fort11_isTrue(key,CKA_EXTRACTABLE)) {
  1363. fort11_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,
  1364.     sizeof(CK_BBOOL));
  1365.     }
  1366.     FMUTEX_Lock(socket->registersLock);
  1367.     keyRegister = GetBestKeyRegister(socket);
  1368.     newKey = NewFortezzaKey(socket, MEK, NULL, keyRegister);
  1369.     FMUTEX_Unlock(socket->registersLock);
  1370.     if (newKey == NULL) {
  1371.         fort11_FreeObject(key);
  1372. fort11_FreeSession(session);
  1373.         FORT11_RETURN (CKR_HOST_MEMORY);
  1374.     }
  1375.     key->objectInfo = (void*)newKey;
  1376.     key->infoFree   = fort11_FreeFortezzaKey;
  1377.     FMUTEX_Lock(slot->objectLock);
  1378.     key->handle = slot->tokenIDCount++;
  1379.     key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
  1380.     FMUTEX_Unlock(slot->objectLock);
  1381.     key->objclass = secretKey;
  1382.     key->slot = slot;
  1383.     key->inDB = PR_TRUE;
  1384.     fort11_AddObject(session, key);
  1385.     fort11_FreeSession(session);
  1386.     SetFortezzaKeyHandle(newKey, key->handle);
  1387.     *phKey = key->handle;
  1388.     FORT11_RETURN (CKR_OK);
  1389.     
  1390. }
  1391. /* C_GenerateKeyPair generates a public-key/private-key pair, 
  1392.  * creating new key objects. */
  1393. PR_PUBLIC_API(CK_RV) C_GenerateKeyPair 
  1394.                      (CK_SESSION_HANDLE    hSession,
  1395.       CK_MECHANISM_PTR     pMechanism, 
  1396.       CK_ATTRIBUTE_PTR     pPublicKeyTemplate,
  1397.       CK_ULONG             ulPublicKeyAttributeCount, 
  1398.       CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,
  1399.       CK_ULONG             ulPrivateKeyAttributeCount, 
  1400.       CK_OBJECT_HANDLE_PTR phPrivateKey,
  1401.       CK_OBJECT_HANDLE_PTR phPublicKey) {
  1402.   return CKR_FUNCTION_NOT_SUPPORTED;
  1403. }
  1404. /* C_WrapKey wraps (i.e., encrypts) a key. */
  1405. PR_PUBLIC_API(CK_RV) C_WrapKey(CK_SESSION_HANDLE hSession,
  1406.        CK_MECHANISM_PTR  pMechanism, 
  1407.        CK_OBJECT_HANDLE  hWrappingKey,
  1408.        CK_OBJECT_HANDLE  hKey, 
  1409.        CK_BYTE_PTR       pWrappedKey,
  1410.        CK_ULONG_PTR      pulWrappedKeyLen) {
  1411.     FORT11_ENTER()
  1412.     PK11Session    *session = fort11_SessionFromHandle (hSession, PR_FALSE);
  1413.     PK11Slot       *slot    = fort11_SlotFromSessionHandle(hSession);
  1414.     FortezzaSocket *socket  = &fortezzaSockets[slot->slotID-1];
  1415.     PK11Object     *wrapKey;
  1416.     PK11Object     *srcKey;
  1417.     FortezzaKey    *wrapFortKey;
  1418.     FortezzaKey    *srcFortKey;
  1419.     int             rv;
  1420.     if (session == NULL) {
  1421.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  1422. fort11_TokenRemoved(slot, session);
  1423. fort11_FreeSession(session);
  1424. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1425.     }
  1426.     if (!socket->isLoggedIn) {
  1427.         fort11_FreeSession(session);
  1428. FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  1429.     }
  1430.     if (pMechanism->mechanism != CKM_SKIPJACK_WRAP) {
  1431.         fort11_FreeSession(session);
  1432.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  1433.     }
  1434.     wrapKey = fort11_ObjectFromHandle (hWrappingKey, session);
  1435.     if ((wrapKey == NULL) || (wrapKey->objectInfo == NULL)) {
  1436.         if (wrapKey) 
  1437.     fort11_FreeObject(wrapKey);
  1438. fort11_FreeSession(session);
  1439.         FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  1440.     }
  1441.     srcKey = fort11_ObjectFromHandle (hKey, session);
  1442.     fort11_FreeSession(session);
  1443.     if ((srcKey == NULL) || (srcKey->objectInfo == NULL)) {
  1444.         FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  1445.     }
  1446.     wrapFortKey = (FortezzaKey*)wrapKey->objectInfo;
  1447.     fort11_FreeObject(wrapKey);
  1448.     srcFortKey = (FortezzaKey*)srcKey->objectInfo;
  1449.     fort11_FreeObject(srcKey);
  1450.     FMUTEX_Lock(socket->registersLock);
  1451.     if (wrapFortKey->keyRegister == KeyNotLoaded) {
  1452.       if (LoadKeyIntoRegister(wrapFortKey) == KeyNotLoaded) {
  1453.   FORT11_RETURN (CKR_DEVICE_ERROR);
  1454.       }
  1455.     }
  1456.     if (srcFortKey->keyRegister == KeyNotLoaded) {
  1457.       if (LoadKeyIntoRegister(srcFortKey) == KeyNotLoaded) {
  1458.   FMUTEX_Unlock(socket->registersLock);
  1459.   FORT11_RETURN (CKR_DEVICE_ERROR);
  1460.       }
  1461.     }
  1462.     MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG);
  1463.     rv = WrapKey (wrapFortKey, srcFortKey, pWrappedKey, *pulWrappedKeyLen);
  1464.     MACI_Unlock(socket->maciSession);
  1465.     FMUTEX_Unlock(socket->registersLock);
  1466.     if (rv != SOCKET_SUCCESS) {
  1467.         FORT11_RETURN (CKR_GENERAL_ERROR);
  1468.     }
  1469.     FORT11_RETURN (CKR_OK);
  1470. }
  1471. /* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
  1472. PR_PUBLIC_API(CK_RV) C_UnwrapKey(CK_SESSION_HANDLE    hSession,
  1473.  CK_MECHANISM_PTR     pMechanism, 
  1474.  CK_OBJECT_HANDLE     hUnwrappingKey,
  1475.  CK_BYTE_PTR          pWrappedKey, 
  1476.  CK_ULONG             ulWrappedKeyLen,
  1477.  CK_ATTRIBUTE_PTR     pTemplate, 
  1478.  CK_ULONG             ulAttributeCount,
  1479.  CK_OBJECT_HANDLE_PTR phKey) {
  1480.     FORT11_ENTER()
  1481.     PK11Session    *session = fort11_SessionFromHandle(hSession, PR_FALSE);
  1482.     PK11Slot       *slot    = fort11_SlotFromSessionHandle(hSession);
  1483.     FortezzaSocket *socket  = &fortezzaSockets[slot->slotID-1];
  1484.     PK11Object     *wrapKey;
  1485.     PK11Object     *newKey;
  1486.     FortezzaKey    *fortKey;
  1487.     FortezzaKey    *unwrapFort;
  1488.     CK_ULONG        key_length;
  1489.     int             i, newKeyRegister;
  1490.     CK_RV           crv = CKR_OK;
  1491.     if (session == NULL) {
  1492.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  1493. fort11_TokenRemoved(slot, session);
  1494. fort11_FreeSession(session);
  1495. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1496.     }
  1497.     if (pMechanism->mechanism != CKM_SKIPJACK_WRAP){
  1498.         fort11_FreeSession(session);
  1499.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  1500.     }
  1501.     if (!socket->isLoggedIn) {
  1502.         fort11_FreeSession(session);
  1503.         FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
  1504.     }    
  1505.     wrapKey = fort11_ObjectFromHandle(hUnwrappingKey, session);
  1506.     if (wrapKey == NULL || wrapKey->objectInfo == NULL) {
  1507.         if (wrapKey)
  1508.     fort11_FreeObject(wrapKey);
  1509.         fort11_FreeSession(session);
  1510.         FORT11_RETURN (CKR_UNWRAPPING_KEY_HANDLE_INVALID);
  1511.     }
  1512.     fortKey = (FortezzaKey*)wrapKey->objectInfo;
  1513.     fort11_FreeObject(wrapKey);
  1514.     newKey = fort11_NewObject(slot);
  1515.     if (newKey == NULL) {
  1516.         fort11_FreeSession(session);
  1517.         FORT11_RETURN (CKR_HOST_MEMORY);
  1518.     }
  1519.     for (i=0; i< (int)ulAttributeCount; i++) {
  1520.         if (pTemplate[i].type == CKA_VALUE_LEN) {
  1521.     key_length = *(CK_ULONG*)pTemplate[i].pValue;
  1522.     continue;
  1523. }
  1524. crv=fort11_AddAttributeType(newKey,fort11_attr_expand(&pTemplate[i]));
  1525. if (crv != CKR_OK) {
  1526.     break;
  1527. }
  1528.     }
  1529.     if (crv != CKR_OK) {
  1530.         fort11_FreeSession(session);
  1531.         fort11_FreeObject(newKey);
  1532. FORT11_RETURN (crv);
  1533.     }
  1534.     /* make sure we don't have any class, key_type, or value fields */
  1535.     if (!fort11_hasAttribute(newKey,CKA_CLASS)) {
  1536. fort11_FreeObject(newKey);
  1537. fort11_FreeSession(session);
  1538. FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE);
  1539.     }
  1540.     if (!fort11_hasAttribute(newKey,CKA_KEY_TYPE)) {
  1541. fort11_FreeObject(newKey);
  1542. fort11_FreeSession(session);
  1543. FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE);
  1544.     }
  1545.     FMUTEX_Lock(socket->registersLock);
  1546.     newKeyRegister = UnwrapKey (pWrappedKey, fortKey);
  1547.     if (newKeyRegister == KeyNotLoaded) {
  1548.         /*Couldn't Unwrap the key*/
  1549.         fort11_FreeObject(newKey);
  1550.         fort11_FreeSession(session);
  1551. FMUTEX_Unlock(socket->registersLock);
  1552.         FORT11_RETURN (CKR_GENERAL_ERROR);
  1553.     }
  1554.     unwrapFort = NewUnwrappedKey(newKeyRegister, fortKey->id, socket);
  1555.     FMUTEX_Unlock(socket->registersLock);
  1556.     if (unwrapFort == NULL) {
  1557.         fort11_FreeObject(newKey);
  1558.         fort11_FreeSession(session);
  1559.         FORT11_RETURN (CKR_HOST_MEMORY);
  1560.     }
  1561.     newKey->objectInfo = unwrapFort;
  1562.     newKey->infoFree   = fort11_FreeFortezzaKey;
  1563.     FMUTEX_Lock(slot->objectLock);
  1564.     newKey->handle = slot->tokenIDCount++;
  1565.     newKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
  1566.     FMUTEX_Unlock(slot->objectLock);
  1567.     newKey->objclass = CKO_SECRET_KEY;
  1568.     newKey->slot  = slot;
  1569.     newKey->inDB  = PR_TRUE;
  1570.     fort11_AddObject (session, newKey);
  1571.     fort11_FreeSession(session);
  1572.     
  1573.     SetFortezzaKeyHandle(unwrapFort, newKey->handle);
  1574.     *phKey = newKey->handle;
  1575.     FORT11_RETURN (CKR_OK);
  1576. }
  1577. /* C_DeriveKey derives a key from a base key, creating a new key object. */
  1578. PR_PUBLIC_API(CK_RV) C_DeriveKey( CK_SESSION_HANDLE    hSession,
  1579.   CK_MECHANISM_PTR     pMechanism, 
  1580.   CK_OBJECT_HANDLE     hBaseKey,
  1581.   CK_ATTRIBUTE_PTR     pTemplate, 
  1582.   CK_ULONG             ulAttributeCount, 
  1583.   CK_OBJECT_HANDLE_PTR phKey) {
  1584.     FORT11_ENTER()
  1585.     PK11Session     *session = fort11_SessionFromHandle(hSession, PR_FALSE);
  1586.     PK11Slot        *slot    = fort11_SlotFromSessionHandle(hSession);
  1587.     FortezzaSocket  *socket  = &fortezzaSockets[slot->slotID-1];
  1588.     PK11Object      *key, *sourceKey;
  1589.     CK_ULONG         i;
  1590.     CK_ULONG         key_length = 0;
  1591.     CK_RV            crv        = 0;
  1592.     CK_KEY_TYPE      keyType    = CKK_SKIPJACK;
  1593.     CK_OBJECT_CLASS  classType  = CKO_SECRET_KEY;  
  1594.     CK_BBOOL      ckTrue     = TRUE;
  1595.     CK_BBOOL         ckFalse    = FALSE;
  1596.     int              ciRV;
  1597.     int              personality;
  1598.     PK11Attribute   *att;
  1599.     CK_KEA_DERIVE_PARAMS_PTR  params;
  1600.     FortezzaKey              *derivedKey;
  1601.     CreateTEKInfo             tekInfo;
  1602.     if (session == NULL) {
  1603.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  1604. fort11_TokenRemoved (slot, session);
  1605. fort11_FreeSession(session);
  1606. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1607.     }
  1608.     if (pMechanism->mechanism != CKM_KEA_KEY_DERIVE) {
  1609.         fort11_FreeSession(session);
  1610.         FORT11_RETURN (CKR_MECHANISM_INVALID);
  1611.     }
  1612.     key = fort11_NewObject (slot);
  1613.     if (key == NULL) {
  1614.         fort11_FreeSession(session);
  1615.         FORT11_RETURN (CKR_HOST_MEMORY);
  1616.     }
  1617.     for (i = 0; i < ulAttributeCount; i++) {
  1618.         crv = fort11_AddAttributeType (key, fort11_attr_expand(&pTemplate[i]));
  1619. if (crv != CKR_OK) {
  1620.     break;
  1621. }
  1622. if (pTemplate[i].type == CKA_KEY_TYPE) {
  1623.     keyType = *(CK_KEY_TYPE*)pTemplate[i].pValue;
  1624. } else if (pTemplate[i].type == CKA_VALUE_LEN) {
  1625.     key_length = *(CK_ULONG*)pTemplate[i].pValue;
  1626. }   
  1627.     }
  1628.     if (crv != CKR_OK) {
  1629.         fort11_FreeObject(key);
  1630. fort11_FreeSession(session);
  1631. FORT11_RETURN (crv);
  1632.     }
  1633.     if (key_length == 0) {
  1634.         key_length = 12;
  1635.     }
  1636.     classType = CKO_SECRET_KEY;
  1637.     crv = fort11_forceAttribute (key, CKA_CLASS, &classType, 
  1638.  sizeof(classType));
  1639.     if (crv != CKR_OK) {
  1640.         fort11_FreeObject(key);
  1641. fort11_FreeSession(session);
  1642. FORT11_RETURN (crv);
  1643.     }
  1644.     crv = fort11_forceAttribute (key, CKA_SENSITIVE, &ckTrue, 
  1645.  sizeof(CK_BBOOL));
  1646.     if (crv != CKR_OK) {
  1647.         fort11_FreeObject(key);
  1648. fort11_FreeSession(session);
  1649. FORT11_RETURN (crv);
  1650.     }
  1651.     crv = fort11_forceAttribute (key, CKA_EXTRACTABLE, &ckFalse, 
  1652.        sizeof(CK_BBOOL));
  1653.     if (crv != CKR_OK) {
  1654.         fort11_FreeSession(session);
  1655. fort11_FreeObject(key);
  1656. FORT11_RETURN (crv);
  1657.     }
  1658.     sourceKey = fort11_ObjectFromHandle (hBaseKey, session);
  1659.     if (sourceKey == NULL) {
  1660.         fort11_FreeObject(key);
  1661. fort11_FreeSession(session);
  1662. FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  1663.     }
  1664.     att = fort11_FindAttribute(sourceKey,CKA_ID);
  1665.     fort11_FreeObject(sourceKey);
  1666.     if (att == NULL) {
  1667. fort11_FreeObject(key);
  1668. fort11_FreeSession(session);
  1669. FORT11_RETURN (CKR_KEY_TYPE_INCONSISTENT);
  1670.     }
  1671.     personality = *(int *) att->attrib.pValue;
  1672.     fort11_FreeAttribute(att);
  1673.     params = (CK_KEA_DERIVE_PARAMS_PTR)pMechanism->pParameter;
  1674.     if (params == NULL) {
  1675. fort11_FreeObject(key);
  1676. fort11_FreeSession(session);
  1677.         FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID);
  1678.     }
  1679.     
  1680.     ciRV = MACI_SetPersonality(socket->maciSession,personality);
  1681.     if (ciRV != CI_OK) {
  1682. fort11_FreeObject(key);
  1683. fort11_FreeSession(session);
  1684. FORT11_RETURN (CKR_DEVICE_ERROR);
  1685.     }
  1686.     /*
  1687.      * If we're sending, generate our own RA.
  1688.      */
  1689.     if (params->isSender) {
  1690. ciRV = MACI_GenerateRa(socket->maciSession,params->pRandomA);
  1691. if (ciRV != CI_OK) {
  1692.     fort11_FreeObject(key);
  1693.     fort11_FreeSession(session);
  1694.     FORT11_RETURN (CKR_DEVICE_ERROR);
  1695. }
  1696.     }
  1697.     PORT_Memcpy (tekInfo.Ra, params->pRandomA, params->ulRandomLen);
  1698.     PORT_Memcpy (tekInfo.Rb, params->pRandomB, params->ulRandomLen);
  1699.     tekInfo.randomLen = params->ulRandomLen;
  1700.     tekInfo.personality = personality;
  1701.     tekInfo.flag = (params->isSender) ? CI_INITIATOR_FLAG : CI_RECIPIENT_FLAG;
  1702.     
  1703.     PORT_Memcpy (tekInfo.pY, params->pPublicData, params->ulPublicDataLen);
  1704.     tekInfo.YSize = params->ulPublicDataLen;
  1705.     FMUTEX_Lock(socket->registersLock);
  1706.     derivedKey = NewFortezzaKey(socket, TEK, &tekInfo, 
  1707. GetBestKeyRegister(socket));
  1708.     FMUTEX_Unlock(socket->registersLock);
  1709.     if (derivedKey == NULL) {
  1710. fort11_FreeObject(key);
  1711. fort11_FreeSession(session);
  1712.         FORT11_RETURN (CKR_GENERAL_ERROR);
  1713.     }
  1714.     key->objectInfo = derivedKey;
  1715.     key->infoFree   = fort11_FreeFortezzaKey;
  1716.     FMUTEX_Lock(slot->objectLock);
  1717.     key->handle = slot->tokenIDCount++;
  1718.     key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
  1719.     FMUTEX_Unlock(slot->objectLock);
  1720.     key->objclass = classType;
  1721.     key->slot = slot;
  1722.     key->inDB = PR_TRUE;
  1723.     fort11_AddObject (session, key);
  1724.     fort11_FreeSession(session);
  1725.     
  1726.     SetFortezzaKeyHandle(derivedKey, key->handle);
  1727.     *phKey = key->handle;
  1728.     FORT11_RETURN (CKR_OK);
  1729. }
  1730. /*
  1731.  **************************** Random Functions:  ************************
  1732.  */
  1733. /* C_SeedRandom mixes additional seed material into the token's random number 
  1734.  * generator. */
  1735. PR_PUBLIC_API(CK_RV) C_SeedRandom(CK_SESSION_HANDLE hSession, 
  1736.   CK_BYTE_PTR       pSeed,
  1737.   CK_ULONG          ulSeedLen) {
  1738.   return CKR_FUNCTION_NOT_SUPPORTED;
  1739. }
  1740. /* C_GenerateRandom generates random data. */
  1741. PR_PUBLIC_API(CK_RV) C_GenerateRandom(CK_SESSION_HANDLE hSession,
  1742.       CK_BYTE_PTR pRandomData, 
  1743.       CK_ULONG          ulRandomLen) {
  1744.     FORT11_ENTER()
  1745.     PK11Slot    *slot    = fort11_SlotFromSessionHandle(hSession);
  1746.     PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
  1747.     CI_RANDOM    randomNum;
  1748.     CK_ULONG     randomSize = sizeof (CI_RANDOM);
  1749.     int          ciRV;
  1750.     CK_ULONG     bytesCopied = 0, bytesToCopy;
  1751.     CK_ULONG     bufferSize  = 0, bytesRemaining;
  1752.     if (session == NULL) {
  1753.         session = fort11_SessionFromHandle (hSession, PR_TRUE);
  1754. fort11_TokenRemoved(slot, session);
  1755. fort11_FreeSession(session);
  1756.         FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1757.     }
  1758.     fort11_FreeSession(session);
  1759.     ciRV = MACI_Select(fortezzaSockets[slot->slotID-1].maciSession, 
  1760.        slot->slotID);
  1761.     if (ciRV != CI_OK) {
  1762.         FORT11_RETURN (CKR_DEVICE_ERROR);
  1763.     }
  1764.     
  1765.     while (bytesCopied < ulRandomLen) {
  1766.       bytesRemaining = ulRandomLen - bytesCopied;
  1767.       if (bufferSize < bytesRemaining) {
  1768.   ciRV = 
  1769.     MACI_GenerateRandom(fortezzaSockets[slot->slotID-1].maciSession, 
  1770. randomNum);
  1771.   if (ciRV != CI_OK)
  1772.       FORT11_RETURN (CKR_DEVICE_ERROR);
  1773.   bufferSize = randomSize;
  1774.       }
  1775.       bytesToCopy = (bytesRemaining > randomSize) ? randomSize : 
  1776.                                             bytesRemaining;
  1777.       PORT_Memcpy (&pRandomData[bytesCopied], 
  1778.    &randomNum[randomSize-bufferSize], bytesToCopy);
  1779.       bytesCopied += bytesToCopy;
  1780.       bufferSize  -= bytesToCopy; 
  1781.     }
  1782.     FORT11_RETURN (CKR_OK);
  1783. }
  1784. /* C_GetFunctionStatus obtains an updated status of a function running 
  1785.  * in parallel with an application. */
  1786. PR_PUBLIC_API(CK_RV) C_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
  1787.     return CKR_FUNCTION_NOT_SUPPORTED;
  1788. }
  1789. /* C_CancelFunction cancels a function running in parallel */
  1790. PR_PUBLIC_API(CK_RV) C_CancelFunction(CK_SESSION_HANDLE hSession) {
  1791.     return CKR_FUNCTION_NOT_SUPPORTED;
  1792. }
  1793. /* C_GetOperationState saves the state of the cryptographic 
  1794.  *operation in a session. */
  1795. PR_PUBLIC_API(CK_RV) C_GetOperationState(CK_SESSION_HANDLE hSession, 
  1796.  CK_BYTE_PTR       pOperationState, 
  1797.  CK_ULONG_PTR      pulOperationStateLen) {
  1798.     FORT11_ENTER()
  1799.     PK11Session     *session   = fort11_SessionFromHandle(hSession, PR_FALSE);
  1800.     PK11Slot        *slot      = fort11_SlotFromSessionHandle(hSession);
  1801.     FortezzaContext *context;
  1802.     if (session  == NULL) {
  1803.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  1804. fort11_TokenRemoved (slot, session);
  1805. fort11_FreeSession(session);
  1806. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1807.     }
  1808.     if (pOperationState == NULL) {
  1809.         *pulOperationStateLen = sizeof (FortezzaContext);
  1810.         fort11_FreeSession(session);
  1811. FORT11_RETURN (CKR_OK);
  1812.     }
  1813.     if (*pulOperationStateLen < sizeof (FortezzaContext)) {
  1814.         fort11_FreeSession(session);
  1815. FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
  1816.     }
  1817.     context = &session->fortezzaContext;
  1818.     fort11_FreeSession(session);
  1819.     PORT_Memcpy (pOperationState, context, sizeof(FortezzaContext));
  1820.     ((FortezzaContext *)pOperationState)->session = NULL;
  1821.     ((FortezzaContext *)pOperationState)->fortezzaKey = NULL;
  1822.     *pulOperationStateLen = sizeof(FortezzaContext);
  1823.     FORT11_RETURN (CKR_OK);
  1824. }
  1825. /* C_SetOperationState restores the state of the cryptographic operation in a session. */
  1826. PR_PUBLIC_API(CK_RV) C_SetOperationState(CK_SESSION_HANDLE hSession, 
  1827.  CK_BYTE_PTR       pOperationState, 
  1828.  CK_ULONG          ulOperationStateLen,
  1829.  CK_OBJECT_HANDLE  hEncryptionKey, 
  1830.  CK_OBJECT_HANDLE  hAuthenticationKey){
  1831.     FORT11_ENTER()
  1832.     PK11Session     *session   = fort11_SessionFromHandle(hSession, PR_FALSE);
  1833.     PK11Slot        *slot      = fort11_SlotFromSessionHandle(hSession);
  1834.     FortezzaContext *context;
  1835.     FortezzaContext  passedInCxt;
  1836.     PK11Object      *keyObject;
  1837.     FortezzaKey     *fortKey;
  1838.     if (session  == NULL) {
  1839.         session = fort11_SessionFromHandle(hSession, PR_TRUE);
  1840. fort11_TokenRemoved (slot, session);
  1841. fort11_FreeSession(session);
  1842. FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
  1843.     }
  1844.     if (ulOperationStateLen != sizeof(FortezzaContext)) {
  1845.         fort11_FreeSession(session);
  1846.         FORT11_RETURN (CKR_SAVED_STATE_INVALID);
  1847.     }
  1848.     PORT_Memcpy(&passedInCxt, pOperationState, sizeof(FortezzaContext));
  1849.     if (passedInCxt.fortezzaSocket->slotID != slot->slotID) {
  1850.         fort11_FreeSession(session);
  1851.         FORT11_RETURN (CKR_SAVED_STATE_INVALID);
  1852.     }
  1853.     passedInCxt.session = NULL;
  1854.     passedInCxt.fortezzaKey = NULL;
  1855.     
  1856.     if (hEncryptionKey != 0) {
  1857.         keyObject = fort11_ObjectFromHandle(hEncryptionKey, session);
  1858. if (keyObject == NULL) {
  1859.     fort11_FreeSession(session);
  1860.     FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
  1861. }
  1862. fortKey = (FortezzaKey*)keyObject->objectInfo;
  1863. fort11_FreeObject(keyObject);
  1864. if (fortKey == NULL) {
  1865.     fort11_FreeSession(session);
  1866.     FORT11_RETURN (CKR_SAVED_STATE_INVALID);
  1867. }
  1868. if (fortKey->keyRegister == KeyNotLoaded) {
  1869.     if (LoadKeyIntoRegister (fortKey) == KeyNotLoaded) {
  1870.         fort11_FreeSession(session);
  1871. FORT11_RETURN (CKR_DEVICE_ERROR);
  1872.     }
  1873. }
  1874. passedInCxt.fortezzaKey = fortKey;
  1875.     } 
  1876.     if (hAuthenticationKey != 0) {
  1877.         fort11_FreeSession(session);
  1878. FORT11_RETURN (CKR_DEVICE_ERROR);
  1879.     }
  1880.     passedInCxt.session = session;
  1881.     context = &session->fortezzaContext;
  1882.     fort11_FreeSession (session);    
  1883.     PORT_Memcpy (context, &passedInCxt, sizeof(passedInCxt));
  1884.     FORT11_RETURN (CKR_OK);
  1885. }
  1886. /* Dual-function cryptographic operations */
  1887. /* C_DigestEncryptUpdate continues a multiple-part digesting and 
  1888.    encryption operation. */
  1889. PR_PUBLIC_API(CK_RV) C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, 
  1890.    CK_BYTE_PTR       pPart,
  1891.    CK_ULONG          ulPartLen, 
  1892.    CK_BYTE_PTR       pEncryptedPart,
  1893.    CK_ULONG_PTR      pulEncryptedPartLen){
  1894.   return CKR_FUNCTION_NOT_SUPPORTED;
  1895. }
  1896. /* C_DecryptDigestUpdate continues a multiple-part decryption and digesting 
  1897.    operation. */
  1898. PR_PUBLIC_API(CK_RV) C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
  1899.    CK_BYTE_PTR       pEncryptedPart, 
  1900.    CK_ULONG          ulEncryptedPartLen,
  1901.    CK_BYTE_PTR       pPart, 
  1902.     CK_ULONG_PTR      pulPartLen){
  1903.   return CKR_FUNCTION_NOT_SUPPORTED;
  1904. }
  1905. /* C_SignEncryptUpdate continues a multiple-part signing and encryption
  1906.    operation. */
  1907. PR_PUBLIC_API(CK_RV) C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, 
  1908.  CK_BYTE_PTR       pPart,
  1909.  CK_ULONG          ulPartLen, 
  1910.  CK_BYTE_PTR       pEncryptedPart,
  1911.  CK_ULONG_PTR      pulEncryptedPartLen){
  1912.   return CKR_FUNCTION_NOT_SUPPORTED;
  1913. }
  1914. /* C_DecryptVerifyUpdate continues a multiple-part decryption and verify 
  1915.    operation. */
  1916. PR_PUBLIC_API(CK_RV) C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, 
  1917.    CK_BYTE_PTR       pEncryptedData, 
  1918.    CK_ULONG          ulEncryptedDataLen, 
  1919.    CK_BYTE_PTR       pData, 
  1920.    CK_ULONG_PTR      pulDataLen){
  1921.   return CKR_FUNCTION_NOT_SUPPORTED;
  1922. }
  1923. /* C_DigestKey continues a multi-part message-digesting operation,
  1924.  * by digesting the value of a secret key as part of the data already digested.
  1925.  */
  1926. PR_PUBLIC_API(CK_RV) C_DigestKey(CK_SESSION_HANDLE hSession, 
  1927.  CK_OBJECT_HANDLE  hKey) {
  1928.   return CKR_FUNCTION_NOT_SUPPORTED;
  1929. }
  1930. PR_PUBLIC_API(CK_RV) C_WaitForSlotEvent(CK_FLAGS flags,
  1931. CK_SLOT_ID_PTR pSlot,
  1932. CK_VOID_PTR pRserved) {
  1933.   return CKR_FUNCTION_FAILED;
  1934. }