Refactor yubico-piv-tool to use import_private_key from libykpiv.

This commit is contained in:
Alessio Di Mauro
2015-11-20 11:49:30 +01:00
parent e39b203d66
commit abc94bc62a
3 changed files with 100 additions and 94 deletions
+6 -5
View File
@@ -291,15 +291,16 @@ int key_to_object_id(int key) {
return object;
}
bool set_component_with_len(unsigned char **in_ptr, const BIGNUM *bn, int element_len) {
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len) {
int real_len = BN_num_bytes(bn);
*in_ptr += set_length(*in_ptr, element_len);
if(real_len > element_len) {
return false;
}
memset(*in_ptr, 0, (size_t)(element_len - real_len));
*in_ptr += element_len - real_len;
*in_ptr += BN_bn2bin(bn, *in_ptr);
memset(in_ptr, 0, (size_t)(element_len - real_len));
in_ptr += element_len - real_len;
BN_bn2bin(bn, in_ptr);
return true;
}
+1 -1
View File
@@ -46,7 +46,7 @@ unsigned char get_algorithm(EVP_PKEY*);
FILE *open_file(const char*, int);
int get_object_id(enum enum_slot slot);
int key_to_object_id(int key);
bool set_component_with_len(unsigned char**, const BIGNUM*, int);
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len);
bool prepare_rsa_signature(const unsigned char*, unsigned int, unsigned char*,
unsigned int*, int);
bool read_pw(const char*, char*, size_t, int);
+57 -52
View File
@@ -324,6 +324,7 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
PKCS12 *p12 = NULL;
X509 *cert = NULL;
bool ret = false;
ykpiv_rc rc = YKPIV_GENERIC_ERROR;
sscanf(slot, "%2x", &key);
@@ -360,119 +361,123 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
{
unsigned char algorithm = get_algorithm(private_key);
unsigned char pp = YKPIV_PINPOLICY_DEFAULT;
unsigned char tp = YKPIV_TOUCHPOLICY_DEFAULT;
if(algorithm == 0) {
goto import_out;
}
{
unsigned char data[0xff];
unsigned long recv_len = sizeof(data);
unsigned char in_data[1024];
unsigned char *in_ptr = in_data;
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, algorithm, key};
int sw;
if(pin_policy != pin_policy__NULL) {
pp = get_pin_policy(pin_policy);
}
if(touch_policy != touch_policy__NULL) {
tp = get_touch_policy(touch_policy);
}
if(YKPIV_IS_RSA(algorithm)) {
RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
unsigned char e[4];
unsigned char *e_ptr = e;
unsigned char p[128];
unsigned char q[128];
unsigned char dmp1[128];
unsigned char dmq1[128];
unsigned char iqmp[128];
int element_len = 128;
if(algorithm == YKPIV_ALGO_RSA1024) {
element_len = 64;
}
if((set_component_with_len(&e_ptr, rsa_private_key->e, 3) == false) ||
!(e[1] == 0x01 && e[2] == 0x00 && e[3] == 0x01)) {
if((set_component(e, rsa_private_key->e, 3) == false) ||
!(e[0] == 0x01 && e[1] == 0x00 && e[2] == 0x01)) {
fprintf(stderr, "Invalid public exponent for import (only 0x10001 supported)\n");
goto import_out;
}
*in_ptr++ = 0x01;
if(set_component_with_len(&in_ptr, rsa_private_key->p, element_len) == false) {
if(set_component(p, rsa_private_key->p, element_len) == false) {
fprintf(stderr, "Failed setting p component.\n");
goto import_out;
}
*in_ptr++ = 0x02;
if(set_component_with_len(&in_ptr, rsa_private_key->q, element_len) == false) {
if(set_component(q, rsa_private_key->q, element_len) == false) {
fprintf(stderr, "Failed setting q component.\n");
goto import_out;
}
*in_ptr++ = 0x03;
if(set_component_with_len(&in_ptr, rsa_private_key->dmp1, element_len) == false) {
if(set_component(dmp1, rsa_private_key->dmp1, element_len) == false) {
fprintf(stderr, "Failed setting dmp1 component.\n");
goto import_out;
}
*in_ptr++ = 0x04;
if(set_component_with_len(&in_ptr, rsa_private_key->dmq1, element_len) == false) {
if(set_component(dmq1, rsa_private_key->dmq1, element_len) == false) {
fprintf(stderr, "Failed setting dmq1 component.\n");
goto import_out;
}
*in_ptr++ = 0x05;
if(set_component_with_len(&in_ptr, rsa_private_key->iqmp, element_len) == false) {
if(set_component(iqmp, rsa_private_key->iqmp, element_len) == false) {
fprintf(stderr, "Failed setting iqmp component.\n");
goto import_out;
}
} else if(YKPIV_IS_EC(algorithm)) {
rc = ykpiv_import_private_key(state, key, algorithm,
p, element_len,
q, element_len,
dmp1, element_len,
dmq1, element_len,
iqmp, element_len,
NULL, 0,
pp, tp);
}
else if(YKPIV_IS_EC(algorithm)) {
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(private_key);
const BIGNUM *s = EC_KEY_get0_private_key(ec);
int element_len = 32;
unsigned char s_ptr[48];
int element_len = 32;
if(algorithm == YKPIV_ALGO_ECCP384) {
element_len = 48;
}
*in_ptr++ = 0x06;
if(set_component_with_len(&in_ptr, s, element_len) == false) {
if(set_component(s_ptr, s, element_len) == false) {
fprintf(stderr, "Failed setting ec private key.\n");
goto import_out;
}
}
if(pin_policy != pin_policy__NULL) {
*in_ptr++ = YKPIV_PINPOLICY_TAG;
*in_ptr++ = 1;
*in_ptr++ = get_pin_policy(pin_policy);
}
if(touch_policy != touch_policy__NULL) {
*in_ptr++ = YKPIV_TOUCHPOLICY_TAG;
*in_ptr++ = 1;
*in_ptr++ = get_touch_policy(touch_policy);
}
if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data,
&recv_len, &sw) != YKPIV_OK) {
return false;
} else if(sw == 0x6a80) {
fprintf(stderr, "Failed import.");
if(pin_policy != pin_policy__NULL) {
fprintf(stderr, "Maybe pin-policy is not supported on this key?\n");
} else if(touch_policy != touch_policy__NULL) {
fprintf(stderr, "Maybe touch-policy is not supported on this key?\n");
} else {
fprintf(stderr, "Maybe algorithm is not supported on this key?\n");
}
} else if(sw != 0x9000) {
fprintf(stderr, "Failed import command with code %x.\n", sw);
} else {
ret = true;
rc = ykpiv_import_private_key(state, key, algorithm,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
s_ptr, element_len,
pp, tp);
}
if(rc != YKPIV_OK) {
ret = false;
}
}
}
import_out:
if(private_key) {
EVP_PKEY_free(private_key);
}
if(p12) {
PKCS12_free(p12);
}
if(cert) {
X509_free(cert);
}
if(input_file != stdin) {
fclose(input_file);
}
return ret;
}