A Secure Element is a tamper resistant 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. Trusted Execution Environment (TEE) is out of scope of this specification.
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 is a work-in-progress specification. Implementers are informed that this API may change without providing any backward compatibility at this stage. If you are interested in implementing or using this API, we encourage you to contact the editors.
See Changes section for history details.
The 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 Protocol Data Unit).
Secure Elements addressed by this specification are microcontrollers 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). These are only examples; many other applications have been and can be deployed.
Applications hosted by the Secure Elements are called on-card applications. On-card applications have a limited, if any, user interface. An application can be useful with an off-card application part, which handles 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.
This specification shows how to develop 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 implements 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.
This specification, although addressing some concepts similar to several 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.
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.
[[!GP-AC]]: The Access Rules and Access Control Enforcer (ACE) concepts.
[[!GP]]: The Supplementary Logical Channel and Issuer Security Domain concepts.
Some Secure Element concepts are defined in ISO/IEC specifications:
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:
Communication with a Secure Element is performed through a reader, which is not only able to read content from Secure Element, but also to write or send any application specific command. Given the removable 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 communication range. For this reason, the API provides a means 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, the web application still needs to identify the application with which it wants to communicate.
To this end, the session object provides a means to open a channel with a specific on-card application, which is uniquely identified by an AID. The web application runtime and the Secure Element may then perform some internal security check to ensure the web application is allowed to connect to this on-card application. If authorized, the returned channel object is the one providing the method to send commands to the on-card application and get the corresponding responses.
The above steps required to send a command to a Secure Element create 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 resources associated with
the target object, which invokes the close()
method on
each underlying object in the chain.
In order to make sure only authorized web applications can access the Secure Element, the web application runtime MUST use 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). The interface between the web application runtime and the Access Control Enforcer is out of scope of this specification.
To control which applications running on a user device are allowed to access on-card applications, several entities are involved:
Sections below describe how the GlobalPlatform Access Control is applied to web applications. Details of the GlobalPlatform Access Control mechanisms itself are defined in [[!GP-AC]].
The Access Control Enforcer uses an application identifier to check whether the off-card application is white listed in Access Rules. The web application runtime computes the application identifier using the following algorithm:
origin
be the ASCII serialization of the web
application origin as defined in [[!RFC6454]]
origin
value.
All applications that have the same origin MUST get the same application identifier, hence use the same Access Rules.
The GlobalPlatform Access Control Enforcer will authorize or deny access based on the conditions and algorithm defined in [[!GP-AC]] section 4.
To be eligible to gain access to the Secure Element API, a web application must meet the following requirements:
This specification defines handling of status word as defined in ISO 7816 specifications, in order to behave correctly with any secure element application across different sectors (banking, transport, identity, etc.).
The API or the underlying implementation MUST handle the protocol T=1 as specified in [[ISO7816-3]] and returns data (if available) and received status word to the application. The API or underlying implementation MUST never automatically issue GET-RESPONSE APDU on reception of any status word.
Unless otherwise specified, when sending command APDU, this specification requires the following management for status word for all the methods defined in this document:
Note that the handling of GET RESPONSE specified above implies that the API or underlying implementation MUST handle response data even if it is more than 256 bytes.
The Navigator exposes the Secure Element service.
partial interface Navigator { readonly attribute SecureElementManager? secureElementManager; };
undefined
.
The SecureElementManager interface provides access to Secure Element readers and is the source of events notifying the presence of Secure Elements.
interface SecureElementManager : EventTarget { attribute EventHandler? onsepresent; attribute EventHandler? onseremoval; Promise<Reader[]> getReaders (); Promise<void> shutdown (); };
sepresent
and event type is
ReaderEvent.
seremoval
and event type is
ReaderEvent.
null
if the
shutdown()
method has been called on this
SecureElementManager object. Several invocations of this
method MAY return different array values, because new readers may
become available, while others may be disconnected.
This method closes all sessions and channels opened from this SecureElementManager object and releases other potential internal resources. When invoked, the user agent MUST run the following steps:
shutdown()
method has already been called
on this object, then resolve promise.
readers
attribute and error an object
initially undefined
.
closeSessions()
method on each
Reader object in the array returned by the
readers
attribute.
closeSessions()
invocations.
readers
attribute value to
null
.
undefined
, then resolve
promise. If countdown is 0 and
error is not undefined
, then reject
promise with the error value.
undefined
then set it to the rejected value. If
countdown is 0 then reject promise with
error value.
The sepresent
and seremoval
events are of
type ReaderEvent.
[Constructor(DOMString type, optional ReaderEventInit eventInitDict), Exposed=Window,Worker] interface ReaderEvent : Event { readonly attribute Reader reader; };
dictionary ReaderEventInit : EventInit { Reader reader; };
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 MUST have at most one present Secure Element. 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.
interface Reader { readonly attribute boolean isSEPresent; readonly attribute DOMString name; readonly attribute SecureElementType secureElementType; readonly attribute boolean isRemovable; Promise<Session> openSession (); Promise<void> closeSessions (); Promise<void> reset (); };
true
if the Secure Element
cannot be detached without powering down the device.
SEUnsupportedException
.
error.
The SecureElementType enum identifies the type of the Secure Element a reader gives access to.
enum SecureElementType { "uicc", "smartcard", "ese", "sd", "other" };
Enumeration description | |
---|---|
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 (contactless, contact or USB token). |
ese |
The Secure Element is embedded 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. |
A Session represents a connection to one of the Secure Elements available on the device. These objects can be used to open and close communication channels with an on-card application.
interface Session { readonly attribute Reader reader; readonly attribute Uint8Array? historicalBytes; Promise<Channel> openBasicChannel (Uint8Array? aid, optional octet p2); Promise<Channel> openSupplementaryChannel (Uint8Array? aid, optional octet p2); Promise<void> close (); };
null
if the interface does not provide it.
This methods opens the basic logical channel and selects
an on-card application. Once this channel has been opened
by an off-card application, it is considered to be
"locked" to other applications: any other call to this method
MUST 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 a SELECT command to
the Secure Element, as defined in [[!ISO7816-4]], with following
header values:
p2
parameter if present, ‘0x00’
otherwise (First or only occurrence).
If aid
is null, then no SELECT command is sent, the
channel is opened on the default selected on-card
application.
If aid
is an empty array (array of size 0), the Lc
and data field of the SELECT command MUST be omitted, so that the
Issuer Security Domain is selected as defined in [[!GP]].
This method MUST trigger the Access Control Enforcer to check the requesting off-card application is authorized to open such channel.
For the SELECT command the API MUST handle received status word
as defined in section 7,
except that for T=0 protocol the GET RESPONSE MUST also be sent
in case of SW warning (‘62 XX’ or ‘63 XX’). If the status
word for the SELECT command indicates that the SE was able to
open a channel (status word ‘90 00’ or status words
referencing a warning), the API MUST keep the channel open and
the channel's openResponse
attribute MUST return the
status word for the SELECT command together with data, if any
data is received.
Other status words for the SELECT command which indicate that the SE was not able to open a channel MUST be considered as an error and the corresponding channel MUST NOT be opened.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
aid |
Uint8Array
|
✔ | ✘ |
This parameter value MUST either be:
|
p2 |
octet
|
✘ | ✔ | The P2 parameter of the SELECT APDU executed for this channel. Except for specific needs, it is recommended to omit this method parameter. If provided, the following values are supported as defined in [[!ISO7816-4]]: ‘00’, ‘04’, ‘08’, ‘0C’. |
This methods opens a supplementary logical channel and
selects an on-card application. The Secure Element MUST
open the next available supplementary logical channel. If no more
supplementary logical channels are 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:
p2
parameter if present, ‘0x00’
otherwise (First or only occurrence).
If aid
is null, then no SELECT is sent, the channel
is opened on the default selected on-card application. In
the case of a UICC it is recommended that the API rejects the
opening of the supplementary logical channel without a specific
AID.
If aid
is an empty array (array of size 0), the Lc
and data field of the SELECT command MUST be omitted, so that the
Issuer Security Domain is selected as defined in [[!GP]].
This method MUST trigger the Access Control Enforcer to check the requesting off-card application is authorized to open such channel.
For the SELECT command the API MUST handle received status word
as defined in section 7,
except that for T=0 protocol the GET RESPONSE MUST also be sent
in case of SW warning (‘62 XX’ or ‘63 XX’). If the status
word for the SELECT command indicates that the SE was able to
open a channel (status word ‘90 00’ or status words
referencing a warning), the API MUST keep the channel open and
the channel's openResponse
attribute MUST return the
status word for the SELECT command together with data, if any
data is received.
Other status words for the SELECT command which indicate that the SE was not able to open a channel MUST be considered as an error and the corresponding channel MUST NOT be opened.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
aid |
Uint8Array
|
✔ | ✘ |
This parameter value MUST either be:
|
p2 |
octet
|
✘ | ✔ | The P2 parameter of the SELECT APDU executed for this channel. Except for specific needs, it is recommended to omit this method parameter. If provided, the following values are supported as defined in [[!ISO7816-4]]: ‘00’, ‘04’, ‘08’, ‘0C’. |
close()
method on an already closed session
has no effect. After invoking this method, calling any other method
on this object MUST fail with an SEClosedException error.
A Channel represents an [[!ISO7816-4]] channel opened to a Secure Element. It can be either a supplementary logical channel or the basic logical channel. It can be used to send commands to and receive responses from an on-card application.
interface Channel { readonly attribute Session session; readonly attribute ChannelType channelType; readonly attribute SEResponse? openResponse; attribute int? timeout; Promise<SEResponse> selectNext (); Promise<SEResponse> transmit (SECommand cmd); Promise<Uint8Array> transmitRaw (Uint8Array cmd); Promise<void> close (); };
null
if the
channel was opened on the default on-card application (no
AID was provided in the open channel operation).
timeout
ms.
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.
For the SELECT command the API MUST handle received status word
as defined in section 7,
except that for T=0 protocol the GET RESPONSE MUST also be sent
in case of SW warning (‘62 XX’ or ‘63 XX’). If the status
word for the SELECT command indicates that the SE was able to
open a channel (status word ‘90 00’ or status words
referencing a warning), the API MUST keep the channel open and
the channel's openResponse
attribute MUST return the
status word for the SELECT command together with data, if any
data is received.
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 MUST trigger the Access Control Enforcer to check the requesting off-card application is authorized to send such command on this channel.
The channel information in the class byte in the APDU
command MUST 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 with SEInvalidValueException
error value:
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
cmd |
SECommand
|
✘ | ✘ | The command to send to the on-card application. |
This method behaves exactly as the transmit method above, except 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 MUST trigger the Access Control Enforcer to check the requesting off-card application is authorized to send such command on this channel.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
cmd |
Uint8Array
|
✘ | ✘ | The raw command to send to the on-card application. The channel information in the class byte of the command (first octet of the cmd data) MUST be ignored. |
close()
method MUST wait for completion of any pending
transmit()
operation before closing the channel.
If the channel is not the basic channel, then a MANAGE CHANNEL Close (P1=0x80) command MUST be sent to the Secure Element for closing the channel.
If the channel is the basic channel, then the following procedure MUST be followed for closing the channel:
In all cases the last SW of the MANAGE CHANNEL Close, MANAGE CHANNEL Reset, or SELECT by DF Name command MUST be ignored and the channel object MUST be closed by the API. After invoking this method, calling any other method on this channel object MUST then fail with an SEClosedException error.
The ChannelType enum identifies the type of the Secure Element channel.
enum ChannelType { "basic", "supplementary" };
Enumeration description | |
---|---|
basic |
Basic logical channel, as defined in [[!ISO7816-4]] (channel number 0). |
supplementary |
Supplementary logical channel, as defined in [[!GP]] (channel number > 0). |
The SECommand interface represents an APDU command that can be sent to a Secure Element.
[Constructor(octet cla, octet ins, octet p1, octet p2, optional Uint8Array data, optional octet le, optional boolean isExtended)] interface SECommand { attribute octet cla; attribute octet ins; attribute octet p1; attribute octet p2; attribute Uint8Array? data; attribute unsigned short le; attribute boolean isExtended; };
null
if command has no
data.
undefined
if application does not require a specific length.
true
the command MUST be transmitted using
extended length encoding.
The SEResponse interface represents an APDU response received from a Secure Element.
[Constructor(Uint8Array raw)] interface SEResponse { readonly attribute Channel channel; readonly attribute octet sw1; readonly attribute octet sw2; readonly attribute Uint8Array data; boolean isStatus (octet? sw1, octet? sw2); };
true
if the
parameters match the value of the response.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
sw1 |
octet
|
✔ | ✘ |
Value to compare to the first octet of response's status
word or null if this first octet may have
any value.
|
sw2 |
octet
|
✔ | ✘ |
Value to compare to the second octet of response's
status word or null if this second
octet may have any value.
|
In the interfaces defined above, some methods return a Promise
object. If an error occurs during the execution of any of these
methods, the reject()
method of Promise's resolver MUST be
invoked with an error value of one of the following DOMException
subtypes:
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 = new Uint8Array( [0xA0, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x63, 0x42, 0x00] ); // my application command var myAppCmd = new SECommand(0x00, 0xCA, 0x9F, 0x7F, undefined, 0x2A); // register sepresent event handler navigator.secureElementManager.onsepresent = (event) => { var session; // open session event.reader.openSession() .then( _session => { session = _session; return session.openBasicChannel(myAppId); }) .then( _channel => { return _channel.transmit(myAppCmd); }) .then( _response => { if (_response.isStatus(0x90, 0x00)) { // process success response mySuccessHandler(_response); } else { // process unexpected response myFailureHandler(_response); } }) .catch( error => { // error handler myErrorHandler(error); }) .then( _ => { if (session) { session.close(); } }) }
The complete list of changes can be viewed on Github. You can also check the issues.