feat(descriptor): SBQ2 connection descriptor format; release v5.8.0

The SB1 invitation runs 2000-2400 characters and needs QR version 38-40, past
the point where a single code is scannable, so the app falls back to an
animated multi-frame QR. SBQ2 is a fixed binary layout carrying only what
brings up DTLS -- ICE credentials, certificate fingerprint, candidates -- with
the SDP rebuilt from a template by a strict serializer. Measured on real Chrome
and Firefox SDP across four network profiles: 98-149 bytes, QR version 6-8.

Key material is meant to move to the DataChannel, bound by a commitment in the
descriptor. That half does not exist yet, so nothing calls this module: the
format is landed for review and freeze, not wired into the connection path.
doc/DESCRIPTOR-SBQ2.md records the gate on phase 3.

The decoder is a parser of hostile input: fixed offsets, explicit lengths,
deny-by-default on reserved values and unknown TLV extension types, trailing
bytes rejected, ICE credentials alphabet-checked so a CRLF cannot reach the
serializer. No compression -- DEFLATE adds bytes on this payload, and dropping
it removes the decompression-bomb surface with it.

Candidate pruning keeps coverage before count: one candidate per (family, type,
transport) survives before any surplus, so an IPv6-only or UDP-blocked path
cannot be pruned away by a v4-first sort.

