Started major overhaul of slot vendors and token vendors.

This commit is contained in:
Alessio Di Mauro
2015-07-27 17:03:29 +02:00
parent 437094b2d7
commit b9596b33f5
11 changed files with 330 additions and 159 deletions
+40
View File
@@ -0,0 +1,40 @@
#include "mechanisms.h"
// Supported mechanisms for signature
static const CK_MECHANISM_TYPE sign[] = {
CKM_RSA_PKCS,
CKM_RSA_PKCS_PSS,
CKM_RSA_X_509,
CKM_SHA1_RSA_PKCS,
CKM_SHA256_RSA_PKCS,
CKM_SHA384_RSA_PKCS,
CKM_SHA512_RSA_PKCS,
CKM_SHA1_RSA_PKCS_PSS,
CKM_SHA256_RSA_PKCS_PSS,
CKM_SHA384_RSA_PKCS_PSS,
CKM_SHA512_RSA_PKCS_PSS,
CKM_ECDSA,
CKM_ECDSA_SHA1
};
CK_RV check_sign_mechanism(const ykcs11_session_t *s, const CK_MECHANISM_PTR m, const CK_OBJECT_HANDLE k) {
CK_ULONG i;
CK_BBOOL supported = CK_FALSE;
/* Check if mechanism is supported by the module */
for (i = 0; i < sizeof(sign) / sizeof(CK_MECHANISM_TYPE); i++) {
if (m->mechanism == sign[i]) {
supported = CK_TRUE;
break;
}
}
if (supported == CK_FALSE)
return CKR_MECHANISM_INVALID;
/* Check if mechanism is supported by the token */
CK_OK;
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef MECHANISMS_H
#define MECHANISMS_H
#include "pkcs11t.h"
CK_RV check_sign_mechanism(const CK_MECHANISM_PTR m, const CK_OBJECT_HANDLE k);
#endif
+95 -8
View File
@@ -1,4 +1,5 @@
#include "utils.h"
#include <stdlib.h>
#include <string.h>
CK_BBOOL has_token(const ykcs11_slot_t *slot) {
@@ -7,7 +8,7 @@ CK_BBOOL has_token(const ykcs11_slot_t *slot) {
}
CK_BBOOL parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len,
CK_RV parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len,
ykcs11_slot_t *slots, CK_ULONG_PTR n_slots, CK_ULONG_PTR n_with_token) {
CK_BYTE i;
@@ -40,6 +41,7 @@ CK_BBOOL parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len,
strncpy(slots[*n_slots].info.slotDescription, p, sizeof(slots[*n_slots].info.slotDescription));
}
else {
// Supported slot
vendor = get_vendor(slots[*n_slots].vid);
// Values must NOT be null terminated and ' ' padded
@@ -48,31 +50,116 @@ CK_BBOOL parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len,
s = slots[*n_slots].info.slotDescription;
l = sizeof(slots[*n_slots].info.slotDescription);
if (vendor.get_slot_description(s, l) != CKR_OK)
return CK_FALSE;
goto failure;
memset(slots[*n_slots].info.manufacturerID, ' ', sizeof(slots[*n_slots].info.manufacturerID));
s = slots[*n_slots].info.manufacturerID;
l = sizeof(slots[*n_slots].info.manufacturerID);
if(vendor.get_slot_manufacturer(s, l) != CKR_OK)
return CK_FALSE;
goto failure;
if (vendor.get_slot_flags(&slots[*n_slots].info.flags) != CKR_OK)
return CK_FALSE;
goto failure;
// Treating hw and fw version the same
if (vendor.get_slot_version(&slots[*n_slots].info.hardwareVersion) != CKR_OK)
return CK_FALSE;
goto failure;
if (vendor.get_slot_version(&slots[*n_slots].info.firmwareVersion) != CKR_OK)
return CK_FALSE;
goto failure;
if (has_token(slots + *n_slots))
if (has_token(slots + *n_slots)) {
// Save token information
(*n_with_token)++;
if (create_token(p, slots + *n_slots) != CKR_OK)
goto failure;
}
}
(*n_slots)++;
p += i + 1;
}
return CK_TRUE;
return CKR_OK;
failure:
// TODO: destroy all token objects
for (i = 0; i < *n_slots; i++)
if (has_token(slots + i))
destroy_token(slots + i);
return CKR_FUNCTION_FAILED;
}
CK_RV create_token(CK_BYTE_PTR p, ykcs11_slot_t *slot) {
vendor_t token_vendor;
CK_TOKEN_INFO_PTR t_info;
fprintf(stderr, "Now trying to get token info from %s\n", p); // TODO: is p needed?
slot->token = malloc(sizeof(ykcs11_token_t)); // TODO: free
if (slot->token == NULL)
return CKR_HOST_MEMORY;
slot->token->vid = YUBICO; // TODO: this must become "slot_vendor.get_token_vid()"
token_vendor = get_vendor(slot->token->vid);
t_info = &slot->token->info;
memset(t_info->label, ' ', sizeof(t_info->label));
if (token_vendor.get_token_label(t_info->label, sizeof(t_info->label)) != CKR_OK)
return CKR_FUNCTION_FAILED;
memset(t_info->manufacturerID, ' ', sizeof(t_info->manufacturerID));
if(token_vendor.get_token_manufacturer(t_info->manufacturerID, sizeof(t_info->manufacturerID)) != CKR_OK)
return CKR_FUNCTION_FAILED;
memset(t_info->model, ' ', sizeof(t_info->model));
if(token_vendor.get_token_model(t_info->model, sizeof(t_info->model)) != CKR_OK)
return CKR_FUNCTION_FAILED;
memset(t_info->serialNumber, ' ', sizeof(t_info->serialNumber));
if(token_vendor.get_token_serial(t_info->serialNumber, sizeof(t_info->serialNumber)) != CKR_OK)
return CKR_FUNCTION_FAILED;
if (token_vendor.get_token_flags(&t_info->flags) != CKR_OK)
return CKR_FUNCTION_FAILED;
t_info->ulMaxSessionCount = CK_UNAVAILABLE_INFORMATION;
t_info->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
t_info->ulMaxRwSessionCount = CK_UNAVAILABLE_INFORMATION;
t_info->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
t_info->ulMaxPinLen = 8;
t_info->ulMinPinLen = 6;
t_info->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
t_info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
t_info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
t_info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
//ykpiv_get_version(piv_state, buf, sizeof(buf));
//if (token_vendor.get_token_version(buf, strlen(buf), &ver) != CKR_OK) // TODO: fix this
// return CKR_FUNCTION_FAILED;
//t_info->hardwareVersion = ver; // version number of hardware // TODO: fix
//t_info->firmwareVersion = ver; // version number of firmware // TODO: fix
memset(t_info->utcTime, ' ', sizeof(t_info->utcTime)); // No clock present, clear
// TODO: also get token objects here? (and destroy on failure)
return CKR_OK;
}
void destroy_token(ykcs11_slot_t *slot) {
free(slot->token);
slot->token = NULL;
}
+4 -9
View File
@@ -1,16 +1,11 @@
#ifndef UTILS_H
#define UTILS_H
#include "pkcs11t.h"
#include "vendors.h"
typedef struct {
vendor_id_t vid;
CK_SLOT_INFO info;
} ykcs11_slot_t; // TODO: move this
#include "ykcs11.h"
CK_BBOOL has_token(const ykcs11_slot_t *slot);
CK_BBOOL parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len,
CK_RV parse_readers(const CK_BYTE_PTR readers, const CK_ULONG len,
ykcs11_slot_t *slots, CK_ULONG_PTR n_slots, CK_ULONG_PTR n_with_token);
CK_RV create_token(CK_BYTE_PTR p, ykcs11_slot_t *slot);
void destroy_token(ykcs11_slot_t *slot);
#endif
+2 -2
View File
@@ -29,7 +29,7 @@ vendor_t get_vendor(vendor_id_t vid) {
v.get_token_mechanisms_num = YUBICO_get_token_mechanisms_num;
v.get_token_mechanism_list = YUBICO_get_token_mechanism_list;
v.get_token_mechanism_info = YUBICO_get_token_mechanism_info;
// v.get_token_objects_num = YUBICO_get_token_objects_num;
v.get_token_objects_num = YUBICO_get_token_objects_num;
v.get_token_object_list = YUBICO_get_token_object_list;
break;
@@ -48,7 +48,7 @@ vendor_t get_vendor(vendor_id_t vid) {
v.get_token_mechanisms_num = NULL;
v.get_token_mechanism_list = NULL;
v.get_token_mechanism_info = NULL;
// v.get_token_objects_num = NULL;
v.get_token_objects_num = NULL;
v.get_token_object_list = NULL;
}
+3 -3
View File
@@ -23,8 +23,8 @@ typedef CK_RV (*get_t_serial_f)(CK_CHAR_PTR, CK_ULONG);
typedef CK_RV (*get_t_mechanisms_num_f)(CK_ULONG_PTR);
typedef CK_RV (*get_t_mechanism_list_f)(CK_MECHANISM_TYPE_PTR, CK_ULONG);
typedef CK_RV (*get_t_mechanism_info_f)(CK_MECHANISM_TYPE, CK_MECHANISM_INFO_PTR);
//typedef CK_RV (*get_t_objects_num_f)(CK_ULONG_PTR);
typedef CK_RV (*get_t_object_list_f)(ykpiv_state *, piv_obj_id_t *, CK_ULONG_PTR);
typedef CK_RV (*get_t_objects_num_f)(ykpiv_state *, CK_ULONG_PTR);
typedef CK_RV (*get_t_object_list_f)(ykpiv_state *, piv_obj_id_t *, CK_ULONG);
typedef struct {
@@ -41,7 +41,7 @@ typedef struct {
get_t_mechanisms_num_f get_token_mechanisms_num;
get_t_mechanism_list_f get_token_mechanism_list;
get_t_mechanism_info_f get_token_mechanism_info;
// get_t_objects_num_f get_token_objects_num;
get_t_objects_num_f get_token_objects_num;
get_t_object_list_f get_token_object_list;
} vendor_t;
+115 -112
View File
@@ -1,8 +1,10 @@
#include "ykcs11.h"
#include "pkcs11.h"
#include <stdio.h>
#include <stdlib.h>
#include <ykpiv.h>
#include <string.h>
#include "vendors.h"
//#include "vendors.h"
#include "utils.h"
#define D(x) do { \
@@ -44,8 +46,7 @@ static ykcs11_slot_t slots[YKCS11_MAX_SLOTS]; // TODO: build at runtime?
static CK_ULONG n_slots = 0;
static CK_ULONG n_slots_with_token = 0;
static CK_SESSION_HANDLE session = CK_INVALID_HANDLE; // TODO: support multiple sessions?
static CK_SESSION_INFO session_info;
static ykcs11_session_t session; // TODO: support multiple sessions?
static struct {
CK_BBOOL active;
@@ -54,8 +55,8 @@ static struct {
piv_obj_id_t *objects;
} find_obj;
static piv_obj_id_t token_objects[PIV_CERT_OBJ_LAST]; // TODO: tide this up, also build at runtime (during open session)?
static CK_ULONG n_token_objects = 0;
/*static piv_obj_id_t token_objects[PIV_CERT_OBJ_LAST]; // TODO: tide this up, also build at runtime (during open session)? And include inside a session struct?
static CK_ULONG n_token_objects = 0;*/
static struct {
CK_BBOOL active;
@@ -236,8 +237,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(
{
DIN;
CK_VERSION ver = {0, 0};
vendor_id_t vid;
vendor_t vendor;
vendor_t token_vendor;
CK_BYTE buf[64];
if (piv_state == NULL)
@@ -246,10 +246,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(
if (slotID >= n_slots)
return CKR_ARGUMENTS_BAD;
vid = slots[slotID].vid;
if (vid == UNKNOWN) {
DBG(("No support for token in slot %lu", slotID));
if (slots[slotID].vid == UNKNOWN) {
DBG(("No support for slot %lu", slotID));
return CKR_TOKEN_NOT_RECOGNIZED;
}
@@ -258,57 +256,29 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(
return CKR_TOKEN_NOT_PRESENT;
}
vendor = get_vendor(vid); // TODO: make a token field in slot_t ?
if (slots[slotID].token->vid == UNKNOWN) {
DBG(("No support for token in slot %lu", slotID));
return CKR_TOKEN_NOT_RECOGNIZED;
}
memset(pInfo->label, ' ', sizeof(pInfo->label));
if (vendor.get_token_label(pInfo->label, sizeof(pInfo->label)) != CKR_OK)
return CKR_FUNCTION_FAILED;
token_vendor = get_vendor(slots[slotID].token->vid);
memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
if(vendor.get_token_manufacturer(pInfo->manufacturerID, sizeof(pInfo->manufacturerID)) != CKR_OK)
return CKR_FUNCTION_FAILED;
memset(pInfo->model, ' ', sizeof(pInfo->model));
if(vendor.get_token_model(pInfo->model, sizeof(pInfo->model)) != CKR_OK)
return CKR_FUNCTION_FAILED;
memset(pInfo->serialNumber, ' ', sizeof(pInfo->serialNumber));
if(vendor.get_token_serial(pInfo->serialNumber, sizeof(pInfo->serialNumber)) != CKR_OK)
return CKR_FUNCTION_FAILED;
// bit flags indicating capabilities and status of the device as defined below // TODO: what about other flags? Like last attempt
if (vendor.get_token_flags(&pInfo->flags) != CKR_OK)
return CKR_FUNCTION_FAILED;
memcpy(pInfo, &slots[slotID].token->info, sizeof(CK_TOKEN_INFO));
// Overwrite value that are application specific
pInfo->ulMaxSessionCount = CK_UNAVAILABLE_INFORMATION; // TODO: should this be 1?
pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION; // number of sessions that this application currently has open with the token
pInfo->ulMaxRwSessionCount = CK_UNAVAILABLE_INFORMATION; // maximum number of read/write sessions that can be opened with the token at one time by a single TODO: should this be 1?
pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION; // number of read/write sessions that this application currently has open with the token
pInfo->ulMaxPinLen = PIV_MAX_PIN_LEN; // maximum length in bytes of the PIN
pInfo->ulMinPinLen = PIV_MIN_PIN_LEN; // minimum length in bytes of the PIN
pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
ykpiv_get_version(piv_state, buf, sizeof(buf));
if (vendor.get_token_version(buf, strlen(buf), &ver) != CKR_OK)
return CKR_FUNCTION_FAILED;
pInfo->hardwareVersion = ver; // version number of hardware
pInfo->firmwareVersion = ver; // version number of firmware
memset(pInfo->utcTime, ' ', sizeof(pInfo->utcTime)); // No clock present, clear
DOUT;
return CKR_OK;
@@ -406,7 +376,6 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)(
if (vendor.get_token_mechanism_info(type, pInfo) != CKR_OK)
return CKR_MECHANISM_INVALID;
DOUT;
return CKR_OK;
}
@@ -459,7 +428,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
{
DIN;
vendor_t vendor;
vendor_t token_vendor;
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
@@ -468,6 +437,11 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
return CKR_ARGUMENTS_BAD;
if (slots[slotID].vid == UNKNOWN) {
DBG(("No support for slot %lu", slotID));
return CKR_TOKEN_NOT_RECOGNIZED;
}
if (slots[slotID].token->vid == UNKNOWN) {
DBG(("No support for token in slot %lu", slotID));
return CKR_TOKEN_NOT_RECOGNIZED;
}
@@ -477,44 +451,59 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
return CKR_TOKEN_NOT_PRESENT;
}
vendor = get_vendor(slots[slotID].vid); // TODO: make a token field in slot_t ?
// Store all the objects available in the token
n_token_objects = sizeof(token_objects) / sizeof(piv_obj_id_t);
if (vendor.get_token_object_list(piv_state, token_objects, &n_token_objects) != CKR_OK) {
DBG(("Unable to retrieve token objects"));
return CKR_FUNCTION_FAILED;
}
if ((flags & CKF_SERIAL_SESSION) == 0) { // TODO: check more error conditions
DBG(("Open session called without CKF_SERIAL_SESSION set"));
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
}
if (session != CK_INVALID_HANDLE) {
if (session.handle != CK_INVALID_HANDLE) {
DBG(("A session with this or another token already exists"));
return CKR_SESSION_COUNT;
}
// TODO: make sue we don't open a session with an UNKNOWN slot/token
if ((flags & CKF_SERIAL_SESSION) == 0) { // TODO: check more error conditions
DBG(("Open session called without CKF_SERIAL_SESSION set")); // Reuired by specs
return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
}
session = YKCS11_SESSION_ID;
session_info.slotID = slotID;
// TODO: KEEP TRACK OF THE APPLICATION
token_vendor = get_vendor(slots[slotID].token->vid);
// Store the slot
session.slot = slots + slotID;
//session.slot->info.slotID = slotID; // Redundant but required in CK_SESSION_INFO
// Get the number of token objects
if (token_vendor.get_token_objects_num(piv_state, &session.slot->token->n_objects) != CKR_OK) {
DBG(("Unable to retrieve number of token objects"));
return CKR_FUNCTION_FAILED;
}
// Get memory for the objects
session.slot->token->objects = malloc(sizeof(piv_obj_id_t) * session.slot->token->n_objects);
if (session.slot->token->objects == NULL) {
DBG(("Unable to allocate memory for token objects"));
return CKR_HOST_MEMORY;
}
// Store all the objects available in the token
if (token_vendor.get_token_object_list(piv_state,
session.slot->token->objects,
session.slot->token->n_objects) != CKR_OK) {
DBG(("Unable to retrieve token objects"));
return CKR_FUNCTION_FAILED;
}
if ((flags & CKF_RW_SESSION)) {
// R/W Session
session_info.state = CKS_RW_PUBLIC_SESSION; // Nobody has logged in, default session
session.info.state = CKS_RW_PUBLIC_SESSION; // Nobody has logged in, default session
}
else {
// R/O Session
session_info.state = CKS_RO_PUBLIC_SESSION; // Nobody has logged in, default session
session.info.state = CKS_RO_PUBLIC_SESSION; // Nobody has logged in, default session
}
session_info.flags = flags;
session_info.ulDeviceError = 0;
session.info.flags = flags;
session.info.ulDeviceError = 0;
*phSession = session;
session.handle = YKCS11_SESSION_ID;
// TODO: KEEP TRACK OF THE APPLICATION
*phSession = session.handle;
DOUT;
return CKR_OK;
@@ -529,16 +518,21 @@ CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session == CK_INVALID_HANDLE) {
if (session.handle == CK_INVALID_HANDLE) {
DBG(("There is no existing session"));
return CKR_SESSION_CLOSED;
}
if (hSession != YKCS11_SESSION_ID)
if (hSession != YKCS11_SESSION_ID) {
DBG(("Unknown session %lu", hSession));
return CKR_SESSION_HANDLE_INVALID;
}
session = CK_INVALID_HANDLE;
memset(&session_info, 0, sizeof(CK_SESSION_INFO));
free(session.slot->token->objects); // TODO: make objects survive a session so there is no need to get them again?
session.slot->token->objects = NULL;
memset(&session, 0, sizeof(ykcs11_session_t));
session.handle = CK_INVALID_HANDLE;
DOUT;
return CKR_OK;
@@ -549,18 +543,18 @@ CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)(
)
{
DIN;
CK_RV rv;
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session_info.slotID != slotID)
if (session.slot != slots + slotID)
return CKR_SLOT_ID_INVALID;
session = CK_INVALID_HANDLE;
memset(&session_info, 0, sizeof(CK_SESSION_INFO)); // TODO: Better to call close session?
rv = C_CloseSession(session.handle);
DOUT;
return CKR_OK;
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(
@@ -576,10 +570,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(
if (pInfo == NULL)
return CKR_ARGUMENTS_BAD;
if (hSession != session)
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
memcpy(pInfo, &session_info, sizeof(CK_SESSION_INFO));
memcpy(pInfo, &session.info, sizeof(CK_SESSION_INFO));
DOUT;
return CKR_OK;
@@ -635,25 +629,25 @@ CK_DEFINE_FUNCTION(CK_RV, C_Login)(
DBG(("user %lu, pin %s, pinlen %lu", userType, pPin, ulPinLen));
if (session == CK_INVALID_HANDLE)
if (session.handle == CK_INVALID_HANDLE)
return CKR_SESSION_CLOSED;
if (hSession != session)
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
if (userType != CKU_SO &&
if (userType != CKU_SO && // TODO: what can SO do?
userType != CKU_USER &&
userType != CKU_CONTEXT_SPECIFIC)
return CKR_USER_TYPE_INVALID;
if ((session_info.flags & CKF_RW_SESSION) == 0) { // TODO: make macros for these?
if ((session.info.flags & CKF_RW_SESSION) == 0) { // TODO: make macros for these?
DBG(("Tried to log-in to a read-only session"));
return CKR_SESSION_READ_ONLY_EXISTS;
}
switch (userType) {
case CKU_USER:
if (session_info.state == CKS_RW_USER_FUNCTIONS)
if (session.info.state == CKS_RW_USER_FUNCTIONS)
return CKR_USER_ALREADY_LOGGED_IN;
tries = 0;
@@ -747,10 +741,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)(
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session != YKCS11_SESSION_ID)
if (session.handle != YKCS11_SESSION_ID)
return CKR_SESSION_CLOSED;
if (hSession != session)
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
if (pTemplate == NULL_PTR || ulCount == 0)
@@ -800,25 +794,28 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session != YKCS11_SESSION_ID)
if (session.handle != YKCS11_SESSION_ID)
return CKR_SESSION_CLOSED;
if (hSession != session)
return CKR_SESSION_HANDLE_INVALID; // TODO: or session closed?
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
if (find_obj.active == CK_TRUE)
return CKR_OPERATION_ACTIVE;
if (slots[session_info.slotID].vid == UNKNOWN) {
DBG(("Slot %lu is tokenless/unsupported", session_info.slotID));
return CKR_SLOT_ID_INVALID;
//vendor = get_vendor(slots[session_info.slotID].vid); // TODO: make a token field in slot_t ?;
find_obj.idx = 0;
find_obj.num = session.slot->token->n_objects;
find_obj.objects = malloc(sizeof(piv_obj_id_t) * find_obj.num);
if (find_obj.objects == NULL) {
DBG(("Unable to allocate memory for finding objects"));
return CKR_HOST_MEMORY;
}
vendor = get_vendor(slots[session_info.slotID].vid); // TODO: make a token field in slot_t ?;
memcpy(find_obj.objects, session.slot->token->objects, sizeof(piv_obj_id_t) * find_obj.num); // TODO: add another 'num' field for then objects have to be excluded because of attribute matching;
find_obj.active = CK_TRUE;
find_obj.idx = 0;
find_obj.num = n_token_objects; // TOTO: actually malloc here so that the array can be changed
find_obj.objects = token_objects;
if (ulCount == 0) {
DBG(("Find ALL the objects!"));
@@ -838,9 +835,9 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(
// TODO: remove objects that don't match
}
// TOTO: do it properly here, jsut a test now
// TODO: do it properly here, jsut a test now
find_obj.num = 1;
find_obj.objects = token_objects + 3;
find_obj.objects = session.slot->token->objects + 3;
DOUT;
return CKR_OK;
@@ -858,10 +855,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)(
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session != YKCS11_SESSION_ID)
if (session.handle != YKCS11_SESSION_ID)
return CKR_SESSION_CLOSED;
if (hSession != session)
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
if (phObject == NULL_PTR ||
@@ -898,15 +895,18 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)(
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session != YKCS11_SESSION_ID)
if (session.handle != YKCS11_SESSION_ID)
return CKR_SESSION_CLOSED;
if (hSession != session)
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
if (find_obj.active != CK_TRUE)
return CKR_OPERATION_NOT_INITIALIZED;
free(find_obj.objects);
find_obj.objects = NULL;
find_obj.active = CK_FALSE;
DOUT;
@@ -1088,17 +1088,20 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
if (piv_state == NULL)
return CKR_CRYPTOKI_NOT_INITIALIZED;
if (session != YKCS11_SESSION_ID)
if (session.handle != YKCS11_SESSION_ID)
return CKR_SESSION_CLOSED;
if (hSession != session)
if (hSession != session.handle)
return CKR_SESSION_HANDLE_INVALID;
if (pMechanism == NULL_PTR ||
hKey == NULL_PTR)
return CKR_ARGUMENTS_BAD;
DBG(("Trying to sign some data with mechanism %lu and key %lu", pMechanism->mechanism, hKey));
DBG(("Trying to sign some data with mechanism %lu and key %lu more", pMechanism->mechanism, hKey));
if (check_sign_mechanism(pMechanism, hKey) == CK_FALSE) // TODO: do we need session here?
return CKR_MECHANISM_INVALID;
sign_info.active = CK_TRUE;
memcpy(&sign_info.mechanism, pMechanism, sizeof(CK_MECHANISM));
@@ -1140,19 +1143,19 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
ykpiv_rc r;
CK_CHAR key;
DBG(("Sending %lu bytes to sign", /*ulDataLen*/sig_len_in));
dump_hex(test_buf, sig_len_in, stderr, CK_TRUE);
DBG(("Sending %lu bytes to sign", ulDataLen/*sig_len_in*/));
dump_hex(pData, ulDataLen, stderr, CK_TRUE);
if (sign_info.key == PIV_DATA_OBJ_X509_PIV_AUTH) {
key = YKPIV_KEY_AUTHENTICATION;
DBG(("Using key 9a"));
}
else {
else { // TODO: test what happens if there is no key on the card
key = YKPIV_KEY_SIGNATURE;
DBG(("Using key 9c"));
}
// TODO: check that mechanism makes sense for the key that we have.
// TODO: check that mechanism makes sense for the key that we have (check in signinit).
if ((r = ykpiv_sign_data(piv_state, /*pData*/test_buf, /*ulDataLen*/sig_len_in, sig_buf, &sig_len_out, YKPIV_ALGO_RSA2048, key)) != YKPIV_OK) {
DBG(("Sign error %s", ykpiv_strerror(r)));
+26
View File
@@ -0,0 +1,26 @@
#ifndef YKCS11_H
#define YKCS11_H
#include "pkcs11t.h"
#include "vendors.h"
typedef struct {
vendor_id_t vid;
CK_TOKEN_INFO info;
piv_obj_id_t *objects;
CK_ULONG n_objects;
} ykcs11_token_t;
typedef struct {
vendor_id_t vid;
CK_SLOT_INFO info;
ykcs11_token_t *token;
} ykcs11_slot_t;
typedef struct {
CK_SESSION_HANDLE handle;
CK_SESSION_INFO info; /* slotid, state, flags, deviceerror */
ykcs11_slot_t *slot;
} ykcs11_session_t;
#endif
+1
View File
@@ -29,6 +29,7 @@ YKCS11_0.1.0
global:
C_Initialize;
C_GetFunctionList;
# TODO: add more here
local:
*;
};
+24 -15
View File
@@ -132,7 +132,6 @@ CK_RV YUBICO_get_slot_flags(CK_FLAGS_PTR flags) {
*flags = slot_flags;
return CKR_OK;
}
CK_RV YUBICO_get_slot_version(CK_VERSION_PTR version) {
@@ -251,21 +250,18 @@ CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_P
return CKR_MECHANISM_INVALID;
}
/*CK_RV YUBICO_get_token_objects_num(CK_ULONG_PTR num) {
*num = token_objects_num;
return CKR_OK;
}*/
#include <stdio.h>
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t *obj, CK_ULONG_PTR len) {
#include <stdio.h> // TODO: delete
static CK_RV get_objects(ykpiv_state *state, CK_BBOOL num_only, piv_obj_id_t *obj, CK_ULONG_PTR len) {
CK_BYTE buf[2048];
CK_ULONG buf_len;
piv_obj_id_t certs[4];
CK_ULONG n_cert = 0;
if (state == NULL || obj == NULL || len == NULL_PTR)
if (state == NULL || len == NULL_PTR)
return CKR_ARGUMENTS_BAD;
if (num_only == CK_FALSE && obj == NULL)
return CKR_ARGUMENTS_BAD;
buf_len = sizeof(buf);
@@ -293,10 +289,18 @@ CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t *obj, CK_ULO
if (ykpiv_fetch_object(state, YKPIV_OBJ_CARD_AUTH, buf, &buf_len) == YKPIV_OK) {
n_cert++;
certs[3] = PIV_CERT_OBJ_X509_CARD_AUTH;
fprintf(stderr, "Found CARD AUTH cert\n");
fprintf(stderr, "Found CARD AUTH cert (9e)\n");
}
if (n_cert + token_objects_num > *len)
fprintf(stderr, "The total number of objects for this token is %lu\n", n_cert + token_objects_num);
if (num_only == CK_TRUE) {
// We just want the number of objects
*len = n_cert + token_objects_num;
return CKR_OK;
}
if (*len < n_cert + token_objects_num)
return CKR_BUFFER_TOO_SMALL;
// Copy mandatory data objects
@@ -305,8 +309,13 @@ CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t *obj, CK_ULO
// Copy certificates
memcpy(obj + token_objects_num, certs, n_cert * sizeof(piv_obj_id_t));
*len = token_objects_num + n_cert;
fprintf(stderr, "The total number of objects for this token is %lu\n", *len);
return CKR_OK;
}
CK_RV YUBICO_get_token_objects_num(ykpiv_state *state, CK_ULONG_PTR num) {
return get_objects(state, CK_TRUE, NULL, num);
}
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t *obj, CK_ULONG num) {
return get_objects(state, CK_FALSE, obj, &num);
}
+2 -2
View File
@@ -18,7 +18,7 @@ CK_RV YUBICO_get_token_version(CK_UTF8CHAR_PTR v_str, CK_ULONG v_str_len, CK_VER
CK_RV YUBICO_get_token_mechanisms_num(CK_ULONG_PTR num);
CK_RV YUBICO_get_token_mechanism_list(CK_MECHANISM_TYPE_PTR mec, CK_ULONG num);
CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_PTR info);
//CK_RV YUBICO_get_token_objects_num(CK_ULONG_PTR num);
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t * obj, CK_ULONG_PTR num);
CK_RV YUBICO_get_token_objects_num(ykpiv_state *state, CK_ULONG_PTR num);
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t * obj, CK_ULONG num);
#endif