A secure element is a tamper proof device, providing a secure storage and execution environment for sensitive data and processing. It offers both physical and logical protection against attacks, ensuring integrity and confidentiality of its content.

This specification defines a communication interface between a web application and a secure element. It makes no assumption on the secure element type, application domain, or physical communication media.

This work-in-progress specification is an unofficial draft. Developers are strongly discouraged to implement it at this stage. If you are interested in implementing or using this API, we encourage you to contact the editors or post on the working group mailing list.

See Changes section for history details.

Introduction

The Secure Element API defined herein allows applications to interact with secure elements. Considered secure elements are those complying to [[!ISO7816-4]], which defines a command/response protocol, based on structured APDU (Application Data Unit).

Technical Background

Secure elements addressed by this specification are micro controllers that may come in different form factors, such as:

Similarly to a computer, a secure element may host one or multiple applications. Typical applications are mobile network authentication (SIM cards), payment (credit cards), authentication and signature (corporate badges, eID, etc.), loyalty, ticketing (public transports). But these are only examples, many other applications have been and can be deployed.

Applications hosted by the secure elements are commonly named on-card applications. Considering the limited, if any, user interface of these devices, and application can only be useful for a user if there is also an off-card application part, which handle the dialog with the user, or with external computing resources. Examples of off-card applications are ATM for payment, mail applications for signature, access control doors for authentication, etc. This specification defines the API to be used by off-card applications based on web technologies.

Use Cases

This specification allows development of web applications making use of these secure element applications. Some typical use cases that applications can address based on this API include:

Whatever the form factor listed above, secure element considered in this specification implement the same [[!ISO7816-4]] transport protocol. The physical media (USB, NFC, or any other wired or wireless technique) used in this communication is abstracted by the API defined in this specification.

Relationship to other W3C APIs

This specification, although addressing some concepts similar to other W3C specifications, has distinct use cases and offer different level of services:

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification and terminology.

Dependencies

This specification depends on interfaces and concepts defined in the following specifications.

[[!HTML]]: event handler.

[[!DOM4]]: the Event and DOMException interfaces, the concept of firing an event.

[[!ES6]]: the Promise object type.

[[!RFC6454]]: The concepts of origin and same-origin, as well as the algorithm for serializing an origin.

[[!WDSIG]]: The author signature file and author certificate, as well of the concept of generating a digital signature

[[!MANIFEST]]: The web application manifest file

[[!GP-AC]]: The Access Rules and Access Control Enforcer concepts.

Some secure element concepts are defined in ISO/IEC specifications:

Security and privacy considerations

Using a secure element may bring additional security to a web application, but is not sufficient to ensure the application is secure. In particular, developers using the Secure Element API should be aware of the following security considerations:

Secure Element services

Communication with a secure element is performed through a reader, which unlike its name suggests it not only able to read content from secure element, but also to write or send any application specific command. Given the removal nature of many secure elements, a reader may be empty, meaning that no secure element is connected to this reader. For instance, a USB smart card reader may be connected to a computer, but no smart card is inserted. Or a device may support NFC interactions with secure elements, but none is in the field. For this reason, the API provides a mean to query the list of available readers, and for each of them if they are empty or if a secure element is present. In addition, this specification defines events that are triggered when a secure element is connected to a reader, and also when it is disconnected.

Once a web application is informed that a reader has a connected secure element, it can open a session with it. Opening a session establishes the communication between the web application and the secure element, and provides a session object to the application. However a secure element is just an application container, and the web application still needs to identify the application with which it wants to communicate.

To this intent, the session object provides a mean to open a channel with a specific secure element application, which is uniquely identified by an AID. The web application runtime and the secure element may then perform some internal security checking to ensure the web application is allowed to connect to this secure element application. If authorized, the returned channel object is the one providing the method to send commands to the secure element application, and get the corresponding responses.

The above steps required to send a command to a secure element creates a set of chained objects. A reader may have several opened sessions, which may have several opened channels. Each object has a close() method to release all ressources associated to the target object, and invoke close() method on all underlying objects in the chain.

Class graph
The figure above represents the class relationships between the secure element entities introduced in this specification.

Access Control

In order to make sure only trusted applications are allowed to use this API, the web application runtime MUST implement the access control defined in [[GP-AC]], which defines a simple mechanism that protects legitimate users using non-compromised devices from malicious applications. Note that it does not protect from a compromised device that would not properly implement the Access Control Enforcer, which is addressed by the internal protection of the secure element itself (using e.g. PIN or secure messaging)

