int EstEID_RealSign(CK_SESSION_HANDLE session, char **signature, unsigned int *signatureLength, const char *hash, unsigned int hashLength, char* name) { CK_OBJECT_HANDLE privateKeyHandle; CK_ULONG objectCount; unsigned int hashWithPaddingLength = 0; char *hashWithPadding; CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0}; CK_OBJECT_CLASS objectClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)}; if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) CLOSE_SESSION_AND_RETURN(FAILURE); if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &privateKeyHandle, 1, &objectCount))) CLOSE_SESSION_AND_RETURN(FAILURE); if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_RETURN(FAILURE); if (objectCount == 0) CLOSE_SESSION_AND_RETURN(FAILURE); // todo ?? set error message if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle))) CLOSE_SESSION_AND_RETURN(FAILURE); hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength); if (hashWithPadding) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding() CK_ULONG len; if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, NULL, &len))) { free(hashWithPadding); CLOSE_SESSION_AND_RETURN(FAILURE); } *signature = (char *)malloc(len); if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, (CK_BYTE_PTR) * signature, &len))) { free(hashWithPadding); CLOSE_SESSION_AND_RETURN(FAILURE); } *signatureLength = len; free(hashWithPadding); } if (session) { if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) { return FAILURE; } } if(name) { free(name); } if (!hashWithPaddingLength) { // This is additional safeguard, as digest length is checked already before calling EstEID_addPadding() EstEID_log("will not sign due to incorrect incoming message digest length"); return FAILURE; } EstEID_log("successfully signed"); return SUCCESS; }
int testStability_sign ( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivateKey, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR *ppSignature, CK_ULONG_PTR pulSignatureLen ) { CK_RV rv; CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 }; rv = p11->C_SignInit(hSession, &mechanism, hPrivateKey); if (rv != CKR_OK) { printf("ERROR: Failed to initialize signing. rv=%s\n", rv2string(rv)); return 1; } *pulSignatureLen = 0; rv = p11->C_Sign(hSession, pData, ulDataLen, NULL_PTR, pulSignatureLen); if (rv != CKR_OK) { printf("ERROR: Failed to check the size of the signature. rv=%s\n", rv2string(rv)); return 1; } *ppSignature = (CK_BYTE_PTR)malloc(*pulSignatureLen); rv = p11->C_Sign(hSession, pData, ulDataLen, *ppSignature, pulSignatureLen); if (rv != CKR_OK) { printf("ERROR: Failed to sign the data. rv=%s\n", rv2string(rv)); free(*ppSignature); *ppSignature = NULL; *pulSignatureLen = 0; return 1; } return 0; }
void processRequest(int client) { DataMarshalling *d = NULL; while (1) { d = new DataMarshalling(client); d->recvData(); if (!strcmp(d->getMsgType(), "C_Initialize")) { int p = 0; printf("Processing: C_Initialize\n"); p = d->unpackInt(); if (p == 0) pFunctionList->C_Initialize(NULL); else { printf("ERROR: C_Initialize shouldn't be called with not NULL\n"); } } else if (!strcmp(d->getMsgType(), "C_Finalize")) { int p = 0; CK_RV ret = 0; printf("Processing: C_Finalize\n"); p = d->unpackInt(); if (p == NULL) { ret = pFunctionList->C_Finalize(NULL); } else { printf("ERROR: C_Finalize shouldn't be called with not NULL\n"); ret = CKR_CANCEL; } { CK_ULONG count = 0; DataMarshalling *d2 = new DataMarshalling(client); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } break; } else if (!strcmp(d->getMsgType(), "C_GetSlotList")) { int p = 0; printf("Processing: C_GetSlotList\n"); p = d->unpackInt(); if (p == 0) { CK_ULONG count = 0; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ ret = pFunctionList->C_GetSlotList(TRUE, NULL, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); d2->sendData(); delete d2; } else { CK_ULONG count = 0; CK_SLOT_ID_PTR slot = NULL; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ pFunctionList->C_GetSlotList(TRUE, NULL, &count); slot = new(CK_SLOT_ID[count]); ret = pFunctionList->C_GetSlotList(TRUE, slot, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); for (int i = 0; i < count; i ++) d2->packInt((char *)&slot[i]); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_OpenSession")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_OpenSession\n"); slotId = d->unpackInt(); flags = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_OpenSession(slotId, flags, NULL, NULL, &sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&sessionId); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_CloseSession")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_CloseSession\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_CloseSession(sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetInfo")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; CK_INFO info; printf("Processing: C_GetInfo\n"); slotId = d->unpackInt(); { CK_RV ret = 0; CK_TOKEN_INFO token; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetInfo(&info); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packChar(info.cryptokiVersion.major); d2->packChar(info.cryptokiVersion.minor); d2->packMem((char *)info.manufacturerID, 32); d2->packInt((char *)&info.flags); d2->packMem((char *)info.libraryDescription, 32); d2->packChar(info.libraryVersion.major); d2->packChar(info.libraryVersion.minor); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetSlotInfo")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_GetSlotInfo\n"); slotId = d->unpackInt(); { CK_RV ret = 0; CK_SLOT_INFO slot; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetSlotInfo(slotId, &slot); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packMem((char *)slot.slotDescription, 64); d2->packMem((char *)slot.manufacturerID, 32); d2->packInt((char *)&slot.flags); d2->packChar(slot.hardwareVersion.major); d2->packChar(slot.hardwareVersion.minor); d2->packChar(slot.firmwareVersion.major); d2->packChar(slot.firmwareVersion.minor); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetTokenInfo")) { unsigned int slotId = 0, flags = 0; CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_GetTokenInfo\n"); slotId = d->unpackInt(); { CK_RV ret = 0; CK_TOKEN_INFO token; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetTokenInfo(slotId, &token); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packMem((char *)token.label, 32); d2->packMem((char *)token.manufacturerID, 32); d2->packMem((char *)token.model, 16); d2->packMem((char *)token.serialNumber, 16); d2->packInt((char *)&token.flags); d2->packInt((char *)&token.ulMaxSessionCount); d2->packInt((char *)&token.ulSessionCount); d2->packInt((char *)&token.ulMaxRwSessionCount); d2->packInt((char *)&token.ulRwSessionCount); d2->packInt((char *)&token.ulMaxPinLen); d2->packInt((char *)&token.ulMinPinLen); d2->packInt((char *)&token.ulTotalPublicMemory); d2->packInt((char *)&token.ulFreePublicMemory); d2->packInt((char *)&token.ulTotalPrivateMemory); d2->packInt((char *)&token.ulFreePrivateMemory); d2->packChar(token.hardwareVersion.major); d2->packChar(token.hardwareVersion.minor); d2->packChar(token.firmwareVersion.major); d2->packChar(token.firmwareVersion.minor); d2->packMem((char *)token.utcTime, 16); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetMechanismList")) { unsigned int slotId = 0; CK_MECHANISM_TYPE_PTR pMechanismList = NULL; printf("Processing: C_GetMechanismList\n"); slotId = d->unpackInt(); pMechanismList = (CK_MECHANISM_TYPE_PTR)d->unpackInt(); if (pMechanismList == NULL) { CK_ULONG count = 0; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ ret = pFunctionList->C_GetMechanismList(slotId, pMechanismList, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); printf("C_GetMechanismList count: %d\n", count); d2->sendData(); delete d2; } else { CK_ULONG count = 0; CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Retrieving Slots size */ pFunctionList->C_GetMechanismList(TRUE, NULL, &count); pMechanismList = new(CK_MECHANISM_TYPE[count]); ret = pFunctionList->C_GetMechanismList(slotId, pMechanismList, &count); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&count); printf("C_GetMechanismList count: %d\n", count); for (int i = 0; i < count; i ++) d2->packInt((char *)&pMechanismList[i]); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetMechanismInfo")) { unsigned int slotId = 0, mechanismType = 0; printf("Processing: C_GetMechanismInfo\n"); slotId = d->unpackInt(); mechanismType = d->unpackInt(); { CK_RV ret = 0; CK_MECHANISM_INFO mechanism; DataMarshalling *d2 = new DataMarshalling(client); ret = pFunctionList->C_GetMechanismInfo(slotId, mechanismType, &mechanism); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&mechanism.ulMinKeySize); d2->packInt((char *)&mechanism.ulMaxKeySize); d2->packInt((char *)&mechanism.flags); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Login")) { CK_SESSION_HANDLE sessionId = 0; unsigned int user = 0, len = 0; CK_CHAR_PTR pin = NULL; printf("Processing: C_Login\n"); sessionId = d->unpackInt(); user = d->unpackInt(); len = d->unpackInt(); pin = (CK_CHAR_PTR) calloc(1, len + 1); if (!pin) { printf("ERROR: NO MEMORY\n"); break; } d->unpackMem((char *)pin, len); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Login(sessionId, user, pin, len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Logout")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_Logout\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Logout(sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_FindObjectsInit")) { CK_SESSION_HANDLE sessionId = 0; unsigned int len = 0; CK_ATTRIBUTE_PTR attr = NULL; printf("Processing: C_FindObjectsInit\n"); sessionId = d->unpackInt(); len = d->unpackInt(); attr = (CK_ATTRIBUTE_PTR) calloc(len, sizeof(CK_ATTRIBUTE)); if (!attr) { printf("ERROR: NO MEMORY\n"); break; } for (int i = 0; i < len; i ++) { attr[i].type = d->unpackInt(); attr[i].ulValueLen = d->unpackInt(); attr[i].pValue = (char *)calloc(1, attr[i].ulValueLen); d->unpackMem((char *)attr[i].pValue, attr[i].ulValueLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_FindObjectsInit(sessionId, attr, len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_FindObjects")) { CK_SESSION_HANDLE sessionId = 0; CK_OBJECT_HANDLE_PTR phObject = NULL; CK_ULONG len = 0, maxlen = 0; printf("Processing: C_FindObjects\n"); sessionId = d->unpackInt(); maxlen = d->unpackInt(); if (maxlen > 0) { phObject = new(CK_OBJECT_HANDLE[maxlen]); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_FindObjects(sessionId, phObject, maxlen, &len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&len); for (int i = 0; i < len && i < maxlen; i ++) d2->packInt((char *)&phObject[i]); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetAttributeValue")) { CK_SESSION_HANDLE sessionId = 0; CK_OBJECT_HANDLE hObject = 0; CK_ULONG len = 0; CK_ATTRIBUTE_PTR attr = NULL; printf("Processing: C_GetAttributeValue\n"); sessionId = d->unpackInt(); hObject = d->unpackInt(); len = d->unpackInt(); attr = (CK_ATTRIBUTE_PTR) calloc(len, sizeof(CK_ATTRIBUTE)); if (!attr) { printf("ERROR: NO MEM C_GetAttributeValue\n"); break; } for (int i = 0; i < len; i ++) { attr[i].type = d->unpackInt(); attr[i].ulValueLen = d->unpackInt(); attr[i].pValue = (char *)d->unpackInt(); if (attr[i].pValue != NULL) { attr[i].pValue = (char *)calloc(1, attr[i].ulValueLen); if (!attr[i].pValue) { printf("ERROR: NO MEM\n"); exit(-1); } //d->unpackMem((char *)attr[i].pValue, attr[i].ulValueLen); } } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); ret = pFunctionList->C_GetAttributeValue(sessionId, hObject, attr, len); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); for (int i = 0; i < len; i ++) { d2->packInt((char *)&attr[i].type); d2->packInt((char *)&attr[i].ulValueLen); d2->packInt((char *)&attr[i].pValue); if (attr[i].pValue != NULL) { d2->packMem((char *)attr[i].pValue, attr[i].ulValueLen); #ifdef FUNC_DEBUG_ if (i == 2) { PCCERT_CONTEXT pCertContext; pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,((BYTE *)attr[i].pValue),attr[i].ulValueLen); printf("data len: %d\n", attr[i].ulValueLen); printf("issuer len: %d\n", pCertContext->pCertInfo->Issuer.cbData); std::wcout << byte2str(pCertContext->pCertInfo->Issuer.pbData, pCertContext->pCertInfo->Issuer.cbData); CertFreeCertificateContext(pCertContext); } #endif } } d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_FindObjectsFinal")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_FindObjectsFinal\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_FindObjectsFinal(sessionId); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_SignInit")) { CK_SESSION_HANDLE sessionId = 0; CK_MECHANISM mechanism; CK_OBJECT_HANDLE hKey; printf("Processing: C_SignInit\n"); sessionId = d->unpackInt(); hKey = d->unpackInt(); mechanism.mechanism = d->unpackInt(); mechanism.ulParameterLen = d->unpackInt(); mechanism.pParameter = NULL; { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_SignInit(sessionId, &mechanism, hKey); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Sign")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL, *signature = NULL; CK_ULONG dataLen = 0, signatureLen = 0; printf("Processing: C_Sign\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_Sign\n"); break; } d->unpackMem((char *)data, dataLen); } signatureLen = d->unpackInt(); signature = (char *)d->unpackInt(); if (signature != NULL) { signature = (char *)calloc(1, signatureLen); if (!signature) { printf("ERROR: NO MEM C_Sign\n"); break; } d->unpackMem((char *)signature, signatureLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Sign(sessionId, (CK_BYTE_PTR)data, dataLen, (CK_BYTE_PTR)signature, &signatureLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&signatureLen); if (signature != NULL) d2->packMem((char *)signature, signatureLen); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_VerifyInit")) { CK_SESSION_HANDLE sessionId = 0; CK_MECHANISM mechanism; CK_OBJECT_HANDLE hKey; printf("Processing: C_VerifyInit\n"); sessionId = d->unpackInt(); hKey = d->unpackInt(); mechanism.mechanism = d->unpackInt(); mechanism.ulParameterLen = d->unpackInt(); mechanism.pParameter = NULL; { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_VerifyInit(sessionId, &mechanism, hKey); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_Verify")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL, *signature = NULL; CK_ULONG dataLen = 0, signatureLen = 0; printf("Processing: C_Verify\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_Verify\n"); break; } d->unpackMem((char *)data, dataLen); } signatureLen = d->unpackInt(); signature = (char *)d->unpackInt(); if (signature != NULL) { signature = (char *)calloc(1, signatureLen); if (!signature) { printf("ERROR: NO MEM C_Verify\n"); break; } d->unpackMem((char *)signature, signatureLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_Verify(sessionId, (CK_BYTE_PTR)data, dataLen, (CK_BYTE_PTR)signature, signatureLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GenerateRandom")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL; CK_ULONG dataLen = 0; printf("Processing: C_GenerateRandom\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_GenerateRandom\n"); break; } //d->unpackMem((char *)data, dataLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GenerateRandom(sessionId, (CK_BYTE_PTR)data, dataLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); if (data != NULL) d2->packMem((char *)data, dataLen); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_SeedRandom")) { CK_SESSION_HANDLE sessionId = 0; char *data = NULL; CK_ULONG dataLen = 0; printf("Processing: C_SeedRandom\n"); sessionId = d->unpackInt(); dataLen = d->unpackInt(); data = (char *)d->unpackInt(); if (data != NULL) { data = (char *)calloc(1, dataLen); if (!data) { printf("ERROR: NO MEM C_SeedRandom\n"); break; } d->unpackMem((char *)data, dataLen); } { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_SeedRandom(sessionId, (CK_BYTE_PTR)data, dataLen); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_GetSessionInfo")) { CK_SESSION_HANDLE sessionId = 0; printf("Processing: C_GetSessionInfo\n"); sessionId = d->unpackInt(); { CK_RV ret = 0; CK_SESSION_INFO info; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_GetSessionInfo(sessionId, &info); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->packInt((char *)&info.slotID); d2->packInt((char *)&info.state); d2->packInt((char *)&info.flags); d2->packInt((char *)&info.ulDeviceError); d2->sendData(); delete d2; } } else if (!strcmp(d->getMsgType(), "C_CloseAllSessions")) { CK_SLOT_ID slotID = 0; printf("Processing: C_Logout\n"); slotID = d->unpackInt(); { CK_RV ret = 0; DataMarshalling *d2 = new DataMarshalling(client); /* * Opening session */ ret = pFunctionList->C_CloseAllSessions(slotID); d2->setMsgType(d->getMsgType()); d2->packInt((char *)&ret); d2->sendData(); delete d2; } } else { pFunctionList->C_Finalize(NULL); } delete d; } }
int EstEID_signHash(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) { CK_SESSION_HANDLE session = 0L; if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE; const char *givenName = EstEID_mapGet(cert, "givenName"); if (!givenName) givenName = ""; const char *surname = EstEID_mapGet(cert, "surname"); if (!surname) surname = ""; const char *personalID = EstEID_mapGet(cert, "serialNumber"); if (!personalID) personalID = ""; char *name = (char *)malloc(strlen(givenName) + strlen(surname) + strlen(personalID) + 4); sprintf(name, "%s %s", givenName, surname); if(strlen(personalID)) { strcat(name, ", "); strcat(name, personalID); } for (int attempt = 0, blocked = FALSE;; attempt++) { char message[1024]; int remainingTries = EstEID_getRemainingTries(slotID); if (remainingTries == -1) CLOSE_SESSION_AND_FAIL; if (!remainingTries || blocked) { sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED); pinPromptData.alertFunction(pinPromptData.nativeWindowHandle, l10n("PIN2 blocked, cannot sign!")); CLOSE_SESSION_AND_FAIL; } if (remainingTries < 3 || attempt) { sprintf(message, "%s%s %i", (attempt ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries); } else { message[0] = 0; } int isPinPad = EstEID_isPinPad(slotID); CK_RV loginResult = CKR_FUNCTION_CANCELED; if(!isPinPad) { // Simple card reader char *pin = pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")), isPinPad); if (!pin || strlen(pin) == 0) { if (pin) free(pin); setUserCancelErrorCodeAndMessage(); CLOSE_SESSION_AND_FAIL; } loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pin, strlen(pin)); free(pin); } else { // PIN pad #ifdef _WIN32 EstEID_log("creating pinpad dialog UI thread"); pinpad_thread_result = -1; FAIL_IF_THREAD_ERROR("CreateMutex", (pinpad_thread_mutex = CreateMutex(NULL, FALSE, NULL))); #else EstEID_log("creating pinpad worker thread"); pinpad_thread_result = -1; FAIL_IF_PTHREAD_ERROR("pthread_mutex_init", pthread_mutex_init(&pinpad_thread_mutex, NULL)); FAIL_IF_PTHREAD_ERROR("pthread_cond_init", pthread_cond_init(&pinpad_thread_condition, NULL)); pthread_t pinpad_thread; EstEID_PINPadThreadData threadData; threadData.session = session; threadData.result = CKR_OK; #endif EstEID_log("thread launched"); #ifdef _WIN32 /* NB! Due to Firefox for Windows specific behaviour C_Login() is launched from main thread and UI code is running in separate thread if running on Windows. */ EstEID_PINPromptDataEx pinPromptDataEx; pinPromptDataEx.pinPromptData = pinPromptData; pinPromptDataEx.message = message; pinPromptDataEx.name = name; CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_pinPadLogin, (LPVOID)&pinPromptDataEx, 0, NULL); loginResult = fl->C_Login(session, CKU_USER, NULL, 0); closePinPadModalSheet(); #else FAIL_IF_PTHREAD_ERROR("pthread_create", pthread_create(&pinpad_thread, NULL, EstEID_pinPadLogin, (void*)&threadData)); pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, 0, isPinPad); loginResult = threadData.result; #endif EstEID_log("pinpad sheet/dialog closed"); if (loginResult == CKR_FUNCTION_CANCELED) { setUserCancelErrorCodeAndMessage(); CLOSE_SESSION_AND_FAIL; } } EstEID_log("loginResult = %s", pkcs11_error_message(loginResult)); switch (loginResult) { case CKR_PIN_LOCKED: blocked = TRUE; case CKR_PIN_INCORRECT: case CKR_PIN_INVALID: case CKR_PIN_LEN_RANGE: EstEID_log("this was attempt %i, loginResult causes to run next round", attempt); continue; default: if (EstEID_CK_failure("C_Login", loginResult)) CLOSE_SESSION_AND_FAIL; } break; // Login successful - correct PIN supplied } if (name){ free(name); name = NULL; } CK_OBJECT_CLASS objectClass = CKO_PRIVATE_KEY; CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)}; if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) CLOSE_SESSION_AND_FAIL; CK_OBJECT_HANDLE privateKeyHandle; CK_ULONG objectCount; if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &privateKeyHandle, 1, &objectCount))) CLOSE_SESSION_AND_FAIL; if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_FAIL; if (objectCount == 0) CLOSE_SESSION_AND_FAIL; // todo ?? set error message CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0}; if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle))) CLOSE_SESSION_AND_FAIL; unsigned int hashWithPaddingLength; char *hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength); CK_ULONG len; if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, NULL, &len))) { free(hashWithPadding); CLOSE_SESSION_AND_FAIL; } *signature = (char *)malloc(len); if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, (CK_BYTE_PTR) * signature, &len))) { free(hashWithPadding); CLOSE_SESSION_AND_FAIL; } *signatureLength = len; free(hashWithPadding); if (session) { if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) { return FAILURE; } } EstEID_log("successfully signed"); return SUCCESS; }
// Import a newly generated RSA1024 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10_RSA() { EVP_PKEY *evp; RSA *rsak; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_BYTE e[] = {0x01, 0x00, 0x01}; CK_BYTE p[64]; CK_BYTE q[64]; CK_BYTE dp[64]; CK_BYTE dq[64]; CK_BYTE qinv[64]; BIGNUM *e_bn; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_RSA; CK_BYTE id = 0; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *px; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_PUBLIC_EXPONENT, e, sizeof(e)}, {CKA_PRIME_1, p, sizeof(p)}, {CKA_PRIME_2, q, sizeof(q)}, {CKA_EXPONENT_1, dp, sizeof(dp)}, {CKA_EXPONENT_2, dq, sizeof(dq)}, {CKA_COEFFICIENT, qinv, sizeof(qinv)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_RSA_PKCS, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); rsak = RSA_new(); if (rsak == NULL) exit(EXIT_FAILURE); e_bn = BN_bin2bn(e, 3, NULL); if (e_bn == NULL) exit(EXIT_FAILURE); asrt(RSA_generate_key_ex(rsak, 1024, e_bn, NULL), 1, "GENERATE RSAK"); asrt(BN_bn2bin(rsak->p, p), 64, "GET P"); asrt(BN_bn2bin(rsak->q, q), 64, "GET Q"); asrt(BN_bn2bin(rsak->dmp1, dp), 64, "GET DP"); asrt(BN_bn2bin(rsak->dmq1, dp), 64, "GET DQ"); asrt(BN_bn2bin(rsak->iqmp, qinv), 64, "GET QINV"); if (EVP_PKEY_set1_RSA(evp, rsak) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); px = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &px)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 9, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); /* r_len = 32; */ /* s_len = 32; */ /* der_ptr = der_encoded; */ /* *der_ptr++ = 0x30; */ /* *der_ptr++ = 0xff; // placeholder, fix below */ /* r_ptr = sig; */ /* *der_ptr++ = 0x02; */ /* *der_ptr++ = r_len; */ /* if (*r_ptr >= 0x80) { */ /* *(der_ptr - 1) = *(der_ptr - 1) + 1; */ /* *der_ptr++ = 0x00; */ /* } */ /* else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { */ /* r_len--; */ /* *(der_ptr - 1) = *(der_ptr - 1) - 1; */ /* r_ptr++; */ /* } */ /* memcpy(der_ptr, r_ptr, r_len); */ /* der_ptr+= r_len; */ /* s_ptr = sig + 32; */ /* *der_ptr++ = 0x02; */ /* *der_ptr++ = s_len; */ /* if (*s_ptr >= 0x80) { */ /* *(der_ptr - 1) = *(der_ptr - 1) + 1; */ /* *der_ptr++ = 0x00; */ /* } */ /* else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { */ /* s_len--; */ /* *(der_ptr - 1) = *(der_ptr - 1) - 1; */ /* s_ptr++; */ /* } */ /* memcpy(der_ptr, s_ptr, s_len); */ /* der_ptr+= s_len; */ /* der_encoded[1] = der_ptr - der_encoded - 2; */ /* dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); */ /* asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); */ } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }
// Import a newly generated P256 pvt key and a certificate // to every slot and use the key to sign some data static void test_import_and_sign_all_10() { EVP_PKEY *evp; EC_KEY *eck; const EC_POINT *ecp; const BIGNUM *bn; char pvt[32]; X509 *cert; ASN1_TIME *tm; CK_BYTE i, j; CK_BYTE some_data[32]; CK_ULONG class_k = CKO_PRIVATE_KEY; CK_ULONG class_c = CKO_CERTIFICATE; CK_ULONG kt = CKK_ECDSA; CK_BYTE id = 0; CK_BYTE params[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}; CK_BYTE sig[64]; CK_ULONG recv_len; CK_BYTE value_c[3100]; CK_ULONG cert_len; CK_BYTE der_encoded[80]; CK_BYTE_PTR der_ptr; CK_BYTE_PTR r_ptr; CK_BYTE_PTR s_ptr; CK_ULONG r_len; CK_ULONG s_len; unsigned char *p; CK_ATTRIBUTE privateKeyTemplate[] = { {CKA_CLASS, &class_k, sizeof(class_k)}, {CKA_KEY_TYPE, &kt, sizeof(kt)}, {CKA_ID, &id, sizeof(id)}, {CKA_EC_PARAMS, ¶ms, sizeof(params)}, {CKA_VALUE, pvt, sizeof(pvt)} }; CK_ATTRIBUTE publicKeyTemplate[] = { {CKA_CLASS, &class_c, sizeof(class_c)}, {CKA_ID, &id, sizeof(id)}, {CKA_VALUE, value_c, sizeof(value_c)} }; CK_OBJECT_HANDLE obj[24]; CK_SESSION_HANDLE session; CK_MECHANISM mech = {CKM_ECDSA, NULL}; evp = EVP_PKEY_new(); if (evp == NULL) exit(EXIT_FAILURE); eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (eck == NULL) exit(EXIT_FAILURE); asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK"); bn = EC_KEY_get0_private_key(eck); asrt(BN_bn2bin(bn, pvt), 32, "EXTRACT PVT"); if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0) exit(EXIT_FAILURE); cert = X509_new(); if (cert == NULL) exit(EXIT_FAILURE); if (X509_set_pubkey(cert, evp) == 0) exit(EXIT_FAILURE); tm = ASN1_TIME_new(); if (tm == NULL) exit(EXIT_FAILURE); ASN1_TIME_set_string(tm, "000001010000Z"); X509_set_notBefore(cert, tm); X509_set_notAfter(cert, tm); cert->sig_alg->algorithm = OBJ_nid2obj(8); cert->cert_info->signature->algorithm = OBJ_nid2obj(8); ASN1_BIT_STRING_set_bit(cert->signature, 8, 1); ASN1_BIT_STRING_set(cert->signature, "\x00", 1); p = value_c; if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c)) exit(EXIT_FAILURE); publicKeyTemplate[2].ulValueLen = cert_len; asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE"); asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1"); asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO"); for (i = 0; i < 24; i++) { id = i; asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT"); asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj + i), CKR_OK, "IMPORT KEY"); } asrt(funcs->C_Logout(session), CKR_OK, "Logout SO"); for (i = 0; i < 24; i++) { for (j = 0; j < 10; j++) { if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1) exit(EXIT_FAILURE); asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER"); asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit"); recv_len = sizeof(sig); asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign"); r_len = 32; s_len = 32; der_ptr = der_encoded; *der_ptr++ = 0x30; *der_ptr++ = 0xff; // placeholder, fix below r_ptr = sig; *der_ptr++ = 0x02; *der_ptr++ = r_len; if (*r_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { r_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; r_ptr++; } memcpy(der_ptr, r_ptr, r_len); der_ptr+= r_len; s_ptr = sig + 32; *der_ptr++ = 0x02; *der_ptr++ = s_len; if (*s_ptr >= 0x80) { *(der_ptr - 1) = *(der_ptr - 1) + 1; *der_ptr++ = 0x00; } else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { s_len--; *(der_ptr - 1) = *(der_ptr - 1) - 1; s_ptr++; } memcpy(der_ptr, s_ptr, s_len); der_ptr+= s_len; der_encoded[1] = der_ptr - der_encoded - 2; dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); } } asrt(funcs->C_Logout(session), CKR_OK, "Logout USER"); asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession"); asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE"); }