Tests cover round-trip against captured Chrome and Firefox SDP, IPv6 and NAT64
addresses, ICE-TCP candidates, the TLV area, clock skew, one-shot binding and
SAS transcript coverage.
This commit is contained in:
lockbitchat
2026-08-06 11:54:05 -04:00
parent 3212138a0d
commit 6e82cfcae2
14 changed files with 1765 additions and 37 deletions
+18
View File
@@ -0,0 +1,18 @@
{
"host_only": {
"offer": "v=0\r\no=- 8025882406963837699 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=candidate:988732788 1 udp 2113937151 771d1a30-f1d1-4f8e-82b7-1305438c5940.local 59046 typ host generation 0 network-cost 999\r\na=ice-ufrag:w7U/\r\na=ice-pwd:KipG1wMsp+hOpj8ajZcvODlD\r\na=ice-options:trickle\r\na=fingerprint:sha-256 56:D6:BE:A5:4B:B9:EA:4F:FD:91:18:EA:28:C3:9F:36:F0:FA:FA:7E:3F:0B:B5:66:28:39:48:33:16:8B:FF:C8\r\na=setup:actpass\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n",
"answer": "v=0\r\no=- 6135472287747382945 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=candidate:790708617 1 udp 2113937151 57cc7e40-40b6-40e1-8248-81edf1d934be.local 65298 typ host generation 0 network-cost 999\r\na=ice-ufrag:tPvC\r\na=ice-pwd:XLZeDsbxW/+Nt33ftg0Io8v8\r\na=ice-options:trickle\r\na=fingerprint:sha-256 55:59:0E:D7:5F:BE:6D:19:A5:1D:00:5A:5B:A7:E6:98:36:13:1F:E6:ED:2A:02:13:27:DC:F6:DE:B2:42:EC:53\r\na=setup:active\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
},
"stun": {
"offer": "v=0\r\no=- 1287905459661968667 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 45882 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 152.166.136.164\r\na=candidate:2197344123 1 udp 2113937151 9b2c4f0d-6917-4559-af8f-edf002be1af4.local 54223 typ host generation 0 network-cost 999\r\na=candidate:203475045 1 udp 1677729535 152.166.136.164 45882 typ srflx raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=ice-ufrag:bBBc\r\na=ice-pwd:sbibKYjfuiROao15zgpzogob\r\na=ice-options:trickle\r\na=fingerprint:sha-256 B4:0C:45:B0:B8:00:8B:D2:07:C2:7B:FA:32:F8:5F:3B:77:23:89:50:7B:70:69:94:9D:C0:3B:BE:9C:3F:46:9F\r\na=setup:actpass\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n",
"answer": "v=0\r\no=- 9108354338848473407 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 42832 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 152.166.136.164\r\na=candidate:1702118434 1 udp 2113937151 9bddaddb-50f6-46c0-b861-c5c35e0d554f.local 49431 typ host generation 0 network-cost 999\r\na=candidate:3953935164 1 udp 1677729535 152.166.136.164 42832 typ srflx raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=ice-ufrag:cf/e\r\na=ice-pwd:OLfqFZLI/2SlC4cka2hdCCWY\r\na=ice-options:trickle\r\na=fingerprint:sha-256 A4:7E:1A:F3:FF:4F:B4:8E:51:19:75:35:96:B6:F4:82:44:FB:FB:14:97:0F:EB:D5:8B:37:8A:FD:B4:21:AA:16\r\na=setup:active\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
},
"turn_all": {
"offer": "v=0\r\no=- 6190378570176556335 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 60938 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 144.172.96.126\r\na=candidate:2999788131 1 udp 2113937151 c0f6ed16-adbe-42af-85d6-28e16e90c45d.local 60928 typ host generation 0 network-cost 999\r\na=candidate:1008018813 1 udp 1677729535 152.166.136.164 45400 typ srflx raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:946064782 1 udp 50340351 144.172.96.126 60938 typ relay raddr 152.166.136.164 rport 45400 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 63477 typ relay raddr 152.166.136.164 rport 33107 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 60311 typ relay raddr 152.166.136.164 rport 48747 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 49605 typ relay raddr 152.166.136.164 rport 33341 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 59290 typ relay raddr 152.166.136.164 rport 34318 generation 0 network-cost 999\r\na=ice-ufrag:iyCI\r\na=ice-pwd:1MIhkkUNEVx/gHU4fBSeaLKy\r\na=ice-options:trickle\r\na=fingerprint:sha-256 B4:51:9A:51:28:02:8F:BC:90:CF:8E:C9:DB:B1:0B:86:D3:D9:57:D4:0C:3C:0B:AD:CD:4A:9F:75:54:EF:E3:63\r\na=setup:actpass\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n",
"answer": "v=0\r\no=- 4208677942963212620 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 55935 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 144.172.96.126\r\na=candidate:1624328767 1 udp 2113937151 72cf1b0b-c850-49c0-984f-9fdba3cc1510.local 49687 typ host generation 0 network-cost 999\r\na=candidate:2588979035 1 udp 1677729535 152.166.136.164 38722 typ srflx raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:3202382357 1 udp 50340351 144.172.96.126 55935 typ relay raddr 152.166.136.164 rport 38722 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 51124 typ relay raddr 152.166.136.164 rport 46651 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 53603 typ relay raddr 152.166.136.164 rport 35591 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 51788 typ relay raddr 152.166.136.164 rport 37397 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 59006 typ relay raddr 152.166.136.164 rport 42296 generation 0 network-cost 999\r\na=ice-ufrag:ZNeq\r\na=ice-pwd:fmXvwyclqup2YcAOa3riQyf5\r\na=ice-options:trickle\r\na=fingerprint:sha-256 08:B6:8E:7F:FE:B6:0B:29:CB:14:9C:BC:71:9B:60:AE:13:13:B7:61:8E:99:F7:AA:07:8A:EC:7A:F8:69:38:35\r\na=setup:active\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
},
"turn_relay_only": {
"offer": "v=0\r\no=- 2484576169985209246 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 51269 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 144.172.96.126\r\na=candidate:2390409615 1 udp 50340351 144.172.96.126 51269 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 52454 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 50222 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 61797 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 50906 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=ice-ufrag:XE1k\r\na=ice-pwd:iSZ8bBcbrE0jhGE8jzuomXax\r\na=ice-options:trickle\r\na=fingerprint:sha-256 2A:23:07:B1:60:25:43:FA:70:3D:96:1E:8C:CC:8C:91:17:06:94:11:DA:AA:16:23:1C:1D:3F:3A:BA:CF:74:8F\r\na=setup:actpass\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n",
"answer": "v=0\r\no=- 4269499427491218796 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 61535 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 144.172.96.126\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 61535 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:333114079 1 udp 16785663 144.172.96.126 60493 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 54229 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=candidate:866909729 1 udp 8191 144.172.96.126 65269 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=ice-ufrag:ZtK/\r\na=ice-pwd:AtRcW+mdaWKxORtSAYpYFPY9\r\na=ice-options:trickle\r\na=fingerprint:sha-256 6E:02:61:A8:9D:92:2F:B5:FA:90:F6:C9:3E:F3:40:BA:81:5A:E8:B2:A6:3D:8B:D2:82:3D:4F:07:47:31:97:9F\r\na=setup:active\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
}
}