Overall architecture

To control which applications running on a user device are allowed to access secure element applications, several entities are involved:

Class graph
The figure above shows the overall access control architecture.

Sections below describe how the Global Platform Access Control is applied to web applications. Details of the Global Platform Access Control mechanisms itself are defined in [[!GP-AC]].

Trusted application identifier

The Access Control Enforcer uses an application identifier to check whether the application is white listed in Access Rules. This identifier needs to be trustworthy so that only authorized application may have a given identifier. Web applications use the certificate-based identifier as defined in [[!GP-AC]]:

While applying the GlobalPlatform Access Control process, if the Access Control Enforcer detects the Secure Element does not implement the GlobalPlatform Access Control (it does not have access rules), the Access Control Enforcer may use its own certificate trust store to grant or refuse access to the Secure Element API.

Additional security rules

When an application is not accessed using an app URI, the origin and integrity of its resources must be guaranteed using the following security restriction:

Navigator Interface

The Navigator exposes the secure element service.

readonly attribute SecureElementManager secureElementManager
When getting the secureElementManager attribute, the user agent MUST return the SecureElementManager object that provides access to available secure element readers. If the user agent doesn't support secure element features, it MUST then return undefined.

SecureElementManager Interface

The SecureElementManager interface provides access to secure element readers, and is the source of events notifying the presence of secure elements.

readonly attribute Reader[] readers
This attribute MUST return the list of available readers in which a secure element may be present. Its value MUST be an empty array if no reader is available. It MUST be null if the close() method has been closed on this SecureElementManager object. Several requests of this attribute MAY return a different array value, because new readers may become available, while others may be disconnected.
attribute EventHandler onsepresent
Event handler for the SE-present event. This event MUST be triggered each time any of the following situations occurs:
  • Application starts while a secure element is present in a reader
  • Application is running, a reader which was already listed in the readers attribute but had no secure element now detects a present secure element.
  • Application is running, a new reader is detected and has a secure element present.
attribute EventHandler onseremoval
Event handler for the SE-removal event. This event MUST be triggered when a secure element which was present in a reader is not present anymore (it has been unplugged, or is out of reach if it was connected through wireless communication). As soon as this event is triggered, all Reader, Session and Channel objects providing access to this secure element are marked as closed. Calling any method other than close() on associated readers, sessions, or channels MUST fail with an SEClosedException error.
Promise<SecureElementManager> close()

This method closes all readers and descendent Session and Channel objects. When invoked, the user agent MUST run the following steps:

  1. Let promise be a newly-created Promise object.
  2. Return promise and continue the following steps asynchronously.
  3. If the close() method has already been called on this object, then resolve promise with this SecureElementManager object.
  4. Let countdown be the number of readers in the readers attribute, and error an object initially undefined.
  5. Invoke close() method on each Reader object in the array returned by the readers attribute.
  6. Let readerpromises be the set of Promise objects returned by these close() invocations.
  7. Set the readers attribute value to null.
  8. If countdown is 0, then resolve promise with this SecureElementManager object.
  9. When a readerpromises element is fulfilled, countdown is decremented. If countdown is 0 and error is undefined, then resolve promise with this SecureElementManager object. If countdown is 0 and error is not undefined, then reject promise with the error value.
  10. When a readerpromises element is rejected, countdown is decremented. If error is undefined then set it to the rejected value. If countdown is 0 then reject promise with error value.

Reader Interface

Readers connected to this device are accessible through the Reader interface. A reader is the connector to a secure element. Given the removable nature of some secure elements, a reader may or may not have a secure element present. A reader may have at most one present secure element simultaneously. A reader MAY for instance be a UICC slot, a USB smart card reader, an NFC interface, or a mother board slot where a embedded secure element is wired.

readonly attribute boolean isSEPresent
This attribute MUST return true if a secure element is present in this reader. It MUST return false otherwise.
readonly attribute DOMString name
This attribute MUST return the name of the reader. This is an arbitrary name set by the system. It MAY be computed based on ready provided data.
readonly attribute SecureElementType secureElementType
This attribute MUST return the SecureElementType value best matching the type of the secure element this reader gives access to. This information may be useful for applications that target a specific secure element type. It may also be used to build the application user interface, to represent the secure element in a realistic way.
readonly attribute ConnectivityType connectivityType
This attribute MUST return the ConnectivityType value matching the connectivity used by the reader to communicate with the secure element.
Promise<Session> openSession()
This method establishes a communication link with a secure element. There may be several sessions opened at the same time, hence a session MUST NOT lock access to the secure element.
Promise<Reader> close()
This method closes all sessions opened by this reader, and their descendent Channel objects. Invoking close() method on an already closed reader is an idempotent operation.

SecureElementType enum

The SecureElementType enum identifies the type of the secure element a reader gives access to.

uicc
The secure element is a UICC used by the device to connect to a mobile network.
smartcard
The secure element is a smart card.
chip
The secure element is a dedicated chip in the device.
sd
The secure element is a SD card, and may be unplugged.
other
For any other secure element type not listed above.

ConnectivityType enum

The ConnectivityType enum identifies the type of the secure element a reader gives access to.

embedded
The secure element is physically attached to the device, and cannot be removed, at least without powering off the device.
plugged
The secure element is plugged to the device, and can be unplugged.
wireless
The secure element is accessed though wireless communication, such as NFC. It can be disconnected.

Session Interface

A Session represent a connection session to one of the Secure Elements available on the device. These objects can be used to get a communication channel with an application hosted by the Secure Element.

readonly attribute octet[] atr
This attribute MUST return the Answer to Reset provided by the secure element, or null if the secure element does not provide one.
Promise<Channel> openBasicChannel()

This methods opens a basic channel to communicate with a secure element application. Once this channel has been opened by an application, it is considered to be "locked" to other applications: any other call to this method will fail with SENoChannelException error until this basic channel is closed. Some secure elements might always deny opening a basic channel.

If the aid parameter is not null, the underlying implementation of this operation MUST send to the secure element a SELECT command, as defined in [[!ISO7816-4]], with following header values:

  • CLA = ‘0x00’
  • INS = ‘0xA4’
  • P1 =’0x04’ (Select by DF name/application identifier)
  • P2 =’0x00’ (First or only occurrence)

If aid is null, then no SELECT is sent, the channel is opened on the default selected secure element application.

This method will trigger the Access Control Enforcer to check the requesting application is authorized to open such channel.

octet[] aid
This parameter value MUST either be:
  • The complete Application Identifier of the targeted application on the secure element;
  • A partial Application Identifier matching a set of targeted applications on the secure element, in which case the channel will be opened on the first matching application;
  • null if the channel should be opened on the default application.
Promise<Channel> openLogicalChannel()

This methods opens a logical channel to communicate with a secure element application. It is up to the secure element to choose which logical channel will be used. If no more logical channel is available, this method MUST fail with SENoChannelException error.

If the aid parameter is not null, the underlying implementation of this operation MUST send to the secure element a SELECT command, as defined in [[!ISO7816-4]], with following header values:

  • CLA = ‘0x01’ to ‘0x03’, ‘0x40 to 0x4F’ (as chosen by the secure element)
  • INS = ‘0xA4’
  • P1 =’0x04’ (Select by DF name/application identifier)
  • P2 =’0x00’ (First or only occurrence)

If aid is null, then no SELECT is sent, the channel is opened on the default selected secure element application.

This method will trigger the Access Control Enforcer to check the requesting application is authorized to open such channel.

octet[] aid
This parameter value MUST either be:
  • The complete Application Identifier of the targeted application on the secure element;
  • A partial Application Identifier matching a set of targeted applications on the secure element, in which case the channel will be opened on the first matching application;
  • null if the channel should be opened on the default application.
Promise<Session> close()
Closes the connection session to the Secure Element. This will close any channels opened by this application with this Secure Element. Invoking close() method on an already closed session is an idempotent operation.

Channel Interface

A Channel represents an ISO/IEC 7816-4 channel opened to a Secure Element. It can be either a logical channel or the basic channel. It can be used to send commands to a Secure Element application.

readonly attribute boolean isBasicChannel
This attribute must return TRUE if this channel is a basic channel, it MUST return FALSE otherwise.
readonly attribute ArrayBufferView openResponse
This attribute MUST return the secure element's response to the channel opening operation. It MUST be null if the channel was opened on the default secure element application (no AID was provided in the open channel operation).
Promise<ArrayBufferView> selectNext()
Updates the targeted application of this channel to be the next one matching the partial Application Identifier passed when this channel was open. Invoking this method MUST fail with an SEInvalidStateException error if this channel was not open with a partial AID, or with an SENoApplicationException error if there is no next application matching that partial AID. In that case the application associated to this channel is unchanged. If a next application has been found and associated to this channel, this operation succeeds and returns the secure element's response. This response value MUST be assigned to the openResponse attribute.
Promise<SEResponse> transmit()

This method transmits a command to the secure element. The user agent MUST ensure the synchronisation between all the concurrent calls to this method: a command MUST NOT be sent to a secure element while a response is still pending on any channel from this same secure element.

This method will trigger the Access Control Enforcer to check the requesting application is authorized to send such command on this channel.

The channel information in the class byte in the APDU command will be ignored. The system MAY modify the class byte of the command to ensure the APDU is transported on this channel. To ensure the invoking web application does not exit from the scope of this channel, the user agent MUST reject the following commands:

  • MANAGE_CHANNEL (INS=0x70)
  • SELECT by DF Name (INS=0xA4 and P1=04)
SECommand cmd
The command to send to the secure element application.
Promise<ArrayBufferView> transmit()

This method behaves exactly as the transmit method above, excepts that both its parameter and the response are passed as a raw binary data. Before transmitting the command to the secure element, the implementation of this method MUST set the logical channel in the class byte of the command so that it fits the channel allocated to this Channel object.

This method will trigger the Access Control Enforcer to check the requesting application is authorized to send such command on this channel.

ArrayBufferView cmd
The raw command to send to the secure element application. The channel information in the class byte of the command (first octet of the cmd data) will be ignored.
Promise<Channel> close()
This method closes this session object. If a transmit operation is still waiting for the secure element response, the user agent must terminate that asynchronous operation with a closed error status. Invoking close() method on an already closed channel is an idempotent operation.

SECommand Interface

The SECommand interface represents an APDU command that can be sent to a secure element.

attribute octet cla
Class byte
attribute octet ins
Instruction byte
attribute octet p1
First octet of the parameter bytes
attribute octet p2
Second octet of the parameter bytes
attribute ArrayBufferView data
Data field bytes, or null if command has no data
attribute unsigned short le
The length of the expected response data, or -1 if application does not require a specific length

SEResponse Interface

The SEResponse interface represents an APDU response received from a secure element.

readonly attribute octet sw1
First octet of response's status word
readonly attribute octet sw2
Second octet of response's status word
readonly attribute ArrayBufferView data
The response's data field bytes
boolean isStatus()
Utility method to test the status word of an APDU response. This method MUST return true if the parameters match the value of the response.
octet sw1
Value to compare to the first octet of response's status word, or null if this first octet may have any value.
octet sw2
Value to compare to the second octet of response's status word, or null if this second octet may have any value.

Error types

In the interfaces defined above, some method return a Promise object. If an error occurs during the execution of any of these methods, the reject() method of promise's resolver will be invoked with an error value of one of the following DOMException subtypes:

SESecurityException
The requested operation does not match the access conditions of the application, as defined in Access Control section
SEIoException
Communication error
SEInvalidStateException
The target object was not in the proper state to execute the operation
SEInvalidValueException
The method was invoked with an incorrect parameter value
SENoChannelException
Tentative to open a channel failed because no channel is available
SENoApplicationException
The requested application was not found on the secure element
SEClosedException
The operation could not be fulfilled because the target object is closed
SEUnknownException
Internal error, no further details available

Code example

The javascript code excerpt below shows how a web application can wait for a card to be present, and send it an APDU command:


            // my application identifier
            var myAppId = ...;
            // my application command
            var myAppCmd = new SECommand(...);

            // get secure element manager
            var seMgr = navigator.secureElementManager;

            // register sepresent event handler
            seMgr.onsepresent = function(reader) {

              // open session
              reader.openSession()
              .then(

                function (session) {
                  // open a basic channel to my application
                  return session.openBasicChannel(myAppID);
                }

              ).then(

                function (channel) {
                  // open a basic channel to my application
                  return channel.transmit(myAppCmd);
                }

              ).then(

                function (response) {
                  if (!response.isStatus(0x90, 0x00) {
                    // this might be an error
                    // ...
                  }
                }

              );
            };

For simplicity and readability reasons, the code above omits the error handling and closing operations that would have to be done in a real web application.

Changes

The complete list of changes can be viewed on Github. You can also check the issues.

Acknowledgements

Thanks to contributors and reviewers...