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