On 06/07/2011 03:17 PM, Andre Zepezauer wrote: > Hello Jean-Pierre, > > SC_PKCS15_PIN_FLAG_VERIFY_RC_COUNTER doesn't correspond to any flag > defined in PKCS#15. Furthermore, the capability to modify the return > code of the VERIFY command is not specific to PKCS#15. > > Why not using a different approach? In example it's possible to detect > the installed packages of CardOS. Depending of the presence of the > "Verify Retry Counter Package" the flags in TEST BSO could be set > accordingly. > Hi Andre,
Any comment/objection? Cheers, Jean-Pierre Index: src/pkcs15init/pkcs15-cardos.c =================================================================== --- src/pkcs15init/pkcs15-cardos.c (revision 5563) +++ src/pkcs15init/pkcs15-cardos.c (working copy) @@ -62,6 +62,7 @@ sc_file_t *, int); static int do_cardos_extract_pubkey(sc_card_t *card, int nr, u8 tag, sc_pkcs15_bignum_t *bn); +static int cardos_have_verifyrc_package(sc_card_t *card); /* Object IDs for PIN objects. * SO PIN = 0x01, SO PUK = 0x02 @@ -413,7 +414,7 @@ unsigned char pinpadded[256]; struct tlv tlv; unsigned int attempts, minlen, maxlen; - int r; + int r, hasverifyrc; if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; @@ -445,6 +446,10 @@ /* parameters */ tlv_next(&tlv, 0x85); tlv_add(&tlv, 0x02); /* options byte */ + hasverifyrc = cardos_have_verifyrc_package(card); + if (hasverifyrc == 1) + /* Use 9 byte OCI parameters to be able to set VerifyRC bit */ + tlv_add(&tlv, 0x04); /* options_2 byte with bit 2 set to return CurrentErrorCounter */ tlv_add(&tlv, attempts & 0xf); /* flags byte */ tlv_add(&tlv, CARDOS_ALGO_PIN); /* algorithm = pin-test */ tlv_add(&tlv, attempts & 0xf); /* errcount = attempts */ @@ -786,6 +791,56 @@ return r; } +static int cardos_have_verifyrc_package(sc_card_t *card) +{ + sc_apdu_t apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + int r; + const u8 *p = rbuf, *q; + size_t len, tlen = 0, ilen = 0; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.lc = 0; + apdu.le = 256; + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); + + if ((len = apdu.resplen) == 0) + /* looks like no package has been installed */ + return 0; + + while (len != 0) { + p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); + if (p == NULL) + return 0; + if (card->type == SC_CARD_TYPE_CARDOS_M4_3) { + /* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */ + /* and Package Number 0x07 */ + q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen); + if (q == NULL || ilen != 4) + return 0; + if (q[0] == 0x07) + return 1; + } else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) { + /* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03 */ + /* and Package Number 0x02 */ + q = sc_asn1_find_tag(card->ctx, p, tlen, 0x03, &ilen); + if (q == NULL || ilen != 4) + return 0; + if (q[0] == 0x02) + return 1; + } else { + return 0; + } + p += tlen; + len -= tlen + 2; + } + + return 0; +} + static struct sc_pkcs15init_operations sc_pkcs15init_cardos_operations = { cardos_erase, NULL, /* init_card */ _______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel