1. Navigator
接口的扩展
[Exposed =Window ,SecureContext ,IsolatedContext ]partial interface Navigator { [SameObject ]readonly attribute SmartCardResourceManager ; };smartCard
1.1. smartCard
属性
获取时,smartCard
属性始终返回同一个
SmartCardResourceManager
对象实例。
2. WorkerNavigator
接口的扩展
[Exposed =(DedicatedWorker ,SharedWorker ),SecureContext ,IsolatedContext ]partial interface WorkerNavigator { [SameObject ]readonly attribute SmartCardResourceManager ; };smartCard
2.1.
smartCard
属性
获取时,smartCard
属性始终返回同一个
SmartCardResourceManager
对象实例。
3.
SmartCardResourceManager
接口
[Exposed =(DedicatedWorker ,SharedWorker ,Window ),SecureContext ,IsolatedContext ]interface {SmartCardResourceManager Promise <SmartCardContext >(); };establishContext
此接口上的方法以异步方式完成,并将 工作排入智能卡 任务源。
3.1. establishContext()
方法
从平台的 PC/SC 栈请求一个 PC/SC 上下文。
establishContext()
方法的步骤如下:
-
如果 this 的 相关全局对象的关联 Document 不获准使用名为 “smart-card”的策略控制功能,则抛出一个 “
SecurityError”DOMException。 -
令 promise 为一个新的 promise。
-
并行运行以下步骤:
-
令 resourceManager 为平台 [PCSC5]
RESOURCEMANAGER类的一个新实例。 -
以一个值为“system”的
Scope参数调用 resourceManager 的EstablishContext方法。 -
如果返回的
RESPONSECODE不是SCARD_S_SUCCESS,则执行 以下步骤: -
否则,执行以下步骤:
-
令 context 为一个新的
SmartCardContext, 其 [[resourceManager]] 内部 槽被设置为 resourceManager。
-
-
-
返回 promise。
4. SmartCardContext
接口
用于与 PC/SC 资源管理器通信的上下文。
[Exposed =(DedicatedWorker ,SharedWorker ,Window ),SecureContext ,IsolatedContext ]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
SmartCardContext
实例使用下表所述的内部槽
创建:
| 内部槽 | 初始值 | 说明(非规范性) |
|---|---|---|
| [[resourceManager]] | null
| 要使用的平台
[PCSC5]
RESOURCEMANAGER。
|
| [[operationInProgress]] | false
| 此上下文中是否存在正在进行的 PC/SC 操作。 |
| [[activeReaderTransactions]] | 一个空映射 | 一个从读卡器名称映射到 SmartCardConnection
的映射;后者在此
上下文中当前持有该读卡器上的活动事务(若有)。
|
| [[connections]] | 一个空有序集合 | 由此上下文创建的现有 SmartCardConnection
实例。
|
| [[tracker]] | null
| 一个
[PCSC5]
SCARDTRACK 实例。
|
| [[signal]] | null
| 未完成的
getStatusChange()
调用的 AbortSignal(若有)。
|
4.1.
listReaders()
方法
listReaders()
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
令 resourceQuery 为平台 [PCSC5]
RESOURCEQUERY类的一个新实例,并将 this.[[resourceManager]] 作为其 构造函数输入参数。 -
令 groups 为平台的 [PCSC5]
STR[],其中包含 与该平台中“系统内所有读卡器”等效的组名列表。 -
令 pcscReaders 为一个空的
STR[]。 -
调用 resourceQuery 的
ListReaders方法, 以 groups 作为输入参数,以 pcscReaders 作为输出参数。 -
令 responseCode 为返回的
RESPONSECODE。 -
销毁 resourceQuery。
-
-
返回 promise。
4.2.
getStatusChange()
方法
getStatusChange(readerStates, options)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果
options["signal"] 存在,则运行以下步骤:-
将 this.[[signal]] 设置为 signal。
-
将取消未完成的 GetStatusChange 算法添加到 signal。
-
如果
options["timeout"] 存在,则将 pcscTimeout 设置为options["timeout"]。 -
令 pcscReaderStates 为一个与
readerStates对应的 [PCSC5]SCARD_READERSTATE[]。 -
将 this.[[operationInProgress]] 设置为
true。 -
将 this.[[tracker]] 设置为平台 [PCSC5]
SCARDTRACK类的一个新实例,并将 this.[[resourceManager]] 作为其 构造函数输入参数。 -
并行运行以下步骤:
-
使用 pcscReaderStates 和 pcscTimeout 作为输入参数,调用 this.[[tracker]].
GetStatusChange()。 -
令 responseCode 为返回的 [PCSC5]
RESPONSECODE。 -
使用智能卡 任务源,在 this 的相关全局对象上排入一个全局任务,该任务执行 以下步骤:
-
将 this.[[tracker]] 设置为
null。 -
清除 operationInProgress(目标为 this)。
-
令 abortReason 为
undefined。 -
如果 this.[[signal]] 不为
null, 则运行以下步骤:-
如果 this.[[signal]] 已 中止,则将 abortReason 设置为 this.[[signal]] 的 中止原因。
-
将 this.[[signal]] 设置为
null。
-
-
如果 responseCode 不是
SCARD_S_SUCCESS,则运行 以下步骤: -
令 readerStatesOut 为一个与 pcscReaderStates 对应的
SmartCardReaderStateOut序列。 -
使用 readerStatesOut 兑现 promise。
-
-
-
返回 promise。
4.2.1.
SmartCardReaderStateIn
字典
dictionary {SmartCardReaderStateIn required DOMString ;readerName required SmartCardReaderStateFlagsIn ;currentState unsigned long ; };currentCount
readerName-
智能卡读卡器的名称。
currentState-
应用程序所知的该智能卡读卡器当前状态。
currentCount-
应用程序所知的此读卡器中卡片插入和移除事件的当前次数。
给定一个名为 readerStates 的 SmartCardReaderStateIn
序列,按以下步骤创建一个对应的 [PCSC5]
SCARD_READERSTATE[]:
-
令 pcscReaderStates 为一个空的
SCARD_READERSTATE[]。 -
对于 readerStates 中的每个类型为
SmartCardReaderStateIn的 stateIn,逐一执行:-
令 pcscState 为一个
SCARD_READERSTATE。 -
将 pcscState.
Reader设置为 stateIn["readerName"]。 -
将 pcscState.
CurrentState设置为与 stateIn["currentState"] 对应的DWORD。 -
如果 stateIn["
currentCount"] 存在,则将 pcscState.CurrentState的高位字设置为 stateIn["currentCount"]。 -
将 pcscState.
EventState设置为零。 -
将 pcscState 追加到 pcscReaderStates。
-
-
返回 pcscReaderStates。
4.2.1.1. SmartCardReaderStateFlagsIn
字典
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-
应用程序不知道当前状态,并希望获知该状态。
ignore-
应用程序对此读卡器不感兴趣,在监视 操作期间不应考虑它。
unavailable-
应用程序认为此读卡器不可供使用。
empty-
应用程序认为读卡器中没有卡片。
present-
应用程序认为读卡器中有卡片。
exclusive-
应用程序认为读卡器中的卡片已分配给另一个 应用程序独占使用。
inuse-
应用程序认为读卡器中的卡片正被一个或多个其他应用程序使用,但 仍可通过共享模式连接。
mute-
应用程序认为读卡器中有一张无响应的卡片。
unpowered-
应用程序认为读卡器中的卡片尚未通电。
与给定 SmartCardReaderStateFlagsIn
对应的 [PCSC5]
DWORD 对应的
按以下步骤创建:
-
令 flagsIn 为给定的
SmartCardReaderStateFlagsIn。 -
令 pcscFlags 为一个设置为零的
DWORD。 -
如果 flagsIn["
unaware"] 为true,则将 [PCSC5]SCARD_STATE_UNAWARE添加到 pcscFlags。 -
如果 flagsIn["
ignore"] 为true,则将 [PCSC5]SCARD_STATE_IGNORE添加到 pcscFlags。 -
如果 flagsIn["
unavailable"] 为true,则将 [PCSC5]SCARD_STATE_UNAVAILABLE添加到 pcscFlags。 -
如果 flagsIn["
empty"] 为true,则将 [PCSC5]SCARD_STATE_EMPTY添加到 pcscFlags。 -
如果 flagsIn["
present"] 为true,则将 [PCSC5]SCARD_STATE_PRESENT添加到 pcscFlags。 -
如果 flagsIn["
exclusive"] 为true,则将 [PCSC5]SCARD_STATE_EXCLUSIVE添加到 pcscFlags。 -
如果 flagsIn["
inuse"] 为true,则将 [PCSC5]SCARD_STATE_INUSE添加到 pcscFlags。 -
如果 flagsIn["
mute"] 为true,则将SCARD_STATE_MUTE添加到 pcscFlags。 -
如果 flagsIn["
unpowered"] 为true,则将SCARD_STATE_UNPOWERED添加到 pcscFlags。 -
返回 pcscFlags。
4.2.2.
SmartCardReaderStateOut
字典
智能卡读卡器的实际状态。
dictionary {SmartCardReaderStateOut required DOMString ;readerName required SmartCardReaderStateFlagsOut ;eventState required unsigned long ;eventCount ArrayBuffer ; };answerToReset
readerName-
智能卡读卡器的名称。
eventState-
该智能卡读卡器的实际状态。
eventCount-
此读卡器中实际发生的卡片插入和移除事件次数。
answerToReset-
已插入卡片的 [ISO7816-3] 复位应答(ATR)(若适用)。
给定一个名为 pcscReaderStates 的 [PCSC5]
SCARD_READERSTATE[],按以下步骤创建一个对应的 SmartCardReaderStateOut
序列:
-
令 readerStatesOut 为一个空的
SmartCardReaderStateOut序列。 -
对于 pcscReaderStates 中的每个类型为
SCARD_READERSTATE的 pcscState,逐一执行:-
令 stateOut 为一个
SmartCardReaderStateOut。 -
将 stateOut["
readerName"] 设置为 pcscState.Reader。 -
将 stateOut["
eventState"] 设置为与 pcscState.EventState对应的SmartCardReaderStateFlagsOut字典。 -
将 stateOut["
eventCount"] 设置为 pcscState.EventState的高位字。 -
如果平台的
SCARD_READERSTATE结构有一个包含卡片 [ISO7816-3] 复位应答的成员,则将 stateOut["answerToReset"] 设置为该值。 -
将 stateOut 追加到 readerStatesOut。
-
-
返回 readerStatesOut。
4.2.2.1. SmartCardReaderStateFlagsOut
字典
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-
应用程序请求忽略此读卡器。
changed-
调用应用程序输入的状态与实际状态之间存在差异。
unavailable-
此读卡器不可供使用。
unknown-
应用程序给出的读卡器名称未知。
empty-
读卡器中没有卡片。
present-
读卡器中有卡片。
exclusive-
读卡器中的卡片已分配给另一个应用程序独占使用。
inuse-
读卡器中的卡片正被一个或多个其他应用程序使用,但仍可通过共享 模式连接。
mute-
读卡器中有一张无响应的卡片。
unpowered-
读卡器中的卡片尚未通电。
给定一个名为 pcscFlags 的 [PCSC5]
DWORD,按以下步骤创建一个对应的 SmartCardReaderStateFlagsOut
字典:
-
令 flagsOut 为一个具有默认成员的
SmartCardReaderStateFlagsOut字典。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_IGNORE,则将 flagsOut["ignore"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_CHANGED,则将 flagsOut["changed"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_UNAVAILABLE,则将 flagsOut["unavailable"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_UNKNOWN,则将 flagsOut["unknown"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_EMPTY,则将 flagsOut["empty"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_PRESENT,则将 flagsOut["present"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_EXCLUSIVE,则将 flagsOut["exclusive"] 设置为true。 -
如果 pcscFlags 具有 [PCSC5]
SCARD_STATE_INUSE,则将 flagsOut["inuse"] 设置为true。 -
如果 pcscFlags 具有
SCARD_STATE_MUTE,则将 flagsOut["mute"] 设置为true。 -
如果 pcscFlags 具有
SCARD_STATE_UNPOWERED,则将 flagsOut["unpowered"] 设置为true。 -
返回 flagsOut。
4.2.3. SmartCardGetStatusChangeOptions
字典
dictionary {SmartCardGetStatusChangeOptions DOMHighResTimeStamp ;timeout AbortSignal ; };signal
timeout-
GetStatusChange() [PCSC5] 方法的超时参数。如果未指定,则使用值为 INFINITE 的超时 (其定义取决于系统)。
signal-
触发时,调用平台的 [PCSC5] Cancel() 方法。
4.3. connect()
方法
connect(readerName, accessMode, options)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[activeReaderTransactions]][
readerName] 存在,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
令 accessFlags 为一个与
accessMode对应的 [PCSC5]DWORD。 -
令 protocolFlags 为一个设置为
0的DWORD。 -
如果
options["preferredProtocols"] 存在,则将 protocolFlags 设置为其对应标志。 -
令 activeProtocol 为一个设置为
0的DWORD。 -
令 comm 为平台 [PCSC5]
SCARDCOMM类的一个新实例,并将 this.[[resourceManager]] 作为其 构造函数参数。 -
调用 comm.
Connect(),以readerName、 accessFlags 和 protocolFlags 作为输入参数,以 activeProtocol 作为输出参数。 -
令 responseCode 为返回的
RESPONSECODE。 -
使用智能卡 任务源,在 this 的相关全局对象上排入一个全局任务,该任务执行以下步骤:
-
清除 operationInProgress(目标为 this)。
-
如果 responseCode 不是
SCARD_S_SUCCESS: -
令 result 为一个空的
SmartCardConnectResult字典。 -
令 connection 为一个新的
SmartCardConnection。 -
将 connection 追加到 this.[[connections]]。
-
将 connection.[[comm]] 设置为 comm。
-
将 connection.[[readerName]] 设置为
readerName。 -
将 connection.[[context]] 设置为 this。
-
将 connection.[[activeProtocol]] 设置为 activeProtocol。
-
将 result["
connection"] 设置为 connection。 -
如果 activeProtocol 是一个有效协议值, 则将 result["
activeProtocol"] 设置为对应的SmartCardProtocol。 -
使用 result 兑现 promise。
-
-
-
返回 promise。
4.3.1.
SmartCardProtocol
枚举
enum {SmartCardProtocol ,"raw" ,"t0" };"t1"
"raw"-
“原始”模式。可用于支持特殊用途需求所需的任意数据交换协议。 对应于 [PCSC5]
SCARD_PROTOCOL_RAWDWORD。 "t0"-
[ISO7816-3] T=0。异步半双工字符传输协议。对应于 [PCSC5]
SCARD_PROTOCOL_T0DWORD。 "t1"-
[ISO7816-3] T=1。异步半双工块传输协议。对应于 [PCSC5]
SCARD_PROTOCOL_T1DWORD。
如果一个
[PCSC5]
DWORD 是
[PCSC5]
SCARD_PROTOCOL_T0、
[PCSC5]
SCARD_PROTOCOL_T1 或
[PCSC5]
SCARD_PROTOCOL_RAW 之一,则它是一个
有效协议值。
给定一个名为 protocols 的 SmartCardProtocol
序列,按以下步骤创建一个带有对应标志的
[PCSC5]
DWORD:
-
令 flags 为一个设置为
0的DWORD。 -
对于 protocols 中的每个类型为
SmartCardProtocol的 protocol,将 protocol 对应的DWORD添加到 flags。 -
返回 flags。
4.3.2.
SmartCardConnectResult
字典
dictionary {SmartCardConnectResult required SmartCardConnection ;connection SmartCardProtocol ; };activeProtocol
connection-
用于访问所创建连接的接口。
activeProtocol-
实际使用的协议。
4.3.3.
SmartCardAccessMode
枚举
enum {SmartCardAccessMode ,"shared" ,"exclusive" };"direct"
"shared"-
应用程序愿意与其他应用程序共享对卡片的访问。
"exclusive"-
应用程序需要独占访问卡片。
"direct"-
无论是否存在卡片,应用程序都需要连接到读卡器。此模式意味着独占访问。
给定一个名为 accessMode 的 SmartCardAccessMode
枚举,按以下步骤创建一个对应的 [PCSC5]
DWORD:
-
令 dword 为一个设置为
0的DWORD。 -
如果 accessMode 是“
shared”, 则将 dword 设置为 [PCSC5]SCARD_SHARE_SHARED。 -
如果 accessMode 是“
exclusive”, 则将 dword 设置为 [PCSC5]SCARD_SHARE_EXCLUSIVE。 -
如果 accessMode 是“
direct”, 则将 dword 设置为 [PCSC5]SCARD_SHARE_DIRECT。 -
返回 dword。
4.3.4.
SmartCardConnectOptions
字典
dictionary {SmartCardConnectOptions sequence <SmartCardProtocol >; };preferredProtocols
preferredProtocols-
可使用的卡片通信协议。
4.4. 辅助算法和定义
要清除
operationInProgress(目标为 SmartCardContext
context),执行以下步骤:
-
断言: context.[[operationInProgress]] 为
true。 -
将 context.[[operationInProgress]] 设置为
false。 -
对于 context.[[connections]] 中的每个类型为
SmartCardConnection的 connection,逐一执行:-
如果 context.[[operationInProgress]] 为
true,则中止这些步骤。
取消未完成的 GetStatusChange 算法的步骤 如下:
-
调用 this.[[tracker]].
Cancel()。
一个
[PCSC5]
DWORD 的高位字,
是对该 DWORD 执行无符号右移 16 位所得的结果。
要将名为 dword 的
[PCSC5]
DWORD 的高位字设置为
给定数字 n,执行以下步骤:
-
将 dword 设置为 dword 按位与
0xFFFF。 -
令 shiftedN 为对 n 执行左移 16 位所得的结果。
-
将 dword 设置为 dword 按位或 shiftedN。
要向
[PCSC5]
DWORD flags 添加标志
f,将 flags 设置为 flags 按位或 f。
如果 flags 按位与 f 的结果为
f,则
[PCSC5]
DWORD flags 具有标志 f。
5.
SmartCardConnection
接口
[Exposed =(DedicatedWorker ,SharedWorker ,Window ),SecureContext ,IsolatedContext ]interface {SmartCardConnection Promise <undefined >(disconnect optional SmartCardDisposition = "leave");disposition 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 ?> ();
SmartCardConnection
实例使用下表所述的内部槽
创建:
| 内部槽 | 初始值 | 说明(非规范性) |
|---|---|---|
| [[comm]] | null
| 要使用的平台 [PCSC5]
SCARDCOMM。
|
| [[readerName]] | null
| 与此连接关联的读卡器名称。 |
| [[context]] | null
| 创建此实例的 SmartCardContext。
|
| [[activeProtocol]] | 0 | 平台
[PCSC5]
实现返回的活动协议 DWORD。
|
| [[transactionState]] | null
| 保存通过 startTransaction()
启动的正在进行的事务的状态(若有)。
|
5.1.
disconnect()
方法
disconnect(disposition)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在且不等于 this,则使用一个“
InvalidStateError”DOMException拒绝 promise 并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
调用 this.[[comm]].
Disconnect(), 并将与disposition对应的DWORD作为输入参数。 -
令 responseCode 为返回的
RESPONSECODE。
-
-
返回 promise。
5.1.1.
SmartCardDisposition
枚举
enum {SmartCardDisposition ,"leave" ,"reset" ,"unpower" };"eject"
"leave"-
不改变卡片状态。对应于 [PCSC5]
SCARD_LEAVE_CARDDWORD。 "reset"-
重置卡片。对应于 [PCSC5]
SCARD_RESET_CARDDWORD。 "unpower"-
断开卡片电源并终止对卡片的访问。对应于 [PCSC5]
SCARD_UNPOWER_CARDDWORD。 "eject"-
从读卡器中弹出卡片。对应于 [PCSC5]
SCARD_EJECT_CARDDWORD。
5.2.
transmit()
方法
transmit(sendBuffer, options)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在且不等于 this,则使用一个“
InvalidStateError”DOMException拒绝 promise 并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
令 protocol 为一个 [PCSC5]
DWORD,其值设置为 this.[[activeProtocol]]。 -
如果
options["protocol"] 存在,则将 protocol 设置为与options["protocol"] 对应的DWORD。 -
如果 protocol 不是一个有效协议值,则使用一个“
InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
令 sendPci 为平台中与 this.[[activeProtocol]] 对应的 [PCSC5]
SCARD_IO_HEADER。 -
令 pcscSendBuffer 为一个包含
sendBuffer的 [PCSC5]BYTE[]。 -
令 recvPci 为平台中等效于空值或 null 的
SCARD_IO_HEADER。 -
令 recvBuffer 为一个足以容纳最大 [ISO7816-3] 扩展响应 APDU(65538 字节)的
BYTE[]。 -
令 recvLength 为一个设置为
0的DWORD。 -
并行运行以下步骤:
-
调用 this.[[comm]].
Transmit(), 并将 sendPci、pcscSendBuffer、recvPci、recvBuffer 和 recvLength 作为实参。 -
令 responseCode 为返回的
RESPONSECODE。 -
使用智能卡任务 源,在 this 的相关全局对象上排入一个全局任务,该任务执行以下步骤:
-
如果 responseCode 不是
SCARD_S_SUCCESS,则使用一个与 responseCode 对应的异常拒绝 promise,并中止这些步骤。 -
使用一个包含 recvBuffer 前 recvLength 个字节的
ArrayBuffer兑现 promise。
-
-
返回 promise。
5.2.1.
SmartCardTransmitOptions
字典
dictionary {SmartCardTransmitOptions SmartCardProtocol ; };protocol
protocol-
传输中要使用的协议。
5.3.
startTransaction()
方法
startTransaction(transaction, options)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在,则使用一个“
InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[transactionState]] 不为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
令 signal 为一个设置为
null的AbortSignal。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
令 responseCode 为返回的 [PCSC5]
RESPONSECODE。 -
使用智能卡任务 源,在 this 的相关全局对象上排入一个全局任务,以使用 this、 responseCode、signal、
transaction和 promise 处理 BeginTransaction 的结果。
-
返回 promise。
5.3.1.
SmartCardTransactionOptions
字典
dictionary {SmartCardTransactionOptions AbortSignal ; };signal
signal-
触发时,调用平台的 [PCSC5] Cancel() 方法。
5.3.2. 辅助算法和定义
- pendingDisposition
-
如果已设置,则表示正在进行的 PC/SC 操作完成后,应调用 [PCSC5]
EndTransaction(),并将此值作为SmartCardDisposition参数。 - pendingException
-
拒绝promise 时要使用的异常。
- promise
-
startTransaction()调用返回的未完成Promise。
要在给定 SmartCardConnection
connection、[PCSC5]
RESPONSECODE responseCode、AbortSignal
signal、SmartCardTransactionCallback
transaction 和 Promise
promise 的情况下,处理 BeginTransaction 的结果,执行以下步骤:
-
清除 operationInProgress(目标为 connection.[[context]])。
-
令 abortReason 为
undefined。 -
如果 signal 不为
null: -
如果 responseCode 不是
SCARD_S_SUCCESS: -
将 connection.[[transactionState]] 设置为 transactionState。
-
将 connection.[[context]].[[activeReaderTransactions]][connection.[[readerName]]] 设置为 connection。
-
令 callbackPromise 为调用 transaction 的结果。
-
对 callbackPromise 作出反应:
-
如果 callbackPromise 以值 v 兑现,则:
-
令 disposition 为“
reset”。 -
如果 v 不是
undefined, 则将 disposition 设置为 v。 -
如果 connection.[[context]].[[operationInProgress]] 为
true:-
将 transactionState 的pendingException 设置为一个“
InvalidStateError”DOMException。 -
将 transactionState 的pendingDisposition 设置为 disposition。
-
-
否则,以 disposition 结束 connection 的事务。
-
-
如果 callbackPromise 因原因 r 被拒绝,则:
-
将 transactionState 的pendingException 设置为 r。
-
如果 connection.[[context]].[[operationInProgress]] 为
true,则将 transactionState 的pendingDisposition 设置为 “reset”。 -
否则,以“
reset”结束 connection 的事务。
-
-
要以 SmartCardDisposition
disposition 结束 SmartCardConnection
connection 的事务,执行以下步骤:
-
断言: connection.[[context]].[[operationInProgress]] 为
false。 -
断言: connection.[[transactionState]] 不为
null。 -
断言: connection.[[transactionState]] 的pendingDisposition 为
null。 -
令 transactionPromise 为 connection.[[transactionState]] 的promise。
-
如果 connection.[[comm]] 为
null:-
使用一个“
InvalidStateError”DOMException拒绝 transactionPromise。 -
将 connection.[[transactionState]] 设置为
null。 -
返回。
-
-
将 connection.[[context]].[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
调用 connection.[[comm]].
EndTransaction(), 并将与 disposition 对应的DWORD作为输入参数。 -
令 responseCode 为返回的 [PCSC5]
RESPONSECODE。 -
使用智能卡任务 源,在 this 的相关全局对象上排入一个全局任务,该任务执行以下步骤:
-
清除 operationInProgress(目标为 connection.[[context]])。
-
从 connection.[[context]].[[activeReaderTransactions]] 中移除 connection.[[readerName]]。
-
令 exception 为 connection.[[transactionState]] 的pendingException。
-
如果 exception 为
null,则执行以下步骤: -
否则,使用 exception 拒绝 transactionPromise。
-
将 connection.[[transactionState]] 设置为
null。
-
-
要结束任何已敲定事务(目标为 SmartCardConnection
connection),执行以下步骤:
-
如果 connection.[[transactionState]] 为
null,则中止这些步骤。 -
令 disposition 为 connection.[[transactionState]] 的pendingDisposition。
-
如果 disposition 为
null,则中止这些步骤。 -
将 connection.[[transactionState]] 的pendingDisposition 设置为
null。 -
以 disposition 结束 connection 的事务。
要取消未完成的
[PCSC5]
SCARDCOMM 操作,调用 this.[[comm]].Cancel()。
5.4.
status()
方法
status()
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在且不等于 this,则使用一个“
InvalidStateError”DOMException拒绝 promise 并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
令 pcscReader 为一个空的
STR[]。 -
令 pcscState 为一个设置为
0的 [PCSC5]DWORD。 -
令 activeProtocol 为一个设置为
0的 [PCSC5]DWORD。 -
令 pcscAtr 为一个足以容纳任何 [ISO7816-3] 复位应答(ATR)的
BYTE[]。 -
调用 this.[[comm]].
Status(), 并将 pcscReader、pcscState、activeProtocol 和 pcscAtr 作为输出参数。 -
令 responseCode 为返回的
RESPONSECODE。 -
使用智能卡任务 源,在 this 的相关全局对象上排入一个全局任务,该任务执行以下步骤:
-
如果 responseCode 不是
SCARD_S_SUCCESS,则使用一个与 responseCode 对应的异常拒绝 promise,并中止这些步骤。 -
令 state 为一个与 pcscState 和 activeProtocol 对应的
SmartCardConnectionState。 -
如果 state 为
undefined, 则使用一个“UnknownError”DOMException拒绝 promise,并中止这些步骤。 -
令 status 为一个新的
SmartCardConnectionStatus。 -
将 status["
readerName"] 设置为 pcscReader。 -
将 status["
state"] 设置为 state。 -
将 status["
answerToReset"] 设置为一个包含写入 pcscAtr 的字节的ArrayBuffer。 -
使用 status 兑现 promise。
-
-
返回 promise。
5.4.1.
SmartCardConnectionStatus
字典
dictionary {SmartCardConnectionStatus required DOMString ;readerName required SmartCardConnectionState ;state ArrayBuffer ; };answerToReset
readerName-
已连接读卡器的名称。
state-
连接的当前状态。
answerToReset-
卡片的复位应答(ATR)字符串(若适用)。
5.4.1.1.
SmartCardConnectionState
枚举
enum {SmartCardConnectionState ,"absent" ,"present" ,"swallowed" ,"powered" ,"negotiable" ,"t0" ,"t1" };"raw"
"absent"-
读卡器中没有卡片。
"present"-
读卡器中有卡片,但尚未移动到可供使用的位置。
"swallowed"-
读卡器中的卡片已处于可供使用的位置。卡片尚未通电。
"powered"-
卡片已通电,但读卡器驱动程序不知道卡片所处的模式。
"negotiable"-
卡片已重置,正在等待 PTS(协议类型选择)协商。
"t0"-
卡片处于 [ISO7816-3] T=0 协议模式,无法协商新协议。
"t1"-
卡片处于 [ISO7816-3] T=1 协议模式,无法协商新协议。
"raw"-
卡片处于原始协议模式,无法协商新协议。
给定一个
[PCSC5]
DWORD pcscState 和一个 DWORD activeProtocol,按以下步骤
创建一个对应的 SmartCardConnectionState:
-
如果 pcscState 是 [PCSC5]
SCARD_NEGOTIABLE,则返回“negotiable”。 -
如果 pcscState 是 [PCSC5]
SCARD_SPECIFIC,则执行以下步骤: -
返回
undefined。
5.5.
control()
方法
control(controlCode, data)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在且不等于 this,则使用一个“
InvalidStateError”DOMException拒绝 promise 并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
令 pcscControlCode 为一个包含
controlCode的 [PCSC5]DWORD。 -
令 outBuffer 为一个足以容纳任何控制命令响应的 [PCSC5]
BYTE[]。 -
令 outBufferLength 为一个设置为
0的DWORD。 -
并行运行以下步骤:
-
调用 this.[[comm]].
Control(), 并将 pcscControlCode、inBuffer、outBuffer 和 outBufferLength 作为实参。 -
令 responseCode 为返回的
RESPONSECODE。
-
-
返回 promise。
5.6.
getAttribute()
方法
getAttribute(tag)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在且不等于 this,则使用一个“
InvalidStateError”DOMException拒绝 promise 并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
令 buffer 为一个足以容纳此读卡器属性的 [PCSC5]
BYTE[],其大小由平台的 [PCSC5] 实现确定。 -
调用 this.[[comm]].
GetReaderCapabilities(), 并将 pcscTag 和 buffer 作为实参。 -
令 responseCode 为返回的
RESPONSECODE。
-
返回 promise。
5.7.
setAttribute()
方法
setAttribute(tag, value)
方法的步骤如下:
-
令 promise 为一个新的 promise。
-
如果 this.[[context]].[[operationInProgress]] 为
true,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
如果 this.[[context]].[[activeReaderTransactions]][this.[[readerName]]] 存在且不等于 this,则使用一个“
InvalidStateError”DOMException拒绝 promise 并返回 promise。 -
如果 this.[[comm]] 为
null,则使用一个“InvalidStateError”DOMException拒绝 promise,并返回 promise。 -
将 this.[[context]].[[operationInProgress]] 设置为
true。 -
并行运行以下步骤:
-
返回 promise。
6. SmartCardError
接口
[Exposed =(DedicatedWorker ,SharedWorker ,Window ),SecureContext ,IsolatedContext ]interface :SmartCardError DOMException {(constructor optional DOMString = "",message SmartCardErrorOptions );options readonly attribute SmartCardResponseCode ; };responseCode
responseCode
属性是相关
[PCSC5]
方法返回的错误或警告响应代码。
给定一个不同于 SCARD_S_SUCCESS 的
[PCSC5]
RESPONSECODE,按以下步骤创建一个
对应的异常:
-
令 pcscCode 为该
RESPONSECODE。 -
如果 pcscCode 是
SCARD_E_NO_SERVICE,则返回一个新的"no-service"SmartCardError。 -
如果 pcscCode 是
SCARD_E_NO_SMARTCARD,则返回一个新的"no-smartcard"SmartCardError。 -
如果 pcscCode 是
SCARD_E_NOT_READY,则返回一个新的"not-ready"SmartCardError。 -
如果 pcscCode 是
SCARD_E_NOT_TRANSACTED,则返回一个新的"not-transacted"SmartCardError。 -
如果 pcscCode 是
SCARD_E_PROTO_MISMATCH,则返回一个新的"proto-mismatch"SmartCardError。 -
如果 pcscCode 是
SCARD_E_READER_UNAVAILABLE,则返回一个新的"reader-unavailable"SmartCardError。 -
如果 pcscCode 是
SCARD_W_REMOVED_CARD,则返回一个新的"removed-card"SmartCardError。 -
如果 pcscCode 是
SCARD_W_RESET_CARD,则返回一个新的"reset-card"SmartCardError。 -
如果 pcscCode 是
SCARD_E_SERVER_TOO_BUSY,则返回一个新的"server-too-busy"SmartCardError。 -
如果 pcscCode 是
SCARD_E_SHARING_VIOLATION,则返回一个新的"sharing-violation"SmartCardError。 -
如果 pcscCode 是
SCARD_E_SYSTEM_CANCELLED,则返回一个新的"system-cancelled"SmartCardError。 -
如果 pcscCode 是
SCARD_E_UNKNOWN_READER,则返回一个新的"unknown-reader"SmartCardError。 -
如果 pcscCode 是
SCARD_W_UNPOWERED_CARD,则返回一个新的"unpowered-card"SmartCardError。 -
如果 pcscCode 是
SCARD_W_UNRESPONSIVE_CARD,则返回一个新的"unresponsive-card"SmartCardError。 -
如果 pcscCode 是
SCARD_W_UNSUPPORTED_CARD,则返回一个新的"unsupported-card"SmartCardError。 -
如果 pcscCode 是
SCARD_E_UNSUPPORTED_FEATURE,则返回一个新的"unsupported-feature"SmartCardError。 -
如果 pcscCode 是
SCARD_E_INVALID_HANDLE,则返回一个新的“InvalidStateError”DOMException。 -
如果 pcscCode 是
SCARD_E_SERVICE_STOPPED,则返回一个新的“InvalidStateError”DOMException。 -
如果 pcscCode 是
SCARD_P_SHUTDOWN,则返回一个新的“AbortError”DOMException。 -
否则,返回一个新的“
UnknownError”DOMException。
6.1.
SmartCardErrorOptions
字典
dictionary {SmartCardErrorOptions required SmartCardResponseCode ; };responseCode
responseCode
成员是 SmartCardError
的
responseCode
属性的值。
6.2.
SmartCardResponseCode
枚举
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"-
[PCSC5] 规范中的 SCARD_E_NO_SERVICE。
"no-smartcard"-
[PCSC5] 规范中的 SCARD_E_NO_SMARTCARD。
"not-ready"-
[PCSC5] 规范中的 SCARD_E_NOT_READY。
"not-transacted"-
[PCSC5] 规范中的 SCARD_E_NOT_TRANSACTED。
"proto-mismatch"-
[PCSC5] 规范中的 SCARD_E_PROTO_MISMATCH。
"reader-unavailable"-
[PCSC5] 规范中的 SCARD_E_READER_UNAVAILABLE。
"removed-card"-
[PCSC5] 规范中的 SCARD_W_REMOVED_CARD。
"reset-card"-
[PCSC5] 规范中的 SCARD_W_RESET_CARD。
"server-too-busy"-
智能卡资源管理器过于繁忙,无法完成此操作。
"sharing-violation"-
[PCSC5] 规范中的 SCARD_E_SHARING_VIOLATION。
"system-cancelled"-
[PCSC5] 规范中的 SCARD_E_SYSTEM_CANCELLED。
"unknown-reader"-
[PCSC5] 规范中的 SCARD_E_UNKNOWN_READER。
"unpowered-card"-
[PCSC5] 规范中的 SCARD_W_UNPOWERED_CARD。
"unresponsive-card"-
[PCSC5] 规范中的 SCARD_W_UNRESPONSIVE_CARD。
"unsupported-card"-
[PCSC5] 规范中的 SCARD_W_UNSUPPORTED_CARD。
"unsupported-feature"-
[PCSC5] 规范中的 SCARD_E_UNSUPPORTED_FEATURE。
7. 安全和隐私注意事项
此 API 使 Web 应用程序能够访问主机的 PC/SC 智能 卡子系统。这是一项强大功能,如果被滥用, 可能对用户的安全和 隐私造成重大负面影响。本节概述所考虑的威胁,以及 用户代理为缓解这些威胁必须遵守的规范性要求。
7.1. 用户同意
访问智能卡读卡器及其中存在的任何卡片是一项
强大功能。如果没有明确许可,用户代理不得
允许 Web 应用程序获得对 SmartCardConnection
对象的访问权限。
必须针对特定
源获得用户同意。许可请求必须由对 connect()
方法的调用触发。用户代理必须显示许可提示,
该提示应明确指出哪个源正在请求访问,并向
用户提供足够的信息以便其作出知情决定(例如,
显示智能卡读卡器的名称)。
用户代理应同时提供 临时许可(例如“仅限此会话”)和持久许可选项。 为降低用户忘记自己已授予持久 访问权限的风险,临时许可应作为 默认且更为醒目的选项。
必须为用户提供一种机制,用于 查看和撤销此前为此 API 授予的任何许可。
7.2. 指纹识别
listReaders()
方法和
answerToReset
成员会公开可用于被动指纹识别的信息,其中后者属于
SmartCardReaderStateOut
字典。智能卡
读卡器是否存在及其型号可能泄露有关用户的信息,例如用户是否
处于企业环境中。复位应答(ATR)还可以进一步
识别智能卡的类型和发行者。
虽然本规范不要求在调用 listReaders()
前显示许可提示,但对整个 API
的访问由“smart-card”
策略控制功能控制。这使管理员或
用户能够
针对特定源禁用此 API,从而缓解指纹识别
风险。
7.3. 设备和数据完整性
control()
和
setAttribute()
方法提供对智能卡读卡器硬件的直接、
低级访问。恶意站点
可能利用这些方法上传恶意固件、
使设备无法运行,或以其他方式干扰其正常
运行。
同样,已连接到智能卡的恶意站点可能 反复尝试 PIN 验证,以永久锁定卡片,或 访问或覆盖敏感且未受保护的数据。
针对这些威胁的主要缓解措施,是要求在创建
SmartCardConnection
对象之前获得明确许可,
因为这会限制对随后所有强大方法的访问。
7.4. 身份验证和欺骗
对于身份验证用例,开发者 应尽可能优先使用 Web Authentication API。
7.5. 跨源通信
具有可写内存的智能卡可用作侧信道,使 不同源能够交换数据,从而绕过其他同源 策略。对此的缓解措施是,仅向特定 源授予明确许可。攻击需要用户向 多个可能恶意的源授予智能卡访问权限。
7.6. 隔离上下文
此 API 必须仅在隔离上下文中公开。
7.7. 文档生命周期
为防止文档在不受用户直接控制时仍持有与敏感硬件的连接,
当文档不再
完全活动时,用户代理必须处置所有活动的
SmartCardContext
对象及其关联的
SmartCardConnection
对象。这包括自动断开
任何活动连接,就像调用了 disconnect()
一样。
8. 集成
8.1. 权限策略
本规范定义了一项功能,用于控制是否可以使用
Navigator
对象上的 smartCard
属性所公开的方法。
此功能的功能名称为 “smart-card”。
此功能的默认允许列表
为 'none'。对于特定源,用户代理可以将其覆盖
为 'self'(例如,根据用户决定)。