From a541948067071b057648bc601df6ec09a7f99601 Mon Sep 17 00:00:00 2001 From: Colton Willey Date: Wed, 6 Nov 2024 11:07:34 -0800 Subject: [PATCH] Initial implementation of simple certificate storage for wolfPKCS11 --- .gitignore | 1 + examples/add_cert.c | 427 +++++++++++++++++++++++++++++++++++ examples/examples.test | 10 + examples/include.am | 5 + src/crypto.c | 214 +++++++++++------- src/internal.c | 494 ++++++++++++++++++++++++++++------------- tests/pkcs11test.c | 193 +++++++++++++++- wolfpkcs11/internal.h | 4 +- wolfpkcs11/pkcs11.h | 20 +- wolfpkcs11/store.h | 1 + 10 files changed, 1124 insertions(+), 245 deletions(-) create mode 100644 examples/add_cert.c diff --git a/.gitignore b/.gitignore index f75e79e..6b2b64e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ examples/add_aes_key examples/add_hmac_key examples/add_rsa_key examples/add_rsa_key_file +examples/add_cert examples/init_token examples/mech_info examples/obj_list diff --git a/examples/add_cert.c b/examples/add_cert.c new file mode 100644 index 0000000..1ddaaba --- /dev/null +++ b/examples/add_cert.c @@ -0,0 +1,427 @@ +/* add_cert.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfPKCS11. + * + * wolfPKCS11 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfPKCS11 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include + +#ifndef WOLFPKCS11_USER_SETTINGS + #include +#endif +#include + +#ifndef HAVE_PKCS11_STATIC +#include +#endif + +#ifndef WOLFPKCS11_NO_STORE + +#ifdef DEBUG_WOLFPKCS11 + #define CHECK_CKR(rv, op) \ + fprintf(stderr, "%s: %ld\n", op, rv) +#else + #define CHECK_CKR(rv, op) \ + if (ret != CKR_OK) \ + fprintf(stderr, "%s: %ld\n", op, rv) +#endif + + +/* DLL Location and slot */ +#ifndef WOLFPKCS11_DLL_FILENAME + #ifdef __MACH__ + #define WOLFPKCS11_DLL_FILENAME "./src/.libs/libwolfpkcs11.dylib" + #else + #define WOLFPKCS11_DLL_FILENAME "./src/.libs/libwolfpkcs11.so" + #endif +#endif +#ifndef WOLFPKCS11_DLL_SLOT + #define WOLFPKCS11_DLL_SLOT 1 +#endif + + +#ifndef HAVE_PKCS11_STATIC +static void* dlib; +#endif +static CK_FUNCTION_LIST* funcList; +static CK_SLOT_ID slot = WOLFPKCS11_DLL_SLOT; + +static byte* userPin = (byte*)"wolfpkcs11-test"; +static CK_ULONG userPinLen; + + +static CK_RV pkcs11_init(const char* library, CK_SESSION_HANDLE* session) +{ + CK_RV ret = CKR_OK; +#ifndef HAVE_PKCS11_STATIC + void* func; + + dlib = dlopen(library, RTLD_NOW | RTLD_LOCAL); + if (dlib == NULL) { + fprintf(stderr, "dlopen error: %s\n", dlerror()); + ret = -1; + } + + if (ret == CKR_OK) { + func = (void*)(CK_C_GetFunctionList)dlsym(dlib, "C_GetFunctionList"); + if (func == NULL) { + fprintf(stderr, "Failed to get function list function\n"); + ret = -1; + } + } + + if (ret == CKR_OK) { + ret = ((CK_C_GetFunctionList)func)(&funcList); + CHECK_CKR(ret, "Get Function List call"); + } + + if (ret != CKR_OK && dlib != NULL) + dlclose(dlib); + +#else + ret = C_GetFunctionList(&funcList); + (void)library; +#endif + + if (ret == CKR_OK) { + ret = funcList->C_Initialize(NULL); + CHECK_CKR(ret, "Initialize"); + } + + if (ret == CKR_OK) { + CK_FLAGS sessFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION; + + ret = funcList->C_OpenSession(slot, sessFlags, NULL, NULL, session); + CHECK_CKR(ret, "Open Session"); + if (ret == CKR_OK && userPinLen != 0) { + ret = funcList->C_Login(*session, CKU_USER, userPin, userPinLen); + CHECK_CKR(ret, "Login"); + } + } + + return ret; +} + + +static void pkcs11_final(CK_SESSION_HANDLE session) +{ + if (userPinLen != 0) + funcList->C_Logout(session); + funcList->C_CloseSession(session); + + funcList->C_Finalize(NULL); +#ifndef HAVE_PKCS11_STATIC + dlclose(dlib); +#endif +} + + +static CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; +static CK_BBOOL ckTrue = CK_TRUE; +CK_CERTIFICATE_TYPE certType = CKC_X_509; +static CK_BYTE certificate[] = { /* ./certs/server-cert.der, 2048-bit */ + 0x30, 0x82, 0x04, 0xE8, 0x30, 0x82, 0x03, 0xD0, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, + 0x00, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, + 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, + 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, + 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, + 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, + 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x33, 0x31, 0x32, + 0x31, 0x33, 0x32, 0x32, 0x31, 0x39, 0x32, 0x38, 0x5A, 0x17, + 0x0D, 0x32, 0x36, 0x30, 0x39, 0x30, 0x38, 0x32, 0x32, 0x31, + 0x39, 0x32, 0x38, 0x5A, 0x30, 0x81, 0x90, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, + 0x66, 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x53, 0x75, 0x70, 0x70, 0x6F, + 0x72, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xC0, 0x95, 0x08, 0xE1, 0x57, 0x41, + 0xF2, 0x71, 0x6D, 0xB7, 0xD2, 0x45, 0x41, 0x27, 0x01, 0x65, + 0xC6, 0x45, 0xAE, 0xF2, 0xBC, 0x24, 0x30, 0xB8, 0x95, 0xCE, + 0x2F, 0x4E, 0xD6, 0xF6, 0x1C, 0x88, 0xBC, 0x7C, 0x9F, 0xFB, + 0xA8, 0x67, 0x7F, 0xFE, 0x5C, 0x9C, 0x51, 0x75, 0xF7, 0x8A, + 0xCA, 0x07, 0xE7, 0x35, 0x2F, 0x8F, 0xE1, 0xBD, 0x7B, 0xC0, + 0x2F, 0x7C, 0xAB, 0x64, 0xA8, 0x17, 0xFC, 0xCA, 0x5D, 0x7B, + 0xBA, 0xE0, 0x21, 0xE5, 0x72, 0x2E, 0x6F, 0x2E, 0x86, 0xD8, + 0x95, 0x73, 0xDA, 0xAC, 0x1B, 0x53, 0xB9, 0x5F, 0x3F, 0xD7, + 0x19, 0x0D, 0x25, 0x4F, 0xE1, 0x63, 0x63, 0x51, 0x8B, 0x0B, + 0x64, 0x3F, 0xAD, 0x43, 0xB8, 0xA5, 0x1C, 0x5C, 0x34, 0xB3, + 0xAE, 0x00, 0xA0, 0x63, 0xC5, 0xF6, 0x7F, 0x0B, 0x59, 0x68, + 0x78, 0x73, 0xA6, 0x8C, 0x18, 0xA9, 0x02, 0x6D, 0xAF, 0xC3, + 0x19, 0x01, 0x2E, 0xB8, 0x10, 0xE3, 0xC6, 0xCC, 0x40, 0xB4, + 0x69, 0xA3, 0x46, 0x33, 0x69, 0x87, 0x6E, 0xC4, 0xBB, 0x17, + 0xA6, 0xF3, 0xE8, 0xDD, 0xAD, 0x73, 0xBC, 0x7B, 0x2F, 0x21, + 0xB5, 0xFD, 0x66, 0x51, 0x0C, 0xBD, 0x54, 0xB3, 0xE1, 0x6D, + 0x5F, 0x1C, 0xBC, 0x23, 0x73, 0xD1, 0x09, 0x03, 0x89, 0x14, + 0xD2, 0x10, 0xB9, 0x64, 0xC3, 0x2A, 0xD0, 0xA1, 0x96, 0x4A, + 0xBC, 0xE1, 0xD4, 0x1A, 0x5B, 0xC7, 0xA0, 0xC0, 0xC1, 0x63, + 0x78, 0x0F, 0x44, 0x37, 0x30, 0x32, 0x96, 0x80, 0x32, 0x23, + 0x95, 0xA1, 0x77, 0xBA, 0x13, 0xD2, 0x97, 0x73, 0xE2, 0x5D, + 0x25, 0xC9, 0x6A, 0x0D, 0xC3, 0x39, 0x60, 0xA4, 0xB4, 0xB0, + 0x69, 0x42, 0x42, 0x09, 0xE9, 0xD8, 0x08, 0xBC, 0x33, 0x20, + 0xB3, 0x58, 0x22, 0xA7, 0xAA, 0xEB, 0xC4, 0xE1, 0xE6, 0x61, + 0x83, 0xC5, 0xD2, 0x96, 0xDF, 0xD9, 0xD0, 0x4F, 0xAD, 0xD7, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x45, 0x30, + 0x82, 0x01, 0x41, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, + 0x04, 0x16, 0x04, 0x14, 0xB3, 0x11, 0x32, 0xC9, 0x92, 0x98, + 0x84, 0xE2, 0xC9, 0xF8, 0xD0, 0x3B, 0x6E, 0x03, 0x42, 0xCA, + 0x1F, 0x0E, 0x8E, 0x3C, 0x30, 0x81, 0xD4, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x81, 0xCC, 0x30, 0x81, 0xC9, 0x80, 0x14, + 0x27, 0x8E, 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, + 0x33, 0x63, 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5, + 0xA1, 0x81, 0x9A, 0xA4, 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, + 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, + 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, + 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x14, 0x33, + 0x44, 0x1A, 0xA8, 0x6C, 0x01, 0xEC, 0xF6, 0x60, 0xF2, 0x70, + 0x51, 0x0A, 0x4C, 0xD1, 0x14, 0xFA, 0xBC, 0xE9, 0x44, 0x30, + 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xFF, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x1D, 0x11, + 0x04, 0x15, 0x30, 0x13, 0x82, 0x0B, 0x65, 0x78, 0x61, 0x6D, + 0x70, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x87, 0x04, 0x7F, + 0x00, 0x00, 0x01, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x25, + 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x02, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x4A, 0xFF, 0xB9, 0xE5, 0x85, 0x9B, + 0xDA, 0x53, 0x66, 0x7F, 0x07, 0x22, 0xBF, 0xB6, 0x19, 0xEA, + 0x42, 0xEB, 0xA4, 0x11, 0x07, 0x62, 0xFF, 0x39, 0x5F, 0x33, + 0x37, 0x3A, 0x87, 0x26, 0x71, 0x3D, 0x13, 0xB2, 0xCA, 0xB8, + 0x64, 0x38, 0x7B, 0x8A, 0x99, 0x48, 0x0E, 0xA5, 0xA4, 0x6B, + 0xB1, 0x99, 0x6E, 0xE0, 0x46, 0x51, 0xBD, 0x19, 0x52, 0xAD, + 0xBC, 0xA6, 0x7E, 0x2A, 0x7A, 0x7C, 0x23, 0xA7, 0xCC, 0xDB, + 0x5E, 0x43, 0x7D, 0x6B, 0x04, 0xC8, 0xB7, 0xDD, 0x95, 0xAD, + 0xF0, 0x91, 0x80, 0x59, 0xC5, 0x19, 0x91, 0x26, 0x27, 0x91, + 0xB8, 0x48, 0x1C, 0xEB, 0x55, 0xB6, 0xAA, 0x7D, 0xA4, 0x38, + 0xF1, 0x03, 0xBC, 0x6C, 0x8B, 0xAA, 0x94, 0xD6, 0x3C, 0x05, + 0x7A, 0x96, 0xC5, 0x06, 0xF1, 0x26, 0x14, 0x2E, 0x75, 0xFB, + 0xDD, 0xE5, 0x35, 0xB3, 0x01, 0x2C, 0xB3, 0xAD, 0x62, 0x5A, + 0x21, 0x9A, 0x08, 0xBE, 0x56, 0xFC, 0xF9, 0xA2, 0x42, 0x87, + 0x86, 0xE5, 0xA9, 0xC5, 0x99, 0xCF, 0xAE, 0x14, 0xBE, 0xE0, + 0xB9, 0x08, 0x24, 0x0D, 0x1D, 0x5C, 0xD6, 0x14, 0xE1, 0x4C, + 0x9F, 0x40, 0xB3, 0xA9, 0xE9, 0x2D, 0x52, 0x8B, 0x4C, 0xBF, + 0xAC, 0x44, 0x31, 0x67, 0xC1, 0x8D, 0x06, 0x85, 0xEC, 0x0F, + 0xE4, 0x99, 0xD7, 0x4B, 0x7B, 0x21, 0x06, 0x66, 0xD4, 0xE4, + 0xF5, 0x9D, 0xFF, 0x8E, 0xF0, 0x86, 0x39, 0x58, 0x1D, 0xA4, + 0x5B, 0xE2, 0x63, 0xEF, 0x7C, 0xC9, 0x18, 0x87, 0xA8, 0x02, + 0x25, 0x10, 0x3E, 0x87, 0x28, 0xF9, 0xF5, 0xEF, 0x47, 0x9E, + 0xA5, 0x80, 0x08, 0x11, 0x90, 0x68, 0xFE, 0xD1, 0xA3, 0xA8, + 0x51, 0xB9, 0x37, 0xFF, 0xD5, 0xCA, 0x7C, 0x87, 0x7F, 0x6B, + 0xBC, 0x2C, 0x12, 0xC8, 0xC5, 0x85, 0x8B, 0xFC, 0x0C, 0xC6, + 0xB9, 0x86, 0xB8, 0xC9, 0x04, 0xC3, 0x51, 0x37, 0xD2, 0x4F +}; + +static CK_RV pkcs11_add_cert(CK_SESSION_HANDLE session, + unsigned char* privId, CK_ULONG privIdLen) +{ + CK_RV ret; + CK_ATTRIBUTE certTmpl[] = { + { CKA_CLASS, &certClass, sizeof(certClass) }, + { CKA_CERTIFICATE_TYPE, &certType, sizeof(certType) }, + { CKA_VALUE, certificate, sizeof(certificate) }, + { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, + { CKA_ID, privId, privIdLen }, + }; + CK_ULONG cnt = sizeof(certTmpl)/sizeof(*certTmpl); + CK_OBJECT_HANDLE obj; + + if (privId == NULL) + cnt -= 2; + + ret = funcList->C_CreateObject(session, certTmpl, cnt, &obj); + CHECK_CKR(ret, "CreateObject Certificate"); + + return ret; +} + + +/* Match the command line argument with the string. + * + * arg Command line argument. + * str String to check for. + * return 1 if the command line argument matches the string, 0 otherwise. + */ +static int string_matches(const char* arg, const char* str) +{ + int len = (int)XSTRLEN(str) + 1; + return XSTRNCMP(arg, str, len) == 0; +} + + +/* Display the usage options of the benchmark program. */ +static void Usage(void) +{ + printf("add_cert\n"); + printf("-? Help, print this usage\n"); + printf("-lib PKCS#11 library to test\n"); + printf("-slot Slot number to use\n"); + printf("-userPin User PIN\n"); + printf("-privId Private key identifier\n"); +} + + +#ifndef NO_MAIN_DRIVER +int main(int argc, char* argv[]) +#else +int add_cert(int argc, char* argv[]) +#endif +{ + int ret; + CK_RV rv; + const char* libName = WOLFPKCS11_DLL_FILENAME; + CK_SESSION_HANDLE session = CK_INVALID_HANDLE; + unsigned char* privId = NULL; + CK_ULONG privIdLen = 0; + +#ifndef WOLFPKCS11_NO_ENV + if (!XGETENV("WOLFPKCS11_TOKEN_PATH")) { + XSETENV("WOLFPKCS11_TOKEN_PATH", "./store", 1); + } +#endif + + argc--; + argv++; + while (argc > 0) { + if (string_matches(*argv, "-?")) { + Usage(); + return 0; + } + else if (string_matches(*argv, "-lib")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "Library name not supplied\n"); + return 1; + } + libName = *argv; + } + else if (string_matches(*argv, "-slot")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "Slot number not supplied\n"); + return 1; + } + slot = atoi(*argv); + } + else if (string_matches(*argv, "-userPin")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "User PIN not supplied\n"); + return 1; + } + userPin = (byte*)*argv; + } + else if (string_matches(*argv, "-privId")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "Private key identifier not supplied\n"); + return 1; + } + privId = (unsigned char*)*argv; + privIdLen = (int)strlen(*argv); + } + else { + fprintf(stderr, "Unrecognized command line argument\n %s\n", + argv[0]); + return 1; + } + + argc--; + argv++; + } + + userPinLen = (int)XSTRLEN((const char*)userPin); + + rv = pkcs11_init(libName, &session); + if (rv == CKR_OK) { + rv = pkcs11_add_cert(session, privId, privIdLen); + } + pkcs11_final(session); + + if (rv == CKR_OK) + ret = 0; + else + ret = 1; + return ret; +} + +#else + +#ifndef NO_MAIN_DRIVER +int main(int argc, char* argv[]) +#else +int add_cert(int argc, char* argv[]) +#endif +{ + (void)argc; + (void)argv; + fprintf(stderr, "Store disabled\n"); + return 0; +} + +#endif + diff --git a/examples/examples.test b/examples/examples.test index 14e2c7f..da05b0e 100755 --- a/examples/examples.test +++ b/examples/examples.test @@ -63,6 +63,16 @@ RESULT=$? RESULT=$? [ $RESULT -ne 0 ] && echo "\n\nAdding an RSA key from file to the token failed" && exit 1 +# Add a cert to the session +./examples/add_cert +RESULT=$? +[ $RESULT -ne 0 ] && echo "\n\nAdding a certificate failed" && exit 1 + +# Add a cert to the token +./examples/add_cert -privId "cert-2048" +RESULT=$? +[ $RESULT -ne 0 ] && echo "\n\nAdding a certificate to the token failed" && exit 1 + # Show all objects on token ./examples/obj_list RESULT=$? diff --git a/examples/include.am b/examples/include.am index cf11c95..362580a 100644 --- a/examples/include.am +++ b/examples/include.am @@ -17,6 +17,10 @@ noinst_PROGRAMS += examples/add_rsa_key_file examples_add_rsa_key_file_SOURCES = examples/add_rsa_key_file.c examples_add_rsa_key_file_LDADD = +noinst_PROGRAMS += examples/add_cert +examples_add_cert_SOURCES = examples/add_cert.c +examples_add_cert_LDADD = + noinst_PROGRAMS += examples/init_token examples_init_token_SOURCES = examples/init_token.c examples_init_token_LDADD = @@ -45,6 +49,7 @@ examples_add_aes_key_LDADD += src/libwolfpkcs11.la examples_add_hmac_key_LDADD += src/libwolfpkcs11.la examples_add_rsa_key_LDADD += src/libwolfpkcs11.la examples_add_rsa_key_file_LDADD += src/libwolfpkcs11.la +examples_add_cert_LDADD += src/libwolfpkcs11.la examples_init_token_LDADD += src/libwolfpkcs11.la examples_mech_info_LDADD += src/libwolfpkcs11.la examples_obj_list_LDADD += src/libwolfpkcs11.la diff --git a/src/crypto.c b/src/crypto.c index 4a9bf2c..9a239c1 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -97,15 +97,22 @@ static CK_ATTRIBUTE_TYPE secretKeyParams[] = { /* Count of secret key data attributes. */ #define SECRET_KEY_PARAMS_CNT (sizeof(secretKeyParams)/sizeof(*secretKeyParams)) +/* Certificate data attributes */ +static CK_ATTRIBUTE_TYPE certParams[] = { + CKA_CERTIFICATE_TYPE, + CKA_VALUE, +}; +#define CERT_PARAMS_CNT (sizeof(certParams)/sizeof(*certParams)) + /* Identify maximum count for stack array. */ #ifndef NO_RSA -#define KEY_MAX_PARAMS RSA_KEY_PARAMS_CNT +#define OBJ_MAX_PARAMS RSA_KEY_PARAMS_CNT #elif defined(HAVE_ECC) -#define KEY_MAX_PARAMS EC_KEY_PARAMS_CNT +#define OBJ_MAX_PARAMS EC_KEY_PARAMS_CNT #elif !defined(NO_DH) -#define KEY_MAX_PARAMS DH_KEY_PARAMS_CNT +#define OBJ_MAX_PARAMS DH_KEY_PARAMS_CNT #else -#define KEY_MAX_PARAMS SECRET_KEY_PARAMS_CNT +#define OBJ_MAX_PARAMS SECRET_KEY_PARAMS_CNT #endif typedef struct AttributeType { @@ -173,6 +180,16 @@ static AttributeType attrType[] = { { CKA_UNWRAP_TEMPLATE, ATTR_TYPE_DATA }, { CKA_DERIVE_TEMPLATE, ATTR_TYPE_DATA }, { CKA_ALLOWED_MECHANISMS, ATTR_TYPE_DATA }, + { CKA_CERTIFICATE_TYPE, ATTR_TYPE_ULONG }, + { CKA_CERTIFICATE_CATEGORY, ATTR_TYPE_ULONG }, + { CKA_ID, ATTR_TYPE_DATA }, + { CKA_ISSUER, ATTR_TYPE_DATA }, + { CKA_SERIAL_NUMBER, ATTR_TYPE_DATA }, + { CKA_PUBLIC_KEY_INFO, ATTR_TYPE_DATA }, + { CKA_URL, ATTR_TYPE_DATA }, + { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, ATTR_TYPE_DATA }, + { CKA_HASH_OF_ISSUER_PUBLIC_KEY, ATTR_TYPE_DATA }, + { CKA_NAME_HASH_ALGORITHM, ATTR_TYPE_ULONG }, }; /* Count of elements in attribute type list. */ #define ATTR_TYPE_SIZE (sizeof(attrType) / sizeof(*attrType)) @@ -253,7 +270,7 @@ static CK_RV CheckAttributes(CK_ATTRIBUTE* pTemplate, CK_ULONG ulCount, int set) else if (attrType[j].type == ATTR_TYPE_BOOL) { if (attr->pValue == NULL && set) return CKR_ATTRIBUTE_VALUE_INVALID; - if ((attr->pValue != NULL) && + if ((attr->pValue != NULL) && (attr->ulValueLen != sizeof(CK_BBOOL))) return CKR_BUFFER_TOO_SMALL; if (set && *(CK_BBOOL*)attr->pValue != CK_TRUE && @@ -264,7 +281,7 @@ static CK_RV CheckAttributes(CK_ATTRIBUTE* pTemplate, CK_ULONG ulCount, int set) else if (attrType[j].type == ATTR_TYPE_DATE) { if (attr->pValue == NULL && set) return CKR_ATTRIBUTE_VALUE_INVALID; - if ((attr->pValue != NULL) && + if ((attr->pValue != NULL) && (attr->ulValueLen != sizeof(CK_DATE))) return CKR_BUFFER_TOO_SMALL; } @@ -302,11 +319,12 @@ static CK_RV SetAttributeValue(WP11_Session* session, WP11_Object* obj, CK_RV rv; CK_ATTRIBUTE* attr; int i, j; - unsigned char* data[KEY_MAX_PARAMS] = { 0, }; - CK_ULONG len[KEY_MAX_PARAMS] = { 0, }; + unsigned char* data[OBJ_MAX_PARAMS] = { 0, }; + CK_ULONG len[OBJ_MAX_PARAMS] = { 0, }; CK_ATTRIBUTE_TYPE* attrs = NULL; int cnt; CK_KEY_TYPE type; + CK_OBJECT_CLASS objClass; if (pTemplate == NULL) return CKR_ARGUMENTS_BAD; @@ -317,38 +335,45 @@ static CK_RV SetAttributeValue(WP11_Session* session, WP11_Object* obj, if (rv != CKR_OK) return rv; - /* Get the value and length of key specific attribute types. */ type = WP11_Object_GetType(obj); - switch (type) { -#ifndef NO_RSA - case CKK_RSA: - attrs = rsaKeyParams; - cnt = RSA_KEY_PARAMS_CNT; - break; -#endif -#ifdef HAVE_ECC - case CKK_EC: - attrs = ecKeyParams; - cnt = EC_KEY_PARAMS_CNT; - break; -#endif -#ifndef NO_DH - case CKK_DH: - attrs = dhKeyParams; - cnt = DH_KEY_PARAMS_CNT; - break; -#endif -#ifndef NO_AES - case CKK_AES: -#endif - case CKK_GENERIC_SECRET: - attrs = secretKeyParams; - cnt = SECRET_KEY_PARAMS_CNT; - break; - default: - (void)len; - return CKR_OBJECT_HANDLE_INVALID; - } + objClass = WP11_Object_GetClass(obj); + if (objClass == CKO_CERTIFICATE) { + attrs = certParams; + cnt = CERT_PARAMS_CNT; + } + else { + /* Get the value and length of key specific attribute types. */ + switch (type) { + #ifndef NO_RSA + case CKK_RSA: + attrs = rsaKeyParams; + cnt = RSA_KEY_PARAMS_CNT; + break; + #endif + #ifdef HAVE_ECC + case CKK_EC: + attrs = ecKeyParams; + cnt = EC_KEY_PARAMS_CNT; + break; + #endif + #ifndef NO_DH + case CKK_DH: + attrs = dhKeyParams; + cnt = DH_KEY_PARAMS_CNT; + break; + #endif + #ifndef NO_AES + case CKK_AES: + #endif + case CKK_GENERIC_SECRET: + attrs = secretKeyParams; + cnt = SECRET_KEY_PARAMS_CNT; + break; + default: + (void)len; + return CKR_OBJECT_HANDLE_INVALID; + } + } for (i = 0; i < cnt; i++) { for (j = 0; j < (int)ulCount; j++) { @@ -362,33 +387,38 @@ static CK_RV SetAttributeValue(WP11_Session* session, WP11_Object* obj, } } - /* Set the value and length of key specific attributes - * Old key data is cleared. - */ - switch (type) { -#ifndef NO_RSA - case CKK_RSA: - ret = WP11_Object_SetRsaKey(obj, data, len); - break; -#endif -#ifdef HAVE_ECC - case CKK_EC: - ret = WP11_Object_SetEcKey(obj, data, len); - break; -#endif -#ifndef NO_DH - case CKK_DH: - ret = WP11_Object_SetDhKey(obj, data, len); - break; -#endif -#ifndef NO_AES - case CKK_AES: -#endif - case CKK_GENERIC_SECRET: - ret = WP11_Object_SetSecretKey(obj, data, len); - break; - default: - break; + if (objClass == CKO_CERTIFICATE) { + ret = WP11_Object_SetCert(obj, data, len); + } + else { + /* Set the value and length of key specific attributes + * Old key data is cleared. + */ + switch (type) { + #ifndef NO_RSA + case CKK_RSA: + ret = WP11_Object_SetRsaKey(obj, data, len); + break; + #endif + #ifdef HAVE_ECC + case CKK_EC: + ret = WP11_Object_SetEcKey(obj, data, len); + break; + #endif + #ifndef NO_DH + case CKK_DH: + ret = WP11_Object_SetDhKey(obj, data, len); + break; + #endif + #ifndef NO_AES + case CKK_AES: + #endif + case CKK_GENERIC_SECRET: + ret = WP11_Object_SetSecretKey(obj, data, len); + break; + default: + break; + } } if (ret == MEMORY_E) return CKR_DEVICE_MEMORY; @@ -635,34 +665,50 @@ static CK_RV CreateObject(WP11_Session* session, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, WP11_Object** object) { CK_RV rv; - CK_KEY_TYPE keyType = -1; - CK_OBJECT_CLASS keyClass = -1; + CK_ULONG objType = -1; + CK_OBJECT_CLASS objectClass = -1; CK_ATTRIBUTE* attr; - FindAttributeType(pTemplate, ulCount, CKA_KEY_TYPE, &attr); - if (attr == NULL) - return CKR_TEMPLATE_INCOMPLETE; - if (attr->pValue == NULL) - return CKR_ATTRIBUTE_VALUE_INVALID; - if (attr->ulValueLen != sizeof(CK_KEY_TYPE)) - return CKR_ATTRIBUTE_VALUE_INVALID; - keyType = *(CK_KEY_TYPE*)attr->pValue; - - if (keyType != CKK_RSA && keyType != CKK_EC && keyType != CKK_DH && - keyType != CKK_AES && keyType != CKK_GENERIC_SECRET) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - FindAttributeType(pTemplate, ulCount, CKA_CLASS, &attr); if (attr != NULL) { if (attr->pValue == NULL) return CKR_ATTRIBUTE_VALUE_INVALID; if (attr->ulValueLen != sizeof(CK_OBJECT_CLASS)) return CKR_ATTRIBUTE_VALUE_INVALID; - keyClass = *(CK_OBJECT_CLASS*)attr->pValue; + objectClass = *(CK_OBJECT_CLASS*)attr->pValue; + } + + if (objectClass == CKO_CERTIFICATE) { + FindAttributeType(pTemplate, ulCount, CKA_CERTIFICATE_TYPE, &attr); + if (attr == NULL) + return CKR_TEMPLATE_INCOMPLETE; + if (attr->pValue == NULL) + return CKR_ATTRIBUTE_VALUE_INVALID; + if (attr->ulValueLen != sizeof(CK_ULONG)) + return CKR_ATTRIBUTE_VALUE_INVALID; + objType = *(CK_ULONG*)attr->pValue; + if (objType != CKC_X_509 && objType != CKC_X_509_ATTR_CERT && + objType != CKC_WTLS) { + return CKR_ATTRIBUTE_VALUE_INVALID; + } + } + else { + FindAttributeType(pTemplate, ulCount, CKA_KEY_TYPE, &attr); + if (attr == NULL) + return CKR_TEMPLATE_INCOMPLETE; + if (attr->pValue == NULL) + return CKR_ATTRIBUTE_VALUE_INVALID; + if (attr->ulValueLen != sizeof(CK_ULONG)) + return CKR_ATTRIBUTE_VALUE_INVALID; + objType = *(CK_ULONG*)attr->pValue; + + if (objType != CKK_RSA && objType != CKK_EC && objType != CKK_DH && + objType != CKK_AES && objType != CKK_GENERIC_SECRET) { + return CKR_ATTRIBUTE_VALUE_INVALID; + } } - rv = NewObject(session, keyType, keyClass, pTemplate, ulCount, object); + rv = NewObject(session, objType, objectClass, pTemplate, ulCount, object); return rv; } diff --git a/src/internal.c b/src/internal.c index 5c7f3a4..3fb5de4 100644 --- a/src/internal.c +++ b/src/internal.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - #ifdef HAVE_CONFIG_H #include #endif @@ -82,6 +81,10 @@ #define WP11_MAX_SYM_KEY_SZ 64 #endif +#ifndef WP11_MAX_CERT_SZ +#define WP11_MAX_CERT_SZ 4096 +#endif + /* Sizes for storage. */ #define WP11_MAX_IV_SZ 16 #define WP11_MAX_GCM_NONCE_SZ 16 @@ -136,6 +139,13 @@ typedef struct WP11_Data { word32 len; /* Length of key data in bytes */ } WP11_Data; +/* Certificate */ +typedef struct WP11_Cert { + byte data[WP11_MAX_CERT_SZ]; /* Certificate data */ + word32 len; /* Length of certificate data in bytes */ + CK_CERTIFICATE_TYPE type; +} WP11_Cert; + #ifndef NO_DH typedef struct WP11_DhKey { byte key[WP11_MAX_DH_KEY_SZ]; /* Public or private key */ @@ -156,6 +166,7 @@ struct WP11_Object { WP11_DhKey dhKey; /* DH parameters object */ #endif WP11_Data symmKey; /* Symmetric key object */ + WP11_Cert cert; /* Certificate object */ } data; #ifdef WOLFPKCS11_TPM WOLFTPM2_KEYBLOB tpmKey; @@ -815,6 +826,10 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, XSNPRINTF(name, sizeof(name), "%s/wp11_dhkey_pub_%016lx_%016lx", str, id1, id2); break; + case WOLFPKCS11_STORE_CERT: + XSNPRINTF(name, sizeof(name), "%s/wp11_cert_%016lx_%016lx", + str, id1, id2); + break; default: ret = -1; break; @@ -1542,6 +1557,68 @@ static int wp11_DecryptData(byte* out, byte* data, int len, byte* key, return ret; } +/** + * Load a certificate from storage. + * + * @param [in, out] object Certificate object. + * @param [in] tokenId Id of token this cert belongs to. + * @param [in] objId Id of object for token. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return BUFFER_E when loading fails. + * @return NOT_AVAILABLE_E when unable to locate data. + */ +static int wp11_Object_Load_Cert(WP11_Object* object, int tokenId, int objId) +{ + int ret; + void* storage = NULL; + + /* Open access to cert. */ + ret = wp11_storage_open(WOLFPKCS11_STORE_CERT, tokenId, objId, 1, &storage); + if (ret == 0) { + /* Read certificate. */ + ret = wp11_storage_read_alloc_array(storage, &object->keyData, + &object->keyDataLen); + wp11_storage_close(storage); + } + + return ret; +} + +/** + * Store an certificate to storage. + * + * @param [in] object Certificte object. + * @param [in] tokenId Id of token this cert belongs to. + * @param [in] objId Id of object for token. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. + * @return BUFFER_E when storing fails. + * @return NOT_AVAILABLE_E when unable to write data. + */ +static int wp11_Object_Store_Cert(WP11_Object* object, int tokenId, int objId) +{ + int ret; + void* storage = NULL; + + if (object->data.cert.len <= 0) { + ret = BAD_FUNC_ARG; + goto exit; + } + + /* Open access to cert. */ + ret = wp11_storage_open(WOLFPKCS11_STORE_CERT, tokenId, objId, 0, &storage); + if (ret == 0) { + /* Write cert to storage. */ + ret = wp11_storage_write_array(storage, object->data.cert.data, + object->data.cert.len); + wp11_storage_close(storage); + } + +exit: + return ret; +} + #ifndef NO_RSA /** * Decode the RSA key. @@ -2562,31 +2639,36 @@ static int wp11_Object_Load(WP11_Object* object, int tokenId, int objId) wp11_storage_close(storage); } if (ret == 0) { - /* Load separate key data. */ - switch (object->type) { - #ifndef NO_RSA - case CKK_RSA: - ret = wp11_Object_Load_RsaKey(object, tokenId, objId); - break; - #endif - #ifdef HAVE_ECC - case CKK_EC: - ret = wp11_Object_Load_EccKey(object, tokenId, objId); - break; - #endif - #ifndef NO_DH - case CKK_DH: - ret = wp11_Object_Load_DhKey(object, tokenId, objId); - break; - #endif - #ifndef NO_AES - case CKK_AES: - #endif - case CKK_GENERIC_SECRET: - ret = wp11_Object_Load_SymmKey(object, tokenId, objId); - break; - default: - ret = NOT_AVAILABLE_E; + if (object->objClass == CKO_CERTIFICATE) { + ret = wp11_Object_Load_Cert(object, tokenId, objId); + } + else { + /* Load separate key data. */ + switch (object->type) { + #ifndef NO_RSA + case CKK_RSA: + ret = wp11_Object_Load_RsaKey(object, tokenId, objId); + break; + #endif + #ifdef HAVE_ECC + case CKK_EC: + ret = wp11_Object_Load_EccKey(object, tokenId, objId); + break; + #endif + #ifndef NO_DH + case CKK_DH: + ret = wp11_Object_Load_DhKey(object, tokenId, objId); + break; + #endif + #ifndef NO_AES + case CKK_AES: + #endif + case CKK_GENERIC_SECRET: + ret = wp11_Object_Load_SymmKey(object, tokenId, objId); + break; + default: + ret = NOT_AVAILABLE_E; + } } } @@ -2675,77 +2757,88 @@ static int wp11_Object_Store(WP11_Object* object, int tokenId, int objId) sizeof(object->iv)); } if (ret == 0) { - /* Store key data separately. */ + if (object->objClass == CKO_CERTIFICATE) { + ret = wp11_Object_Store_Cert(object, tokenId, objId); + } + else { + /* Store key data separately. */ + switch (object->type) { + #ifndef NO_RSA + case CKK_RSA: + ret = wp11_Object_Store_RsaKey(object, tokenId, objId); + break; + #endif + #ifdef HAVE_ECC + case CKK_EC: + ret = wp11_Object_Store_EccKey(object, tokenId, objId); + break; + #endif + #ifndef NO_DH + case CKK_DH: + ret = wp11_Object_Store_DhKey(object, tokenId, objId); + break; + #endif + #ifndef NO_AES + case CKK_AES: + #endif + case CKK_GENERIC_SECRET: + ret = wp11_Object_Store_SymmKey(object, tokenId, objId); + break; + default: + ret = NOT_AVAILABLE_E; + } + } + } + + return ret; +} + +/** + * Decode the key object. Private keys require decryption. + * + * When decryption authentication fails then the wrong user is trying to access + * the private key. + * + * @param [in, out] object Key object. + * @return 0 on success. + * @return -ve on failure. + */ +static int wp11_Object_Decode(WP11_Object* object) +{ + int ret; + + if (object->objClass == CKO_CERTIFICATE) { + object->encoded = 0; + ret = 0; + } + else { switch (object->type) { #ifndef NO_RSA case CKK_RSA: - ret = wp11_Object_Store_RsaKey(object, tokenId, objId); + ret = wp11_Object_Decode_RsaKey(object); break; #endif #ifdef HAVE_ECC case CKK_EC: - ret = wp11_Object_Store_EccKey(object, tokenId, objId); + ret = wp11_Object_Decode_EccKey(object); break; #endif #ifndef NO_DH case CKK_DH: - ret = wp11_Object_Store_DhKey(object, tokenId, objId); + ret = wp11_Object_Decode_DhKey(object); break; #endif #ifndef NO_AES case CKK_AES: #endif case CKK_GENERIC_SECRET: - ret = wp11_Object_Store_SymmKey(object, tokenId, objId); + ret = wp11_Object_Decode_SymmKey(object); break; default: ret = NOT_AVAILABLE_E; } } - return ret; -} - -/** - * Decode the key object. Private keys require decryption. - * - * When decryption authentication fails then the wrong user is trying to access - * the private key. - * - * @param [in, out] object Key object. - * @return 0 on success. - * @return -ve on failure. - */ -static int wp11_Object_Decode(WP11_Object* object) -{ - int ret; - - switch (object->type) { - #ifndef NO_RSA - case CKK_RSA: - ret = wp11_Object_Decode_RsaKey(object); - break; - #endif - #ifdef HAVE_ECC - case CKK_EC: - ret = wp11_Object_Decode_EccKey(object); - break; - #endif - #ifndef NO_DH - case CKK_DH: - ret = wp11_Object_Decode_DhKey(object); - break; - #endif - #ifndef NO_AES - case CKK_AES: - #endif - case CKK_GENERIC_SECRET: - ret = wp11_Object_Decode_SymmKey(object); - break; - default: - ret = NOT_AVAILABLE_E; - } - /* Authentication failure means this object isn't for this user. */ if (ret == AES_GCM_AUTH_E) ret = 0; @@ -2765,46 +2858,51 @@ static int wp11_Object_Encode(WP11_Object* object, int protect) { int ret; - switch (object->type) { - #ifndef NO_RSA - case CKK_RSA: - ret = wp11_Object_Encode_RsaKey(object); - if (protect && ret == 0 && object->objClass == CKO_PRIVATE_KEY) { - wc_FreeRsaKey(&object->data.rsaKey); - object->encoded = 1; - } - break; - #endif - #ifdef HAVE_ECC - case CKK_EC: - ret = wp11_Object_Encode_EccKey(object); - if (protect && ret == 0 && object->objClass == CKO_PRIVATE_KEY) { - wc_ecc_free(&object->data.ecKey); - object->encoded = 1; - } - break; - #endif - #ifndef NO_DH - case CKK_DH: - ret = wp11_Object_Encode_DhKey(object); - if (protect && ret == 0 && object->objClass == CKO_PRIVATE_KEY) { - XMEMSET(object->data.dhKey.key, 0, object->data.dhKey.len); - object->encoded = 1; - } - break; - #endif - #ifndef NO_AES - case CKK_AES: - #endif - case CKK_GENERIC_SECRET: - ret = wp11_Object_Encode_SymmKey(object); - if (protect && ret == 0) { - XMEMSET(object->data.symmKey.data, 0, object->data.symmKey.len); - object->encoded = 1; - } - break; - default: - ret = NOT_AVAILABLE_E; + if (object->objClass == CKO_CERTIFICATE) { + ret = 0; + } + else { + switch (object->type) { + #ifndef NO_RSA + case CKK_RSA: + ret = wp11_Object_Encode_RsaKey(object); + if (protect && ret == 0 && object->objClass == CKO_PRIVATE_KEY) { + wc_FreeRsaKey(&object->data.rsaKey); + object->encoded = 1; + } + break; + #endif + #ifdef HAVE_ECC + case CKK_EC: + ret = wp11_Object_Encode_EccKey(object); + if (protect && ret == 0 && object->objClass == CKO_PRIVATE_KEY) { + wc_ecc_free(&object->data.ecKey); + object->encoded = 1; + } + break; + #endif + #ifndef NO_DH + case CKK_DH: + ret = wp11_Object_Encode_DhKey(object); + if (protect && ret == 0 && object->objClass == CKO_PRIVATE_KEY) { + XMEMSET(object->data.dhKey.key, 0, object->data.dhKey.len); + object->encoded = 1; + } + break; + #endif + #ifndef NO_AES + case CKK_AES: + #endif + case CKK_GENERIC_SECRET: + ret = wp11_Object_Encode_SymmKey(object); + if (protect && ret == 0) { + XMEMSET(object->data.symmKey.data, 0, object->data.symmKey.len); + object->encoded = 1; + } + break; + default: + ret = NOT_AVAILABLE_E; + } } return ret; @@ -2828,6 +2926,11 @@ static void wp11_Object_Unstore(WP11_Object* object, int tokenId, int objId) wp11_storage_open(WOLFPKCS11_STORE_OBJECT, tokenId, objId, 0, &storage); wp11_storage_close(storage); + /* CKK_* and CKC_* values overlap, check for cert separately */ + if (object->objClass == CKO_CERTIFICATE) { + storeObjType = WOLFPKCS11_STORE_CERT; + } + else { /* Open access to symmetric key. */ switch (object->type) { #ifndef NO_RSA @@ -2860,6 +2963,7 @@ static void wp11_Object_Unstore(WP11_Object* object, int tokenId, int objId) case CKK_GENERIC_SECRET: storeObjType = WOLFPKCS11_STORE_SYMMKEY; break; + } } wp11_storage_open(storeObjType, tokenId, objId, 0, &storage); wp11_storage_close(storage); @@ -4842,24 +4946,29 @@ void WP11_Object_Free(WP11_Object* object) XFREE(object->label, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (object->keyId != NULL) XFREE(object->keyId, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#ifndef NO_RSA - if (object->type == CKK_RSA) - wc_FreeRsaKey(&object->data.rsaKey); -#endif -#ifdef HAVE_ECC - if (object->type == CKK_EC) - wc_ecc_free(&object->data.ecKey); -#endif -#ifndef NO_DH - if (object->type == CKK_DH) - wc_FreeDhKey(&object->data.dhKey.params); -#endif - if (object->type == CKK_AES || object->type == CKK_GENERIC_SECRET) - XMEMSET(object->data.symmKey.data, 0, object->data.symmKey.len); -#ifndef WOLFPKCS11_NO_STORE - if (object->keyData != NULL) - XFREE(object->keyData, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + if (object->objClass == CKO_CERTIFICATE) { + XMEMSET(object->data.cert.data, 0, object->data.cert.len); + } + else { + #ifndef NO_RSA + if (object->type == CKK_RSA) + wc_FreeRsaKey(&object->data.rsaKey); + #endif + #ifdef HAVE_ECC + if (object->type == CKK_EC) + wc_ecc_free(&object->data.ecKey); + #endif + #ifndef NO_DH + if (object->type == CKK_DH) + wc_FreeDhKey(&object->data.dhKey.params); + #endif + if (object->type == CKK_AES || object->type == CKK_GENERIC_SECRET) + XMEMSET(object->data.symmKey.data, 0, object->data.symmKey.len); + #ifndef WOLFPKCS11_NO_STORE + if (object->keyData != NULL) + XFREE(object->keyData, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + } /* Dispose of object. */ XFREE(object, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -5270,6 +5379,42 @@ int WP11_Object_SetSecretKey(WP11_Object* object, unsigned char** data, return ret; } +int WP11_Object_SetCert(WP11_Object* object, unsigned char** data, + CK_ULONG* len) +{ + int ret = 0; + WP11_Cert* cert; + + if (object->onToken) + WP11_Lock_LockRW(object->lock); + + cert = &object->data.cert; + cert->len = 0; + XMEMSET(cert->data, 0, sizeof(cert->data)); + + /* First item is certificate type */ + if (ret == 0 && data[0] != NULL && len[0] != (int)sizeof(CK_ULONG)) + ret = BAD_FUNC_ARG; + if (ret == 0 && data[0] != NULL) + cert->type = (word32)*(CK_ULONG*)data[0]; + + /* Second item is certificate data (CKA_VALUE) */ + if (ret == 0 && data[1] != NULL) { + if ((word32)len[1] > sizeof(cert->data)) + ret = BUFFER_E; + else + cert->len = (word32)len[1]; + } + if (ret == 0 && data[1] != NULL) + XMEMCPY(cert->data, data[1], cert->len); + + if (object->onToken) + WP11_Lock_UnlockRW(object->lock); + + return ret; +} + + /** * Set the object's class. * @@ -5882,33 +6027,43 @@ int WP11_Object_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, break; default: - switch (object->type) { -#ifndef NO_RSA - case CKK_RSA: - ret = RsaObject_GetAttr(object, type, data, len); - break; -#endif -#ifdef HAVE_ECC - case CKK_EC: - ret = EcObject_GetAttr(object, type, data, len); - break; -#endif -#ifndef NO_DH - case CKK_DH: - ret = DhObject_GetAttr(object, type, data, len); - break; -#endif -#ifndef NO_AES - case CKK_AES: -#endif - case CKK_GENERIC_SECRET: - ret = SecretObject_GetAttr(object, type, data, len); + { + if ((object->objClass == CKO_CERTIFICATE) && + (type == CKA_VALUE)) { + ret = GetData((byte*)object->data.cert.data, + object->data.cert.len, data, len); break; - default: - ret = NOT_AVAILABLE_E; + } + else { + switch (object->type) { + #ifndef NO_RSA + case CKK_RSA: + ret = RsaObject_GetAttr(object, type, data, len); + break; + #endif + #ifdef HAVE_ECC + case CKK_EC: + ret = EcObject_GetAttr(object, type, data, len); + break; + #endif + #ifndef NO_DH + case CKK_DH: + ret = DhObject_GetAttr(object, type, data, len); + break; + #endif + #ifndef NO_AES + case CKK_AES: + #endif + case CKK_GENERIC_SECRET: + ret = SecretObject_GetAttr(object, type, data, len); + break; + default: + ret = NOT_AVAILABLE_E; + break; + } break; + } } - break; } if (object->onToken) @@ -6186,6 +6341,9 @@ int WP11_Object_SetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, } break; case CKA_VALUE: + if (object->objClass == CKO_CERTIFICATE) { + break; /* Handled in WP11_Object_SetCert */ + } switch (object->type) { #ifdef HAVE_ECC case CKK_EC: @@ -6199,8 +6357,8 @@ int WP11_Object_SetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, case CKK_GENERIC_SECRET: break; default: - ret = BAD_FUNC_ARG; - break; + ret = BAD_FUNC_ARG; + break; } break; case CKA_KEY_TYPE: @@ -6209,6 +6367,26 @@ int WP11_Object_SetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, case CKA_TOKEN: /* Handled in layer above */ break; + case CKA_CERTIFICATE_TYPE: + /* Handled in WP11_Object_SetCert */ + break; + case CKA_SUBJECT: + case CKA_ISSUER: + case CKA_SERIAL_NUMBER: + case CKA_AC_ISSUER: + case CKA_ATTR_TYPES: + case CKA_CERTIFICATE_CATEGORY: + case CKA_JAVA_MIDP_SECURITY_DOMAIN: + case CKA_URL: + case CKA_HASH_OF_SUBJECT_PUBLIC_KEY: + case CKA_HASH_OF_ISSUER_PUBLIC_KEY: + case CKA_NAME_HASH_ALGORITHM: + case CKA_CHECK_VALUE: + /* Fields are allowed, but not saved yet */ + if (object->objClass != CKO_CERTIFICATE) { + ret = BAD_FUNC_ARG; + } + break; default: ret = BAD_FUNC_ARG; break; diff --git a/tests/pkcs11test.c b/tests/pkcs11test.c index d2f8173..48c23e7 100644 --- a/tests/pkcs11test.c +++ b/tests/pkcs11test.c @@ -78,6 +78,7 @@ static CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY; #endif static CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY; static CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY; +static CK_OBJECT_CLASS certificateClass = CKO_CERTIFICATE; #if defined(HAVE_ECC) || !defined(NO_DH) static CK_BBOOL ckFalse = CK_FALSE; @@ -1653,7 +1654,7 @@ static CK_RV test_attribute_get(void* args) CHECK_CKR(ret, "C_GetAttributeValue"); for (i = 0; i < (int)getTmplCnt; i++) { - getTmpl[i].pValue = XMALLOC(getTmpl[i].ulValueLen * sizeof(byte), + getTmpl[i].pValue = XMALLOC(getTmpl[i].ulValueLen * sizeof(byte), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (getTmpl[i].pValue == NULL) ret = CKR_DEVICE_MEMORY; @@ -7577,6 +7578,195 @@ static CK_RV test_hmac_sha512_fail(void* args) #endif #endif +static CK_RV test_x509(void* args) +{ + CK_RV ret = CKR_OK; + CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args; + CK_CERTIFICATE_TYPE certType = CKC_X_509; + CK_UTF8CHAR label[] = "A certificate object"; + CK_BYTE subject[] = "C = US, ST = Montana, L = Bozeman, O = wolfSSL, " + "OU = Support, CN = www.wolfssl.com, emailAddress = info@wolfssl.com"; + CK_BYTE id[] = {0x27, 0x8E, 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, + 0x33, 0x63, 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5 + }; + CK_BYTE certificate[] = { /* ./certs/server-cert.der, 2048-bit */ + 0x30, 0x82, 0x04, 0xE8, 0x30, 0x82, 0x03, 0xD0, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, + 0x00, 0x30, 0x81, 0x94, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x07, 0x4D, 0x6F, + 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, 0x30, 0x0E, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, 0x6F, 0x7A, 0x65, + 0x6D, 0x61, 0x6E, 0x31, 0x11, 0x30, 0x0F, 0x06, 0x03, 0x55, + 0x04, 0x0A, 0x0C, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6F, 0x6F, + 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0B, 0x0C, 0x0A, 0x43, 0x6F, 0x6E, 0x73, 0x75, 0x6C, 0x74, + 0x69, 0x6E, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, + 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, + 0x1F, 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, + 0x0D, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, + 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, + 0x6F, 0x6D, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x33, 0x31, 0x32, + 0x31, 0x33, 0x32, 0x32, 0x31, 0x39, 0x32, 0x38, 0x5A, 0x17, + 0x0D, 0x32, 0x36, 0x30, 0x39, 0x30, 0x38, 0x32, 0x32, 0x31, + 0x39, 0x32, 0x38, 0x5A, 0x30, 0x81, 0x90, 0x31, 0x0B, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, + 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x31, 0x10, + 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, 0x07, 0x42, + 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x10, 0x30, 0x0E, + 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x07, 0x77, 0x6F, 0x6C, + 0x66, 0x53, 0x53, 0x4C, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, + 0x55, 0x04, 0x0B, 0x0C, 0x07, 0x53, 0x75, 0x70, 0x70, 0x6F, + 0x72, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0C, 0x0F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, + 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, + 0x30, 0x1D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, + 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, + 0x6D, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xC0, 0x95, 0x08, 0xE1, 0x57, 0x41, + 0xF2, 0x71, 0x6D, 0xB7, 0xD2, 0x45, 0x41, 0x27, 0x01, 0x65, + 0xC6, 0x45, 0xAE, 0xF2, 0xBC, 0x24, 0x30, 0xB8, 0x95, 0xCE, + 0x2F, 0x4E, 0xD6, 0xF6, 0x1C, 0x88, 0xBC, 0x7C, 0x9F, 0xFB, + 0xA8, 0x67, 0x7F, 0xFE, 0x5C, 0x9C, 0x51, 0x75, 0xF7, 0x8A, + 0xCA, 0x07, 0xE7, 0x35, 0x2F, 0x8F, 0xE1, 0xBD, 0x7B, 0xC0, + 0x2F, 0x7C, 0xAB, 0x64, 0xA8, 0x17, 0xFC, 0xCA, 0x5D, 0x7B, + 0xBA, 0xE0, 0x21, 0xE5, 0x72, 0x2E, 0x6F, 0x2E, 0x86, 0xD8, + 0x95, 0x73, 0xDA, 0xAC, 0x1B, 0x53, 0xB9, 0x5F, 0x3F, 0xD7, + 0x19, 0x0D, 0x25, 0x4F, 0xE1, 0x63, 0x63, 0x51, 0x8B, 0x0B, + 0x64, 0x3F, 0xAD, 0x43, 0xB8, 0xA5, 0x1C, 0x5C, 0x34, 0xB3, + 0xAE, 0x00, 0xA0, 0x63, 0xC5, 0xF6, 0x7F, 0x0B, 0x59, 0x68, + 0x78, 0x73, 0xA6, 0x8C, 0x18, 0xA9, 0x02, 0x6D, 0xAF, 0xC3, + 0x19, 0x01, 0x2E, 0xB8, 0x10, 0xE3, 0xC6, 0xCC, 0x40, 0xB4, + 0x69, 0xA3, 0x46, 0x33, 0x69, 0x87, 0x6E, 0xC4, 0xBB, 0x17, + 0xA6, 0xF3, 0xE8, 0xDD, 0xAD, 0x73, 0xBC, 0x7B, 0x2F, 0x21, + 0xB5, 0xFD, 0x66, 0x51, 0x0C, 0xBD, 0x54, 0xB3, 0xE1, 0x6D, + 0x5F, 0x1C, 0xBC, 0x23, 0x73, 0xD1, 0x09, 0x03, 0x89, 0x14, + 0xD2, 0x10, 0xB9, 0x64, 0xC3, 0x2A, 0xD0, 0xA1, 0x96, 0x4A, + 0xBC, 0xE1, 0xD4, 0x1A, 0x5B, 0xC7, 0xA0, 0xC0, 0xC1, 0x63, + 0x78, 0x0F, 0x44, 0x37, 0x30, 0x32, 0x96, 0x80, 0x32, 0x23, + 0x95, 0xA1, 0x77, 0xBA, 0x13, 0xD2, 0x97, 0x73, 0xE2, 0x5D, + 0x25, 0xC9, 0x6A, 0x0D, 0xC3, 0x39, 0x60, 0xA4, 0xB4, 0xB0, + 0x69, 0x42, 0x42, 0x09, 0xE9, 0xD8, 0x08, 0xBC, 0x33, 0x20, + 0xB3, 0x58, 0x22, 0xA7, 0xAA, 0xEB, 0xC4, 0xE1, 0xE6, 0x61, + 0x83, 0xC5, 0xD2, 0x96, 0xDF, 0xD9, 0xD0, 0x4F, 0xAD, 0xD7, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x45, 0x30, + 0x82, 0x01, 0x41, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, + 0x04, 0x16, 0x04, 0x14, 0xB3, 0x11, 0x32, 0xC9, 0x92, 0x98, + 0x84, 0xE2, 0xC9, 0xF8, 0xD0, 0x3B, 0x6E, 0x03, 0x42, 0xCA, + 0x1F, 0x0E, 0x8E, 0x3C, 0x30, 0x81, 0xD4, 0x06, 0x03, 0x55, + 0x1D, 0x23, 0x04, 0x81, 0xCC, 0x30, 0x81, 0xC9, 0x80, 0x14, + 0x27, 0x8E, 0x67, 0x11, 0x74, 0xC3, 0x26, 0x1D, 0x3F, 0xED, + 0x33, 0x63, 0xB3, 0xA4, 0xD8, 0x1D, 0x30, 0xE5, 0xE8, 0xD5, + 0xA1, 0x81, 0x9A, 0xA4, 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, + 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0C, 0x07, 0x4D, 0x6F, 0x6E, 0x74, 0x61, 0x6E, 0x61, + 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0C, + 0x07, 0x42, 0x6F, 0x7A, 0x65, 0x6D, 0x61, 0x6E, 0x31, 0x11, + 0x30, 0x0F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x08, 0x53, + 0x61, 0x77, 0x74, 0x6F, 0x6F, 0x74, 0x68, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x0A, 0x43, 0x6F, + 0x6E, 0x73, 0x75, 0x6C, 0x74, 0x69, 0x6E, 0x67, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x77, + 0x77, 0x77, 0x2E, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73, 0x6C, + 0x2E, 0x63, 0x6F, 0x6D, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01, 0x16, + 0x10, 0x69, 0x6E, 0x66, 0x6F, 0x40, 0x77, 0x6F, 0x6C, 0x66, + 0x73, 0x73, 0x6C, 0x2E, 0x63, 0x6F, 0x6D, 0x82, 0x14, 0x33, + 0x44, 0x1A, 0xA8, 0x6C, 0x01, 0xEC, 0xF6, 0x60, 0xF2, 0x70, + 0x51, 0x0A, 0x4C, 0xD1, 0x14, 0xFA, 0xBC, 0xE9, 0x44, 0x30, + 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xFF, 0x30, 0x1C, 0x06, 0x03, 0x55, 0x1D, 0x11, + 0x04, 0x15, 0x30, 0x13, 0x82, 0x0B, 0x65, 0x78, 0x61, 0x6D, + 0x70, 0x6C, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x87, 0x04, 0x7F, + 0x00, 0x00, 0x01, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x25, + 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x02, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x4A, 0xFF, 0xB9, 0xE5, 0x85, 0x9B, + 0xDA, 0x53, 0x66, 0x7F, 0x07, 0x22, 0xBF, 0xB6, 0x19, 0xEA, + 0x42, 0xEB, 0xA4, 0x11, 0x07, 0x62, 0xFF, 0x39, 0x5F, 0x33, + 0x37, 0x3A, 0x87, 0x26, 0x71, 0x3D, 0x13, 0xB2, 0xCA, 0xB8, + 0x64, 0x38, 0x7B, 0x8A, 0x99, 0x48, 0x0E, 0xA5, 0xA4, 0x6B, + 0xB1, 0x99, 0x6E, 0xE0, 0x46, 0x51, 0xBD, 0x19, 0x52, 0xAD, + 0xBC, 0xA6, 0x7E, 0x2A, 0x7A, 0x7C, 0x23, 0xA7, 0xCC, 0xDB, + 0x5E, 0x43, 0x7D, 0x6B, 0x04, 0xC8, 0xB7, 0xDD, 0x95, 0xAD, + 0xF0, 0x91, 0x80, 0x59, 0xC5, 0x19, 0x91, 0x26, 0x27, 0x91, + 0xB8, 0x48, 0x1C, 0xEB, 0x55, 0xB6, 0xAA, 0x7D, 0xA4, 0x38, + 0xF1, 0x03, 0xBC, 0x6C, 0x8B, 0xAA, 0x94, 0xD6, 0x3C, 0x05, + 0x7A, 0x96, 0xC5, 0x06, 0xF1, 0x26, 0x14, 0x2E, 0x75, 0xFB, + 0xDD, 0xE5, 0x35, 0xB3, 0x01, 0x2C, 0xB3, 0xAD, 0x62, 0x5A, + 0x21, 0x9A, 0x08, 0xBE, 0x56, 0xFC, 0xF9, 0xA2, 0x42, 0x87, + 0x86, 0xE5, 0xA9, 0xC5, 0x99, 0xCF, 0xAE, 0x14, 0xBE, 0xE0, + 0xB9, 0x08, 0x24, 0x0D, 0x1D, 0x5C, 0xD6, 0x14, 0xE1, 0x4C, + 0x9F, 0x40, 0xB3, 0xA9, 0xE9, 0x2D, 0x52, 0x8B, 0x4C, 0xBF, + 0xAC, 0x44, 0x31, 0x67, 0xC1, 0x8D, 0x06, 0x85, 0xEC, 0x0F, + 0xE4, 0x99, 0xD7, 0x4B, 0x7B, 0x21, 0x06, 0x66, 0xD4, 0xE4, + 0xF5, 0x9D, 0xFF, 0x8E, 0xF0, 0x86, 0x39, 0x58, 0x1D, 0xA4, + 0x5B, 0xE2, 0x63, 0xEF, 0x7C, 0xC9, 0x18, 0x87, 0xA8, 0x02, + 0x25, 0x10, 0x3E, 0x87, 0x28, 0xF9, 0xF5, 0xEF, 0x47, 0x9E, + 0xA5, 0x80, 0x08, 0x11, 0x90, 0x68, 0xFE, 0xD1, 0xA3, 0xA8, + 0x51, 0xB9, 0x37, 0xFF, 0xD5, 0xCA, 0x7C, 0x87, 0x7F, 0x6B, + 0xBC, 0x2C, 0x12, 0xC8, 0xC5, 0x85, 0x8B, 0xFC, 0x0C, 0xC6, + 0xB9, 0x86, 0xB8, 0xC9, 0x04, 0xC3, 0x51, 0x37, 0xD2, 0x4F + }; + + CK_ATTRIBUTE tmpl[] = { + {CKA_CLASS, &certificateClass, sizeof(certificateClass)}, + {CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)}, + {CKA_TOKEN, &ckTrue, sizeof(ckTrue)}, + {CKA_LABEL, label, sizeof(label)-1}, + {CKA_SUBJECT, subject, sizeof(subject)-1}, + {CKA_ID, id, sizeof(id)}, + {CKA_VALUE, certificate, sizeof(certificate)} + }; + CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl); + CK_OBJECT_HANDLE obj; + CK_ATTRIBUTE getTmpl[] = { + { CKA_VALUE, NULL, 0 } + }; + CK_ULONG getTmplCnt = sizeof(getTmpl) / sizeof(*getTmpl); + + ret = funcList->C_CreateObject(session, tmpl, tmplCnt, &obj); + CHECK_CKR(ret, "Create certificate object"); + if (ret == CKR_OK) { + ret = funcList->C_GetAttributeValue(session, obj, getTmpl, getTmplCnt); + CHECK_CKR(ret, "C_GetAttributeValue"); + + if (ret == CKR_OK) { + getTmpl[0].pValue = XMALLOC(getTmpl[0].ulValueLen * sizeof(byte), + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (getTmpl[0].pValue == NULL) + ret = CKR_DEVICE_MEMORY; + CHECK_CKR(ret, "Allocate get attribute memory"); + + if (ret == CKR_OK) { + ret = funcList->C_GetAttributeValue(session, obj, getTmpl, getTmplCnt); + CHECK_CKR(ret, "C_GetAttributeValue"); + + if (sizeof(certificate) != getTmpl[0].ulValueLen) { + ret = CKR_GENERAL_ERROR; + } + if (XMEMCMP(certificate, getTmpl[0].pValue, sizeof(certificate)) != 0) { + ret = CKR_GENERAL_ERROR; + } + CHECK_CKR(ret, "Verify that stored cert matches original"); + + XFREE(getTmpl[0].pValue, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + } + ret = funcList->C_DestroyObject(session, obj); + } + return ret; +} + static CK_RV test_random(void* args) { CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args; @@ -7860,6 +8050,7 @@ static TEST_FUNC testFunc[] = { #endif #endif PKCS11TEST_FUNC_SESS_DECL(test_random), + PKCS11TEST_FUNC_SESS_DECL(test_x509), }; static int testFuncCnt = sizeof(testFunc) / sizeof(*testFunc); diff --git a/wolfpkcs11/internal.h b/wolfpkcs11/internal.h index 7454545..f098bdb 100644 --- a/wolfpkcs11/internal.h +++ b/wolfpkcs11/internal.h @@ -263,8 +263,10 @@ int WP11_Object_SetDhKey(WP11_Object* object, unsigned char** data, CK_ULONG* len); int WP11_Object_SetSecretKey(WP11_Object* object, unsigned char** data, CK_ULONG* len); -int WP11_Object_SetClass(WP11_Object* object, CK_OBJECT_CLASS objClass); +int WP11_Object_SetCert(WP11_Object* object, unsigned char** data, + CK_ULONG* len); +int WP11_Object_SetClass(WP11_Object* object, CK_OBJECT_CLASS objClass); CK_OBJECT_CLASS WP11_Object_GetClass(WP11_Object* object); int WP11_Object_Find(WP11_Session* session, CK_OBJECT_HANDLE objHandle, diff --git a/wolfpkcs11/pkcs11.h b/wolfpkcs11/pkcs11.h index a4552fe..a259c1b 100644 --- a/wolfpkcs11/pkcs11.h +++ b/wolfpkcs11/pkcs11.h @@ -143,8 +143,21 @@ extern "C" { #define CKA_APPLICATION 0x00000010UL #define CKA_VALUE 0x00000011UL #define CKA_OBJECT_ID 0x00000012UL + +#define CKA_CERTIFICATE_TYPE 0x00000080UL +#define CKA_ISSUER 0x00000081UL +#define CKA_SERIAL_NUMBER 0x00000082UL +#define CKA_AC_ISSUER 0x00000083UL #define CKA_OWNER 0x00000084UL +#define CKA_ATTR_TYPES 0x00000085UL #define CKA_TRUSTED 0x00000086UL +#define CKA_CERTIFICATE_CATEGORY 0x00000087UL +#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL +#define CKA_URL 0x00000089UL +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL +#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL +#define CKA_CHECK_VALUE 0x00000090UL #define CKA_KEY_TYPE 0x00000100UL #define CKA_SUBJECT 0x00000101UL #define CKA_ID 0x00000102UL @@ -322,6 +335,11 @@ extern "C" { #define CKZ_DATA_SPECIFIED 0x00000001UL +#define CKC_X_509 0x00000000UL +#define CKC_X_509_ATTR_CERT 0x00000001UL +#define CKC_WTLS 0x00000002UL +#define CKC_VENDOR_DEFINED 0x80000000UL + typedef unsigned char CK_BYTE; typedef CK_BYTE CK_CHAR; typedef CK_BYTE CK_UTF8CHAR; @@ -335,7 +353,7 @@ typedef CK_UTF8CHAR* CK_UTF8CHAR_PTR; typedef CK_ULONG* CK_ULONG_PTR; typedef void* CK_VOID_PTR; typedef CK_VOID_PTR* CK_VOID_PTR_PTR; - +typedef CK_ULONG CK_CERTIFICATE_TYPE; typedef CK_ULONG CK_RV; diff --git a/wolfpkcs11/store.h b/wolfpkcs11/store.h index 39d6b40..93ca476 100644 --- a/wolfpkcs11/store.h +++ b/wolfpkcs11/store.h @@ -31,6 +31,7 @@ #define WOLFPKCS11_STORE_ECCKEY_PUB 0x06 #define WOLFPKCS11_STORE_DHKEY_PRIV 0x07 #define WOLFPKCS11_STORE_DHKEY_PUB 0x08 +#define WOLFPKCS11_STORE_CERT 0x09 /* * Opens access to location to read/write token data.