diff --git a/lib/tests/test-config.h b/lib/tests/test-config.h new file mode 100644 index 00000000..5e25ade1 --- /dev/null +++ b/lib/tests/test-config.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 Yubico AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_CONFIG_H +#define TEST_CONFIG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * _WIN32 + * + * Pre-processor symbol that describes the Windows system architecture. + */ +/* #undef _WIN32 */ + + /** + * HW_TESTS + * + * Pre-processor symbol indicating whether tests that require a YubiKEY are + * enabled or disabled. + * Default value is disabled + */ +#define HW_TESTS 1 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 1252a2ed..09490122 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -61,6 +61,7 @@ static uint64_t pid; int verbose; static CK_FUNCTION_LIST function_list; +static CK_FUNCTION_LIST_3_0 function_list_3; static CK_SESSION_HANDLE get_session_handle(ykcs11_session_t *session) { return (CK_SESSION_HANDLE)(session - sessions + 1); @@ -3788,8 +3789,425 @@ CK_DEFINE_FUNCTION(CK_RV, C_CancelFunction)( return CKR_FUNCTION_NOT_PARALLEL; } +static const CK_INTERFACE interfaces_list[] = {{(CK_CHAR_PTR) "PKCS 11", + &function_list_3, 0}, + {(CK_CHAR_PTR) "PKCS 11", + &function_list, 0}}; + +/* C_GetInterfaceList returns all the interfaces supported by the module*/ +CK_DEFINE_FUNCTION(CK_RV, C_GetInterfaceList) +(CK_INTERFACE_PTR pInterfacesList, /* returned interfaces */ + CK_ULONG_PTR pulCount /* number of interfaces returned */ +) { + DIN; + CK_RV rv = CKR_OK; + if (!pulCount) { + DBG("C_GetInterfaceList called with pulCount = NULL"); + rv = CKR_ARGUMENTS_BAD; + goto out; + } + if (pInterfacesList) { + if (*pulCount < sizeof(interfaces_list) / sizeof(interfaces_list[0])) { + DBG("C_GetInterfaceList called with *pulCount = %lu", *pulCount); + *pulCount = sizeof(interfaces_list) / sizeof(interfaces_list[0]); + rv = CKR_BUFFER_TOO_SMALL; + goto out; + } + memcpy(pInterfacesList, interfaces_list, sizeof(interfaces_list)); + } + *pulCount = sizeof(interfaces_list) / sizeof(interfaces_list[0]); +out: + DOUT; + return rv; +} + +/* C_GetInterface returns a specific interface from the module. */ +CK_DEFINE_FUNCTION(CK_RV, C_GetInterface) +(CK_UTF8CHAR_PTR pInterfaceName, /* name of the interface */ + CK_VERSION_PTR pVersion, /* version of the interface */ + CK_INTERFACE_PTR_PTR ppInterface, /* returned interface */ + CK_FLAGS flags /* flags controlling the semantics + * of the interface */ +) { + DIN; + CK_RV rv = CKR_FUNCTION_FAILED; + if (!ppInterface) { + DBG("C_GetInterface called with ppInterface = NULL"); + rv = CKR_ARGUMENTS_BAD; + goto out; + } + size_t i; + for (i = 0; i < sizeof(interfaces_list) / sizeof(interfaces_list[0]); i++) { + CK_FUNCTION_LIST_PTR function_list = + (CK_FUNCTION_LIST_PTR) interfaces_list[i].pFunctionList; + if ((flags & interfaces_list[i].flags) != flags) { + DBG("C_GetInterface skipped interface %zu (%s %u.%u) because flags " + "was %lu", + i, interfaces_list[i].pInterfaceName, + function_list->version.major, function_list->version.minor, + flags); + continue; + } + if (pVersion && (pVersion->major != function_list->version.major || + pVersion->minor != function_list->version.minor)) { + DBG("C_GetInterface skipped interface %zu (%s %u.%u) because " + "pVersion was %u.%u", + i, interfaces_list[i].pInterfaceName, + function_list->version.major, function_list->version.minor, + pVersion->major, pVersion->minor); + continue; + } + if (pInterfaceName && strcmp((char *) pInterfaceName, + (char *) interfaces_list[i].pInterfaceName)) { + DBG("C_GetInterface skipped interface %zu (%s %u.%u) because " + "pInterfacename was %s", + i, interfaces_list[i].pInterfaceName, + function_list->version.major, function_list->version.minor, + pInterfaceName); + continue; + } + DBG("C_GetInterface selected interface %zu (%s %u.%u)", i, + interfaces_list[i].pInterfaceName, function_list->version.major, + function_list->version.minor); + *ppInterface = (CK_INTERFACE_PTR) &interfaces_list[i]; + rv = CKR_OK; + break; + } +out: + DOUT; + return rv; +} + +CK_DEFINE_FUNCTION(CK_RV, C_LoginUser) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_USER_TYPE userType, /* the user type */ + CK_UTF8CHAR_PTR pPin, /* the user's PIN */ + CK_ULONG ulPinLen, /* the length of the PIN */ + CK_UTF8CHAR_PTR pUsername, /* the user's name */ + CK_ULONG ulUsernameLen /*the length of the user's name */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_SessionCancel) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_FLAGS flags /* flags control which sessions are cancelled */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageEncryptInit) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of encryption key */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_EncryptMessage) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ + CK_ULONG ulAssociatedDataLen, /* AEAD Associated data length */ + CK_BYTE_PTR pPlaintext, /* plain text */ + CK_ULONG ulPlaintextLen, /* plain text length */ + CK_BYTE_PTR pCiphertext, /* gets cipher text */ + CK_ULONG_PTR pulCiphertextLen /* gets cipher text length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_EncryptMessageBegin) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ + CK_ULONG ulAssociatedDataLen /* AEAD Associated data length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_EncryptMessageNext) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pPlaintextPart, /* plain text */ + CK_ULONG ulPlaintextPartLen, /* plain text length */ + CK_BYTE_PTR pCiphertextPart, /* gets cipher text */ + CK_ULONG_PTR pulCiphertextPartLen, /* gets cipher text length */ + CK_FLAGS flags /* multi mode flag */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageEncryptFinal) +(CK_SESSION_HANDLE hSession /* the session's handle */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageDecryptInit) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of decryption key */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_DecryptMessage) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ + CK_ULONG ulAssociatedDataLen, /* AEAD Associated data length */ + CK_BYTE_PTR pCiphertext, /* cipher text */ + CK_ULONG ulCiphertextLen, /* cipher text length */ + CK_BYTE_PTR pPlaintext, /* gets plain text */ + CK_ULONG_PTR pulPlaintextLen /* gets plain text length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_DecryptMessageBegin) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ + CK_ULONG ulAssociatedDataLen /* AEAD Associated data length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_DecryptMessageNext) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pCiphertext, /* cipher text */ + CK_ULONG ulCiphertextLen, /* cipher text length */ + CK_BYTE_PTR pPlaintext, /* gets plain text */ + CK_ULONG_PTR pulPlaintextLen, /* gets plain text length */ + CK_FLAGS flags /* multi mode flag */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageDecryptFinal) +(CK_SESSION_HANDLE hSession /* the session's handle */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageSignInit) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signing mechanism */ + CK_OBJECT_HANDLE hKey /* handle of signing key */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_SignMessage) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pData, /* data to sign */ + CK_ULONG ulDataLen, /* data to sign length */ + CK_BYTE_PTR pSignature, /* gets signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_SignMessageBegin) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen /* length of message specific parameter */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_SignMessageNext) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pData, /* data to sign */ + CK_ULONG ulDataLen, /* data to sign length */ + CK_BYTE_PTR pSignature, /* gets signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageSignFinal) +(CK_SESSION_HANDLE hSession /* the session's handle */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageVerifyInit) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signing mechanism */ + CK_OBJECT_HANDLE hKey /* handle of signing key */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_VerifyMessage) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pData, /* data to sign */ + CK_ULONG ulDataLen, /* data to sign length */ + CK_BYTE_PTR pSignature, /* signature */ + CK_ULONG ulSignatureLen /* signature length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_VerifyMessageBegin) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen /* length of message specific parameter */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_VerifyMessageNext) +(CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_VOID_PTR pParameter, /* message specific parameter */ + CK_ULONG ulParameterLen, /* length of message specific parameter */ + CK_BYTE_PTR pData, /* data to sign */ + CK_ULONG ulDataLen, /* data to sign length */ + CK_BYTE_PTR pSignature, /* signature */ + CK_ULONG ulSignatureLen /* signature length */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_DEFINE_FUNCTION(CK_RV, C_MessageVerifyFinal) +(CK_SESSION_HANDLE hSession /* the session's handle */ +) { + DIN; + DOUT; + return CKR_FUNCTION_NOT_SUPPORTED; +} + static CK_FUNCTION_LIST function_list = { - { 2, 40 }, + {CRYPTOKI_LEGACY_VERSION_MAJOR, CRYPTOKI_LEGACY_VERSION_MINOR}, + 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, +}; + +static CK_FUNCTION_LIST_3_0 function_list_3 = { + {CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR}, C_Initialize, C_Finalize, C_GetInfo, @@ -3858,4 +4276,28 @@ static CK_FUNCTION_LIST function_list = { C_GetFunctionStatus, C_CancelFunction, C_WaitForSlotEvent, + C_GetInterfaceList, + C_GetInterface, + C_LoginUser, + C_SessionCancel, + C_MessageEncryptInit, + C_EncryptMessage, + C_EncryptMessageBegin, + C_EncryptMessageNext, + C_MessageEncryptFinal, + C_MessageDecryptInit, + C_DecryptMessage, + C_DecryptMessageBegin, + C_DecryptMessageNext, + C_MessageDecryptFinal, + C_MessageSignInit, + C_SignMessage, + C_SignMessageBegin, + C_SignMessageNext, + C_MessageSignFinal, + C_MessageVerifyInit, + C_VerifyMessage, + C_VerifyMessageBegin, + C_VerifyMessageNext, + C_MessageVerifyFinal, };