Copyright © 2015-2016 GlobalPlatform. This document is licensed under the Apache License, Version 2.0
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.
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:
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, and MUST NOT are to be interpreted as described in [RFC2119].
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.
SecureElementManager
Interface
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
();
};
onsepresent
of type EventHandler, nullable
sepresent
and event type is
ReaderEvent
.
onseremoval
of type EventHandler, nullable
Session
and Channel
objects providing access to this Secure Element are marked as closed. The event name is seremoval
and event type is
ReaderEvent
.
getReaders
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.
shutdown
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
.
SecureElementManager
object.
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
;
};
ReaderEvent.reader
of type Reader
, readonly
dictionary ReaderEventInit : EventInit {
Reader
reader
;
};
ReaderEventInit.reader
of type Reader
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 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
();
};
isSEPresent
of type boolean, readonly
name
of type DOMString, readonly
secureElementType
of type SecureElementType
, readonly
SecureElementType
value that matches 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.
isRemovable
of type boolean, readonly
true
if the Secure Element cannot be detached without powering down the device.
openSession
closeSessions
reset
SEUnsupportedException
. error.
SecureElementType
Enum
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. |
Session
Interface
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
();
};
reader
of type Reader
, readonly
historicalBytes
of type Uint8Array, readonly, nullable
null
if the interface does not provide it.
openBasicChannel
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’. |
openSupplementaryChannel
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
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.
Channel
Interface
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
();
};
session
of type Session
, readonly
channelType
of type ChannelType
, readonly
openResponse
of type SEResponse
, readonly, nullable
null
if the channel was opened on the default on-card application (no
AID was provided in the open channel operation).
timeout
of type int
timeout
ms.
selectNext
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.
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 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. |
transmitRaw
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
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.
ChannelType
Enum
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). |
SECommand
Interface
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
;
};
cla
of type octet
ins
of type octet
p1
of type octet
p2
of type octet
data
of type Uint8Array, nullable
null
if command has no data.
le
of type unsigned
short
undefined
if application does not require a specific length.
isExtended
of type boolean
true
the command MUST be transmitted using
extended length encoding.
SEResponse
Interface
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);
};
channel
of type Channel
, readonly
sw1
of type octet, readonly
sw2
of type octet, readonly
data
of type Uint8Array, readonly
isStatus
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.