Init update given 6985 and 61xx in two different scenario
Asked Answered
A

5

10

I have a java card and i write a small code to send APDU to java card. here when i am sending Init_Update command , m getting 0x6985 like:-

CMD -> 80 50 00 00 08 11 22 33 44 55 66 77 88
RES <- 6985

But when I am sending this command with other tool , it is giving required result like:-

Transmit: 80 50 00 00 08    []
  11 22 33 44 55 66 77 88                            ."3DUfw.
Card answered: 61 1C

My java code is working good for other java card I have. Could anybody tell me what can be cause of this different behavior..

// full java code


     public static void main(String[] args) {
            // TODO code application logic here
            try
            {

        factory = TerminalFactory.getDefault();
                    terminals = factory.terminals().list(); 
                terminal = terminals.get(0);
                card = terminal.connect("*");
                    channel =card.getBasicChannel();

                    CommandAPDU cmdAPDU;
                     ResponseAPDU response;
                    byte[] select_isd = {(byte) 0x00,(byte) 0xA4,(byte) 0x04,(byte) 0x00,(byte) 0x08,(byte) 0xA0,(byte) 0x00,
                                         (byte) 0x00,(byte) 0x00,(byte) 0x03,(byte) 0x00,(byte) 0x00,(byte) 0x00 };
                    cmdAPDU = new CommandAPDU(select_isd);
                     response = channel.transmit(cmdAPDU);
                    byte[] INIT_UPDATE = {(byte) 0x80,(byte) 0x50,(byte) 0x00,(byte) 0x00,(byte) 0x08,(byte) 0x11,(byte) 0x22,
                                          (byte) 0x33,(byte) 0x44,(byte) 0x55,(byte) 0x66,(byte) 0x77,(byte) 0x88 };
                     cmdAPDU = new CommandAPDU(INIT_UPDATE);
                     response = channel.transmit(cmdAPDU);
 }
        catch( Exception ex)
        {

        }
    }

Other tool log is look like:-

Card opened
12 bytes ATR received:
3B 68 00 00 00 73 C8 40 00 00 90 00

Transmit: 00 A4 04 00 08    [SELECT FILE]
  A0 00 00 00 03 00 00 00                            ........
Card answered: 61 12

Transmit: 00 C0 00 00 12    [GET RESPONSE]
Card answered: 90 00
  6F 10 84 08 A0 00 00 00 03 00 00 00 A5 04 9F 65    o..............e
  01 FF                                              ..

Transmit: 80 50 00 00 08    []
  11 22 33 44 55 66 77 88                            ."3DUfw.
Card answered: 61 1C

But when i run my java code I am getting 6985 for INIT_UPDATE command.

Please let me know if require any other information for my side..

==newly added=== I tried to run my script in JCOP shell, my script is like:-

/mode trace=on
/terminal 
/atr
/send 80CAA08D05
/send 802E000014B555C94B0B2368B4840201808502032288020060
/send 80D8000000
/atr
/send 80500000081122334455667788

and it give me required result. Same i tried to implement in java , my new java code is look like:- =====New Updated JAVA Code===

factory = TerminalFactory.getDefault();
         terminals = factory.terminals().list(); 
         terminal = terminals.get(0);

         card = terminal.connect("*");
         channel =card.getBasicChannel();

         CommandAPDU cmdAPDU;
         ResponseAPDU response;
         byte[] x = { (byte) 0x80, (byte) 0xCA, (byte) 0xA0,(byte) 0x8D,(byte)0x05};
         byte[] y = {    remove command for security reasons};
         byte[] z = {     (byte) 0x80, (byte) 0xD8, (byte) 0x00, (byte) 0x00, (byte) 0x00}; // it set default key


           cmdAPDU = new CommandAPDU(x);
         response = channel.transmit(cmdAPDU);
                System.out.println(response.toString());

                  cmdAPDU = new CommandAPDU(y);
         response = channel.transmit(cmdAPDU);
                System.out.println(response.toString());

                           cmdAPDU = new CommandAPDU(z);
         response = channel.transmit(cmdAPDU);
                System.out.println(response.toString());

                   card.disconnect(true);
                    card = terminal.connect("*");
                   channel =card.getBasicChannel();


         byte[] INIT_UPDATE = {(byte) 0x80,(byte) 0x50,(byte) 0x00,(byte) 0x00,(byte) 0x08,(byte) 0x11,(byte) 0x22,(byte) 0x33,(byte) 0x44,(byte) 0x55,(byte) 0x66,(byte) 0x77,(byte) 0x88 };

         cmdAPDU = new CommandAPDU(INIT_UPDATE);
        response = channel.transmit(cmdAPDU);
