Smart cards 2024

CarderPlanet

Professional
Messages
2,556
Reputation
7
Reaction score
586
Points
83
Content:
  • Part 1. Operating principles
  • Part 2. APDU
  • Part 3. TLV
  • Part 4. JavaCard


Part 1. Operating principles​


We all use different types of smart cards in our daily lives. The most striking examples of smart cards are: SIM cards, credit cards, electronic documents, etc.

Essentially, a smart card is a cryptography-optimized microcontroller with an increased level of security. What does this mean? Unlike a standard microcontroller, access to smart card memory is strictly controlled by the processor. Thus, reading data from the card and writing it on it are regulated by the software of the card itself. Moreover, chip manufacturers are taking measures to prevent unauthorized access (copying all memory, reprogramming) to the card at the electronic and physical level.

Using a smart card​

A smart card is used in cases where it is necessary to authenticate its owner. An example of this is the SIM card. Its main role is to prove to the operator that the phone connected to the network belongs to a specific subscriber. After such a check, the operator will be able to direct communications from and to the subscriber’s number to the exact phone number, as well as register the subscriber’s payment balance.

From a technical point of view, the card is equipped with the following functions:
  • Saving the cardholder’s identification data (most often ID numbers, not the cardholder’s contact information).
  • Store and verify PIN codes for two-factor authentication.
  • Generation and storage of cryptographic keys and certificates. Typically, these keys are used exclusively to perform other functions within the card and cannot be read.
  • Generating a digital signature.
  • Authentication using the "Challenge-Response" scheme.
  • Other specific functions inherent in one or another type of card.

Smart card operation​

Cards do not work independently, but only in conjunction with a so-called terminal (telephone, ATM, other wired or wireless electronic reader). The reader provides electricity to the card and sends commands. The card never initiates communication, but always responds to any commands sent to it by the terminal. If there is no response, the card will be considered “MUTED”, i.e. not working. In such a situation, the terminal either does not react at all to the error, or tries to restore communication with the card after RESET.

At the logical level, communication between the terminal and the card occurs in the APDU format described by the ISO7816-4 standard. As for the physical level, the above-mentioned communication is regulated not by one specific standard, but by many of them. For example, there are standards for contact (ISO7816-3 T=0 and T=1, USB, etc.) and contactless (ISO14443, NFC/SWP) communication.

I would like to describe in more detail the communication between the terminal and the card. It happens as follows:
  1. Initializing the physical channel (Cold reset, ATR, etc.)
  2. Select the desired program using the SELECT command. This step is optional. If it is not executed, then communication will be carried out with the program selected by default when initializing the channel
  3. Further communication to implement specific tasks

It is worth mentioning that more than one program can be installed on a card. In addition, the terminal has the ability to communicate in parallel with one or more programs using so-called logical channels. The number of logical channels supported depends on the specific card. The ISO7816-4 standard allows the card to support a maximum of 20 channels. However, in practice, most cards only support 4 channels.

Native and Javacards​

Some smart cards go into production with one or more programs designed to perform specific functions (SIM and USIM, EMV, etc.) already pre-installed on them and not subject to change, addition, or removal. Such cards, called Native, are attractive due to their low price (when purchased in bulk) and the relative simplicity of the code used to program them, which reduces the likelihood of card security problems. However, the most interesting cards in my opinion are those based on JavaCard and Global Platform, in which the OS of the card is the platform on which various applications can be installed. Applications written for JavaCard using standard APIs will be able to be loaded on all cards that support a compatible version of the platform, regardless of the card manufacturer. As for the Global Platform, this is a set of specifications that regulate the secure administration of the card, including the installation, blocking or removal of certain applications, as well as management of the life cycle (Life Cycle) of the card.

A small note about the card administration. The card user, as a rule, is not the owner or administrator of the card. For example, the SIM Card administrator is the mobile operator, not the subscriber. Only the operator has the right to install or remove applications on/from the card. However, it is also possible to purchase “blank” cards for your own application development.

Thus, in this part of my article I touched on the basis of the operation of a smart card, both at the external and internal levels, and also gave a brief definition of the concept of a smart card. I would like to devote the following parts of the article to:
  1. Brief description of APDU format according to ISO7816-4 standard
  2. description of the BER-TLV format
  3. concept and essence of JavaCard
  4. various aspects of the Global Platform


