refactor writing object to it's own library function
ykpiv_save_object(), use that for writing certs
This commit is contained in:
+57
-14
@@ -80,6 +80,19 @@ static int get_length(const unsigned char *buffer, size_t *len) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char *set_object(int object_id, unsigned char *buffer) {
|
||||||
|
if(object_id == YKPIV_OBJ_DISCOVERY) {
|
||||||
|
*buffer++ = 1;
|
||||||
|
*buffer++ = YKPIV_OBJ_DISCOVERY;
|
||||||
|
} else if(object_id > 0xffff && object_id <= 0xffffff) {
|
||||||
|
*buffer++ = 3;
|
||||||
|
*buffer++ = (object_id >> 16) & 0xff;
|
||||||
|
*buffer++ = (object_id >> 8) & 0xff;
|
||||||
|
*buffer++ = object_id & 0xff;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) {
|
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) {
|
||||||
ykpiv_state *s = malloc(sizeof(ykpiv_state));
|
ykpiv_state *s = malloc(sizeof(ykpiv_state));
|
||||||
if(s == NULL) {
|
if(s == NULL) {
|
||||||
@@ -633,25 +646,17 @@ ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
|||||||
unsigned char *data, unsigned long *len) {
|
unsigned char *data, unsigned long *len) {
|
||||||
int sw;
|
int sw;
|
||||||
unsigned char indata[5];
|
unsigned char indata[5];
|
||||||
|
unsigned char *inptr = indata;
|
||||||
unsigned char templ[] = {0, YKPIV_INS_GET_DATA, 0x3f, 0xff};
|
unsigned char templ[] = {0, YKPIV_INS_GET_DATA, 0x3f, 0xff};
|
||||||
long inlen = 5;
|
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
|
|
||||||
indata[0] = 0x5c;
|
*inptr++ = 0x5c;
|
||||||
if(object_id == YKPIV_OBJ_DISCOVERY) {
|
inptr = set_object(object_id, inptr);
|
||||||
indata[1] = 1;
|
if(inptr == NULL) {
|
||||||
indata[2] = YKPIV_OBJ_DISCOVERY;
|
|
||||||
inlen = 3;
|
|
||||||
} else if(object_id > 0xffff && object_id <= 0xffffff) {
|
|
||||||
indata[1] = 3;
|
|
||||||
indata[2] = (object_id >> 16) & 0xff;
|
|
||||||
indata[3] = (object_id >> 8) & 0xff;
|
|
||||||
indata[4] = object_id & 0xff;
|
|
||||||
} else {
|
|
||||||
return YKPIV_INVALID_OBJECT;
|
return YKPIV_INVALID_OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((res = ykpiv_transfer_data(state, templ, indata, inlen, data, len, &sw))
|
if((res = ykpiv_transfer_data(state, templ, indata, inptr - indata, data, len, &sw))
|
||||||
!= YKPIV_OK) {
|
!= YKPIV_OK) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -662,5 +667,43 @@ ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
|||||||
memmove(data, data + 1 + offs, outlen);
|
memmove(data, data + 1 + offs, outlen);
|
||||||
*len = outlen;
|
*len = outlen;
|
||||||
}
|
}
|
||||||
return YKPIV_OK;
|
if(sw == 0x9000) {
|
||||||
|
return YKPIV_OK;
|
||||||
|
} else {
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||||
|
unsigned char *indata, size_t len) {
|
||||||
|
|
||||||
|
unsigned char data[2048];
|
||||||
|
unsigned char *dataptr = data;
|
||||||
|
unsigned char templ[] = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
||||||
|
int sw;
|
||||||
|
ykpiv_rc res;
|
||||||
|
|
||||||
|
if(len > sizeof(data) - 9) {
|
||||||
|
return YKPIV_SIZE_ERROR;
|
||||||
|
}
|
||||||
|
*dataptr++ = 0x5c;
|
||||||
|
dataptr = set_object(object_id, dataptr);
|
||||||
|
if(dataptr == NULL) {
|
||||||
|
return YKPIV_INVALID_OBJECT;
|
||||||
|
}
|
||||||
|
*dataptr++ = 0x53;
|
||||||
|
dataptr += set_length(dataptr, len);
|
||||||
|
memcpy(dataptr, indata, len);
|
||||||
|
dataptr += len;
|
||||||
|
|
||||||
|
if((res = ykpiv_transfer_data(state, templ, data, dataptr - data, NULL, 0,
|
||||||
|
&sw)) != YKPIV_OK) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sw == 0x9000) {
|
||||||
|
return YKPIV_OK;
|
||||||
|
} else {
|
||||||
|
return YKPIV_GENERIC_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ extern "C"
|
|||||||
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries);
|
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries);
|
||||||
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
|
||||||
unsigned char *data, unsigned long *len);
|
unsigned char *data, unsigned long *len);
|
||||||
|
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
||||||
|
unsigned char *indata, size_t len);
|
||||||
|
|
||||||
#define YKPIV_ALGO_3DES 0x03
|
#define YKPIV_ALGO_3DES 0x03
|
||||||
#define YKPIV_ALGO_RSA1024 0x06
|
#define YKPIV_ALGO_RSA1024 0x06
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ global:
|
|||||||
ykpiv_get_version;
|
ykpiv_get_version;
|
||||||
ykpiv_verify;
|
ykpiv_verify;
|
||||||
ykpiv_fetch_object;
|
ykpiv_fetch_object;
|
||||||
|
ykpiv_save_object;
|
||||||
|
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
|
|||||||
+4
-25
@@ -377,7 +377,6 @@ static bool import_cert(ykpiv_state *state, enum enum_key_format cert_format,
|
|||||||
X509 *cert = NULL;
|
X509 *cert = NULL;
|
||||||
PKCS12 *p12 = NULL;
|
PKCS12 *p12 = NULL;
|
||||||
EVP_PKEY *private_key = NULL;
|
EVP_PKEY *private_key = NULL;
|
||||||
int object = get_object_id(slot);
|
|
||||||
|
|
||||||
input_file = open_file(input_file_name, INPUT);
|
input_file = open_file(input_file_name, INPUT);
|
||||||
if(!input_file) {
|
if(!input_file) {
|
||||||
@@ -409,31 +408,14 @@ static bool import_cert(ykpiv_state *state, enum enum_key_format cert_format,
|
|||||||
{
|
{
|
||||||
unsigned char certdata[2100];
|
unsigned char certdata[2100];
|
||||||
unsigned char *certptr = certdata;
|
unsigned char *certptr = certdata;
|
||||||
unsigned char data[0xff];
|
int object = get_object_id(slot);
|
||||||
unsigned char templ[] = {0, YKPIV_INS_PUT_DATA, 0x3f, 0xff};
|
|
||||||
unsigned long recv_len = sizeof(data);
|
|
||||||
int cert_len = i2d_X509(cert, NULL);
|
int cert_len = i2d_X509(cert, NULL);
|
||||||
int bytes;
|
ykpiv_rc res;
|
||||||
int sw;
|
|
||||||
|
|
||||||
if(cert_len > 2048) {
|
if(cert_len > 2048) {
|
||||||
fprintf(stderr, "Certificate to large, maximum 2048 bytes (was %d bytes).\n", cert_len);
|
fprintf(stderr, "Certificate to large, maximum 2048 bytes (was %d bytes).\n", cert_len);
|
||||||
goto import_cert_out;
|
goto import_cert_out;
|
||||||
}
|
}
|
||||||
*certptr++ = 0x5c;
|
|
||||||
*certptr++ = 0x03;
|
|
||||||
*certptr++ = (object >> 16) & 0xff;
|
|
||||||
*certptr++ = (object >> 8) & 0xff;
|
|
||||||
*certptr++ = object & 0xff;
|
|
||||||
*certptr++ = 0x53;
|
|
||||||
if(cert_len < 0x80) {
|
|
||||||
bytes = 1;
|
|
||||||
} else if(cert_len < 0xff) {
|
|
||||||
bytes = 2;
|
|
||||||
} else {
|
|
||||||
bytes = 3;
|
|
||||||
}
|
|
||||||
certptr += set_length(certptr, cert_len + bytes + 6);
|
|
||||||
*certptr++ = 0x70;
|
*certptr++ = 0x70;
|
||||||
certptr += set_length(certptr, cert_len);
|
certptr += set_length(certptr, cert_len);
|
||||||
/* i2d_X509 increments certptr here.. */
|
/* i2d_X509 increments certptr here.. */
|
||||||
@@ -444,11 +426,8 @@ static bool import_cert(ykpiv_state *state, enum enum_key_format cert_format,
|
|||||||
*certptr++ = 0xfe; /* LRC */
|
*certptr++ = 0xfe; /* LRC */
|
||||||
*certptr++ = 0;
|
*certptr++ = 0;
|
||||||
|
|
||||||
if(ykpiv_transfer_data(state, templ, certdata, certptr - certdata, data,
|
if((res = ykpiv_save_object(state, object, certdata, (size_t)(certptr - certdata))) != YKPIV_OK) {
|
||||||
&recv_len, &sw) != YKPIV_OK) {
|
fprintf(stderr, "Failed commands with device: %s\n", ykpiv_strerror(res));
|
||||||
fprintf(stderr, "Failed commands with device.\n");
|
|
||||||
} else if(sw != 0x9000) {
|
|
||||||
fprintf(stderr, "Failed loading certificate to device with code %x.\n", sw);
|
|
||||||
} else {
|
} else {
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user