Arawak answered 27/4, 2015 at 5:0 Comment(17)
have you selected ISD before sending initialize update?Or send ATR before sending initialize update.Theatrics
Please add this part of your code, if possible.Porridge
611C means there are 0x1C = 28 bytes to read. You should respond to 61XX with GET RESPONSE command (00 C0 00 00 XX) to get your response data.Nissen
@anurag I tried to call ISD before Init-update, it was fine in other tool but in java code ISD is responding with 0x6112 but unit update still giving 0x6985.what is send atr?Arawak
@Abraham code edited, please check.Arawak
I think there is only two scenario! 1- Two reader connected to the computer and this two tools target two different card! 2- Your reader is both contact and contact-less and also your card is a Hybrid card (Dual-interface with two different chip inside). One interface is in Locked life cycle state and the other is not locked! Your program target one interface and the other tool target other interface!! :)) I know these are really rare situations!Porridge
@abraham My card is dual interface card but my reader is contact only and i am testing my java code with contact scenario....Arawak
I would suggest that you show us more code and, in particular what other commdns you send in your code/are sent by that tool you are using.Jacklighter
@MichaelRoland I updated the full code which I am using. Please check.Arawak
@rohitamitpathak What response do you get for the select_isd command when executing your code?Jacklighter
@MichaelRoland it is returning 9000 with other FCI data.Arawak
@rohitamitpathak Just a wild guess, but you might want to try to add an additional (byte) 0x00 (i.e. an Le field) at the end of your INIT_UPDATE command.Jacklighter
@MichaelRoland I tried it but result is same.Arawak
@Abraham I fired some set of command from jcshell and implement same in java code you can check. JCshell gives good response while java code still giving me 6985 when INIT_UPDATE fire. Oh sorry I forget to remove this from jcshell script. Please remove it or make it xxxxxxxArawak
@rohitamitpathak I couldn't edit my comment, so I remove it. thanks for your response.Porridge
@rohitamitpathak Do you mean that New Updated JAVA Cod still doesn't work fine?!!Porridge
yes i am still getting 0x6985 when sending command via java code, jcsh not giving 6985Arawak
G
7

6985 means conditions of use not satisfied. As you didn't use any keys up till now it it probably means that the card is locked or terminated.


611C is an status word used for APDU's send over T=0. T=0 doesn't handle both command and response (aka "ISO case 4") in the same APDU, so a GET RESPONSE is required for ISO case 4 commands. Either the first application handles this out of sight (as Java Card itself does) - combining the two APDU's - or it creates a T=1 connection instead of a T=0 connection.

It has little to do with the 6985 status word because you would expect this warning to be produced before the business logic of the INITIALIZE UPDATE command is processed - the command is only processed if output can be produced.

Gravelblind answered 28/4, 2015 at 16:33 Comment(4)
Actually my card is not locked because it is giving 611C in other tool, you are right , javax.smartcard.io handle get response internally, so we don't need to worry about. I am worried why my java code returning 6985 with this card.Arawak
@Maarten Bodewes: Sorry to disagree: 69 85 means conditions of use not satisfied while security.conditions not satisfied is represented by 69 82.Farrah
@guidit Thanks, substantially edited answer. There were quite a few things wrong with it but the gist of the answer stays the same.Gravelblind
@Maarten : Sorry to disagree : Initialized Update command never give 6985, if the Card is Terminated or Locked. Rather as per specification Mapping Guideline GP v2.1.1 on v2.2.1 under section 6.5.5 : If the Card is Terminated then a response of '6D00' is returned. And as per GP2.2.1 specification : Initialized Update command works with Card Life Cycle State (CLCS) Locked, because if you moved CLCS from Secure to Locked via Secure session (SCP02) and then moving CLCS back to Secured state (from Locked state) you need to establish secure session via InitUpdate and External Authenticate commands.Heartbreaker
H
4
  1. For SW '6985'

As per the specification Mapping Guideline of Existing GP v2.1.1 Implementation on v2.2.1 : under section 6.5.2

" If a secure channel is currently active on a logical channel other than the logical channel on which this command (Initialize Update command) was issued, a response of '6985' is returned."

Kindly cross check with this behavior in the case when Initialize Update command fails with 6985.

  1. For SW '611C'

