/* * COPYRIGHT (c) International Business Machines Corp. 2020 * * This program is provided under the terms of the Common Public License, * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this * software constitutes recipient's acceptance of CPL-1.0 terms which can be * found in the file LICENSE file or at * https://opensource.org/licenses/cpl1.0.php */ #include #include #include #include "pkcs11types.h" #include "regress.h" static int get_interface_test(void) { CK_FUNCTION_LIST_3_0 *tfn; CK_INTERFACE *interface; CK_VERSION version, *v; CK_SLOT_ID slot; CK_FLAGS flags; CK_RV rv; int rc = -1; testcase_new_assertion(); flags = 0ULL; rv = funcs3->C_GetInterface(NULL, NULL, NULL, flags); if (rv != CKR_ARGUMENTS_BAD) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } flags = ~0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"PKCS 11", NULL, &interface, flags); if (rv != CKR_FUNCTION_FAILED) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } version.major = 0; version.minor = 0; flags = 0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"PKCS 11", &version, &interface, flags); if (rv != CKR_FUNCTION_FAILED) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } flags = 0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"INVALID", NULL, &interface, flags); if (rv != CKR_FUNCTION_FAILED) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } flags = 0ULL; rv = funcs3->C_GetInterface(NULL, NULL, &interface, flags); if (rv != CKR_OK) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } v = (CK_VERSION *)interface->pFunctionList; printf("%s\n", "Default interface:"); printf("pInterfaceName %s\n", interface->pInterfaceName); printf("pFunctionList version %u.%u\n", v->major, v->minor); printf("flags 0x%016lx\n", interface->flags); flags = 0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"PKCS 11", NULL, &interface, flags); if (rv != CKR_OK) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } if (strcmp((char *)interface->pInterfaceName, "PKCS 11") != 0) { testcase_fail("Returned interface name: %s.\n", interface->pInterfaceName); goto ret; } v = (CK_VERSION *)interface->pFunctionList; printf("%s\n", "Default PKCS #11 interface:"); printf("pInterfaceName %s\n", interface->pInterfaceName); printf("pFunctionList version %u.%u\n", v->major, v->minor); printf("flags 0x%016lx\n", interface->flags); version.major = 1; version.minor = 0; flags = 0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"Vendor IBM", NULL, &interface, flags); if (rv != CKR_OK) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } if (strcmp((char *)interface->pInterfaceName, "Vendor IBM") != 0) { testcase_fail("Returned interface name: %s.\n", interface->pInterfaceName); goto ret; } v = (CK_VERSION *)interface->pFunctionList; printf("%s\n", "Vendor defined interface (IBM):"); printf("pInterfaceName %s\n", interface->pInterfaceName); printf("pFunctionList version %u.%u\n", v->major, v->minor); printf("flags 0x%016lx\n", interface->flags); version.major = 2; version.minor = 40; flags = 0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"PKCS 11", &version, &interface, flags); if (rv != CKR_OK) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } if (strcmp((char *)interface->pInterfaceName, "PKCS 11") != 0) { testcase_fail("Returned interface name: %s.\n", interface->pInterfaceName); goto ret; } v = (CK_VERSION *)interface->pFunctionList; if (v->major != version.major || v->minor != version.minor) { testcase_fail("Returned version: %u.%u.\n", v->major, v->minor); goto ret; } printf("%s\n", "PKCS #11 version 2.40 interface:"); printf("pInterfaceName %s\n", interface->pInterfaceName); printf("pFunctionList version %u.%u\n", v->major, v->minor); printf("flags 0x%016lx\n", interface->flags); version.major = 3; version.minor = 0; flags = 0ULL; rv = funcs3->C_GetInterface((CK_UTF8CHAR *)"PKCS 11", &version, &interface, flags); if (rv != CKR_OK) { testcase_fail("C_GetInterface returned %s.\n", p11_get_ckr(rv)); goto ret; } if (strcmp((char *)interface->pInterfaceName, "PKCS 11") != 0) { testcase_fail("Returned interface name: %s.\n", interface->pInterfaceName); goto ret; } v = (CK_VERSION *)interface->pFunctionList; if (v->major != version.major || v->minor != version.minor) { testcase_fail("Returned version: %u.%u.\n", v->major, v->minor); goto ret; } printf("%s\n", "PKCS #11 version 3.0 interface:"); printf("pInterfaceName %s\n", interface->pInterfaceName); printf("pFunctionList version %u.%u\n", v->major, v->minor); printf("flags 0x%016lx\n", interface->flags); tfn = (CK_FUNCTION_LIST_3_0 *)interface->pFunctionList; if (tfn->C_Initialize == NULL || tfn->C_Finalize == NULL || tfn->C_GetInfo == NULL || tfn->C_GetFunctionList == NULL || tfn->C_GetSlotList == NULL || tfn->C_GetSlotInfo == NULL || tfn->C_GetTokenInfo == NULL || tfn->C_GetMechanismList == NULL || tfn->C_GetMechanismInfo == NULL || tfn->C_InitToken == NULL || tfn->C_InitPIN == NULL || tfn->C_SetPIN == NULL || tfn->C_OpenSession == NULL || tfn->C_CloseSession == NULL || tfn->C_CloseAllSessions == NULL || tfn->C_GetSessionInfo == NULL || tfn->C_GetOperationState == NULL || tfn->C_SetOperationState == NULL || tfn->C_Login == NULL || tfn->C_Logout == NULL || tfn->C_CreateObject == NULL || tfn->C_CopyObject == NULL || tfn->C_DestroyObject == NULL || tfn->C_GetObjectSize == NULL || tfn->C_GetAttributeValue == NULL || tfn->C_SetAttributeValue == NULL || tfn->C_FindObjectsInit == NULL || tfn->C_FindObjects == NULL || tfn->C_FindObjectsFinal == NULL || tfn->C_EncryptInit == NULL || tfn->C_Encrypt == NULL || tfn->C_EncryptUpdate == NULL || tfn->C_EncryptFinal == NULL || tfn->C_DecryptInit == NULL || tfn->C_Decrypt == NULL || tfn->C_DecryptUpdate == NULL || tfn->C_DecryptFinal == NULL || tfn->C_DigestInit == NULL || tfn->C_Digest == NULL || tfn->C_DigestUpdate == NULL || tfn->C_DigestKey == NULL || tfn->C_DigestFinal == NULL || tfn->C_SignInit == NULL || tfn->C_Sign == NULL || tfn->C_SignUpdate == NULL || tfn->C_SignFinal == NULL || tfn->C_SignRecoverInit == NULL || tfn->C_SignRecover == NULL || tfn->C_VerifyInit == NULL || tfn->C_Verify == NULL || tfn->C_VerifyUpdate == NULL || tfn->C_VerifyFinal == NULL || tfn->C_VerifyRecoverInit == NULL || tfn->C_VerifyRecover == NULL || tfn->C_DigestEncryptUpdate == NULL || tfn->C_DecryptDigestUpdate == NULL || tfn->C_SignEncryptUpdate == NULL || tfn->C_DecryptVerifyUpdate == NULL || tfn->C_GenerateKey == NULL || tfn->C_GenerateKeyPair == NULL || tfn->C_WrapKey == NULL || tfn->C_UnwrapKey == NULL || tfn->C_DeriveKey == NULL || tfn->C_SeedRandom == NULL || tfn->C_GenerateRandom == NULL || tfn->C_GetFunctionStatus == NULL || tfn->C_CancelFunction == NULL || tfn->C_WaitForSlotEvent == NULL /* Additional PKCS #11 3.0 functions */ || tfn->C_GetInterfaceList == NULL || tfn->C_GetInterface == NULL || tfn->C_LoginUser == NULL || tfn->C_SessionCancel == NULL || tfn->C_MessageEncryptInit == NULL || tfn->C_EncryptMessage == NULL || tfn->C_EncryptMessageBegin == NULL || tfn->C_EncryptMessageNext == NULL || tfn->C_MessageEncryptFinal == NULL || tfn->C_MessageDecryptInit == NULL || tfn->C_DecryptMessage == NULL || tfn->C_DecryptMessageBegin == NULL || tfn->C_DecryptMessageNext == NULL || tfn->C_MessageDecryptFinal == NULL || tfn->C_MessageSignInit == NULL || tfn->C_SignMessage == NULL || tfn->C_SignMessageBegin == NULL || tfn->C_SignMessageNext == NULL || tfn->C_MessageSignFinal == NULL || tfn->C_MessageVerifyInit == NULL || tfn->C_VerifyMessage == NULL || tfn->C_VerifyMessageBegin == NULL || tfn->C_VerifyMessageNext == NULL || tfn->C_MessageVerifyFinal == NULL) { testcase_fail("%s", "Returned CK_FUNCTION_LIST_3_0 contains" " a NULL function pointer.\n"); goto ret; } /* * Function pointers are != NULL. * Now check if they are valid. */ slot = 0; tfn->C_Initialize(NULL); tfn->C_Finalize(NULL); tfn->C_GetInfo(NULL); tfn->C_GetFunctionList(NULL); tfn->C_GetSlotList(CK_FALSE, NULL, NULL); tfn->C_GetSlotInfo(slot, NULL); tfn->C_GetTokenInfo(slot, NULL); tfn->C_GetMechanismList(slot, NULL, NULL); tfn->C_GetMechanismInfo(slot, 0UL, NULL); tfn->C_InitToken(slot, NULL, 0UL, NULL); tfn->C_InitPIN(0UL, NULL, 0UL); tfn->C_SetPIN(0UL, NULL, 0UL, NULL, 0UL); tfn->C_OpenSession(slot, 0UL, NULL, NULL, NULL); tfn->C_CloseSession(0UL); tfn->C_CloseAllSessions(slot); tfn->C_GetSessionInfo(0UL, NULL); tfn->C_GetOperationState(0UL, NULL, NULL); tfn->C_SetOperationState(0UL, NULL, 0UL, 0UL, 0UL); tfn->C_Login(0UL, 0UL, NULL, 0UL); tfn->C_Logout(0UL); tfn->C_CreateObject(0UL, NULL, 0UL, NULL); tfn->C_CopyObject(0UL, 0UL, NULL, 0UL, NULL); tfn->C_DestroyObject(0UL, 0UL); tfn->C_GetObjectSize(0UL, 0UL, NULL); tfn->C_GetAttributeValue(0UL, 0UL, NULL, 0UL); tfn->C_SetAttributeValue(0UL, 0UL, NULL, 0UL); tfn->C_FindObjectsInit(0UL, NULL, 0UL); tfn->C_FindObjects(0UL, NULL, 0UL, NULL); tfn->C_FindObjectsFinal(0UL); tfn->C_EncryptInit(0UL, NULL, 0UL); tfn->C_Encrypt(0UL, NULL, 0UL, NULL, NULL); tfn->C_EncryptUpdate(0UL, NULL, 0UL, NULL, NULL); tfn->C_EncryptFinal(0UL, NULL, NULL); tfn->C_DecryptInit(0UL, NULL, 0UL); tfn->C_Decrypt(0UL, NULL, 0UL, NULL, NULL); tfn->C_DecryptUpdate(0UL, NULL, 0UL, NULL, NULL); tfn->C_DecryptFinal(0UL, NULL, NULL); tfn->C_DigestInit(0UL, NULL); tfn->C_Digest(0UL, NULL, 0UL, NULL, 0UL); tfn->C_DigestUpdate(0UL, NULL, 0UL); tfn->C_DigestKey(0UL, 0UL); tfn->C_DigestFinal(0UL, NULL, NULL); tfn->C_SignInit(0UL, NULL, 0UL); tfn->C_Sign(0UL, NULL, 0UL, NULL, NULL); tfn->C_SignUpdate(0UL, NULL, 0UL); tfn->C_SignFinal(0UL, NULL, NULL); tfn->C_SignRecoverInit(0UL, NULL, 0UL); tfn->C_SignRecover(0UL, NULL, 0UL, NULL, NULL); tfn->C_VerifyInit(0UL, NULL, 0UL); tfn->C_Verify(0UL, NULL, 0UL, NULL, 0UL); tfn->C_VerifyUpdate(0UL, NULL, 0UL); tfn->C_VerifyFinal(0UL, NULL, 0UL); tfn->C_VerifyRecoverInit(0UL, NULL, 0UL); tfn->C_VerifyRecover(0UL, NULL, 0UL, NULL, NULL); tfn->C_DigestEncryptUpdate(0UL, NULL, 0UL, NULL, NULL); tfn->C_DecryptDigestUpdate(0UL, NULL, 0UL, NULL, NULL); tfn->C_SignEncryptUpdate(0UL, NULL, 0UL, NULL, NULL); tfn->C_DecryptVerifyUpdate(0UL, NULL, 0UL, NULL, NULL); tfn->C_GenerateKey(0UL, NULL, NULL, 0UL, NULL); tfn->C_GenerateKeyPair(0UL, NULL, NULL, 0UL, NULL, 0UL, NULL, NULL); tfn->C_WrapKey(0UL, NULL, 0UL, 0UL, NULL, NULL); tfn->C_UnwrapKey(0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL, NULL); tfn->C_DeriveKey(0UL, NULL, 0UL, NULL, 0UL, NULL); tfn->C_SeedRandom(0UL, NULL, 0UL); tfn->C_GenerateRandom(0UL, NULL, 0UL); tfn->C_GetFunctionStatus(0UL); tfn->C_CancelFunction(0UL); tfn->C_WaitForSlotEvent(0UL, &slot, NULL); /* Additional PKCS #11 3.0 functions */ tfn->C_GetInterfaceList(NULL, NULL); tfn->C_GetInterface(NULL, NULL, NULL, 0UL); tfn->C_LoginUser(0UL, 0UL, NULL, 0UL, NULL, 0UL); tfn->C_SessionCancel(0UL, 0UL); tfn->C_MessageEncryptInit(0UL, NULL, 0UL); tfn->C_EncryptMessage(0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL); tfn->C_EncryptMessageBegin(0UL, NULL, 0UL, NULL, 0UL); tfn->C_EncryptMessageNext(0UL, NULL, 0UL, NULL, 0UL, NULL, NULL, 0UL); tfn->C_MessageEncryptFinal(0UL); tfn->C_MessageDecryptInit(0UL, NULL, 0UL); tfn->C_DecryptMessage(0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL); tfn->C_DecryptMessageBegin(0UL, NULL, 0UL, NULL, 0UL); tfn->C_DecryptMessageNext(0UL, NULL, 0UL, NULL, 0UL, NULL, NULL, 0UL); tfn->C_MessageDecryptFinal(0UL); tfn->C_MessageSignInit(0UL, NULL, 0UL); tfn->C_SignMessage(0UL, NULL, 0UL, NULL, 0UL, NULL, NULL); tfn->C_SignMessageBegin(0UL, NULL, 0UL); tfn->C_SignMessageNext(0UL, NULL, 0UL, NULL, 0UL, NULL, NULL); tfn->C_MessageSignFinal(0UL); tfn->C_MessageVerifyInit(0UL, NULL, 0UL); tfn->C_VerifyMessage(0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL); tfn->C_VerifyMessageBegin(0UL, NULL, 0UL); tfn->C_VerifyMessageNext(0UL, NULL, 0UL, NULL, 0UL, NULL, 0UL); tfn->C_MessageVerifyFinal(0UL); testcase_pass("C_GetInterface works.\n"); rc = 0; ret: return rc; } static int get_interface_list_test(void) { CK_INTERFACE *il = NULL; CK_ULONG nmemb = 0UL, i; CK_VERSION *version; CK_RV rv; int rc = -1; testcase_new_assertion(); rv = funcs3->C_GetInterfaceList(NULL, NULL); if (rv != CKR_ARGUMENTS_BAD) { testcase_fail("C_GetInterfaceList returned %s.\n", p11_get_ckr(rv)); goto ret; } rv = funcs3->C_GetInterfaceList(NULL, &nmemb); if (rv != CKR_OK) { testcase_fail("C_GetInterfaceList returned %s.\n", p11_get_ckr(rv)); goto ret; } if (nmemb == 0) { testcase_fail("C_GetInterfaceList interface list has" " %lu elements.\n", nmemb); goto ret; } il = calloc(nmemb, sizeof(*il)); if (il == NULL) { testcase_error("calloc failed.\n"); goto ret; } nmemb--; rv = funcs3->C_GetInterfaceList(il, &nmemb); if (rv != CKR_BUFFER_TOO_SMALL) { testcase_fail("C_GetInterfaceList returned %s.\n", p11_get_ckr(rv)); goto ret; } rv = funcs3->C_GetInterfaceList(il, &nmemb); if (rv != CKR_OK) { testcase_fail("C_GetInterfaceList returned %s.\n", p11_get_ckr(rv)); goto ret; } for (i = 0UL; i < nmemb; i++) { if (strncmp((char *)il[i].pInterfaceName, "PKCS 11", strlen("PKCS 11")) != 0 && strncmp((char *)il[i].pInterfaceName, "Vendor ", strlen("Vendor ")) != 0) { testcase_fail("Invalid interface name.\n"); goto ret; } if (il[i].pFunctionList == NULL) { testcase_fail("%s", "Interface with NULL function list.\n"); goto ret; } if ((il[i].flags & ~CKF_INTERFACE_FORK_SAFE) != 0) { testcase_fail("Interface with unknown flags: 0x%016lx.\n", il[i].flags); goto ret; } version = (CK_VERSION *)il[i].pFunctionList; printf("Interface %lu:\n", i); printf("pInterfaceName %s\n", il[i].pInterfaceName); printf("pFunctionList version %u.%u\n", version->major, version->minor); printf("flags 0x%016lx\n", il[i].flags); } testcase_pass("C_GetInterfaceList works.\n"); rc = 0; ret: free(il); return rc; } int main(void) { int rc = -1; testcase_setup(0); if (do_GetFunctionList() != TRUE) { testcase_error("%s", "do_GetFunctionList() failed.\n"); goto ret; } rc = get_interface_list_test(); if (rc) goto ret; rc = get_interface_test(); ret: testcase_print_result(); /* make sure we return non-zero if rc is non-zero */ return ((rc == 0) || (rc % 256) ? (int)rc : -1); }