|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||
java.lang.Objectjavacard.framework.APDU
Application Protocol Data Unit (APDU) is the communication format between the card and the off-card applications. The format of the APDU is defined in ISO specification 7816-4.
This class only supports messages which conform to the structure of command and response defined in ISO 7816-4. The behavior of messages which use proprietary structure of messages ( for example with header CLA byte in range 0xD0-0xFE ) is undefined. This class does not support extended length fields.
The APDU object is owned by the Java Card runtime
environment. The APDU class maintains a byte array
buffer which is used to transfer incoming APDU header and data bytes
as well as outgoing data. The buffer length must be at least 133
bytes ( 5 bytes of header and 128 bytes of data ). The Java Card
runtime environment must zero out the APDU buffer before each new
message received from the CAD.
The Java Card runtime environment designates the
APDU object as a temporary Java Card runtime
environment Entry Point Object (See Runtime Specification for
the Java Card Platform, section 6.2.1 for details). A temporary
Java Card runtime environment Entry Point Object can be accessed
from any applet context. References to these temporary objects
cannot be stored in class variables or instance variables or array
components.
The Java Card runtime environment similarly marks the APDU buffer as a global array (See Runtime Specification for the Java Card Platform, section 6.2.2 for details). A global array can be accessed from any applet context. References to global arrays cannot be stored in class variables or instance variables or array components.
The applet receives the APDU instance to process
from the Java Card runtime environment in the
Applet.process(APDU) method, and the first five bytes [
CLA, INS, P1, P2, P3 ] are available in the APDU buffer.
The APDU class API is designed to be transport
protocol independent. In other words, applets can use the same APDU
methods regardless of whether the underlying protocol in use is T=0
or T=1 (as defined in ISO 7816-3).
The incoming APDU data size may be bigger than the APDU buffer
size and may therefore need to be read in portions by the applet.
Similarly, the outgoing response APDU data size may be bigger than
the APDU buffer size and may need to be written in portions by the
applet. The APDU class has methods to facilitate this.
For sending large byte arrays as response data, the
APDU class provides a special method
sendBytesLong() which manages the APDU buffer.
// The purpose of this example is to show most of the methods
// in use and not to depict any particular APDU processing
public void process(APDU apdu){
// ...
byte[] buffer = apdu.getBuffer();
byte cla = buffer[ISO7816.OFFSET_CLA];
byte ins = buffer[ISO7816.OFFSET_INS];
...
// assume this command has incoming data
// Lc tells us the incoming apdu command length
short bytesLeft = (short) (buffer[ISO7816.OFFSET_LC] & 0x00FF);
if (bytesLeft < (short)55) ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
short readCount = apdu.setIncomingAndReceive();
while ( bytesLeft > 0){
// process bytes in buffer[5] to buffer[readCount+4];
bytesLeft -= readCount;
readCount = apdu.receiveBytes ( ISO7816.OFFSET_CDATA );
}
//
//...
//
// Note that for a short response as in the case illustrated here
// the three APDU method calls shown : setOutgoing(),setOutgoingLength() & sendBytes()
// could be replaced by one APDU method call : setOutgoingAndSend().
// construct the reply APDU
short le = apdu.setOutgoing();
if (le < (short)2) ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
apdu.setOutgoingLength( (short)3 );
// build response data in apdu.buffer[ 0.. outCount-1 ];
buffer[0] = (byte)1; buffer[1] = (byte)2; buffer[3] = (byte)3;
apdu.sendBytes ( (short)0 , (short)3 );
// return good complete status 90 00
}
The APDU class also defines a set of
STATE_.. constants which represent the various
processing states of the APDUobject based on the
methods invoked and the state of the data transfers. The
getCurrentState() method returns the current state.
Note that the state number assignments are ordered as follows: STATE_INITIAL < STATE_PARTIAL_INCOMING < STATE_FULL_INCOMING < STATE_OUTGOING < STATE_OUTGOING_LENGTH_KNOWN < STATE_PARTIAL_OUTGOING < STATE_FULL_OUTGOING.
The following are processing error states and have negative state number assignments : STATE_ERROR_NO_T0_GETRESPONSE, STATE_ERROR_T1_IFD_ABORT, STATE_ERROR_IO and STATE_ERROR_NO_T0_REISSUE.
APDUException| Field Summary | |
static byte |
PROTOCOL_MEDIA_CONTACTLESS_TYPE_A
Transport protocol Media - Contactless Type A |
static byte |
PROTOCOL_MEDIA_CONTACTLESS_TYPE_B
Transport protocol Media - Contactless Type B |
static byte |
PROTOCOL_MEDIA_DEFAULT
Transport protocol Media - Contacted Asynchronous Half Duplex |
static byte |
PROTOCOL_MEDIA_MASK
Media nibble mask in protocol byte |
static byte |
PROTOCOL_MEDIA_USB
Transport protocol Media - USB |
static byte |
PROTOCOL_T0
ISO 7816 transport protocol type T=0. |
static byte |
PROTOCOL_T1
This constant is used to denote both the ISO 7816 transport protocol type T=1 and the variant for contactless cards defined in ISO 14443-4. |
static byte |
PROTOCOL_TYPE_MASK
Type nibble mask in protocol byte |
static byte |
STATE_ERROR_IO
This error state of a APDU object occurs when an
APDUException with reason code
APDUException.IO_ERROR has been thrown. |
static byte |
STATE_ERROR_NO_T0_GETRESPONSE
This error state of a APDU object occurs when an
APDUException with reason code
APDUException.NO_T0_GETRESPONSE has been thrown. |
static byte |
STATE_ERROR_NO_T0_REISSUE
This error state of a APDU object occurs when an
APDUException with reason code
APDUException.NO_T0_REISSUE has been thrown. |
static byte |
STATE_ERROR_T1_IFD_ABORT
This error state of a APDU object occurs when an
APDUException with reason code
APDUException.T1_IFD_ABORT has been thrown. |
static byte |
STATE_FULL_INCOMING
This is the state of a APDU object when all the
incoming data been received. |
static byte |
STATE_FULL_OUTGOING
This is the state of a APDU object when all
outbound data has been transferred. |
static byte |
STATE_INITIAL
This is the state of a new APDU object when only
the command header is valid. |
static byte |
STATE_OUTGOING
This is the state of a new APDU object when data
transfer mode is outbound but length is not yet known. |
static byte |
STATE_OUTGOING_LENGTH_KNOWN
This is the state of a APDU object when data
transfer mode is outbound and outbound length is known. |
static byte |
STATE_PARTIAL_INCOMING
This is the state of a APDU object when incoming
data has partially been received. |
static byte |
STATE_PARTIAL_OUTGOING
This is the state of a APDU object when some
outbound data has been transferred but not all. |
| Method Summary | |
byte[] |
getBuffer()
Returns the APDU buffer byte array. |
static byte |
getCLAChannel()
Returns the logical channel number associated with the current APDU command based on the CLA byte. |
static APDU |
getCurrentAPDU()
This method is called to obtain a reference to the current APDU object. |
static byte[] |
getCurrentAPDUBuffer()
This method is called to obtain a reference to the current APDU buffer. |
byte |
getCurrentState()
This method returns the current processing state of the APDU object. |
static short |
getInBlockSize()
Returns the configured incoming block size. |
byte |
getNAD()
Returns the Node Address byte (NAD) in T=1 protocol, and 0 in T=0 protocol. |
static short |
getOutBlockSize()
Returns the configured outgoing block size. |
static byte |
getProtocol()
Returns the ISO 7816 transport protocol type, T=1 or T=0 in the low nibble and the transport media in the upper nibble in use. |
short |
receiveBytes(short bOff)
Gets as many data bytes as will fit without APDU buffer overflow, at the specified offset bOff. |
void |
sendBytes(short bOff,
short len)
Sends len more bytes from APDU buffer at specified
offset bOff. |
void |
sendBytesLong(byte[] outData,
short bOff,
short len)
Sends len more bytes from outData byte
array starting at specified offset bOff. |
short |
setIncomingAndReceive()
This is the primary receive method. |
short |
setOutgoing()
This method is used to set the data transfer direction to outbound and to obtain the expected length of response (Le). |
void |
setOutgoingAndSend(short bOff,
short len)
This is the "convenience" send method. |
void |
setOutgoingLength(short len)
Sets the actual length of response data. |
short |
setOutgoingNoChaining()
This method is used to set the data transfer direction to outbound without using BLOCK CHAINING (See ISO 7816-3/4) and to obtain the expected length of response (Le). |
static void |
waitExtension()
Requests additional processing time from CAD. |
| Methods inherited from class java.lang.Object |
equals |
| Field Detail |
public static final byte PROTOCOL_MEDIA_MASK
public static final byte STATE_ERROR_NO_T0_GETRESPONSE
APDU object occurs when an
APDUException with reason code
APDUException.NO_T0_GETRESPONSE has been thrown.
public static final byte PROTOCOL_MEDIA_CONTACTLESS_TYPE_B
public static final byte STATE_FULL_OUTGOING
APDU object when all
outbound data has been transferred.
public static final byte STATE_PARTIAL_OUTGOING
APDU object when some
outbound data has been transferred but not all.
public static final byte PROTOCOL_MEDIA_USB
public static final byte STATE_ERROR_NO_T0_REISSUE
APDU object occurs when an
APDUException with reason code
APDUException.NO_T0_REISSUE has been thrown.
public static final byte PROTOCOL_TYPE_MASK
public static final byte PROTOCOL_T0
public static final byte PROTOCOL_MEDIA_DEFAULT
public static final byte STATE_OUTGOING_LENGTH_KNOWN
APDU object when data
transfer mode is outbound and outbound length is known.
public static final byte STATE_INITIAL
APDU object when only
the command header is valid.
public static final byte STATE_PARTIAL_INCOMING
APDU object when incoming
data has partially been received.
public static final byte STATE_OUTGOING
APDU object when data
transfer mode is outbound but length is not yet known.
public static final byte STATE_ERROR_T1_IFD_ABORT
APDU object occurs when an
APDUException with reason code
APDUException.T1_IFD_ABORT has been thrown.
public static final byte PROTOCOL_T1
public static final byte STATE_FULL_INCOMING
APDU object when all the
incoming data been received.
public static final byte PROTOCOL_MEDIA_CONTACTLESS_TYPE_A
public static final byte STATE_ERROR_IO
APDU object occurs when an
APDUException with reason code
APDUException.IO_ERROR has been thrown.
| Method Detail |
public static short getInBlockSize()
This information may be used to ensure that there is enough
space remaining in the APDU buffer when
receiveBytes() is invoked.
Note:
receiveBytes() the
bOff param should account for this
potential blocksize.
receiveBytes(short)public static byte getCLAChannel()
APDU command based on the CLA byte. A number in the
range 0-3 based on the least significant two bits of the CLA
byte is returned if the command contains logical channel
encoding. If the command does not contain logical channel
information, 0 is returned. See Runtime Specification for
the Java Card Platform, section 4.3 for encoding details.
public static void waitExtension()
throws APDUException
Notes:
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setOutgoingNoChaining() previously invoked.
APDUException.IO_ERROR on I/O error.
public static byte[] getCurrentAPDUBuffer()
throws SecurityException
Note:
APDU object and
APDU buffer are reserved for use by RMIService.
Remote method parameter data may become corrupted.
APDU object being
processed
SecurityException - if
public short setIncomingAndReceive()
throws APDUException
Notes:
receiveBytes(5).
Applet.process() method.
APDU
object to STATE_PARTIAL_INCOMING if all incoming
bytes are not received.
APDU
object to STATE_FULL_INCOMING if all incoming bytes
are received.
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setIncomingAndReceive() already invoked or if
setOutgoing() or
setOutgoingNoChaining() previously invoked.
APDUException.IO_ERROR on I/O error.
APDUException.T1_IFD_ABORT if T=1 protocol is
in use and the CAD sends in an ABORT S-Block command to abort
the data transfer. public static short getOutBlockSize()
This information may be used prior to invoking the
setOutgoingLength() method, to limit the length of
outgoing messages when BLOCK CHAINING is not allowed.
Note:
setOutgoingLength() the
len param should account for this
potential blocksize.
setOutgoingLength(short)
public void setOutgoingLength(short len)
throws APDUException
0 is specified, no data will be output.
Note:
APDU
object to STATE_OUTGOING_LENGTH_KNOWN.
len - the length of response data
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setOutgoing() not called or this method already
invoked.
APDUException.BAD_LENGTH if len is
greater than 256 or if non BLOCK CHAINED data transfer is
requested and len is greater than (IFSD-2), where
IFSD is the Outgoing Block Size. The -2 accounts for the status
bytes in T=1.
APDUException.NO_GETRESPONSE if T=0 protocol is
in use and the CAD does not respond to
(ISO7816.SW_BYTES_REMAINING_00+count) response
status with GET RESPONSE command on the same origin logical
channel number as that of the current APDU command.
APDUException.NO_T0_REISSUE if T=0 protocol is
in use and the CAD does not respond to
(ISO7816.SW_CORRECT_LENGTH_00+count) response
status by re-issuing same APDU command on the same origin
logical channel number as that of the current APDU command with
the corrected length.
APDUException.IO_ERROR on I/O error.getOutBlockSize()
public void setOutgoingAndSend(short bOff,
short len)
throws APDUException
setOutgoing(), setOutgoingLength( len
) followed by sendBytes ( bOff, len ). In
addition, once this method is invoked, sendBytes()
and sendBytesLong() methods cannot be invoked and
the APDU buffer must not be altered.
Sends len byte response from the APDU buffer
starting at the specified offset bOff.
Notes:
APDU send methods can be
invoked.
Applet.process()
APDU
object to STATE_FULL_OUTGOING.
bOff - the offset into APDU bufferlen - the bytelength of the data to send
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setOutgoing() or setOutgoingAndSend()
previously invoked or response byte count exceeded.
APDUException.IO_ERROR on I/O error.public byte[] getBuffer()
Note:
public short setOutgoing()
throws APDUException
Notes.
APDU
object to STATE_OUTGOING.
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if this method, or
setOutgoingNoChaining() method already invoked.
APDUException.IO_ERROR on I/O error.
public short receiveBytes(short bOff)
throws APDUException
bOff. Gets all
the remaining bytes if they fit.
Notes:
APDUException with
T1_IFD_ABORT reason code, the Java Card
runtime environment will restart APDU command processing using
the newly received command. No more input data can be received.
No output data can be transmitted. No error status response can
be returned.
APDU
object to STATE_PARTIAL_INCOMING if all incoming
bytes are not received.
APDU
object to STATE_FULL_INCOMING if all incoming bytes
are received.
bOff - the offset into APDU buffer
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setIncomingAndReceive() not called or if
setOutgoing() or
setOutgoingNoChaining() previously invoked.
APDUException.BUFFER_BOUNDS if not enough
buffer space for incoming block size.
APDUException.IO_ERROR on I/O error.
APDUException.T1_IFD_ABORT if T=1 protocol is
in use and the CAD sends in an ABORT S-Block command to abort
the data transfer. getInBlockSize()
public void sendBytes(short bOff,
short len)
throws APDUException
len more bytes from APDU buffer at specified
offset bOff.
If the last part of the response is being sent by the invocation of this method, the APDU buffer must not be altered. If the data is altered, incorrect output may be sent to the CAD. Requiring that the buffer not be altered allows the implementation to reduce protocol overhead by transmitting the last part of the response along with the status bytes.
Notes:
setOutgoingNoChaining() was
invoked, output block chaining must not be used.
setOutgoingNoChaining() was invoked, Le
bytes must be transmitted before
(ISO7816.SW_BYTES_REMAINING_00+remaining
bytes) response status is returned.
APDUException with
NO_T0_GETRESPONSE or
NO_T0_REISSUE reason code, the Java Card
runtime environment will restart APDU command processing using
the newly received command. No more output data can be
transmitted. No error status response can be returned.
APDUException with
T1_IFD_ABORT reason code, the Java Card
runtime environment will restart APDU command processing using
the newly received command. No more output data can be
transmitted. No error status response can be returned.
APDU
object to STATE_PARTIAL_OUTGOING if all outgoing
bytes have not been sent.
APDU
object to STATE_FULL_OUTGOING if all outgoing bytes
have been sent.
bOff - the offset into APDU bufferlen - the length of the data in bytes to send
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setOutgoingLength() not called or
setOutgoingAndSend() previously invoked or response
byte count exceeded or if
APDUException.NO_T0_GETRESPONSE or
APDUException.NO_T0_REISSUE or
APDUException.T1_IFD_ABORT previously thrown.
APDUException.BUFFER_BOUNDS if
bOff is negative or len is negative or
bOff+len exceeds the buffer size.
APDUException.IO_ERROR on I/O error.
APDUException.NO_GETRESPONSE if T=0 protocol is
in use and the CAD does not respond to
(ISO7816.SW_BYTES_REMAINING_00+count) response
status with GET RESPONSE command on the same origin logical
channel number as that of the current APDU command.
APDUException.NO_T0_REISSUE if T=0 protocol is
in use and the CAD does not respond to
(ISO7816.SW_CORRECT_LENGTH_00+count) response
status by re-issuing same APDU command on the same origin
logical channel number as that of the current APDU command with
the corrected length.
APDUException.T1_IFD_ABORT if T=1 protocol is
in use and the CAD sends in an ABORT S-Block command to abort
the data transfer. setOutgoing()
public short setOutgoingNoChaining()
throws APDUException
setOutgoing() method by
applets which need to be compatible with legacy CAD/terminals
which do not support ISO 7816-3/4 defined block chaining. See
Runtime Specification for the Java Card Platform,
section 9.4 for details.
Notes.
waitExtension() method cannot be
used.
(ISO7816.SW_BYTES_REMAINING_00+count)
response status chaining.
APDU
object to STATE_OUTGOING.
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if this method, or
setOutgoing() method already invoked.
APDUException.IO_ERROR on I/O errorpublic byte getNAD()
public static APDU getCurrentAPDU()
throws SecurityException
APDU object. This method can only be called in the
context of the currently selected applet.
Note:
APDU object being processed
SecurityException - if
public static byte getProtocol()
PROTOCOL_T0public byte getCurrentState()
APDU object. It is used by the
BasicService class to help services collaborate in
the processing of an incoming APDU command. Valid codes are
listed in STATE_ .. constants above. See STATE_INITIAL
BasicService
public void sendBytesLong(byte[] outData,
short bOff,
short len)
throws APDUException,
SecurityException
len more bytes from outData byte
array starting at specified offset bOff.
If the last of the response is being sent by the invocation of this method, the APDU buffer must not be altered. If the data is altered, incorrect output may be sent to the CAD. Requiring that the buffer not be altered allows the implementation to reduce protocol overhead by transmitting the last part of the response along with the status bytes.
The Java Card runtime environment may use the APDU buffer to send data to the CAD.
Notes:
setOutgoingNoChaining() was
invoked, output block chaining must not be used.
setOutgoingNoChaining() was invoked, Le
bytes must be transmitted before
(ISO7816.SW_BYTES_REMAINING_00+remaining
bytes) response status is returned.
APDUException with
NO_T0_GETRESPONSE or
NO_T0_REISSUE reason code, the Java Card
runtime environment will restart APDU command processing using
the newly received command. No more output data can be
transmitted. No error status response can be returned.
APDUException with
T1_IFD_ABORT reason code, the Java Card
runtime environment will restart APDU command processing using
the newly received command. No more output data can be
transmitted. No error status response can be returned.
APDU
object to STATE_PARTIAL_OUTGOING if all outgoing
bytes have not been sent.
APDU
object to STATE_FULL_OUTGOING if all outgoing bytes
have been sent.
outData - the source data byte arraybOff - the offset into OutData arraylen - the byte length of the data to send
SecurityException - if the outData array is
not accessible in the caller's context
APDUException - with the following reason codes:
APDUException.ILLEGAL_USE if
setOutgoingLength() not called or
setOutgoingAndSend() previously invoked or response
byte count exceeded or if
APDUException.NO_T0_GETRESPONSE or
APDUException.NO_T0_REISSUE or
APDUException.NO_T0_REISSUE previously thrown.
APDUException.IO_ERROR on I/O error.
APDUException.NO_T0_GETRESPONSE if T=0 protocol
is in use and CAD does not respond to
(ISO7816.SW_BYTES_REMAINING_00+count) response
status with GET RESPONSE command on the same origin logical
channel number as that of the current APDU command.
APDUException.T1_IFD_ABORT if T=1 protocol is
in use and the CAD sends in an ABORT S-Block command to abort
the data transfer. setOutgoing()
|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||