Unofficial Draft
Copyright © 2025 the document editors/authors. Text is available under the Creative Commons Attribution 4.0 International Public License; additional terms may apply.
The objective of this API is to enable smart card (PC/SC) applications to move to the Web Platform. It gives them access to the PC/SC implementation (and card reader drivers) available in the host OS. There is also a companion explainer document.
This document is a draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organization.
WebIDL[Exposed=(DedicatedWorker, SharedWorker, Window), SecureContext, IsolatedContext]
interface SmartCardResourceManager
{
Promise<SmartCardContext
> establishContext
();
};
Methods on this interface complete asynchronously, queuing work on the smart card task source.
Requests a PC/SC context from the platform's PC/SC stack.
TheestablishContext
()
method steps are:
SecurityError
" DOMException
.
RESOURCEMANAGER
class.EstablishContext
method of resourceManager with
a "system" Scope
parameter.RESPONSECODE
is not SCARD_S_SUCCESS
, perform
the following steps:
corresponding
exception.SmartCardContext
whose
[[resourceManager]]
internal slot is set
to resourceManager.A context for communicating with the PC/SC resource manager.
WebIDL[Exposed=(DedicatedWorker, SharedWorker, Window), SecureContext]
interface SmartCardContext
{
Promise<sequence<DOMString>> listReaders
();
Promise<sequence<SmartCardReaderStateOut
>> getStatusChange
(
sequence<SmartCardReaderStateIn
> readerStates,
optional SmartCardGetStatusChangeOptions
options = {});
Promise<SmartCardConnectResult
> connect
(
DOMString readerName,
SmartCardAccessMode
accessMode,
optional SmartCardConnectOptions
options = {});
};
Instances of SmartCardContext
are created with the internal slots
described in the following table:
Internal slot | Initial value | Description (non-normative) |
---|---|---|
[[resourceManager]] | null |
The platform's [PCSC5] RESOURCEMANAGER to be used. |
[[operationInProgress]] | false |
Whether there is an ongoing PC/SC operation in this context. |
[[connections]] | An empty ordered set | The existing SmartCardConnection s created by this context. |
[[tracker]] | null |
A [PCSC5] SCARDTRACK instance. |
[[signal]] | null |
The AbortSignal of the outstanding
getStatusChange () call, if any. |
The listReaders
()
method steps
are:
[[operationInProgress]]
is
true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[operationInProgress]]
to
true
.RESOURCEQUERY
class, with
this.[[resourceManager]]
as its
constructor input parameter.STR[]
containing the list of group names that is equivalent to "all
readers in the system" in that platform.
STR[]
.
ListReaders
method of resourceQuery with
groups as input and pcscReaders as output parameters.RESPONSECODE
.SCARD_S_SUCCESS
:
SCARD_E_NO_READERS_AVAILABLE
,
resolve promise with an empty sequence
of
DOMString
.
corresponding
to
responseCode.sequence
of
DOMString
equivalent to pcscReaders.The getStatusChange
(readerStates, options)
method steps
are:
[[operationInProgress]]
is
true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.signal
"]
exists, run the following steps:
signal
"].[[signal]]
to signalCancel the outstanding GetStatusChange
algorithm to signal.DWORD
set to [PCSC5]
INFINITE
.timeout
"]
exists, set pcscTimeout to
options["timeout
"].SCARD_READERSTATE[]
corresponding to
readerStates.[[operationInProgress]]
to
true
.[[tracker]]
to a new instance of the
platform's [PCSC5] SCARDTRACK
class, with
this.[[resourceManager]]
as its
constructor input parameter.[[tracker]]
.GetStatusChange()
with pcscReaderStates and pcscTimeout as input parameters.RESPONSECODE
.[[tracker]]
to null
.undefined
.[[signal]]
is not null
,
run the following steps:
[[signal]]
is
aborted then set abortReason to
this.[[signal]]
's
abort reason.cancel the outstanding GetStatusChange
algorithm from
this.[[signal]]
.[[signal]]
to
null
.SCARD_S_SUCCESS
, run the
following steps:
SCARD_E_CANCELLED
and
abortReason is not undefined
then reject
promise with abortReason.corresponding
to responseCode.SmartCardReaderStateOut
corresponding to
pcscReaderStates.WebIDLdictionary SmartCardReaderStateIn
{
required DOMString readerName
;
required SmartCardReaderStateFlagsIn
currentState
;
unsigned long currentCount
;
};
readerName
membercurrentState
membercurrentCount
memberGiven a sequence of SmartCardReaderStateIn
named
readerStates, a
corresponding
[PCSC5] SCARD_READERSTATE[]
is created with the following
steps:
SCARD_READERSTATE[]
.SCARD_READERSTATE
.Reader
to
stateIn["readerName
"].CurrentState
to the DWORD
corresponding
to stateIn["currentState
"].currentCount
"]
exists, set the high word of
pcscState.CurrentState
to
stateIn["currentCount
"].EventState
to zero.WebIDLdictionary SmartCardReaderStateFlagsIn
{
boolean unaware
= false;
boolean ignore
= false;
boolean empty
= false;
boolean present
= false;
boolean exclusive
= false;
boolean inuse
= false;
boolean mute
= false;
boolean unpowered
= false;
};
unaware
memberignore
memberunavailable
memberempty
memberpresent
memberexclusive
memberinuse
membermute
memberunpowered
memberThe [PCSC5] DWORD
corresponding
to a given SmartCardReaderStateFlagsIn
is created with the
following steps:
SmartCardReaderStateFlagsIn
.DWORD
set to zero.unaware
"] is
true
, add [PCSC5] SCARD_STATE_UNAWARE
to
pcscFlags.ignore
"] is
true
, add [PCSC5] SCARD_STATE_IGNORE
to
pcscFlags.unavailable
"]
is true
, add [PCSC5]
SCARD_STATE_UNAVAILABLE
to pcscFlags.empty
"] is
true
, add [PCSC5] SCARD_STATE_EMPTY
to
pcscFlags.present
"] is
true
, add [PCSC5] SCARD_STATE_PRESENT
to
pcscFlags.exclusive
"] is
true
, add [PCSC5] SCARD_STATE_EXCLUSIVE
to
pcscFlags.inuse
"] is
true
, add [PCSC5] SCARD_STATE_INUSE
to
pcscFlags.mute
"] is
true
, add SCARD_STATE_MUTE
to
pcscFlags.
unpowered
"] is
true
, add SCARD_STATE_UNPOWERED
to
pcscFlags.The actual state of a smart card reader.
WebIDLdictionary SmartCardReaderStateOut
{
required DOMString readerName
;
required SmartCardReaderStateFlagsOut
eventState
;
required unsigned long eventCount
;
ArrayBuffer answerToReset
;
};
readerName
membereventState
membereventCount
memberanswerToReset
memberGiven a [PCSC5] SCARD_READERSTATE[]
named
pcscReaderStates, a corresponding sequence of
SmartCardReaderStateOut
is created with the following steps:
SmartCardReaderStateOut
.SmartCardReaderStateOut
.readerName
"] to
pcscState.Reader
.eventState
"] to
the SmartCardReaderStateFlagsOut
dictionary
corresponding
to pcscState.EventState
.eventCount
"] to
the high word of pcscState.EventState
.
SCARD_READERSTATE
structure has a member
containing the card's [ISO7186-3] Answer To Reset, set
stateOut["answerToReset
"] to
that value.WebIDLdictionary SmartCardReaderStateFlagsOut
{
boolean ignore
= false;
boolean changed
= false;
boolean unknown
= false;
boolean empty
= false;
boolean present
= false;
boolean exclusive
= false;
boolean inuse
= false;
boolean mute
= false;
boolean unpowered
= false;
};
ignore
memberchanged
memberunavailable
memberunknown
memberempty
memberpresent
memberexclusive
memberinuse
membermute
memberunpowered
memberGiven a [PCSC5] DWORD
named pcscFlags, a corresponding
SmartCardReaderStateFlagsOut
dictionary is created with the
following steps:
SmartCardReaderStateFlagsOut
dictionary with default members.SCARD_STATE_IGNORE
, set
flagsOut["ignore
"] to
true
.SCARD_STATE_CHANGED
, set
flagsOut["changed
"] to
true
.SCARD_STATE_UNAVAILABLE
, set
flagsOut["unavailable
"] to
true
.SCARD_STATE_UNKNOWN
, set
flagsOut["unknown
"] to
true
.SCARD_STATE_EMPTY
, set
flagsOut["empty
"] to
true
.SCARD_STATE_PRESENT
, set
flagsOut["present
"] to
true
.SCARD_STATE_EXCLUSIVE
, set
flagsOut["exclusive
"] to
true
.SCARD_STATE_INUSE
, set
flagsOut["inuse
"] to
true
.SCARD_STATE_MUTE
, set
flagsOut["mute
"] to
true
.SCARD_STATE_UNPOWERED
, set
flagsOut["unpowered
"] to
true
.WebIDLdictionary SmartCardGetStatusChangeOptions
{
DOMHighResTimeStamp timeout
;
AbortSignal signal
;
};
timeout
membersignal
memberThe connect
(readerName, accessMode, options)
method steps are:
[[operationInProgress]]
is
true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[operationInProgress]]
to
true
.DWORD
corresponding to
accessMode.DWORD
set to 0
.preferredProtocols
"]
exists, set protocolFlags to its
corresponding flags.DWORD
set to 0
.SCARDCOMM
class, with
this.[[resourceManager]]
as its
constructor parameter.Connect()
with readerName, accessFlags
and protocolFlags as input and activeProtocol as output parameters.RESPONSECODE
.SCARD_S_SUCCESS
:
corresponding
to responseCode and abort these steps.SmartCardConnectResult
dictionary.SmartCardConnection
.[[connections]]
.[[comm]]
to comm.
[[context]]
to
this.
[[activeProtocol]]
to
activeProtocol.
connection
"] to
connection.activeProtocol
"] to the
corresponding SmartCardProtocol
.WebIDLenum SmartCardProtocol
{
"raw
",
"t0
",
"t1
"
};
raw
SCARD_PROTOCOL_RAW
DWORD
.t0
SCARD_PROTOCOL_T0
DWORD
.t1
SCARD_PROTOCOL_T1
DWORD
.A [PCSC5] DWORD
is a valid protocol value if it is either
[PCSC5] SCARD_PROTOCOL_T0
, [PCSC5] SCARD_PROTOCOL_T1
or
[PCSC5] SCARD_PROTOCOL_RAW
.
Given a sequence of SmartCardProtocol
named
protocols, a [PCSC5] DWORD
with the corresponding
flags is created with the following steps:
WebIDLdictionary SmartCardConnectResult
{
required SmartCardConnection
connection
;
SmartCardProtocol
activeProtocol
;
};
connection
memberactiveProtocol
memberWebIDLenum SmartCardAccessMode
{
"shared
",
"exclusive
",
"direct
"
};
shared
exclusive
direct
Given a SmartCardAccessMode
enum named
accessMode, a corresponding [PCSC5]
DWORD
is created with the following steps:
WebIDLdictionary SmartCardConnectOptions
{
sequence<SmartCardProtocol
> preferredProtocols
;
};
preferredProtocols
To clear the operationInProgress of a
SmartCardContext
context, perform the following steps:
[[operationInProgress]]
is true
.[[operationInProgress]]
to
false
.[[connections]]
:
[[operationInProgress]]
is
true
, abort there steps.The cancel the outstanding GetStatusChange algorithm steps are:
[[tracker]]
.Cancel()
.The high word of a [PCSC5] DWORD
is the result of an
unsigned right shift of 16 bits on that DWORD
.
To set the high word of a [PCSC5] DWORD
named
dword to a given number n, perform the following steps.
0xFFFF
.To add a flag f to a [PCSC5] DWORD
flags, set flags to flags bitwise OR f.
A [PCSC5] DWORD
flags has a flag f
if flags bitwise AND f is f.
WebIDL[Exposed=(DedicatedWorker, SharedWorker, Window), SecureContext]
interface SmartCardConnection
{
Promise<undefined> disconnect
(optional SmartCardDisposition
disposition = "leave");
Promise<ArrayBuffer> transmit
(BufferSource sendBuffer,
optional SmartCardTransmitOptions
options = {});
Promise<undefined> startTransaction
(SmartCardTransactionCallback
transaction,
optional SmartCardTransactionOptions
options = {});
Promise<SmartCardConnectionStatus
> status
();
Promise<ArrayBuffer> control
([EnforceRange] unsigned long controlCode,
BufferSource data);
Promise<ArrayBuffer> getAttribute
([EnforceRange] unsigned long tag);
Promise<undefined> setAttribute
([EnforceRange] unsigned long tag, BufferSource value);
};
callback SmartCardTransactionCallback
= Promise<SmartCardDisposition
?> ();
Instances of SmartCardConnection
are created with the internal slots
described in the following table:
Internal slot | Initial value | Description (non-normative) |
---|---|---|
[[comm]] | null |
The platform's [PCSC5] SCARDCOMM to be used. |
[[context]] | null |
The SmartCardContext that created this instance. |
[[activeProtocol]] | 0 | The active protocol DWORD , as returned by the platform's
[PCSC5] implementation. |
[[transactionState]] | null |
Holds the state of an ongoing transaction
started with startTransaction () , if
any. |
The disconnect
(disposition)
method steps
are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.[[context]]
.[[operationInProgress]]
to true
.[[comm]]
.Disconnect()
with a DWORD
corresponding to
disposition as input parameter.RESPONSECODE
.[[context]]
.SCARD_S_SUCCESS
, reject
promise with an exception
corresponding
to responseCode and abort
these steps.[[comm]]
.[[comm]]
to null
.WebIDLenum SmartCardDisposition
{
"leave
",
"reset
",
"unpower
",
"eject
"
};
leave
SCARD_LEAVE_CARD
DWORD
.reset
SCARD_RESET_CARD
DWORD
.unpower
SCARD_UNPOWER_CARD
DWORD
.eject
SCARD_EJECT_CARD
DWORD
.The transmit
(sendBuffer, options)
method steps
are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.DWORD
set to
this.[[activeProtocol]]
.
protocol
"]
exists, set protocol to the DWORD
corresponding to
options["protocol
"].
InvalidStateError
" DOMException
and return promise.[[context]]
.[[operationInProgress]]
to true
.SCARD_IO_HEADER
corresponding to
this.[[activeProtocol]]
.BYTE[]
containing sendBuffer.SCARD_IO_HEADER
equivalent of empty or null.BYTE[]
big enough to hold
the largest [ISO7186-3] extended response APDU (65538 bytes).DWORD
set to 0
.[[comm]]
.Transmit()
with sendPci, pcscSendBuffer, recvPci, recvBuffer and
recvLength as arguments.RESPONSECODE
.[[context]]
.SCARD_S_SUCCESS
, reject
promise with an exception
corresponding
to responseCode and abort
these steps.ArrayBuffer
containing
the first recvLength bytes of recvBuffer.WebIDLdictionary SmartCardTransmitOptions
{
SmartCardProtocol
protocol
;
};
protocol
memberThe startTransaction
(transaction, options)
method steps are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.[[transactionState]]
is not
null
, reject promise with a "InvalidStateError
"
DOMException
and return promise.AbortSignal
set to null
.signal
"]
exists, run the following steps:
[[context]]
.[[operationInProgress]]
to true
.[[comm]]
.BeginTransaction()
.RESPONSECODE
.WebIDLdictionary SmartCardTransactionOptions
{
AbortSignal signal
;
};
signal
memberA transaction state is a struct with the following items:
Item | Description (non-normative) |
---|---|
pendingDisposition | If set, it means once the ongoing PC/SC operation finishes
[PCSC5] EndTransaction() should be called with this value as the
SmartCardDisposition parameter. |
pendingException | The exception to be used when rejecting promise. |
promise | The pending Promise returned by a
startTransaction () call. |
To process the result of a BeginTransaction given a
SmartCardConnection
connection, a [PCSC5]
RESPONSECODE
responseCode, an AbortSignal
signal, a SmartCardTransactionCallback
transaction and a Promise
promise, perform the following steps:
[[context]]
.undefined
.null
:
cancel
algorithm from
signal.SCARD_S_SUCCESS
:
SCARD_E_CANCELLED
and
abortReason is not undefined
then reject
promise with abortReason.corresponding
to
responseCode.[[transactionState]]
to transactionState.reset
".
undefined
, set disposition to
v.[[context]]
.[[operationInProgress]]
is true
:
InvalidStateError
"
DOMException
.[[context]]
.[[operationInProgress]]
is true
, set
transactionState's pendingDisposition to
"reset
".reset
".To end the transaction of a SmartCardConnection
connection with a SmartCardDisposition
disposition, perform the following steps:
[[context]]
.[[operationInProgress]]
is false
.[[transactionState]]
is not
null
.[[transactionState]]
's
pendingDisposition is null
.[[transactionState]]
's
promise.[[comm]]
is null
:
InvalidStateError
"
DOMException
.[[transactionState]]
to
null
.[[context]]
.[[operationInProgress]]
to true
.[[comm]]
.EndTransaction()
with
a DWORD
corresponding to disposition as input parameter.RESPONSECODE
.[[context]]
.[[transactionState]]
's
pendingException.null
, perform the following steps:
SCARD_S_SUCCESS
,
resolve transactionPromise.corresponding
to
responseCode.[[transactionState]]
to null
.To end any settled transaction of a
SmartCardConnection
connection, perform the
following steps:
[[transactionState]]
is
null
, abort these steps.[[transactionState]]
's
pendingDisposition.null
, abort these steps.[[transactionState]]
's
pendingDisposition to null
.To cancel outstanding [PCSC5] SCARDCOMM
operations,
call this.[[comm]]
.Cancel()
.
The status
()
method steps are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.[[context]]
.[[operationInProgress]]
to true
.STR[]
.DWORD
set to 0
.DWORD
set to 0
.BYTE[]
big enough to hold
any [ISO7186-3] Answer To Reset (ATR).[[comm]]
.Status()
with pcscReader, pcscState, activeProtocol and pcscAtr as
output parameters.RESPONSECODE
.[[context]]
.SCARD_S_SUCCESS
, reject
promise with an exception
corresponding
to responseCode and abort
these steps.SmartCardConnectionState
corresponding to pcscState
and activeProtocol.undefined
, reject promise with an
"UnknownError
" DOMException
and abort these steps.SmartCardConnectionStatus
.readerName
"]
to pcscReader.state
"]
to state.answerToReset
"] to
an ArrayBuffer
with the bytes that were written to
pcscAtr.WebIDLdictionary SmartCardConnectionStatus
{
required DOMString readerName
;
required SmartCardConnectionState
state
;
ArrayBuffer answerToReset
;
};
readerName
memberstate
memberanswerToReset
memberWebIDLenum SmartCardConnectionState
{
"absent
",
"present
",
"swallowed
",
"powered
",
"negotiable
",
"t0
",
"t1
",
"raw
"
};
absent
present
swallowed
powered
negotiable
t0
t1
raw
Given a [PCSC5] DWORD
pcscState and a DWORD
activeProtocol, a
corresponding
SmartCardConnectionState
is created with the following steps:
SCARD_ABSENT
, return
"absent
".SCARD_PRESENT
, return
"present
".SCARD_SWALLOWED
, return
"swallowed
".SCARD_POWERED
, return
"powered
".SCARD_NEGOTIABLE
, return
"negotiable
".SCARD_SPECIFIC
, perform the
following steps:
undefined
.The control
(controlCode, data)
method steps are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.[[context]]
.[[operationInProgress]]
to true
.DWORD
containing
controlCode.BYTE[]
inBuffer.BYTE[]
large enough
to hold any control command response.DWORD
set to 0
.[[comm]]
.Control()
with pcscControlCode, inBuffer, outBuffer and
outBufferLength as arguments.RESPONSECODE
.[[context]]
.SCARD_S_SUCCESS
, reject
promise with an exception
corresponding
to responseCode and abort
these steps.ArrayBuffer
from
resultBytes in this's relevant Realm.The getAttribute
(tag)
method steps are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.[[context]]
.[[operationInProgress]]
to true
.DWORD
containing tag.BYTE[]
large
enough to hold this reader attribute, as determined by the
platform's [PCSC5] implementation.[[comm]]
.GetReaderCapabilities()
with pcscTag and buffer as arguments.RESPONSECODE
.[[context]]
.SCARD_S_SUCCESS
, reject
promise with an exception
corresponding
to responseCode and abort
these steps.ArrayBuffer
from
resultBytes in this's relevant Realm.The setAttribute
(tag, value)
method steps are:
[[context]]
.[[operationInProgress]]
is true
, reject promise with a "InvalidStateError
"
DOMException
and return promise.[[comm]]
is null
, reject
promise with a "InvalidStateError
" DOMException
and return
promise.[[context]]
.[[operationInProgress]]
to true
.DWORD
containing
tag.BYTE[]
buffer.[[comm]]
.SetReaderCapabilities()
with pcscTag and buffer as arguments.RESPONSECODE
.[[context]]
.SCARD_S_SUCCESS
, reject
promise with an exception
corresponding
to responseCode and abort
these steps.WebIDL[Exposed=(DedicatedWorker, SharedWorker, Window), Serializable]
interface SmartCardError
: DOMException {
constructor
(optional DOMString message = "", SmartCardErrorOptions
options);
readonly attribute SmartCardResponseCode
responseCode
;
};
The responseCode
attribute is the error or warning response
code returned by the related [PCSC5] method.
Given a [PCSC5] RESPONSECODE
different from SCARD_S_SUCCESS
, a
corresponding exception is
created with the following steps:
RESPONSECODE
.SCARD_E_NO_SERVICE
, return a new
"no-service
" SmartCardError
.
SCARD_E_NO_SMARTCARD
, return a new
"no-smartcard
" SmartCardError
.SCARD_E_NOT_READY
, return a new
"not-ready
" SmartCardError
.SCARD_E_NOT_TRANSACTED
, return a new
"not-transacted
" SmartCardError
.SCARD_E_PROTO_MISMATCH
, return a new
"proto-mismatch
" SmartCardError
.SCARD_E_READER_UNAVAILABLE
, return a new
"reader-unavailable
"
SmartCardError
.SCARD_W_REMOVED_CARD
, return a new
"removed-card
" SmartCardError
.SCARD_W_RESET_CARD
, return a new
"reset-card
" SmartCardError
.SCARD_E_SERVER_TOO_BUSY
, return a new
"server-too-busy
" SmartCardError
.SCARD_E_SHARING_VIOLATION
, return a new
"sharing-violation
" SmartCardError
.SCARD_E_SYSTEM_CANCELLED
, return a new
"system-cancelled
" SmartCardError
.SCARD_E_UNKNOWN_READER
, return a new
"unknown-reader
" SmartCardError
.SCARD_W_UNPOWERED_CARD
, return a new
"unpowered-card
" SmartCardError
.SCARD_W_UNRESPONSIVE_CARD
, return a new
"unresponsive-card
" SmartCardError
.SCARD_W_UNSUPPORTED_CARD
, return a new
"unsupported-card
" SmartCardError
.SCARD_E_UNSUPPORTED_FEATURE
, return a new
"unsupported-feature
"
SmartCardError
.SCARD_E_INVALID_PARAMETER
, return a new
TypeError
.SCARD_E_INVALID_HANDLE
, return a new
"InvalidStateError
" DOMException
.SCARD_E_SERVICE_STOPPED
, return a new
"InvalidStateError
" DOMException
.SCARD_P_SHUTDOWN
, return a new
"AbortError
" DOMException
.UnknownError
" DOMException
.WebIDLdictionary SmartCardErrorOptions
{
required SmartCardResponseCode
responseCode
;
};
The responseCode
member is the value for SmartCardError
's
responseCode
attribute.
WebIDLenum SmartCardResponseCode
{
"no-service
",
"no-smartcard
",
"not-ready
",
"not-transacted
",
"proto-mismatch
",
"reader-unavailable
",
"removed-card
",
"reset-card
",
"server-too-busy
",
"sharing-violation
",
"system-cancelled
",
"unknown-reader
",
"unpowered-card
",
"unresponsive-card
",
"unsupported-card
",
"unsupported-feature
"
};
no-service
no-smartcard
not-ready
not-transacted
proto-mismatch
reader-unavailable
removed-card
reset-card
server-too-busy
sharing-violation
system-cancelled
unknown-reader
unpowered-card
unresponsive-card
unsupported-card
unsupported-feature
This API provides web applications with access to the host's PC/SC smart card subsystem. This is a powerful feature that, if misused, could have significant negative impacts on a user's security and privacy. This section outlines the threats considered and the normative requirements for user agents to mitigate them.
Access to a smart card reader and any card present within it is a
powerful feature. A user agent MUST NOT
allow a web application to gain access to a SmartCardConnection
object without express permission.
User consent MUST be obtained for a specific
origin. The request for consent MUST be
triggered by a call to the connect
()
method. The
user agent MUST display a permission prompt
that clearly indicates which origin is requesting access and provides
the user with enough information to make an informed decision (for
example, by displaying the name of the smart card reader).
User agents SHOULD provide options for both transient (e.g., "for this session only") and persistent permission. To mitigate the risk of users forgetting they have granted persistent access, transient permission SHOULD be the default and more prominent option.
Users MUST be provided with a mechanism to view and revoke any previously granted permissions for this API.
The listReaders
()
method and the
answerToReset
member of the
SmartCardReaderStateOut
dictionary expose information that can be
used for passive fingerprinting. The presence and model of smart card
readers can reveal information about the user, such as whether they
are in a corporate environment. The Answer to Reset (ATR) can further
identify the type and issuer of a smart card.
While this specification does not require a permission prompt before
calling listReaders
()
, access to the entire API
is controlled by the "smart-card"
policy-controlled feature. This allows administrators or users to
disable the API for specific origins, mitigating the fingerprinting
risk.
The control
()
and
setAttribute
()
methods provide direct,
low-level access to the smart card reader hardware. A malicious site
could potentially use these methods to upload malicious firmware,
render the device inoperable, or otherwise interfere with its normal
operation.
Similarly, a malicious site with a connection to a smart card could repeatedly attempt PIN verification to permanently block the card, or access or overwrite sensitive, unprotected data.
The primary mitigation for these threats is the requirement for
express permission before a SmartCardConnection
object is created,
as this gates access to all subsequent powerful methods.
This API operates at a low level and does not have inherent protections against phishing or other forms of spoofing attacks that are present in higher-level APIs like WebAuthn. A malicious site could trick a user into performing an authentication ceremony that is then used to impersonate the user on a different site.
For authentication use cases, developers SHOULD prefer using the Web Authentication API wherever possible.
A smart card with writable memory could be used as a side-channel for different origins to exchange data, bypassing other same-origin policies. The mitigation for this is that express permission is granted to a specific origin. An attack would require the user to grant smart card access to multiple, potentially malicious, origins.
This API MUST only be exposed in an isolated context.
To prevent documents from holding connections to sensitive hardware
while not in the user's direct control, a user agent
MUST dispose of all active
SmartCardContext
objects and their associated
SmartCardConnection
s when a document is no longer
fully active. This includes automatically disconnecting
any active connections as if disconnect
()
were
called.
This specification defines a feature that controls whether the
methods exposed by the smartCard
attribute on the
Navigator
object may be used.
The feature name for this feature is "smart-card".
The default allowlist for this feature
is 'none'
. User agents MAY override this
to 'self'
for particular origins (for example based on user decision).
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, MUST NOT, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: