martinpaljak / GlobalPlatformPro

🌐 🔐 Manage applets and keys on JavaCard-s like a pro
https://javacard.pro/globalplatform
GNU Lesser General Public License v3.0
704 stars 212 forks source link

T=0: INITIALIZE UPDATE failed SW: 6E00 #67

Open user8547 opened 7 years ago

user8547 commented 7 years ago

Here is T=0 only card that produces SW 0x6E00 on INITIALIZE UPDATE when "OMNIKEY CardMan 1021 00 00" reader is used, while works fine when "Gemalto PC Twin Reader 00 00" is used.

OMNIKEY CardMan 1021 00 00:

[DEBUG] PlaintextKeys - static keys: 
ENC: Ver:0 ID:0 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F KCV: 8BAF47
MAC: Ver:0 ID:0 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F KCV: 8BAF47
KEK: Ver:0 ID:0 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F KCV: 8BAF47
# Detected readers from JNA2PCSC
[*] OMNIKEY CardMan 1021 00 00
SCardConnect("OMNIKEY CardMan 1021 00 00", T=*) -> T=0, 3B6E00004573744549442076657220312E30
SCardBeginTransaction("OMNIKEY CardMan 1021 00 00")
Reader: OMNIKEY CardMan 1021 00 00
ATR: 3B6E00004573744549442076657220312E30
More information about your card:
    http://smartcard-atr.appspot.com/parse?ATR=3B6E00004573744549442076657220312E30

A>> T=0 (4+0000) 00A40400 00 
A<< (0018+2) (698ms) 6F108408A000000003000000A5049F6501FF 9000
[DEBUG] GlobalPlatform - Auto-detected ISD AID: A000000003000000
[DEBUG] GlobalPlatform - Auto-detected block size: 255
A>> T=0 (4+0008) 80500000 08 97AB5C9928DF292C 00
A<< (0000+2) (155ms) 6E00
pro.javacard.gp.GPException: INITIALIZE UPDATE failed SW: 6E00
    at pro.javacard.gp.GPException.check(GPException.java:66)
    at pro.javacard.gp.GlobalPlatform.openSecureChannel(GlobalPlatform.java:484)
    at pro.javacard.gp.GPTool.main(GPTool.java:463)

Gemalto PC Twin Reader 00 00:

[DEBUG] PlaintextKeys - static keys: 
ENC: Ver:0 ID:0 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F KCV: 8BAF47
MAC: Ver:0 ID:0 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F KCV: 8BAF47
KEK: Ver:0 ID:0 Type:DES3 Len:16 Value:404142434445464748494A4B4C4D4E4F KCV: 8BAF47
# Detected readers from JNA2PCSC
[*] Gemalto PC Twin Reader 00 00
SCardConnect("Gemalto PC Twin Reader 00 00", T=*) -> T=0, 3B6E00004573744549442076657220312E30
SCardBeginTransaction("Gemalto PC Twin Reader 00 00")
Reader: Gemalto PC Twin Reader 00 00
ATR: 3B6E00004573744549442076657220312E30
More information about your card:
    http://smartcard-atr.appspot.com/parse?ATR=3B6E00004573744549442076657220312E30

A>> T=0 (4+0000) 00A40400 00 
A<< (0018+2) (251ms) 6F108408A000000003000000A5049F6501FF 9000
[DEBUG] GlobalPlatform - Auto-detected ISD AID: A000000003000000
[DEBUG] GlobalPlatform - Auto-detected block size: 255
A>> T=0 (4+0008) 80500000 08 CFC1C97CC76B1C4C 00
A<< (0028+2) (189ms) 000000008899279C0000FF020043630B9687630B3FC0F6E77514EE13 9000
...

The problem can be reproduced also in non-ISD applet. I.e., by sending APDU "80 50 00 00 08 e4 ff 61 7a 53 f8 01 73 00" to applet, responding with SW "61 1c" and then sending "APDU 80 c0 00 00 1c" to applet. The applet logged received APDUs which where later dumped from the card.

In case of OMNIKEY reader the second APDU received by the applet is incorrect (note the prepended 0x00):

80 50 00 00 08 e4 ff 61 7a 53 f8 01 73
00 80 c0 00 00 

while in the case of Gemalto reader the APDUs received are as expected:

80 50 00 00 08 e4 ff 61 7a 53 f8 01 73 
80 c0 00 00 1c

If the last Le=0x00 byte is removed from the INITIALIZE UPDATE APDU, the GET RESPONSE APDU is received by card correctly, without 0x00 byte prepended. Hence it seems that in case 4 APDU the Le is buffered (in the card or reader!?) and sent before the next APDU.

This is not purely the card bug since with the other reader APDU is sent correctly. This is also not purely the reader bug, since with other T=0 cards and OMNIKEY reader I could not reproduce the problem.

The question to GlobalPlatformPro maintainers is whether workaround of removing Le/Ne byte can be implemented for APDUs sent over T=0?

--- GlobalPlatform.java.orig    2017-04-10 11:21:16.940634110 +0300
+++ GlobalPlatform.java 2017-04-10 11:26:00.336225810 +0300
@@ -470,7 +470,7 @@
        // P1 key version (SCP1)
        // P2 either key ID (SCP01) or 0 (SCP2)
        // TODO: use it here for KeyID?
-       CommandAPDU initUpdate = new CommandAPDU(CLA_GP, INS_INITIALIZE_UPDATE, keys.getKeysetVersion(), keys.getKeysetID(), host_challenge, 256);
+       CommandAPDU initUpdate = new CommandAPDU(CLA_GP, INS_INITIALIZE_UPDATE, keys.getKeysetVersion(), keys.getKeysetID(), host_challenge);

        ResponseAPDU response = channel.transmit(initUpdate);
        int sw = response.getSW();
@@ -992,7 +992,7 @@
        // By default use tags
        int p2 = reg.tags? 0x02 : 0x00;

-       CommandAPDU cmd = new CommandAPDU(CLA_GP, INS_GET_STATUS, p1, p2, data, 256);
+       CommandAPDU cmd = new CommandAPDU(CLA_GP, INS_GET_STATUS, p1, p2, data);
        ResponseAPDU response = transmit(cmd);

        // Workaround for legacy cards, like SCE 6.0 FIXME: this does not work properly
@@ -1028,7 +1028,7 @@
            bo.write(response.getData());

            while (response.getSW() == 0x6310) {
-               cmd = new CommandAPDU(CLA_GP, INS_GET_STATUS, p1, p2 | 0x01, data, 256);
+               cmd = new CommandAPDU(CLA_GP, INS_GET_STATUS, p1, p2 | 0x01, data);
                response = transmit(cmd);

                sw = response.getSW();

The Le byte was introduced as a workaround for Gemalto cards in this commit https://github.com/martinpaljak/GlobalPlatformPro/commit/8981c63ea9570d244198602aef3f81a9480ccea8. I suppose that removing Le for case 4 APDUs over T=0 should not create a problem for Gemalto cards, since Le byte in case 4 APDUs over T=0 is not (should not be) included in TPDU anyway.

LudovicRousseau commented 7 years ago

You/the program should not use a Case-4 APDU with a T=0 card. In fact the driver should convert the Case-4 APDU into 2 TPDU commands (initial command + Get Response command). I just checked ISO 7816-3:2006 page 36.

My CCID driver does NOT convert a Case-4 APDU into 2 TPDU commands. I am even surprised that it works with a Gemalto PC Twin Reader since this is also a TPDU reader.

martinpaljak commented 7 years ago

I think this is a fault from a "misconfigured" Chinese javacard, which behaves in a Chinese way (Unionpay). I know that a misbehaving cards exist, but eventually it must be responded reliably by well-behaving software. How exactly, should be evaluated ASAP.

On Mon, 10 Apr 2017 at 23:37 Ludovic Rousseau notifications@github.com wrote:

You/the program should not use a Case-A APDU with a T=0 card. In fact the driver should convert the Case-4 APDU into 2 TPDU commands (initial command + Get Response command). I just checked ISO 7816-3:2006 page 36.

My CCID driver does NOT convert a Case-4 APDU into 2 TPDU commands. I am even surprised that it works with a Gemalto PC Twin Reader since this is also a TPDU reader.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/martinpaljak/GlobalPlatformPro/issues/67#issuecomment-293071152, or mute the thread https://github.com/notifications/unsubscribe-auth/AACzthuZvUpMTrXNnlZ0RhKSAHZ1tA2Tks5rupLigaJpZM4M4hft .

--

typos expected due to mobile device

erwinyo87 commented 7 years ago

try add this code to your gp code System.setProperty("sun.security.smartcardio.t0GetResponse", "false");

6E00 is happening too to my project with no ISD i solved it with the code this is only happening in java, because i try use PyApduTools initialize update working fine