add ykpiv_verify to the library
This commit is contained in:
+45
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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 {
|
} else {
|
||||||
fprintf(stderr, "Pin code verification failed with code %x.\n", sw);
|
fprintf(stderr, "Pin code blocked, use unblock-pin action to unblock.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Pin code verification failed: '%s'\n", ykpiv_strerror(res));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user