refactor so we get algorithm from a function.

This commit is contained in:
Klas Lindfors
2014-02-06 09:54:29 +01:00
parent be9211dc5b
commit 71cb66e5bf
+113 -78
View File
@@ -87,6 +87,7 @@ static int send_data(SCARDHANDLE*, APDU*, unsigned int, unsigned char*, unsigned
static int set_length(unsigned char*, int); static int set_length(unsigned char*, int);
static int get_length(unsigned char*, int *); static int get_length(unsigned char*, int *);
static X509_NAME *parse_name(char*); static X509_NAME *parse_name(char*);
static unsigned char get_algorithm(EVP_PKEY*);
static bool connect_reader(SCARDHANDLE *card, SCARDCONTEXT *context, const char *wanted, int verbose) { static bool connect_reader(SCARDHANDLE *card, SCARDCONTEXT *context, const char *wanted, int verbose) {
unsigned long num_readers; unsigned long num_readers;
@@ -534,85 +535,72 @@ static bool import_key(SCARDHANDLE *card, enum enum_key_format key_format,
} }
{ {
int type = EVP_PKEY_type(private_key->type); unsigned char algorithm = get_algorithm(private_key);
if(type == EVP_PKEY_RSA) { if(algorithm == 11) {
int algorithm; fprintf(stderr, "import key only supports RSA.\n");
RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
int size = RSA_size(rsa_private_key);
if(size == 256) {
algorithm = 7;
} else if(size == 128) {
algorithm = 6;
} else {
fprintf(stderr, "Unuseable key of %d bits, only 1024 and 2048 is supported.\n", size * 8);
ret = false;
goto import_out;
}
if(verbose) {
fprintf(stderr, "Found RSA-%d key.\n", size * 8);
}
{
APDU apdu;
unsigned char in_data[1024];
unsigned char *in_ptr = in_data;
int sw;
int in_size;
*in_ptr++ = 0x01;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->p));
in_ptr += BN_bn2bin(rsa_private_key->p, in_ptr);
*in_ptr++ = 0x02;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->q));
in_ptr += BN_bn2bin(rsa_private_key->q, in_ptr);
*in_ptr++ = 0x03;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->dmp1));
in_ptr += BN_bn2bin(rsa_private_key->dmp1, in_ptr);
*in_ptr++ = 0x04;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->dmq1));
in_ptr += BN_bn2bin(rsa_private_key->dmq1, in_ptr);
*in_ptr++ = 0x05;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->iqmp));
in_ptr += BN_bn2bin(rsa_private_key->iqmp, in_ptr);
in_size = in_ptr - in_data;
in_ptr = in_data;
while(in_ptr < in_data + in_size) {
unsigned char data[0xff];
unsigned long recv_len = sizeof(data);
size_t this_size = 0xff;
memset(apdu.raw, 0, sizeof(apdu));
if(in_ptr + 0xff < in_data + in_size) {
apdu.st.cla = 0x10;
} else {
this_size = (size_t)((in_data + in_size) - in_ptr);
}
if(verbose) {
fprintf(stderr, "going to send %lu bytes in this go.\n", (unsigned long)this_size);
}
apdu.st.ins = 0xfe;
apdu.st.p1 = algorithm;
apdu.st.p2 = key;
apdu.st.lc = this_size;
memcpy(apdu.st.data, in_ptr, this_size);
sw = send_data(card, &apdu, this_size + 5, data, &recv_len, verbose);
if(sw != 0x9000) {
fprintf(stderr, "Failed import command with code %x.", sw);
ret = false;
goto import_out;
}
in_ptr += this_size;
}
}
} else {
/* TODO: ECC */
fprintf(stderr, "Unknown type: %d\n", type);
ret = false; ret = false;
goto import_out;
} else if(algorithm == 0) {
ret = false;
goto import_out;
}
{
APDU apdu;
unsigned char in_data[1024];
unsigned char *in_ptr = in_data;
int sw;
int in_size;
RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
*in_ptr++ = 0x01;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->p));
in_ptr += BN_bn2bin(rsa_private_key->p, in_ptr);
*in_ptr++ = 0x02;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->q));
in_ptr += BN_bn2bin(rsa_private_key->q, in_ptr);
*in_ptr++ = 0x03;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->dmp1));
in_ptr += BN_bn2bin(rsa_private_key->dmp1, in_ptr);
*in_ptr++ = 0x04;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->dmq1));
in_ptr += BN_bn2bin(rsa_private_key->dmq1, in_ptr);
*in_ptr++ = 0x05;
in_ptr += set_length(in_ptr, BN_num_bytes(rsa_private_key->iqmp));
in_ptr += BN_bn2bin(rsa_private_key->iqmp, in_ptr);
in_size = in_ptr - in_data;
in_ptr = in_data;
while(in_ptr < in_data + in_size) {
unsigned char data[0xff];
unsigned long recv_len = sizeof(data);
size_t this_size = 0xff;
memset(apdu.raw, 0, sizeof(apdu));
if(in_ptr + 0xff < in_data + in_size) {
apdu.st.cla = 0x10;
} else {
this_size = (size_t)((in_data + in_size) - in_ptr);
}
if(verbose) {
fprintf(stderr, "going to send %lu bytes in this go.\n", (unsigned long)this_size);
}
apdu.st.ins = 0xfe;
apdu.st.p1 = algorithm;
apdu.st.p2 = key;
apdu.st.lc = this_size;
memcpy(apdu.st.data, in_ptr, this_size);
sw = send_data(card, &apdu, this_size + 5, data, &recv_len, verbose);
if(sw != 0x9000) {
fprintf(stderr, "Failed import command with code %x.", sw);
ret = false;
goto import_out;
}
in_ptr += this_size;
}
} }
} }
import_out: import_out:
@@ -825,6 +813,7 @@ static bool request_certificate(SCARDHANDLE *card, enum enum_key_format key_form
X509_ALGOR algor; X509_ALGOR algor;
unsigned char digest[20]; unsigned char digest[20];
unsigned int digest_len = sizeof(digest); unsigned int digest_len = sizeof(digest);
unsigned char algorithm;
if(!strcmp(input_file_name, "-")) { if(!strcmp(input_file_name, "-")) {
input_file = stdin; input_file = stdin;
@@ -857,6 +846,8 @@ static bool request_certificate(SCARDHANDLE *card, enum enum_key_format key_form
ret = false; ret = false;
goto request_out; goto request_out;
} }
algorithm = get_algorithm(public_key);
req = X509_REQ_new(); req = X509_REQ_new();
if(!req) { if(!req) {
fprintf(stderr, "Failed to allocate request structure.\n"); fprintf(stderr, "Failed to allocate request structure.\n");
@@ -900,6 +891,16 @@ static bool request_certificate(SCARDHANDLE *card, enum enum_key_format key_form
dump_hex(digest, digest_len); dump_hex(digest, digest_len);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
{
APDU apdu;
unsigned char data[0xff];
unsigned long recv_len = sizeof(data);
int sw;
memset(apdu.raw, 0, sizeof(apdu.raw));
apdu.st.ins = 0x87;
apdu.st.p1 = algorithm;
}
request_out: request_out:
if(input_file != stdin) { if(input_file != stdin) {
@@ -920,6 +921,40 @@ request_out:
return ret; return ret;
} }
static unsigned char get_algorithm(EVP_PKEY *key) {
int type = EVP_PKEY_type(key->type);
switch(type) {
case EVP_PKEY_RSA:
{
RSA *rsa = EVP_PKEY_get1_RSA(key);
int size = RSA_size(rsa);
if(size == 256) {
return 7;
} else if(size == 128) {
return 6;
} else {
fprintf(stderr, "Unuseable key of %d bits, only 1024 and 2048 is supported.\n", size * 8);
return 0;
}
}
case EVP_PKEY_EC:
{
EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key);
const EC_GROUP *group = EC_KEY_get0_group(ec);
int curve = EC_GROUP_get_curve_name(group);
if(curve == NID_X9_62_prime256v1) {
return 11;
} else {
fprintf(stderr, "Unknown EC curve %d\n", curve);
return 0;
}
}
default:
fprintf(stderr, "Unknown algorithm %d.\n", type);
return 0;
}
}
static X509_NAME *parse_name(char *name) { static X509_NAME *parse_name(char *name) {
X509_NAME *parsed = NULL; X509_NAME *parsed = NULL;
char *ptr = name; char *ptr = name;