I recently got a dell latitude d830 laptop, which instead of the spec-less,
pci smartcard controller from TI that my last machine had, includes an
oz776 usb controller. This gave me the opportunity to implement/test ccid
character mode support for openct. The patch for this is attached.
This patch does not address the problem with earlier versions of this
device that had broken descriptors. Now that I know about this problem (I
don't read opensc-user, so I didn't see the discussion of it there), I will
probably work something up in the next few weeks.
T=1 cards that advertise an IFSD of 254 will not work with this device, due
to proto-t1.c rejecting 254 byte I-Blocks from non-block-oriented devices.
I do not know why t1_xcv behaves this way.
It appears that these devices support a usb-passthrough mode. At least, the
first time I inserted a cryptoflex/egate device into the slot, it appeared
as a usb device (and I found this:
<http://www.o2micro.com/news/pr_050822.html>). However, ever since I
started using the device with openct, this no longer happens, even after a
powercycle. Does anyone know how this is configured?
Lastly, it appears that the usb id was specified incorrectly in
etc/Info.plist and etc/openct.conf.
b97/7761 is a usb hub. The actual smartcard devices are b97/7762 (according
to ccid/readers/Oz776S.txt from pcsc) and b97/7772 (my new machine)
Index: src/ifd/ifd-ccid.c
===================================================================
--- src/ifd/ifd-ccid.c (revision 966)
+++ src/ifd/ifd-ccid.c (working copy)
@@ -449,9 +449,18 @@
unsigned char sendbuf[CCID_MAX_MSG_LEN + 1];
unsigned char recvbuf[CCID_MAX_MSG_LEN + 1];
int r;
+ unsigned char ctlbuf[3], *ctlptr=0;
+ ctlptr=NULL;
+ if (st->reader_type == TYPE_CHAR) {
+ ctlbuf[0] = 0;
+ ctlbuf[1] = rlen & 0xff;
+ ctlbuf[2] = (rlen >> 8) & 0xff;
+ ctlptr = ctlbuf;
+ }
+
r = ccid_prepare_cmd(reader, sendbuf, st->maxmsg,
- slot, CCID_CMD_XFRBLOCK, NULL, sbuf, slen);
+ slot, CCID_CMD_XFRBLOCK, ctlptr, sbuf, slen);
if (r < 0)
return r;
@@ -694,13 +703,6 @@
st->flags |= FLAG_NO_PTS;
st->ifsd = ccid.dwMaxIFSD;
- if (st->reader_type == TYPE_CHAR) {
- ct_error("ccid: Character mode readers not supported");
- free(st);
- ifd_device_close(dev);
- return -1;
- }
-
/* must provide AUTO or at least one of 5/3.3/1.8 */
if (st->voltage_support == 0) {
ct_error
@@ -1118,7 +1120,7 @@
return ptslen;
}
r = ccid_exchange(reader, s, pts, ptslen, ptsret,
- sizeof(ptsret));
+ ptslen);
if (r < 0)
return r;
r = ifd_verify_pts(&atr_info, proto, ptsret, r);
@@ -1130,8 +1132,13 @@
memset(¶mbuf[r], 0, sizeof(parambuf) - r);
if (proto == IFD_PROTOCOL_T0) {
- p = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT,
- reader, slot->dad);
+ if (st->reader_type == TYPE_CHAR) {
+ p = ifd_protocol_new(proto,
+ reader, slot->dad);
+ } else {
+ p = ifd_protocol_new(IFD_PROTOCOL_TRANSPARENT,
+ reader, slot->dad);
+ }
} else {
p = ifd_protocol_new(proto, reader, slot->dad);
if (p) {
@@ -1155,6 +1162,9 @@
ct_error("%s: internal error", reader->name);
return -1;
}
+ /* ccid_recv needs to know the exact expected data length */
+ if (st->reader_type == TYPE_CHAR)
+ ifd_protocol_set_parameter(p, IFD_PROTOCOL_BLOCK_ORIENTED, 0);
if (slot->proto) {
ifd_protocol_free(slot->proto);
slot->proto = NULL;
@@ -1237,6 +1247,8 @@
free(st->sbuf[dad]);
st->sbuf[dad] = NULL;
st->slen[dad] = 0;
+ if (r < 0)
+ ifd_debug(3, "failed: %d", r);
return r;
}
_______________________________________________
opensc-devel mailing list
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel