/* * COPYRIGHT (c) International Business Machines Corp. 2001-2017 * * This program is provided under the terms of the Common Public License, * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this * software constitutes recipient's acceptance of CPL-1.0 terms which can be * found in the file LICENSE file or at * https://opensource.org/licenses/cpl1.0.php */ #if NGPTH #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "trace.h" #include "ock_syslog.h" void api_init(); // NOTES: // In many cases the specificaiton does not allow returns // of CKR_ARGUMENTSB_BAD. We break the spec, since validation of parameters // to the function are best represented by this return code (where // specific RC's such as CKR_INVALID_SESSION do not exist). // NOTE NOTE NOTE NOTE // The parameter checking on the update operations may need to be // modified (as well as the encrypt/decrypt) to call the stdll // anyway with sanatized parameters since on error, the encrypt/decrypt // sign operations are all supposed to complete. // Therefor the parameter checking here might need to be done in // the STDLL instead of the API. // This would affect ALL the Multipart operations which have // an init followed by one or more operations. // Globals for the API API_Proc_Struct_t *Anchor = NULL; // Initialized to NULL unsigned int Initialized = 0; // Initialized flag pthread_mutex_t GlobMutex = PTHREAD_MUTEX_INITIALIZER; // Global Mutex CK_FUNCTION_LIST FuncList; int slot_loaded[NUMBER_SLOTS_MANAGED]; // Array of flags to indicate // if the STDLL loaded CK_BBOOL in_child_fork_initializer = FALSE; void child_fork_initializer() { /* * Reinitialize trace so that the trace output appears under the new * process's trace file, and not in the parent process's once. * C_Finalize will pass the new trace handle to the tokens, so that their * finalization code will also trace into the new trace file. */ trace_finalize(); trace_initialize(); /* * Terminate all slots by calling C_Finalize(). This will also free the * Anchor and set it to NULL. * A forked child is no PKCS11 application after fork. Thus it needs to * call C_Initialize again to become a PKC11 application and be able to * use Opencryptoki. * Indicate that we are in the fork initializer. * A forked child process has the same mapped memory as the parent, but * since client is no PKCS11 application after fork, it must not update * (i.e decrease) the reference count during C_Finalize. * If the client calls C_Initialize to become a PKCS11 application, it * will then increase the reference count. */ in_child_fork_initializer = TRUE; if (Anchor != NULL) C_Finalize(NULL); in_child_fork_initializer = FALSE; } //------------------------------------------------------------------------ // API function C_CancelFunction //------------------------------------------------------------------------ // This is a legacy function and performs no operations per the // specification. CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession) { UNUSED(hSession); TRACE_INFO("C_CancelFunction\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_PARALLEL)); return CKR_FUNCTION_NOT_PARALLEL; // PER PKCS#11v2.20,Sec 11.16 } //------------------------------------------------------------------------ // API function C_CloseAllSessions //------------------------------------------------------------------------ // Netscape Required // // This is a special one since the API can do this by removing // all active sessions on the slot... The STDLL does not have to implement // this. however this function will fail if any Session removal fails // in the walk. Which could lead to undetermined results. // //------------------------------------------------------------------------ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) { // Although why does modutil do a close all sessions. It is a single // application it can only close its sessions... // And all sessions should be closed anyhow. TRACE_INFO("CloseAllSessions\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } /* for every node in the API-level session tree, if the session's slot * matches slotID, close it */ CloseAllSessions(slotID, FALSE); return CKR_OK; } // end of C_CloseAllSessions //------------------------------------------------------------------------ // API function C_CloseSession //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_CloseSession\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_CloseSession) { // Map the Session to the slot session rv = fcn->ST_CloseSession(sltp->TokData, &rSession, FALSE); TRACE_DEVEL("Called STDLL rv = 0x%lx\n", rv); // If the STDLL successfully closed the session // we can free it.. Otherwise we will have to leave it // lying arround. if (rv == CKR_OK) { RemoveFromSessionList(hSession); // Need to decrement the global slot session count as well // as the per process slot session count to allow for // proper tracking of the number of sessions on a slot. // This allows things like InitToken to properly work in case // other applications have the token active. decr_sess_counts(rSession.slotID); } else { TRACE_DEVEL("fcn->ST_CloseSession failed:0x%lx\n", rv); } } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_CloseSession //------------------------------------------------------------------------ // API function C_CopyObject //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_CopyObject\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); if (!phNewObject) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } // null template with a count... will cause the lower layer // to have problems // Template with 0 count is not a problem. we can let // the STDLL handle that... if (!pTemplate && ulCount) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_CopyObject) { // Map the Session to the slot session rv = fcn->ST_CopyObject(sltp->TokData, &rSession, hObject, pTemplate, ulCount, phNewObject); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_CopyObject //------------------------------------------------------------------------ // API function C_CreateObject //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_CreateObject\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); // Null template is invalid... An object needs a minimal // template for creation. if (!pTemplate) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } // A 0 count for the template is bad if (ulCount == 0) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } // A Null pointer to return the handle in is also bad // since we could de-reference incorrectly. if (!phObject) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_CreateObject) { // Map the Session to the slot session rv = fcn->ST_CreateObject(sltp->TokData, &rSession, pTemplate, ulCount, phObject); TRACE_DEVEL("fcn->ST_CreateObject returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_CreateObject //------------------------------------------------------------------------ // API function C_Decrypt //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Decrypt\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Decrypt) { // Map the Session to the slot session rv = fcn->ST_Decrypt(sltp->TokData, &rSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen); TRACE_DEVEL("fcn->ST_Decrypt returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Decrypt //------------------------------------------------------------------------ // API function C_DecryptDigestUpdate //------------------------------------------------------------------------ // Netscape Required CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DecryptDigestUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); // This may have to go to the STDLL for validation if (!pEncryptedPart || !pulPartLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptDigestUpdate) { // Map the Session to the slot session rv = fcn->ST_DecryptDigestUpdate(sltp->TokData, &rSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen); TRACE_DEVEL("fcn->ST_DecryptDigestUpdate returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DecryptFinal //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DecryptFinal\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptFinal) { // Map the Session to the slot session rv = fcn->ST_DecryptFinal(sltp->TokData, &rSession, pLastPart, pulLastPartLen); TRACE_DEVEL("fcn->ST_DecryptFinal returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DecryptFinal //------------------------------------------------------------------------ // API function C_DecryptInit //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DecryptInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); // Null mechanism pointer is not good if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptInit) { // Map the Session to the slot session rv = fcn->ST_DecryptInit(sltp->TokData, &rSession, pMechanism, hKey); TRACE_DEVEL("fcn->ST_DecryptInit returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DecryptInit //------------------------------------------------------------------------ // API function C_DecryptUpdate //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DecryptUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptUpdate) { // Map the Session to the slot session rv = fcn->ST_DecryptUpdate(sltp->TokData, &rSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen); TRACE_DEVEL("fcn->ST_DecryptUpdate:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DecryptUpdate //------------------------------------------------------------------------ // API function C_DecryptVerifyUpdate //------------------------------------------------------------------------ CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DecryptVerifyUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); // May have to let these go through and let the STDLL handle them if (!pEncryptedPart || !pulPartLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DecryptVerifyUpdate) { // Map the Session to the slot session rv = fcn->ST_DecryptVerifyUpdate(sltp->TokData, &rSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen); TRACE_DEVEL("fcn->ST_DecryptVerifyUpdate returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DeriveKey //------------------------------------------------------------------------ CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DeriveKey\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); // Null phKey is invalid // Null mechanism pointer is invalid // This is allowed for some SSL3 mechs. the STDLL has to catch this // condition since it validates the mechanism //if (!phKey ) return CKR_ARGUMENTS_BAD; if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } // Null template with attribute count is bad // but we will let a template with len 0 pass through if (!pTemplate && ulAttributeCount) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DeriveKey) { // Map the Session to the slot session rv = fcn->ST_DeriveKey(sltp->TokData, &rSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey); TRACE_DEVEL("fcn->ST_DeriveKey returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DestroyObject //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DestroyObject\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DestroyObject) { // Map the Session to the slot session rv = fcn->ST_DestroyObject(sltp->TokData, &rSession, hObject); TRACE_DEVEL("fcn->ST_DestroyObject returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_DestroyObject //------------------------------------------------------------------------ // API function C_Digest //------------------------------------------------------------------------ CK_RV C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Digest\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Digest) { // Map the Session to the slot session rv = fcn->ST_Digest(sltp->TokData, &rSession, pData, ulDataLen, pDigest, pulDigestLen); TRACE_DEVEL("fcn->ST_Digest:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestEncryptUpdate //------------------------------------------------------------------------ CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DigestEncryptUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } // May have to pass on through to the STDLL if (!pPart || !pulEncryptedPartLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestEncryptUpdate) { // Map the Session to the slot session rv = fcn->ST_DigestEncryptUpdate(sltp->TokData, &rSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); TRACE_DEVEL("fcn->ST_DigestEncryptUpdate returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestFinal //------------------------------------------------------------------------ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DigestFinal\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestFinal) { // Map the Session to the slot session rv = fcn->ST_DigestFinal(sltp->TokData, &rSession, pDigest, pulDigestLen); TRACE_DEVEL("fcn->ST_DigestFinal returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestInit //------------------------------------------------------------------------ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DigestInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestInit) { // Map the Session to the slot session rv = fcn->ST_DigestInit(sltp->TokData, &rSession, pMechanism); TRACE_DEVEL("fcn->ST_DigestInit returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestKey //------------------------------------------------------------------------ CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DigestKey\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestKey) { // Map the Session to the slot session rv = fcn->ST_DigestKey(sltp->TokData, &rSession, hKey); TRACE_DEBUG("fcn->ST_DigestKey returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_DigestUpdate //------------------------------------------------------------------------ CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_DigestUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_DigestUpdate) { // Map the Session to the slot session rv = fcn->ST_DigestUpdate(sltp->TokData, &rSession, pPart, ulPartLen); TRACE_DEVEL("fcn->ST_DigestUpdate returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Encrypt //------------------------------------------------------------------------ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Encrypt\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Encrypt) { // Map the Session to the slot session rv = fcn->ST_Encrypt(sltp->TokData, &rSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); TRACE_DEVEL("fcn->ST_Encrypt returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_EncryptFinal //------------------------------------------------------------------------ CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_EncryptFinal\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_EncryptFinal) { // Map the Session to the slot session rv = fcn->ST_EncryptFinal(sltp->TokData, &rSession, pLastEncryptedPart, pulLastEncryptedPartLen); TRACE_DEVEL("fcn->ST_EncryptFinal: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_EncryptInit //------------------------------------------------------------------------ CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_EncryptInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_EncryptInit) { // Map the Session to the slot session rv = fcn->ST_EncryptInit(sltp->TokData, &rSession, pMechanism, hKey); TRACE_INFO("fcn->ST_EncryptInit returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_EncryptUpdate //------------------------------------------------------------------------ CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_EncryptUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_EncryptUpdate) { // Map the Session to the slot session rv = fcn->ST_EncryptUpdate(sltp->TokData, &rSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); TRACE_DEVEL("fcn->ST_EncryptUpdate returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Finalize //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Finalize(CK_VOID_PTR pReserved) { API_Slot_t *sltp; CK_SLOT_ID slotID; Slot_Mgr_Socket_t *shData; SLOT_INFO *sinfp; CK_RV rc = CKR_OK; if (pReserved != NULL) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } /* * Lock so that only one thread can run C_Initialize or C_Finalize at * a time */ pthread_mutex_lock(&GlobMutex); // Grab Process level Global MUTEX TRACE_INFO("C_Finalize\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } shData = &(Anchor->SocketDataP); // unload all the STDLL's from the application // This is in case the APP decides to do the re-initialize and // continue on for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { sltp = &(Anchor->SltList[slotID]); if (slot_loaded[slotID]) { CloseAllSessions(slotID, in_child_fork_initializer); if (sltp->pSTfini) { sinfp = &(shData->slot_info[slotID]); // call the terminate function.. sltp->pSTfini(sltp->TokData, slotID, sinfp, &trace, in_child_fork_initializer); } } DL_UnLoad(sltp, slotID); } // Un register from Slot D API_UnRegister(); bt_destroy(&Anchor->sess_btree); detach_shared_memory(Anchor->SharedMemP); free(Anchor); // Free API Proc Struct Anchor = NULL; trace_finalize(); //close the lock file descriptor here to avoid memory leak ProcClose(); done: // Unlock pthread_mutex_unlock(&GlobMutex); return rc; } // end of C_Finalize //------------------------------------------------------------------------ // API function C_FindObjects //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_FindObjects\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!phObject || !pulObjectCount) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_FindObjects) { // Map the Session to the slot session rv = fcn->ST_FindObjects(sltp->TokData, &rSession, phObject, ulMaxObjectCount, pulObjectCount); TRACE_DEVEL("fcn->ST_FindObjects returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_FindObjects //------------------------------------------------------------------------ // API function C_FindObjectsFinal //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_FindObjectsFinal\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_FindObjectsFinal) { // Map the Session to the slot session rv = fcn->ST_FindObjectsFinal(sltp->TokData, &rSession); TRACE_DEVEL("fcn->ST_FindObjectsFinal returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_FindObjectsFinal //------------------------------------------------------------------------ // API function // C_FindObjectsInit //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_FindObjectsInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } // What does a NULL template really mean if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_FindObjectsInit) { // Map the Session to the slot session rv = fcn->ST_FindObjectsInit(sltp->TokData, &rSession, pTemplate, ulCount); TRACE_DEVEL("fcn->ST_FindObjectsInit returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_FindObjectsInit //------------------------------------------------------------------------ // API function C_GenerateKey //------------------------------------------------------------------------ // Netscape Required CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GenerateKey\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!phKey) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GenerateKey) { // Map the Session to the slot session rv = fcn->ST_GenerateKey(sltp->TokData, &rSession, pMechanism, pTemplate, ulCount, phKey); TRACE_DEVEL("fcn->ST_GenerateKey returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GenerateKeyPair //------------------------------------------------------------------------ // Netscape Required CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GenerateKeyPair\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!phPublicKey || !phPrivateKey) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } // what other validation of parameters ... What about // template pointers is a Null template pointer valid in generate // key... Are there defaults. if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GenerateKeyPair) { // Map the Session to the slot session rv = fcn->ST_GenerateKeyPair(sltp->TokData, &rSession, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); TRACE_DEVEL("fcn->ST_GenerateKeyPair returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GenerateRandom //------------------------------------------------------------------------ // Netscape Required CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GenerateRandom\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!RandomData) return CKR_ARGUMENTS_BAD; if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GenerateRandom) { // Map the Session to the slot session rv = fcn->ST_GenerateRandom(sltp->TokData, &rSession, RandomData, ulRandomLen); TRACE_DEVEL("fcn->ST_GenerateRandom returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GetAttributeValue //------------------------------------------------------------------------ // Netscape Required // // //------------------------------------------------------------------------ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GetAttributeValue\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pTemplate) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } if (ulCount == 0) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetAttributeValue) { // Map the Session to the slot session rv = fcn->ST_GetAttributeValue(sltp->TokData, &rSession, hObject, pTemplate, ulCount); TRACE_DEVEL("fcn->ST_GetAttributeValue returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetAttributeValue //------------------------------------------------------------------------ // API function C_GetFunctionList //------------------------------------------------------------------------ // Netscape Required CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { api_init(); TRACE_INFO("C_GetFunctionList\n"); FuncList.version.major = VERSION_MAJOR; FuncList.version.minor = VERSION_MINOR; FuncList.C_Initialize = C_Initialize; FuncList.C_Finalize = C_Finalize; FuncList.C_GetInfo = C_GetInfo; FuncList.C_GetFunctionList = C_GetFunctionList; FuncList.C_GetSlotList = C_GetSlotList; FuncList.C_GetSlotInfo = C_GetSlotInfo; FuncList.C_GetTokenInfo = C_GetTokenInfo; FuncList.C_GetMechanismList = C_GetMechanismList; FuncList.C_GetMechanismInfo = C_GetMechanismInfo; FuncList.C_InitToken = C_InitToken; FuncList.C_InitPIN = C_InitPIN; FuncList.C_SetPIN = C_SetPIN; FuncList.C_OpenSession = C_OpenSession; FuncList.C_CloseSession = C_CloseSession; FuncList.C_CloseAllSessions = C_CloseAllSessions; FuncList.C_GetSessionInfo = C_GetSessionInfo; FuncList.C_GetOperationState = C_GetOperationState; FuncList.C_SetOperationState = C_SetOperationState; FuncList.C_Login = C_Login; FuncList.C_Logout = C_Logout; FuncList.C_CreateObject = C_CreateObject; FuncList.C_CopyObject = C_CopyObject; FuncList.C_DestroyObject = C_DestroyObject; FuncList.C_GetObjectSize = C_GetObjectSize; FuncList.C_GetAttributeValue = C_GetAttributeValue; FuncList.C_SetAttributeValue = C_SetAttributeValue; FuncList.C_FindObjectsInit = C_FindObjectsInit; FuncList.C_FindObjects = C_FindObjects; FuncList.C_FindObjectsFinal = C_FindObjectsFinal; FuncList.C_EncryptInit = C_EncryptInit; FuncList.C_Encrypt = C_Encrypt; FuncList.C_EncryptUpdate = C_EncryptUpdate; FuncList.C_EncryptFinal = C_EncryptFinal; FuncList.C_DecryptInit = C_DecryptInit; FuncList.C_Decrypt = C_Decrypt; FuncList.C_DecryptUpdate = C_DecryptUpdate; FuncList.C_DecryptFinal = C_DecryptFinal; FuncList.C_DigestInit = C_DigestInit; FuncList.C_Digest = C_Digest; FuncList.C_DigestUpdate = C_DigestUpdate; FuncList.C_DigestKey = C_DigestKey; FuncList.C_DigestFinal = C_DigestFinal; FuncList.C_SignInit = C_SignInit; FuncList.C_Sign = C_Sign; FuncList.C_SignUpdate = C_SignUpdate; FuncList.C_SignFinal = C_SignFinal; FuncList.C_SignRecoverInit = C_SignRecoverInit; FuncList.C_SignRecover = C_SignRecover; FuncList.C_VerifyInit = C_VerifyInit; FuncList.C_Verify = C_Verify; FuncList.C_VerifyUpdate = C_VerifyUpdate; FuncList.C_VerifyFinal = C_VerifyFinal; FuncList.C_VerifyRecoverInit = C_VerifyRecoverInit; FuncList.C_VerifyRecover = C_VerifyRecover; FuncList.C_DigestEncryptUpdate = C_DigestEncryptUpdate; FuncList.C_DecryptDigestUpdate = C_DecryptDigestUpdate; FuncList.C_SignEncryptUpdate = C_SignEncryptUpdate; FuncList.C_DecryptVerifyUpdate = C_DecryptVerifyUpdate; FuncList.C_GenerateKey = C_GenerateKey; FuncList.C_GenerateKeyPair = C_GenerateKeyPair; FuncList.C_WrapKey = C_WrapKey; FuncList.C_UnwrapKey = C_UnwrapKey; FuncList.C_DeriveKey = C_DeriveKey; FuncList.C_SeedRandom = C_SeedRandom; FuncList.C_GenerateRandom = C_GenerateRandom; FuncList.C_GetFunctionStatus = C_GetFunctionStatus; FuncList.C_CancelFunction = C_CancelFunction; FuncList.C_WaitForSlotEvent = C_WaitForSlotEvent; if (ppFunctionList) { (*ppFunctionList) = &FuncList; return CKR_OK; } TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } //------------------------------------------------------------------------ // API function C_GetFunctionStatus //------------------------------------------------------------------------ CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession) { UNUSED(hSession); TRACE_INFO("C_GetFunctionStatus\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_PARALLEL)); return CKR_FUNCTION_NOT_PARALLEL; // PER Specification PG 170 } //------------------------------------------------------------------------ // API function C_GetInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetInfo(CK_INFO_PTR pInfo) { Slot_Mgr_Socket_t *shData; TRACE_INFO("C_GetInfo\n"); if (!API_Initialized()) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } shData = &(Anchor->SocketDataP); if (!pInfo) { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } CK_Info_From_Internal(pInfo, &(shData->ck_info)); return CKR_OK; } // end of C_GetInfo //------------------------------------------------------------------------ // API function C_GetMechanismInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; TRACE_INFO("C_GetMechansimInfo %lu %lx %p\n", slotID, type, (void *)pInfo); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetMechanismInfo) { rv = fcn->ST_GetMechanismInfo(sltp->TokData, slotID, type, pInfo); TRACE_DEVEL("fcn->ST_GetMechanismInfo returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetMechanismInfo //------------------------------------------------------------------------ // API function C_GetMechanismList //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; TRACE_INFO("C_GetMechanismList\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } // Always have to have a pulCount if (!pulCount) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } TRACE_DEVEL("Slot %lu MechList %p Count %lu\n", slotID, (void *)pMechanismList, *pulCount); // Null PMechanism is valid to get a count of mechanisms if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetMechanismList) { rv = fcn->ST_GetMechanismList(sltp->TokData, slotID, pMechanismList, pulCount); TRACE_DEVEL("fcn->ST_GetMechanismList returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } if (rv == CKR_OK) { if (pMechanismList) { unsigned long i; for (i = 0; i < *pulCount; i++) { TRACE_DEVEL("Mechanism[%lu] 0x%08lX \n", i, pMechanismList[i]); } } } return rv; } // end of C_GetMechanismList //------------------------------------------------------------------------ // API function C_GetObjectSize //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GetObjectSize\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pulSize) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetObjectSize) { // Map the Session to the slot session rv = fcn->ST_GetObjectSize(sltp->TokData, &rSession, hObject, pulSize); TRACE_DEVEL("fcn->ST_GetObjectSize retuned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetObjectSize //------------------------------------------------------------------------ // API function C_GetOperationState //------------------------------------------------------------------------ CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GetOperateionState\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } // NULL pOperationState is valid to get buffer // size if (!pulOperationStateLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetOperationState) { // Map the Session to the slot session rv = fcn->ST_GetOperationState(sltp->TokData, &rSession, pOperationState, pulOperationStateLen); TRACE_DEVEL("fcn->ST_GetOperationState returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_GetSessionInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_GetSessionInfo %lx %p\n", hSession, (void *)pInfo); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pInfo) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetSessionInfo) { // Map the Session to the slot session rv = fcn->ST_GetSessionInfo(sltp->TokData, &rSession, pInfo); TRACE_DEVEL("fcn->ST_GetSessionInfo returned: 0x%lx\n", rv); TRACE_DEVEL("Slot %lu State %lx Flags %lx DevErr %lx\n", pInfo->slotID, pInfo->state, pInfo->flags, pInfo->ulDeviceError); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetSessionInfo //------------------------------------------------------------------------ // API function C_GetSlotInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ #ifdef PKCS64 CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { Slot_Info_t_64 *sinfp; Slot_Mgr_Socket_t *shData; TRACE_INFO("C_GetSlotInfo Slot=%lu ptr=%p\n", slotID, (void *)pInfo); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } shData = &(Anchor->SocketDataP); if (!pInfo) { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } sinfp = shData->slot_info; sinfp += slotID; if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } // Netscape and others appear to call // this for every slot. If the slot does not have // a registered STDLL, then this is a FUnction Failed case if (sinfp->present == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } #ifdef __64BIT__ memcpy(pInfo, (char *) &(sinfp->pk_slot), sizeof(CK_SLOT_INFO)); #else memcpy((char *) &(pInfo->slotDescription[0]), (char *) &(sinfp->pk_slot.slotDescription[0]), sizeof(pInfo->slotDescription)); memcpy((char *) &(pInfo->manufacturerID[0]), (char *) &(sinfp->pk_slot.manufacturerID[0]), sizeof(pInfo->manufacturerID)); pInfo->flags = sinfp->pk_slot.flags; pInfo->hardwareVersion = sinfp->pk_slot.hardwareVersion; pInfo->firmwareVersion = sinfp->pk_slot.firmwareVersion; #endif return CKR_OK; } // end of C_GetSlotInfo #else CK_RV C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { uint16 count; uint16 index; uint16 sindx; Slot_Info_t *sinfp; Slot_Mgr_Socket_t *shData = &(Anchor->SocketDataP); TRACE_INFO("C_GetSlotInfo Slot=%d ptr=%p\n", slotID, (void *)pInfo); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pInfo) { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } sinfp = shData->slot_info; sinfp += slotID; count = 0; if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } // Netscape and others appear to call // this for every slot. If the slot does not have // a registered STDLL, then this is a FUnction Failed case if (sinfp->present == FALSE) { TRACE_ERROR("%s: No STDLL present.\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } memcpy(pInfo, (char *) &(sinfp->pk_slot), sizeof(CK_SLOT_INFO)); return CKR_OK; } // end of C_GetSlotInfo #endif //------------------------------------------------------------------------ // API function C_GetSlotList //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { CK_ULONG count; uint16 index; uint16 sindx; Slot_Mgr_Socket_t *shData; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif TRACE_INFO("C_GetSlotList\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } shData = &(Anchor->SocketDataP); // Null pSlotList is valid to get count for array allocation if (pulCount == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } TRACE_DEVEL(" Present %d Count %lu\n", tokenPresent, *pulCount); sinfp = shData->slot_info; count = 0; // Count the slots based off the present flag // Go through all the slots and count them up // Remember if the tokenPresent Flag is set do not count the // not present ones. // // ------------------------------------------------------------ // // Present indicates that the slot is managed by the Slot manager // and that an appropriate registration has been made in the DB // // It does not imply that a token is present. // Slots with STDLL's are ALWAYS present in the system wether they // have a token or not is determined from the token functions. // // According to the spec the tokenPresent flag indicates if all // slots are wanted, or those which have tokens present. We will // use this to mean if a STDLL is present or not. All slots // are in the system, if a STDLL is attached to a slot, then it is // present( not to be confused with the Tokens flags indicating // presence). Presence of a STDLL on a slot indicates that there // is a "token reader" available. // // Note: All slots should be named by the slot manager with the // slot id in them... // ------------------------------------------------------------ // // Note: The CK_INFO_STRUCT present flag indicates that a token is present // in the reader located in the slot. Right now we are dealing only // with non-removable tokens, so the slot flags set in the slot DB // are fixed by the STDLL. Ultimately when we get to removable tokens, the // slot manager will have to monitor the device in the slot and set the flag // accordingly. // // This does however change the reporting back of Slot Lists... // // We were using the presence of a STDLL to indicate if a Token is present // or not. however we need to report back based on 2 flags. // // First a stdll must be in the table, second the slot info flags must be // set to present to return. // ---------------------------------------------- // // Also need to validate that the STDLL successfully loaded. for (index = 0; index < NUMBER_SLOTS_MANAGED; index++) { // if there is a STDLL in the slot then we have to count it // otherwise the slot is NOT counted. if (sinfp[index].present == TRUE && slot_loaded[index] == TRUE) { if (tokenPresent) { if ((sinfp[index].pk_slot.flags & CKF_TOKEN_PRESENT)) { count++; } } else { count++; } } } // If only the count is wanted then we set the value and exit if (pSlotList == NULL) { *pulCount = count; return CKR_OK; } // Verify that the buffer passed is large enough if (*pulCount < count) { TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL)); *pulCount = count; return CKR_BUFFER_TOO_SMALL; } *pulCount = count; // Walk through the slot manager information and copy in the // slot id to the list of slot indexes. // // This is incorrectly going to assume that the slots are // sequentialy allocated. While most likely we should be robust // and handle it. // Count should correct based on the first loop. // for (sindx = 0, index = 0; (index < NUMBER_SLOTS_MANAGED) && (sindx < count); index++) { if (sinfp[index].present == TRUE && slot_loaded[index] == TRUE) { if (tokenPresent) { if (sinfp[index].pk_slot.flags & CKF_TOKEN_PRESENT) { pSlotList[sindx] = sinfp[index].slot_number; sindx++; // only increment when we have used it. } } else { pSlotList[sindx] = sinfp[index].slot_number; sindx++; // only increment when we have used it. } } } return CKR_OK; } // end of C_GetSlotList //------------------------------------------------------------------------ // API function C_GetTokenInfo //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; Slot_Mgr_Socket_t *shData; #ifdef PKCS64 Slot_Info_t_64 *sinfp; #else Slot_Info_t *sinfp; #endif TRACE_INFO("C_GetTokenInfo\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } shData = &(Anchor->SocketDataP); if (!pInfo) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[slotID]); TRACE_DEVEL("Slot p = %p id %lu\n", (void *)sltp, slotID); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } // Need to check if the slot is not populated // then we can return the proper return code for a // slot that has no content. sinfp = shData->slot_info; if (sinfp[slotID].present == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_GetTokenInfo) { rv = fcn->ST_GetTokenInfo(sltp->TokData, slotID, pInfo); if (rv == CKR_OK) { get_sess_count(slotID, &(pInfo->ulSessionCount)); } TRACE_DEVEL("rv %lu CK_TOKEN_INFO Flags %lx\n", rv, pInfo->flags); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_GetTokenInfo void Call_Finalize() { C_Finalize(NULL); return; } //------------------------------------------------------------------------ // API function C_Initialize //------------------------------------------------------------------------ // Netscape Required // // //------------------------------------------------------------------------ CK_RV C_Initialize(CK_VOID_PTR pVoid) { CK_C_INITIALIZE_ARGS *pArg; char fcnmap = 0; CK_RV rc = CKR_OK; /* * Lock so that only one thread can run C_Initialize or C_Finalize at * a time */ pthread_mutex_lock(&GlobMutex); trace_initialize(); TRACE_INFO("C_Initialize\n"); if (!Anchor) { Anchor = (API_Proc_Struct_t *) malloc(sizeof(API_Proc_Struct_t)); if (Anchor == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); rc = CKR_HOST_MEMORY; goto done; } } else { // Linux the atfork routines handle this TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_ALREADY_INITIALIZED)); rc = CKR_CRYPTOKI_ALREADY_INITIALIZED; goto done; } // Clear out the load list memset(slot_loaded, 0, sizeof(int) * NUMBER_SLOTS_MANAGED); TRACE_DEBUG("Anchor allocated at %s\n", (char *) Anchor); // Validation of the parameters passed // if pVoid is NULL, then everything is OK. The applicaiton // will not be doing multi thread accesses. We can use the OS // locks anyhow. // if (pVoid != NULL) { TRACE_DEVEL("Initialization arg = %p Flags %lu\n", pVoid, ((CK_C_INITIALIZE_ARGS *) pVoid)->flags); pArg = (CK_C_INITIALIZE_ARGS *) pVoid; // Check for a pReserved set if (pArg->pReserved != NULL) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); rc = CKR_ARGUMENTS_BAD; goto error; } // Set up a bit map indicating the presense of the functions. fcnmap = (pArg->CreateMutex ? 0x01 << 0 : 0); fcnmap |= (pArg->DestroyMutex ? 0x01 << 1 : 0); fcnmap |= (pArg->LockMutex ? 0x01 << 2 : 0); fcnmap |= (pArg->UnlockMutex ? 0x01 << 3 : 0); // Verify that all or none of the functions are set if (fcnmap != 0) { if (fcnmap != 0x0f) { OCK_SYSLOG(LOG_ERR, "C_Initialize: Invalid " "number of functions passed in " "argument structure.\n"); rc = CKR_ARGUMENTS_BAD; goto error; } } // If we EVER need to create threads from this library we must // check the Flags for the Can_Create_OS_Threads flag // Right now the library DOES NOT create threads and therefore this // check is irrelavant. if (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) { TRACE_DEVEL("Can't create OS threads...This is OK\n"); } // Since this is an initialization path, we will be verbose in the // code rather than efficient. // // in reality, we only need to check for case 3 since all others // are acceptable to us... for one reason or another. // // Case 1 Flag not set and functiopn pointers NOT supplied if (!(pArg->flags & CKF_OS_LOCKING_OK) && !(fcnmap)) { ; // This is COOL. Same as a NUL pointer Locking is irrelavent. } else { // Case 2. Flags set and Fcn pointers NOT supplied. if ((pArg->flags & CKF_OS_LOCKING_OK) && !(fcnmap)) { ; // This to is COOL since we require native locking } else { // Case 3 Flag Not set and pointers supplied. Can't handle this // one. if (!(pArg->flags & CKF_OS_LOCKING_OK) && fcnmap) { OCK_SYSLOG(LOG_ERR, "C_Initialize: " "Application specified that " "OS locking is invalid. " "PKCS11 Module requires OS " "locking.\n"); // Only support Native OS locking. rc = CKR_CANT_LOCK; goto error; } else { // Case 4 Flag set and fcn pointers set if ((pArg->flags & CKF_OS_LOCKING_OK) && fcnmap) { ; // This is also cool. } else { // Were really hosed here since this should not have // occured TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR)); rc = CKR_GENERAL_ERROR; goto error; } } } } } else { // Pointer to void... // This is OK we can go on from here. ; } // Create the shared memory lock. if (CreateProcLock() != CKR_OK) { TRACE_ERROR("Process Lock Failed.\n"); rc = CKR_FUNCTION_FAILED; goto error; } //Zero out API_Proc_Struct //Map Shared Memory Region //if ( Shared Memory Mapped not Successful ) // Free allocated Memory // Return CKR_HOST_MEMORY memset((char *) Anchor, 0, sizeof(API_Proc_Struct_t)); bt_init(&Anchor->sess_btree, free); Anchor->Pid = getpid(); // Get shared memory if ((Anchor->SharedMemP = attach_shared_memory()) == NULL) { OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to attach to " "shared memory. Verify that the slot management " "daemon is running, errno=%d\n", errno); TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); rc = CKR_HOST_MEMORY; goto error; } TRACE_DEBUG("Shared memory %p \n", Anchor->SharedMemP); if (!init_socket_data()) { OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to create a " "socket. Verify that the slot management daemon is " "running.\n"); TRACE_ERROR("Cannot attach to socket.\n"); rc = CKR_FUNCTION_FAILED; goto error_shm; } // Initialize structure values //Register with pkcsslotd if (!API_Register()) { // free memory allocated // return CKR_FUNCTION_FAILED // return CKR_FUNCTION_NOT_SUPPORTED; TRACE_ERROR("Failed to register process with pkcsslotd.\n"); rc = CKR_FUNCTION_FAILED; goto error_shm; } // // load all the slot DLL's here { CK_SLOT_ID slotID; API_Slot_t *sltp; for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { sltp = &(Anchor->SltList[slotID]); slot_loaded[slotID] = DL_Load_and_Init(sltp, slotID); } } pthread_mutex_unlock(&GlobMutex); return CKR_OK; error_shm: detach_shared_memory(Anchor->SharedMemP); error: bt_destroy(&Anchor->sess_btree); free((void *) Anchor); Anchor = NULL; done: pthread_mutex_unlock(&GlobMutex); return rc; } // end of C_Initialize //------------------------------------------------------------------------ // API function C_InitPIN //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_InitPin\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } // A Null Pin with a Len is invalid // A Null pin with a 0 len is no pin at all? if (!pPin && ulPinLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); // XXX Remove me, this test should be completely unnecessary // Move this to after the session validation... if (rSession.slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_InitPIN) { // Map the Session to the slot session rv = fcn->ST_InitPIN(sltp->TokData, &rSession, pPin, ulPinLen); TRACE_DEVEL("fcn->ST_InitPIN returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_InitPIN //------------------------------------------------------------------------ // API function C_InitToken //------------------------------------------------------------------------ //Netscape NEVER Calls this according to the Netscape documentation CK_RV C_InitToken(CK_SLOT_ID slotID, CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_CHAR_PTR pLabel) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; TRACE_INFO("C_InitToken\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } // Null pPin and a pinlen is a problem if (!pPin && ulPinLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!pLabel) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } // Prior to invoking the Tokens initialization, the // API needs to verify that NO other applications have any // sessions established with this particular slot // // Hooks into the shared memory to determine how many sessions // on a given token are open need to be added. // When a session is opened, it increments the count. When // closed it decrements the count. Protected by an MUTEX // In the shared memory region the slot_info[slotID].sesscount // variable needs to be checked, and held locked until the operation // is complete. if (sessions_exist(slotID)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_EXISTS)); return CKR_SESSION_EXISTS; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_InitToken) { rv = fcn->ST_InitToken(sltp->TokData, slotID, pPin, ulPinLen, pLabel); TRACE_DEVEL("fcn->ST_InitToken returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Login //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Login\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } #if 0 /* Allow incorrect PIN checks to fall into the SC_Login * function, since v2.11 requires flags to be set. - KEY */ if (!pPin) { return CKR_PIN_INCORRECT; } #endif if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Login) { // Map the Session to the slot session rv = fcn->ST_Login(sltp->TokData, &rSession, userType, pPin, ulPinLen); TRACE_DEVEL("fcn->ST_Login returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Login //------------------------------------------------------------------------ // API function C_Logout //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Logout(CK_SESSION_HANDLE hSession) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Logout\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Logout) { // Map the Session to the slot session rv = fcn->ST_Logout(sltp->TokData, &rSession); TRACE_DEVEL("fcn->ST_Logout returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Logout //------------------------------------------------------------------------ // API function C_OpenSession //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ // // Note: Need to worry about handling the Notify and Applicaiton call backs // that are here... STDLL will NEVER deal with these... The // usage of them appears to be optional from the specification // but we may need to do something with them at a later date. // CK_RV C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T *apiSessp; TRACE_INFO("C_OpenSession %lu %lx %p %p %p\n", slotID, flags, pApplication, *(void **)(&Notify), *(void **)(&phSession)); if (!(flags & CKF_SERIAL_SESSION)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_PARALLEL_NOT_SUPPORTED)); return CKR_SESSION_PARALLEL_NOT_SUPPORTED; } if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (slotID >= NUMBER_SLOTS_MANAGED) { TRACE_ERROR("%s\n", ock_err(ERR_SLOT_ID_INVALID)); return CKR_SLOT_ID_INVALID; } if (!phSession) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; // // Need to handle the failure of a load here... } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((apiSessp = (ST_SESSION_T *) malloc(sizeof(ST_SESSION_T))) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } if (fcn->ST_OpenSession) { rv = fcn->ST_OpenSession(sltp->TokData, slotID, flags, &(apiSessp->sessionh)); TRACE_DEVEL("fcn->ST_OpenSession returned: 0x%lx\n", rv); // If the session allocation is successful, then we need to // complete the API session block and return. Otherwise // we free the API session block and exit if (rv == CKR_OK) { /* add a refernece to this handle/slot_id pair to the binary tree we * maintain at the API level, returning the API-level object's * handle as the session handle the app will get */ *phSession = AddToSessionList(apiSessp); if (*phSession == 0) { /* failed to add the object to the API-level tree, close the * STDLL-level session and return failure */ fcn->ST_CloseSession(sltp->TokData, apiSessp, FALSE); free(apiSessp); rv = CKR_HOST_MEMORY; goto done; } apiSessp->slotID = slotID; // NOTE: Need to add Session counter to the shared // memory slot value.... Atomic operation. // sharedmem->slot_info[slotID].sessioncount incremented // when ever a session is attached. // Also increment the per process slot counter to indicate // how many sessions this process owns of the total amount. This // way if the process abends garbage collection in the slot manager // can adequatly clean up the total count value... incr_sess_counts(slotID); } else { free(apiSessp); } } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); free(apiSessp); rv = CKR_FUNCTION_NOT_SUPPORTED; } done: return rv; } // end of C_OpenSession //------------------------------------------------------------------------ // API function C_SeedRandom //------------------------------------------------------------------------ CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SeedRandom\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pSeed && ulSeedLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SeedRandom) { // Map the Session to the slot session rv = fcn->ST_SeedRandom(sltp->TokData, &rSession, pSeed, ulSeedLen); TRACE_DEVEL("fcn->ST_SeedRandom returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_SetAttributeValue //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SetAttributeValue\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); if (!pTemplate) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } if (!ulCount) { TRACE_ERROR("%s\n", ock_err(ERR_TEMPLATE_INCOMPLETE)); return CKR_TEMPLATE_INCOMPLETE; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SetAttributeValue) { // Map the Session to the slot session rv = fcn->ST_SetAttributeValue(sltp->TokData, &rSession, hObject, pTemplate, ulCount); TRACE_DEVEL("fcn->ST_SetAttributeValue returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SetAttributeValue //------------------------------------------------------------------------ // API function C_SetOperationState //------------------------------------------------------------------------ CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SetOperationState\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); if (!pOperationState || ulOperationStateLen == 0) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SetOperationState) { // Map the Session to the slot session rv = fcn->ST_SetOperationState(sltp->TokData, &rSession, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey); TRACE_DEVEL("fcn->ST_SetOperationState returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_SetPIN //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SetPIN\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pOldPin || !pNewPin) return CKR_PIN_INVALID; if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SetPIN) { // Map the Session to the slot session rv = fcn->ST_SetPIN(sltp->TokData, &rSession, pOldPin, ulOldLen, pNewPin, ulNewLen); TRACE_DEVEL("fcn->ST_SetPIN returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SetPIN //------------------------------------------------------------------------ // API function C_Sign //------------------------------------------------------------------------ // Netscape Required // // // //------------------------------------------------------------------------ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Sign\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pulSignatureLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Sign) { // Map the Session to the slot session rv = fcn->ST_Sign(sltp->TokData, &rSession, pData, ulDataLen, pSignature, pulSignatureLen); TRACE_DEVEL("fcn->ST_Sign returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_Sign //------------------------------------------------------------------------ // API function C_SignEncryptUpdate //------------------------------------------------------------------------ CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SignEncryptUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pPart || !pulEncryptedPartLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignEncryptUpdate) { // Map the Session to the slot session rv = fcn->ST_SignEncryptUpdate(sltp->TokData, &rSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); TRACE_DEVEL("fcn->ST_SignEncryptUpdate return: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_SignFinal //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SignEncryptUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pulSignatureLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignFinal) { // Map the Session to the slot session rv = fcn->ST_SignFinal(sltp->TokData, &rSession, pSignature, pulSignatureLen); TRACE_DEVEL("fcn->ST_SignFinal returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SignFinal //------------------------------------------------------------------------ // API function C_SignInit //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SignInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignInit) { // Map the Session to the slot session rv = fcn->ST_SignInit(sltp->TokData, &rSession, pMechanism, hKey); TRACE_DEVEL("fcn->ST_SignInit returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SignInit //------------------------------------------------------------------------ // API function C_SignRecover //------------------------------------------------------------------------ CK_RV C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SignRecover\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pulSignatureLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignRecover) { // Map the Session to the slot session rv = fcn->ST_SignRecover(sltp->TokData, &rSession, pData, ulDataLen, pSignature, pulSignatureLen); TRACE_DEVEL("fcn->ST_SignRecover returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_SignRecoverInit //------------------------------------------------------------------------ CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SignRecoverInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignRecoverInit) { // Map the Session to the slot session rv = fcn->ST_SignRecoverInit(sltp->TokData, &rSession, pMechanism, hKey); TRACE_DEVEL("fcn->ST_SignRecoverInit returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_SignUpdate //------------------------------------------------------------------------ // // // //------------------------------------------------------------------------ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_SignUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_SignUpdate) { // Map the Session to the slot session rv = fcn->ST_SignUpdate(sltp->TokData, &rSession, pPart, ulPartLen); TRACE_DEVEL("fcn->ST_SignUpdate returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } // end of C_SignUpdate //------------------------------------------------------------------------ // API function C_UnwrapKey //------------------------------------------------------------------------ // Netscape Required CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_UnwrapKey\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!phKey) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } // what about the other pointers... probably need // to be set correctly if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_UnwrapKey) { // Map the Session to the slot session rv = fcn->ST_UnwrapKey(sltp->TokData, &rSession, pMechanism, hUnwrappingKey, pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey); TRACE_DEVEL("fcn->ST_UnwrapKey returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_Verify //------------------------------------------------------------------------ // Netscape Required CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_Verify\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pData || !pSignature) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_Verify) { // Map the Session to the slot session rv = fcn->ST_Verify(sltp->TokData, &rSession, pData, ulDataLen, pSignature, ulSignatureLen); TRACE_DEVEL("fcn->ST_Verify returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyFinal //------------------------------------------------------------------------ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_VerifyFinal\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pSignature) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyFinal) { // Map the Session to the slot session rv = fcn->ST_VerifyFinal(sltp->TokData, &rSession, pSignature, ulSignatureLen); TRACE_DEVEL("fcn->ST_VerifyFinal returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyInit //------------------------------------------------------------------------ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_VerifyInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyInit) { // Map the Session to the slot session rv = fcn->ST_VerifyInit(sltp->TokData, &rSession, pMechanism, hKey); TRACE_DEVEL("fcn->ST_VerifyInit returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyRecover //------------------------------------------------------------------------ // Netscape Required CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_VerifyRecover\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pSignature || !pulDataLen) { TRACE_ERROR("%s\n", ock_err(ERR_ARGUMENTS_BAD)); return CKR_ARGUMENTS_BAD; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyRecover) { // Map the Session to the slot session rv = fcn->ST_VerifyRecover(sltp->TokData, &rSession, pSignature, ulSignatureLen, pData, pulDataLen); TRACE_DEVEL("fcn->ST_VerifyRecover returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyRecoverInit //------------------------------------------------------------------------ CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_VerifyRecoverInit\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyRecoverInit) { // Map the Session to the slot session rv = fcn->ST_VerifyRecoverInit(sltp->TokData, &rSession, pMechanism, hKey); TRACE_DEVEL("fcn->ST_VerifyRecoverInit returned:0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_VerifyUpdate //------------------------------------------------------------------------ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_VerifyUpdate\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_VerifyUpdate) { // Map the Session to the slot session rv = fcn->ST_VerifyUpdate(sltp->TokData, &rSession, pPart, ulPartLen); TRACE_DEVEL("fcn->ST_VerifyUpdate returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } //------------------------------------------------------------------------ // API function C_WaitForSlotEvent //------------------------------------------------------------------------ // // //NOTE: We need to implement this one even though Netscape does not //make use of this... // //Standard code template won't work with this. We need to look at //the slot manager and the shared memory indicating the slot bitmap //Blocking needs to be worked out. At the initial release do not //support BLocked calls on wait for slot event. // //Support Note: //This function is really used for removable tokens, and is pretty //inefficient. It may be best to return CKR_FUNCTION_UNSUPPORTED //if it becomes a field issue, until removable token support is fully //implemented. Be forewarned. //------------------------------------------------------------------------ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved) { UNUSED(flags); UNUSED(pSlot); UNUSED(pReserved); #ifdef PLUGGABLE_TOKENS_SUPPORTED #ifdef PKCS64 Slot_Mgr_Proc_t_64 *procp; #else Slot_Mgr_Proc_t *procp; #endif #endif TRACE_INFO("C_WaitForSlotEvent\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } #ifndef PLUGGABLE_TOKENS_SUPPORTED // Since there are no tokens which we support that have the // ability to create slot events, and slotd does not // fully support this (it needs to be aware of the functions exported // by an STDLL to poll the slot for a token event and this // has not been fully implemented at this time, although the // design and structure of the shared memory in slotd do. TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); return CKR_FUNCTION_NOT_SUPPORTED; #else // Get the pointer to the process element.. // This could be done in a single line, but for readability we do it // in 2 steps. shm = Anchor->SharedMemP; procp = &shm->proc_table[Anchor->MgrProcIndex]; // Grab the mutex for the application in shared memory // Check the bit mask for non-zero. If the bit mask is non-zero // find the first slot which is set and set the pSlot value // and return CKR_OK. // for now we will just lock the whole shared memory // REally should be the procp->proc_mutex // but this is such an infrequent thing that we will simply get // the global shared memory lock ProcLock(); if (procp->slotmap) { // find the first bit set // This will have to change if more than 32 slots ever get supported // including the test for a bit turned on.. for (i = 0; NUMBER_SLOTS_MANAGED; i++) { if (procp->slotmap & (1 << i)) { break; } } *pSlot = i; // set the flag ProcUnLock(); return CKR_OK; } else { if (flags & CKF_DONT_BLOCK) { ProcUnLock(); return CKR_NO_EVENT; } else { // WE need to // 1. Set the blocking variable in the system map to true. // 2. clear the condition variable // // Note: for now we will just poll the bitmap every // second or look for the error field to go to true. // Check first if we are already blocking on another thread // for this process. According to the spec this behavior is // undefined. // We will choose to fail the call. if (procp->blocking) { TRACE_DEVEL("WaitForSlot event called by process twice.\n"); ProcUnLock(); // Unlock aftersetting TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); return CKR_FUNCTION_FAILED; } procp->error = 0; procp->blocking = 0x01; ProcUnLock(); // Unlock aftersetting // NOTE: We need to have an asynchronous mechanism for // the slot manager to wake up anyone blocking on this. // But Since we are not supporting removable tokens, this // call should be almos never made. It might be best to // return CKR_FUNCTION_UNSUPPORTED, but we'll wait and see. while (!procp->slotmap && !procp->error) { // Note This is really bad form. But what the heck sleep(1); } ProcLock(); procp->blocking = 0; if (procp->error) { ProcUnLock(); TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR)); return CKR_GENERAL_ERROR; // We bailed on this because we were terminating // General error should cause the calling thread to not try // anything else... We need to look at how this holds up in // practice. } else { // must have fallen out of loop because of a slot getting an // event for (i = 0; NUMBER_SLOTS_MANAGED; i++) { if (procp->slotmap & (1 << i)) { break; } } *pSlot = i; // set the flag ProcUnLock(); return CKR_OK; } } } #endif } // end of C_WaitForSlotEvent //------------------------------------------------------------------------ // API function // C_WrapKey //------------------------------------------------------------------------ // Netscape Required CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) { CK_RV rv; API_Slot_t *sltp; STDLL_FcnList_t *fcn; ST_SESSION_T rSession; TRACE_INFO("C_WrapKey\n"); if (API_Initialized() == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); return CKR_CRYPTOKI_NOT_INITIALIZED; } if (!pMechanism) { TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } // other pointers??? if (!Valid_Session(hSession, &rSession)) { TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID)); TRACE_ERROR("Session handle id: %lu\n", hSession); return CKR_SESSION_HANDLE_INVALID; } TRACE_INFO("Valid Session handle id: %lu\n", rSession.sessionh); sltp = &(Anchor->SltList[rSession.slotID]); if (sltp->DLLoaded == FALSE) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if ((fcn = sltp->FcnList) == NULL) { TRACE_ERROR("%s\n", ock_err(ERR_TOKEN_NOT_PRESENT)); return CKR_TOKEN_NOT_PRESENT; } if (fcn->ST_WrapKey) { // Map the Session to the slot session rv = fcn->ST_WrapKey(sltp->TokData, &rSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen); TRACE_DEVEL("fcn->ST_WrapKey returned: 0x%lx\n", rv); } else { TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); rv = CKR_FUNCTION_NOT_SUPPORTED; } return rv; } #ifdef __sun #pragma init(api_init) #else void api_init(void) __attribute__ ((constructor)); #endif void api_init(void) { // Should only have to do the atfork stuff at load time... if (!Initialized) { pthread_atfork(NULL, NULL, (void (*)()) child_fork_initializer); Initialized = 1; } } #ifdef __sun #pragma fini(api_fini) #else void api_fini(void) __attribute__ ((destructor)); #endif void api_fini() { if (API_Initialized() == TRUE) { Call_Finalize(); } }