Part 2. APDU​


After the general information described in the first part, today we will talk about APDU in the format described in the ISO7816-4 standard.

APDU (application protocol data unit) is a communication format between the card and the terminal. The terminal sends a Command APDU (C-APDU), and the card responds with a Response APDU (R-APDU).

C-APDU​


The C-APDU format is:
HeaderBody
CLA INS P1 P2[Lc field] [Data field] [Le field]

Each header element is stored in one byte and is required. Let's return to the title a little later, now let's talk about the body of the command.

The body elements are as follows:
  • Lc : Length of the Data element in bytes.
  • Data : command data.
  • Le : The expected length of the response data in bytes, excluding the length of the Status Word.

Lc and Le, if present, can occupy 1 (Short Length) or 3 bytes (Extended Length) each. Short Length encodes values from 1 to 256. The data length of 256 bytes is written as "00". With Extended Length, values from 1 to 65536 are encoded. The first byte is always “00” and the remaining 2 bytes are a number in Big Endian format. When Lc or Le is "00 00 00", then the data length is 65536 bytes.

Depending on their presence or absence, the body elements of a command can be divided into 4 categories:
  • Case 1 : Body is completely absent, that is, the command does not contain any data and is not expected to receive any data from the card upon response.
  • Case 2 : Only Le is present in the body, that is, the command does not contain any data, but it is expected to receive data from the card.
  • Case 3 : The body contains Lc and Data, that is, the command contains data, but it is not expected to receive data from the card.
  • Case 4 : All elements are present in the body, which means the command contains data and is expected to receive data from the card.

I will show examples of commands later. Now let's go back to header.

ElementMeaning
CLAClass byte . Contains command metadata (logical channel, Secure Messaging, etc.).
INS Instruction byte. Instruction code. This is a hexadecimal number whose highest nibble cannot be 6 or 9. However, the lowest nibble is always an even number.
P1The first parameter of the command . If it is not needed, then its value is “00”.
P2Second parameter of the command . If it is not needed, then its value is also “00”.

Since my series of articles is aimed at examining the Global Platform in detail, I will describe the meaning of the CLA in the context of the Global Platform.

CLA byte with logical channel from 0 to 3
b8b7b6b5b4b3b2b1Meaning
0000----Team from ISO7816-4 standard
1000----Team from the Global Platform specification
-00000--No Secure Messaging
-00001--Secure Messaging by Global Platform
-00010--Secure Messaging according to ISO7816-4 without C-MAC
-00011--Secure Messaging according to ISO7816-4 with C-MAC
-000--XXLogical channel

CLA byte with logical channel 4 to 19
b8b7b6b5b4b3b2b1Meaning
01-0----Team from ISO7816-4 standard
11-0----Team from the Global Platform specification
-100----No Secure Messaging
-110----Secure Messaging by Global Platform or ISO7816-4
-1-0XXXXLogical channel

b7 determines if the CLA format is as in the first or as in the second table. When a logical channel is in the range from 0 to 3, then its value is written in bits 1 and 2. Otherwise, the number written in bits 1-4 encodes the number from 4 to 19 (0 = 4, 1 = 5, ..., 15 = 19).

b5 in the ISO7816-4 standard stands for Command Chaining. Not used in Global Platform.

R-APDU​

The R-APDU format is:
BodyTrailer
[Data field]SW1 SW2

Body is present upon successful execution (with or without comments) of commands from the categories Case 2 and Case 4. Its content depends on the specific command. The Trailer is always there and contains the so-called Status Word, that is, a result code, positive or negative. The status can be one of the following:

SW1SW2Meaning
Successful execution
9000OK.
61ХХOK, but there are still XX bytes of data.
The performance ended with comments
62ХХSW2 clarifies the reasons for the comment. The permanent memory has not been modified.
63ХХSW2 clarifies the reasons for the comment. The permanent memory has been modified.
Errors when executing the command
6400The command was not executed. The permanent memory has not been modified.
65ХХThe command was not executed. The constant has been changed.
66ХХThe command was not executed for security reasons.
Command format errors
6700Invalid command length.
6881The card does not support the specified logical channel.
6882The card does not support the specified type of Secure Messaging.
69XXThe command is not allowed.
6AXXInvalid command parameters.
6B00Invalid command parameters.
6CXXIncorrect Le.
6D00Unknown INS.
6E00Unknown CLA.
6F00Error without description.

