WIP port minidriver ykpiv_util_* functions
This commit is contained in:
+1
-1
@@ -32,7 +32,7 @@ AM_CPPFLAGS = $(OPENSSL_CFLAGS) $(PCSC_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libykpiv.la
|
||||
|
||||
libykpiv_la_SOURCES = ykpiv.c version.c ykpiv.pc.in ykpiv.map internal.h
|
||||
libykpiv_la_SOURCES = ykpiv.c util.c version.c ykpiv.pc.in ykpiv.map internal.h
|
||||
libykpiv_la_SOURCES += error.c
|
||||
libykpiv_la_includedir = $(includedir)/ykpiv
|
||||
libykpiv_la_include_HEADERS = ykpiv.h ykpiv-version.h
|
||||
|
||||
+39
-3
@@ -45,11 +45,32 @@
|
||||
#define READER_LEN 32
|
||||
#define MAX_READERS 16
|
||||
|
||||
#define DES_LEN_3DES 8*3
|
||||
#define CB_MGM_KEY DES_LEN_3DES
|
||||
|
||||
typedef void* (*ykpiv_pfn_alloc)(void* alloc_data, size_t size);
|
||||
typedef void* (*ykpiv_pfn_realloc)(void* alloc_data, void* address, size_t size);
|
||||
typedef void (*ykpiv_pfn_free)(void* alloc_data, void* address);
|
||||
typedef struct {
|
||||
ykpiv_pfn_alloc pfn_alloc;
|
||||
ykpiv_pfn_realloc pfn_realloc;
|
||||
ykpiv_pfn_free pfn_free;
|
||||
void * alloc_data;
|
||||
} ykpiv_allocator;
|
||||
|
||||
extern ykpiv_allocator _mem_default_allocator;
|
||||
|
||||
struct ykpiv_state {
|
||||
SCARDCONTEXT context;
|
||||
SCARDHANDLE card;
|
||||
int verbose;
|
||||
char *pin;
|
||||
|
||||
ykpiv_allocator allocator;
|
||||
bool isNEO;
|
||||
uint8_t mgmKey[CB_MGM_KEY];
|
||||
bool fMgmKeySet;
|
||||
|
||||
};
|
||||
|
||||
union u_APDU {
|
||||
@@ -66,8 +87,23 @@ union u_APDU {
|
||||
|
||||
typedef union u_APDU APDU;
|
||||
|
||||
unsigned const char aid[] = {
|
||||
0xa0, 0x00, 0x00, 0x03, 0x08
|
||||
};
|
||||
extern unsigned const char aid[];
|
||||
|
||||
// the object size is restricted to the firmware's message buffer size, which
|
||||
// always contains 0x5C + 1 byte len + 3 byte id + 0x53 + 3 byte len = 9 bytes,
|
||||
// so while the message buffer == CB_BUF_MAX, the maximum object we can store
|
||||
// is CB_BUF_MAX - 9
|
||||
#define CB_OBJ_MAX_NEO (CB_BUF_MAX_NEO - 9)
|
||||
#define CB_OBJ_MAX_YK4 (CB_BUF_MAX_YK4 - 9)
|
||||
#define CB_OBJ_MAX CB_OBJ_MAX_YK4
|
||||
|
||||
#define CB_BUF_MAX_NEO 2048
|
||||
#define CB_BUF_MAX_YK4 3072
|
||||
#define CB_BUF_MAX CB_BUF_MAX_YK4
|
||||
|
||||
#define CB_ATR_MAX 33
|
||||
|
||||
#define ATR_NEO_R3 "\x3b\xfc\x13\x00\x00\x81\x31\xfe\x15\x59\x75\x62\x69\x6b\x65\x79\x4e\x45\x4f\x72\x33\xe1"
|
||||
#define ATR_YK4 "\x3b\xf8\x13\x00\x00\x81\x31\xfe\x15\x59\x75\x62\x69\x6b\x65\x79\x34\xd4"
|
||||
|
||||
#endif
|
||||
|
||||
+1003
File diff suppressed because it is too large
Load Diff
+115
-30
@@ -44,6 +44,33 @@
|
||||
static ykpiv_rc send_data(ykpiv_state *state, APDU *apdu,
|
||||
unsigned char *data, unsigned long *recv_len, int *sw);
|
||||
|
||||
unsigned const char aid[] = {
|
||||
0xa0, 0x00, 0x00, 0x03, 0x08
|
||||
};
|
||||
|
||||
|
||||
static void* _default_alloc(void *data, size_t cb) {
|
||||
(void)data;
|
||||
return calloc(cb, 1);
|
||||
}
|
||||
|
||||
static void * _default_realloc(void *data, void *p, size_t cb) {
|
||||
(void)data;
|
||||
return realloc(p, cb);
|
||||
}
|
||||
|
||||
static void _default_free(void *data, void *p) {
|
||||
(void)data;
|
||||
free(p);
|
||||
}
|
||||
|
||||
ykpiv_allocator _default_allocator = {
|
||||
.pfn_alloc = _default_alloc,
|
||||
.pfn_realloc = _default_realloc,
|
||||
.pfn_free = _default_free,
|
||||
.alloc_data = 0
|
||||
};
|
||||
|
||||
static void dump_hex(const unsigned char *buf, unsigned int len) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
@@ -51,7 +78,7 @@ static void dump_hex(const unsigned char *buf, unsigned int len) {
|
||||
}
|
||||
}
|
||||
|
||||
static int set_length(unsigned char *buffer, size_t length) {
|
||||
int _ykpiv_set_length(unsigned char *buffer, size_t length) {
|
||||
if(length < 0x80) {
|
||||
*buffer++ = length;
|
||||
return 1;
|
||||
@@ -67,7 +94,7 @@ static int set_length(unsigned char *buffer, size_t length) {
|
||||
}
|
||||
}
|
||||
|
||||
static int get_length(const unsigned char *buffer, size_t *len) {
|
||||
int _ykpiv_get_length(const unsigned char *buffer, size_t *len) {
|
||||
if(buffer[0] < 0x81) {
|
||||
*len = buffer[0];
|
||||
return 1;
|
||||
@@ -96,19 +123,33 @@ static unsigned char *set_object(int object_id, unsigned char *buffer) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) {
|
||||
ykpiv_state *s = malloc(sizeof(ykpiv_state));
|
||||
if(s == NULL) {
|
||||
ykpiv_rc ykpiv_init_with_allocator(ykpiv_state **state, int verbose, const ykpiv_allocator *allocator) {
|
||||
ykpiv_state *s;
|
||||
if (NULL == state) {
|
||||
return YKPIV_GENERIC_ERROR;
|
||||
}
|
||||
if (NULL == allocator || !allocator->pfn_alloc || !allocator->pfn_realloc || !allocator->pfn_free) {
|
||||
return YKPIV_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
s = allocator->pfn_alloc(allocator->alloc_data, sizeof(ykpiv_state));
|
||||
if (NULL == s) {
|
||||
return YKPIV_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(ykpiv_state));
|
||||
s->pin = NULL;
|
||||
s->allocator = *allocator;
|
||||
s->verbose = verbose;
|
||||
s->context = SCARD_E_INVALID_HANDLE;
|
||||
s->context = SCARD_E_INVALID_HANDLE; // TREV TODO -1 on Windows
|
||||
*state = s;
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) {
|
||||
return ykpiv_init_with_allocator(state, verbose, &_default_allocator);
|
||||
}
|
||||
|
||||
ykpiv_rc ykpiv_done(ykpiv_state *state) {
|
||||
ykpiv_disconnect(state);
|
||||
free(state->pin);
|
||||
@@ -130,7 +171,7 @@ ykpiv_rc ykpiv_disconnect(ykpiv_state *state) {
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
static ykpiv_rc select_application(ykpiv_state *state) {
|
||||
ykpiv_rc _ykpiv_select_application(ykpiv_state *state) {
|
||||
APDU apdu;
|
||||
unsigned char data[0xff];
|
||||
unsigned long recv_len = sizeof(data);
|
||||
@@ -158,12 +199,32 @@ static ykpiv_rc select_application(ykpiv_state *state) {
|
||||
}
|
||||
}
|
||||
|
||||
ykpiv_rc _ykpiv_ensure_application_selected(ykpiv_state *state) {
|
||||
ykpiv_rc res = YKPIV_OK;
|
||||
|
||||
if (NULL == state) {
|
||||
return YKPIV_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
res = ykpiv_verify(state, NULL, 0);
|
||||
|
||||
if ((YKPIV_OK != res) && (YKPIV_WRONG_PIN != res)) {
|
||||
res = _ykpiv_select_application(state);
|
||||
}
|
||||
else {
|
||||
res = YKPIV_OK;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
||||
unsigned long active_protocol;
|
||||
char reader_buf[2048];
|
||||
size_t num_readers = sizeof(reader_buf);
|
||||
long rc;
|
||||
char *reader_ptr;
|
||||
SCARDHANDLE card = (SCARDHANDLE)-1;
|
||||
|
||||
ykpiv_rc ret = ykpiv_list_readers(state, reader_buf, &num_readers);
|
||||
if(ret != YKPIV_OK) {
|
||||
@@ -183,7 +244,7 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
||||
fprintf(stderr, "trying to connect to reader '%s'.\n", reader_ptr);
|
||||
}
|
||||
rc = SCardConnect(state->context, reader_ptr, SCARD_SHARE_SHARED,
|
||||
SCARD_PROTOCOL_T1, &state->card, &active_protocol);
|
||||
SCARD_PROTOCOL_T1, &card, &active_protocol);
|
||||
if(rc != SCARD_S_SUCCESS)
|
||||
{
|
||||
if(state->verbose) {
|
||||
@@ -191,7 +252,24 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (select_application(state) != YKPIV_OK) {
|
||||
|
||||
// if card handle has changed, determine if handle is valid (less efficient, but complete)
|
||||
if ((card != state->card)) {
|
||||
char reader[CB_BUF_MAX];
|
||||
uint32_t reader_len = (uint32_t)sizeof(reader);
|
||||
uint8_t atr[CB_ATR_MAX];
|
||||
uint32_t atr_len = (uint32_t)sizeof(atr);
|
||||
|
||||
// Cannot set the reader len to NULL. Confirmed in OSX 10.10, so we have to retrieve it even though we don't need it.
|
||||
if (SCARD_S_SUCCESS != SCardStatus(card, reader, &reader_len, NULL, NULL, atr, &atr_len)) {
|
||||
return YKPIV_PCSC_ERROR;
|
||||
}
|
||||
|
||||
state->isNEO = (((sizeof(ATR_NEO_R3) - 1) == atr_len) && (0 == memcmp(ATR_NEO_R3, atr, atr_len)));
|
||||
}
|
||||
state->card = card;
|
||||
|
||||
if (_ykpiv_select_application(state) != YKPIV_OK) {
|
||||
continue;
|
||||
}
|
||||
return YKPIV_OK;
|
||||
@@ -226,7 +304,7 @@ static ykpiv_rc reconnect(ykpiv_state *state) {
|
||||
}
|
||||
return YKPIV_PCSC_ERROR;
|
||||
}
|
||||
if ((res = select_application(state)) != YKPIV_OK) {
|
||||
if ((res = _ykpiv_select_application(state)) != YKPIV_OK) {
|
||||
return res;
|
||||
}
|
||||
if (state->pin) {
|
||||
@@ -279,7 +357,7 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) {
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
static ykpiv_rc begin_transaction(ykpiv_state *state) {
|
||||
ykpiv_rc _ykpiv_begin_transaction(ykpiv_state *state) {
|
||||
long rc;
|
||||
ykpiv_rc res;
|
||||
|
||||
@@ -299,7 +377,7 @@ static ykpiv_rc begin_transaction(ykpiv_state *state) {
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
static ykpiv_rc end_transaction(ykpiv_state *state) {
|
||||
ykpiv_rc _ykpiv_end_transaction(ykpiv_state *state) {
|
||||
long rc = SCardEndTransaction(state->card, SCARD_LEAVE_CARD);
|
||||
if(rc != SCARD_S_SUCCESS && state->verbose) {
|
||||
fprintf(stderr, "error: Failed to end pcsc transaction, rc=%08lx\n", rc);
|
||||
@@ -316,7 +394,7 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||
ykpiv_rc res;
|
||||
*out_len = 0;
|
||||
|
||||
res = begin_transaction(state);
|
||||
res = _ykpiv_begin_transaction(state);
|
||||
if (res != YKPIV_OK) {
|
||||
return res;
|
||||
}
|
||||
@@ -340,16 +418,16 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||
memcpy(apdu.st.data, in_ptr, this_size);
|
||||
res = send_data(state, &apdu, data, &recv_len, sw);
|
||||
if(res != YKPIV_OK) {
|
||||
end_transaction(state);
|
||||
_ykpiv_end_transaction(state);
|
||||
return res;
|
||||
} else if(*sw != SW_SUCCESS && *sw >> 8 != 0x61) {
|
||||
return end_transaction(state);
|
||||
return _ykpiv_end_transaction(state);
|
||||
}
|
||||
if(*out_len + recv_len - 2 > max_out) {
|
||||
if(state->verbose) {
|
||||
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.\n", *out_len + recv_len - 2, max_out);
|
||||
}
|
||||
end_transaction(state);
|
||||
_ykpiv_end_transaction(state);
|
||||
return YKPIV_SIZE_ERROR;
|
||||
}
|
||||
if(out_data) {
|
||||
@@ -372,10 +450,10 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||
apdu.st.ins = 0xc0;
|
||||
res = send_data(state, &apdu, data, &recv_len, sw);
|
||||
if(res != YKPIV_OK) {
|
||||
end_transaction(state);
|
||||
_ykpiv_end_transaction(state);
|
||||
return res;
|
||||
} else if(*sw != SW_SUCCESS && *sw >> 8 != 0x61) {
|
||||
return end_transaction(state);
|
||||
return _ykpiv_end_transaction(state);
|
||||
}
|
||||
if(*out_len + recv_len - 2 > max_out) {
|
||||
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.", *out_len + recv_len - 2, max_out);
|
||||
@@ -386,7 +464,7 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||
*out_len += recv_len - 2;
|
||||
}
|
||||
}
|
||||
return end_transaction(state);
|
||||
return _ykpiv_end_transaction(state);
|
||||
}
|
||||
|
||||
static ykpiv_rc send_data(ykpiv_state *state, APDU *apdu,
|
||||
@@ -430,6 +508,8 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
|
||||
|
||||
DES_key_schedule ks1, ks2, ks3;
|
||||
|
||||
// TREV TODO: default/derived key
|
||||
|
||||
/* set up our key */
|
||||
{
|
||||
const_DES_cblock key_tmp;
|
||||
@@ -639,11 +719,11 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
|
||||
}
|
||||
|
||||
*dataptr++ = 0x7c;
|
||||
dataptr += set_length(dataptr, in_len + bytes + 3);
|
||||
dataptr += _ykpiv_set_length(dataptr, in_len + bytes + 3);
|
||||
*dataptr++ = 0x82;
|
||||
*dataptr++ = 0x00;
|
||||
*dataptr++ = YKPIV_IS_EC(algorithm) && decipher ? 0x85 : 0x81;
|
||||
dataptr += set_length(dataptr, in_len);
|
||||
dataptr += _ykpiv_set_length(dataptr, in_len);
|
||||
memcpy(dataptr, sign_in, (size_t)in_len);
|
||||
dataptr += in_len;
|
||||
|
||||
@@ -670,7 +750,7 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
|
||||
return YKPIV_PARSE_ERROR;
|
||||
}
|
||||
dataptr = data + 1;
|
||||
dataptr += get_length(dataptr, &len);
|
||||
dataptr += _ykpiv_get_length(dataptr, &len);
|
||||
/* skip the 82 tag */
|
||||
if(*dataptr != 0x82) {
|
||||
if(state->verbose) {
|
||||
@@ -679,7 +759,7 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
|
||||
return YKPIV_PARSE_ERROR;
|
||||
}
|
||||
dataptr++;
|
||||
dataptr += get_length(dataptr, &len);
|
||||
dataptr += _ykpiv_get_length(dataptr, &len);
|
||||
if(len > *out_len) {
|
||||
if(state->verbose) {
|
||||
fprintf(stderr, "Wrong size on output buffer.\n");
|
||||
@@ -768,10 +848,10 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
|
||||
}
|
||||
return YKPIV_OK;
|
||||
} else if((sw >> 8) == 0x63) {
|
||||
*tries = (sw & 0xf);
|
||||
if (tries) *tries = (sw & 0xf);
|
||||
return YKPIV_WRONG_PIN;
|
||||
} else if(sw == SW_ERR_AUTH_BLOCKED) {
|
||||
*tries = 0;
|
||||
if (tries) *tries = 0;
|
||||
return YKPIV_WRONG_PIN;
|
||||
} else {
|
||||
return YKPIV_GENERIC_ERROR;
|
||||
@@ -869,7 +949,7 @@ ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
||||
|
||||
if(sw == SW_SUCCESS) {
|
||||
size_t outlen;
|
||||
int offs = get_length(data + 1, &outlen);
|
||||
int offs = _ykpiv_get_length(data + 1, &outlen);
|
||||
if(offs == 0) {
|
||||
return YKPIV_SIZE_ERROR;
|
||||
}
|
||||
@@ -884,6 +964,7 @@ ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
||||
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||
unsigned char *indata, size_t len) {
|
||||
|
||||
// TREV TODO: buffer sizes different in minidriver
|
||||
unsigned char data[3072];
|
||||
unsigned char *dataptr = data;
|
||||
unsigned char templ[] = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
||||
@@ -899,7 +980,7 @@ ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||
return YKPIV_INVALID_OBJECT;
|
||||
}
|
||||
*dataptr++ = 0x53;
|
||||
dataptr += set_length(dataptr, len);
|
||||
dataptr += _ykpiv_set_length(dataptr, len);
|
||||
memcpy(dataptr, indata, len);
|
||||
dataptr += len;
|
||||
|
||||
@@ -908,9 +989,13 @@ ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||
return res;
|
||||
}
|
||||
|
||||
if(sw == SW_SUCCESS) {
|
||||
if(SW_SUCCESS == sw) {
|
||||
return YKPIV_OK;
|
||||
} else {
|
||||
}
|
||||
else if (SW_ERR_SECURITY_STATUS == sw) {
|
||||
return YKPIV_AUTHENTICATION_ERROR;
|
||||
}
|
||||
else {
|
||||
return YKPIV_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1008,7 +1093,7 @@ ykpiv_rc ykpiv_import_private_key(ykpiv_state *state, const unsigned char key, u
|
||||
|
||||
for (i = 0; i < n_params; i++) {
|
||||
*in_ptr++ = param_tag + i;
|
||||
in_ptr += set_length(in_ptr, elem_len);
|
||||
in_ptr += _ykpiv_set_length(in_ptr, elem_len);
|
||||
padding = elem_len - lens[i];
|
||||
memset(in_ptr, 0, padding);
|
||||
in_ptr += padding;
|
||||
|
||||
+121
@@ -58,6 +58,9 @@ extern "C"
|
||||
YKPIV_INVALID_OBJECT = -11,
|
||||
YKPIV_ALGORITHM_ERROR = -12,
|
||||
YKPIV_PIN_LOCKED = -13,
|
||||
|
||||
YKPIV_ARGUMENT_ERROR = -14, //i.e. invalid input argument
|
||||
YKPIV_RANGE_ERROR = -15 //i.e. value range error
|
||||
} ykpiv_rc;
|
||||
|
||||
const char *ykpiv_strerror(ykpiv_rc err);
|
||||
@@ -220,6 +223,124 @@ extern "C"
|
||||
#define YKPIV_IS_EC(a) ((a == YKPIV_ALGO_ECCP256 || a == YKPIV_ALGO_ECCP384))
|
||||
#define YKPIV_IS_RSA(a) ((a == YKPIV_ALGO_RSA1024 || a == YKPIV_ALGO_RSA2048))
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// UTIL
|
||||
//
|
||||
|
||||
#define DEVTYPE_UNKNOWN 0x00000000
|
||||
#define DEVTYPE_NEO 0x4E450000 //"NE"
|
||||
#define DEVTYPE_YK 0x594B0000 //"YK"
|
||||
#define DEVTYPE_NEOr3 (DEVTYPE_NEO | 0x00007233) //"r3"
|
||||
#define DEVTYPE_YK4 (DEVTYPE_YK | 0x00000034) // "4"
|
||||
typedef uint32_t ykpiv_devmodel;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct _ykpiv_key {
|
||||
uint8_t slot;
|
||||
uint16_t cert_len;
|
||||
uint8_t cert[1];
|
||||
} ykpiv_key;
|
||||
|
||||
typedef struct _ykpiv_container {
|
||||
wchar_t name[40];
|
||||
uint8_t slot;
|
||||
uint8_t key_spec;
|
||||
uint16_t key_size_bits;
|
||||
uint8_t flags;
|
||||
uint8_t pin_id;
|
||||
uint8_t associated_echd_container;
|
||||
uint8_t cert_fingerprint[20];
|
||||
} ykpiv_container;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* Util api always allocates data on your behalf, if data = 0, *data != 0, or data_len = 0 an invalid parameter will be returned; to free data, call ykpiv_util_free(). */
|
||||
|
||||
/**
|
||||
* Free allocated data
|
||||
*
|
||||
* @param state state
|
||||
* @param data pointer to buffer allocated by ykpiv
|
||||
*
|
||||
* @return ypiv_rc error code
|
||||
*/
|
||||
ykpiv_rc ykpiv_util_free(ykpiv_state *state, void *data);
|
||||
|
||||
ykpiv_rc ykpiv_util_list_keys(ykpiv_state *state, uint8_t *key_count, ykpiv_key **data, size_t *data_len);
|
||||
ykpiv_rc ykpiv_util_read_cert(ykpiv_state *state, uint8_t slot, uint8_t **data, size_t *data_len);
|
||||
ykpiv_rc ykpiv_util_write_cert(ykpiv_state *state, uint8_t slot, uint8_t *data, size_t data_len);
|
||||
ykpiv_rc ykpiv_util_delete_cert(ykpiv_state *state, uint8_t slot);
|
||||
|
||||
/**
|
||||
* Generate Key
|
||||
*
|
||||
* @param state state
|
||||
* @param slot key slot
|
||||
* @param algorithm algorithm
|
||||
*
|
||||
* @return ykpiv_rc error code
|
||||
*
|
||||
* If algorithm is RSA1024 or RSA2048, the modulus, modulus_len, exp, and exp_len output parameters must be supplied. They are filled with with public modulus (big-endian), its size, the public exponent (big-endian), and its size respectively.
|
||||
* If algorithm is ECCP256 or ECCP384, the point and point_len output parameters must be supplied. They are filled with the public point (uncompressed octet-string encoded per SEC1 section 2.3.4)
|
||||
* If algorithm is ECCP256, the curve is always ANSI X9.62 Prime 256v1
|
||||
* If algorithm is ECCP384, the curve is always secp384r1
|
||||
*/
|
||||
ykpiv_rc ykpiv_util_generate_key(ykpiv_state *state, uint8_t slot, uint8_t algorithm, uint8_t pin_policy, uint8_t touch_policy, uint8_t **modulus, size_t *modulus_len, uint8_t **exp, size_t *exp_len, uint8_t **point, size_t *point_len);
|
||||
|
||||
ykpiv_rc ykpiv_util_read_mscmap(ykpiv_state *state, ykpiv_container **containers, size_t *n_containers);
|
||||
ykpiv_rc ykpiv_util_write_mscmap(ykpiv_state *state, ykpiv_container *containers, size_t n_containers);
|
||||
ykpiv_rc ykpiv_util_read_msroots(ykpiv_state *state, uint8_t **data, size_t *data_len);
|
||||
ykpiv_rc ykpiv_util_write_msroots(ykpiv_state *state, uint8_t *data, size_t data_len);
|
||||
|
||||
ykpiv_rc ykpiv_util_reset(ykpiv_state *state);
|
||||
|
||||
/**
|
||||
* Card identifier
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t data[16];
|
||||
} ykpiv_cardid;
|
||||
|
||||
/**
|
||||
* Get card identifier
|
||||
*
|
||||
* @param state state
|
||||
* @param cardid ykpiv_cardid return value
|
||||
*
|
||||
* @return ykpiv_rc error code
|
||||
*/
|
||||
ykpiv_rc ykpiv_util_get_cardid(ykpiv_state *state, ykpiv_cardid *cardid);
|
||||
|
||||
/**
|
||||
* Set card identifier
|
||||
*
|
||||
* The card must be authenticated to call this function.
|
||||
*
|
||||
* @param state state
|
||||
* @param cardid cardid to set, if NULL, randomly generate
|
||||
*
|
||||
* @return ypiv_rc error code
|
||||
*
|
||||
*/
|
||||
ykpiv_rc ykpiv_util_set_cardid(ykpiv_state *state, const ykpiv_cardid *cardid);
|
||||
|
||||
/**
|
||||
* Get device model
|
||||
*
|
||||
* The card must be connected to call this function.
|
||||
*
|
||||
* @param state state
|
||||
*
|
||||
* @return device model
|
||||
*
|
||||
*/
|
||||
ykpiv_devmodel ykpiv_util_devicemodel(ykpiv_state *state);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user