If the information is too long for a single response data field, then the card shall return the beginning of the information followed by SW1-SW2 set to '61XX'. Then a subsequent GET RESPONSE provides 'XX' bytes of information. The process may be repeated until the card sends SW1-SW2 set to '9000'.

Here in this case you need to send GET RESPONSE command with P3 as 1C and CARD will return 1C bytes of data.

Heartbreaker answered 5/5, 2015 at 17:23 Comment(5)
How we handle secure channel kind of things, we Just sending 80 50 00 00 08 11 22 33 44 55 66 77 88????Arawak
@Rohit : 80 50 00 00 08 11 22 33 44 55 66 77 88 is nothing but Initialized Update command which with the help of External Authenticate command is used to initiate Secure Session (SCP02 session). Initialized Update command can give 6985 because of some reasons, in which one of them I explained above i.e. if logical channels are supported and secure session is active on a security domain in one logical channel then if you try to initiate secure session (via sending Initialized Update command) on same security domain in other logical channel then Initialized Update command will give 6985.Heartbreaker
Check whether secure session is currently active on same security domain (on which you are sending Initialized update command) in some other logical channel. Better close all other logical channel (if possible) via Mange channel command (see Global platform specification) and then check your scenario.Heartbreaker
Some other reasons due to which Initialized Update command can give 6985 are : 1- If SCP02 key set is not present on security domain (on which Initialized Update command is issued). SCP02 key sets are from 20 to 2F. Kindly check this whether key set is present or not. 2- If Security domain (in which Initialized Update command is issued) do not has SCP capability (please refer UICC configuration specification for this, and see Tag '81' in SD installation parameter), kindly cross check the SCP capability also.Heartbreaker
I found the cod is quite simple, getting basic channel and transmit INIT_update on same channel. I am sorry but what more you want me to do is not clear. For your information, I tried this with Jcop shell script, my script is like /mode trace=on /terminal /atr /send 80CAA08D05 /send 802E000014xxxxxxxxxx... /send 80D8000000 /atr #INITUPDATE /send 80500000081122334455667788 it is working fine and giving 61xxArawak
C
0

You can use the BusHound to catch some APDUs,then compare and analyse the differences between the two tools during sending commands.

Cerium answered 29/4, 2015 at 6:54 Comment(1)
I tried but not find a place to send my command like :- 80 50 00 00 08 11 22 33 44 55 66 77 88Arawak
P
0

May I ask you to try this program also?

 public static void main(String[] args) {
     try{
         factory = TerminalFactory.getDefault();
         terminals = factory.terminals().list(); 
         terminal = terminals.get(0);

         card = terminal.connect("*");
         channel =card.getBasicChannel();

         CommandAPDU cmdAPDU1;
         CommandAPDU cmdAPDU2;
         ResponseAPDU response1;
         ResponseAPDU response2;

         byte[] select_isd = {(byte) 0x00,(byte) 0xA4,(byte) 0x04,(byte) 0x00,(byte) 0x08,(byte) 0xA0,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x03,(byte) 0x00,(byte) 0x00,(byte) 0x00 };
         byte[] INIT_UPDATE = {(byte) 0x80,(byte) 0x50,(byte) 0x00,(byte) 0x00,(byte) 0x08,(byte) 0x11,(byte) 0x22,(byte) 0x33,(byte) 0x44,(byte) 0x55,(byte) 0x66,(byte) 0x77,(byte) 0x88 };

         cmdAPDU1 = new CommandAPDU(select_isd);
         cmdAPDU2 = new CommandAPDU(INIT_UPDATE);
         response1 = channel.transmit(cmdAPDU1);
         response2 = channel.transmit(cmdAPDU2);
         }
     catch( Exception ex)
     {

     }
}

I'm afraid if the new CommandAPDU between transmit methods, reset the connection between the card and the reader.

Update:

If the above program return the same error, please try this one also :

