Add gzip support to ykpiv_util_import_certificate(), and use in yubico-piv-tool
This commit is contained in:
+3
-3
@@ -145,7 +145,7 @@ START_TEST(test_read_write_list_delete_cert) {
|
|||||||
size_t read_cert_len = 0;
|
size_t read_cert_len = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
res = ykpiv_util_write_cert(g_state, YKPIV_KEY_AUTHENTICATION, (uint8_t*)g_cert, sizeof(g_cert));
|
res = ykpiv_util_write_cert(g_state, YKPIV_KEY_AUTHENTICATION, (uint8_t*)g_cert, sizeof(g_cert), YKPIV_CERTINFO_UNCOMPRESSED);
|
||||||
ck_assert_int_eq(res, YKPIV_OK);
|
ck_assert_int_eq(res, YKPIV_OK);
|
||||||
|
|
||||||
res = ykpiv_util_read_cert(g_state, YKPIV_KEY_AUTHENTICATION, &read_cert, &read_cert_len);
|
res = ykpiv_util_read_cert(g_state, YKPIV_KEY_AUTHENTICATION, &read_cert, &read_cert_len);
|
||||||
@@ -411,7 +411,7 @@ START_TEST(test_generate_key) {
|
|||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
uint8_t *mod, *exp;
|
uint8_t *mod, *exp;
|
||||||
size_t mod_len, exp_len;
|
size_t mod_len, exp_len;
|
||||||
res = ykpiv_util_write_cert(g_state, YKPIV_KEY_AUTHENTICATION, (uint8_t*)g_cert, sizeof(g_cert));
|
res = ykpiv_util_write_cert(g_state, YKPIV_KEY_AUTHENTICATION, (uint8_t*)g_cert, sizeof(g_cert), YKPIV_CERTINFO_UNCOMPRESSED);
|
||||||
ck_assert_int_eq(res, YKPIV_OK);
|
ck_assert_int_eq(res, YKPIV_OK);
|
||||||
res = ykpiv_util_generate_key(g_state,
|
res = ykpiv_util_generate_key(g_state,
|
||||||
YKPIV_KEY_AUTHENTICATION,
|
YKPIV_KEY_AUTHENTICATION,
|
||||||
@@ -666,7 +666,7 @@ uint8_t *alloc_auth_cert() {
|
|||||||
uint8_t *read_cert = NULL;
|
uint8_t *read_cert = NULL;
|
||||||
size_t read_cert_len = 0;
|
size_t read_cert_len = 0;
|
||||||
|
|
||||||
res = ykpiv_util_write_cert(g_state, YKPIV_KEY_AUTHENTICATION, (uint8_t*)g_cert, sizeof(g_cert));
|
res = ykpiv_util_write_cert(g_state, YKPIV_KEY_AUTHENTICATION, (uint8_t*)g_cert, sizeof(g_cert), YKPIV_CERTINFO_UNCOMPRESSED);
|
||||||
ck_assert_int_eq(res, YKPIV_OK);
|
ck_assert_int_eq(res, YKPIV_OK);
|
||||||
|
|
||||||
res = ykpiv_util_read_cert(g_state, YKPIV_KEY_AUTHENTICATION, &read_cert, &read_cert_len);
|
res = ykpiv_util_read_cert(g_state, YKPIV_KEY_AUTHENTICATION, &read_cert, &read_cert_len);
|
||||||
|
|||||||
+7
-7
@@ -58,7 +58,7 @@ const uint8_t CCC_TMPL[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static ykpiv_rc _read_certificate(ykpiv_state *state, uint8_t slot, uint8_t *buf, size_t *buf_len);
|
static ykpiv_rc _read_certificate(ykpiv_state *state, uint8_t slot, uint8_t *buf, size_t *buf_len);
|
||||||
static ykpiv_rc _write_certificate(ykpiv_state *state, uint8_t slot, uint8_t *data, size_t data_len);
|
static ykpiv_rc _write_certificate(ykpiv_state *state, uint8_t slot, uint8_t *data, size_t data_len, uint8_t certinfo);
|
||||||
|
|
||||||
static ykpiv_rc _read_metadata(ykpiv_state *state, uint8_t tag, uint8_t* data, size_t* pcb_data);
|
static ykpiv_rc _read_metadata(ykpiv_state *state, uint8_t tag, uint8_t* data, size_t* pcb_data);
|
||||||
static ykpiv_rc _write_metadata(ykpiv_state *state, uint8_t tag, uint8_t *data, size_t cb_data);
|
static ykpiv_rc _write_metadata(ykpiv_state *state, uint8_t tag, uint8_t *data, size_t cb_data);
|
||||||
@@ -293,13 +293,13 @@ Cleanup:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_util_write_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, uint8_t certinfo) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
|
|
||||||
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return YKPIV_PCSC_ERROR;
|
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) return YKPIV_PCSC_ERROR;
|
||||||
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
if (YKPIV_OK != (res = _ykpiv_ensure_application_selected(state))) goto Cleanup;
|
||||||
|
|
||||||
res = _write_certificate(state, slot, data, data_len);
|
res = _write_certificate(state, slot, data, data_len, certinfo);
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
|
||||||
@@ -308,7 +308,7 @@ Cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_util_delete_cert(ykpiv_state *state, uint8_t slot) {
|
ykpiv_rc ykpiv_util_delete_cert(ykpiv_state *state, uint8_t slot) {
|
||||||
return ykpiv_util_write_cert(state, slot, NULL, 0);
|
return ykpiv_util_write_cert(state, slot, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_util_block_puk(ykpiv_state *state) {
|
ykpiv_rc ykpiv_util_block_puk(ykpiv_state *state) {
|
||||||
@@ -1252,7 +1252,7 @@ static ykpiv_rc _read_certificate(ykpiv_state *state, uint8_t slot, uint8_t *buf
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ykpiv_rc _write_certificate(ykpiv_state *state, uint8_t slot, uint8_t *data, size_t data_len) {
|
static ykpiv_rc _write_certificate(ykpiv_state *state, uint8_t slot, uint8_t *data, size_t data_len, uint8_t certinfo) {
|
||||||
// TREV TODO: should this select application?
|
// TREV TODO: should this select application?
|
||||||
uint8_t buf[CB_OBJ_MAX];
|
uint8_t buf[CB_OBJ_MAX];
|
||||||
size_t cbBuf = sizeof(buf);
|
size_t cbBuf = sizeof(buf);
|
||||||
@@ -1290,8 +1290,8 @@ static ykpiv_rc _write_certificate(ykpiv_state *state, uint8_t slot, uint8_t *da
|
|||||||
// write compression info and LRC trailer
|
// write compression info and LRC trailer
|
||||||
buf[offset++] = TAG_CERT_COMPRESS;
|
buf[offset++] = TAG_CERT_COMPRESS;
|
||||||
buf[offset++] = 0x01;
|
buf[offset++] = 0x01;
|
||||||
buf[offset++] = 0x00; // TODO: Handle compression when certificate exceeds buffer size
|
buf[offset++] = certinfo == YKPIV_CERTINFO_GZIP ? 0x01 : 0x00;
|
||||||
buf[offset++] = TAG_CERT_LRC; // LRC
|
buf[offset++] = TAG_CERT_LRC;
|
||||||
buf[offset++] = 00;
|
buf[offset++] = 00;
|
||||||
|
|
||||||
// write onto device
|
// write onto device
|
||||||
|
|||||||
+5
-1
@@ -198,6 +198,8 @@ extern "C"
|
|||||||
|
|
||||||
#define YKPIV_OBJ_ATTESTATION 0x5fff01
|
#define YKPIV_OBJ_ATTESTATION 0x5fff01
|
||||||
|
|
||||||
|
#define YKPIV_OBJ_MAX_SIZE 3072
|
||||||
|
|
||||||
#define YKPIV_INS_VERIFY 0x20
|
#define YKPIV_INS_VERIFY 0x20
|
||||||
#define YKPIV_INS_CHANGE_REFERENCE 0x24
|
#define YKPIV_INS_CHANGE_REFERENCE 0x24
|
||||||
#define YKPIV_INS_RESET_RETRY 0x2c
|
#define YKPIV_INS_RESET_RETRY 0x2c
|
||||||
@@ -241,6 +243,8 @@ extern "C"
|
|||||||
#define YKPIV_RETRIES_DEFAULT 3
|
#define YKPIV_RETRIES_DEFAULT 3
|
||||||
#define YKPIV_RETRIES_MAX 0xff
|
#define YKPIV_RETRIES_MAX 0xff
|
||||||
|
|
||||||
|
#define YKPIV_CERTINFO_UNCOMPRESSED 0
|
||||||
|
#define YKPIV_CERTINFO_GZIP 1
|
||||||
|
|
||||||
//
|
//
|
||||||
// UTIL
|
// UTIL
|
||||||
@@ -291,7 +295,7 @@ extern "C"
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_util_list_keys(ykpiv_state *state, uint8_t *key_count, ykpiv_key **data, size_t *data_len);
|
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_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_write_cert(ykpiv_state *state, uint8_t slot, uint8_t *data, size_t data_len, uint8_t certinfo);
|
||||||
ykpiv_rc ykpiv_util_delete_cert(ykpiv_state *state, uint8_t slot);
|
ykpiv_rc ykpiv_util_delete_cert(ykpiv_state *state, uint8_t slot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+45
@@ -255,6 +255,51 @@ int set_length(unsigned char *buffer, int length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_slot_hex(enum enum_slot slot_enum) {
|
||||||
|
int slot = -1;
|
||||||
|
|
||||||
|
switch (slot_enum) {
|
||||||
|
case slot_arg_9a:
|
||||||
|
slot = 0x9a;
|
||||||
|
break;
|
||||||
|
case slot_arg_9c:
|
||||||
|
case slot_arg_9d:
|
||||||
|
case slot_arg_9e:
|
||||||
|
slot = 0x9c + ((int)slot_enum - (int)slot_arg_9c);
|
||||||
|
break;
|
||||||
|
case slot_arg_82:
|
||||||
|
case slot_arg_83:
|
||||||
|
case slot_arg_84:
|
||||||
|
case slot_arg_85:
|
||||||
|
case slot_arg_86:
|
||||||
|
case slot_arg_87:
|
||||||
|
case slot_arg_88:
|
||||||
|
case slot_arg_89:
|
||||||
|
case slot_arg_8a:
|
||||||
|
case slot_arg_8b:
|
||||||
|
case slot_arg_8c:
|
||||||
|
case slot_arg_8d:
|
||||||
|
case slot_arg_8e:
|
||||||
|
case slot_arg_8f:
|
||||||
|
case slot_arg_90:
|
||||||
|
case slot_arg_91:
|
||||||
|
case slot_arg_92:
|
||||||
|
case slot_arg_93:
|
||||||
|
case slot_arg_94:
|
||||||
|
case slot_arg_95:
|
||||||
|
slot = 0x82 + ((int)slot_enum - (int)slot_arg_82);
|
||||||
|
break;
|
||||||
|
case slot_arg_f9:
|
||||||
|
slot = 0xf9;
|
||||||
|
break;
|
||||||
|
case slot__NULL:
|
||||||
|
default:
|
||||||
|
slot = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
int get_object_id(enum enum_slot slot) {
|
int get_object_id(enum enum_slot slot) {
|
||||||
int object;
|
int object;
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ int get_length(const unsigned char*, int*);
|
|||||||
X509_NAME *parse_name(const char*);
|
X509_NAME *parse_name(const char*);
|
||||||
unsigned char get_algorithm(EVP_PKEY*);
|
unsigned char get_algorithm(EVP_PKEY*);
|
||||||
FILE *open_file(const char*, int);
|
FILE *open_file(const char*, int);
|
||||||
|
int get_slot_hex(enum enum_slot slot_enum);
|
||||||
int get_object_id(enum enum_slot slot);
|
int get_object_id(enum enum_slot slot);
|
||||||
int key_to_object_id(int key);
|
int key_to_object_id(int key);
|
||||||
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len);
|
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len);
|
||||||
|
|||||||
+3
-20
@@ -495,35 +495,18 @@ static bool import_cert(ykpiv_state *state, enum enum_key_format cert_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned char certdata[3072];
|
unsigned char certdata[YKPIV_OBJ_MAX_SIZE];
|
||||||
unsigned char *certptr = certdata;
|
unsigned char *certptr = certdata;
|
||||||
int object = get_object_id(slot);
|
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
|
|
||||||
if(4 + cert_len + 5 > sizeof(certdata)) { /* 4 is prefix size, 5 is postfix size */
|
|
||||||
fprintf(stderr, "Certificate is too large to fit in buffer.\n");
|
|
||||||
goto import_cert_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
*certptr++ = 0x70;
|
|
||||||
certptr += set_length(certptr, cert_len);
|
|
||||||
if (compress) {
|
if (compress) {
|
||||||
if (fread(certptr, 1, (size_t)cert_len, input_file) != (size_t)cert_len) {
|
if (fread(certdata, 1, (size_t)cert_len, input_file) != (size_t)cert_len) {
|
||||||
fprintf(stderr, "Failed to read compressed certificate\n");
|
fprintf(stderr, "Failed to read compressed certificate\n");
|
||||||
goto import_cert_out;
|
goto import_cert_out;
|
||||||
}
|
}
|
||||||
certptr += cert_len;
|
|
||||||
} else {
|
} else {
|
||||||
/* i2d_X509 increments certptr here.. */
|
|
||||||
i2d_X509(cert, &certptr);
|
i2d_X509(cert, &certptr);
|
||||||
}
|
}
|
||||||
*certptr++ = 0x71;
|
if ((res = ykpiv_util_write_cert(state, get_slot_hex(slot), certdata, cert_len, compress)) != YKPIV_OK) {
|
||||||
*certptr++ = 1;
|
|
||||||
*certptr++ = compress; /* certinfo (gzip etc) */
|
|
||||||
*certptr++ = 0xfe; /* LRC */
|
|
||||||
*certptr++ = 0;
|
|
||||||
|
|
||||||
if((res = ykpiv_save_object(state, object, certdata, (size_t)(certptr - certdata))) != YKPIV_OK) {
|
|
||||||
fprintf(stderr, "Failed commands with device: %s\n", ykpiv_strerror(res));
|
fprintf(stderr, "Failed commands with device: %s\n", ykpiv_strerror(res));
|
||||||
} else {
|
} else {
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user