Re: performance: sc_read_record and file caching

Martin Vogt <[email protected]> Wed, 15 Jul 2026 19:04:52 +0200
Newsgroups gmane.comp.encryption.opensc.devel
Message-ID <CAOE8yMArPGPpYcx8YM0yrjYDjMwaEaohaaMZar1EEKzaSjvfNw@mail.gmail.com>
--===============6505233333177550077==
Content-Type: multipart/alternative; boundary="0000000000002717de0656a95331"

--0000000000002717de0656a95331
Content-Type: text/plain; charset="UTF-8"

Hello,

I now have a jcop_read_record, which succeeds. (see demo code below)
For example it reads 10 records all with:

Outgoing APDU (5 bytes):
00 B2 01 04 80 .....

P:41519; T:0x140602795439424 18:49:23.296 [opensc-pkcs11]
reader-pcsc.c:260:pcsc_internal_transmit: called
P:41519; T:0x140602795439424 18:49:23.317 [opensc-pkcs11]
reader-pcsc.c:357:pcsc_transmit:
Incoming APDU (4 bytes):
00 00 90 00 ....

[2,3,4,...A]
up to:
Outgoing APDU (5 bytes):
00 B2 0A 04 80 .....

P:41519; T:0x140602795439424 18:49:23.476 [opensc-pkcs11]
reader-pcsc.c:260:pcsc_internal_transmit: called
P:41519; T:0x140602795439424 18:49:23.493 [opensc-pkcs11]
reader-pcsc.c:357:pcsc_transmit:
Incoming APDU (4 bytes):
00 00 90 00 ....

But then the file is not getting cached because the overall len is 0 and in
the next iteration it sends the
APDUs again.

It fails with:
SC_FILE_EF_LINEAR_VARIABLE_TLV
P:41519; T:0x140602795439424 18:49:23.507 [opensc-pkcs11]
card.c:515:sc_unlock: called
P:41519; T:0x140602795439424 18:49:23.507 [opensc-pkcs11]
reader-pcsc.c:770:pcsc_unlock: called
leave with SC_ERROR_RECORD_NOT_FOUND
GOING to use_file_cache: len:0
FAILED GOING to use_file_cache

(see demo code below)



it turns out that len in pkc15.c is zero and therefor its not get cached.
Should it be able to get cached even for len 0?

best regards,

Martin

demo code:

card-jcop.c

 jcop_ops.read_record = jcop_read_record;

static int
jcop_read_record(struct sc_card *card, unsigned int rec_nr, unsigned int
idx,
u8 *buf, size_t count, unsigned long flags)
{
struct sc_apdu apdu;
int r;
/* XXX maybe use some bigger buffer */
unsigned char resp[SC_MAX_APDU_RESP_SIZE];
unsigned char *encoded_data = NULL, *decoded_data = NULL;
size_t encoded_data_len = 0, decoded_data_len = 0;
     struct jcop_private_data *drvdata=DRVDATA(card);


if (rec_nr > 0xFF)

LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);

printf("JCOP rec_nr:%d idx:%d\n",rec_nr,idx);

if (idx == 0) {

sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB2, rec_nr, 0);
apdu.le = count;
apdu.resplen = count;
apdu.resp = buf;


          drvdata->call_cnt=1;
} else {

// B3 ist not supported, I receive
// SW1 SW2 == 6A 81
// This means "Function not supported"
// Therefore we try 00 "read next" (didn't work)
// next try: enumerate


          // next try: alwas return SC_ERROR_FILE_END_REACHED
          return SC_ERROR_FILE_END_REACHED;

}
apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
if (flags & SC_RECORD_BY_REC_NR)

apdu.p2 |= 0x04;


iso7816_fixup_transceive_length(card, &apdu);
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_TEST_GOTO_ERR(card->ctx, r, "Card returned error");

if (idx == 0) {

r = (int)apdu.resplen;


} else {
          r = (int)apdu.resplen;

}

err:


free(encoded_data);
free(decoded_data);
LOG_FUNC_RETURN(card->ctx, r);


}

pkcs15.c 2613

printf("GOING to use_file_cache: len:%d\n",len);
if (len && p15card->opts.use_file_cache) {

printf("match1\n");

if (((p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES) ||
!private_data)) {

sc_pkcs15_cache_file(p15card, in_path, data, len);


} else {

printf("UNMACTH2\n");


}
} else {

printf("FAILED GOING to use_file_cache\n");
exit(1);

}

--0000000000002717de0656a95331
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello,<br></div><div dir=3D"ltr"></div><div><br></div=
>I now have a jcop_read_record, which succeeds. (see demo code below)<br>Fo=
r example it reads 10 records all with:<br><br>Outgoing APDU (5 bytes):<br>=
00 B2 01 04 80 .....<br><br>P:41519; T:0x140602795439424 18:49:23.296 [open=
sc-pkcs11] reader-pcsc.c:260:pcsc_internal_transmit: called<br>P:41519; T:0=
x140602795439424 18:49:23.317 [opensc-pkcs11] reader-pcsc.c:357:pcsc_transm=
it: =C2=A0<br>Incoming APDU (4 bytes):<br>00 00 90 00 ....<br><br>[2,3,4,..=
.A]<br>up to:<br>Outgoing APDU (5 bytes):<br>00 B2 0A 04 80 .....<br><br>P:=
41519; T:0x140602795439424 18:49:23.476 [opensc-pkcs11] reader-pcsc.c:260:p=
csc_internal_transmit: called<br>P:41519; T:0x140602795439424 18:49:23.493 =
[opensc-pkcs11] reader-pcsc.c:357:pcsc_transmit: =C2=A0<br>Incoming APDU (4=
 bytes):<br>00 00 90 00 ....<br><br>But then the file is not getting cached=
 because the overall len is 0 and in the next iteration it sends the<br>APD=