Errors from the 69ХХ and 6АХХ series are often used in the Global Platform and will be described in detail in the parts of the article dedicated to the Global Platform.

Statuses from the 61ХХ and 6CXX series require special attention. Code 61XX is possible when the card executed a command from the Case 2 or Case 4 category and sent an incomplete response. In this case, SW2 encodes the length of the remainder of the response (“00” = 256). In response, the terminal can send the GET RESPONSE command in order to obtain the remaining data. This procedure can be repeated several times until the card sends a complete response. The real Status Word is the status contained in the last response to the GET RESPONSE command. This situation occurs mainly when APDU is transmitted via the ISO7816-3 T=0 protocol due to the peculiarities of transmitting commands from the Case 4 category (we’ll talk about this a little later). Code 6CXX occurs when the specified Le does not match the actual length of the response. It is worth noting that in this case the card does not send any data to the R-APDU, but requires the terminal to repeat the command with Le equal to the number encoded in SW2.

Features of transmitting commands in the Case 4 category via the T=0 protocol​

The T=0 protocol is very common, as it is used in SIM cards. Its peculiarity is that header always consists of 5 bytes: CLA, INS, P1, P2, P3. P3 can be used for Lc or Le encoding. It turns out that it will be superfluous for Case 1 teams, suitable for Case 2 and Case 3 teams, but insufficient for Case 4 teams, where both Lc and Le are needed. How can I solve this problem?

In the following way. Case 4 commands are transmitted with P3=Lc, as if it were a Case 3 command. Then the card, upon successful execution of the command, responds without data, but with status 61XX. In turn, the terminal sends the GET RESPONSE command (from the Case 2 category), and then the card sends the real response.

GET RESPONSE
ElementMeaning
CLAlike the previous command, but without Secure Messaging and bit8 = 0 (although cards also accept bit8 = 1)
INSC0
P100
P200
Lc-
Data-
LeXX (usually SW2 of the previous answer)

Examples of communication with the card​

Finally, we come to the most interesting part of the article - examples.

GET DATA (Card Production Life Cycle)
C-APDU => 80 CA 9F 7F 00
R-APDU <= 6C 2D
C-APDU => 80 CA 9F 7F 2D
R-APDU <= 9F 7F 2A 47 90 50 40 47 91 81 02 31 00 83 58 00 11 68 91 45 81 48 12 83 65 00 00 00 00 01 2F 31 30 31 31 36 38 00 00 00 00 00 00 00 00 90 00

The GET DATA command (Case 2) reads information from the card. Which one is determined by the parameters P1 and P2. The answer is in BER-TLV format (the subject of the next part of the article). Here we see how at the beginning the command was sent with the wrong Le and the card, in turn, responded with the status 6C 2D. After repeating the command with Le = 2D, the card sent a response and a final status of 9000 indicating successful execution.

GET STATUS via T=1
C-APDU => 80 F2 40 00 08 4F 06 31 32 33 34 35 36 09
R-APDU <= 06 31 32 33 34 35 36 07 00 90 00

The GET STATUS command (Case 4) provides information about the life cycle of the card and applications. In this example, Lc = 8, Data = 4F 06 31 32 33 34 35 36 and Le = 9. I will not go into further explanation of the meaning of this data at this stage as it is not that important. In response, the card sends data 06 31 32 33 34 35 36 07 00 and status 9000. Below we will see exactly the same command, only sent via the T=0 protocol.

GET STATUS via T=0
C-APDU => 80 F2 40 00 08 4F 06 31 32 33 34 35 36
R-APDU => 61 09
C-APDU => 00 C0 00 00 09
R-APDU <= 06 31 32 33 34 35 36 07 00 90 00

Here we see that GET STATUS is sent without Le. The protocol doesn't allow us to do this because P3 specifies Lc. In response, the card will tell us the length of the data we need to receive. Then we send the GET RESPONSE command with Le = 9. After this, the card finally sends us the corresponding response.

So we have come to the end of this part. If anyone has questions, you can write them in the comments. The next part of the article will be about BER-TLV, since this data encoding format is used for almost everything related to smart cards.


Part 3. TLV​


In the last part we saw how communication occurs between the terminal and the card. We looked at the C-APDU and R-APDU formats, but we didn't pay attention to what data those APDUs contained. In this part we will look at the most common formats in which information is transferred between the terminal and the card (and vice versa). They all belong to the same family - TLV.

TLV stands for T ag, L ength, V alue and is used to structure information. At a very abstract level, a TLV can be thought of as a binary version of XML. However, what is Tag, Length, Value?
  • Tag : it tells what kind of information is in the TLV. A view can be, for example, a simple string or number, an identifier, or even a complex structure. In some embodiments, the Tag also contains meta information about the TLV.
  • Length : The length, in bytes, of the Value element.
  • Value : data contained in the TLV

Each TLV variant has its own rules for encoding each element. Next we will look at the most common TLV options. I would like to immediately note that this article will mainly focus on BER-TLV, since it is the most common, flexible and complex format. The remaining TLV options will be discussed only briefly.

BER-TLV​

So, let's talk about the main character of this article - BER-TLV. It is part of the ASN.1 standard and is used far beyond smart cards.

Tag​

The first byte of the tag has the following format:
b8b7b6b5b4b3b2b1
ClassTypeTag

The following classes exist:
b8b7Description
00Generic - Basic data types such as string data or numbers. Rarely used in smart cards
01Application - types whose meaning varies depending on the application
10Context-sensitive - types whose meaning depends on the given composite type
11Private - types whose meaning depends on the specific organization

Since the specification describes the full meaning of the tag, remembering the meaning of the classes is completely unnecessary. The class does not affect how the tag is processed.

The most interesting bit is bit 6. When it is 1, this TLV contains other TLVs. If, on the other hand, its value is 0, then the TLV contains plain data or data not structured in TLV format.

The remaining bits (5-1) are usually just the tag number. However, if they are all ones, then the tag number continues on the second byte. If bit8 of the second byte is 1, then the number continues on to the third byte, etc. In practice, smart cards only use tags written on one or two bytes.

Length​

The length can be definite or indefinite.

The unspecified length is written to one byte with the value 0x80. This method is only valid for composite TLVs (that is, TLVs that contain other TLVs). In such a case, the TLV must necessarily contain TLV-NULL as the last element, which is encoded as "00 00". This method is often used in more modern standards, but in general it is not very common.

A specific length is written on one or more bytes.
Data lengthCoding
0x00 <= x <= 0x7Fthe value is written unchanged on one byte
0x80 <= x <= 0xFF0x81 and the value in the second byte
0x100 <= x <= 0xFFFF0x82 and the value on the second and third bytes
0x10000 <= x <= 0xFFFFFF0x83 and the value on the next three bytes
0x1000000 <= x <= 0xFFFFFFFF0x84 and the value on the next four bytes

In principle, this table could be continued further. However, huge TLVs are not common in the smart card space. I personally have never seen a length written in more than three bytes (including the 0x82 prefix). Values are always written in Big Endian format.

Please note that in smart cards this method of recording the length is often used even outside of the TLV (i.e. only LV), but, as a rule, with the exception that the value 0x80 can also be written as is, on one byte.

Value​

Value can be either a sequence of TLVs or simply bytes, the meaning of which depends on the context and application. It is unacceptable to mix both types of data in the same TLV. The TLVs contained in a composite TLV can be of any kind—composite or simple. This element is missing when the TLV length is 0.

Examples​

AID (Application Identifier)
4F 08 A0 00 00 01 51 00 00 00

Tag 0x4F: a simple application TLV, in this example containing 8 bytes (the value of which is the Application Identifier, i.e. the application identifier).

Life Cycle State
9F70 01 0F

Tag 0x9F70: A simple context-sensitive TLV, in this example containing 1 byte. Note that in the first byte of the tag (9F), bits 5-1 are all ones, so the tag continues into the next byte.

Load File Data Block
C4 82 0x01 0x0c 01...another 266 bytes...0a

Tag 0xC4: A simple private TLV, in this example containing 268 bytes. The length is written in three bytes, the first of which is the 0x82 prefix.

GlobalPlatform Registry related data
E3 11 4F 08 A0 00 00 01 51 00 00 00 9F70 01 0F C5 01 00

Tag 0xE3: A composite private TLV containing other TLVs. In this example, it is the only one that contains simple TLVs. It is also acceptable to contain compound TLVs or a mixture of compound and simple ones.

In theory, this could also be written as
E3 80 4F 08 A0 00 00 01 51 00 00 00 9F70 01 0F C5 01 00 00 00

using indefinite length. In practice, however, a card accepts (or sends) an unspecified length only when allowed by the specification.

COMPREHENSION-TLV​

COMPREHENSION-TLV is described in the ETSI TS 101 220 standard. The length is coded in the same way as for BER-TLV. The tag is encoded according to the following tables:

On one byte (0x01 - 0x7E)
b8b7b6b5b4b3b2b1
CRTag

On three bytes (0x0001 - 0x7FFF)
Byte 1Byte 2Byte 3
b8-b1b8b7b6b5b4b3b2b1b8-b1
0x7FCRTag

The abbreviation CR stands for Comprehension Required. When this bit is 1, the recipient of the TLV must return an error in case it does not support this TLV. If, on the contrary, it is 0, then the recipient is free to ignore the TLV if it is not supported.

The main use of COMPREHENSION-TLV is the transfer of parameters to the SIM-Toolkit (SIM-Toolkit is used, among other things, to operate the SIM-Menu in phones). To increase compatibility between cards and phones, optional parameters (i.e. those parameters without which the command can somehow be executed) are sent with CR = 0.

SIMPLE-TLV​

SIMPLE-TLV is described in the ISO7816-4 standard. Unlike BER-TLV, in SIMPLE-TLV the tag is simply a number between 0x01 and 0xFE, containing no class or type information. The length is written as follows:
Data lengthCoding
0x00 <= x <= 0xFEthe value is written unchanged on one byte
0xFF <= x <= 0xFFFF0xFF and the value on the second and third byte

DGI (Data Grouping Identifier)​

DGI is described in the Global Platform Card Specifications and GP Systems Scripting Language Specification. The tag is always encoded on two bytes and does not contain any meta information. The length is written in the same way as for SIMPLE-TLV. DGIs often contain BER-TLVs, but can also be simple.

COMPACT-TLV​

COMPACT-TLV is described in the ISO7816-4 standard and is used exclusively in ATR (Answer to Reset). In this format, the tag and length are written in the same byte. In the older nibble the tag is written, and in the younger nibble the length is written.

So we have come to the end of this part. If anyone has any questions, you can write them in the comments. The next part of the article will be about JavaCard, and after that we will directly talk about the Global Platform.


Part 4. JavaCard​


Today I would like to talk about JavaCard. This article will focus on the concept of JavaCard and an overview of its architecture. If there is interest in this topic, then I could write a separate series of articles that will cover in detail all aspects of JavaCard. I’ll say right away that I’m not going to teach you how to write your first application in JavaCard, because... There are already too many articles on the Internet about this. Today we will talk mainly about the principles of JavaCard operation.

So, a JavaCard-based smart card is a card on which applications run on the JavaCard Virtual Machine (a limited version of the Java Virtual Machine, adapted for smart cards) in the so-called JavaCard Runtime Environment (which has very little in common with the Java Runtime Environment) .

In terms of terminology, applications are called Applets and are contained in Packages. Packages are distributed in CAP-files (instead of Jar-files). Packages and applications have their own AID (Application Identifier). This is necessary so that they can be clearly identified in commands such as: SELECT, INSTALL, DELETE, etc. (SELECT is described in ISO7816-4, and JavaCard and other commands are described in the Global Platform).

The lifecycle of Applets is somewhat different from the typical lifecycle of desktop applications. Applet is any class that inherits from the base class "Applet". When installing applications, its static install method is called. This method must create an object of the appropriate class and call the register method on it. Subsequently, the object will be saved in the system and will receive its own AID, which will be used for further communication with the application. The object and its data fields are stored in NVM (Non-Volatile Memory). Every object or array created by the application using the "new" operator will also reside in NVM. This means that, unlike traditional computer programs, the state of JavaCard applications is permanent and is not lost even when the card is turned off.

Communication with the application​

At any time, there is one active application on each open logical channel. The active application is the application that receives all APDUs sent by the terminal. When receiving an APDU, JavaCard calls the active application's process method, which takes the received APDU as its only parameter. This method is the core of Applet, since requests from the terminal are processed there. The received APDU object is also used to send responses.

Applet can be activated in two ways:
  • when a card is reset or when a logical channel is opened, the system, as a rule, activates the application that is marked as Default Application
  • using the SELECT command with P1 = 0x04 and the AID (full or partial) of the application in Data

When an application is activated using the SELECT command, the process method will be called immediately after activation with an APDU containing this command. This allows the Applet to send information in response to a SELECT command when activated. The Applet class provides a selectingApplet() method to determine if a command received caused the application to be activated.

The application also has the ability to overwrite the select() and deselect() methods to respectively perform initialization on activation and de-initialization on deactivation. These methods will be called regardless of how the application was activated.

Logical channels can be opened and closed using the MANAGE CHANNEL command. Any commands, including SELECT, can be sent over open logical channels. SELECT and MANAGE CHANNEL are the only commands that are processed directly by the system, and not by the active application. Although in the case of the SELECT command, we can say that it is processed by both the system and the active application.

The full rules for activating an application and processing a SELECT command are quite complex, and there are minor inconsistencies between JavaCard and the Global Platform. However, I will touch on this topic in one of my next articles. Now it is worth saying that cards often follow the rules described in the Global Platform.

Memory management​

As I said above, objects and arrays are saved in NVM by default. In addition to NVM, JavaCard also provides the ability to create arrays in RAM using a number of methods from the JCSystem class. In this case, there are 2 types of temporary memory: Clear on Reset and Clear on Deselect. The first one is erased when the card is turned off or reset. The second one is erased when the Applet is no longer active (ie: when SELECTing another application, shutting down, reset, etc.). It is worth noting that although the contents of the array are erased (that is, all zeros or false are written there), the array itself remains, and it can, for example, be stored in the data field of an object.

What is stored in NVM:
  • All objects and their data fields.
  • All arrays.
  • Contents of arrays created by the new operator.

What is stored in RAM (CLEAR_ON_RESET or CLEAR_ON_DESELECT):
  • Contents of arrays created by the JCSystem.makeTransient<type>Array functions. It is important to note that objects found in the array created by JCSystem.makeTransientObjectArray() will still be stored in NVM. Only a link to them will be in RAM.
  • Global Arrays: system ones (APDU buffer and Install Parameters buffer), as well as Global Arrays created using JCSystem.makeGlobalArray().
  • Transaction buffer. However, this buffer cannot be directly accessed.

An application should typically create all the objects and arrays it needs when it installs, rather than dynamically. The reason for this is mainly two factors:

1) The desire to ensure that if an application is successfully installed, it will not stop working if some other application has taken all the free memory.
2) The garbage collector is an optional (albeit very common) function. This means that when objects are created dynamically, there is a risk that the created objects will never be deleted. Over time, this will lead to a lack of free memory. Even if a garbage collector is present, this procedure does not occur automatically, but at the request of the application (JCSystem.requestObjectDeletion()).

Subsequently, the application code is rarely “clean” according to the parameters of object-oriented programming. Using a common byte[] for many different operations is a very common practice. Classes consisting exclusively of static methods and running on byte[] are also not uncommon. In addition, the creation of classes and objects is reduced to a minimum. Memory is limited and must be protected at all costs.

It is also worth noting the role of the APDU object. Its buffer, located in RAM, is erased before each command is received. It is customary to use it not only to generate a response, but often even as a temporary buffer. Its size is at least 256 bytes, or much larger if the card supports Extended Length.

Applet Firewall​

An important feature of JavaCard that can confuse programmers is the presence of the so-called Applet Firewall. The purpose of a Firewall is to prevent any Applet from having access to another's data. I’ll say right away that JavaCard allows communication between applications using Shareable Interfaces, and also that packages are libraries of classes and functions that can be used in different applications. This is why the need for a firewall arises. The basic principles of Applet Firewall are as follows:
  • Each application belongs to one context. All applications from the same package belong to the same context.
  • Each object belongs to one application or system.
  • A package without applications (library) has no context. Objects from its classes belong to the application that created them.
  • There is always one active context in the system.
  • Access (reading/writing in the case of an array and calling methods in the case of an object) is allowed only to objects belonging to the active context.
  • The system has access to all objects.
  • Calls to static methods are always resolved and executed in the active context. Access to static data fields is also allowed. However, objects referenced by static fields follow the general firewall rules.
  • Temporary arrays of type CLEAR_ON_DESELECT are only available when the active context matches the active application context.

