A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://wicg.github.io/web-smart-card/ below:

Web Smart Card API

Abstract

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.

Status of This 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.

Table of Contents
  1. Abstract
  2. Status of This Document
  3. 1. Extensions to the Navigator interface
    1. 1.1 smartCard attribute
  4. 2. Extensions to the WorkerNavigator interface
    1. 2.1 smartCard attribute
  5. 3. SmartCardResourceManager interface
    1. 3.1 establishContext() method
  6. 4. SmartCardContext interface
    1. 4.1 listReaders() method
    2. 4.2 getStatusChange() method
      1. 4.2.1 SmartCardReaderStateIn dictionary
        1. 4.2.1.1 SmartCardReaderStateFlagsIn dictionary
      2. 4.2.2 SmartCardReaderStateOut dictionary
        1. 4.2.2.1 SmartCardReaderStateFlagsOut dictionary
      3. 4.2.3 SmartCardGetStatusChangeOptions dictionary
    3. 4.3 connect() method
      1. 4.3.1 SmartCardProtocol enum
      2. 4.3.2 SmartCardConnectResult dictionary
      3. 4.3.3 SmartCardAccessMode enum
      4. 4.3.4 SmartCardConnectOptions dictionary
    4. 4.4 Auxiliary algorithms and definitions
  7. 5. SmartCardConnection interface
    1. 5.1 disconnect() method
      1. 5.1.1 SmartCardDisposition enum
    2. 5.2 transmit() method
      1. 5.2.1 SmartCardTransmitOptions dictionary
    3. 5.3 startTransaction() method
      1. 5.3.1 SmartCardTransactionOptions dictionary
      2. 5.3.2 Auxiliary algorithms and definitions
    4. 5.4 status() method
      1. 5.4.1 SmartCardConnectionStatus dictionary
        1. 5.4.1.1 SmartCardConnectionState enum
    5. 5.5 control() method
    6. 5.6 getAttribute() method
    7. 5.7 setAttribute() method
  8. 6. SmartCardError interface
    1. 6.1 SmartCardErrorOptions dictionary
    2. 6.2 SmartCardResponseCode enum
  9. 7. Integrations
    1. 7.1 Permissions Policy
  10. 8. Conformance
  11. A. References
    1. A.1 Normative references
[Exposed=Window, SecureContext]
partial interface Navigator {
  [SameObject] readonly attribute SmartCardResourceManager smartCard;
};

When getting, the smartCard attribute always returns the same instance of the SmartCardResourceManager object.

[Exposed=(DedicatedWorker, SharedWorker), SecureContext]
partial interface WorkerNavigator {
  [SameObject] readonly attribute SmartCardResourceManager smartCard;
};

When getting, the smartCard attribute always returns the same instance of the SmartCardResourceManager object.

[Exposed=(DedicatedWorker, SharedWorker, Window), SecureContext]
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.

The establishContext() method steps are:
  1. If this's relevant global object's associated Document is not allowed to use the policy-controlled feature named "smart-card", throw a "SecurityError" DOMException.
  2. Let promise be a new promise.
  3. Run the following steps in parallel:
    1. Let resourceManager be a new instance of the platform's [PCSC5] RESOURCEMANAGER class.
    2. Invoke the EstablishContext method of resourceManager with a "system" Scope parameter.
    3. If the returned RESPONSECODE is not SCARD_S_SUCCESS, perform the following steps:
      1. Destroy resourceManager.
      2. Queue a global task on the relevant global object of this using the smart card task source to reject promise with a corresponding exception.
    4. Otherwise, perform the following steps:
      1. Let context be a new SmartCardContext whose [[resourceManager]] internal slot is set to resourceManager.
      2. Queue a global task on the relevant global object of this using the smart card task source to resolve promise with context.
  4. Return promise.

A context for communicating with the PC/SC resource manager.

[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 SmartCardConnections 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:

  1. Let promise be a new promise.
  2. If this.[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. Set this.[[operationInProgress]] to true.
  4. Run the following steps in parallel:
    1. Let resourceQuery be a new instance of the platform's [PCSC5] RESOURCEQUERY class, with this.[[resourceManager]] as its constructor input parameter.
    2. Let groups be the platform's [PCSC5] STR[] containing the list of group names that is equivalent to "all readers in the system" in that platform.

      Note

      This could be an empty STR[] in some [PCSC5] implementations.
    3. Let pcscReaders be an empty STR[].
    4. Invoke the ListReaders method of resourceQuery with groups as input and pcscReaders as output parameters.
    5. Let responseCode be the returned RESPONSECODE.
    6. Destroy resourceQuery.
    7. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.
      2. If responseCode is not SCARD_S_SUCCESS:
        1. If responseCode is SCARD_E_NO_READERS_AVAILABLE, resolve promise with an empty sequence of DOMString.

          Note

          SCARD_E_NO_READERS_AVAILABLE is not part of [PCSC5] but it is still considered in this specification as existing PC/SC implementations use it.

        2. Otherwise, reject promise with an exception corresponding to responseCode.
      3. Otherwise, resolve promise with a sequence of DOMString equivalent to pcscReaders.
  5. Return promise.

The getStatusChange(readerStates, options) method steps are:

  1. Let promise be a new promise.
  2. If this.[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If options["signal"] exists, run the following steps:
    1. Let signal be options["signal"].
    2. If signal is aborted, reject promise with signal's abort reason and return promise.
    3. Set this.[[signal]] to signal
    4. Add the Cancel the outstanding GetStatusChange algorithm to signal.
  4. Let pcscTimeout be a [PCSC5] DWORD set to [PCSC5] INFINITE.
  5. If options["timeout"] exists, set pcscTimeout to options["timeout"].
  6. Let pcscReaderStates be a [PCSC5] SCARD_READERSTATE[] corresponding to readerStates.
  7. Set this.[[operationInProgress]] to true.
  8. Set this.[[tracker]] to a new instance of the platform's [PCSC5] SCARDTRACK class, with this.[[resourceManager]] as its constructor input parameter.
  9. Run the following steps in parallel:
    1. Call this.[[tracker]].GetStatusChange() with pcscReaderStates and pcscTimeout as input parameters.
    2. Let responseCode be the returned [PCSC5] RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Set this.[[tracker]] to null.
      2. Clear the operationInProgress of this.
      3. Let abortReason be undefined.
      4. If this.[[signal]] is not null, run the following steps:
        1. If this.[[signal]] is aborted then set abortReason to this.[[signal]]'s abort reason.
        2. Remove the cancel the outstanding GetStatusChange algorithm from this.[[signal]].
        3. Set this.[[signal]] to null.
      5. If responseCode is not SCARD_S_SUCCESS, run the following steps:
        1. If responseCode is SCARD_E_CANCELLED and abortReason is not undefined then reject promise with abortReason.
        2. Otherwise, reject promise with an exception corresponding to responseCode.
        3. Return.
      6. Let readerStatesOut be a sequence of SmartCardReaderStateOut corresponding to pcscReaderStates.
      7. Resolve promise with readerStatesOut.
  10. Return promise.
dictionary SmartCardReaderStateIn {
  required DOMString readerName;
  required SmartCardReaderStateFlagsIn currentState;
  unsigned long currentCount;
};
readerName member
Name of the smart card reader.
currentState member
The current state of that smart card reader as known by the application.
currentCount member
The current number of card insertion and removal events in this reader, as known by the application.

Given a sequence of SmartCardReaderStateIn named readerStates, a corresponding [PCSC5] SCARD_READERSTATE[] is created with the following steps:

  1. Let pcscReaderStates be an empty SCARD_READERSTATE[].
  2. For each stateIn in readerStates:
    1. Let pcscState be a SCARD_READERSTATE.
    2. Set pcscState.Reader to stateIn["readerName"].
    3. Set pcscState.CurrentState to the DWORD corresponding to stateIn["currentState"].
    4. If stateIn["currentCount"] exists, set the high word of pcscState.CurrentState to stateIn["currentCount"].
    5. Set pcscState.EventState to zero.
    6. Append pcscState to pcscReaderStates.
  3. Return pcscReaderStates.
dictionary SmartCardReaderStateFlagsIn {
  boolean unaware = false;
  boolean ignore = false;
  boolean unavailable = false;
  boolean empty = false;
  boolean present = false;
  boolean exclusive = false;
  boolean inuse = false;
  boolean mute = false;
  boolean unpowered = false;
};
unaware member
The application is unaware of the current state, and would like to know.
ignore member
The application is not interested in this reader, and it should not be considered during monitoring operations.
unavailable member
The application believes that this reader is not available for use.
empty member
The application believes that there is not a card in the reader.
present member
The application believes that there is a card in the reader.
exclusive member
The application believes that the card in the reader is allocated for exclusive use by another application.
inuse member
The application believes that the card in the reader is in use by one or more other applications, but may be connected to in shared mode.
mute member
The application believes that there is an unresponsive card in the reader.
unpowered member
The application believes that the card in the reader has not been powered up.

The [PCSC5] DWORD corresponding to a given SmartCardReaderStateFlagsIn is created with the following steps:

  1. Let flagsIn be the given SmartCardReaderStateFlagsIn.
  2. Let pcscFlags be a DWORD set to zero.
  3. If flagsIn["unaware"] is true, add [PCSC5] SCARD_STATE_UNAWARE to pcscFlags.
  4. If flagsIn["ignore"] is true, add [PCSC5] SCARD_STATE_IGNORE to pcscFlags.
  5. If flagsIn["unavailable"] is true, add [PCSC5] SCARD_STATE_UNAVAILABLE to pcscFlags.
  6. If flagsIn["empty"] is true, add [PCSC5] SCARD_STATE_EMPTY to pcscFlags.
  7. If flagsIn["present"] is true, add [PCSC5] SCARD_STATE_PRESENT to pcscFlags.
  8. If flagsIn["exclusive"] is true, add [PCSC5] SCARD_STATE_EXCLUSIVE to pcscFlags.
  9. If flagsIn["inuse"] is true, add [PCSC5] SCARD_STATE_INUSE to pcscFlags.
  10. If flagsIn["mute"] is true, add SCARD_STATE_MUTE to pcscFlags.
  11. If flagsIn["unpowered"] is true, add SCARD_STATE_UNPOWERED to pcscFlags.
  12. Return pcscFlags.

Note

SCARD_STATE_MUTE and SCARD_STATE_UNPOWERED are not part of [PCSC5] but are still considered in this specification as existing PC/SC implementations use it.

The actual state of a smart card reader.

dictionary SmartCardReaderStateOut {
  required DOMString readerName;
  required SmartCardReaderStateFlagsOut eventState;
  required unsigned long eventCount;
  ArrayBuffer answerToReset;
};
readerName member
Name of the smart card reader.
eventState member
The actual state of that smart card reader.
eventCount member
The actual number of card insertion and removal events in this reader.
answerToReset member
The inserted card's [ISO7186-3] Answer To Reset (ATR), if applicable.

Given a [PCSC5] SCARD_READERSTATE[] named pcscReaderStates, a corresponding sequence of SmartCardReaderStateOut is created with the following steps:

  1. Let readerStatesOut be an empty sequence of SmartCardReaderStateOut.
  2. For each pcscState in pcscReaderStates:
    1. Let stateOut be a SmartCardReaderStateOut.
    2. Set stateOut["readerName"] to pcscState.Reader.
    3. Set stateOut["eventState"] to the SmartCardReaderStateFlagsOut dictionary corresponding to pcscState.EventState.
    4. Set stateOut["eventCount"] to the high word of pcscState.EventState.

      Note: Number of card insertion and removal events

      Having the number of card insertion and removal events stored in the upper 2 bytes of the EventState and CurrentState DWORDs is not part of [PCSC5] but it is still considered in this specification as several existing PC/SC implementations use it.

      In PC/SC implementations where this information is not available, the upper two bytes of EventState will always be zero and so the resulting "eventCount" will be zero.

      The algorithms in this specification assume that PC/SC implementations will define all [PCSC5] SCARD_STATE_* flags to be DWORD values no higher than 0xFFFF.

    5. If the platform's SCARD_READERSTATE structure has a member containing the card's [ISO7186-3] Answer To Reset, set stateOut["answerToReset"] to that value.
    6. Append stateOut to readerStatesOut.
  3. Return readerStatesOut.
dictionary SmartCardReaderStateFlagsOut {
  boolean ignore = false;
  boolean changed = false;
  boolean unavailable = false;
  boolean unknown = false;
  boolean empty = false;
  boolean present = false;
  boolean exclusive = false;
  boolean inuse = false;
  boolean mute = false;
  boolean unpowered = false;
};
ignore member
The application requested that this reader be ignored.
changed member
There is a difference between the state input by the calling application, and the actual state.
unavailable member
This reader is not available for use.
unknown member
The reader name given by the application is not known.
empty member
There is no card in the reader.
present member
There is a card in the reader.
exclusive member
The card in the reader is allocated for exclusive use by another application.
inuse member
The card in the reader is in use by one or more other applications, but may be connected to in shared mode.
mute member
There is an unresponsive card in the reader.
unpowered member
The card in the reader has not been powered up.

Given a [PCSC5] DWORD named pcscFlags, a corresponding SmartCardReaderStateFlagsOut dictionary is created with the following steps:

  1. Let flagsOut be a SmartCardReaderStateFlagsOut dictionary with default members.
  2. If pcscFlags has [PCSC5] SCARD_STATE_IGNORE, set flagsOut["ignore"] to true.
  3. If pcscFlags has [PCSC5] SCARD_STATE_CHANGED, set flagsOut["changed"] to true.
  4. If pcscFlags has [PCSC5] SCARD_STATE_UNAVAILABLE, set flagsOut["unavailable"] to true.
  5. If pcscFlags has [PCSC5] SCARD_STATE_UNKNOWN, set flagsOut["unknown"] to true.
  6. If pcscFlags has [PCSC5] SCARD_STATE_EMPTY, set flagsOut["empty"] to true.
  7. If pcscFlags has [PCSC5] SCARD_STATE_PRESENT, set flagsOut["present"] to true.
  8. If pcscFlags has [PCSC5] SCARD_STATE_EXCLUSIVE, set flagsOut["exclusive"] to true.
  9. If pcscFlags has [PCSC5] SCARD_STATE_INUSE, set flagsOut["inuse"] to true.
  10. If pcscFlags has SCARD_STATE_MUTE, set flagsOut["mute"] to true.
  11. If pcscFlags has SCARD_STATE_UNPOWERED, set flagsOut["unpowered"] to true.
  12. Return flagsOut.

Note

SCARD_STATE_MUTE and SCARD_STATE_UNPOWERED are not part of [PCSC5] but are still considered in this specification as existing PC/SC implementations use it.

dictionary SmartCardGetStatusChangeOptions {
  DOMHighResTimeStamp timeout;
  AbortSignal signal;
};
timeout member
Timeout parameter for the GetStatusChange() [PCSC5] method. If not specified, a timeout value of INFINITE (which is defined system dependent) will be used.
signal member
When triggered, the platform's [PCSC5] Cancel() method is called.

The connect(readerName, accessMode, options) method steps are:

  1. Let promise be a new promise.
  2. If this.[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. Set this.[[operationInProgress]] to true.
  4. Run the following steps in parallel:
    1. Let accessFlags be a [PCSC5] DWORD corresponding to accessMode.
    2. Let protocolFlags be a DWORD set to 0.
    3. If options["preferredProtocols"] exists, set protocolFlags to its corresponding flags.
    4. Let activeProtocol be a DWORD set to 0.
    5. Let comm be a new instance of the platform's [PCSC5] SCARDCOMM class, with this.[[resourceManager]] as its constructor parameter.
    6. Call comm.Connect() with readerName, accessFlags and protocolFlags as input and activeProtocol as output parameters.
    7. Let responseCode be the returned RESPONSECODE.
    8. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.
      2. If responseCode is not SCARD_S_SUCCESS:
        1. Destroy comm.
        2. Reject promise with an exception corresponding to responseCode and abort these steps.
      3. Let result be an empty SmartCardConnectResult dictionary.
      4. Let connection be a new SmartCardConnection.
      5. Append connection to this.[[connections]].
      6. Set connection.[[comm]] to comm.
      7. Set connection.[[context]] to this.
      8. Set connection.[[activeProtocol]] to activeProtocol.
      9. Set result["connection"] to connection.
      10. If activeProtocol is a valid protocol value, set result["activeProtocol"] to the corresponding SmartCardProtocol.
      11. Resolve promise with result.
  5. Return promise.
enum SmartCardProtocol {
  "raw",
  "t0",
  "t1"
};
raw
"Raw" mode. May be used to support arbitrary data exchange protocols for special-purpose requirements. Corresponds to a [PCSC5] SCARD_PROTOCOL_RAW DWORD.
t0
[ISO7186-3] T=0. Asynchronous half duplex character transmission protocol. Corresponds to a [PCSC5] SCARD_PROTOCOL_T0 DWORD.
t1
[ISO7186-3] T=1. Asynchronous half duplex block transmission protocol. Corresponds to a [PCSC5] 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:

  1. Let flags be a DWORD set to 0.
  2. For each protocol in protocols, add the corresponding DWORD of protocol to flags.
  3. Return flags.
dictionary SmartCardConnectResult {
  required SmartCardConnection connection;
  SmartCardProtocol activeProtocol;
};
connection member
An interface to the connection created.
activeProtocol member
The protocol actually in use.
enum SmartCardAccessMode {
  "",
  "exclusive",
  "direct"
};
Application is willing to share access to card with other applications.
exclusive
Application requires exclusive access to the card.
direct
Application requires connection to reader whether or not card is present. Implies exclusive access.

Given a SmartCardAccessMode enum named accessMode, a corresponding [PCSC5] DWORD is created with the following steps:

  1. Let dword be a DWORD set to 0.
  2. If accessMode is "", set dword to [PCSC5] SCARD_SHARE_SHARED.
  3. If accessMode is "exclusive", set dword to [PCSC5] SCARD_SHARE_EXCLUSIVE.
  4. If accessMode is "direct", set dword to [PCSC5] SCARD_SHARE_DIRECT.
  5. Return dword.
dictionary SmartCardConnectOptions {
  sequence<SmartCardProtocol> preferredProtocols;
};
preferredProtocols
Card communication protocols that may be used.

To clear the operationInProgress of a SmartCardContext context, perform the following steps:

  1. Assert: context.[[operationInProgress]] is true.
  2. Set context.[[operationInProgress]] to false.
  3. For each connection of context.[[connections]]:
    1. End any settled transaction of connection.
    2. If context.[[operationInProgress]] is true, abort there steps.

Note

A transaction ends when the Promise returned by the SmartCardTransactionCallback passed to startTransaction() settles. At this point the user agent should call [PCSC5] EndTransaction() to effect that on the platform's PC/SC stack. But that won't be possible if at that moment there's already another PC/SC operation taking place in the connection's PC/SC context. The user agent then has to wait until this ongoing PC/SC operation finishes before ending that settled transaction.

The cancel the outstanding GetStatusChange algorithm steps are:

  1. Call this.[[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.

  1. Set dword to dword bitwise AND 0xFFFF.
  2. Let shiftedN be the result of a left shift of 16 bits on n.
  3. Set dword to dword bitwise OR shiftedN.

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.

[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.

Note: Lack of the reconnect method

[PCSC5] mentions also the Reconnect method, which has no equivalent here. This is because its behavior differs between implementations—PC/SC Lite does not release the transactions held by the process, while Microsoft's WinSCard does. While PCSC lite's behavior cannot be replicated cross-platform, Microsoft Windows WinSCard can be achieved via calling Disconnect + Connect. Moreover, in case of the Javascript API the benefit of maintaining the same connection handle ID is lost, as the ID is not exposed, only the SmartCardConnection which is an abstraction over it. Hence, there are no material benefits to including this method in the web API.

The disconnect(disposition) method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. Set this.[[context]].[[operationInProgress]] to true.
  5. Run the following steps in parallel:
    1. Call this.[[comm]].Disconnect() with a DWORD corresponding to disposition as input parameter.
    2. Let responseCode be the returned RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.[[context]].
      2. If responseCode is not SCARD_S_SUCCESS, reject promise with an exception corresponding to responseCode and abort these steps.
      3. Destroy this.[[comm]].
      4. Set this.[[comm]] to null.
      5. Resolve promise.
  6. Return promise.
enum SmartCardDisposition {
  "leave",
  "reset",
  "unpower",
  "eject"
};
leave
Don't alter card state. Corresponds to a [PCSC5] SCARD_LEAVE_CARD DWORD.
reset
Reset the card. Corresponds to a [PCSC5] SCARD_RESET_CARD DWORD.
unpower
Unpower and terminate access to the card. Corresponds to a [PCSC5] SCARD_UNPOWER_CARD DWORD.
eject
Eject the card from the reader. Corresponds to a [PCSC5] SCARD_EJECT_CARD DWORD.

The transmit(sendBuffer, options) method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. Let protocol be a [PCSC5] DWORD set to this.[[activeProtocol]].
  5. If options["protocol"] exists, set protocol to the DWORD corresponding to options["protocol"].
  6. If protocol is not a valid protocol value, reject promise with a "InvalidStateError" DOMException and return promise.
  7. Set this.[[context]].[[operationInProgress]] to true.
  8. Let sendPci be the platform's [PCSC5] SCARD_IO_HEADER corresponding to this.[[activeProtocol]].
  9. Let pcscSendBuffer be a [PCSC5] BYTE[] containing sendBuffer.
  10. Let recvPci be the platform's SCARD_IO_HEADER equivalent of empty or null.
  11. Let recvBuffer be a BYTE[] big enough to hold the largest [ISO7186-3] extended response APDU (65538 bytes).
  12. Let recvLength be a DWORD set to 0.
  13. Run the following steps in parallel:
    1. Call this.[[comm]].Transmit() with sendPci, pcscSendBuffer, recvPci, recvBuffer and recvLength as arguments.
    2. Let responseCode be the returned RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.[[context]].
      2. If responseCode is not SCARD_S_SUCCESS, reject promise with an exception corresponding to responseCode and abort these steps.
      3. Resolve promise with an ArrayBuffer containing the first recvLength bytes of recvBuffer.
  14. Return promise.
dictionary SmartCardTransmitOptions {
  SmartCardProtocol protocol;
};
protocol member
The protocol to be used in the transmission.

The startTransaction(transaction, options) method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. If this.[[transactionState]] is not null, reject promise with a "InvalidStateError" DOMException and return promise.
  5. Let signal be an AbortSignal set to null.
  6. If options["signal"] exists, run the following steps:
    1. If options["signal"] is aborted, reject promise with options["signal"]'s abort reason and return promise.
    2. Set signal to options["signal"].
    3. Add the cancel algorithm to signal.
  7. Set this.[[context]].[[operationInProgress]] to true.
  8. Run the following steps in parallel:
    1. Call this.[[comm]].BeginTransaction().
    2. Let responseCode be the returned [PCSC5] RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source to process the result of a BeginTransaction with this, responseCode, signal, transaction and promise.
  9. Return promise.
dictionary SmartCardTransactionOptions {
  AbortSignal signal;
};
signal member
When triggered, the platform's [PCSC5] Cancel() method is called.

A 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:

  1. Clear the operationInProgress of connection.[[context]].
  2. Let abortReason be undefined.
  3. If signal is not null:
    1. Remove the cancel algorithm from signal.
    2. If signal is aborted then set abortReason to signal's abort reason.
  4. If responseCode is not SCARD_S_SUCCESS:
    1. If responseCode is SCARD_E_CANCELLED and abortReason is not undefined then reject promise with abortReason.
    2. Otherwise, reject promise with an exception corresponding to responseCode.
    3. Return.
  5. Let transactionState be a new transaction state with its promise item set to promise.
  6. Set connection.[[transactionState]] to transactionState.
  7. Let callbackPromise be the result of invoking transaction.
  8. React to callbackPromise:

To end the transaction of a SmartCardConnection connection with a SmartCardDisposition disposition, perform the following steps:

  1. Assert: connection.[[context]].[[operationInProgress]] is false.
  2. Assert: connection.[[transactionState]] is not null.
  3. Assert: connection.[[transactionState]]'s pendingDisposition is null.
  4. Let transactionPromise be connection.[[transactionState]]'s promise.
  5. If connection.[[comm]] is null:
    1. Reject transactionPromise with a "InvalidStateError" DOMException.
    2. Set connection.[[transactionState]] to null.
    3. Return.
  6. Set connection.[[context]].[[operationInProgress]] to true.
  7. Run the following steps in parallel:
    1. Call this.[[comm]].EndTransaction() with a DWORD corresponding to disposition as input parameter.
    2. Let responseCode be the returned [PCSC5] RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of connection.[[context]].
      2. Let exception be connection.[[transactionState]]'s pendingException.
      3. If exception is null, perform the following steps:
        1. If responseCode is SCARD_S_SUCCESS, resolve transactionPromise.
        2. Otherwise, reject transactionPromise with an exception corresponding to responseCode.
      4. Otherwise, reject transactionPromise with exception.
      5. Set connection.[[transactionState]] to null.

To end any settled transaction of a SmartCardConnection connection, perform the following steps:

  1. If connection.[[transactionState]] is null, abort these steps.
  2. Let disposition be connection.[[transactionState]]'s pendingDisposition.
  3. If disposition is null, abort these steps.
  4. Set connection.[[transactionState]]'s pendingDisposition to null.
  5. End the transaction of connection with disposition.

To cancel outstanding [PCSC5] SCARDCOMM operations, call this.[[comm]].Cancel().

The status() method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. Set this.[[context]].[[operationInProgress]] to true.
  5. Run the following steps in parallel:
    1. Let pcscReader be an empty STR[].
    2. Let pcscState be a [PCSC5] DWORD set to 0.
    3. Let activeProtocol be a [PCSC5] DWORD set to 0.
    4. Let pcscAtr be a BYTE[] big enough to hold any [ISO7186-3] Answer To Reset (ATR).
    5. Call this.[[comm]].Status() with pcscReader, pcscState, activeProtocol and pcscAtr as output parameters.
    6. Let responseCode be the returned RESPONSECODE.
    7. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.[[context]].
      2. If responseCode is not SCARD_S_SUCCESS, reject promise with an exception corresponding to responseCode and abort these steps.
      3. Let state be a SmartCardConnectionState corresponding to pcscState and activeProtocol.
      4. If state is undefined, reject promise with an "UnknownError" DOMException and abort these steps.
      5. Let status be a new SmartCardConnectionStatus.
      6. Set status["readerName"] to pcscReader.
      7. Set status["state"] to state.
      8. Set status["answerToReset"] to an ArrayBuffer with the bytes that were written to pcscAtr.
      9. Resolve promise with status.
  6. Return promise.
dictionary SmartCardConnectionStatus {
  required DOMString readerName;
  required SmartCardConnectionState state;
  ArrayBuffer answerToReset;
};
readerName member
Name of the connected reader.
state member
Current state of the connection.
answerToReset member
The answer to reset (ATR) string from the card, if applicable.
enum SmartCardConnectionState {
  "absent",
  "present",
  "swallowed",
  "powered",
  "negotiable",
  "t0",
  "t1",
  "raw"
};
absent
There is no card in the reader.
present
There is a card in the reader, but it has not been moved into position for use.
swallowed
There is a card in the reader in position for use. The card is not powered.
powered
Power is being provided to the card, but the reader driver is unaware of the mode of the card.
negotiable
The card has been reset and is awaiting PTS (protocol type selection) negotiation.
t0
The card is in [ISO7186-3] T=0 protocol mode and a new protocol may not be negotiated.
t1
The card is in [ISO7186-3] T=1 protocol mode and a new protocol may not be negotiated.
raw
The card is in raw protocol mode and a new protocol may not be negotiated.

Given a [PCSC5] DWORD pcscState and a DWORD activeProtocol, a corresponding SmartCardConnectionState is created with the following steps:

  1. If pcscState is [PCSC5] SCARD_ABSENT, return "absent".
  2. If pcscState is [PCSC5] SCARD_PRESENT, return "present".
  3. If pcscState is [PCSC5] SCARD_SWALLOWED, return "swallowed".
  4. If pcscState is [PCSC5] SCARD_POWERED, return "powered".
  5. If pcscState is [PCSC5] SCARD_NEGOTIABLE, return "negotiable".
  6. If pcscState is [PCSC5] SCARD_SPECIFIC, perform the following steps:
    1. If activeProtocol is [PCSC5] SCARD_PROTOCOL_T0, return "t0".
    2. If activeProtocol is [PCSC5] SCARD_PROTOCOL_T1, return "t1".
    3. If activeProtocol is [PCSC5] SCARD_PROTOCOL_RAW, return "raw".
  7. Return undefined.

The control(controlCode, data) method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. Set this.[[context]].[[operationInProgress]] to true.
  5. Let pcscControlCode be a [PCSC5] DWORD containing controlCode.
  6. Get a copy of the buffer source data and save the result in a [PCSC5] BYTE[] inBuffer.
  7. Let outBuffer be a [PCSC5] BYTE[] large enough to hold any control command response.
  8. Let outBufferLength be a DWORD set to 0.
  9. Run the following steps in parallel:
    1. Call this.[[comm]].Control() with pcscControlCode, inBuffer, outBuffer and outBufferLength as arguments.
    2. Let responseCode be the returned RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.[[context]].
      2. If responseCode is not SCARD_S_SUCCESS, reject promise with an exception corresponding to responseCode and abort these steps.
      3. Let resultBytes be the first outBufferLength bytes of outBuffer.
      4. Resolve promise with the result of creating an ArrayBuffer from resultBytes in this's relevant Realm.
  10. Return promise.

The getAttribute(tag) method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. Set this.[[context]].[[operationInProgress]] to true.
  5. Run the following steps in parallel:
    1. Let pcscTag be a [PCSC5] DWORD containing tag.
    2. Let buffer be a [PCSC5] BYTE[] large enough to hold this reader attribute, as determined by the platform's [PCSC5] implementation.
    3. Call this.[[comm]].GetReaderCapabilities() with pcscTag and buffer as arguments.
    4. Let responseCode be the returned RESPONSECODE.
    5. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.[[context]].
      2. If responseCode is not SCARD_S_SUCCESS, reject promise with an exception corresponding to responseCode and abort these steps.
      3. Let resultBytes be the bytes of buffer containing the attribute read.
      4. Resolve promise with the result of creating an ArrayBuffer from resultBytes in this's relevant Realm.
  6. Return promise.

Note: Output buffer size

Known [PCSC5] platform implementations allow either the output buffer to be automatically allocated or to query the size needed for it. This covers the gap left by [PCSC5] in that regard.

The setAttribute(tag, value) method steps are:

  1. Let promise be a new promise.
  2. If this.[[context]].[[operationInProgress]] is true, reject promise with a "InvalidStateError" DOMException and return promise.
  3. If this.[[comm]] is null, reject promise with a "InvalidStateError" DOMException and return promise.
  4. Set this.[[context]].[[operationInProgress]] to true.
  5. Let pcscTag be a [PCSC5] DWORD containing tag.
  6. Get a copy of the buffer source value and save the result in a [PCSC5] BYTE[] buffer.
  7. Run the following steps in parallel:
    1. Call this.[[comm]].SetReaderCapabilities() with pcscTag and buffer as arguments.
    2. Let responseCode be the returned RESPONSECODE.
    3. Queue a global task on the relevant global object of this using the smart card task source which performs the following steps:
      1. Clear the operationInProgress of this.[[context]].
      2. If responseCode is not SCARD_S_SUCCESS, reject promise with an exception corresponding to responseCode and abort these steps.
      3. Resolve promise.
  8. Return promise.
[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:

Note: Unspecified response codes

The following RESPONSECODEs are not part of [PCSC5] but are still considered in this specification as existing PC/SC implementations use them:

  1. Let pcscCode be that RESPONSECODE.
  2. If pcscCode is SCARD_E_NO_SERVICE, return a new "no-service" SmartCardError.
  3. If pcscCode is SCARD_E_NO_SMARTCARD, return a new "no-smartcard" SmartCardError.
  4. If pcscCode is SCARD_E_NOT_READY, return a new "not-ready" SmartCardError.
  5. If pcscCode is SCARD_E_NOT_TRANSACTED, return a new "not-transacted" SmartCardError.
  6. If pcscCode is SCARD_E_PROTO_MISMATCH, return a new "proto-mismatch" SmartCardError.
  7. If pcscCode is SCARD_E_READER_UNAVAILABLE, return a new "reader-unavailable" SmartCardError.
  8. If pcscCode is SCARD_W_REMOVED_CARD, return a new "removed-card" SmartCardError.
  9. If pcscCode is SCARD_W_RESET_CARD, return a new "reset-card" SmartCardError.
  10. If pcscCode is SCARD_E_SERVER_TOO_BUSY, return a new "server-too-busy" SmartCardError.
  11. If pcscCode is SCARD_E_SHARING_VIOLATION, return a new "sharing-violation" SmartCardError.
  12. If pcscCode is SCARD_E_SYSTEM_CANCELLED, return a new "system-cancelled" SmartCardError.
  13. If pcscCode is SCARD_E_UNKNOWN_READER, return a new "unknown-reader" SmartCardError.
  14. If pcscCode is SCARD_W_UNPOWERED_CARD, return a new "unpowered-card" SmartCardError.
  15. If pcscCode is SCARD_W_UNRESPONSIVE_CARD, return a new "unresponsive-card" SmartCardError.
  16. If pcscCode is SCARD_W_UNSUPPORTED_CARD, return a new "unsupported-card" SmartCardError.
  17. If pcscCode is SCARD_E_UNSUPPORTED_FEATURE, return a new "unsupported-feature" SmartCardError.
  18. If pcscCode is SCARD_E_INVALID_PARAMETER, return a new TypeError.
  19. If pcscCode is SCARD_E_INVALID_HANDLE, return a new "InvalidStateError" DOMException.
  20. If pcscCode is SCARD_E_SERVICE_STOPPED, return a new "InvalidStateError" DOMException.
  21. If pcscCode is SCARD_P_SHUTDOWN, return a new "AbortError" DOMException.
  22. Otherwise return a new "UnknownError" DOMException.
dictionary SmartCardErrorOptions {
  required SmartCardResponseCode responseCode;
};

The responseCode member is the value for SmartCardError's responseCode attribute.

enum 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
SCARD_E_NO_SERVICE in the [PCSC5] spec.
no-smartcard
SCARD_E_NO_SMARTCARD in the [PCSC5] spec.
not-ready
SCARD_E_NOT_READY in the [PCSC5] spec.
not-transacted
SCARD_E_NOT_TRANSACTED in the [PCSC5] spec.
proto-mismatch
SCARD_E_PROTO_MISMATCH in the [PCSC5] spec.
reader-unavailable
SCARD_E_READER_UNAVAILABLE in the [PCSC5] spec.
removed-card
SCARD_W_REMOVED_CARD in the [PCSC5] spec.
reset-card
SCARD_W_RESET_CARD in the [PCSC5] spec.
server-too-busy
The smart card resource manager is too busy to complete this operation.
sharing-violation
SCARD_E_SHARING_VIOLATION in the [PCSC5] spec.
system-cancelled
SCARD_E_SYSTEM_CANCELLED in the [PCSC5] spec.
unknown-reader
SCARD_E_UNKNOWN_READER in the [PCSC5] spec.
unpowered-card
SCARD_W_UNPOWERED_CARD in the [PCSC5] spec.
unresponsive-card
SCARD_W_UNRESPONSIVE_CARD in the [PCSC5] spec.
unsupported-card
SCARD_W_UNSUPPORTED_CARD in the [PCSC5] spec.
unsupported-feature
SCARD_E_UNSUPPORTED_FEATURE in the [PCSC5] spec.

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 'self'.

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.

[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[hr-time-3]
High Resolution Time. Yoav Weiss. W3C. 7 November 2024. W3C Working Draft. URL: https://www.w3.org/TR/hr-time-3/
[html]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[ISO7186-3]
Identification cards - Integrated circuit cards; Part 3: Cards with contacts - Electrical interface and transmission protocols. ISO/IEC. 1 November 2006. Published. URL: https://www.iso.org/standard/38770.html
[PCSC5]
Interoperability Specification for ICCs and Personal Computer Systems; Part 5. ICC Resource Manager Definition. PC/SC Workgroup. 30 September 2005. Published. URL: https://pcscworkgroup.com/Download/Specifications/pcsc5_v2.01.01.pdf
[permissions-policy]
Permissions Policy. Ian Clelland. W3C. 10 February 2025. W3C Working Draft. URL: https://www.w3.org/TR/permissions-policy-1/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

Referenced in:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.3