
gniibe at fsij
Dec 20, 2011, 6:10 PM
Post #2 of 2
(119 views)
Permalink
|
On 2011-12-20 at 12:51 +0900, NIIBE Yutaka wrote: > commit 37fadead90e985b544c9f817cf7c7b0ada797d3c Let me explain this commit a bit. Note that this is not the patch to fully support extended APDU exchange level communication, but to support most of cases. I think that full support requires to have 64KiB buffer, but for almost all cases for OpenPGP card interaction (I mean, Gnuk), it doesn't require such a big buffer. The maximum case is for handling of Data Object of 0x7f21 ("CERT-3"), This commit doesn't handle this case. I will write another mail about Data Object of 0x7f21 ("CERT-3"). Next maximum case is to store key from host to card. The magic number 289 comes from for 2048-bit key: 7 (header of CCID message) + 22 (Extended header list, kind of key, private key template, tag) + 4 (E : 00 01 00 01) + 128 (P) + 128 (Q) Besides, the commit supports packets in a chain. With these changes, OpenPGP card v2 with extended APDU exchange level communication (== Gnuk) works well (except DO 0x7f21). I paste output of "git show 37fadead90e985b544c9f817cf7c7b0ada797d3c" to ask your review and comment. commit 37fadead90e985b544c9f817cf7c7b0ada797d3c Author: NIIBE Yutaka <gniibe [at] fsij> Date: Mon Dec 5 12:00:14 2011 +0900 Support extended APDU exchange level somehow. * ccid-driver.c (ccid_transceive_apdu_level): Permit sending packet where apdulen <= 289. Support receiving packets in a chain. diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 7338ccc..5755b07 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -2590,8 +2590,8 @@ ccid_transceive_apdu_level (ccid_driver_t handle, /* The maximum length for a short APDU T=1 block is 261. For an extended APDU T=1 block the maximum length 65544; however - extended APDU exchange level is not yet supported. */ - if (apdulen > 261) + extended APDU exchange level is not fully supported yet. */ + if (apdulen > 289) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ msg[0] = PC_to_RDR_XfrBlock; @@ -2614,8 +2614,51 @@ ccid_transceive_apdu_level (ccid_driver_t handle, if (rc) return rc; - apdu = msg + 10; - apdulen = msglen - 10; + if (msg[9] == 1) + { + size_t total_msglen = msglen; + + while (1) + { + unsigned char status; + + msg = recv_buffer + total_msglen; + + msg[0] = PC_to_RDR_XfrBlock; + msg[5] = 0; /* slot */ + msg[6] = seqno = handle->seqno++; + msg[7] = bwi; /* bBWI */ + msg[8] = 0x10; /* Request next data block */ + msg[9] = 0; + set_msg_len (msg, 0); + msglen = 10; + + rc = bulk_out (handle, msg, msglen, 0); + if (rc) + return rc; + + rc = bulk_in (handle, msg, sizeof recv_buffer - total_msglen, &msglen, + RDR_to_PC_DataBlock, seqno, 5000, 0); + if (rc) + return rc; + status = msg[9]; + memmove (msg, msg+10, msglen - 10); + total_msglen += msglen - 10; + if (total_msglen >= sizeof recv_buffer) + return CCID_DRIVER_ERR_OUT_OF_CORE; + + if (status == 0x02) + break; + } + + apdu = recv_buffer + 10; + apdulen = total_msglen - 10; + } + else + { + apdu = msg + 10; + apdulen = msglen - 10; + } if (resp) { -- _______________________________________________ Gnupg-devel mailing list Gnupg-devel [at] gnupg http://lists.gnupg.org/mailman/listinfo/gnupg-devel
|