Us again.<br><br>It fails with:<br>SC_FILE_EF_LINEAR_VARIABLE_TLV<br>P:4151=
9; T:0x140602795439424 18:49:23.507 [opensc-pkcs11] card.c:515:sc_unlock: c=
alled<br>P:41519; T:0x140602795439424 18:49:23.507 [opensc-pkcs11] reader-p=
csc.c:770:pcsc_unlock: called<br>leave with SC_ERROR_RECORD_NOT_FOUND<br>GO=
ING to use_file_cache: len:0<br>FAILED GOING to use_file_cache<br><br>(see =
demo code below)<br><br><br><br>it turns out that len in pkc15.c is zero an=
d therefor its not get cached.<br>Should it be able to get cached even for =
len 0?<br><br>best regards,<br><br>Martin<br><br>demo code:<br><br>card-jco=
p.c<br><br>=C2=A0jcop_ops.read_record =3D jcop_read_record;<br><br>static i=
nt<br>jcop_read_record(struct sc_card *card, unsigned int rec_nr, unsigned =
int idx,<br>u8 *buf, size_t count, unsigned long flags)<br>{<br>struct sc_a=
pdu apdu;<br>int r;<br>/* XXX maybe use some bigger buffer */<br>unsigned c=
har resp[SC_MAX_APDU_RESP_SIZE];<br>unsigned char *encoded_data =3D NULL, *=
decoded_data =3D NULL;<br>size_t encoded_data_len =3D 0, decoded_data_len =
=3D 0;<br>=C2=A0 =C2=A0 =C2=A0struct jcop_private_data *drvdata=3DDRVDATA(c=
ard);<br><br><br>if (rec_nr &gt; 0xFF)<br><blockquote style=3D"margin:0 0 0=
 40px;border:none;padding:0px">LOG_FUNC_RETURN(card-&gt;ctx, SC_ERROR_INVAL=
ID_ARGUMENTS);</blockquote>printf(&quot;JCOP rec_nr:%d idx:%d\n&quot;,rec_n=
r,idx);<br><br>if (idx =3D=3D 0) {<br><br><blockquote style=3D"margin:0 0 0=
 40px;border:none;padding:0px">sc_format_apdu(card, &amp;apdu, SC_APDU_CASE=
_2, 0xB2, rec_nr, 0);<br>apdu.le =3D count;<br>apdu.resplen =3D count;<br>a=
pdu.resp =3D buf;</blockquote><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 drvdat=
a-&gt;call_cnt=3D1;<br>} else {<br><br><blockquote style=3D"margin:0 0 0 40=
px;border:none;padding:0px">// B3 ist not supported, I receive<br>// SW1 SW=
2 =3D=3D 6A 81<br>// This means &quot;Function not supported&quot;<br>// Th=
erefore we try 00 &quot;read next&quot; (didn&#39;t work)<br>// next try: e=
numerate</blockquote><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // next try: al=
was return SC_ERROR_FILE_END_REACHED<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
return SC_ERROR_FILE_END_REACHED;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<br>=
}<br>apdu.p2 =3D (flags &amp; SC_RECORD_EF_ID_MASK) &lt;&lt; 3;<br>if (flag=
s &amp; SC_RECORD_BY_REC_NR)<br><blockquote style=3D"margin:0 0 0 40px;bord=
er:none;padding:0px">apdu.p2 |=3D 0x04;</blockquote><br>iso7816_fixup_trans=
ceive_length(card, &amp;apdu);<br>r =3D sc_transmit_apdu(card, &amp;apdu);<=
br>LOG_TEST_GOTO_ERR(card-&gt;ctx, r, &quot;APDU transmit failed&quot;);<br=
>r =3D sc_check_sw(card, apdu.sw1, apdu.sw2);<br>LOG_TEST_GOTO_ERR(card-&gt=
;ctx, r, &quot;Card returned error&quot;);<br><br>if (idx =3D=3D 0) {<br><b=
r><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px">r =3D (in=
t)apdu.resplen;</blockquote><br>} else {<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 r =3D (int)apdu.resplen;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<br>}<br>=
<br>err:<br><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"=
><br>free(encoded_data);<br>free(decoded_data);<br>LOG_FUNC_RETURN(card-&gt=
;ctx, r);</blockquote><br>}<br><br>pkcs15.c 2613<br><br>printf(&quot;GOING =
to use_file_cache: len:%d\n&quot;,len);<br>if (len &amp;&amp; p15card-&gt;o=
pts.use_file_cache) {<br><br>printf(&quot;match1\n&quot;);<br><br>if (((p15=
card-&gt;opts.use_file_cache &amp; SC_PKCS15_OPTS_CACHE_ALL_FILES) || !priv=
ate_data)) {<br><br><blockquote style=3D"margin:0 0 0 40px;border:none;padd=
ing:0px">sc_pkcs15_cache_file(p15card, in_path, data, len);</blockquote><br=
>} else {<br><br><blockquote style=3D"margin:0 0 0 40px;border:none;padding=
:0px">printf(&quot;UNMACTH2\n&quot;);</blockquote><br>}<br>} else {<br><br>=
printf(&quot;FAILED GOING to use_file_cache\n&quot;);<br>exit(1);<br><br>}<=
br></div>

--0000000000002717de0656a95331--


--===============6505233333177550077==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--===============6505233333177550077==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Opensc-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensc-devel

--===============6505233333177550077==--