Added basic version of slot info functions.

This commit is contained in:
Alessio Di Mauro
2015-06-30 11:14:36 +02:00
parent 5e50401a0a
commit 2b2fe1f9fa
6 changed files with 263 additions and 141 deletions
+7 -1
View File
@@ -41,10 +41,16 @@
#endif
#endif
#define READER_LEN 32
#define MAX_READERS 16
struct ykpiv_state {
SCARDCONTEXT context;
SCARDHANDLE card;
int verbose;
unsigned long n_readers;
char readers[MAX_READERS][READER_LEN];
unsigned long tot_readers_len;
int verbose;
};
union u_APDU {
+66 -29
View File
@@ -20,7 +20,7 @@
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, We grant you additional
* terms of the OpenSSL or SSLeay licenses, We grant you additional
* permission to convey the resulting work. Corresponding Source for a
* non-source form of such a combination shall include the source code
* for the parts of OpenSSL used as well as that of the covered work.
@@ -131,6 +131,7 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
unsigned long active_protocol;
char reader_buf[1024];
long rc;
int i;
char *reader_ptr;
rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &state->context);
@@ -164,19 +165,31 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
return YKPIV_PCSC_ERROR;
}
// TODO: improve here
state->n_readers = 0;
state->tot_readers_len = num_readers;
reader_ptr = reader_buf;
for (i = 0; i < num_readers; i++)
if (reader_buf[i] == '\0' && i != num_readers - 1) {
strcpy(state->readers[state->n_readers], reader_ptr); // TODO: strdup?
state->n_readers = state->n_readers + 1;
reader_ptr += i + 1;
}
// *********
reader_ptr = reader_buf;
if(wanted) {
while(*reader_ptr != '\0') {
if(strstr(reader_ptr, wanted)) {
if(state->verbose) {
fprintf(stderr, "using reader '%s' matching '%s'.\n", reader_ptr, wanted);
}
break;
if(state->verbose) {
fprintf(stderr, "using reader '%s' matching '%s'.\n", reader_ptr, wanted);
}
break;
} else {
if(state->verbose) {
fprintf(stderr, "skipping reader '%s' since it doesn't match.\n", reader_ptr);
}
reader_ptr += strlen(reader_ptr) + 1;
if(state->verbose) {
fprintf(stderr, "skipping reader '%s' since it doesn't match.\n", reader_ptr);
}
reader_ptr += strlen(reader_ptr) + 1;
}
}
}
@@ -266,7 +279,7 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
}
if(*out_len + recv_len - 2 > max_out) {
if(state->verbose) {
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.\n", *out_len + recv_len - 2, max_out);
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.\n", *out_len + recv_len - 2, max_out);
}
return YKPIV_SIZE_ERROR;
}
@@ -400,7 +413,7 @@ ykpiv_rc ykpiv_authenticate(ykpiv_state *state, unsigned const char *key) {
*dataptr++ = 8;
if(RAND_pseudo_bytes(dataptr, 8) == -1) {
if(state->verbose) {
fprintf(stderr, "Failed getting randomness for authentication.\n");
fprintf(stderr, "Failed getting randomness for authentication.\n");
}
return YKPIV_RANDOMNESS_ERROR;
}
@@ -440,11 +453,11 @@ ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key) {
DES_set_odd_parity(&key_tmp);
if(DES_is_weak_key(&key_tmp) != 0) {
if(state->verbose) {
fprintf(stderr, "Won't set new key '");
dump_hex(new_key + i * 8, 8);
fprintf(stderr, "' since it's weak (with parity the key is: ");
dump_hex(key_tmp, 8);
fprintf(stderr, ").\n");
fprintf(stderr, "Won't set new key '");
dump_hex(new_key + i * 8, 8);
fprintf(stderr, "' since it's weak (with parity the key is: ");
dump_hex(key_tmp, 8);
fprintf(stderr, ").\n");
}
return YKPIV_GENERIC_ERROR;
}
@@ -519,26 +532,26 @@ static ykpiv_rc _general_authenticate(ykpiv_state *state,
pad_len = 128;
case YKPIV_ALGO_RSA2048:
if(pad_len == 0) {
pad_len = 256;
pad_len = 256;
}
if(!decipher) {
if(in_len + RSA_PKCS1_PADDING_SIZE > pad_len) {
return YKPIV_SIZE_ERROR;
}
RSA_padding_add_PKCS1_type_1(sign_in, pad_len, raw_in, in_len);
in_len = pad_len;
if(in_len + RSA_PKCS1_PADDING_SIZE > pad_len) {
return YKPIV_SIZE_ERROR;
}
RSA_padding_add_PKCS1_type_1(sign_in, pad_len, raw_in, in_len);
in_len = pad_len;
} else {
if(in_len != pad_len) {
return YKPIV_SIZE_ERROR;
}
memcpy(sign_in, raw_in, in_len);
if(in_len != pad_len) {
return YKPIV_SIZE_ERROR;
}
memcpy(sign_in, raw_in, in_len);
}
break;
case YKPIV_ALGO_ECCP256:
if(!decipher && in_len > 32) {
return YKPIV_SIZE_ERROR;
return YKPIV_SIZE_ERROR;
} else if(decipher && in_len != 65) {
return YKPIV_SIZE_ERROR;
return YKPIV_SIZE_ERROR;
}
memcpy(sign_in, raw_in, in_len);
break;
@@ -734,7 +747,7 @@ ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
dataptr += len;
if((res = ykpiv_transfer_data(state, templ, data, dataptr - data, NULL, &outlen,
&sw)) != YKPIV_OK) {
&sw)) != YKPIV_OK) {
return res;
}
@@ -744,3 +757,27 @@ ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
return YKPIV_GENERIC_ERROR;
}
}
ykpiv_rc ykpiv_get_reader_slot_number(ykpiv_state *state, unsigned long *slots, unsigned long *total) {
if (state == NULL)
return YKPIV_MEMORY_ERROR;
*slots = state->n_readers;
*total = state->tot_readers_len;
return YKPIV_OK;
}
ykpiv_rc ykpiv_get_reader_slot(ykpiv_state *state, unsigned long slot, char *reader) {
if (state == NULL)
return YKPIV_MEMORY_ERROR;
if (slot >= state->n_readers)
return YKPIV_SIZE_ERROR;
strcpy(reader, state->readers[slot]);
return YKPIV_OK;
}
+45 -42
View File
@@ -20,7 +20,7 @@
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, We grant you additional
* terms of the OpenSSL or SSLeay licenses, We grant you additional
* permission to convey the resulting work. Corresponding Source for a
* non-source form of such a combination shall include the source code
* for the parts of OpenSSL used as well as that of the covered work.
@@ -40,50 +40,53 @@ extern "C"
{
#endif
typedef struct ykpiv_state ykpiv_state;
typedef struct ykpiv_state ykpiv_state;
typedef enum {
YKPIV_OK = 0,
YKPIV_MEMORY_ERROR = -1,
YKPIV_PCSC_ERROR = -2,
YKPIV_SIZE_ERROR = -3,
YKPIV_APPLET_ERROR = -4,
YKPIV_AUTHENTICATION_ERROR = -5,
YKPIV_RANDOMNESS_ERROR = -6,
YKPIV_GENERIC_ERROR = -7,
YKPIV_KEY_ERROR = -8,
YKPIV_PARSE_ERROR = -9,
YKPIV_WRONG_PIN = -10,
YKPIV_INVALID_OBJECT = -11,
YKPIV_ALGORITHM_ERROR = -12,
} ykpiv_rc;
typedef enum {
YKPIV_OK = 0,
YKPIV_MEMORY_ERROR = -1,
YKPIV_PCSC_ERROR = -2,
YKPIV_SIZE_ERROR = -3,
YKPIV_APPLET_ERROR = -4,
YKPIV_AUTHENTICATION_ERROR = -5,
YKPIV_RANDOMNESS_ERROR = -6,
YKPIV_GENERIC_ERROR = -7,
YKPIV_KEY_ERROR = -8,
YKPIV_PARSE_ERROR = -9,
YKPIV_WRONG_PIN = -10,
YKPIV_INVALID_OBJECT = -11,
YKPIV_ALGORITHM_ERROR = -12,
} ykpiv_rc;
const char *ykpiv_strerror(ykpiv_rc err);
const char *ykpiv_strerror_name(ykpiv_rc err);
const char *ykpiv_strerror(ykpiv_rc err);
const char *ykpiv_strerror_name(ykpiv_rc err);
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose);
ykpiv_rc ykpiv_done(ykpiv_state *state);
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted);
ykpiv_rc ykpiv_disconnect(ykpiv_state *state);
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
const unsigned char *in_data, long in_len,
unsigned char *out_data, unsigned long *out_len, int *sw);
ykpiv_rc ykpiv_authenticate(ykpiv_state *state, const unsigned char *key);
ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key);
ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len,
unsigned char *hex_out, size_t *out_len);
ykpiv_rc ykpiv_sign_data(ykpiv_state *state, const unsigned char *sign_in,
size_t in_len,unsigned char *sign_out, size_t *out_len,
unsigned char algorithm, unsigned char key);
ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *enc_in,
size_t in_len, unsigned char *enc_out, size_t *out_len,
unsigned char algorithm, unsigned char key);
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len);
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries);
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
unsigned char *data, unsigned long *len);
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose);
ykpiv_rc ykpiv_done(ykpiv_state *state);
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted);
ykpiv_rc ykpiv_disconnect(ykpiv_state *state);
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
const unsigned char *in_data, long in_len,
unsigned char *out_data, unsigned long *out_len, int *sw);
ykpiv_rc ykpiv_authenticate(ykpiv_state *state, const unsigned char *key);
ykpiv_rc ykpiv_set_mgmkey(ykpiv_state *state, const unsigned char *new_key);
ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len,
unsigned char *hex_out, size_t *out_len);
ykpiv_rc ykpiv_sign_data(ykpiv_state *state, const unsigned char *sign_in,
size_t in_len,unsigned char *sign_out, size_t *out_len,
unsigned char algorithm, unsigned char key);
ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *enc_in,
size_t in_len, unsigned char *enc_out, size_t *out_len,
unsigned char algorithm, unsigned char key);
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len);
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries);
ykpiv_rc ykpiv_fetch_object(ykpiv_state *state, int object_id,
unsigned char *data, unsigned long *len);
ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
unsigned char *indata, size_t len);
unsigned char *indata, size_t len);
ykpiv_rc ykpiv_get_reader_slot_number(ykpiv_state *state, unsigned long *slots, unsigned long *total);
ykpiv_rc ykpiv_get_reader_slot(ykpiv_state *state, unsigned long slot, char *reader);
#define YKPIV_ALGO_3DES 0x03
#define YKPIV_ALGO_RSA1024 0x06
@@ -118,7 +121,7 @@ extern "C"
#define YKPIV_INS_GET_DATA 0xcb
#define YKPIV_INS_PUT_DATA 0xdb
/* Yubico vendor specific instructions */
/* Yubico vendor specific instructions */
#define YKPIV_INS_SET_MGMKEY 0xff
#define YKPIV_INS_IMPORT_KEY 0xfe
#define YKPIV_INS_GET_VERSION 0xfd
+2
View File
@@ -52,4 +52,6 @@ YKPIV_0.2.0
{
global:
ykpiv_decipher_data;
ykpiv_get_reader_slot_number;
ykpiv_get_reader_slot;
} YKPIV_0.1.0;