rework get_length() and fix bug(s)

This commit is contained in:
Klas Lindfors
2014-02-05 15:17:30 +01:00
parent 3657cc5000
commit 24c7f22022
+28 -37
View File
@@ -85,8 +85,7 @@ 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(unsigned char*, int *);
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;
@@ -323,17 +322,17 @@ static bool generate_key(SCARDHANDLE *card, const char *slot, enum enum_algorith
public_key = EVP_PKEY_new(); public_key = EVP_PKEY_new();
if(algorithm == algorithm_arg_RSA1024 || algorithm == algorithm_arg_RSA2048) { if(algorithm == algorithm_arg_RSA1024 || algorithm == algorithm_arg_RSA2048) {
unsigned char *data_ptr = data + 5; unsigned char *data_ptr = data + 5;
int len; int len = 0;
rsa = RSA_new(); rsa = RSA_new();
if(*data_ptr != 0x81) { if(*data_ptr != 0x81) {
fprintf(stderr, "Failed to parse public key structure.\n"); fprintf(stderr, "Failed to parse public key structure. (ptr was %02x)\n", *data_ptr);
ret = false; ret = false;
goto generate_out; goto generate_out;
} }
data_ptr++; data_ptr++;
len = get_length(data_ptr); data_ptr += get_length(data_ptr, &len);
data_ptr += get_length_bytes(len); printf("modulus is %d.\n", len);
bignum_n = BN_bin2bn(data_ptr, len, NULL); bignum_n = BN_bin2bn(data_ptr, len, NULL);
if(bignum_n == NULL) { if(bignum_n == NULL) {
fprintf(stderr, "Failed to parse public key modulus.\n"); fprintf(stderr, "Failed to parse public key modulus.\n");
@@ -343,13 +342,12 @@ static bool generate_key(SCARDHANDLE *card, const char *slot, enum enum_algorith
data_ptr += len; data_ptr += len;
if(*data_ptr != 0x82) { if(*data_ptr != 0x82) {
fprintf(stderr, "Failed to parse public key structure.\n"); fprintf(stderr, "Failed to parse public key structure (2). (ptr was %02x)\n", *data_ptr);
ret = false; ret = false;
goto generate_out; goto generate_out;
} }
data_ptr++; data_ptr++;
len = get_length(data_ptr); data_ptr += get_length(data_ptr, &len);
data_ptr += get_length_bytes(len);
bignum_e = BN_bin2bn(data_ptr, len, NULL); bignum_e = BN_bin2bn(data_ptr, len, NULL);
if(bignum_e == NULL) { if(bignum_e == NULL) {
fprintf(stderr, "Failed to parse public key exponent.\n"); fprintf(stderr, "Failed to parse public key exponent.\n");
@@ -404,23 +402,17 @@ generate_out:
if(output_file != stdout) { if(output_file != stdout) {
fclose(output_file); fclose(output_file);
} }
if(public_key) { if(point) {
EVP_PKEY_free(public_key); EC_POINT_free(point);
}
if(rsa) {
RSA_free(rsa);
}
if(bignum_n) {
BN_free(bignum_n);
}
if(bignum_e) {
BN_free(bignum_e);
} }
if(eckey) { if(eckey) {
EC_KEY_free(eckey); EC_KEY_free(eckey);
} }
if(point) { if(rsa) {
EC_POINT_free(point); RSA_free(rsa);
}
if(public_key) {
EVP_PKEY_free(public_key);
} }
return ret; return ret;
@@ -719,7 +711,13 @@ static bool import_cert(SCARDHANDLE *card, enum enum_key_format cert_format,
*certptr++ = (object >> 8) & 0xff; *certptr++ = (object >> 8) & 0xff;
*certptr++ = object & 0xff; *certptr++ = object & 0xff;
*certptr++ = 0x53; *certptr++ = 0x53;
bytes = get_length_bytes(cert_len); if(cert_len < 0x80) {
bytes = 1;
} else if(cert_len < 0xff) {
bytes = 2;
} else {
bytes = 3;
}
certptr += set_length(certptr, cert_len + bytes + 6); certptr += set_length(certptr, cert_len + bytes + 6);
*certptr++ = 0x70; *certptr++ = 0x70;
certptr += set_length(certptr, cert_len); certptr += set_length(certptr, cert_len);
@@ -872,25 +870,18 @@ static bool parse_key(char *key_arg, unsigned char *key, int verbose) {
return true; return true;
} }
static int get_length(unsigned char *buffer) { static int get_length(unsigned char *buffer, int *len) {
if(buffer[0] < 0x81) { if(buffer[0] < 0x81) {
return buffer[0]; *len = 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; return 1;
} else if(len < 0xff) { } else if((*buffer & 0x7f) == 1) {
*len = buffer[1];
return 2; return 2;
} else { } else if((*buffer & 0x7f) == 2) {
*len = (buffer[1] << 8) + buffer[2];
return 3; return 3;
} }
return 0;
} }
static int set_length(unsigned char *buffer, int length) { static int set_length(unsigned char *buffer, int length) {