public static void main(String[] args) {
     try{
         factory = TerminalFactory.getDefault();
         terminals = factory.terminals().list(); 
         terminal = terminals.get(0);

         card = terminal.connect("*");
         channel =card.getBasicChannel();

         CommandAPDU cmdAPDU;
         ResponseAPDU response;


         byte[] select_isd = {(byte) 0x00,(byte) 0xA4,(byte) 0x04,(byte) 0x00,(byte) 0x08,(byte) 0xA0,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x03,(byte) 0x00,(byte) 0x00,(byte) 0x00 };
         byte[] get_response={(byte)0x00,(byte)0xC0 ,(byte)0x00 ,(byte)0x00 ,(byte)0x12};
         byte[] INIT_UPDATE = {(byte) 0x80,(byte) 0x50,(byte) 0x00,(byte) 0x00,(byte) 0x08,(byte) 0x11,(byte) 0x22,(byte) 0x33,(byte) 0x44,(byte) 0x55,(byte) 0x66,(byte) 0x77,(byte) 0x88 };

         cmdAPDU = new CommandAPDU(select_isd);
         response = channel.transmit(cmdAPDU);

         cmdAPDU = new CommandAPDU(get_response);
         response = channel.transmit(cmdAPDU);

         cmdAPDU = new CommandAPDU(INIT_UPDATE);
         response = channel.transmit(cmdAPDU);

         }
     catch( Exception ex)
     {

     }
}

Eagerly waiting for your response.

Update-2:

I think trying a Python script is useful to find out what is the problem. Can you try this also:

>>> from smartcard.System import readers
>>> from smartcard.util import toHexString
>>>
>>> r=readers()
#if you have more than one reader or a dual interface reader, put the right index in the below line instead of `0`
>>> connection = r[0].createConnection()
>>> connection.connect()
>>>
>>> SELECT = [0xA0, 0xA4, 0x04, 0x00, 0x08 , 0xA0 , 0x00 , 0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 ]
>>> GET_RESPONSE = [ 0x00, 0xC0, 0x00, 0x00, 0x12]
>>> INIT_UPDATE= [0x80, 0x50, 0x00, 0x00, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88]
>>>
>>> data, sw1, sw2 = connection.transmit( SELECT)
>>> print "%s %x %x" % (data, sw1, sw2)
>>>
#if the sw1 and sw2 of above command is not `0x6112`, don't send GET_RESPOSE command.
>>> data, sw1, sw2 = connection.transmit( GET_RESPONSE)
>>> print "%s %x %x" % (data, sw1, sw2)    
>>>
>>> data, sw1, sw2 = connection.transmit( INIT_UPDATE)
>>> print "%s %x %x" % (data, sw1, sw2)

Note that the above script is for Python 2.7 and you must istall PySCard also

Porridge answered 6/5, 2015 at 7:46 Comment(4)
thanks for suggestion. but your first example returning ResponseAPDU: 20 bytes, SW=9000 ResponseAPDU: 2 bytes, SW=6985 and second example returning ResponseAPDU: 20 bytes, SW=9000 ResponseAPDU: 2 bytes, SW=6f00 ResponseAPDU: 2 bytes, SW=6985Arawak
It's totally strange behaviour. I dont know why it is happening.Arawak
@rohitamitpathak May I ask you to try the Python script that I added to my asnwer in Updae-2 section also?Porridge
I tried this with Jcop shell script, my script is like /mode trace=on /terminal /atr /send 80CAA08D05 /send 802E000014xxxxxxxxxx... /send 80D8000000 /atr #INITUPDATE /send 80500000081122334455667788 it is working fine and giving 61xxArawak
B
0

The problem is that is mandatory an EXTERNAL UPDATE command immediately after of INITIAL UPDATE. If you receive a 61nn response and send the C0 command to retrieve the remainder data from INITIAL UPDATE, the EXTERNAL AUTH command fails indicating that an "access condition not satisfied" [6982]; then, you have al least two possible alternatives to fix this:

  1. Connect your Reader in T=1 protocol mode

lResult=SCardConnect( *pphContext, tszReaderName, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1,//<--FORCE TO SCARD_PROTOCOL_T1, pphCard, &dwActiveProtocol) )); //<--VERIFY THAT THIS VALUE IS SETTED TO 2 Adjust your engine APDU sender to use T1 protocol to receive the information on the response avoiding the use of the getResp command

{00 C0 00 00 nn}
  1. (I assumed that's OK, I'm still working in this) If you want to use T0 protocol, you must resend two times the INITIAL UPDATE command, the first time is for to obtain the data from the response using a C0 command. The second try will re-establish the secure channel lost to use the C0 Apdu command. Here, is possible that you need some mechanism to manage channel command to close additional channels (see https://globalplatform.org/wp-content/uploads/2018/06/GPC_Specification-2.2.1.pdf paragraph 11.7), because you could receive a 6985 as response and you smartcard appears unabled to execute INITIAL UPDATE with no error.
Broad answered 24/8, 2021 at 19:13 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.