On Wed, 2011-06-08 at 11:50 +0200, Jean-Pierre Szikora wrote:
> 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?

A flag SC_CARD_FLAG_ISO_VERIFY would be of general use. If set, then
it's possible to send the VERIFY command with *empty* data field to get
the number of further allowed retries coded in SW '63CX'.

That means, that cardos_have_verifyrc_package would be placed better in
card-cardos.c and only "card->flags & SC_CARD_FLAG_ISO_VERIFY" needs to
be checked in pkcs15-cardos.c

Prerequisite is that opensc-tool -s "00 20 00 01" returns something
like: Received (SW1=0x63, SW2=0xC3)

Any comment/objection?

> 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