ui: guided OPEN CHANNEL parameters for the BIP opening request (v3.5.0)

The 01 (BIP channel opening) variant was raw hex while 03 (TCP) had a detailed
form.  The asymmetry is real - 01 accepts any OPEN CHANNEL COMPREHENSION-TLVs
(TS 102 226 9.2.1) while 03's set is fixed by 9.2.3 - so 01 now offers a
Fields/Hex switch instead of a rigid form:

- Fields (default) composes the most-used OPEN CHANNEL parameters per
  SIMalliance Stepping Stones R7 18.6.1: bearer description (default 35 01 03),
  transport protocol (UDP 01 / TCP 02, UICC client, remote - the only values
  TS 102 223 6.6.27.4 allows when the transport level is present) with the
  destination port, destination address, NAA/APN, buffer size, alpha
  (transparent checkbox -> 05 00 = no user confirmation) and an extra-TLVs
  field for login/password and anything else.  The local address is never
  emitted (9.2.1 and the guide forbid it).
- Hex keeps the raw COMPREHENSION-TLVs field; pushOpenChannelTlvs() is a pure,
  vector-tested composer feeding the same encoder as before.

Help 2.7 EN/RU and the READMEs explain the two modes; sw cache ->
simple-v251; version stays 3.5.0.
This commit is contained in:
2026-09-23 22:58:22 +03:00
parent 052d90c03e
commit 82f45d488f
7 changed files with 144 additions and 17 deletions
+1 -1
View File
@@ -381,7 +381,7 @@ The **Command Scripting template** checkbox wraps the whole `81` triggering comm
The **Channel / link trigger** sub-pill builds the §9 requests with the same encoder as the RAM/GP chain's **PUSH** row and offers **Pack into Secured packet** (TAR stays manual - the request goes to the target application) and **→ Expanded Script** (each APDU becomes a `22` Command TLV): The **Channel / link trigger** sub-pill builds the §9 requests with the same encoder as the RAM/GP chain's **PUSH** row and offers **Pack into Secured packet** (TAR stays manual - the request goes to the target application) and **→ Expanded Script** (each APDU becomes a `22` Command TLV):
- **BIP channel opening** (`01`) - OPEN CHANNEL COMPREHENSION-TLVs optional; the application issues the proactive OPEN CHANNEL itself. SIMalliance Stepping Stones R7 §18.6 recommends sending it together with the CAT_TP request in the same message (channel parameters in `01`, CAT_TP port in `02`) - the form has an *Also request the CAT_TP link establishment (02)* checkbox and the pair goes out as one concatenated command script; - **BIP channel opening** (`01`) - built in *Fields* mode from the most-used OPEN CHANNEL parameters (bearer, UDP/TCP client remote + port, destination address, NAA/APN, buffer size, alpha; the local address is never emitted), or in *Hex* mode with the raw COMPREHENSION-TLVs; the application issues the proactive OPEN CHANNEL itself. SIMalliance Stepping Stones R7 §18.6 recommends sending it together with the CAT_TP request in the same message (channel parameters in `01`, CAT_TP port in `02`) - the form has an *Also request the CAT_TP link establishment (02)* checkbox and the pair goes out as one concatenated command script;
- **CAT_TP link** (`02`) - destination port in transport level `3C` with protocol type 00 (mandatory), optional buffer size `39` / identification data `36`; standalone it relies on card-provisioned defaults, so prefer the pair above; - **CAT_TP link** (`02`) - destination port in transport level `3C` with protocol type 00 (mandatory), optional buffer size `39` / identification data `36`; standalone it relies on card-provisioned defaults, so prefer the pair above;
- **TCP connection** (`03`) - bearer `35`, transport level `3C` with protocol type 02, destination address `3E` (`21` IPv4 / `57` IPv6 / `F0` FQDN), NAA/APN `47`; the parameters are the OPEN CHANNEL TCP set and are mandatory in the request, so `03` is self-contained (no companion `01`) - the connection is established over BIP or a direct IP connection (TS 102 483) where supported; - **TCP connection** (`03`) - bearer `35`, transport level `3C` with protocol type 02, destination address `3E` (`21` IPv4 / `57` IPv6 / `F0` FQDN), NAA/APN `47`; the parameters are the OPEN CHANNEL TCP set and are mandatory in the request, so `03` is self-contained (no companion `01`) - the connection is established over BIP or a direct IP connection (TS 102 483) where supported;
- **Identification packet** (`04`) is not a trigger - it needs an already open TCP channel, so the TCP request has an *Also send the identification packet (04)* checkbox that appends it in the same message; `04` also stays in the chain's PUSH row for scripts. - **Identification packet** (`04`) is not a trigger - it needs an already open TCP channel, so the TCP request has an *Also send the identification packet (04)* checkbox that appends it in the same message; `04` also stays in the chain's PUSH row for scripts.
+1 -1
View File
@@ -356,7 +356,7 @@ CLA = `80` (GlobalPlatform v2.3.1). Удалённое управление со
Подвкладка **«Триггер канала/линка»** собирает запросы §9 тем же кодировщиком, что и строка **PUSH** в цепочке RAM/GP, и предлагает **«Упаковать в Secured packet»** (TAR остаётся ручным — запрос адресован целевому приложению) и **→ Расширенный скрипт** (каждый APDU становится Command TLV `22`): Подвкладка **«Триггер канала/линка»** собирает запросы §9 тем же кодировщиком, что и строка **PUSH** в цепочке RAM/GP, и предлагает **«Упаковать в Secured packet»** (TAR остаётся ручным — запрос адресован целевому приложению) и **→ Расширенный скрипт** (каждый APDU становится Command TLV `22`):
- **Открытие BIP-канала** (`01`) — COMPREHENSION-TLV OPEN CHANNEL необязательны; проактивную команду OPEN CHANNEL выдаёт само приложение. Stepping Stones R7 §18.6 рекомендует отправлять его вместе с CAT_TP-запросом в одном сообщении (параметры канала в `01`, порт CAT_TP в `02`) — в форме есть флажок «Также запросить установление соединения CAT_TP (02)», пара уходит одним скриптом команд; - **Открытие BIP-канала** (`01`) — собирается в режиме *Fields* из самых употребительных параметров OPEN CHANNEL (bearer, UDP/TCP клиент + порт, адрес назначения, NAA/APN, размер буфера, alpha; локальный адрес не отправляется), либо в режиме *Hex* с сырыми COMPREHENSION-TLV; проактивную команду OPEN CHANNEL выдаёт само приложение. Stepping Stones R7 §18.6 рекомендует отправлять его вместе с CAT_TP-запросом в одном сообщении (параметры канала в `01`, порт CAT_TP в `02`) — в форме есть флажок «Также запросить установление соединения CAT_TP (02)», пара уходит одним скриптом команд;
- **CAT_TP** (`02`) — порт назначения в transport level `3C` с типом 00 (обязателен), необязательные buffer size `39` / данные идентификации `36`; отдельно полагается на предустановленные на карте умолчания, поэтому предпочтительна пара выше; - **CAT_TP** (`02`) — порт назначения в transport level `3C` с типом 00 (обязателен), необязательные buffer size `39` / данные идентификации `36`; отдельно полагается на предустановленные на карте умолчания, поэтому предпочтительна пара выше;
- **TCP-соединение** (`03`) — bearer `35`, transport level `3C` с типом 02, адрес назначения `3E` (`21` IPv4 / `57` IPv6 / `F0` FQDN), NAA/APN `47`; это параметры OPEN CHANNEL для TCP, и они обязательны в запросе, поэтому `03` самодостаточен (сопутствующий `01` не нужен) — соединение устанавливается через BIP или прямое IP-соединение по TS 102 483, где поддерживается; - **TCP-соединение** (`03`) — bearer `35`, transport level `3C` с типом 02, адрес назначения `3E` (`21` IPv4 / `57` IPv6 / `F0` FQDN), NAA/APN `47`; это параметры OPEN CHANNEL для TCP, и они обязательны в запросе, поэтому `03` самодостаточен (сопутствующий `01` не нужен) — соединение устанавливается через BIP или прямое IP-соединение по TS 102 483, где поддерживается;
- **Пакет идентификации** (`04`) — не триггер: ему нужен уже открытый TCP-канал, поэтому у TCP-запроса есть флажок «Также отправить пакет идентификации (04)», добавляющий его в то же сообщение; `04` также остаётся в строке PUSH цепочки для сценариев. - **Пакет идентификации** (`04`) — не триггер: ему нужен уже открытый TCP-канал, поэтому у TCP-запроса есть флажок «Также отправить пакет идентификации (04)», добавляющий его в то же сообщение; `04` также остаётся в строке PUSH цепочки для сценариев.
+1 -1
View File
@@ -255,7 +255,7 @@
<h4 id="push-ts102226" class="font-medium mb-1 mt-3">PUSH по TS 102 226 §9</h4> <h4 id="push-ts102226" class="font-medium mb-1 mt-3">PUSH по TS 102 226 §9</h4>
<p class="text-sm mb-2">Подвкладка <strong>&laquo;Триггер канала/линка&raquo;</strong> собирает запросы &sect;9 тем же кодировщиком, что и строка <strong>PUSH</strong> в цепочке RAM/GP, показывает предпросмотр C-APDU, и предлагает <strong>&laquo;Упаковать в Secured packet&raquo;</strong> (TAR остаётся ручным: запрос адресован целевому приложению, а не Security Domain) и <strong>&rarr; Расширенный скрипт</strong> (оборачивает каждый APDU в Command TLV <code class="font-mono text-sm">22</code> и добавляет их в конструктор Expanded Script).</p> <p class="text-sm mb-2">Подвкладка <strong>&laquo;Триггер канала/линка&raquo;</strong> собирает запросы &sect;9 тем же кодировщиком, что и строка <strong>PUSH</strong> в цепочке RAM/GP, показывает предпросмотр C-APDU, и предлагает <strong>&laquo;Упаковать в Secured packet&raquo;</strong> (TAR остаётся ручным: запрос адресован целевому приложению, а не Security Domain) и <strong>&rarr; Расширенный скрипт</strong> (оборачивает каждый APDU в Command TLV <code class="font-mono text-sm">22</code> и добавляет их в конструктор Expanded Script).</p>
<ul class="list-disc list-inside text-sm space-y-1 mb-3"> <ul class="list-disc list-inside text-sm space-y-1 mb-3">
<li><strong>Открытие BIP-канала</strong> (<code class="font-mono text-sm">01</code>) &mdash; необязательные COMPREHENSION-TLV OPEN CHANNEL; при пустом значении действуют умолчания приложения. Проактивную команду OPEN CHANNEL выдаёт само приложение (&sect;9.1.1). SIMalliance Stepping Stones R7 &sect;18.6 рекомендует отправлять его <strong>вместе с CAT_TP-запросом в одном сообщении</strong> (параметры канала — в <code class="font-mono text-sm">01</code>, порт CAT_TP — в <code class="font-mono text-sm">02</code>), поэтому в форме есть флажок <em>&laquo;Также запросить установление соединения CAT_TP (02)&raquo;</em>; пара передаётся одним скриптом команд (конкатенированные SMS, если больше 140 октетов).</li> <li><strong>Открытие BIP-канала</strong> (<code class="font-mono text-sm">01</code>) &mdash; собирается в режиме <strong>Fields</strong> из самых употребительных параметров OPEN CHANNEL (Stepping Stones &sect;18.6.1): описание bearer, транспортный протокол (UDP или TCP, клиент UICC, удалённое соединение &mdash; только эти значения допускает команда) с портом назначения, адрес назначения, NAA/APN, размер буфера и alpha (флажок <em>прозрачный режим</em> отправляет нулевой alpha, т.е. без подтверждения пользователя); логин/пароль и остальное — в поле дополнительных TLV. <strong>Локальный адрес не отправляется никогда</strong> (&sect;9.2.1 и руководство это запрещают). Режим <strong>Hex</strong> принимает сырые COMPREHENSION-TLV. Проактивную команду OPEN CHANNEL выдаёт само приложение (&sect;9.1.1). SIMalliance Stepping Stones R7 &sect;18.6 рекомендует отправлять его <strong>вместе с CAT_TP-запросом в одном сообщении</strong> (параметры канала — в <code class="font-mono text-sm">01</code>, порт CAT_TP — в <code class="font-mono text-sm">02</code>), поэтому в форме есть флажок <em>&laquo;Также запросить установление соединения CAT_TP (02)&raquo;</em>; пара передаётся одним скриптом команд (конкатенированные SMS, если больше 140 октетов).</li>
<li><strong>Установление соединения CAT_TP</strong> (<code class="font-mono text-sm">02</code>) &mdash; порт назначения в transport level <code class="font-mono text-sm">3C</code> с типом протокола 00 (обязателен), необязательные buffer size <code class="font-mono text-sm">39</code> / данные идентификации <code class="font-mono text-sm">36</code>. Отдельно он полагается на предустановленные на карте умолчания канала/CAT_TP, против чего предостерегает руководство Stepping Stones; предпочтительна пара выше.</li> <li><strong>Установление соединения CAT_TP</strong> (<code class="font-mono text-sm">02</code>) &mdash; порт назначения в transport level <code class="font-mono text-sm">3C</code> с типом протокола 00 (обязателен), необязательные buffer size <code class="font-mono text-sm">39</code> / данные идентификации <code class="font-mono text-sm">36</code>. Отдельно он полагается на предустановленные на карте умолчания канала/CAT_TP, против чего предостерегает руководство Stepping Stones; предпочтительна пара выше.</li>
<li><strong>TCP-соединение</strong> (<code class="font-mono text-sm">03</code>) &mdash; bearer <code class="font-mono text-sm">35</code>, transport level <code class="font-mono text-sm">3C</code> с типом протокола 02 = TCP-клиент, удалённое соединение, адрес назначения <code class="font-mono text-sm">3E</code> (<code class="font-mono text-sm">21</code> IPv4 / <code class="font-mono text-sm">57</code> IPv6 / <code class="font-mono text-sm">F0</code> FQDN), NAA/APN <code class="font-mono text-sm">47</code>; порт и адрес обязательны. Это параметры OPEN CHANNEL для TCP, и они обязательны в запросе, поэтому <code class="font-mono text-sm">03</code> <strong>самодостаточен</strong> &mdash; сопутствующий <code class="font-mono text-sm">01</code> не нужен. Соединение устанавливается через BIP или, если карта и терминал это поддерживают, через прямое IP-соединение (TS 102 483).</li> <li><strong>TCP-соединение</strong> (<code class="font-mono text-sm">03</code>) &mdash; bearer <code class="font-mono text-sm">35</code>, transport level <code class="font-mono text-sm">3C</code> с типом протокола 02 = TCP-клиент, удалённое соединение, адрес назначения <code class="font-mono text-sm">3E</code> (<code class="font-mono text-sm">21</code> IPv4 / <code class="font-mono text-sm">57</code> IPv6 / <code class="font-mono text-sm">F0</code> FQDN), NAA/APN <code class="font-mono text-sm">47</code>; порт и адрес обязательны. Это параметры OPEN CHANNEL для TCP, и они обязательны в запросе, поэтому <code class="font-mono text-sm">03</code> <strong>самодостаточен</strong> &mdash; сопутствующий <code class="font-mono text-sm">01</code> не нужен. Соединение устанавливается через BIP или, если карта и терминал это поддерживают, через прямое IP-соединение (TS 102 483).</li>
<li><strong>Пакет идентификации</strong> (<code class="font-mono text-sm">04</code>) не является триггером: он предполагает уже открытый TCP-канал и имеет смысл только как продолжение в том же сообщении, поэтому у TCP-запроса есть флажок <em>&laquo;Также отправить пакет идентификации (04)&raquo;</em>, добавляющий его (данные необязательны; при пустом значении используется ICCID). <code class="font-mono text-sm">04</code> также остаётся доступным в строке PUSH цепочки RAM/GP для сценариев.</li> <li><strong>Пакет идентификации</strong> (<code class="font-mono text-sm">04</code>) не является триггером: он предполагает уже открытый TCP-канал и имеет смысл только как продолжение в том же сообщении, поэтому у TCP-запроса есть флажок <em>&laquo;Также отправить пакет идентификации (04)&raquo;</em>, добавляющий его (данные необязательны; при пустом значении используется ICCID). <code class="font-mono text-sm">04</code> также остаётся доступным в строке PUSH цепочки RAM/GP для сценариев.</li>
+1 -1
View File
@@ -254,7 +254,7 @@
<h4 id="push-ts102226" class="font-medium mb-1 mt-3">TS 102 226 §9 PUSH</h4> <h4 id="push-ts102226" class="font-medium mb-1 mt-3">TS 102 226 §9 PUSH</h4>
<p class="text-sm mb-2">The <strong>Channel / link trigger</strong> sub-pill builds the &sect;9 requests with the same encoder as the RAM/GP chain's <strong>PUSH</strong> row, previews the C-APDU(s), and offers <strong>Pack into Secured packet</strong> (the TAR stays manual: the request is addressed to the target application, not the Security Domain) and <strong>&rarr; Expanded Script</strong> (wraps each APDU in the <code class="font-mono text-sm">22</code> Command TLV and appends them to the Expanded Script builder).</p> <p class="text-sm mb-2">The <strong>Channel / link trigger</strong> sub-pill builds the &sect;9 requests with the same encoder as the RAM/GP chain's <strong>PUSH</strong> row, previews the C-APDU(s), and offers <strong>Pack into Secured packet</strong> (the TAR stays manual: the request is addressed to the target application, not the Security Domain) and <strong>&rarr; Expanded Script</strong> (wraps each APDU in the <code class="font-mono text-sm">22</code> Command TLV and appends them to the Expanded Script builder).</p>
<ul class="list-disc list-inside text-sm space-y-1 mb-3"> <ul class="list-disc list-inside text-sm space-y-1 mb-3">
<li><strong>BIP channel opening</strong> (<code class="font-mono text-sm">01</code>) &mdash; optional OPEN CHANNEL COMPREHENSION-TLVs; the application defaults apply when empty. The application issues the proactive OPEN CHANNEL itself (&sect;9.1.1). SIMalliance Stepping Stones R7 &sect;18.6 recommends sending it <strong>together with the CAT_TP request in the same message</strong> (the channel parameters ride in <code class="font-mono text-sm">01</code>, the CAT_TP port in <code class="font-mono text-sm">02</code>), so the form has an <em>Also request the CAT_TP link establishment (02)</em> checkbox; the pair is one concatenated command script (concatenated SMS when it exceeds 140 octets).</li> <li><strong>BIP channel opening</strong> (<code class="font-mono text-sm">01</code>) &mdash; built in <strong>Fields</strong> mode from the most-used OPEN CHANNEL parameters (Stepping Stones &sect;18.6.1): bearer description, transport protocol (UDP or TCP, UICC client, remote &mdash; the only values the command allows) with the destination port, destination address, NAA/APN, buffer size and alpha (a <em>transparent</em> checkbox sends the null alpha, i.e. no user confirmation); login/password and anything else go in the extra-TLVs field. The <strong>local address is never emitted</strong> (&sect;9.2.1 and the guide both forbid it). <strong>Hex</strong> mode takes the raw COMPREHENSION-TLVs instead. The application issues the proactive OPEN CHANNEL itself (&sect;9.1.1). SIMalliance Stepping Stones R7 &sect;18.6 recommends sending it <strong>together with the CAT_TP request in the same message</strong> (the channel parameters ride in <code class="font-mono text-sm">01</code>, the CAT_TP port in <code class="font-mono text-sm">02</code>), so the form has an <em>Also request the CAT_TP link establishment (02)</em> checkbox; the pair is one concatenated command script (concatenated SMS when it exceeds 140 octets).</li>
<li><strong>CAT_TP link establishment</strong> (<code class="font-mono text-sm">02</code>) &mdash; destination port in transport level <code class="font-mono text-sm">3C</code> with protocol type 00 (mandatory), optional buffer size <code class="font-mono text-sm">39</code> / identification data <code class="font-mono text-sm">36</code>. Standalone it relies on card-provisioned channel/CAT_TP defaults, which the Stepping Stones guide advises against; prefer the pair above.</li> <li><strong>CAT_TP link establishment</strong> (<code class="font-mono text-sm">02</code>) &mdash; destination port in transport level <code class="font-mono text-sm">3C</code> with protocol type 00 (mandatory), optional buffer size <code class="font-mono text-sm">39</code> / identification data <code class="font-mono text-sm">36</code>. Standalone it relies on card-provisioned channel/CAT_TP defaults, which the Stepping Stones guide advises against; prefer the pair above.</li>
<li><strong>TCP connection</strong> (<code class="font-mono text-sm">03</code>) &mdash; bearer <code class="font-mono text-sm">35</code>, transport level <code class="font-mono text-sm">3C</code> with protocol type 02 = TCP client remote, destination address <code class="font-mono text-sm">3E</code> (<code class="font-mono text-sm">21</code> IPv4 / <code class="font-mono text-sm">57</code> IPv6 / <code class="font-mono text-sm">F0</code> FQDN), NAA/APN <code class="font-mono text-sm">47</code>; port and address are mandatory. These are the OPEN CHANNEL TCP parameters and they are mandatory in the request, so <code class="font-mono text-sm">03</code> is <strong>self-contained</strong> &mdash; it needs no companion <code class="font-mono text-sm">01</code>. The application establishes the connection over BIP or, where the card and terminal support it, over a direct IP connection (TS 102 483).</li> <li><strong>TCP connection</strong> (<code class="font-mono text-sm">03</code>) &mdash; bearer <code class="font-mono text-sm">35</code>, transport level <code class="font-mono text-sm">3C</code> with protocol type 02 = TCP client remote, destination address <code class="font-mono text-sm">3E</code> (<code class="font-mono text-sm">21</code> IPv4 / <code class="font-mono text-sm">57</code> IPv6 / <code class="font-mono text-sm">F0</code> FQDN), NAA/APN <code class="font-mono text-sm">47</code>; port and address are mandatory. These are the OPEN CHANNEL TCP parameters and they are mandatory in the request, so <code class="font-mono text-sm">03</code> is <strong>self-contained</strong> &mdash; it needs no companion <code class="font-mono text-sm">01</code>. The application establishes the connection over BIP or, where the card and terminal support it, over a direct IP connection (TS 102 483).</li>
<li><strong>Identification packet</strong> (<code class="font-mono text-sm">04</code>) is not a trigger: it presupposes an already open TCP channel and only makes sense as a follow-up in the same message, so the TCP request carries an <em>Also send the identification packet (04)</em> checkbox that appends it (optional data; the ICCID is used when empty). <code class="font-mono text-sm">04</code> also stays available in the RAM/GP chain's PUSH row for script sequences.</li> <li><strong>Identification packet</strong> (<code class="font-mono text-sm">04</code>) is not a trigger: it presupposes an already open TCP channel and only makes sense as a follow-up in the same message, so the TCP request carries an <em>Also send the identification packet (04)</em> checkbox that appends it (optional data; the ICCID is used when empty). <code class="font-mono text-sm">04</code> also stays available in the RAM/GP chain's PUSH row for script sequences.</li>
+98 -3
View File
@@ -303,8 +303,48 @@
</select> </select>
</div> </div>
<div data-push-link="01"> <div data-push-link="01">
<label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="OPEN CHANNEL COMPREHENSION-TLVs (hex, optional)">OPEN CHANNEL COMPREHENSION-TLVs (hex, optional)</label> <div class="mb-2">
<label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Mode">Mode</label>
<select id="push-link-oc-mode" onchange="pushUpdate('link')" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 font-mono">
<option value="fields" data-l10n="Fields">Fields</option>
<option value="hex" data-l10n="Hex">Hex</option>
</select>
</div>
<div id="push-link-oc-fields">
<div class="grid grid-cols-2 gap-2 mb-2">
<div><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Bearer description (hex, default 350103)">Bearer description (hex, default 350103)</label>
<input id="push-link-oc-bearer" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="350103"></div>
<div><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Buffer size (hex, 2 bytes)">Buffer size (hex, 2 bytes)</label>
<input id="push-link-oc-buffer" oninput="pushUpdate('link')" maxlength="4" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="0200"></div>
<div><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Transport protocol">Transport protocol</label>
<select id="push-link-oc-proto" onchange="pushUpdate('link')" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 font-mono">
<option value="01" data-l10n="UDP, UICC client, remote">UDP, UICC client, remote</option>
<option value="02" data-l10n="TCP, UICC client, remote">TCP, UICC client, remote</option>
</select></div>
<div><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Destination port (hex)">Destination port (hex)</label>
<input id="push-link-oc-port" oninput="pushUpdate('link')" maxlength="4" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="1F90"></div>
<div><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Destination address value (hex: 21 IPv4 / 57 IPv6 / F0 FQDN)">Destination address value (hex: 21 IPv4 / 57 IPv6 / F0 FQDN)</label>
<input id="push-link-oc-addr" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="210A000001"></div>
<div><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="NAA / APN (text)">NAA / APN (text)</label>
<input id="push-link-oc-apn" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="internet"></div>
</div>
<div class="mb-2">
<label class="flex items-center gap-2 text-xs text-gray-600 dark:text-slate-400">
<input type="checkbox" id="push-link-oc-alpha-null" onchange="pushUpdate('link')" class="rounded">
<span data-l10n="Alpha (transparent — no user confirmation)">Alpha (transparent — no user confirmation)</span>
</label>
<div class="mt-1"><label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Alpha identifier (hex, optional)">Alpha identifier (hex, optional)</label>
<input id="push-link-oc-alpha" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800"></div>
</div>
<div class="mb-2">
<label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="Extra TLVs (hex, optional)">Extra TLVs (hex, optional)</label>
<input id="push-link-oc-extra" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
</div>
</div>
<div id="push-link-oc-hex">
<label class="block mb-1 text-xs font-medium text-gray-500 dark:text-slate-400" data-l10n="OPEN CHANNEL COMPREHENSION-TLVs (hex)">OPEN CHANNEL COMPREHENSION-TLVs (hex)</label>
<textarea id="push-link-data" rows="2" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 mb-2" placeholder="82102081..."></textarea> <textarea id="push-link-data" rows="2" oninput="pushUpdate('link')" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 mb-2" placeholder="82102081..."></textarea>
</div>
<label class="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-slate-300 mb-2"> <label class="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-slate-300 mb-2">
<input type="checkbox" id="push-link-cat" onchange="pushUpdate('link')" class="rounded"> <input type="checkbox" id="push-link-cat" onchange="pushUpdate('link')" class="rounded">
<span data-l10n="Also request the CAT_TP link establishment (02) in the same message">Also request the CAT_TP link establishment (02) in the same message</span> <span data-l10n="Also request the CAT_TP link establishment (02) in the same message">Also request the CAT_TP link establishment (02) in the same message</span>
@@ -2182,9 +2222,48 @@ function pushReadFields(section) {
pushApn: v('push-' + section + '-apn'), pushApn: v('push-' + section + '-apn'),
pushExtra: v('push-' + section + '-extra'), pushExtra: v('push-' + section + '-extra'),
idpIdent: v('push-' + section + '-idp-ident'), idpIdent: v('push-' + section + '-idp-ident'),
ocMode: v('push-' + section + '-oc-mode') || 'fields',
ocBearer: v('push-' + section + '-oc-bearer'),
ocBuffer: v('push-' + section + '-oc-buffer'),
ocProto: v('push-' + section + '-oc-proto') || '01',
ocPort: v('push-' + section + '-oc-port'),
ocAddr: v('push-' + section + '-oc-addr'),
ocApn: v('push-' + section + '-oc-apn'),
ocAlphaNull: !!(document.getElementById('push-' + section + '-oc-alpha-null') || {}).checked,
ocAlpha: v('push-' + section + '-oc-alpha'),
ocExtra: v('push-' + section + '-oc-extra'),
}; };
} }
// OPEN CHANNEL COMPREHENSION-TLVs from the guided "Fields" mode of the BIP
// channel opening request (the most used parameters per SIMalliance Stepping
// Stones R7 18.6.1). The local address is never emitted (TS 102 226 9.2.1
// forbids it and the guide recommends against it); login/password and anything
// else stay in the extra TLVs field. Bearer, buffer size and the destination
// address keep the defaults/behaviour of the OPEN CHANNEL command: the bearer
// defaults to the default bearer (35 01 03), the transport level is only
// emitted with a port and is limited to UDP/TCP client remote (TS 102 223
// 6.6.27.4).
function pushOpenChannelTlvs(f) {
const hx = s => (s || '').replace(/[^0-9a-fA-F]/g, '').toUpperCase();
const four = s => hx(s).padStart(4, '0').slice(-4);
let out = hx(f.ocBearer) || '350103';
const port = hx(f.ocPort);
if (port) out += '3C03' + (f.ocProto === '02' ? '02' : '01') + four(port);
const addr = hx(f.ocAddr);
if (addr) out += '3E' + berLenStr(addr.length / 2) + addr;
const apn = _hotaAsciiHex((f.ocApn || '').trim());
if (apn) out += '47' + berLenStr(apn.length / 2) + apn;
const buffer = hx(f.ocBuffer);
if (buffer) out += '3902' + four(buffer);
if (f.ocAlphaNull) out += '0500';
else {
const alpha = hx(f.ocAlpha);
if (alpha) out += '05' + berLenStr(alpha.length / 2) + alpha;
}
return out + hx(f.ocExtra);
}
// C-APDUs for a §9 push from the form's field values; empty when a mandatory // C-APDUs for a §9 push from the form's field values; empty when a mandatory
// parameter is missing (TS 102 226 9.2.2/9.2.3: CAT_TP and TCP need the // parameter is missing (TS 102 226 9.2.2/9.2.3: CAT_TP and TCP need the
// destination port, TCP also the destination address). P2=01/04 may carry no // destination port, TCP also the destination address). P2=01/04 may carry no
@@ -2200,7 +2279,8 @@ function pushSectionApdus(section, f) {
if (request === '02' && hx(f.pushPort).length !== 4) return []; if (request === '02' && hx(f.pushPort).length !== 4) return [];
if (request === '03' && (hx(f.pushPort).length !== 4 || !hx(f.pushAddr))) return []; if (request === '03' && (hx(f.pushPort).length !== 4 || !hx(f.pushAddr))) return [];
const p2 = parseInt(request, 16); const p2 = parseInt(request, 16);
const data = chainPushData(Object.assign({}, f, { pushType: request })); const ocTlvs = (request === '01' && f.ocMode !== 'hex') ? pushOpenChannelTlvs(f) : f.pushData;
const data = chainPushData(Object.assign({}, f, { pushType: request, pushData: ocTlvs }));
const apdus = [data const apdus = [data
? buildApdu(0x80, 0xEC, 0x01, p2, data.length / 2, data) ? buildApdu(0x80, 0xEC, 0x01, p2, data.length / 2, data)
: buildApdu(0x80, 0xEC, 0x01, p2, null, null)]; : buildApdu(0x80, 0xEC, 0x01, p2, null, null)];
@@ -2244,6 +2324,11 @@ function pushUpdate(section) {
const btn = document.getElementById('push-' + section + '-' + kind + '-btn'); const btn = document.getElementById('push-' + section + '-' + kind + '-btn');
if (btn) btn.disabled = !apdus.length; if (btn) btn.disabled = !apdus.length;
}); });
const ocFields = document.getElementById('push-' + section + '-oc-fields');
const ocHex = document.getElementById('push-' + section + '-oc-hex');
const ocHexMode = f.ocMode === 'hex';
if (ocFields) ocFields.classList.toggle('hidden', ocHexMode);
if (ocHex) ocHex.classList.toggle('hidden', !ocHexMode);
const idpBlock = document.getElementById('push-' + section + '-idp-block'); const idpBlock = document.getElementById('push-' + section + '-idp-block');
if (idpBlock) idpBlock.classList.toggle('hidden', !(f.request === '03' && f.withIdp)); if (idpBlock) idpBlock.classList.toggle('hidden', !(f.request === '03' && f.withIdp));
// On request 01 the shared CAT_TP field blocks (port, max SDU, identification // On request 01 the shared CAT_TP field blocks (port, max SDU, identification
@@ -14983,13 +15068,23 @@ const LANG_RU = {
'Request': 'Запрос', 'Request': 'Запрос',
'BIP channel opening (OPEN CHANNEL)': 'Открытие BIP-канала (OPEN CHANNEL)', 'BIP channel opening (OPEN CHANNEL)': 'Открытие BIP-канала (OPEN CHANNEL)',
'Channel / link trigger': 'Триггер канала/линка', 'Channel / link trigger': 'Триггер канала/линка',
'Mode': 'Режим',
'Fields': 'Поля',
'Hex': 'Hex',
'Bearer description (hex, default 350103)': 'Описание bearer (hex, по умолчанию 350103)',
'Buffer size (hex, 2 bytes)': 'Размер буфера (hex, 2 байта)',
'Transport protocol': 'Транспортный протокол',
'UDP, UICC client, remote': 'UDP, клиент UICC, удалённое соединение',
'TCP, UICC client, remote': 'TCP, клиент UICC, удалённое соединение',
'Alpha (transparent — no user confirmation)': 'Alpha (прозрачный режим — без подтверждения пользователя)',
'Alpha identifier (hex, optional)': 'Alpha-идентификатор (hex, необязательно)',
'Also request the CAT_TP link establishment (02) in the same message': 'Также запросить установление соединения CAT_TP (02) в том же сообщении', 'Also request the CAT_TP link establishment (02) in the same message': 'Также запросить установление соединения CAT_TP (02) в том же сообщении',
'Channel / link establishment (TS 102 226 §9)': 'Установление канала/линка (TS 102 226 §9)', 'Channel / link establishment (TS 102 226 §9)': 'Установление канала/линка (TS 102 226 §9)',
'Also send the identification packet (04) in the same message': 'Также отправить пакет идентификации (04) в том же сообщении', 'Also send the identification packet (04) in the same message': 'Также отправить пакет идентификации (04) в том же сообщении',
'The identification packet follows the TCP request in the same message (ICCID when empty).': 'Пакет идентификации отправляется следом за TCP-запросом в том же сообщении (при пустом значении — ICCID).', 'The identification packet follows the TCP request in the same message (ICCID when empty).': 'Пакет идентификации отправляется следом за TCP-запросом в том же сообщении (при пустом значении — ICCID).',
'CAT_TP link establishment': 'Установление соединения CAT_TP', 'CAT_TP link establishment': 'Установление соединения CAT_TP',
'TCP connection': 'TCP-соединение', 'TCP connection': 'TCP-соединение',
'OPEN CHANNEL COMPREHENSION-TLVs (hex, optional)': 'COMPREHENSION-TLV OPEN CHANNEL (hex, необязательно)', 'OPEN CHANNEL COMPREHENSION-TLVs (hex)': 'COMPREHENSION-TLV OPEN CHANNEL (hex)',
'Destination port (hex)': 'Порт назначения (hex)', 'Destination port (hex)': 'Порт назначения (hex)',
'Max SDU (hex, optional)': 'Макс. SDU (hex, необязательно)', 'Max SDU (hex, optional)': 'Макс. SDU (hex, необязательно)',
'Identification data (hex, optional)': 'Данные идентификации (hex, необязательно)', 'Identification data (hex, optional)': 'Данные идентификации (hex, необязательно)',
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE = 'simple-v250'; const CACHE = 'simple-v251';
const URLS = [ const URLS = [
'index.html', 'index.html',
'help.html', 'help.html',
+40 -8
View File
@@ -31,7 +31,7 @@ function extractFunc(src, name) {
const FNS = ['berLenStr', 'buildApdu', 'buildSelect', 'escHtml', 'esc', 'chainInit', const FNS = ['berLenStr', 'buildApdu', 'buildSelect', 'escHtml', 'esc', 'chainInit',
'chainKind', 'chainIsEmbedded', 'chainCommands', 'chainBuildRowHex', 'chainKind', 'chainIsEmbedded', 'chainCommands', 'chainBuildRowHex',
'chainSimBuildRowHex', 'chainRamBuildRowHex', 'chainPushData', '_hotaAsciiHex', 'chainSimBuildRowHex', 'chainRamBuildRowHex', 'chainPushData', '_hotaAsciiHex',
'chainApduList', 'chainBuildFcp', 'pushSectionApdus']; 'chainApduList', 'chainBuildFcp', 'pushSectionApdus', 'pushOpenChannelTlvs'];
let code = ''; let code = '';
for (const f of FNS) code += extractFunc(html, f) + '\n'; for (const f of FNS) code += extractFunc(html, f) + '\n';
for (const c of ['CHAIN_CMDS_SIM', 'CHAIN_CMDS_USIM', 'CHAIN_CMDS_RAM']) { for (const c of ['CHAIN_CMDS_SIM', 'CHAIN_CMDS_USIM', 'CHAIN_CMDS_RAM']) {
@@ -229,8 +229,8 @@ test('CREATE FILE FCP template skeleton (TS 102 222 table 4)', () => {
test('pushSectionApdus builds the guided §9 channel/link requests', () => { test('pushSectionApdus builds the guided §9 channel/link requests', () => {
// BIP channel opening: OPEN CHANNEL TLVs are optional. // BIP channel opening: OPEN CHANNEL TLVs are optional.
assert.deepStrictEqual(pushSectionApdus('link', { request: '01', pushData: '350103' }), ['80EC010103350103']); assert.deepStrictEqual(pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '350103' }), ['80EC010103350103']);
assert.deepStrictEqual(pushSectionApdus('link', { request: '01', pushData: '' }), ['80EC0101']); assert.deepStrictEqual(pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '' }), ['80EC0101']);
// CAT_TP: the destination port is mandatory (9.2.2). // CAT_TP: the destination port is mandatory (9.2.2).
assert.deepStrictEqual(pushSectionApdus('link', { request: '02', pushPort: '1F90' }), ['80EC0102053C03001F90']); assert.deepStrictEqual(pushSectionApdus('link', { request: '02', pushPort: '1F90' }), ['80EC0102053C03001F90']);
assert.deepStrictEqual(pushSectionApdus('link', { request: '02', pushPort: '' }), []); assert.deepStrictEqual(pushSectionApdus('link', { request: '02', pushPort: '' }), []);
@@ -250,19 +250,51 @@ test('pushSectionApdus builds the guided §9 channel/link requests', () => {
pushSectionApdus('link', { request: '03', pushPort: '0050', pushAddr: '210A000001', pushApn: 'internet', withIdp: true, idpIdent: '0102' }), pushSectionApdus('link', { request: '03', pushPort: '0050', pushAddr: '210A000001', pushApn: 'internet', withIdp: true, idpIdent: '0102' }),
[tcp, '80EC01040436020102']); [tcp, '80EC01040436020102']);
// The follow-up only applies to the TCP request. // The follow-up only applies to the TCP request.
assert.deepStrictEqual(pushSectionApdus('link', { request: '01', pushData: '', withIdp: true }), ['80EC0101']); assert.deepStrictEqual(pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '', withIdp: true }), ['80EC0101']);
// Stepping Stones R7 18.6: the BIP channel opening and the CAT_TP link // Stepping Stones R7 18.6: the BIP channel opening and the CAT_TP link
// request go in the same message; 01 carries the channel parameters, 02 the // request go in the same message; 01 carries the channel parameters, 02 the
// CAT_TP port (mandatory) plus optional max SDU / identification data. // CAT_TP port (mandatory) plus optional max SDU / identification data.
assert.deepStrictEqual( assert.deepStrictEqual(
pushSectionApdus('link', { request: '01', pushData: '', withCat: true, pushPort: '1F90' }), pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '', withCat: true, pushPort: '1F90' }),
['80EC0101', '80EC0102053C03001F90']); ['80EC0101', '80EC0102053C03001F90']);
assert.deepStrictEqual( assert.deepStrictEqual(
pushSectionApdus('link', { request: '01', pushData: '', withCat: true, pushPort: '1F90', pushSdu: '0200', pushIdent: 'ABCD' }), pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '', withCat: true, pushPort: '1F90', pushSdu: '0200', pushIdent: 'ABCD' }),
['80EC0101', '80EC01020D3C03001F90390202003602ABCD']); ['80EC0101', '80EC01020D3C03001F90390202003602ABCD']);
// The CAT_TP port is mandatory for the pair, and the option only applies to 01. // The CAT_TP port is mandatory for the pair, and the option only applies to 01.
assert.deepStrictEqual(pushSectionApdus('link', { request: '01', pushData: '', withCat: true, pushPort: '' }), []); assert.deepStrictEqual(pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '', withCat: true, pushPort: '' }), []);
assert.deepStrictEqual(pushSectionApdus('link', { request: '01', pushData: '', withCat: false, pushPort: '1F90' }), ['80EC0101']); assert.deepStrictEqual(pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '', withCat: false, pushPort: '1F90' }), ['80EC0101']);
});
test('pushOpenChannelTlvs composes the guided OPEN CHANNEL parameters', () => {
// The bearer defaults to the default bearer (35 01 03); the local address is
// never emitted (TS 102 226 9.2.1 / Stepping Stones 18.6.1).
assert.strictEqual(pushOpenChannelTlvs({}), '350103');
assert.strictEqual(pushOpenChannelTlvs({ ocBearer: '350104' }), '350104');
// Transport level (UDP or TCP client remote only, TS 102 223 6.6.27.4).
assert.strictEqual(pushOpenChannelTlvs({ ocProto: '01', ocPort: '1F90' }), '3501033C03011F90');
assert.strictEqual(pushOpenChannelTlvs({ ocProto: '02', ocPort: '0050' }), '3501033C03020050');
// Full set: transport level + destination address + NAA + buffer size +
// transparent alpha (05 00 = no user confirmation).
assert.strictEqual(
pushOpenChannelTlvs({ ocProto: '01', ocPort: '1F90', ocAddr: '210A000001', ocApn: 'internet',
ocBuffer: '0200', ocAlphaNull: true }),
'350103' + '3C03011F90' + '3E05210A000001' + '4708696E7465726E6574' + '39020200' + '0500');
// A custom alpha identifier and free-form extra TLVs (login/password, ...).
assert.strictEqual(pushOpenChannelTlvs({ ocAlpha: '00410042' }), '350103050400410042');
assert.strictEqual(pushOpenChannelTlvs({ ocExtra: '4708696E7465726E6574' }), '3501034708696E7465726E6574');
// Fields mode feeds the same encoder as the raw hex field.
assert.deepStrictEqual(
pushSectionApdus('link', { request: '01', ocMode: 'fields', ocProto: '01', ocPort: '1F90' }),
['80EC0101083501033C03011F90']);
assert.deepStrictEqual(
pushSectionApdus('link', { request: '01', ocMode: 'hex', pushData: '350103' }),
['80EC010103350103']);
// Fields mode plus the CAT_TP follow-up: the OPEN CHANNEL port is its own
// field, the CAT_TP port comes from the shared one.
assert.deepStrictEqual(
pushSectionApdus('link', { request: '01', ocMode: 'fields', ocProto: '01', ocPort: '1F90',
withCat: true, pushPort: '1F91' }),
['80EC0101083501033C03011F90', '80EC0102053C03001F91']);
}); });
test('chainApduList drops GET RESPONSE and splits multi-APDU rows', () => { test('chainApduList drops GET RESPONSE and splits multi-APDU rows', () => {