Started major overhaul of slot vendors and token vendors.
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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
@@ -1,4 +1,5 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
CK_BBOOL has_token(const ykcs11_slot_t *slot) {
|
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) {
|
ykcs11_slot_t *slots, CK_ULONG_PTR n_slots, CK_ULONG_PTR n_with_token) {
|
||||||
|
|
||||||
CK_BYTE i;
|
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));
|
strncpy(slots[*n_slots].info.slotDescription, p, sizeof(slots[*n_slots].info.slotDescription));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Supported slot
|
||||||
vendor = get_vendor(slots[*n_slots].vid);
|
vendor = get_vendor(slots[*n_slots].vid);
|
||||||
|
|
||||||
// Values must NOT be null terminated and ' ' padded
|
// 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;
|
s = slots[*n_slots].info.slotDescription;
|
||||||
l = sizeof(slots[*n_slots].info.slotDescription);
|
l = sizeof(slots[*n_slots].info.slotDescription);
|
||||||
if (vendor.get_slot_description(s, l) != CKR_OK)
|
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));
|
memset(slots[*n_slots].info.manufacturerID, ' ', sizeof(slots[*n_slots].info.manufacturerID));
|
||||||
s = slots[*n_slots].info.manufacturerID;
|
s = slots[*n_slots].info.manufacturerID;
|
||||||
l = sizeof(slots[*n_slots].info.manufacturerID);
|
l = sizeof(slots[*n_slots].info.manufacturerID);
|
||||||
if(vendor.get_slot_manufacturer(s, l) != CKR_OK)
|
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)
|
if (vendor.get_slot_flags(&slots[*n_slots].info.flags) != CKR_OK)
|
||||||
return CK_FALSE;
|
goto failure;
|
||||||
|
|
||||||
// Treating hw and fw version the same
|
// Treating hw and fw version the same
|
||||||
if (vendor.get_slot_version(&slots[*n_slots].info.hardwareVersion) != CKR_OK)
|
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)
|
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)++;
|
(*n_with_token)++;
|
||||||
|
|
||||||
|
if (create_token(p, slots + *n_slots) != CKR_OK)
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(*n_slots)++;
|
(*n_slots)++;
|
||||||
p += i + 1;
|
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
@@ -1,16 +1,11 @@
|
|||||||
#ifndef UTILS_H
|
#ifndef UTILS_H
|
||||||
#define UTILS_H
|
#define UTILS_H
|
||||||
|
|
||||||
#include "pkcs11t.h"
|
#include "ykcs11.h"
|
||||||
#include "vendors.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
vendor_id_t vid;
|
|
||||||
CK_SLOT_INFO info;
|
|
||||||
} ykcs11_slot_t; // TODO: move this
|
|
||||||
|
|
||||||
CK_BBOOL has_token(const ykcs11_slot_t *slot);
|
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);
|
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
|
#endif
|
||||||
|
|||||||
+2
-2
@@ -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_mechanisms_num = YUBICO_get_token_mechanisms_num;
|
||||||
v.get_token_mechanism_list = YUBICO_get_token_mechanism_list;
|
v.get_token_mechanism_list = YUBICO_get_token_mechanism_list;
|
||||||
v.get_token_mechanism_info = YUBICO_get_token_mechanism_info;
|
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;
|
v.get_token_object_list = YUBICO_get_token_object_list;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ vendor_t get_vendor(vendor_id_t vid) {
|
|||||||
v.get_token_mechanisms_num = NULL;
|
v.get_token_mechanisms_num = NULL;
|
||||||
v.get_token_mechanism_list = NULL;
|
v.get_token_mechanism_list = NULL;
|
||||||
v.get_token_mechanism_info = 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;
|
v.get_token_object_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -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_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_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_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_objects_num_f)(ykpiv_state *, 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_object_list_f)(ykpiv_state *, piv_obj_id_t *, CK_ULONG);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -41,7 +41,7 @@ typedef struct {
|
|||||||
get_t_mechanisms_num_f get_token_mechanisms_num;
|
get_t_mechanisms_num_f get_token_mechanisms_num;
|
||||||
get_t_mechanism_list_f get_token_mechanism_list;
|
get_t_mechanism_list_f get_token_mechanism_list;
|
||||||
get_t_mechanism_info_f get_token_mechanism_info;
|
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;
|
get_t_object_list_f get_token_object_list;
|
||||||
} vendor_t;
|
} vendor_t;
|
||||||
|
|
||||||
|
|||||||
+123
-120
@@ -1,8 +1,10 @@
|
|||||||
|
#include "ykcs11.h"
|
||||||
#include "pkcs11.h"
|
#include "pkcs11.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <ykpiv.h>
|
#include <ykpiv.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "vendors.h"
|
//#include "vendors.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#define D(x) do { \
|
#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 = 0;
|
||||||
static CK_ULONG n_slots_with_token = 0;
|
static CK_ULONG n_slots_with_token = 0;
|
||||||
|
|
||||||
static CK_SESSION_HANDLE session = CK_INVALID_HANDLE; // TODO: support multiple sessions?
|
static ykcs11_session_t session; // TODO: support multiple sessions?
|
||||||
static CK_SESSION_INFO session_info;
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
CK_BBOOL active;
|
CK_BBOOL active;
|
||||||
@@ -54,8 +55,8 @@ static struct {
|
|||||||
piv_obj_id_t *objects;
|
piv_obj_id_t *objects;
|
||||||
} find_obj;
|
} 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 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 CK_ULONG n_token_objects = 0;*/
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
CK_BBOOL active;
|
CK_BBOOL active;
|
||||||
@@ -236,8 +237,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(
|
|||||||
{
|
{
|
||||||
DIN;
|
DIN;
|
||||||
CK_VERSION ver = {0, 0};
|
CK_VERSION ver = {0, 0};
|
||||||
vendor_id_t vid;
|
vendor_t token_vendor;
|
||||||
vendor_t vendor;
|
|
||||||
CK_BYTE buf[64];
|
CK_BYTE buf[64];
|
||||||
|
|
||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
@@ -246,10 +246,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(
|
|||||||
if (slotID >= n_slots)
|
if (slotID >= n_slots)
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
vid = slots[slotID].vid;
|
if (slots[slotID].vid == UNKNOWN) {
|
||||||
|
DBG(("No support for slot %lu", slotID));
|
||||||
if (vid == UNKNOWN) {
|
|
||||||
DBG(("No support for token in slot %lu", slotID));
|
|
||||||
return CKR_TOKEN_NOT_RECOGNIZED;
|
return CKR_TOKEN_NOT_RECOGNIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,58 +256,30 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(
|
|||||||
return CKR_TOKEN_NOT_PRESENT;
|
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));
|
token_vendor = get_vendor(slots[slotID].token->vid);
|
||||||
if (vendor.get_token_label(pInfo->label, sizeof(pInfo->label)) != CKR_OK)
|
|
||||||
return CKR_FUNCTION_FAILED;
|
|
||||||
|
|
||||||
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->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->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->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->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->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->ulMinPinLen = PIV_MIN_PIN_LEN; // minimum length in bytes of the PIN
|
||||||
|
|
||||||
pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
|
pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
|
||||||
|
|
||||||
pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
|
pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
|
||||||
|
|
||||||
pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
|
pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
|
||||||
|
|
||||||
pInfo->ulFreePrivateMemory = 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;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
@@ -406,7 +376,6 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)(
|
|||||||
if (vendor.get_token_mechanism_info(type, pInfo) != CKR_OK)
|
if (vendor.get_token_mechanism_info(type, pInfo) != CKR_OK)
|
||||||
return CKR_MECHANISM_INVALID;
|
return CKR_MECHANISM_INVALID;
|
||||||
|
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
@@ -459,7 +428,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
|
|||||||
{
|
{
|
||||||
DIN;
|
DIN;
|
||||||
|
|
||||||
vendor_t vendor;
|
vendor_t token_vendor;
|
||||||
|
|
||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
@@ -468,6 +437,11 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
|
|||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
if (slots[slotID].vid == UNKNOWN) {
|
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));
|
DBG(("No support for token in slot %lu", slotID));
|
||||||
return CKR_TOKEN_NOT_RECOGNIZED;
|
return CKR_TOKEN_NOT_RECOGNIZED;
|
||||||
}
|
}
|
||||||
@@ -477,44 +451,59 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(
|
|||||||
return CKR_TOKEN_NOT_PRESENT;
|
return CKR_TOKEN_NOT_PRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor = get_vendor(slots[slotID].vid); // TODO: make a token field in slot_t ?
|
if (session.handle != CK_INVALID_HANDLE) {
|
||||||
|
|
||||||
// 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) {
|
|
||||||
DBG(("A session with this or another token already exists"));
|
DBG(("A session with this or another token already exists"));
|
||||||
return CKR_SESSION_COUNT;
|
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;
|
token_vendor = get_vendor(slots[slotID].token->vid);
|
||||||
session_info.slotID = slotID;
|
|
||||||
// TODO: KEEP TRACK OF THE APPLICATION
|
// 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)) {
|
if ((flags & CKF_RW_SESSION)) {
|
||||||
// R/W 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 {
|
else {
|
||||||
// R/O Session
|
// 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.flags = flags;
|
||||||
session_info.ulDeviceError = 0;
|
session.info.ulDeviceError = 0;
|
||||||
|
|
||||||
*phSession = session;
|
session.handle = YKCS11_SESSION_ID;
|
||||||
|
// TODO: KEEP TRACK OF THE APPLICATION
|
||||||
|
|
||||||
|
*phSession = session.handle;
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
@@ -529,16 +518,21 @@ CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(
|
|||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session == CK_INVALID_HANDLE) {
|
if (session.handle == CK_INVALID_HANDLE) {
|
||||||
DBG(("There is no existing session"));
|
DBG(("There is no existing session"));
|
||||||
return CKR_SESSION_CLOSED;
|
return CKR_SESSION_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hSession != YKCS11_SESSION_ID)
|
if (hSession != YKCS11_SESSION_ID) {
|
||||||
|
DBG(("Unknown session %lu", hSession));
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
session = CK_INVALID_HANDLE;
|
free(session.slot->token->objects); // TODO: make objects survive a session so there is no need to get them again?
|
||||||
memset(&session_info, 0, sizeof(CK_SESSION_INFO));
|
session.slot->token->objects = NULL;
|
||||||
|
|
||||||
|
memset(&session, 0, sizeof(ykcs11_session_t));
|
||||||
|
session.handle = CK_INVALID_HANDLE;
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
@@ -549,18 +543,18 @@ CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
DIN;
|
DIN;
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session_info.slotID != slotID)
|
if (session.slot != slots + slotID)
|
||||||
return CKR_SLOT_ID_INVALID;
|
return CKR_SLOT_ID_INVALID;
|
||||||
|
|
||||||
session = CK_INVALID_HANDLE;
|
rv = C_CloseSession(session.handle);
|
||||||
memset(&session_info, 0, sizeof(CK_SESSION_INFO)); // TODO: Better to call close session?
|
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(
|
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(
|
||||||
@@ -576,10 +570,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)(
|
|||||||
if (pInfo == NULL)
|
if (pInfo == NULL)
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
memcpy(pInfo, &session_info, sizeof(CK_SESSION_INFO));
|
memcpy(pInfo, &session.info, sizeof(CK_SESSION_INFO));
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
@@ -635,25 +629,25 @@ CK_DEFINE_FUNCTION(CK_RV, C_Login)(
|
|||||||
|
|
||||||
DBG(("user %lu, pin %s, pinlen %lu", userType, pPin, ulPinLen));
|
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;
|
return CKR_SESSION_CLOSED;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
if (userType != CKU_SO &&
|
if (userType != CKU_SO && // TODO: what can SO do?
|
||||||
userType != CKU_USER &&
|
userType != CKU_USER &&
|
||||||
userType != CKU_CONTEXT_SPECIFIC)
|
userType != CKU_CONTEXT_SPECIFIC)
|
||||||
return CKR_USER_TYPE_INVALID;
|
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"));
|
DBG(("Tried to log-in to a read-only session"));
|
||||||
return CKR_SESSION_READ_ONLY_EXISTS;
|
return CKR_SESSION_READ_ONLY_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (userType) {
|
switch (userType) {
|
||||||
case CKU_USER:
|
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;
|
return CKR_USER_ALREADY_LOGGED_IN;
|
||||||
|
|
||||||
tries = 0;
|
tries = 0;
|
||||||
@@ -747,10 +741,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)(
|
|||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session != YKCS11_SESSION_ID)
|
if (session.handle != YKCS11_SESSION_ID)
|
||||||
return CKR_SESSION_CLOSED;
|
return CKR_SESSION_CLOSED;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
if (pTemplate == NULL_PTR || ulCount == 0)
|
if (pTemplate == NULL_PTR || ulCount == 0)
|
||||||
@@ -800,25 +794,28 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(
|
|||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session != YKCS11_SESSION_ID)
|
if (session.handle != YKCS11_SESSION_ID)
|
||||||
return CKR_SESSION_CLOSED;
|
return CKR_SESSION_CLOSED;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID; // TODO: or session closed?
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
if (find_obj.active == CK_TRUE)
|
if (find_obj.active == CK_TRUE)
|
||||||
return CKR_OPERATION_ACTIVE;
|
return CKR_OPERATION_ACTIVE;
|
||||||
|
|
||||||
if (slots[session_info.slotID].vid == UNKNOWN) {
|
//vendor = get_vendor(slots[session_info.slotID].vid); // TODO: make a token field in slot_t ?;
|
||||||
DBG(("Slot %lu is tokenless/unsupported", session_info.slotID));
|
|
||||||
return CKR_SLOT_ID_INVALID;
|
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.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) {
|
if (ulCount == 0) {
|
||||||
DBG(("Find ALL the objects!"));
|
DBG(("Find ALL the objects!"));
|
||||||
@@ -832,15 +829,15 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(
|
|||||||
find_obj.active = CK_FALSE;
|
find_obj.active = CK_FALSE;
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ulCount; i++) {
|
for (i = 0; i < ulCount; i++) {
|
||||||
DBG(("Parameter %lu\nType: %lu Value: %lu Len: %lu", i, pTemplate[i].type, *((CK_ULONG_PTR)pTemplate[i].pValue), pTemplate[i].ulValueLen));
|
DBG(("Parameter %lu\nType: %lu Value: %lu Len: %lu", i, pTemplate[i].type, *((CK_ULONG_PTR)pTemplate[i].pValue), pTemplate[i].ulValueLen));
|
||||||
// TODO: remove objects that don't match
|
// 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.num = 1;
|
||||||
find_obj.objects = token_objects + 3;
|
find_obj.objects = session.slot->token->objects + 3;
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
@@ -858,10 +855,10 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)(
|
|||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session != YKCS11_SESSION_ID)
|
if (session.handle != YKCS11_SESSION_ID)
|
||||||
return CKR_SESSION_CLOSED;
|
return CKR_SESSION_CLOSED;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
if (phObject == NULL_PTR ||
|
if (phObject == NULL_PTR ||
|
||||||
@@ -885,7 +882,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)(
|
|||||||
*pulObjectCount = 1;
|
*pulObjectCount = 1;
|
||||||
|
|
||||||
DBG(("Returning object %lu", *phObject));
|
DBG(("Returning object %lu", *phObject));
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,15 +895,18 @@ CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)(
|
|||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session != YKCS11_SESSION_ID)
|
if (session.handle != YKCS11_SESSION_ID)
|
||||||
return CKR_SESSION_CLOSED;
|
return CKR_SESSION_CLOSED;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
if (find_obj.active != CK_TRUE)
|
if (find_obj.active != CK_TRUE)
|
||||||
return CKR_OPERATION_NOT_INITIALIZED;
|
return CKR_OPERATION_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
free(find_obj.objects);
|
||||||
|
find_obj.objects = NULL;
|
||||||
|
|
||||||
find_obj.active = CK_FALSE;
|
find_obj.active = CK_FALSE;
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
@@ -1088,24 +1088,27 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
|
|||||||
if (piv_state == NULL)
|
if (piv_state == NULL)
|
||||||
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
|
||||||
if (session != YKCS11_SESSION_ID)
|
if (session.handle != YKCS11_SESSION_ID)
|
||||||
return CKR_SESSION_CLOSED;
|
return CKR_SESSION_CLOSED;
|
||||||
|
|
||||||
if (hSession != session)
|
if (hSession != session.handle)
|
||||||
return CKR_SESSION_HANDLE_INVALID;
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
|
||||||
if (pMechanism == NULL_PTR ||
|
if (pMechanism == NULL_PTR ||
|
||||||
hKey == NULL_PTR)
|
hKey == NULL_PTR)
|
||||||
return CKR_ARGUMENTS_BAD;
|
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;
|
sign_info.active = CK_TRUE;
|
||||||
memcpy(&sign_info.mechanism, pMechanism, sizeof(CK_MECHANISM));
|
memcpy(&sign_info.mechanism, pMechanism, sizeof(CK_MECHANISM));
|
||||||
sign_info.key = hKey;
|
sign_info.key = hKey;
|
||||||
// TODO: also allocate some space for the signature
|
// TODO: also allocate some space for the signature
|
||||||
|
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
@@ -1132,27 +1135,27 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
|
|
||||||
if (sign_info.active == CK_FALSE)
|
if (sign_info.active == CK_FALSE)
|
||||||
return CKR_OPERATION_NOT_INITIALIZED;
|
return CKR_OPERATION_NOT_INITIALIZED;
|
||||||
|
|
||||||
// TODO: check conditions
|
// TODO: check conditions
|
||||||
char test_buf[] = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20\xa7\x47\x16\x1b\x15\x5f\xd0\x05\xbc\xbe\x84\x4a\x28\xa9\x6c\x74\xfe\xf6\x6a\x42\x84\xa0\x4e\x05\x7a\x0c\x88\xe2\xc8\x83\xc0\x00";
|
char test_buf[] = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20\xa7\x47\x16\x1b\x15\x5f\xd0\x05\xbc\xbe\x84\x4a\x28\xa9\x6c\x74\xfe\xf6\x6a\x42\x84\xa0\x4e\x05\x7a\x0c\x88\xe2\xc8\x83\xc0\x00";
|
||||||
CK_ULONG sig_len_in = sizeof(test_buf) - 1;
|
CK_ULONG sig_len_in = sizeof(test_buf) - 1;
|
||||||
CK_ULONG sig_len_out = 1024;
|
CK_ULONG sig_len_out = 1024;
|
||||||
ykpiv_rc r;
|
ykpiv_rc r;
|
||||||
CK_CHAR key;
|
CK_CHAR key;
|
||||||
|
|
||||||
DBG(("Sending %lu bytes to sign", /*ulDataLen*/sig_len_in));
|
DBG(("Sending %lu bytes to sign", ulDataLen/*sig_len_in*/));
|
||||||
dump_hex(test_buf, sig_len_in, stderr, CK_TRUE);
|
dump_hex(pData, ulDataLen, stderr, CK_TRUE);
|
||||||
|
|
||||||
if (sign_info.key == PIV_DATA_OBJ_X509_PIV_AUTH) {
|
if (sign_info.key == PIV_DATA_OBJ_X509_PIV_AUTH) {
|
||||||
key = YKPIV_KEY_AUTHENTICATION;
|
key = YKPIV_KEY_AUTHENTICATION;
|
||||||
DBG(("Using key 9a"));
|
DBG(("Using key 9a"));
|
||||||
}
|
}
|
||||||
else {
|
else { // TODO: test what happens if there is no key on the card
|
||||||
key = YKPIV_KEY_SIGNATURE;
|
key = YKPIV_KEY_SIGNATURE;
|
||||||
DBG(("Using key 9c"));
|
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) {
|
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)));
|
DBG(("Sign error %s", ykpiv_strerror(r)));
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -29,6 +29,7 @@ YKCS11_0.1.0
|
|||||||
global:
|
global:
|
||||||
C_Initialize;
|
C_Initialize;
|
||||||
C_GetFunctionList;
|
C_GetFunctionList;
|
||||||
|
# TODO: add more here
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
+24
-15
@@ -132,7 +132,6 @@ CK_RV YUBICO_get_slot_flags(CK_FLAGS_PTR flags) {
|
|||||||
*flags = slot_flags;
|
*flags = slot_flags;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV YUBICO_get_slot_version(CK_VERSION_PTR version) {
|
CK_RV YUBICO_get_slot_version(CK_VERSION_PTR version) {
|
||||||
@@ -251,23 +250,20 @@ CK_RV YUBICO_get_token_mechanism_info(CK_MECHANISM_TYPE mec, CK_MECHANISM_INFO_P
|
|||||||
return CKR_MECHANISM_INVALID;
|
return CKR_MECHANISM_INVALID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#include <stdio.h> // TODO: delete
|
||||||
/*CK_RV YUBICO_get_token_objects_num(CK_ULONG_PTR num) {
|
static CK_RV get_objects(ykpiv_state *state, CK_BBOOL num_only, piv_obj_id_t *obj, CK_ULONG_PTR len) {
|
||||||
|
|
||||||
*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) {
|
|
||||||
CK_BYTE buf[2048];
|
CK_BYTE buf[2048];
|
||||||
CK_ULONG buf_len;
|
CK_ULONG buf_len;
|
||||||
|
|
||||||
piv_obj_id_t certs[4];
|
piv_obj_id_t certs[4];
|
||||||
CK_ULONG n_cert = 0;
|
CK_ULONG n_cert = 0;
|
||||||
|
|
||||||
if (state == NULL || obj == NULL || len == NULL_PTR)
|
if (state == NULL || len == NULL_PTR)
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
|
if (num_only == CK_FALSE && obj == NULL)
|
||||||
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
buf_len = sizeof(buf);
|
buf_len = sizeof(buf);
|
||||||
if (ykpiv_fetch_object(state, YKPIV_OBJ_AUTHENTICATION, buf, &buf_len) == YKPIV_OK) {
|
if (ykpiv_fetch_object(state, YKPIV_OBJ_AUTHENTICATION, buf, &buf_len) == YKPIV_OK) {
|
||||||
n_cert++;
|
n_cert++;
|
||||||
@@ -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) {
|
if (ykpiv_fetch_object(state, YKPIV_OBJ_CARD_AUTH, buf, &buf_len) == YKPIV_OK) {
|
||||||
n_cert++;
|
n_cert++;
|
||||||
certs[3] = PIV_CERT_OBJ_X509_CARD_AUTH;
|
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;
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
// Copy mandatory data objects
|
// 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
|
// Copy certificates
|
||||||
memcpy(obj + token_objects_num, certs, n_cert * sizeof(piv_obj_id_t));
|
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;
|
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
@@ -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_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_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_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_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_PTR num);
|
CK_RV YUBICO_get_token_object_list(ykpiv_state *state, piv_obj_id_t * obj, CK_ULONG num);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user