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
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel