summaryrefslogtreecommitdiff
path: root/tests/mock-pkcs11.c
diff options
context:
space:
mode:
authorPatrick Griffis <pgriffis@igalia.com>2021-04-27 13:29:19 -0500
committerCarlos Garcia Campos <carlosgc@gnome.org>2021-06-02 07:22:46 +0000
commitc775f93c923c615a50987d8eebd0dc325b57c1e4 (patch)
tree1da8cd1114c6e85e9135692c96da647a61ea3305 /tests/mock-pkcs11.c
parentdac4665a0c3858dbde3f59c8ca27007b87b8231f (diff)
downloadlibsoup-c775f93c923c615a50987d8eebd0dc325b57c1e4.tar.gz
ssl-test: Add tests for PKCS#11 pin protected cert
Diffstat (limited to 'tests/mock-pkcs11.c')
-rw-r--r--tests/mock-pkcs11.c2866
1 files changed, 2866 insertions, 0 deletions
diff --git a/tests/mock-pkcs11.c b/tests/mock-pkcs11.c
new file mode 100644
index 00000000..fc549d94
--- /dev/null
+++ b/tests/mock-pkcs11.c
@@ -0,0 +1,2866 @@
+/*
+ * Copyright 2011-2016 The Pkcs11Interop Project
+ * Copyright 2019 Igalia S.L.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Originally written for the Pkcs11Interop project by: Jaroslav IMRICH <jimrich@jimrich.sk>
+ */
+
+/*
+ * This file implements a PKCS #11 module to be loaded that returns a mock slot and objects.
+ *
+ * It is based on this project originally: https://github.com/Pkcs11Interop/pkcs11-mock
+ *
+ * Quite a few things have been changed since then though:
+ * - The CK defines just below use glib macros just out of convenience.
+ * - Logging was added just for ease of debugging.
+ * - Instead of hardcoded defines for objects this now has an array
+ * of mock_objects that is easier to read and extend. The search behavior
+ * of C_FindObjects was also updated to actually search through this.
+ * - The certificates/keys are real certificates/keys backed by gnutls
+ * loading them in C_Initialize from glib-networkings normal test data.
+ * This changes the behavior of many functions most notably including C_GetAttributeValue
+ * and C_Sign to use them. Any function not used in a TLS handshake was largely
+ * ignored and won't work.
+ */
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "MockPKCS11"
+
+#include <gio/gio.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
+
+/* See http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html */
+#define CK_PTR *
+#define CK_DEFINE_FUNCTION(returnType, name) returnType G_MODULE_EXPORT name
+#define CK_DECLARE_FUNCTION(returnType, name) returnType G_MODULE_EXPORT name
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
+#define NULL_PTR NULL
+
+#include "pkcs11/pkcs11.h"
+
+
+#define IGNORE(P) (void)(P)
+
+#define MOCK_MANUFACTURER_ID "GLib-Networking"
+#define MOCK_MODEL "mock"
+#define PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN 256
+#define PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN 4
+
+static CK_INFO mock_info = {
+ .cryptokiVersion = { 2, 40 },
+ .manufacturerID = MOCK_MANUFACTURER_ID,
+ .libraryDescription = "Mock Module",
+};
+
+typedef struct {
+ CK_OBJECT_CLASS object_class;
+ CK_TOKEN_INFO info;
+ union {
+ gnutls_x509_crt_t cert;
+ gnutls_privkey_t key;
+ };
+} MockObject;
+
+static MockObject mock_objects[] = {
+ {
+ .object_class = CKO_CERTIFICATE,
+ .info = {
+ .model = MOCK_MODEL,
+ .label = "Mock Certificate",
+ .serialNumber = "1",
+ .manufacturerID = MOCK_MANUFACTURER_ID,
+ .flags = CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED,
+ .ulMaxSessionCount = 1,
+ },
+ },
+ {
+ .object_class = CKO_PRIVATE_KEY,
+ .info = {
+ .model = MOCK_MODEL,
+ .label = "Mock Private Key",
+ .serialNumber = "2",
+ .manufacturerID = MOCK_MANUFACTURER_ID,
+ .flags = CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED,
+ .ulMaxSessionCount = 1,
+ .ulMaxPinLen = PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN,
+ .ulMinPinLen = PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN,
+ },
+ }
+};
+
+typedef struct {
+ CK_SLOT_INFO info;
+ //CK_TOKEN_INFO_PTR tokens[2];
+} MockSlot;
+
+static const MockSlot mock_slots[] = {
+ {
+ .info = {
+ .slotDescription = "Mock Slot",
+ .manufacturerID = MOCK_MANUFACTURER_ID,
+ .flags = CKF_TOKEN_PRESENT,
+ },
+ }
+};
+
+
+// FIXME: These are left overs that are unused
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_DATA 1
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY 2
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY 3
+#define PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY 4
+#define PKCS11_MOCK_CK_SLOT_ID 0
+
+#define PKCS11_MOCK_CK_SESSION_ID 1
+
+typedef enum
+{
+ PKCS11_MOCK_CK_OPERATION_NONE,
+ PKCS11_MOCK_CK_OPERATION_FIND,
+ PKCS11_MOCK_CK_OPERATION_ENCRYPT,
+ PKCS11_MOCK_CK_OPERATION_DECRYPT,
+ PKCS11_MOCK_CK_OPERATION_DIGEST,
+ PKCS11_MOCK_CK_OPERATION_SIGN,
+ PKCS11_MOCK_CK_OPERATION_SIGN_RECOVER,
+ PKCS11_MOCK_CK_OPERATION_VERIFY,
+ PKCS11_MOCK_CK_OPERATION_VERIFY_RECOVER,
+ PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT,
+ PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST,
+ PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT,
+ PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY
+} PKCS11_MOCK_CK_OPERATION;
+
+#define PKCS11_MOCK_CKO_ANYTHING -1 // We'll use -1 as a magic match all
+
+static CK_BBOOL pkcs11_mock_initialized = CK_FALSE;
+static CK_BBOOL pkcs11_mock_session_opened = CK_FALSE;
+static CK_ULONG pkcs11_mock_session_state = CKS_RO_PUBLIC_SESSION;
+static PKCS11_MOCK_CK_OPERATION pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+static CK_ULONG pkcs11_mock_sign_key = 0;
+static CK_LONG mock_search_template_class = PKCS11_MOCK_CKO_ANYTHING;
+static char *mock_search_template_label;
+static CK_ULONG mock_search_iterator = 0;
+static gboolean mock_logged_in_state = FALSE;
+static size_t mock_login_attempts = 0;
+static CK_ULONG mock_sign_algo = 0;
+
+static CK_FUNCTION_LIST pkcs11_mock_functions =
+{
+ {2, 20},
+ &C_Initialize,
+ &C_Finalize,
+ &C_GetInfo,
+ &C_GetFunctionList,
+ &C_GetSlotList,
+ &C_GetSlotInfo,
+ &C_GetTokenInfo,
+ &C_GetMechanismList,
+ &C_GetMechanismInfo,
+ &C_InitToken,
+ &C_InitPIN,
+ &C_SetPIN,
+ &C_OpenSession,
+ &C_CloseSession,
+ &C_CloseAllSessions,
+ &C_GetSessionInfo,
+ &C_GetOperationState,
+ &C_SetOperationState,
+ &C_Login,
+ &C_Logout,
+ &C_CreateObject,
+ &C_CopyObject,
+ &C_DestroyObject,
+ &C_GetObjectSize,
+ &C_GetAttributeValue,
+ &C_SetAttributeValue,
+ &C_FindObjectsInit,
+ &C_FindObjects,
+ &C_FindObjectsFinal,
+ &C_EncryptInit,
+ &C_Encrypt,
+ &C_EncryptUpdate,
+ &C_EncryptFinal,
+ &C_DecryptInit,
+ &C_Decrypt,
+ &C_DecryptUpdate,
+ &C_DecryptFinal,
+ &C_DigestInit,
+ &C_Digest,
+ &C_DigestUpdate,
+ &C_DigestKey,
+ &C_DigestFinal,
+ &C_SignInit,
+ &C_Sign,
+ &C_SignUpdate,
+ &C_SignFinal,
+ &C_SignRecoverInit,
+ &C_SignRecover,
+ &C_VerifyInit,
+ &C_Verify,
+ &C_VerifyUpdate,
+ &C_VerifyFinal,
+ &C_VerifyRecoverInit,
+ &C_VerifyRecover,
+ &C_DigestEncryptUpdate,
+ &C_DecryptDigestUpdate,
+ &C_SignEncryptUpdate,
+ &C_DecryptVerifyUpdate,
+ &C_GenerateKey,
+ &C_GenerateKeyPair,
+ &C_WrapKey,
+ &C_UnwrapKey,
+ &C_DeriveKey,
+ &C_SeedRandom,
+ &C_GenerateRandom,
+ &C_GetFunctionStatus,
+ &C_CancelFunction,
+ &C_WaitForSlotEvent
+};
+
+
+/* Copy a string into a buffer without NUL termination and padded with ' ' */
+static void
+copy_padded_string(CK_UTF8CHAR_PTR dest, const CK_UTF8CHAR_PTR src, size_t dest_size)
+{
+ const size_t len = strlen((char*)src);
+
+ g_assert (len < dest_size);
+
+ memset(dest, ' ', dest_size);
+ memcpy(dest, src, len);
+}
+
+CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs)
+{
+ int status;
+ gnutls_datum_t data;
+ char *path;
+
+ if (CK_TRUE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_ALREADY_INITIALIZED;
+
+ IGNORE(pInitArgs);
+
+ path = g_test_build_filename(G_TEST_DIST, "test-cert.pem", NULL);
+ status = gnutls_load_file(path, &data);
+ g_debug("Loading %s - %s", path, gnutls_strerror(status));
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ status = gnutls_x509_crt_init(&mock_objects[0].cert);
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ status = gnutls_x509_crt_import(mock_objects[0].cert, &data, GNUTLS_X509_FMT_PEM);
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ gnutls_free(data.data);
+ g_free(path);
+
+ path = g_test_build_filename(G_TEST_DIST, "test-key.pem", NULL);
+ status = gnutls_load_file(path, &data);
+ g_debug("Loading %s - %s", path, gnutls_strerror(status));
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ status = gnutls_privkey_init(&mock_objects[1].key);
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ status = gnutls_privkey_import_x509_raw(mock_objects[1].key, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ gnutls_free(data.data);
+ g_free(path);
+
+ pkcs11_mock_initialized = CK_TRUE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(CK_VOID_PTR pReserved)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ IGNORE(pReserved);
+
+ gnutls_x509_crt_deinit(mock_objects[0].cert);
+ gnutls_privkey_deinit(mock_objects[1].key);
+
+ pkcs11_mock_initialized = CK_FALSE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ pInfo->cryptokiVersion = mock_info.cryptokiVersion;
+ copy_padded_string(pInfo->manufacturerID, mock_info.manufacturerID, sizeof(pInfo->manufacturerID));
+ pInfo->flags = 0;
+ copy_padded_string(pInfo->libraryDescription, mock_info.libraryDescription, sizeof(pInfo->libraryDescription));
+ pInfo->libraryVersion = mock_info.libraryVersion;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
+{
+ if (NULL == ppFunctionList)
+ return CKR_ARGUMENTS_BAD;
+
+ *ppFunctionList = &pkcs11_mock_functions;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ IGNORE(tokenPresent);
+
+ if (NULL == pulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pSlotList)
+ {
+ *pulCount = 1;
+ }
+ else
+ {
+ if (0 == *pulCount)
+ return CKR_BUFFER_TOO_SMALL;
+
+ pSlotList[0] = PKCS11_MOCK_CK_SLOT_ID;
+ *pulCount = 1;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
+{
+ MockSlot mock_slot;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (slotID > G_N_ELEMENTS (mock_slots))
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ mock_slot = mock_slots[slotID];
+
+ copy_padded_string(pInfo->slotDescription, mock_slot.info.slotDescription, sizeof(pInfo->slotDescription));
+ copy_padded_string(pInfo->manufacturerID, mock_slot.info.manufacturerID, sizeof(pInfo->manufacturerID));
+ pInfo->flags = mock_slot.info.flags;
+ pInfo->hardwareVersion = mock_slot.info.hardwareVersion;
+ pInfo->firmwareVersion = mock_slot.info.firmwareVersion;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
+{
+ CK_TOKEN_INFO token;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (slotID > G_N_ELEMENTS (mock_slots))
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ token = mock_objects[slotID].info;
+
+ copy_padded_string(pInfo->label, token.label, sizeof(pInfo->label));
+ copy_padded_string(pInfo->manufacturerID, token.manufacturerID, sizeof(pInfo->manufacturerID));
+ copy_padded_string(pInfo->serialNumber, token.serialNumber, sizeof(pInfo->serialNumber));
+ copy_padded_string(pInfo->model, token.model, sizeof(pInfo->model));
+ pInfo->flags = token.flags;
+ pInfo->ulMaxSessionCount = token.ulMaxSessionCount;
+ pInfo->ulSessionCount = (CK_TRUE == pkcs11_mock_session_opened) ? 1 : 0;
+ pInfo->ulMaxRwSessionCount = token.ulMaxRwSessionCount;
+ pInfo->ulRwSessionCount = ((CK_TRUE == pkcs11_mock_session_opened) && ((CKS_RO_PUBLIC_SESSION != pkcs11_mock_session_state) || (CKS_RO_USER_FUNCTIONS != pkcs11_mock_session_state))) ? 1 : 0;
+ pInfo->ulMaxPinLen = token.ulMaxPinLen;
+ pInfo->ulMinPinLen = token.ulMinPinLen;
+ pInfo->ulTotalPublicMemory = token.ulTotalPublicMemory;
+ pInfo->ulFreePublicMemory = token.ulFreePublicMemory;
+ pInfo->ulTotalPrivateMemory = token.ulTotalPrivateMemory;
+ pInfo->ulFreePrivateMemory = token.ulFreePrivateMemory;
+ pInfo->hardwareVersion = token.hardwareVersion;
+ pInfo->firmwareVersion = token.firmwareVersion;
+ memset(pInfo->utcTime, ' ', sizeof(pInfo->utcTime));
+
+ // FIXME: Not picked up by gnutls
+ if (mock_login_attempts > 2)
+ {
+ pInfo->flags |= CKF_USER_PIN_COUNT_LOW;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (slotID > G_N_ELEMENTS(mock_slots))
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pMechanismList)
+ {
+ *pulCount = 9;
+ }
+ else
+ {
+ if (9 > *pulCount)
+ return CKR_BUFFER_TOO_SMALL;
+
+ pMechanismList[0] = CKM_RSA_PKCS_KEY_PAIR_GEN;
+ pMechanismList[1] = CKM_RSA_PKCS;
+ pMechanismList[2] = CKM_SHA1_RSA_PKCS;
+ pMechanismList[3] = CKM_RSA_PKCS_OAEP;
+ pMechanismList[4] = CKM_DES3_CBC;
+ pMechanismList[5] = CKM_DES3_KEY_GEN;
+ pMechanismList[6] = CKM_SHA_1;
+ pMechanismList[7] = CKM_XOR_BASE_AND_DATA;
+ pMechanismList[8] = CKM_AES_CBC;
+
+ *pulCount = 9;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (type)
+ {
+ case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_GENERATE_KEY_PAIR;
+ break;
+
+ case CKM_RSA_PKCS:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER | CKF_WRAP | CKF_UNWRAP;
+ break;
+
+ case CKM_SHA1_RSA_PKCS:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_SIGN | CKF_VERIFY;
+ break;
+
+ case CKM_RSA_PKCS_OAEP:
+ pInfo->ulMinKeySize = 1024;
+ pInfo->ulMaxKeySize = 1024;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
+ break;
+
+ case CKM_DES3_CBC:
+ pInfo->ulMinKeySize = 192;
+ pInfo->ulMaxKeySize = 192;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
+ break;
+
+ case CKM_DES3_KEY_GEN:
+ pInfo->ulMinKeySize = 192;
+ pInfo->ulMaxKeySize = 192;
+ pInfo->flags = CKF_GENERATE;
+ break;
+
+ case CKM_SHA_1:
+ pInfo->ulMinKeySize = 0;
+ pInfo->ulMaxKeySize = 0;
+ pInfo->flags = CKF_DIGEST;
+ break;
+
+ case CKM_XOR_BASE_AND_DATA:
+ pInfo->ulMinKeySize = 128;
+ pInfo->ulMaxKeySize = 256;
+ pInfo->flags = CKF_DERIVE;
+ break;
+
+ case CKM_AES_CBC:
+ pInfo->ulMinKeySize = 128;
+ pInfo->ulMaxKeySize = 256;
+ pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT;
+ break;
+
+ case CKM_RSA_PKCS_PSS:
+ // FIXME: Made up key sizes
+ pInfo->ulMinKeySize = 256;
+ pInfo->ulMaxKeySize = 256;
+ // Flags based on table here: http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/csd01/pkcs11-curr-v2.40-csd01.html
+ pInfo->flags = CKF_SIGN | CKF_VERIFY;
+ break;
+
+ default:
+ return CKR_MECHANISM_INVALID;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_InitToken)(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (NULL == pPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulPinLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulPinLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ if (NULL == pLabel)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CK_TRUE == pkcs11_mock_session_opened)
+ return CKR_SESSION_EXISTS;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_InitPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (CKS_RW_SO_FUNCTIONS != pkcs11_mock_session_state)
+ return CKR_USER_NOT_LOGGED_IN;
+
+ if (NULL == pPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulPinLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulPinLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((CKS_RO_PUBLIC_SESSION == pkcs11_mock_session_state) || (CKS_RO_USER_FUNCTIONS == pkcs11_mock_session_state))
+ return CKR_SESSION_READ_ONLY;
+
+ if (NULL == pOldPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulOldLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulOldLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ if (NULL == pNewPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulNewLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulNewLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (CK_TRUE == pkcs11_mock_session_opened)
+ return CKR_SESSION_COUNT;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ if (!(flags & CKF_SERIAL_SESSION))
+ return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
+
+ IGNORE(pApplication);
+
+ IGNORE(Notify);
+
+ if (NULL == phSession)
+ return CKR_ARGUMENTS_BAD;
+
+ pkcs11_mock_session_opened = CK_TRUE;
+ pkcs11_mock_session_state = (flags & CKF_RW_SESSION) ? CKS_RW_PUBLIC_SESSION : CKS_RO_PUBLIC_SESSION;
+ *phSession = PKCS11_MOCK_CK_SESSION_ID;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ pkcs11_mock_session_opened = CK_FALSE;
+ pkcs11_mock_session_state = CKS_RO_PUBLIC_SESSION;
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)(CK_SLOT_ID slotID)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_SLOT_ID != slotID)
+ return CKR_SLOT_ID_INVALID;
+
+ pkcs11_mock_session_opened = CK_FALSE;
+ pkcs11_mock_session_state = CKS_RO_PUBLIC_SESSION;
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pInfo)
+ return CKR_ARGUMENTS_BAD;
+
+ pInfo->slotID = PKCS11_MOCK_CK_SLOT_ID;
+ pInfo->state = pkcs11_mock_session_state;
+ pInfo->flags = CKF_SERIAL_SESSION;
+ if ((pkcs11_mock_session_state != CKS_RO_PUBLIC_SESSION) && (pkcs11_mock_session_state != CKS_RO_USER_FUNCTIONS))
+ pInfo->flags = pInfo->flags | CKF_RW_SESSION;
+ pInfo->ulDeviceError = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetOperationState)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulOperationStateLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pOperationState)
+ {
+ *pulOperationStateLen = 256;
+ }
+ else
+ {
+ if (256 > *pulOperationStateLen)
+ return CKR_BUFFER_TOO_SMALL;
+
+ memset(pOperationState, 1, 256);
+ *pulOperationStateLen = 256;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SetOperationState)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pOperationState)
+ return CKR_ARGUMENTS_BAD;
+
+ if (256 != ulOperationStateLen)
+ return CKR_ARGUMENTS_BAD;
+
+ IGNORE(hEncryptionKey);
+
+ IGNORE(hAuthenticationKey);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
+{
+ // More hardcoding
+ const char *password = "ABC123";
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((CKU_SO != userType) && (CKU_USER != userType) && (CKU_CONTEXT_SPECIFIC != userType))
+ return CKR_USER_TYPE_INVALID;
+
+ if (NULL == pPin)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((ulPinLen < PKCS11_MOCK_CK_TOKEN_INFO_MIN_PIN_LEN) || (ulPinLen > PKCS11_MOCK_CK_TOKEN_INFO_MAX_PIN_LEN))
+ return CKR_PIN_LEN_RANGE;
+
+ // FIXME: gnutls bug? It calls this before an operation
+ // if (pkcs11_mock_active_operation == PKCS11_MOCK_CK_OPERATION_NONE && CKU_CONTEXT_SPECIFIC != userType)
+ // return CKR_OPERATION_NOT_INITIALIZED;
+
+ if (mock_logged_in_state == TRUE)
+ return CKR_USER_ALREADY_LOGGED_IN;
+
+ if (ulPinLen == strlen (password) && strncmp ((char*)pPin, password, ulPinLen) == 0)
+ {
+ mock_logged_in_state = TRUE;
+ mock_login_attempts = 0;
+ return CKR_OK;
+ }
+ else
+ {
+ mock_login_attempts += 1;
+ return CKR_PIN_INCORRECT;
+ }
+
+ // TODO: We don't test any of these states atm
+ // switch (pkcs11_mock_session_state)
+ // {
+ // case CKS_RO_PUBLIC_SESSION:
+
+ // if (CKU_SO == userType)
+ // rv = CKR_SESSION_READ_ONLY_EXISTS;
+ // else
+ // pkcs11_mock_session_state = CKS_RO_USER_FUNCTIONS;
+
+ // break;
+
+ // case CKS_RO_USER_FUNCTIONS:
+ // case CKS_RW_USER_FUNCTIONS:
+
+ // rv = (CKU_SO == userType) ? CKR_USER_ANOTHER_ALREADY_LOGGED_IN : CKR_USER_ALREADY_LOGGED_IN;
+
+ // break;
+
+ // case CKS_RW_PUBLIC_SESSION:
+
+ // pkcs11_mock_session_state = (CKU_SO == userType) ? CKS_RW_SO_FUNCTIONS : CKS_RW_USER_FUNCTIONS;
+
+ // break;
+
+ // case CKS_RW_SO_FUNCTIONS:
+
+ // rv = (CKU_SO == userType) ? CKR_USER_ALREADY_LOGGED_IN : CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
+
+ // break;
+ // }
+
+ // return rv;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Logout)(CK_SESSION_HANDLE hSession)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (mock_logged_in_state == FALSE)
+ return CKR_USER_NOT_LOGGED_IN;
+
+ // if ((pkcs11_mock_session_state == CKS_RO_PUBLIC_SESSION) || (pkcs11_mock_session_state == CKS_RW_PUBLIC_SESSION))
+ // return CKR_USER_NOT_LOGGED_IN;
+
+ mock_logged_in_state = FALSE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phObject)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phObject = PKCS11_MOCK_CK_OBJECT_HANDLE_DATA;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(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_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == phNewObject)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((NULL != pTemplate) && (0 >= ulCount))
+ {
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ }
+
+ *phNewObject = PKCS11_MOCK_CK_OBJECT_HANDLE_DATA;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hObject))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetObjectSize)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (hObject > G_N_ELEMENTS (mock_objects))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == pulSize)
+ return CKR_ARGUMENTS_BAD;
+
+ *pulSize = 0; // FIXME: mock_objects[hObject].size;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ CK_ULONG i = 0;
+ MockObject obj;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (hObject > G_N_ELEMENTS (mock_objects))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ obj = mock_objects[hObject];
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (CKA_LABEL == pTemplate[i].type || CKA_ID == pTemplate[i].type)
+ {
+ if (NULL != pTemplate[i].pValue)
+ {
+ if (pTemplate[i].ulValueLen < strlen((char*)obj.info.label))
+ return CKR_BUFFER_TOO_SMALL;
+ else
+ memcpy(pTemplate[i].pValue, obj.info.label, strlen((char*)obj.info.label));
+ }
+
+ pTemplate[i].ulValueLen = strlen((char*)obj.info.label);
+ }
+ else if (CKA_EXTRACTABLE == pTemplate[i].type)
+ {
+ *((CK_BBOOL *) pTemplate[i].pValue) = obj.object_class == CKO_CERTIFICATE ? CK_TRUE : CK_FALSE;
+ pTemplate[i].ulValueLen = sizeof(CK_BBOOL);
+ }
+ else if (CKA_NEVER_EXTRACTABLE == pTemplate[i].type || CKA_SENSITIVE == pTemplate[i].type)
+ {
+ *((CK_BBOOL *) pTemplate[i].pValue) = obj.object_class == CKO_PRIVATE_KEY ? CK_TRUE : CK_FALSE;
+ pTemplate[i].ulValueLen = sizeof(CK_BBOOL);
+ }
+ else if (CKA_CERTIFICATE_CATEGORY == pTemplate[i].type)
+ {
+ CK_ULONG t;
+ if (pTemplate[i].ulValueLen < sizeof(CK_ULONG))
+ return CKR_BUFFER_TOO_SMALL;
+
+ if (obj.object_class == CKO_CERTIFICATE)
+ t = CK_CERTIFICATE_CATEGORY_AUTHORITY;
+ else
+ t = CK_CERTIFICATE_CATEGORY_UNSPECIFIED;
+
+ memcpy(pTemplate[i].pValue, &t, sizeof(CK_ULONG));
+ }
+ else if (CKA_SUBJECT == pTemplate[i].type)
+ {
+ int status;
+ gnutls_datum_t data;
+ gnutls_x509_dn_t dn; /* Owned by cert */
+
+ g_assert (obj.object_class == CKO_CERTIFICATE);
+
+ status = gnutls_x509_crt_get_subject(obj.cert, &dn);
+ g_assert(status == GNUTLS_E_SUCCESS);
+ status = gnutls_x509_dn_get_str(dn, &data);
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ if (data.size > pTemplate[i].ulValueLen)
+ {
+ gnutls_free(data.data);
+ pTemplate[i].ulValueLen = data.size;
+ if (pTemplate[i].pValue != NULL) /* If NULL return OK */
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pTemplate[i].pValue, data.data, data.size);
+ pTemplate[i].ulValueLen = data.size;
+ gnutls_free(data.data);
+ }
+ }
+ else if (CKA_VALUE == pTemplate[i].type)
+ {
+ if (obj.object_class == CKO_CERTIFICATE)
+ {
+ int status;
+ gnutls_datum_t data;
+
+ status = gnutls_x509_crt_export2(obj.cert, GNUTLS_X509_FMT_DER, &data);
+ g_assert(status == GNUTLS_E_SUCCESS);
+
+ if (data.size > pTemplate[i].ulValueLen)
+ {
+ gnutls_free(data.data);
+ pTemplate[i].ulValueLen = data.size;
+ if (pTemplate[i].pValue != NULL) /* If NULL return OK */
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pTemplate[i].pValue, data.data, data.size);
+ gnutls_free(data.data);
+ pTemplate[i].ulValueLen = data.size;
+ }
+ }
+ else
+ {
+ pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
+ }
+ }
+ else if (CKA_CLASS == pTemplate[i].type)
+ {
+ if (NULL != pTemplate[i].pValue)
+ *((CK_ULONG *) pTemplate[i].pValue) = obj.object_class;
+ pTemplate[i].ulValueLen = sizeof (obj.object_class);
+ }
+ else if (CKA_CERTIFICATE_TYPE == pTemplate[i].type)
+ {
+ CK_CERTIFICATE_TYPE ret = CKC_X_509;
+
+ if (pTemplate[i].ulValueLen != sizeof(CK_CERTIFICATE_TYPE))
+ return CKR_ARGUMENTS_BAD;
+
+ /* TODO: Test both TRUE and FALSE */
+ memcpy(pTemplate[i].pValue, &ret, sizeof(CK_CERTIFICATE_TYPE));
+ }
+ else if (CKA_KEY_TYPE == pTemplate[i].type)
+ {
+ CK_KEY_TYPE t;
+ if (pTemplate[i].ulValueLen != sizeof(CK_KEY_TYPE))
+ return CKR_ARGUMENTS_BAD;
+
+ if (obj.object_class != CKO_PRIVATE_KEY)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (gnutls_privkey_get_pk_algorithm (obj.key, NULL))
+ {
+ case GNUTLS_PK_RSA:
+ t = CKK_RSA;
+ break;
+ case GNUTLS_PK_DSA:
+ t = CKK_DSA;
+ break;
+ case GNUTLS_PK_DH:
+ t = CKK_DH;
+ break;
+ case GNUTLS_PK_EC:
+ t = CKK_EC;
+ break;
+ default:
+ pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+
+ memcpy(pTemplate[i].pValue, &t, sizeof(CK_KEY_TYPE));
+ }
+ else if (CKA_ALWAYS_AUTHENTICATE == pTemplate[i].type)
+ {
+ CK_BBOOL ret = CK_TRUE;
+
+ if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL))
+ return CKR_ARGUMENTS_BAD;
+
+ /* TODO: Test both TRUE and FALSE */
+ memcpy(pTemplate[i].pValue, &ret, sizeof(CK_BBOOL));
+ }
+ else if (CKA_MODULUS == pTemplate[i].type && obj.object_class == CKO_PRIVATE_KEY)
+ {
+ /* Hardcode RSA for now */
+ gnutls_datum_t modulus;
+ int status = gnutls_privkey_export_rsa_raw (obj.key, &modulus, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ g_assert (status == GNUTLS_E_SUCCESS);
+
+ if (modulus.size > pTemplate[i].ulValueLen)
+ {
+ gnutls_free(modulus.data);
+ pTemplate[i].ulValueLen = modulus.size;
+ if (pTemplate[i].pValue != NULL) /* If NULL return OK */
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pTemplate[i].pValue, modulus.data, modulus.size);
+ gnutls_free(modulus.data);
+ pTemplate[i].ulValueLen = modulus.size;
+ }
+ }
+ else if (CKA_SIGN == pTemplate[i].type && obj.object_class == CKO_PRIVATE_KEY) /* Any key type in future */
+ {
+ CK_BBOOL ret = CK_TRUE;
+
+ if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL))
+ return CKR_ARGUMENTS_BAD;
+
+ memcpy(pTemplate[i].pValue, &ret, sizeof(CK_BBOOL));
+ }
+ else
+ {
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (hObject > G_N_ELEMENTS (mock_objects))
+ if ((PKCS11_MOCK_CK_OBJECT_HANDLE_DATA != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hObject) &&
+ (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hObject))
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if ((CKA_LABEL == pTemplate[i].type) || (CKA_VALUE == pTemplate[i].type))
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ else
+ {
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+ }
+
+ return CKR_OK;
+}
+
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ CK_ULONG i = 0;
+ CK_ULONG_PTR cka_class_value = NULL;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation)
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pTemplate && ulCount != 0)
+ return CKR_ARGUMENTS_BAD;
+
+ mock_search_template_class = PKCS11_MOCK_CKO_ANYTHING;
+ g_clear_pointer (&mock_search_template_label, g_free);
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (CKA_CLASS == pTemplate[i].type)
+ {
+ if (sizeof(CK_ULONG) != pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ cka_class_value = (CK_ULONG_PTR) pTemplate[i].pValue;
+ mock_search_template_class = *cka_class_value;
+ }
+ else if (CKA_LABEL == pTemplate[i].type)
+ {
+ const char *cka_label_value = (char*)pTemplate[i].pValue;
+ mock_search_template_label = g_strndup (cka_label_value, pTemplate[i].ulValueLen);
+ }
+ else
+ {
+ g_info ("Ignoring search template for %lu", pTemplate[i].type);
+ }
+ }
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_FIND;
+ mock_search_iterator = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_FIND != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if ((NULL == phObject) && (0 < ulMaxObjectCount))
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulObjectCount)
+ return CKR_ARGUMENTS_BAD;
+
+ *pulObjectCount = 0;
+ for (; mock_search_iterator < G_N_ELEMENTS (mock_objects) && *pulObjectCount < ulMaxObjectCount; mock_search_iterator++)
+ {
+ if ((mock_search_template_class == PKCS11_MOCK_CKO_ANYTHING || mock_objects[mock_search_iterator].object_class == mock_search_template_class) &&
+ (mock_search_template_label == NULL || g_strcmp0 ((char*)mock_objects[mock_search_iterator].info.label, mock_search_template_label) == 0))
+ {
+ phObject[*pulObjectCount] = mock_search_iterator;
+ *pulObjectCount = *pulObjectCount + 1;
+ }
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_FIND != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_SIGN != pkcs11_mock_active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (pMechanism->mechanism)
+ {
+ case CKM_RSA_PKCS:
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_RSA_PKCS_OAEP:
+
+ if ((NULL == pMechanism->pParameter) || (sizeof(CK_RSA_PKCS_OAEP_PARAMS) != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_DES3_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (8 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_AES_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (16 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ default:
+
+ return CKR_MECHANISM_INVALID;
+ }
+
+ switch (pkcs11_mock_active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_NONE:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_SIGN:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
+{
+ CK_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_ENCRYPT != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedData)
+ {
+ if (ulDataLen > *pulEncryptedDataLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulDataLen; i++)
+ pEncryptedData[i] = pData[i] ^ 0xAB;
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulEncryptedDataLen = ulDataLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_ENCRYPT != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedPart)
+ {
+ if (ulPartLen > *pulEncryptedPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulPartLen; i++)
+ pEncryptedPart[i] = pPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_ENCRYPT != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT != pkcs11_mock_active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulLastEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pLastEncryptedPart)
+ {
+ switch (pkcs11_mock_active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_ENCRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_SIGN;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+ }
+
+ *pulLastEncryptedPartLen = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_VERIFY != pkcs11_mock_active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ switch (pMechanism->mechanism)
+ {
+ case CKM_RSA_PKCS:
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_RSA_PKCS_OAEP:
+
+ if ((NULL == pMechanism->pParameter) || (sizeof(CK_RSA_PKCS_OAEP_PARAMS) != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_DES3_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (8 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ case CKM_AES_CBC:
+
+ if ((NULL == pMechanism->pParameter) || (16 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+
+ break;
+
+ default:
+
+ return CKR_MECHANISM_INVALID;
+ }
+
+ switch (pkcs11_mock_active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_NONE:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_VERIFY:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pData)
+ {
+ if (ulEncryptedDataLen > *pulDataLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedDataLen; i++)
+ pData[i] = pEncryptedData[i] ^ 0xAB;
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulDataLen = ulEncryptedDataLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pPart)
+ {
+ if (ulEncryptedPartLen > *pulPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedPartLen; i++)
+ pPart[i] = pEncryptedPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_DECRYPT != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY != pkcs11_mock_active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulLastPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pLastPart)
+ {
+ switch (pkcs11_mock_active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_VERIFY;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+ }
+
+ *pulLastPartLen = 0;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_ENCRYPT != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT != pkcs11_mock_active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_SHA_1 != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ switch (pkcs11_mock_active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_NONE:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_ENCRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+{
+ CK_BYTE hash[20] = { 0x7B, 0x50, 0x2C, 0x3A, 0x1F, 0x48, 0xC8, 0x60, 0x9A, 0xE2, 0x12, 0xCD, 0xFB, 0x63, 0x9D, 0xEE, 0x39, 0x67, 0x3F, 0x5E };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulDigestLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pDigest)
+ {
+ if (sizeof(hash) > *pulDigestLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pDigest, hash, sizeof(hash));
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulDigestLen = sizeof(hash);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+{
+ CK_BYTE hash[20] = { 0x7B, 0x50, 0x2C, 0x3A, 0x1F, 0x48, 0xC8, 0x60, 0x9A, 0xE2, 0x12, 0xCD, 0xFB, 0x63, 0x9D, 0xEE, 0x39, 0x67, 0x3F, 0x5E };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_DIGEST != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST != pkcs11_mock_active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulDigestLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pDigest)
+ {
+ if (sizeof(hash) > *pulDigestLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pDigest, hash, sizeof(hash));
+
+ switch (pkcs11_mock_active_operation)
+ {
+ case PKCS11_MOCK_CK_OPERATION_DIGEST:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_ENCRYPT;
+ break;
+ case PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST:
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT;
+ break;
+ default:
+ return CKR_FUNCTION_FAILED;
+ }
+ }
+ }
+
+ *pulDigestLen = sizeof(hash);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_ENCRYPT != pkcs11_mock_active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (hKey > G_N_ELEMENTS(mock_objects) || mock_objects[hKey].object_class != CKO_PRIVATE_KEY)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ mock_sign_algo = pMechanism->mechanism;
+
+ // TODO: Hardcoded list
+ if (CKM_RSA_PKCS_PSS == pMechanism->mechanism)
+ {
+ CK_RSA_PKCS_PSS_PARAMS *params;
+
+ if ((NULL == pMechanism->pParameter) || (0 == pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ params = pMechanism->pParameter;
+
+ g_assert (params->hashAlg == CKM_SHA256);
+ g_assert (params->mgf == CKG_MGF1_SHA256);
+ // if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ // return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else if (CKM_RSA_PKCS == pMechanism->mechanism)
+ {
+ // FIXME: Also assert SHA256?
+ }
+ else
+ {
+ g_assert_not_reached ();
+ return CKR_MECHANISM_INVALID;
+ }
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE == pkcs11_mock_active_operation)
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_SIGN;
+ else
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT;
+
+ pkcs11_mock_sign_key = hKey;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ const gnutls_datum_t data = {
+ .data = pData,
+ .size = ulDataLen,
+ };
+ gnutls_datum_t signature;
+ int status;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ // TODO: Handle user not logged in
+
+ // TODO: Hardcoded algo list
+ if (mock_sign_algo == CKM_RSA_PKCS_PSS)
+ status = gnutls_privkey_sign_hash2 (mock_objects[pkcs11_mock_sign_key].key, GNUTLS_SIGN_RSA_PSS_SHA256,
+ GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS, &data, &signature);
+ else if (mock_sign_algo == CKM_RSA_PKCS)
+ status = gnutls_privkey_sign_hash2 (mock_objects[pkcs11_mock_sign_key].key, GNUTLS_SIGN_RSA_SHA256,
+ GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, &data, &signature);
+ else
+ g_assert_not_reached ();
+
+ // g_assert (status == GNUTLS_E_SUCCESS);
+ if (status != GNUTLS_E_SUCCESS)
+ return CKR_FUNCTION_FAILED; // TODO: Best return code?
+
+ if (signature.size > *pulSignatureLen)
+ {
+ gnutls_free (signature.data);
+ *pulSignatureLen = signature.size;
+ if (pSignature != NULL)
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ // This is called twice, once with NULL to just query size
+ if (pSignature != NULL)
+ {
+ memcpy (pSignature, signature.data, signature.size);
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ *pulSignatureLen = signature.size;
+ gnutls_free (signature.data);
+ }
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_SIGN != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT != pkcs11_mock_active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pSignature)
+ {
+ if (sizeof(signature) > *pulSignatureLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ memcpy(pSignature, signature, sizeof(signature));
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN == pkcs11_mock_active_operation)
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ else
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_ENCRYPT;
+ }
+ }
+
+ *pulSignatureLen = sizeof(signature);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignRecoverInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation)
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS == pMechanism->mechanism)
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_SIGN_RECOVER;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN_RECOVER != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pSignature)
+ {
+ if (ulDataLen > *pulSignatureLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulDataLen; i++)
+ pSignature[i] = pData[i] ^ 0xAB;
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulSignatureLen = ulDataLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT != pkcs11_mock_active_operation))
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((CKM_RSA_PKCS == pMechanism->mechanism) || (CKM_SHA1_RSA_PKCS == pMechanism->mechanism))
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE == pkcs11_mock_active_operation)
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_VERIFY;
+ else
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pSignature)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (sizeof(signature) != ulSignatureLen)
+ return CKR_SIGNATURE_LEN_RANGE;
+
+ if (0 != memcmp(pSignature, signature, sizeof(signature)))
+ return CKR_SIGNATURE_INVALID;
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+{
+ CK_BYTE signature[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((PKCS11_MOCK_CK_OPERATION_VERIFY != pkcs11_mock_active_operation) &&
+ (PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY != pkcs11_mock_active_operation))
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pSignature)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (sizeof(signature) != ulSignatureLen)
+ return CKR_SIGNATURE_LEN_RANGE;
+
+ if (0 != memcmp(pSignature, signature, sizeof(signature)))
+ return CKR_SIGNATURE_INVALID;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY == pkcs11_mock_active_operation)
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ else
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_DECRYPT;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_NONE != pkcs11_mock_active_operation)
+ return CKR_OPERATION_ACTIVE;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS == pMechanism->mechanism)
+ {
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hKey)
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ else
+ {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_VERIFY_RECOVER;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_VERIFY_RECOVER != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pSignature)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSignatureLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulDataLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pData)
+ {
+ if (ulSignatureLen > *pulDataLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulSignatureLen; i++)
+ pData[i] = pSignature[i] ^ 0xAB;
+
+ pkcs11_mock_active_operation = PKCS11_MOCK_CK_OPERATION_NONE;
+ }
+ }
+
+ *pulDataLen = ulSignatureLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
+{
+ CK_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DIGEST_ENCRYPT != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedPart)
+ {
+ if (ulPartLen > *pulEncryptedPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulPartLen; i++)
+ pEncryptedPart[i] = pPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT_DIGEST != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pPart)
+ {
+ if (ulEncryptedPartLen > *pulPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedPartLen; i++)
+ pPart[i] = pEncryptedPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
+{
+ CK_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_SIGN_ENCRYPT != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pEncryptedPart)
+ {
+ if (ulPartLen > *pulEncryptedPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulPartLen; i++)
+ pEncryptedPart[i] = pPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+ CK_ULONG i = 0;
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if (PKCS11_MOCK_CK_OPERATION_DECRYPT_VERIFY != pkcs11_mock_active_operation)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pEncryptedPart)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulEncryptedPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pulPartLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pPart)
+ {
+ if (ulEncryptedPartLen > *pulPartLen)
+ {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ for (i = 0; i < ulEncryptedPartLen; i++)
+ pPart[i] = pEncryptedPart[i] ^ 0xAB;
+ }
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(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_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_DES3_KEY_GEN != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phKey)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phKey = PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(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_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS_KEY_PAIR_GEN != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (NULL == pPublicKeyTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPublicKeyAttributeCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pPrivateKeyTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulPrivateKeyAttributeCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phPublicKey)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phPrivateKey)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulPublicKeyAttributeCount; i++)
+ {
+ if (NULL == pPublicKeyTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pPublicKeyTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ for (i = 0; i < ulPrivateKeyAttributeCount; i++)
+ {
+ if (NULL == pPrivateKeyTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pPrivateKeyTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phPublicKey = PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY;
+ *phPrivateKey = PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(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_BYTE wrappedKey[10] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PUBLIC_KEY != hWrappingKey)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hKey)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (NULL != pWrappedKey)
+ {
+ if (sizeof(wrappedKey) > *pulWrappedKeyLen)
+ return CKR_BUFFER_TOO_SMALL;
+ else
+ memcpy(pWrappedKey, wrappedKey, sizeof(wrappedKey));
+ }
+
+ *pulWrappedKeyLen = sizeof(wrappedKey);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(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_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_RSA_PKCS != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL != pMechanism->pParameter) || (0 != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_PRIVATE_KEY != hUnwrappingKey)
+ return CKR_KEY_HANDLE_INVALID;
+
+ if (NULL == pWrappedKey)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulWrappedKeyLen)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pTemplate)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulAttributeCount)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == phKey)
+ return CKR_ARGUMENTS_BAD;
+
+ for (i = 0; i < ulAttributeCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ *phKey = PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(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_ULONG i = 0;
+
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pMechanism)
+ return CKR_ARGUMENTS_BAD;
+
+ if (CKM_XOR_BASE_AND_DATA != pMechanism->mechanism)
+ return CKR_MECHANISM_INVALID;
+
+ if ((NULL == pMechanism->pParameter) || (sizeof(CK_KEY_DERIVATION_STRING_DATA) != pMechanism->ulParameterLen))
+ return CKR_MECHANISM_PARAM_INVALID;
+
+ if (PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY != hBaseKey)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ if (NULL == phKey)
+ return CKR_ARGUMENTS_BAD;
+
+ if ((NULL != pTemplate) && (0 >= ulAttributeCount))
+ {
+ for (i = 0; i < ulAttributeCount; i++)
+ {
+ if (NULL == pTemplate[i].pValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ if (0 >= pTemplate[i].ulValueLen)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ }
+
+ *phKey = PKCS11_MOCK_CK_OBJECT_HANDLE_SECRET_KEY;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == pSeed)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulSeedLen)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen)
+{
+
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ if (NULL == RandomData)
+ return CKR_ARGUMENTS_BAD;
+
+ if (0 >= ulRandomLen)
+ return CKR_ARGUMENTS_BAD;
+
+ memset(RandomData, 1, ulRandomLen);
+
+ return CKR_OK;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionStatus)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_CancelFunction)(CK_SESSION_HANDLE hSession)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((CK_FALSE == pkcs11_mock_session_opened) || (PKCS11_MOCK_CK_SESSION_ID != hSession))
+ return CKR_SESSION_HANDLE_INVALID;
+
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+
+CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
+{
+ if (CK_FALSE == pkcs11_mock_initialized)
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+
+ if ((0 != flags) && (CKF_DONT_BLOCK != flags))
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL == pSlot)
+ return CKR_ARGUMENTS_BAD;
+
+ if (NULL != pReserved)
+ return CKR_ARGUMENTS_BAD;
+
+ return CKR_NO_EVENT;
+}