proper output of public key after generate
This commit is contained in:
+111
-8
@@ -68,6 +68,8 @@ typedef union u_APDU APDU;
|
|||||||
static void dump_hex(unsigned const char*, unsigned int);
|
static void dump_hex(unsigned const char*, unsigned int);
|
||||||
static int send_data(SCARDHANDLE*, APDU, unsigned int, unsigned char*, unsigned long*, int);
|
static int send_data(SCARDHANDLE*, APDU, unsigned int, unsigned char*, unsigned long*, int);
|
||||||
static int set_length(unsigned char*, int);
|
static int set_length(unsigned char*, int);
|
||||||
|
static int get_length(unsigned char*);
|
||||||
|
static int get_length_bytes(int);
|
||||||
|
|
||||||
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;
|
||||||
@@ -230,16 +232,29 @@ static void print_version(SCARDHANDLE *card, int verbose) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool generate_key(SCARDHANDLE *card, const char *slot, enum enum_algorithm algorithm, int verbose) {
|
static bool generate_key(SCARDHANDLE *card, const char *slot, enum enum_algorithm algorithm, const char *output_file_name, enum enum_key_format key_format, int verbose) {
|
||||||
APDU apdu;
|
APDU apdu;
|
||||||
unsigned char data[1024];
|
unsigned char data[1024];
|
||||||
unsigned long recv_len = 0xff;
|
unsigned long recv_len = 0xff;
|
||||||
unsigned long received = 0;
|
unsigned long received = 0;
|
||||||
int sw;
|
int sw;
|
||||||
int key = 0;
|
int key = 0;
|
||||||
|
FILE *output_file;
|
||||||
|
bool ret = true;
|
||||||
|
EVP_PKEY *public_key = NULL;
|
||||||
|
|
||||||
sscanf(slot, "%x", &key);
|
sscanf(slot, "%x", &key);
|
||||||
|
|
||||||
|
if(!strcmp(output_file_name, "-")) {
|
||||||
|
output_file = stdout;
|
||||||
|
} else {
|
||||||
|
output_file = fopen(output_file_name, "r");
|
||||||
|
if(!output_file) {
|
||||||
|
fprintf(stderr, "Failed opening '%s'!\n", output_file_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = 0x47;
|
apdu.st.ins = 0x47;
|
||||||
apdu.st.p2 = key;
|
apdu.st.p2 = key;
|
||||||
@@ -261,6 +276,8 @@ static bool generate_key(SCARDHANDLE *card, const char *slot, enum enum_algorith
|
|||||||
case algorithm__NULL:
|
case algorithm__NULL:
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unexepcted algorithm.\n");
|
fprintf(stderr, "Unexepcted algorithm.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
}
|
}
|
||||||
sw = send_data(card, apdu, 10, data, &recv_len, verbose);
|
sw = send_data(card, apdu, 10, data, &recv_len, verbose);
|
||||||
|
|
||||||
@@ -271,12 +288,79 @@ static bool generate_key(SCARDHANDLE *card, const char *slot, enum enum_algorith
|
|||||||
memset(apdu.raw, 0, sizeof(apdu));
|
memset(apdu.raw, 0, sizeof(apdu));
|
||||||
apdu.st.ins = 0xc0;
|
apdu.st.ins = 0xc0;
|
||||||
sw = send_data(card, apdu, 4, data + received, &recv_len, verbose);
|
sw = send_data(card, apdu, 4, data + received, &recv_len, verbose);
|
||||||
received += recv_len;
|
}
|
||||||
|
if(sw != 0x9000) {
|
||||||
|
fprintf(stderr, "Failed to generate new key.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
|
}
|
||||||
|
/* to drop the 90 00 and the 7f 49 at the start */
|
||||||
|
received += recv_len - 4;
|
||||||
|
|
||||||
|
if(key_format == key_format_arg_PEM) {
|
||||||
|
public_key = EVP_PKEY_new();
|
||||||
|
if(algorithm == algorithm_arg_RSA1024 || algorithm == algorithm_arg_RSA2048) {
|
||||||
|
unsigned char *data_ptr = data + 5;
|
||||||
|
int len;
|
||||||
|
RSA *rsa = RSA_new();
|
||||||
|
BIGNUM *n, *e;
|
||||||
|
|
||||||
|
if(*data_ptr != 0x81) {
|
||||||
|
fprintf(stderr, "Failed to parse public key structure.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
|
}
|
||||||
|
data_ptr++;
|
||||||
|
len = get_length(data_ptr);
|
||||||
|
data_ptr += get_length_bytes(len);
|
||||||
|
n = BN_bin2bn(data_ptr, len, NULL);
|
||||||
|
if(n == NULL) {
|
||||||
|
fprintf(stderr, "Failed to parse public key modulus.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
|
}
|
||||||
|
data_ptr += len;
|
||||||
|
|
||||||
|
if(*data_ptr != 0x82) {
|
||||||
|
fprintf(stderr, "Failed to parse public key structure.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
|
}
|
||||||
|
data_ptr++;
|
||||||
|
len = get_length(data_ptr);
|
||||||
|
data_ptr += get_length_bytes(len);
|
||||||
|
e = BN_bin2bn(data_ptr, len, NULL);
|
||||||
|
if(e == NULL) {
|
||||||
|
fprintf(stderr, "Failed to parse public key exponent.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_hex(data, received);
|
rsa->n = n;
|
||||||
|
rsa->e = e;
|
||||||
|
EVP_PKEY_assign_RSA(public_key, rsa);
|
||||||
|
} else {
|
||||||
|
/* TODO: ECC pubkey out */
|
||||||
|
fprintf(stderr, "only RSA gets an output..\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
|
}
|
||||||
|
PEM_write_PUBKEY(output_file, public_key);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Only PEM is supported as public_key output.\n");
|
||||||
|
ret = false;
|
||||||
|
goto generate_out;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
generate_out:
|
||||||
|
if(output_file != stdout) {
|
||||||
|
fclose(output_file);
|
||||||
|
}
|
||||||
|
if(public_key) {
|
||||||
|
EVP_PKEY_free(public_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool set_mgm_key(SCARDHANDLE *card, unsigned const char *new_key, int verbose) {
|
static bool set_mgm_key(SCARDHANDLE *card, unsigned const char *new_key, int verbose) {
|
||||||
@@ -353,14 +437,12 @@ static bool import_key(SCARDHANDLE *card, enum enum_key_format key_format, const
|
|||||||
EVP_PKEY *private_key = NULL;
|
EVP_PKEY *private_key = NULL;
|
||||||
PKCS12 *p12 = NULL;
|
PKCS12 *p12 = NULL;
|
||||||
X509 *cert = NULL;
|
X509 *cert = NULL;
|
||||||
bool in_stdin = false;
|
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
sscanf(slot, "%x", &key);
|
sscanf(slot, "%x", &key);
|
||||||
|
|
||||||
if(!strcmp(input_file_name, "-")) {
|
if(!strcmp(input_file_name, "-")) {
|
||||||
input_file = stdin;
|
input_file = stdin;
|
||||||
in_stdin = true;
|
|
||||||
} else {
|
} else {
|
||||||
input_file = fopen(input_file_name, "r");
|
input_file = fopen(input_file_name, "r");
|
||||||
if(!input_file) {
|
if(!input_file) {
|
||||||
@@ -481,7 +563,7 @@ import_out:
|
|||||||
if(cert) {
|
if(cert) {
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
}
|
}
|
||||||
if(!in_stdin) {
|
if(input_file != stdin) {
|
||||||
fclose(input_file);
|
fclose(input_file);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -547,6 +629,27 @@ static bool parse_key(char *key_arg, unsigned char *key, int verbose) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_length(unsigned char *buffer) {
|
||||||
|
if(buffer[0] < 0x81) {
|
||||||
|
return buffer[0];
|
||||||
|
} else if((*buffer & 0x7f) == 1) {
|
||||||
|
return buffer[1];
|
||||||
|
} else if((*buffer & 0x7f) == 2) {
|
||||||
|
return((buffer[1] << 8) + buffer[0]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_length_bytes(int len) {
|
||||||
|
if(len < 0x81) {
|
||||||
|
return 1;
|
||||||
|
} else if(len < 0xff) {
|
||||||
|
return 2;
|
||||||
|
} else {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int set_length(unsigned char *buffer, int length) {
|
static int set_length(unsigned char *buffer, int length) {
|
||||||
if(length < 0x80) {
|
if(length < 0x80) {
|
||||||
*buffer++ = length;
|
*buffer++ = length;
|
||||||
@@ -607,7 +710,7 @@ int main(int argc, char *argv[]) {
|
|||||||
print_version(&card, verbosity);
|
print_version(&card, verbosity);
|
||||||
} else if(action == action_arg_generate) {
|
} else if(action == action_arg_generate) {
|
||||||
if(args_info.slot_arg != slot__NULL) {
|
if(args_info.slot_arg != slot__NULL) {
|
||||||
if(generate_key(&card, args_info.slot_orig, args_info.algorithm_arg, verbosity) == false) {
|
if(generate_key(&card, args_info.slot_orig, args_info.algorithm_arg, args_info.output_arg, args_info.key_format_arg, verbosity) == false) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user