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

Reply via email to