Using a Shareable Interface, a programmer can allow certain methods of one object to be accessible to applications from another context. When one of these methods is called, the system switches the context to the context that owns the object providing the Shareable Interface. This means that this method only has access to objects belonging to its context, and if, for example, you pass byte[] to this method as a parameter from the original context, then an error will occur during access. After the method completes execution, the context is switched back to the original one.

The application also has access to certain objects owned by the system. Such objects are called Entry Points. There are two types of Entry Points: temporary and permanent. Permanent Entry Points are simple and can be accessed from any context. An example of this is objects from the AID class. Temporary Entry Points, on the other hand, have a limitation that does not allow references to them to be stored in object data fields or static class fields. An example of a temporary Entry Point is an APDU object.

As of JavaCard 3.0.4, it is also possible to create Global Arrays using the JCSystem.makeGlobalArray() method. Their behavior is exactly the same as that of temporary Entry Points. They are primarily needed as a parameter for methods called using the Shareable Interface technique.

Atomicity and transactions​

JavaCard guarantees atomic operations when changing data fields of objects or classes. Atomicity is also ensured by methods that operate on arrays (except for those with the NonAtomic suffix in their name). This means that, for example, Util.arrayCopy will either copy all the bytes (if successful) or leave the array unchanged in case of error or loss of energy.

If you need to make changes to multiple persistent fields and arrays in a single atomic operation, then JavaCard also provides the JCSystem.beginTransaction() functions to start a transaction and JCSystem.commitTransaction() to complete it. All changes that occur to arrays and persistent fields between calls to JCSystem.beginTransaction() and JCSystem.commitTransaction() will automatically be part of the transaction. If a transaction is aborted due to an error, loss of energy, or a call to the JCSystem.abortTransaction() method, the system will restore the original state. It is worth remembering that the technical implementation of the transaction uses an additional system buffer. If the buffer is completely filled, the system gives a TransactionException error.

RMI​

JavaCard supports RMI (Remote Method Invocation) technology. In this article I will not discuss this technology. Let me just say that this functionality is not widespread, and many cards do not support it.

API​

Much of the JavaCard API is dedicated to cryptography. There are classes for encryption, creating and verifying digital signatures, generating keys and random numbers, calculating checksums and hashes, and implementing key exchange schemes. In addition to cryptography, JavaCard also provides classes for storing and validating PINs and even biometrics. The remaining classes provide access to functionality described in other chapters or are auxiliary for working with strings, numbers, TLVs, etc. As for the API, it will be treated in another series of articles.

Main Limitations of JavaCard Compared to Java​

The JavaCard application programming language is Java. Almost Java. Thus, the types char, float, double, long and enum are not supported. The int type is optional for maps (usually modern maps support it) and its use, unless enabled by the appropriate option, will result in an error when converting the application to a CAP-file. Forget about for, iterator and lambda. Generics, static imports and annotations (Runtime Invisible only) are supported by the converter starting from version 3.0.0, because they do not affect code execution.

To compile the code, an ordinary compiler from the JDK is used. Incompatibility errors will only be noticeable when converting to a CAP file or using a smart JavaCard IDE.

The biggest problem for programmers is actually the lack of int by default. Usually they are really not needed, so you don’t want to activate them unnecessarily. However, the Java compiler has a habit of automatically casting the result of all arithmetic operations to type int. To avoid this, the code must use an explicit type cast to short or byte, which makes the code less readable.

Another limitation occurs in the initialization of static fields, namely that they can only be initialized with constants and arrays containing constants, but not with objects.

Conclusion​

So this was my introduction to JavaCard. If you find this article interesting, or at least it has piqued your interest in this topic, then you can write in the comments what exactly you would like to know more about. This way I can decide in what order and in what detail to write about this or that functionality and application of JavaCard. In any case, the next article on the Global Platform will be the final one in this series.

Resource​

ISO7816-4
 
Last edited by a moderator:
Top