Reputation: 21
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
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.
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.
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).
If the old formatted is not working anymore you have 3 options:
Upvotes: 0