Hello Кирилл,

Actually, the User PIN of RuToken-ECP initialized on Linux cannot be unlocked
in the mode with attribution of the new PIN value.

If the RuToken-ECP is initialized by the 'Rutoken Control Panel' on Windows,
this operation is allowed and protected by SoPIN.

I would like to make Linux initialization similar to the one on Windows, and, 
if no objections, to apply the patch in attachment.

In these patch:
- the 'EF PIN file' section is added to the profile 'rutoken-ecp';
- in rutoken-ecp specific pkcs15init part the 'RESET-PIN' acl from this profile 
section controls the corresponding ACL for the newly created User PIN.
- in rutoken-ecp specific libopensc part the PIN reset procedure takes into 
account a new PIN unblock mode.


Kind regards,
Viktor.

Index: src/pkcs15init/pkcs15-rtecp.c
===================================================================
--- src/pkcs15init/pkcs15-rtecp.c       (révision 5526)
+++ src/pkcs15init/pkcs15-rtecp.c       (copie de travail)
@@ -168,12 +168,13 @@
 {
        sc_context_t *ctx;
        sc_pkcs15_pin_info_t *pin_info;
-       sc_file_t *file;
+       sc_file_t *file = NULL;
        /*                        GCHV min-length Flags Attempts  Reserve */
        unsigned char prop[]  = { 0x01,       '?', 0x01,     '?', 0, 0 };
        /*                  AccessMode Unblock Change             Delete */
        unsigned char sec[15] = { 0x43,    '?',   '?', 0, 0, 0, 0,  0xFF };
-       int r;
+       char pin_sname[0x10];
+       int r, reset_by_sopin = 0;
 
        (void)puk; /* no warning */
        if (!profile || !p15card || !p15card->card || !p15card->card->ctx || 
!df 
@@ -182,6 +183,7 @@
 
        ctx = p15card->card->ctx;
        SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
+
        if (puk_len != 0)
        {
                sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Do not enter User 
unblocking PIN (PUK): %s\n",
@@ -196,6 +198,25 @@
                                " (Rutoken ECP) PINs\n", pin_info->reference);
                return SC_ERROR_NOT_SUPPORTED;
        }
+
+       snprintf(pin_sname, sizeof(pin_sname), "CHV%i", pin_info->reference);
+       if (pin_info->reference == RTECP_USER_PIN_REF)   {
+               r = sc_profile_get_file(profile, pin_sname, &file);
+               if (!r)   {
+                       const struct sc_acl_entry *acl = NULL;
+
+                       r = sc_pkcs15init_fixup_file(profile, p15card, file);
+                       SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, 
"Cannot fixup the ACLs of PIN file");
+
+                       acl = sc_file_get_acl_entry(file, SC_AC_OP_PIN_RESET);
+                       if (acl && acl->method == SC_AC_CHV && acl->key_ref == 
RTECP_SO_PIN_REF)   {
+                               sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Allow reset 
of User PIN with SoPIN\n");
+                               reset_by_sopin = 1;
+                       }
+                       sc_file_free(file);
+               }
+       }
+
        file = sc_file_new();
        if (!file)
                SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, 
SC_ERROR_OUT_OF_MEMORY);
@@ -203,7 +224,7 @@
        file->size = pin_len;
        assert(sizeof(sec)/sizeof(sec[0]) > 2);
        sec[1] = (pin_info->reference == RTECP_SO_PIN_REF) ? 0xFF : 
RTECP_SO_PIN_REF;
-       sec[2] = (unsigned char)pin_info->reference;
+       sec[2] = (unsigned char)pin_info->reference | (reset_by_sopin ? 
RTECP_SO_PIN_REF : 0);
        r = sc_file_set_sec_attr(file, sec, sizeof(sec));
        if (r == SC_SUCCESS)
        {
Index: src/pkcs15init/rutoken_ecp.profile
===================================================================
--- src/pkcs15init/rutoken_ecp.profile  (révision 5526)
+++ src/pkcs15init/rutoken_ecp.profile  (copie de travail)
@@ -23,6 +23,8 @@
     encode-df-length    = no;
     # Have a lastUpdate field in the EF(TokenInfo)?
     do-last-update      = yes;
+
+    pkcs15-id-style     = mozilla;
 }
 
 # Default settings.
@@ -69,6 +71,10 @@
 }
 
 filesystem {
+    EF CHV2 {
+        file-id = 0002;
+        ACL     = *=NEVER, UPDATE=$SOPIN, PIN-RESET=$SOPIN;
+    }
 
     DF MF {
         path    = 3F00;
Index: src/libopensc/card-rtecp.c
===================================================================
--- src/libopensc/card-rtecp.c  (révision 5526)
+++ src/libopensc/card-rtecp.c  (copie de travail)
@@ -485,10 +485,32 @@
 {
        sc_apdu_t apdu;
        int r;
+       unsigned char pin_data[SC_MAX_APDU_BUFFER_SIZE];
+       size_t offs = 0;
 
        (void)type, (void)puk, (void)puklen, (void)newref, (void)newlen; /* no 
warning */
+
        assert(card && card->ctx);
-       sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 0x03, ref_qualifier);
+       if (!newref || !newlen)   {
+               sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 0x03, 
ref_qualifier);
+       }
+       else   {
+               // 00 24 01 02 0E 80 02 00 08 A5 08 31 32 33 34 35 36 37 38
+               pin_data[offs++] = 0x80;
+               pin_data[offs++] = 0x02;
+               pin_data[offs++] = 0x00;
+               pin_data[offs++] = newlen;
+               pin_data[offs++] = 0xA5;
+               pin_data[offs++] = newlen;
+               memcpy(pin_data + offs, newref, newlen);
+               offs += newlen;
+
+               sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x01, 
ref_qualifier);
+               apdu.data = pin_data;
+               apdu.datalen = offs;
+               apdu.lc = offs;
+       }
+
        r = sc_transmit_apdu(card, &apdu);
        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
        r = sc_check_sw(card, apdu.sw1, apdu.sw2);
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to