add ykpiv_verify to the library

This commit is contained in:
Klas Lindfors
2014-06-23 09:57:10 +02:00
parent 052b80830a
commit 31d9d0d680
4 changed files with 60 additions and 23 deletions
+45
View File
@@ -557,3 +557,48 @@ ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len) {
return YKPIV_GENERIC_ERROR; return YKPIV_GENERIC_ERROR;
} }
} }
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
APDU apdu;
unsigned char data[0xff];
unsigned long recv_len = sizeof(data);
int sw;
size_t len = strlen(pin);
ykpiv_rc res;
if(len > 8) {
return YKPIV_SIZE_ERROR;
}
memset(apdu.raw, 0, sizeof(apdu.raw));
apdu.st.ins = YKPIV_INS_VERIFY;
apdu.st.p1 = 0x00;
apdu.st.p2 = 0x80;
apdu.st.lc = 0x08;
memcpy(apdu.st.data, pin, len);
if(len < 8) {
memset(apdu.st.data + len, 0xff, 8 - len);
}
if((res = ykpiv_send_data(state, apdu.raw, data, &recv_len, &sw)) != YKPIV_OK) {
return res;
} else if(sw == 0x9000) {
return YKPIV_OK;
} else if((sw >> 8) == 0x63) {
if(state->verbose) {
fprintf(stderr, "Pin verification failed, %d tries left before pin is blocked.\n", sw & 0xff);
}
*tries = (sw & 0xff);
return YKPIV_WRONG_PIN;
} else if(sw == 0x6983) {
if(state->verbose) {
fprintf(stderr, "Pin code blocked, use unblock-pin action to unblock.\n");
}
*tries = 0;
return YKPIV_WRONG_PIN;
} else {
if(state->verbose) {
fprintf(stderr, "Pin code verification failed with code %x.\n", sw);
}
return YKPIV_GENERIC_ERROR;
}
}
+2
View File
@@ -53,6 +53,7 @@ extern "C"
YKPIV_GENERIC_ERROR = -7, YKPIV_GENERIC_ERROR = -7,
YKPIV_KEY_ERROR = -8, YKPIV_KEY_ERROR = -8,
YKPIV_PARSE_ERROR = -9, YKPIV_PARSE_ERROR = -9,
YKPIV_WRONG_PIN = -10,
} ykpiv_rc; } ykpiv_rc;
const char *ykpiv_strerror(ykpiv_rc err); const char *ykpiv_strerror(ykpiv_rc err);
@@ -75,6 +76,7 @@ extern "C"
int in_len,unsigned char *sign_out, int *out_len, int in_len,unsigned char *sign_out, int *out_len,
unsigned char algorithm, unsigned char key); unsigned char algorithm, unsigned char key);
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len); 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);
#define YKPIV_ALGO_3DES 0x03 #define YKPIV_ALGO_3DES 0x03
#define YKPIV_ALGO_RSA1024 0x06 #define YKPIV_ALGO_RSA1024 0x06
+1
View File
@@ -41,6 +41,7 @@ global:
ykpiv_parse_key; ykpiv_parse_key;
ykpiv_sign_data; ykpiv_sign_data;
ykpiv_get_version; ykpiv_get_version;
ykpiv_verify;
local: local:
*; *;
+12 -23
View File
@@ -797,36 +797,25 @@ selfsign_out:
} }
static bool verify_pin(ykpiv_state *state, const char *pin) { static bool verify_pin(ykpiv_state *state, const char *pin) {
APDU apdu; int tries = -1;
unsigned char data[0xff]; ykpiv_rc res;
unsigned long recv_len = sizeof(data); int len = strlen(pin);
int sw;
size_t len = strlen(pin);
if(len > 8) { if(len > 8) {
fprintf(stderr, "Maximum 8 digits of PIN supported.\n"); fprintf(stderr, "Maximum 8 digits of PIN supported.\n");
return false;
} }
memset(apdu.raw, 0, sizeof(apdu.raw)); res = ykpiv_verify(state, pin, &tries);
apdu.st.ins = YKPIV_INS_VERIFY; if(res == YKPIV_OK) {
apdu.st.p1 = 0x00;
apdu.st.p2 = 0x80;
apdu.st.lc = 0x08;
memcpy(apdu.st.data, pin, len);
if(len < 8) {
memset(apdu.st.data + len, 0xff, 8 - len);
}
if(ykpiv_send_data(state, apdu.raw, data, &recv_len, &sw) != YKPIV_OK) {
return false;
} else if(sw == 0x9000) {
return true; return true;
} else if((sw >> 8) == 0x63) { } else if(res == YKPIV_WRONG_PIN) {
fprintf(stderr, "Pin verification failed, %d tries left before pin is blocked.\n", sw & 0xff); if(tries > 0) {
} else if(sw == 0x6983) { fprintf(stderr, "Pin verification failed, %d tries left before pin is blocked.\n", tries);
fprintf(stderr, "Pin code blocked, use unblock-pin action to unblock.\n"); } else {
fprintf(stderr, "Pin code blocked, use unblock-pin action to unblock.\n");
}
} else { } else {
fprintf(stderr, "Pin code verification failed with code %x.\n", sw); fprintf(stderr, "Pin code verification failed: '%s'\n", ykpiv_strerror(res));
} }
return false; return false;
} }