CK_DEFINE_FUNCTION(CK_RV, C_InitPIN) ( CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pSession->State != RWSecurityOfficer) { return CKR_USER_NOT_LOGGED_IN; } if(pSession->Token->SessionMgmt != NULL && pSession->Token->SessionMgmt->InitPin != NULL) { ret = pSession->Token->SessionMgmt->InitPin(&pSession->Context, pPin, ulPinLen); } else { ret = CKR_FUNCTION_NOT_SUPPORTED; } return ret; }
/* C_Logout logs a user out from a token. */ CK_DEFINE_FUNCTION(CK_RV, C_Logout) ( CK_SESSION_HANDLE hSession /* the session's handle */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pSession->State <= RWPublic && pSession->State != ROUser) return CKR_USER_NOT_LOGGED_IN; if(pSession->Token->SessionMgmt == NULL) { ret = pSession->Token->SessionMgmt->Logout(&pSession->Context); } // back to public session (ro or rw) pSession->State = (CryptokiSessionState)((pSession->State & ReadWriteFlag) | ROPublic); if(pSession->IsLoginContext) { pSession->IsLoginContext = FALSE; } else { pSession->Token->TokenWideState = ROPublic; } return ret; }
/* C_DestroyObject destroys an object. */ CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject /* the object's handle */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->DestroyObject) { ret = pSession->Token->ObjectMgmt->DestroyObject(&pSession->Context, hObject); #ifdef _DEBUG pSession->RemoveObjectHandle(hObject); #endif return ret; } return CKR_FUNCTION_NOT_SUPPORTED; }
/* C_CopyObject copies an object, creating a new object for the * copy. */ CK_DEFINE_FUNCTION(CK_RV, C_CopyObject) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ CK_ULONG ulCount, /* attributes in template */ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pTemplate == NULL ) return CKR_ARGUMENTS_BAD; if(phNewObject == NULL ) return CKR_ARGUMENTS_BAD; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->CopyObject) { ret = pSession->Token->ObjectMgmt->CopyObject(&pSession->Context, hObject, pTemplate, ulCount, phNewObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phNewObject); } #endif return ret; } return CKR_FUNCTION_NOT_SUPPORTED; }
/* C_Login logs a user into a token. */ CK_DEFINE_FUNCTION(CK_RV, C_Login) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_USER_TYPE userType, /* the user type */ CK_UTF8CHAR_PTR pPin, /* the user's PIN */ CK_ULONG ulPinLen /* the length of the PIN */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(userType > 2 ) return CKR_USER_TYPE_INVALID; if(pSession->State > RWPublic || pSession->State == ROUser) return CKR_USER_ALREADY_LOGGED_IN; if(pSession->Token->TokenInfo.ulSessionCount > 0 && userType == CKU_SO) return CKR_SESSION_READ_ONLY_EXISTS; if(pSession->Token->TokenWideState != ROPublic) return CKR_USER_ANOTHER_ALREADY_LOGGED_IN; if(pSession->Token->SessionMgmt == NULL) { if(CKR_OK == (ret = pSession->Token->SessionMgmt->Login(&pSession->Context, userType, pPin, ulPinLen))) { // use |= to maintain the r/w flag pSession->State = (CryptokiSessionState)((pSession->State & ReadWriteFlag) | (userType == CKU_SO ? RWSecurityOfficer : ROUser)); } } else { // TODO: blindly accept or check PIN with encrypted pin stored somewhere? pSession->State = (CryptokiSessionState)((pSession->State & ReadWriteFlag) | (userType == CKU_SO ? RWSecurityOfficer : ROUser)); } if(userType == CKU_CONTEXT_SPECIFIC) { pSession->IsLoginContext = TRUE; } else { // don't store read/write since that is session specific pSession->Token->TokenWideState = (CryptokiSessionState)(userType == CKU_SO ? ROUser + 1 : ROUser); } return ret; }
/* C_CloseSession closes a session between an application and a * Token. */ CK_DEFINE_FUNCTION(CK_RV, C_CloseSession) ( CK_SESSION_HANDLE hSession /* the session's handle */ ) { CryptokiSession* pSession = NULL; CK_SLOT_ID slotID; CK_RV ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) { return ret; } return CloseSession(pSession, slotID); }
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_SESSION_INFO_PTR pInfo /* receives session info */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; CK_ULONG devError = 0; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pInfo == NULL) return CKR_ARGUMENTS_BAD; pInfo->slotID = slotID; pInfo->state = NETMF_CRYPTOKI_SESSION_STATE_CONVERT(pSession->State); pInfo->flags = CKF_SERIAL_SESSION | (NETMF_CRYPTOKI_SESSION_IS_RW(pSession->State) ? CKF_RW_SESSION : 0); pInfo->ulDeviceError = 0; if(pSession->Token != NULL && pSession->Token->TokenState) { if(pSession->Token->TokenState->GetDeviceError != NULL) pSession->Token->TokenState->GetDeviceError(&devError); pInfo->ulDeviceError = devError; // if this session is not logged in and the CKU_SO or CKU_USER is logged in, then use the token wide // session state. if( !NETMF_CRYPTOKI_SESSION_IS_PUBLIC(pSession->Token->TokenWideState) && NETMF_CRYPTOKI_SESSION_IS_PUBLIC(pSession->State)) { // RWSecurityOfficer can not change a RO session if((pSession->Token->TokenWideState | ReadWriteFlag) != RWSecurityOfficer || NETMF_CRYPTOKI_SESSION_IS_RW(pSession->State)) { pInfo->state = NETMF_CRYPTOKI_SESSION_STATE_CONVERT_TOKEN(pSession->Token->TokenWideState, pSession->State); } } } return CKR_OK; }
CK_DEFINE_FUNCTION(CK_RV, C_SetPIN) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ CK_ULONG ulOldLen, /* length of the old PIN */ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ CK_ULONG ulNewLen /* length of the new PIN */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; switch(pSession->State) { case RWPublic: case RWUser: case RWSecurityOfficer: break; default: return CKR_SESSION_READ_ONLY; } if(0 == (pSession->Token->TokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) { if(pOldPin == NULL || pNewPin == NULL) return CKR_ARGUMENTS_BAD; } if(pSession->Token->SessionMgmt != NULL && pSession->Token->SessionMgmt->SetPin != NULL) { ret = pSession->Token->SessionMgmt->SetPin(&pSession->Context, pOldPin, ulOldLen, pNewPin, ulNewLen); } else { ret = CKR_FUNCTION_NOT_SUPPORTED; } return ret; }
/* C_FindObjectsFinal finishes a search for token and session * objects. */ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal) ( CK_SESSION_HANDLE hSession /* the session's handle */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->FindObjectsFinal) { return pSession->Token->ObjectMgmt->FindObjectsFinal(&pSession->Context); } return CKR_FUNCTION_NOT_SUPPORTED; }
/* C_FindObjectsInit initializes a search for token and session * objects that match a template. */ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ CK_ULONG ulCount /* attrs in search template */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pTemplate == NULL ) return CKR_ARGUMENTS_BAD; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->FindObjectsInit) { return pSession->Token->ObjectMgmt->FindObjectsInit(&pSession->Context, pTemplate, ulCount); } return CKR_FUNCTION_NOT_SUPPORTED; }
/* C_GetObjectSize gets the size of an object in bytes. */ CK_DEFINE_FUNCTION(CK_RV, C_GetObjectSize) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ULONG_PTR pulSize /* receives size of object */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pulSize == NULL ) return CKR_ARGUMENTS_BAD; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->GetObjectSize) { return pSession->Token->ObjectMgmt->GetObjectSize(&pSession->Context, hObject, pulSize); } return CKR_FUNCTION_NOT_SUPPORTED; }
/* C_FindObjects continues a search for token and session * objects that match a template, obtaining additional object * handles. */ CK_DEFINE_FUNCTION(CK_RV, C_FindObjects) ( CK_SESSION_HANDLE hSession, /* session's handle */ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ CK_ULONG ulMaxObjectCount, /* max handles to get */ CK_ULONG_PTR pulObjectCount /* actual # returned */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pulObjectCount == NULL ) return CKR_ARGUMENTS_BAD; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->FindObjects) { return pSession->Token->ObjectMgmt->FindObjects(&pSession->Context, phObject, ulMaxObjectCount, pulObjectCount); } return CKR_FUNCTION_NOT_SUPPORTED; }
/* C_SetAttributeValue modifies the value of one or more object * attributes */ CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject, /* the object's handle */ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ CK_ULONG ulCount /* attributes in template */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pTemplate == NULL ) return CKR_ARGUMENTS_BAD; if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->SetAttributeValue) { return pSession->Token->ObjectMgmt->SetAttributeValue(&pSession->Context, hObject, pTemplate, ulCount); } return CKR_FUNCTION_NOT_SUPPORTED; }
int ssl_connect_internal(int sd, const char* szTargetHost, int sslContextHandle) { int err = SOCK_SOCKET_ERROR; SSL *ssl = NULL; int nonblock = 0; // Retrieve SSL struct from g_SSL_Driver if((sslContextHandle >= ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0)) { goto error; } // sd should already have been created // Now do the SSL negotiation ssl = (SSL*)g_SSL_Driver.m_sslContextArray[sslContextHandle].SslContext; if (ssl == NULL) goto error; if (!SSL_set_fd(ssl, sd)) { goto error; } if(ssl->verify_mode != SSL_VERIFY_NONE) { SSL_CTX* pCtx = SSL_get_SSL_CTX(ssl); if(pCtx != NULL) { X509_STORE *pStore = SSL_CTX_get_cert_store(pCtx); if(sk_num(&pStore->objs->stack) == 0) { CryptokiSession* pSession; CK_SLOT_ID slotID; OBJECT_DATA* pObj; CK_ATTRIBUTE attribs[2]; CK_OBJECT_CLASS cls = SwapEndianIfBEc32(CKO_CERTIFICATE); LPSTR label = "CA"; CK_SESSION_HANDLE hSess; if(CKR_OK == C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &hSess) && CKR_OK == Cryptoki_GetSlotIDFromSession(hSess, &slotID, &pSession)) { attribs[0].type = CKA_CLASS; attribs[0].pValue = &cls; attribs[0].ulValueLen = sizeof(cls); attribs[1].type = CKA_LABEL; attribs[1].pValue = label; attribs[1].ulValueLen = 2; if(CKR_OK == C_FindObjectsInit(hSess, attribs, ARRAYSIZE(attribs))) { CK_OBJECT_HANDLE hObjs[20]; CK_ULONG cnt = 0; if(CKR_OK == C_FindObjects(hSess, hObjs, ARRAYSIZE(hObjs), &cnt) && cnt > 0) { for(int i=0; i<cnt; i++) { pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(&pSession->Context, hObjs[i]); if(pObj != NULL && pObj->Type == 3 /*CertificateType*/) { CERT_DATA* pCert = (CERT_DATA*)pObj->Data; X509_STORE_add_cert(pStore, pCert->cert); } } } C_FindObjectsFinal(hSess); } } if(pStore->objs == NULL || 0 == sk_num(&pStore->objs->stack)) { ssl->verify_mode = SSL_VERIFY_NONE; } C_CloseSession(hSess); } } } if(szTargetHost != NULL && szTargetHost[0] != 0) { SSL_set_tlsext_host_name(ssl, szTargetHost); } SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); err = SSL_connect (ssl); nonblock = 1; SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); err = SSL_get_error(ssl,err); if(err == SSL_ERROR_WANT_READ) { err = SOCK_EWOULDBLOCK; #if !defined(TCPIP_LWIP) && !defined(TCPIP_LWIP_OS) SOCKET_DRIVER.ClearStatusBitsForSocket( sd, FALSE ); #endif } else if(err == SSL_ERROR_WANT_WRITE) { err = SOCK_TRY_AGAIN; #if !defined(TCPIP_LWIP) && !defined(TCPIP_LWIP_OS) SOCKET_DRIVER.ClearStatusBitsForSocket( sd, TRUE ); #endif } SOCKET_DRIVER.SetSocketSslData(sd, (void*)ssl); error: return err; }
/* C_CreateObject creates a new object. */ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ CK_ULONG ulCount, /* attributes in template */ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; CK_ULONG i = 0; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pTemplate == NULL ) return CKR_ARGUMENTS_BAD; if(phObject == NULL ) return CKR_ARGUMENTS_BAD; *phObject = (CK_OBJECT_HANDLE)-1; if(pTemplate[i].type == CKA_CLASS && pTemplate[i].ulValueLen == sizeof(CK_OBJECT_CLASS)) { CK_OBJECT_CLASS cls = SwapEndianIfBEc32(*(CK_OBJECT_CLASS*)pTemplate[i].pValue); i++; if(i > ulCount) return CKR_ARGUMENTS_BAD; switch(cls) { case CKO_SECRET_KEY: if(pSession->Token->KeyMgmt != NULL && pSession->Token->KeyMgmt->LoadSecretKey != NULL ) { if(pTemplate[i].type == CKA_KEY_TYPE) { CK_KEY_TYPE type = SwapEndianIfBEc32(*(CK_KEY_TYPE*)pTemplate[i].pValue); i++; if(i > ulCount) return CKR_ARGUMENTS_BAD; if(pTemplate[i].type == CKA_VALUE) { ret = pSession->Token->KeyMgmt->LoadSecretKey(&pSession->Context, type, (const UINT8*)pTemplate[i].pValue, pTemplate[i].ulValueLen, phObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } } } break; case CKO_PRIVATE_KEY: case CKO_PUBLIC_KEY: if(pSession->Token->KeyMgmt != NULL) { if(pTemplate[i].type == CKA_KEY_TYPE) { CK_KEY_TYPE type = SwapEndianIfBEc32(*(CK_KEY_TYPE*)pTemplate[i].pValue); bool bPrivate = (cls == CKO_PRIVATE_KEY); if(type == CKK_DSA && pSession->Token->KeyMgmt->LoadDsaKey != NULL) { DsaKeyData dsaKeyData; memset(&dsaKeyData, 0, sizeof(dsaKeyData)); i++; for(;i<ulCount; i++) { switch(pTemplate[i].type) { case CKA_PRIME: dsaKeyData.Prime_p = (PBYTE)pTemplate[i].pValue; dsaKeyData.Prime_p_len = pTemplate[i].ulValueLen; break; case CKA_SUBPRIME: dsaKeyData.Subprime_q = (PBYTE)pTemplate[i].pValue; dsaKeyData.Subprime_q_len = pTemplate[i].ulValueLen; break; case CKA_BASE: dsaKeyData.Base_g = (PBYTE)pTemplate[i].pValue; dsaKeyData.Base_g_len = pTemplate[i].ulValueLen; break; case CKA_PRIVATE_EXPONENT: dsaKeyData.Private_x = (PBYTE)pTemplate[i].pValue; dsaKeyData.Private_x_len = pTemplate[i].ulValueLen; break; case CKA_VALUE: if(bPrivate) { dsaKeyData.Private_x = (PBYTE)pTemplate[i].pValue; dsaKeyData.Private_x_len = pTemplate[i].ulValueLen; } else { dsaKeyData.Public_y = (PBYTE)pTemplate[i].pValue; dsaKeyData.Public_y_len = pTemplate[i].ulValueLen; } break; // public and private in same key case CKA_PUBLIC_EXPONENT: if(bPrivate) { dsaKeyData.Public_y = (PBYTE)pTemplate[i].pValue; dsaKeyData.Public_y_len = pTemplate[i].ulValueLen; } break; } } dsaKeyData.Seed_len = dsaKeyData.Base_g_len; ret = pSession->Token->KeyMgmt->LoadDsaKey(&pSession->Context, dsaKeyData, bPrivate, phObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } else if(type == CKK_RSA && pSession->Token->KeyMgmt->LoadRsaKey != NULL) { PBYTE pRawData = NULL; CK_ULONG rawDataLen = 0; RsaKeyData pParams; memset(&pParams, 0, sizeof(pParams)); i++; for(;i<ulCount; i++) { switch(pTemplate[i].type) { case CKA_MODULUS: pParams.Modulus = (PBYTE)pTemplate[i].pValue; pParams.Modulus_len = pTemplate[i].ulValueLen; break; case CKA_PUBLIC_EXPONENT: pParams.PublicExponent = (PBYTE)pTemplate[i].pValue; pParams.PublicExponent_len = pTemplate[i].ulValueLen; break; case CKA_PRIVATE_EXPONENT: pParams.PrivateExponent = (PBYTE)pTemplate[i].pValue; pParams.PrivateExponent_len = pTemplate[i].ulValueLen; break; case CKA_PRIME_1: pParams.Prime1 = (PBYTE)pTemplate[i].pValue; pParams.Prime1_len = pTemplate[i].ulValueLen; break; case CKA_PRIME_2: pParams.Prime2 = (PBYTE)pTemplate[i].pValue; pParams.Prime2_len = pTemplate[i].ulValueLen; break; case CKA_EXPONENT_1: pParams.Exponent1 = (PBYTE)pTemplate[i].pValue; pParams.Exponent1_len = pTemplate[i].ulValueLen; break; case CKA_EXPONENT_2: pParams.Exponent2 = (PBYTE)pTemplate[i].pValue; pParams.Exponent2_len = pTemplate[i].ulValueLen; break; case CKA_COEFFICIENT: pParams.Coefficient = (PBYTE)pTemplate[i].pValue; pParams.Coefficient_len = pTemplate[i].ulValueLen; break; case CKA_VALUE: pRawData = (PBYTE)pTemplate[i].pValue; rawDataLen = pTemplate[i].ulValueLen; break; } } if(pRawData != NULL && rawDataLen > 0) { ret = pSession->Token->KeyMgmt->LoadKeyBlob(&pSession->Context, pRawData, rawDataLen, CKK_RSA, Public, phObject); } else { ret = pSession->Token->KeyMgmt->LoadRsaKey(&pSession->Context, pParams, bPrivate, phObject); } #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } } } break; } } // give the drivers object management a chance to handle this if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->CreateObject != NULL) { ret = pSession->Token->ObjectMgmt->CreateObject(&pSession->Context, pTemplate, ulCount, phObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } return CKR_FUNCTION_NOT_SUPPORTED; }