break out looped sending from request-cert to own function
This commit is contained in:
+78
-44
@@ -87,6 +87,8 @@ union u_APDU {
|
||||
typedef union u_APDU APDU;
|
||||
|
||||
static void dump_hex(unsigned const char*, unsigned int);
|
||||
static int transfer_data(SCARDHANDLE*, APDU*, unsigned char*, long,
|
||||
unsigned char*, unsigned long*, int verbose);
|
||||
static int send_data(SCARDHANDLE*, APDU*, unsigned char*, unsigned long*, int);
|
||||
static int set_length(unsigned char*, int);
|
||||
static int get_length(unsigned char*, int*);
|
||||
@@ -934,11 +936,15 @@ static bool request_certificate(SCARDHANDLE *card, enum enum_key_format key_form
|
||||
unsigned char indata[1024];
|
||||
unsigned char *dataptr = indata;
|
||||
unsigned char data[1024];
|
||||
unsigned long recv_len;
|
||||
unsigned long received = 0;
|
||||
unsigned long recv_len = sizeof(data);
|
||||
int sw;
|
||||
int bytes;
|
||||
int datasize;
|
||||
APDU apdu;
|
||||
|
||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||
apdu.st.ins = 0x87;
|
||||
apdu.st.p1 = algorithm;
|
||||
apdu.st.p2 = key;
|
||||
|
||||
if(len < 0x80) {
|
||||
bytes = 1;
|
||||
@@ -957,51 +963,12 @@ static bool request_certificate(SCARDHANDLE *card, enum enum_key_format key_form
|
||||
memcpy(dataptr, signinput, (size_t)len);
|
||||
dataptr += len;
|
||||
|
||||
datasize = dataptr - indata;
|
||||
dataptr = indata;
|
||||
while(dataptr < indata + datasize) {
|
||||
size_t this_size = 0xff;
|
||||
APDU apdu;
|
||||
recv_len = 0xff;
|
||||
|
||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||
if(dataptr + 0xff < indata + datasize) {
|
||||
apdu.st.cla = 0x10;
|
||||
} else {
|
||||
this_size = (size_t)((indata + datasize) - dataptr);
|
||||
}
|
||||
if(verbose) {
|
||||
fprintf(stderr, "going to send %lu bytes in this go.\n", (unsigned long)this_size);
|
||||
}
|
||||
|
||||
apdu.st.ins = 0x87;
|
||||
apdu.st.p1 = algorithm;
|
||||
apdu.st.p2 = key;
|
||||
apdu.st.lc = this_size;
|
||||
memcpy(apdu.st.data, dataptr, this_size);
|
||||
sw = send_data(card, &apdu, data, &recv_len, verbose);
|
||||
if((sw & 0x6100) == 0x6100) {
|
||||
received += recv_len - 2;
|
||||
recv_len = 0xff;
|
||||
dataptr = data + received;
|
||||
memset(apdu.raw, 0, sizeof(apdu));
|
||||
apdu.st.ins = 0xc0;
|
||||
sw = send_data(card, &apdu, dataptr, &recv_len, verbose);
|
||||
if(sw == 0x9000) {
|
||||
received += recv_len - 2;
|
||||
} else {
|
||||
sw = transfer_data(card, &apdu, indata, dataptr - indata, data, &recv_len, verbose);
|
||||
if(sw != 0x9000) {
|
||||
fprintf(stderr, "Failed sign command with code %x.\n", sw);
|
||||
ret = false;
|
||||
goto request_out;
|
||||
}
|
||||
} else if(sw != 0x9000) {
|
||||
fprintf(stderr, "Failed sign command with code %x.\n", sw);
|
||||
ret = false;
|
||||
goto request_out;
|
||||
}
|
||||
dataptr += this_size;
|
||||
}
|
||||
|
||||
/* skip the first 7c tag */
|
||||
if(data[0] != 0x7c) {
|
||||
fprintf(stderr, "Failed parsing signature reply.\n");
|
||||
@@ -1022,6 +989,10 @@ static bool request_certificate(SCARDHANDLE *card, enum enum_key_format key_form
|
||||
M_ASN1_BIT_STRING_set(sig, dataptr, len);
|
||||
req->signature = sig;
|
||||
|
||||
fprintf(stderr, "Whole data is: ");
|
||||
dump_hex(dataptr, len);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if(key_format == key_format_arg_PEM) {
|
||||
PEM_write_X509_REQ(output_file, req);
|
||||
} else {
|
||||
@@ -1159,6 +1130,69 @@ parse_err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int transfer_data(SCARDHANDLE *card, APDU *apdu_tmpl, unsigned char *in_data,
|
||||
long in_len, unsigned char *out_data, unsigned long *out_len,
|
||||
int verbose) {
|
||||
unsigned char *in_ptr = in_data;
|
||||
unsigned long max_out = *out_len;
|
||||
int sw = 0;
|
||||
*out_len = 0;
|
||||
|
||||
while(in_ptr < in_data + in_len) {
|
||||
size_t this_size = 0xff;
|
||||
unsigned long recv_len = 0xff;
|
||||
unsigned char data[0xff];
|
||||
APDU apdu;
|
||||
|
||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||
memcpy(apdu.raw, apdu_tmpl->raw, 4);
|
||||
if(in_ptr + 0xff < in_data + in_len) {
|
||||
apdu.st.cla = 0x10;
|
||||
} else {
|
||||
this_size = (size_t)((in_data + in_len) - in_ptr);
|
||||
}
|
||||
if(verbose > 2) {
|
||||
fprintf(stderr, "Going to send %lu bytes in this go.\n", (unsigned long)this_size);
|
||||
}
|
||||
apdu.st.lc = this_size;
|
||||
memcpy(apdu.st.data, in_ptr, this_size);
|
||||
sw = send_data(card, &apdu, data, &recv_len, verbose);
|
||||
if(sw != 0x9000 && sw >> 8 != 0x61) {
|
||||
return sw;
|
||||
}
|
||||
if(*out_len + recv_len - 2 > max_out) {
|
||||
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.", *out_len + recv_len - 2, max_out);
|
||||
}
|
||||
memcpy(out_data, data, recv_len - 2);
|
||||
out_data += recv_len - 2;
|
||||
out_len += recv_len - 2;
|
||||
in_ptr += this_size;
|
||||
}
|
||||
while(sw >> 8 == 0x61) {
|
||||
APDU apdu;
|
||||
unsigned long recv_len = 0xff;
|
||||
unsigned char data[0xff];
|
||||
|
||||
if(verbose > 2) {
|
||||
fprintf(stderr, "The card indicates there is %d bytes more data for us.\n", sw & 0xff);
|
||||
}
|
||||
|
||||
memset(apdu.raw, 0, sizeof(apdu.raw));
|
||||
apdu.st.ins = 0xc0;
|
||||
sw = send_data(card, &apdu, data, &recv_len, verbose);
|
||||
if(sw != 0x9000 && sw >> 8 != 0x61) {
|
||||
return sw;
|
||||
}
|
||||
if(*out_len + recv_len - 2 > max_out) {
|
||||
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.", *out_len + recv_len - 2, max_out);
|
||||
}
|
||||
memcpy(out_data, data, recv_len - 2);
|
||||
out_data += recv_len - 2;
|
||||
out_len += recv_len - 2;
|
||||
}
|
||||
return sw;
|
||||
}
|
||||
|
||||
static int send_data(SCARDHANDLE *card, APDU *apdu, unsigned char *data,
|
||||
unsigned long *recv_len, int verbose) {
|
||||
long rc;
|
||||
|
||||
Reference in New Issue
Block a user