- implemented change/unblock pin
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@244 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
4fa7283ae2
commit
c58b72fc54
|
@ -915,6 +915,87 @@ gpk_verify(struct sc_card *card, unsigned int type, int ref,
|
||||||
return SC_ERROR_INVALID_ARGUMENTS;
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change secret code. This is used by reset_retry_counter and
|
||||||
|
* change_reference_data
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
gpk_set_secret_code(struct sc_card *card, unsigned int mode,
|
||||||
|
unsigned int type, int ref,
|
||||||
|
const u8 *puk, size_t puklen,
|
||||||
|
const u8 *pin, size_t pinlen,
|
||||||
|
int *tries_left)
|
||||||
|
{
|
||||||
|
struct sc_apdu apdu;
|
||||||
|
u8 data[8];
|
||||||
|
unsigned int n;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (card->ctx->debug)
|
||||||
|
debug(card->ctx, "gpk_set_secret_code(mode=%d, ref=%d)\n",
|
||||||
|
mode, ref);
|
||||||
|
if (type != SC_AC_CHV || !puk || !puklen)
|
||||||
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
|
memset(&apdu, 0, sizeof(apdu));
|
||||||
|
apdu.cse = SC_APDU_CASE_3_SHORT;
|
||||||
|
apdu.cla = 0x80;
|
||||||
|
apdu.ins = 0x24;
|
||||||
|
apdu.p1 = mode;
|
||||||
|
apdu.p2 = ref & 7;
|
||||||
|
apdu.lc = 8;
|
||||||
|
apdu.data= data;
|
||||||
|
apdu.datalen = 8;
|
||||||
|
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
for (n = 0; n < 8 && n < puklen; n += 2)
|
||||||
|
data[n >> 1] = (puk[n] << 4) | (puk[n+1] & 0xf);
|
||||||
|
for (n = 0; n < 8 && n < pinlen; n += 2)
|
||||||
|
data[4 + (n >> 1)] = (pin[n] << 4) | (pin[n+1] & 0xf);
|
||||||
|
|
||||||
|
r = sc_transmit_apdu(card, &apdu);
|
||||||
|
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||||
|
|
||||||
|
/* Special case: extract tries_left */
|
||||||
|
if (apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) {
|
||||||
|
if (tries_left)
|
||||||
|
*tries_left = apdu.sw2 & 0xF;
|
||||||
|
return SC_ERROR_PIN_CODE_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||||
|
SC_TEST_RET(card->ctx, r, "Card returned error");
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unblock the CHV
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
gpk_reset_retry_counter(struct sc_card *card,
|
||||||
|
unsigned int type, int ref,
|
||||||
|
const u8 *puk, size_t puklen,
|
||||||
|
const u8 *pin, size_t pinlen)
|
||||||
|
{
|
||||||
|
return gpk_set_secret_code(card, 0x01, type, ref,
|
||||||
|
puk, puklen, pin, pinlen, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change the PIN
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
gpk_change_reference_data(struct sc_card *card,
|
||||||
|
unsigned int type, int ref,
|
||||||
|
const u8 *puk, size_t puklen,
|
||||||
|
const u8 *pin, size_t pinlen,
|
||||||
|
int *tries_left)
|
||||||
|
{
|
||||||
|
return gpk_set_secret_code(card, 0x00, type, ref,
|
||||||
|
puk, puklen, pin, pinlen, tries_left);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select a security environment (Set Crypto Context in GPK docs).
|
* Select a security environment (Set Crypto Context in GPK docs).
|
||||||
* When we get here, the PK file has already been selected.
|
* When we get here, the PK file has already been selected.
|
||||||
|
@ -1405,6 +1486,8 @@ sc_get_driver()
|
||||||
gpk_ops.set_security_env= gpk_set_security_env;
|
gpk_ops.set_security_env= gpk_set_security_env;
|
||||||
gpk_ops.restore_security_env= gpk_restore_security_env;
|
gpk_ops.restore_security_env= gpk_restore_security_env;
|
||||||
gpk_ops.compute_signature= gpk_compute_signature;
|
gpk_ops.compute_signature= gpk_compute_signature;
|
||||||
|
gpk_ops.reset_retry_counter = gpk_reset_retry_counter;
|
||||||
|
gpk_ops.change_reference_data = gpk_change_reference_data;
|
||||||
}
|
}
|
||||||
return &gpk_drv;
|
return &gpk_drv;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue