Entersafe changes by Weitao Sun:
1.Card type FTCOS/PK-01C added. (new) 2.Limit pin length in range [4,16). (bug fix) 3.Can not unblock PIN. (bug fix) git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3674 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
117d790aea
commit
4670238556
|
@ -30,6 +30,10 @@ static struct sc_atr_table entersafe_atrs[] = {
|
|||
"3b:0f:00:65:46:53:05:19:05:71:df:00:00:00:00:00:00",
|
||||
"ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff:00:00:00:00:00:00",
|
||||
"ePass3000", SC_CARD_TYPE_ENTERSAFE_3K, 0, NULL },
|
||||
{
|
||||
"3b:9f:95:81:31:fe:9f:00:65:46:53:05:30:06:71:df:00:00:00:80:6a:82:5e",
|
||||
"FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00:00",
|
||||
"FTCOS/PK-01C", SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C, 0, NULL },
|
||||
{ NULL, NULL, NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -43,12 +47,18 @@ static struct sc_card_driver entersafe_drv = {
|
|||
NULL, 0, NULL
|
||||
};
|
||||
|
||||
static u8 trans_code[] =
|
||||
static u8 trans_code_3k[] =
|
||||
{
|
||||
0x01,0x02,0x03,0x04,
|
||||
0x05,0x06,0x07,0x08,
|
||||
};
|
||||
|
||||
static u8 trans_code_ftcos_pk_01c[] =
|
||||
{
|
||||
0x92,0x34,0x2E,0xEF,
|
||||
0x23,0x40,0x4F,0xD1,
|
||||
};
|
||||
|
||||
static u8 init_key[] =
|
||||
{
|
||||
1, 2, 3, 4,
|
||||
|
@ -118,7 +128,9 @@ static int entersafe_init(sc_card_t *card)
|
|||
_sc_card_add_rsa_alg(card,1024, flags, 0x10001);
|
||||
_sc_card_add_rsa_alg(card,2048, flags, 0x10001);
|
||||
|
||||
/*card->caps = SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT; */
|
||||
card->caps = SC_CARD_CAP_RNG;
|
||||
|
||||
card->drv_data = 0;
|
||||
|
||||
/* we need read_binary&friends with max 224 bytes per read */
|
||||
|
@ -674,7 +686,22 @@ static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data)
|
|||
apdu.data=(u8*)&data->data.mf;
|
||||
apdu.datalen=apdu.lc=sizeof(data->data.mf);
|
||||
|
||||
r = entersafe_transmit_apdu(card, &apdu,trans_code,sizeof(trans_code),0,1);
|
||||
switch(card->type)
|
||||
{
|
||||
case SC_CARD_TYPE_ENTERSAFE_3K:
|
||||
{
|
||||
r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1);
|
||||
}break;
|
||||
case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C:
|
||||
{
|
||||
r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1);
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
r = SC_ERROR_INTERNAL;
|
||||
}break;
|
||||
}
|
||||
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
return sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
}
|
||||
|
@ -920,7 +947,7 @@ static void entersafe_init_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num
|
|||
pin->max_length = 16;
|
||||
pin->pad_length = 16;
|
||||
pin->offset = 5 + num * 16;
|
||||
pin->pad_char=0x00;
|
||||
pin->pad_char = 0x00;
|
||||
}
|
||||
|
||||
static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
|
||||
|
@ -932,7 +959,41 @@ static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
|
|||
entersafe_init_pin_info(&data->pin2,1);
|
||||
data->flags |= SC_PIN_CMD_NEED_PADDING;
|
||||
|
||||
r = iso_ops->pin_cmd(card,data,tries_left);
|
||||
if(data->cmd!=SC_PIN_CMD_UNBLOCK)
|
||||
{
|
||||
r = iso_ops->pin_cmd(card,data,tries_left);
|
||||
}
|
||||
else
|
||||
{
|
||||
{/*verify*/
|
||||
sc_apdu_t apdu;
|
||||
u8 sbuf[0x10]={0};
|
||||
|
||||
memcpy(sbuf,data->pin1.data,data->pin1.len);
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,0x20,0x00,data->pin_reference+1);
|
||||
apdu.lc = apdu.datalen = sizeof(sbuf);
|
||||
apdu.data = sbuf;
|
||||
|
||||
r = entersafe_transmit_apdu(card, &apdu,0,0,0,0);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
}
|
||||
|
||||
{/*change*/
|
||||
sc_apdu_t apdu;
|
||||
u8 sbuf[0x12]={0};
|
||||
|
||||
sbuf[0] = 0x33;
|
||||
sbuf[1] = 0x00;
|
||||
memcpy(sbuf+2,data->pin2.data,data->pin2.len);
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,0xF4,0x0B,data->pin_reference);
|
||||
apdu.cla = 0x84;
|
||||
apdu.lc = apdu.datalen = sizeof(sbuf);
|
||||
apdu.data = sbuf;
|
||||
|
||||
r = entersafe_transmit_apdu(card, &apdu,key_maintain,sizeof(key_maintain),1,1);
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
}
|
||||
}
|
||||
SC_FUNC_RETURN(card->ctx, 4, r);
|
||||
}
|
||||
|
||||
|
@ -961,7 +1022,23 @@ static int entersafe_erase_card(sc_card_t *card)
|
|||
apdu.lc=2;
|
||||
apdu.datalen=2;
|
||||
apdu.data=sbuf;
|
||||
r = entersafe_transmit_apdu(card, &apdu,trans_code,sizeof(trans_code),0,1);
|
||||
|
||||
switch(card->type)
|
||||
{
|
||||
case SC_CARD_TYPE_ENTERSAFE_3K:
|
||||
{
|
||||
r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1);
|
||||
}break;
|
||||
case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C:
|
||||
{
|
||||
r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1);
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
r = SC_ERROR_INTERNAL;
|
||||
}break;
|
||||
}
|
||||
|
||||
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
}
|
||||
|
@ -1472,10 +1549,10 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_
|
|||
memset(sbuf,0,sizeof(sbuf));
|
||||
sbuf[0] = 0; /* key len extern */
|
||||
sbuf[1] = 16; /* key len */
|
||||
sbuf[2] = 0x0b; /* USAGE */
|
||||
sbuf[2] = 0x0B; /* USAGE */
|
||||
sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */
|
||||
sbuf[4] = 0X04; /* CHANGE AC */
|
||||
sbuf[5] = 0x14; /* UPDATE AC */
|
||||
sbuf[5] = 0x38; /* UPDATE AC */
|
||||
sbuf[6] = 0x01; /* ALGO */
|
||||
sbuf[7] = 0xFF; /* EC */
|
||||
sbuf[8] = 0x00; /* VER */
|
||||
|
@ -1489,6 +1566,28 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_
|
|||
SC_TEST_RET(card->ctx, r, "Preinstall user PIN failed");
|
||||
}
|
||||
|
||||
{/* user PUK */
|
||||
memset(sbuf,0,sizeof(sbuf));
|
||||
sbuf[0] = 0; /* key len extern */
|
||||
sbuf[1] = 16; /* key len */
|
||||
sbuf[2] = 0x0B; /* USAGE */
|
||||
sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */
|
||||
sbuf[4] = 0X08; /* CHANGE AC */
|
||||
sbuf[5] = 0xC0; /* UPDATE AC */
|
||||
sbuf[6] = 0x01; /* ALGO */
|
||||
sbuf[7] = 0xFF; /* EC */
|
||||
sbuf[8] = 0x00; /* VER */
|
||||
|
||||
sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xF0,0x00,ENTERSAFE_USER_PIN_ID+1);
|
||||
apdu.cla=0x84;
|
||||
apdu.data=sbuf;
|
||||
apdu.lc=apdu.datalen=0x19;
|
||||
|
||||
r = entersafe_transmit_apdu(card,&apdu,init_key,sizeof(init_key),0,1);
|
||||
SC_TEST_RET(card->ctx, r, "Preinstall user PUK failed");
|
||||
}
|
||||
|
||||
|
||||
SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -578,8 +578,6 @@ struct sc_rutoken_decipherinfo {
|
|||
|
||||
#define ENTERSAFE_AC_EVERYONE 0x00
|
||||
#define ENTERSAFE_AC_USER 0x04
|
||||
#define ENTERSAFE_AC_USER_ 0x08
|
||||
|
||||
|
||||
#define ENTERSAFE_AC_NEVER 0xC0
|
||||
#define ENTERSAFE_AC_ALWAYS 0x10
|
||||
|
|
|
@ -144,6 +144,7 @@ enum {
|
|||
/* EnterSafe cards */
|
||||
SC_CARD_TYPE_ENTERSAFE_BASE = 19000,
|
||||
SC_CARD_TYPE_ENTERSAFE_3K,
|
||||
SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C,
|
||||
};
|
||||
|
||||
extern sc_card_driver_t *sc_get_rutoken_driver(void);
|
||||
|
|
|
@ -12,6 +12,7 @@ cardinfo {
|
|||
option default {
|
||||
macros {
|
||||
pin-flags = initialized, needs-padding;
|
||||
min-pin-length = 4;
|
||||
df_acl = *=NEVER;
|
||||
protected = *=$PIN,READ=NONE;
|
||||
dir-size = 128;
|
||||
|
@ -49,21 +50,25 @@ PIN so-pin {
|
|||
reference = 1;
|
||||
attempts = 3;
|
||||
flags = $pin-flags;
|
||||
min-length = $min-pin-length;
|
||||
}
|
||||
PIN so-puk {
|
||||
reference = 1;
|
||||
attempts = 3;
|
||||
flags = $pin-flags;
|
||||
min-length = $min-pin-length;
|
||||
}
|
||||
PIN user-pin {
|
||||
reference = 1;
|
||||
attempts = 3;
|
||||
flags = $pin-flags;
|
||||
min-length = $min-pin-length;
|
||||
}
|
||||
PIN user-puk {
|
||||
reference = 1;
|
||||
attempts = 3;
|
||||
flags = $pin-flags;
|
||||
min-length = $min-pin-length;
|
||||
}
|
||||
|
||||
# Additional filesystem info.
|
||||
|
@ -147,7 +152,6 @@ filesystem {
|
|||
}
|
||||
EF public-key {
|
||||
file-id = 3003;
|
||||
size = 320;
|
||||
structure = transparent;
|
||||
ACL = *=NEVER,READ=NONE,UPDATE=$PIN;
|
||||
}
|
||||
|
@ -173,16 +177,7 @@ filesystem {
|
|||
structure = transparent;
|
||||
ACL = *=NEVER,READ=NONE,UPDATE=$PIN;
|
||||
}
|
||||
|
||||
# private data objects are stored in transparent EFs.
|
||||
EF data {
|
||||
file-id = 3401;
|
||||
structure = transparent;
|
||||
ACL = *=NEVER,READ=$PIN,UPDATE=$PIN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,23 +258,45 @@ static int entersafe_create_pin(sc_profile_t *profile, sc_card_t *card,
|
|||
{
|
||||
int r;
|
||||
sc_pkcs15_pin_info_t *pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data;
|
||||
sc_entersafe_wkey_data data;
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, 1);
|
||||
|
||||
if (!pin || !pin_len || pin_len > 16)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
{/*pin*/
|
||||
sc_entersafe_wkey_data data;
|
||||
|
||||
data.key_id=pin_info->reference;
|
||||
data.usage=0x0B;
|
||||
data.key_data.symmetric.EC=0x33;
|
||||
data.key_data.symmetric.ver=0x00;
|
||||
/* pad pin with 0 */
|
||||
memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
|
||||
memcpy(data.key_data.symmetric.key_val, pin, pin_len);
|
||||
data.key_data.symmetric.key_len=16;
|
||||
if (!pin || !pin_len || pin_len > 16)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
data.key_id=pin_info->reference;
|
||||
data.usage=0x0B;
|
||||
data.key_data.symmetric.EC=0x33;
|
||||
data.key_data.symmetric.ver=0x00;
|
||||
/* pad pin with 0 */
|
||||
memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
|
||||
memcpy(data.key_data.symmetric.key_val, pin, pin_len);
|
||||
data.key_data.symmetric.key_len=16;
|
||||
|
||||
r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
|
||||
}
|
||||
|
||||
{/*puk*/
|
||||
sc_entersafe_wkey_data data;
|
||||
|
||||
if (!puk || !puk_len || puk_len > 16)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
data.key_id=pin_info->reference+1;
|
||||
data.usage=0x0B;
|
||||
data.key_data.symmetric.EC=0x33;
|
||||
data.key_data.symmetric.ver=0x00;
|
||||
/* pad pin with 0 */
|
||||
memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
|
||||
memcpy(data.key_data.symmetric.key_val, puk, puk_len);
|
||||
data.key_data.symmetric.key_len=16;
|
||||
|
||||
r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
|
||||
}
|
||||
|
||||
r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
|
||||
|
||||
SC_FUNC_RETURN(card->ctx,4,r);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue