check length of private key components before setting

the card functions only accepts key components of correct size
so here we add 0 before if they're shorter (usually one byte shorter)
thus fixing the issue where the card returned 6f00
This commit is contained in:
Klas Lindfors
2014-11-12 14:08:11 +01:00
parent d0cef2f469
commit 36468219c2
3 changed files with 41 additions and 12 deletions
+12
View File
@@ -203,3 +203,15 @@ int get_object_id(enum enum_slot slot) {
} }
return object; return object;
} }
bool set_component_with_len(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);
return true;
}
+1
View File
@@ -42,5 +42,6 @@ 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_object_id(enum enum_slot slot); int get_object_id(enum enum_slot slot);
bool set_component_with_len(unsigned char**, const BIGNUM*, int);
#endif #endif
+28 -12
View File
@@ -326,33 +326,49 @@ static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
int sw; int sw;
if(algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) { if(algorithm == YKPIV_ALGO_RSA1024 || algorithm == YKPIV_ALGO_RSA2048) {
RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key); RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
int element_len = 128;
if(algorithm == YKPIV_ALGO_RSA1024) {
element_len = 64;
}
*in_ptr++ = 0x01; *in_ptr++ = 0x01;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->p)); if(set_component_with_len(&in_ptr, rsa_private_key->p, element_len) == false) {
in_ptr += BN_bn2bin(rsa_private_key->p, in_ptr); fprintf(stderr, "Failed setting p component.\n");
goto import_out;
}
*in_ptr++ = 0x02; *in_ptr++ = 0x02;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->q)); if(set_component_with_len(&in_ptr, rsa_private_key->q, element_len) == false) {
in_ptr += BN_bn2bin(rsa_private_key->q, in_ptr); fprintf(stderr, "Failed setting q component.\n");
goto import_out;
}
*in_ptr++ = 0x03; *in_ptr++ = 0x03;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->dmp1)); if(set_component_with_len(&in_ptr, rsa_private_key->dmp1, element_len) == false) {
in_ptr += BN_bn2bin(rsa_private_key->dmp1, in_ptr); fprintf(stderr, "Failed setting dmp1 component.\n");
goto import_out;
}
*in_ptr++ = 0x04; *in_ptr++ = 0x04;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->dmq1)); if(set_component_with_len(&in_ptr, rsa_private_key->dmq1, element_len) == false) {
in_ptr += BN_bn2bin(rsa_private_key->dmq1, in_ptr); fprintf(stderr, "Failed setting dmq1 component.\n");
goto import_out;
}
*in_ptr++ = 0x05; *in_ptr++ = 0x05;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->iqmp)); if(set_component_with_len(&in_ptr, rsa_private_key->iqmp, element_len) == false) {
in_ptr += BN_bn2bin(rsa_private_key->iqmp, in_ptr); fprintf(stderr, "Failed setting iqmp component.\n");
goto import_out;
}
} else if(algorithm == YKPIV_ALGO_ECCP256) { } else if(algorithm == YKPIV_ALGO_ECCP256) {
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(private_key); EC_KEY *ec = EVP_PKEY_get1_EC_KEY(private_key);
const BIGNUM *s = EC_KEY_get0_private_key(ec); const BIGNUM *s = EC_KEY_get0_private_key(ec);
*in_ptr++ = 0x06; *in_ptr++ = 0x06;
in_ptr += set_length(in_ptr, BN_num_bytes(s)); if(set_component_with_len(&in_ptr, s, 32) == false) {
in_ptr += BN_bn2bin(s, in_ptr); fprintf(stderr, "Failed setting ec private key.\n");
goto import_out;
}
} }
if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data, if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data,