martin rupp
martin rupp

Reputation: 21

How to communicate programmatically with the JCOP simulator, how to programmatically send APDUs to a JCOP simulator?

The JCOP simulator is a tool provided by NXP which allows the simulation of the JCOP OS via a plug-in available for Eclipse (JCOP tools). It provides a simulation of the Javacard Machine similar to other tools such as JCIDE. However, the JCOP simulator does not allow direct communication from terminals by exposing itself as a PC/SC reader. Instead it uses a specific network protocol. The JCOP simulator listens by default on three network ports for respectively contact, contactless and debug. There exist tools such as: JCOPVR https://code.google.com/archive/p/jcopvr/ which can provide a way to communicate with the JCOP simulator via PC/SC. These tools are usually based around ifhandler.c ( ifhandler) developed by MUSCLE project. But as it appears that the network protocol used by the JCOP simulator has changed since the latest release of these tools, they do not seem to work. Therefore, my question is: is there a way to get a tool that allows to programmatically send and receive apdus (and other similar functions) to the latest version of the JCOP simulator - JCOP Simulator JCOP 4.7 R4.10.12 U ? Alternatively, are there resources about the network protocol used by the latest version of the JCOP simulator, since the tools mentioned before may need simple fine-tuning to be working correctly with the new simulator versions? I assume this problem have been encountered before by smartcard developers working with JCOP. Of course, the ideal way would be to ask NXP about this but as these are third party tools developed outside NXP, they may not be willing to support or exposes private specifications.

This is a snippet of the base code ifhandler.c, That function sends and receives APDUs to the JCOP simulator but doesn't seem to work with latest version of the simulator JCOP 4.7 R4.10.12 (or I was not able to make it work correctly)

RESPONSECODE IFDHTransmitToICC ( DWORD Lun, SCARD_IO_HEADER SendPci, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength, PSCARD_IO_HEADER RecvPci ) { /* This function performs an APDU exchange with the card/slot specified by Lun. The driver is responsible for performing any protocol specific exchanges such as T=0/1 ... differences. Calling this function will abstract all protocol differences.
 SendPci
 Protocol - 0, 1, .... 14
 Length   - Not used.

 TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F 0x00)
 TxLength - Length of this buffer.
 RxBuffer - Receive APDU example (0x61 0x14)
 RxLength - Length of the received APDU.  This function will be passed
 the size of the buffer of RxBuffer and this function is responsible for
 setting this to the length of the received APDU.  This should be ZERO
 on all errors.  The resource manager will take responsibility of zeroing
 out any temporary APDU buffers for security reasons.

 RecvPci
 Protocol - 0, 1, .... 14
 Length   - Not used.

 Notes:
 The driver is responsible for knowing what type of card it has.  If the current
 slot/card contains a memory card then this command should ignore the Protocol
 and use the MCT style commands for support for these style cards and transmit 
 them appropriately.  If your reader does not support memory cards or you don't
 want to then ignore this.

 RxLength should be set to zero on error.

 returns:
 
 IFD_SUCCESS
 IFD_COMMUNICATION_ERROR
 IFD_RESPONSE_TIMEOUT
 IFD_ICC_NOT_PRESENT
 IFD_PROTOCOL_NOT_SUPPORTED*/
int ret;
dbg_log("JCOP.Transmit(): Lun 0x%x\n", Lun);
dbg_log("JCOP.Transmit(): io_hdr proto %d, length %d\n", SendPci.Protocol, SendPci.Length);
dbg_log("JCOP.Transmit(): txb 0x%x, txbl %d, rxb 0x%x, rxbl %d\n", TxBuffer, TxLength, RxBuffer, *RxLength);

if (JCOP_socket < 0){
dbg_log("JCOP.Transmit(): invalid jcop socket\n");
return IFD_COMMUNICATION_ERROR;
}

if (TxLength >= 256){
dbg_log("JCOP.Transmit(): invalid transmit buffer size %d\n", TxLength);
jcop_close();
return IFD_COMMUNICATION_ERROR;
}

// copy data from send_buffer to JCOP_buffer and send
JCOP_buffer[0] = 0x1;
JCOP_buffer[1] = 0x0;
JCOP_buffer[2] = TxLength/256;
JCOP_buffer[3] = TxLength%256;
memcpy(JCOP_buffer+4, TxBuffer, TxLength);

dbg_ba2s(JCOP_buffer, TxLength+4);
dbg_log("jcop send: %s\n", DBG_buf);

// send apdu
ret = _write(JCOP_socket, JCOP_buffer, TxLength + 4);
if (ret < 0){
dbg_log("Failed to transmit to jcop\n");
jcop_close();
return IFD_COMMUNICATION_ERROR;
}

// read apdu
ret = jcop_read(0x1);
if (ret < 0){
dbg_log("Failed to receive apdu response\n");
return IFD_COMMUNICATION_ERROR;
}
*RxLength = ret - 4;
memcpy(RxBuffer, JCOP_buffer+4, *RxLength);
dbg_ba2s(RxBuffer, *RxLength);
dbg_log("jcop response apdu: %s\n", DBG_buf);

return IFD_SUCCESS;

}

Upvotes: 1

Views: 360

Answers (1)

Nodir Gulyamov
Nodir Gulyamov

Reputation: 365

The former JCOP Simulator Architect (now working on other parts of JCOP) is here. I was the co-author of the new JCOP Simulator network protocol and will try to answer to your question without violating my NDA.

A little history

The network protocol which communicates to the JCOP Simulator called JRCP (JCOP Remote Connection Protocol). The initial version (version 1) was designed by IBM and it was very basic APDU exchange protocol. The current version (version 2) is fully redesigned to support multi-interface, HCI events, multiple targets etc. I doubt that any open source tool is supporting it.

Old message format

It must contain backward compatibility in the following OLD message format:

------------------------------------------------------------
| MTY (1 byte) | NAD (1 byte) | Length (2 bytes) | PAYLOAD |
------------------------------------------------------------

MTY = Message Type

NAD = Node Address

Length = length of the payload

Payload = your APDU

But please take this info with a grain of salt because latest version probably dropped the backward compatibility. (It was working when I stepped out 5 years ago).

Proposed solutions:

If the old formatted is not working anymore you have 3 options:

  1. Under your current NDA with NXP you can request JRCP protocol specification. I know the we provided it to some customers.
  2. You can request (I am not sure that it is still available) Virtual PCSC tool from NXP which is capable to provide PCSC access to the JCOP Simulator
  3. The fastest is usage of JCShell which is a part of the JCOP Tools (integrated in the Eclipse) and send your APDUs in the simple command window.

Upvotes: 0

Related Questions