@floegence/flowersec-core 3.2.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +57 -200
  2. package/THIRD_PARTY_NOTICES.md +11 -11
  3. package/dist/browser/index.d.ts +0 -5
  4. package/dist/browser/index.js +0 -3
  5. package/dist/cli.js +93 -64
  6. package/dist/facade.d.ts +0 -17
  7. package/dist/facade.js +0 -11
  8. package/dist/generated/unicode151.d.ts +2 -0
  9. package/dist/generated/unicode151.js +83 -0
  10. package/dist/interop/proxyServerPeer.js +34 -20
  11. package/dist/interop/serverParityPeer.js +11 -252
  12. package/dist/node/acceptor.d.ts +1 -57
  13. package/dist/node/acceptor.js +3 -420
  14. package/dist/node/acceptorV3.js +2 -2
  15. package/dist/node/connectSessionV3.js +2 -2
  16. package/dist/node/index.d.ts +2 -17
  17. package/dist/node/index.js +1 -9
  18. package/dist/node/nativeTransportAddon.d.ts +7 -36
  19. package/dist/node/nativeTransportAddon.js +7 -27
  20. package/dist/node/proxyServer.d.ts +2 -2
  21. package/dist/node/proxyServer.js +2 -2
  22. package/dist/node/rawQuicAdapterV3.d.ts +2 -2
  23. package/dist/node/rawQuicAdapterV3.js +1 -1
  24. package/dist/node/rawQuicServerV3.d.ts +2 -2
  25. package/dist/node/rawQuicServerV3.js +1 -1
  26. package/dist/node/rawQuicTls.d.ts +2 -0
  27. package/dist/node/{rawQuicAdapter.js → rawQuicTls.js} +30 -45
  28. package/dist/node/tunnelRuntimeV3.js +2 -2
  29. package/dist/proxy/index.d.ts +1 -1
  30. package/dist/proxy/index.js +1 -1
  31. package/dist/proxy/integration.d.ts +5 -5
  32. package/dist/proxy/integration.js +2 -2
  33. package/dist/proxy/runtime.js +11 -26
  34. package/dist/proxy/serviceWorkerRuntime.d.ts +7 -0
  35. package/dist/proxy/serviceWorkerRuntime.js +75 -0
  36. package/dist/proxy/types.d.ts +0 -1
  37. package/dist/proxy/windowBridge.d.ts +2 -0
  38. package/dist/proxy/windowBridge.js +53 -6
  39. package/dist/public/contract.d.ts +1 -3
  40. package/dist/public/streamHandlers.d.ts +0 -3
  41. package/dist/public/streamHandlers.js +2 -4
  42. package/dist/public/streamMetadata.js +2 -2
  43. package/dist/runtime/errors.d.ts +2 -2
  44. package/dist/testSupport/tlsFixture.d.ts +2 -0
  45. package/dist/testSupport/tlsFixture.js +8 -0
  46. package/dist/utils/errors.d.ts +0 -2
  47. package/dist/utils/errors.js +0 -80
  48. package/dist/v3/artifact.js +17 -3
  49. package/dist/v3/carrier.d.ts +2 -2
  50. package/dist/v3/controller.js +2 -6
  51. package/dist/v3/protocol.js +2 -103
  52. package/dist/v3/retryDisposition.d.ts +2 -2
  53. package/dist/v3/retryDisposition.js +0 -7
  54. package/dist/v3/security.d.ts +1 -10
  55. package/dist/v3/security.js +2 -9
  56. package/dist/vendor/tr46.d.ts +4 -0
  57. package/dist/vendor/tr46.js +37 -32
  58. package/package.json +19 -17
  59. package/sbom/cyclonedx.json +62 -62
  60. package/sbom/spdx.json +65 -65
  61. package/dist/browser/connectSession.d.ts +0 -13
  62. package/dist/browser/connectSession.js +0 -40
  63. package/dist/browser/runtimeCapability.d.ts +0 -13
  64. package/dist/browser/runtimeCapability.js +0 -27
  65. package/dist/browser/sessionRuntime.d.ts +0 -2
  66. package/dist/browser/sessionRuntime.js +0 -21
  67. package/dist/browser/v2.d.ts +0 -3
  68. package/dist/browser/v2.js +0 -2
  69. package/dist/browser/webTransportClient.d.ts +0 -8
  70. package/dist/browser/webTransportClient.js +0 -55
  71. package/dist/connectionController.d.ts +0 -55
  72. package/dist/connectionController.js +0 -441
  73. package/dist/connector/adapters/rawQuicCandidate.d.ts +0 -5
  74. package/dist/connector/adapters/rawQuicCandidate.js +0 -71
  75. package/dist/connector/adapters/webSocketCandidate.d.ts +0 -7
  76. package/dist/connector/adapters/webSocketCandidate.js +0 -116
  77. package/dist/connector/adapters/webTransportCandidate.d.ts +0 -5
  78. package/dist/connector/adapters/webTransportCandidate.js +0 -73
  79. package/dist/connector/admissionCommit.d.ts +0 -31
  80. package/dist/connector/admissionCommit.js +0 -239
  81. package/dist/connector/sessionAcceptor.d.ts +0 -38
  82. package/dist/connector/sessionAcceptor.js +0 -158
  83. package/dist/connector/sessionConfig.d.ts +0 -3
  84. package/dist/connector/sessionConfig.js +0 -30
  85. package/dist/connector/sessionConnector.d.ts +0 -47
  86. package/dist/connector/sessionConnector.js +0 -606
  87. package/dist/node/connectSession.d.ts +0 -23
  88. package/dist/node/connectSession.js +0 -93
  89. package/dist/node/controlplane.d.ts +0 -137
  90. package/dist/node/controlplane.js +0 -443
  91. package/dist/node/rawQuicAdapter.d.ts +0 -9
  92. package/dist/node/rawQuicServer.d.ts +0 -24
  93. package/dist/node/rawQuicServer.js +0 -37
  94. package/dist/node/runtimeCapability.d.ts +0 -14
  95. package/dist/node/runtimeCapability.js +0 -24
  96. package/dist/node/sessionRuntime.d.ts +0 -2
  97. package/dist/node/sessionRuntime.js +0 -13
  98. package/dist/node/tunnelRuntime.d.ts +0 -42
  99. package/dist/node/tunnelRuntime.js +0 -559
  100. package/dist/node/v2.d.ts +0 -11
  101. package/dist/node/v2.js +0 -6
  102. package/dist/node/webSocketServer.d.ts +0 -24
  103. package/dist/node/webSocketServer.js +0 -135
  104. package/dist/public/artifact.d.ts +0 -11
  105. package/dist/public/artifact.js +0 -44
  106. package/dist/public/artifactLease.d.ts +0 -10
  107. package/dist/public/artifactLease.js +0 -41
  108. package/dist/public/connectError.d.ts +0 -6
  109. package/dist/public/connectError.js +0 -9
  110. package/dist/transport/webSocketAdapter.d.ts +0 -31
  111. package/dist/transport/webSocketAdapter.js +0 -370
  112. package/dist/transport/webTransportAdapter.d.ts +0 -27
  113. package/dist/transport/webTransportAdapter.js +0 -534
  114. package/dist/v2/admissionError.d.ts +0 -4
  115. package/dist/v2/admissionError.js +0 -8
  116. package/dist/v2/artifact.d.ts +0 -128
  117. package/dist/v2/artifact.js +0 -1131
  118. package/dist/v2/artifactLease.d.ts +0 -1
  119. package/dist/v2/artifactLease.js +0 -7
  120. package/dist/v2/capability.d.ts +0 -29
  121. package/dist/v2/capability.js +0 -190
  122. package/dist/v2/carrier.d.ts +0 -84
  123. package/dist/v2/carrier.js +0 -411
  124. package/dist/v2/contract.d.ts +0 -46
  125. package/dist/v2/contract.js +0 -1
  126. package/dist/v2/handshake.d.ts +0 -80
  127. package/dist/v2/handshake.js +0 -470
  128. package/dist/v2/index.d.ts +0 -14
  129. package/dist/v2/index.js +0 -7
  130. package/dist/v2/opaqueArtifact.d.ts +0 -1
  131. package/dist/v2/opaqueArtifact.js +0 -2
  132. package/dist/v2/protocol.d.ts +0 -99
  133. package/dist/v2/protocol.js +0 -737
  134. package/dist/v2/publicSession.d.ts +0 -1
  135. package/dist/v2/publicSession.js +0 -281
  136. package/dist/v2/retryDisposition.d.ts +0 -16
  137. package/dist/v2/retryDisposition.js +0 -30
  138. package/dist/v2/session.d.ts +0 -310
  139. package/dist/v2/session.js +0 -2127
  140. package/dist/v2/streamLifetimeLedger.d.ts +0 -31
  141. package/dist/v2/streamLifetimeLedger.js +0 -131
  142. package/dist/v2/streamMetadata.d.ts +0 -1
  143. package/dist/v2/streamMetadata.js +0 -7
  144. package/dist/v2/unreliableMessage.d.ts +0 -43
  145. package/dist/v2/unreliableMessage.js +0 -254
@@ -1,737 +0,0 @@
1
- import { gcm } from "@noble/ciphers/aes.js";
2
- import { chacha20poly1305 } from "@noble/ciphers/chacha.js";
3
- import { expand } from "@noble/hashes/hkdf.js";
4
- import { hmac } from "@noble/hashes/hmac.js";
5
- import { sha256 } from "@noble/hashes/sha2.js";
6
- const encoder = new TextEncoder();
7
- const MAX_UINT32 = 0xffffffff;
8
- const MAX_UINT64 = (1n << 64n) - 1n;
9
- const SETUP_PREFACE_BYTES = 56;
10
- const RECORD_HEADER_BYTES = 24;
11
- const INNER_HEADER_BYTES = 8;
12
- const MAX_DATA_BYTES = 16_384;
13
- const MAX_CIPHERTEXT_BYTES = INNER_HEADER_BYTES + MAX_DATA_BYTES + 16;
14
- const OPEN_FIXED_PAYLOAD_BYTES = 46;
15
- const MAX_OPEN_BYTES = 8_192;
16
- const MAX_OPEN_KIND_BYTES = 128;
17
- const MAX_OPEN_METADATA_BYTES = 4_096;
18
- const MAX_OPEN_METADATA_DEPTH = 4;
19
- const MAX_OPEN_METADATA_NODES = 64;
20
- const MAX_OPEN_METADATA_KEYS = 64;
21
- const MAX_OPEN_METADATA_ARRAY = 32;
22
- const MAX_OPEN_METADATA_KEY_BYTES = 64;
23
- const MAX_OPEN_METADATA_STRING_BYTES = 512;
24
- const UNICODE_15_1_ASSIGNED_RANGES_HEX = [
25
- "00000000037700037A00037F00038400038A00038C00038C00038E0003A10003A300052F00053100055600055900058A00058D00058F0005910005C7",
26
- "0005D00005EA0005EF0005F400060000070D00070F00074A00074D0007B10007C00007FA0007FD00082D00083000083E00084000085B00085E00085E",
27
- "00086000086A00087000088E00089000089100089800098300098500098C00098F0009900009930009A80009AA0009B00009B20009B20009B60009B9",
28
- "0009BC0009C40009C70009C80009CB0009CE0009D70009D70009DC0009DD0009DF0009E30009E60009FE000A01000A03000A05000A0A000A0F000A10",
29
- "000A13000A28000A2A000A30000A32000A33000A35000A36000A38000A39000A3C000A3C000A3E000A42000A47000A48000A4B000A4D000A51000A51",
30
- "000A59000A5C000A5E000A5E000A66000A76000A81000A83000A85000A8D000A8F000A91000A93000AA8000AAA000AB0000AB2000AB3000AB5000AB9",
31
- "000ABC000AC5000AC7000AC9000ACB000ACD000AD0000AD0000AE0000AE3000AE6000AF1000AF9000AFF000B01000B03000B05000B0C000B0F000B10",
32
- "000B13000B28000B2A000B30000B32000B33000B35000B39000B3C000B44000B47000B48000B4B000B4D000B55000B57000B5C000B5D000B5F000B63",
33
- "000B66000B77000B82000B83000B85000B8A000B8E000B90000B92000B95000B99000B9A000B9C000B9C000B9E000B9F000BA3000BA4000BA8000BAA",
34
- "000BAE000BB9000BBE000BC2000BC6000BC8000BCA000BCD000BD0000BD0000BD7000BD7000BE6000BFA000C00000C0C000C0E000C10000C12000C28",
35
- "000C2A000C39000C3C000C44000C46000C48000C4A000C4D000C55000C56000C58000C5A000C5D000C5D000C60000C63000C66000C6F000C77000C8C",
36
- "000C8E000C90000C92000CA8000CAA000CB3000CB5000CB9000CBC000CC4000CC6000CC8000CCA000CCD000CD5000CD6000CDD000CDE000CE0000CE3",
37
- "000CE6000CEF000CF1000CF3000D00000D0C000D0E000D10000D12000D44000D46000D48000D4A000D4F000D54000D63000D66000D7F000D81000D83",
38
- "000D85000D96000D9A000DB1000DB3000DBB000DBD000DBD000DC0000DC6000DCA000DCA000DCF000DD4000DD6000DD6000DD8000DDF000DE6000DEF",
39
- "000DF2000DF4000E01000E3A000E3F000E5B000E81000E82000E84000E84000E86000E8A000E8C000EA3000EA5000EA5000EA7000EBD000EC0000EC4",
40
- "000EC6000EC6000EC8000ECE000ED0000ED9000EDC000EDF000F00000F47000F49000F6C000F71000F97000F99000FBC000FBE000FCC000FCE000FDA",
41
- "0010000010C50010C70010C70010CD0010CD0010D000124800124A00124D00125000125600125800125800125A00125D00126000128800128A00128D",
42
- "0012900012B00012B20012B50012B80012BE0012C00012C00012C20012C50012C80012D60012D800131000131200131500131800135A00135D00137C",
43
- "0013800013990013A00013F50013F80013FD00140000169C0016A00016F800170000171500171F00173600174000175300176000176C00176E001770",
44
- "0017720017730017800017DD0017E00017E90017F00017F90018000018190018200018780018800018AA0018B00018F500190000191E00192000192B",
45
- "00193000193B00194000194000194400196D0019700019740019800019AB0019B00019C90019D00019DA0019DE001A1B001A1E001A5E001A60001A7C",
46
- "001A7F001A89001A90001A99001AA0001AAD001AB0001ACE001B00001B4C001B50001B7E001B80001BF3001BFC001C37001C3B001C49001C4D001C88",
47
- "001C90001CBA001CBD001CC7001CD0001CFA001D00001F15001F18001F1D001F20001F45001F48001F4D001F50001F57001F59001F59001F5B001F5B",
48
- "001F5D001F5D001F5F001F7D001F80001FB4001FB6001FC4001FC6001FD3001FD6001FDB001FDD001FEF001FF2001FF4001FF6001FFE002000002064",
49
- "00206600207100207400208E00209000209C0020A00020C00020D00020F000210000218B00219000242600244000244A002460002B73002B76002B95",
50
- "002B97002CF3002CF9002D25002D27002D27002D2D002D2D002D30002D67002D6F002D70002D7F002D96002DA0002DA6002DA8002DAE002DB0002DB6",
51
- "002DB8002DBE002DC0002DC6002DC8002DCE002DD0002DD6002DD8002DDE002DE0002E5D002E80002E99002E9B002EF3002F00002FD5002FF000303F",
52
- "0030410030960030990030FF00310500312F00313100318E0031900031E30031EF00321E00322000A48C00A49000A4C600A4D000A62B00A64000A6F7",
53
- "00A70000A7CA00A7D000A7D100A7D300A7D300A7D500A7D900A7F200A82C00A83000A83900A84000A87700A88000A8C500A8CE00A8D900A8E000A953",
54
- "00A95F00A97C00A98000A9CD00A9CF00A9D900A9DE00A9FE00AA0000AA3600AA4000AA4D00AA5000AA5900AA5C00AAC200AADB00AAF600AB0100AB06",
55
- "00AB0900AB0E00AB1100AB1600AB2000AB2600AB2800AB2E00AB3000AB6B00AB7000ABED00ABF000ABF900AC0000D7A300D7B000D7C600D7CB00D7FB",
56
- "00D80000FA6D00FA7000FAD900FB0000FB0600FB1300FB1700FB1D00FB3600FB3800FB3C00FB3E00FB3E00FB4000FB4100FB4300FB4400FB4600FBC2",
57
- "00FBD300FD8F00FD9200FDC700FDCF00FE1900FE2000FE5200FE5400FE6600FE6800FE6B00FE7000FE7400FE7600FEFC00FEFF00FEFF00FF0100FFBE",
58
- "00FFC200FFC700FFCA00FFCF00FFD200FFD700FFDA00FFDC00FFE000FFE600FFE800FFEE00FFF901000B01000D01002601002801003A01003C01003D",
59
- "01003F01004D01005001005D0100800100FA01010001010201010701013301013701018E01019001019C0101A00101A00101D00101FD01028001029C",
60
- "0102A00102D00102E00102FB01030001032301032D01034A01035001037A01038001039D01039F0103C30103C80103D501040001049D0104A00104A9",
61
- "0104B00104D30104D80104FB01050001052701053001056301056F01057A01057C01058A01058C0105920105940105950105970105A10105A30105B1",
62
- "0105B30105B90105BB0105BC0106000107360107400107550107600107670107800107850107870107B00107B20107BA010800010805010808010808",
63
- "01080A01083501083701083801083C01083C01083F01085501085701089E0108A70108AF0108E00108F20108F40108F50108FB01091B01091F010939",
64
- "01093F01093F0109800109B70109BC0109CF0109D2010A03010A05010A06010A0C010A13010A15010A17010A19010A35010A38010A3A010A3F010A48",
65
- "010A50010A58010A60010A9F010AC0010AE6010AEB010AF6010B00010B35010B39010B55010B58010B72010B78010B91010B99010B9C010BA9010BAF",
66
- "010C00010C48010C80010CB2010CC0010CF2010CFA010D27010D30010D39010E60010E7E010E80010EA9010EAB010EAD010EB0010EB1010EFD010F27",
67
- "010F30010F59010F70010F89010FB0010FCB010FE0010FF601100001104D01105201107501107F0110C20110CD0110CD0110D00110E80110F00110F9",
68
- "0111000111340111360111470111500111760111800111DF0111E10111F401120001121101121301124101128001128601128801128801128A01128D",
69
- "01128F01129D01129F0112A90112B00112EA0112F00112F901130001130301130501130C01130F01131001131301132801132A011330011332011333",
70
- "01133501133901133B01134401134701134801134B01134D01135001135001135701135701135D01136301136601136C01137001137401140001145B",
71
- "01145D0114610114800114C70114D00114D90115800115B50115B80115DD01160001164401165001165901166001166C0116800116B90116C00116C9",
72
- "01170001171A01171D01172B01173001174601180001183B0118A00118F20118FF01190601190901190901190C011913011915011916011918011935",
73
- "01193701193801193B0119460119500119590119A00119A70119AA0119D70119DA0119E4011A00011A47011A50011AA2011AB0011AF8011B00011B09",
74
- "011C00011C08011C0A011C36011C38011C45011C50011C6C011C70011C8F011C92011CA7011CA9011CB6011D00011D06011D08011D09011D0B011D36",
75
- "011D3A011D3A011D3C011D3D011D3F011D47011D50011D59011D60011D65011D67011D68011D6A011D8E011D90011D91011D93011D98011DA0011DA9",
76
- "011EE0011EF8011F00011F10011F12011F3A011F3E011F59011FB0011FB0011FC0011FF1011FFF01239901240001246E012470012474012480012543",
77
- "012F90012FF2013000013455014400014646016800016A38016A40016A5E016A60016A69016A6E016ABE016AC0016AC9016AD0016AED016AF0016AF5",
78
- "016B00016B45016B50016B59016B5B016B61016B63016B77016B7D016B8F016E40016E9A016F00016F4A016F4F016F87016F8F016F9F016FE0016FE4",
79
- "016FF0016FF10170000187F7018800018CD5018D00018D0801AFF001AFF301AFF501AFFB01AFFD01AFFE01B00001B12201B13201B13201B15001B152",
80
- "01B15501B15501B16401B16701B17001B2FB01BC0001BC6A01BC7001BC7C01BC8001BC8801BC9001BC9901BC9C01BCA301CF0001CF2D01CF3001CF46",
81
- "01CF5001CFC301D00001D0F501D10001D12601D12901D1EA01D20001D24501D2C001D2D301D2E001D2F301D30001D35601D36001D37801D40001D454",
82
- "01D45601D49C01D49E01D49F01D4A201D4A201D4A501D4A601D4A901D4AC01D4AE01D4B901D4BB01D4BB01D4BD01D4C301D4C501D50501D50701D50A",
83
- "01D50D01D51401D51601D51C01D51E01D53901D53B01D53E01D54001D54401D54601D54601D54A01D55001D55201D6A501D6A801D7CB01D7CE01DA8B",
84
- "01DA9B01DA9F01DAA101DAAF01DF0001DF1E01DF2501DF2A01E00001E00601E00801E01801E01B01E02101E02301E02401E02601E02A01E03001E06D",
85
- "01E08F01E08F01E10001E12C01E13001E13D01E14001E14901E14E01E14F01E29001E2AE01E2C001E2F901E2FF01E2FF01E4D001E4F901E7E001E7E6",
86
- "01E7E801E7EB01E7ED01E7EE01E7F001E7FE01E80001E8C401E8C701E8D601E90001E94B01E95001E95901E95E01E95F01EC7101ECB401ED0101ED3D",
87
- "01EE0001EE0301EE0501EE1F01EE2101EE2201EE2401EE2401EE2701EE2701EE2901EE3201EE3401EE3701EE3901EE3901EE3B01EE3B01EE4201EE42",
88
- "01EE4701EE4701EE4901EE4901EE4B01EE4B01EE4D01EE4F01EE5101EE5201EE5401EE5401EE5701EE5701EE5901EE5901EE5B01EE5B01EE5D01EE5D",
89
- "01EE5F01EE5F01EE6101EE6201EE6401EE6401EE6701EE6A01EE6C01EE7201EE7401EE7701EE7901EE7C01EE7E01EE7E01EE8001EE8901EE8B01EE9B",
90
- "01EEA101EEA301EEA501EEA901EEAB01EEBB01EEF001EEF101F00001F02B01F03001F09301F0A001F0AE01F0B101F0BF01F0C101F0CF01F0D101F0F5",
91
- "01F10001F1AD01F1E601F20201F21001F23B01F24001F24801F25001F25101F26001F26501F30001F6D701F6DC01F6EC01F6F001F6FC01F70001F776",
92
- "01F77B01F7D901F7E001F7EB01F7F001F7F001F80001F80B01F81001F84701F85001F85901F86001F88701F89001F8AD01F8B001F8B101F90001FA53",
93
- "01FA6001FA6D01FA7001FA7C01FA8001FA8801FA9001FABD01FABF01FAC501FACE01FADB01FAE001FAE801FAF001FAF801FB0001FB9201FB9401FBCA",
94
- "01FBF001FBF901FFFE02A6DF02A70002B73902B74002B81D02B82002CEA102CEB002EBE002EBF002EE5D02F80002FA1D02FFFE03134A0313500323AF",
95
- "03FFFE03FFFF04FFFE04FFFF05FFFE05FFFF06FFFE06FFFF07FFFE07FFFF08FFFE08FFFF09FFFE09FFFF0AFFFE0AFFFF0BFFFE0BFFFF0CFFFE0CFFFF",
96
- "0DFFFE0DFFFF0E00010E00010E00200E007F0E01000E01EF0EFFFE10FFFF",
97
- ].join("");
98
- const UNICODE_15_1_ASSIGNED_RANGES = decodeUnicodeRanges(UNICODE_15_1_ASSIGNED_RANGES_HEX);
99
- const strictDecoder = new TextDecoder("utf-8", { fatal: true });
100
- export class ProtocolV2Error extends Error {
101
- }
102
- export var DirectionV2;
103
- (function (DirectionV2) {
104
- DirectionV2[DirectionV2["ClientToServer"] = 1] = "ClientToServer";
105
- DirectionV2[DirectionV2["ServerToClient"] = 2] = "ServerToClient";
106
- })(DirectionV2 || (DirectionV2 = {}));
107
- export var CipherSuiteV2;
108
- (function (CipherSuiteV2) {
109
- CipherSuiteV2[CipherSuiteV2["ChaCha20Poly1305"] = 1] = "ChaCha20Poly1305";
110
- CipherSuiteV2[CipherSuiteV2["AES256GCM"] = 2] = "AES256GCM";
111
- })(CipherSuiteV2 || (CipherSuiteV2 = {}));
112
- export var InnerTypeV2;
113
- (function (InnerTypeV2) {
114
- InnerTypeV2[InnerTypeV2["Open"] = 1] = "Open";
115
- InnerTypeV2[InnerTypeV2["OpenACK"] = 2] = "OpenACK";
116
- InnerTypeV2[InnerTypeV2["OpenReject"] = 3] = "OpenReject";
117
- InnerTypeV2[InnerTypeV2["Data"] = 4] = "Data";
118
- InnerTypeV2[InnerTypeV2["FIN"] = 5] = "FIN";
119
- InnerTypeV2[InnerTypeV2["StreamKeyUpdate"] = 6] = "StreamKeyUpdate";
120
- InnerTypeV2[InnerTypeV2["SessionReady"] = 16] = "SessionReady";
121
- InnerTypeV2[InnerTypeV2["Ping"] = 17] = "Ping";
122
- InnerTypeV2[InnerTypeV2["Pong"] = 18] = "Pong";
123
- InnerTypeV2[InnerTypeV2["SessionKeyUpdate"] = 19] = "SessionKeyUpdate";
124
- InnerTypeV2[InnerTypeV2["StreamReset"] = 20] = "StreamReset";
125
- InnerTypeV2[InnerTypeV2["GoAway"] = 21] = "GoAway";
126
- InnerTypeV2[InnerTypeV2["SessionClose"] = 22] = "SessionClose";
127
- InnerTypeV2[InnerTypeV2["SessionReadyACK"] = 23] = "SessionReadyACK";
128
- InnerTypeV2[InnerTypeV2["SessionKeyUpdateACK"] = 24] = "SessionKeyUpdateACK";
129
- InnerTypeV2[InnerTypeV2["StreamKeyUpdateACK"] = 25] = "StreamKeyUpdateACK";
130
- InnerTypeV2[InnerTypeV2["SessionReadyConfirm"] = 26] = "SessionReadyConfirm";
131
- })(InnerTypeV2 || (InnerTypeV2 = {}));
132
- export function deriveEpochZero(sessionPRK, direction) {
133
- assertBytes("session PRK", sessionPRK, 32);
134
- assertDirection(direction);
135
- const epochSecret = expand32(sessionPRK, labelWith("flowersec v2 epoch zero", byte(direction)));
136
- return deriveEpochRoots(epochSecret);
137
- }
138
- export function deriveEpochRoots(epochSecret) {
139
- assertBytes("epoch secret", epochSecret, 32);
140
- return {
141
- epochSecret: epochSecret.slice(),
142
- controlRoot: expand32(epochSecret, labelWith("flowersec v2 control root")),
143
- streamRoot: expand32(epochSecret, labelWith("flowersec v2 stream root")),
144
- setupRoot: expand32(epochSecret, labelWith("flowersec v2 setup root")),
145
- rekeyRoot: expand32(epochSecret, labelWith("flowersec v2 rekey root")),
146
- };
147
- }
148
- export function deriveNextEpoch(rekeyRoot, h3, direction, nextEpoch) {
149
- assertBytes("rekey root", rekeyRoot, 32);
150
- assertBytes("H3", h3, 32);
151
- assertDirection(direction);
152
- assertU32("next epoch", nextEpoch);
153
- return expand32(rekeyRoot, labelWith("flowersec v2 next epoch", h3, byte(direction), u32be(nextEpoch)));
154
- }
155
- export function deriveStreamMaterial(streamRoot, h3, logicalStreamID, direction, epoch) {
156
- assertBytes("stream root", streamRoot, 32);
157
- assertBytes("H3", h3, 32);
158
- assertLogicalStreamID(logicalStreamID);
159
- assertDirection(direction);
160
- assertU32("epoch", epoch);
161
- const secret = expand32(streamRoot, labelWith("flowersec v2 stream", h3, u64be(logicalStreamID), byte(direction), u32be(epoch)));
162
- return {
163
- secret,
164
- recordKey: expand32(secret, labelWith("flowersec v2 record key")),
165
- noncePrefix: expand(sha256, secret, labelWith("flowersec v2 nonce"), 4),
166
- };
167
- }
168
- export function deriveControlMaterial(controlRoot, h3, direction, epoch) {
169
- assertBytes("control root", controlRoot, 32);
170
- assertBytes("H3", h3, 32);
171
- assertDirection(direction);
172
- assertU32("epoch", epoch);
173
- const secret = expand32(controlRoot, labelWith("flowersec v2 control", h3, u64be(0n), byte(direction), u32be(epoch)));
174
- return {
175
- secret,
176
- recordKey: expand32(secret, labelWith("flowersec v2 record key")),
177
- noncePrefix: expand(sha256, secret, labelWith("flowersec v2 nonce"), 4),
178
- };
179
- }
180
- export function computeSetupMAC(setupRoot, h3, preface) {
181
- assertBytes("setup root", setupRoot, 32);
182
- assertBytes("H3", h3, 32);
183
- const raw = encodeSetupPreface(preface);
184
- return hmac(sha256, setupRoot, labelWith("flowersec-v2-setup", h3, raw.subarray(0, 24)));
185
- }
186
- export function encodeSetupPreface(preface) {
187
- assertLogicalStreamID(preface.logicalStreamID);
188
- if ((preface.openerRole !== 1 && preface.openerRole !== 2) ||
189
- (preface.openerRole === 1 && (preface.logicalStreamID & 1n) !== 1n) ||
190
- (preface.openerRole === 2 && (preface.logicalStreamID & 1n) !== 0n)) {
191
- throw new ProtocolV2Error("invalid FSS2 opener or logical stream ID");
192
- }
193
- assertU32("initial send epoch", preface.initialSendEpoch);
194
- assertBytes("setup MAC", preface.setupMAC, 32);
195
- const out = new Uint8Array(SETUP_PREFACE_BYTES);
196
- out.set(encoder.encode("FSS2"), 0);
197
- out[4] = 2;
198
- out[5] = preface.openerRole;
199
- out.set(u64be(preface.logicalStreamID), 8);
200
- out.set(u32be(preface.initialSendEpoch), 16);
201
- out.set(preface.setupMAC, 24);
202
- return out;
203
- }
204
- export function decodeSetupPrefaceV2(raw) {
205
- if (raw.length !== SETUP_PREFACE_BYTES ||
206
- raw[0] !== 0x46 || raw[1] !== 0x53 || raw[2] !== 0x53 || raw[3] !== 0x32 ||
207
- raw[4] !== 2 || raw[6] !== 0 || raw[7] !== 0 || readU32be(raw, 20) !== 0) {
208
- throw new ProtocolV2Error("invalid FSS2 setup preface");
209
- }
210
- const openerRole = raw[5];
211
- const logicalStreamID = readU64be(raw, 8);
212
- if ((openerRole !== 1 && openerRole !== 2) ||
213
- logicalStreamID === 0n ||
214
- (openerRole === 1 && (logicalStreamID & 1n) !== 1n) ||
215
- (openerRole === 2 && (logicalStreamID & 1n) !== 0n)) {
216
- throw new ProtocolV2Error("invalid FSS2 opener or logical stream ID");
217
- }
218
- return {
219
- openerRole,
220
- logicalStreamID,
221
- initialSendEpoch: readU32be(raw, 16),
222
- setupMAC: raw.slice(24, 56),
223
- };
224
- }
225
- export function verifySetupMAC(setupRoot, h3, preface) {
226
- const want = computeSetupMAC(setupRoot, h3, { ...preface, setupMAC: new Uint8Array(32) });
227
- return bytesEqual(want, preface.setupMAC);
228
- }
229
- export function computeFSS2HashV2(raw) {
230
- decodeSetupPrefaceV2(raw);
231
- return sha256(raw);
232
- }
233
- export function encodeRecordHeader(header) {
234
- validateRecordHeader(header);
235
- const out = new Uint8Array(RECORD_HEADER_BYTES);
236
- out.set(encoder.encode("FSR2"), 0);
237
- out[4] = 2;
238
- out[5] = RECORD_HEADER_BYTES;
239
- out.set(u32be(header.epoch), 8);
240
- out.set(u64be(header.sequence), 12);
241
- out.set(u32be(header.ciphertextLength), 20);
242
- return out;
243
- }
244
- export function decodeRecordHeader(raw) {
245
- if (raw.length !== RECORD_HEADER_BYTES ||
246
- raw[0] !== 0x46 ||
247
- raw[1] !== 0x53 ||
248
- raw[2] !== 0x52 ||
249
- raw[3] !== 0x32 ||
250
- raw[4] !== 2 ||
251
- raw[5] !== RECORD_HEADER_BYTES ||
252
- raw[6] !== 0 ||
253
- raw[7] !== 0) {
254
- throw new ProtocolV2Error("invalid FSR2 header");
255
- }
256
- const header = {
257
- epoch: readU32be(raw, 8),
258
- sequence: readU64be(raw, 12),
259
- ciphertextLength: readU32be(raw, 20),
260
- };
261
- validateRecordHeader(header);
262
- return header;
263
- }
264
- export function buildDataInner(payload) {
265
- if (payload.length < 1 || payload.length > MAX_DATA_BYTES) {
266
- throw new ProtocolV2Error("invalid v2 DATA payload length");
267
- }
268
- const out = new Uint8Array(INNER_HEADER_BYTES + payload.length);
269
- out[0] = 4;
270
- out.set(u32be(payload.length), 4);
271
- out.set(payload, INNER_HEADER_BYTES);
272
- return out;
273
- }
274
- export function encodeInnerRecordV2(type, payload) {
275
- validateInnerPayload(type, payload.length);
276
- const out = new Uint8Array(INNER_HEADER_BYTES + payload.length);
277
- out[0] = type;
278
- out.set(u32be(payload.length), 4);
279
- out.set(payload, INNER_HEADER_BYTES);
280
- return out;
281
- }
282
- export function decodeInnerRecordV2(raw) {
283
- if (raw.length < INNER_HEADER_BYTES || raw[1] !== 0 || raw[2] !== 0 || raw[3] !== 0) {
284
- throw new ProtocolV2Error("invalid FSR2 inner record");
285
- }
286
- const length = readU32be(raw, 4);
287
- if (raw.length !== INNER_HEADER_BYTES + length) {
288
- throw new ProtocolV2Error("invalid FSR2 inner record length");
289
- }
290
- const type = raw[0];
291
- validateInnerPayload(type, length);
292
- return { type, payload: raw.slice(INNER_HEADER_BYTES) };
293
- }
294
- export function encodeOpenPayload(payload) {
295
- assertLogicalStreamID(payload.logicalStreamID);
296
- assertBytes("FSS2 hash", payload.fss2Hash, 32);
297
- const kind = validateOpenKind(payload.kind);
298
- const metadata = canonicalMetadata(payload.metadata, true);
299
- const total = OPEN_FIXED_PAYLOAD_BYTES + kind.length + metadata.length;
300
- if (total > MAX_OPEN_BYTES)
301
- throw new ProtocolV2Error("OPEN payload is too large");
302
- const out = new Uint8Array(total);
303
- out.set(u64be(payload.logicalStreamID), 0);
304
- out.set(payload.fss2Hash, 8);
305
- new DataView(out.buffer).setUint16(40, kind.length, false);
306
- new DataView(out.buffer).setUint32(42, metadata.length, false);
307
- out.set(kind, OPEN_FIXED_PAYLOAD_BYTES);
308
- out.set(metadata, OPEN_FIXED_PAYLOAD_BYTES + kind.length);
309
- return out;
310
- }
311
- export function decodeOpenPayload(raw) {
312
- if (raw.length < OPEN_FIXED_PAYLOAD_BYTES || raw.length > MAX_OPEN_BYTES) {
313
- throw new ProtocolV2Error("invalid OPEN payload length");
314
- }
315
- const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
316
- const logicalStreamID = view.getBigUint64(0, false);
317
- assertLogicalStreamID(logicalStreamID);
318
- const kindLength = view.getUint16(40, false);
319
- const metadataLength = view.getUint32(42, false);
320
- if (OPEN_FIXED_PAYLOAD_BYTES + kindLength + metadataLength !== raw.length) {
321
- throw new ProtocolV2Error("invalid OPEN field lengths");
322
- }
323
- let kind;
324
- try {
325
- kind = strictDecoder.decode(raw.subarray(OPEN_FIXED_PAYLOAD_BYTES, OPEN_FIXED_PAYLOAD_BYTES + kindLength));
326
- }
327
- catch {
328
- throw new ProtocolV2Error("OPEN kind is not valid UTF-8");
329
- }
330
- validateOpenKind(kind);
331
- const metadata = canonicalMetadata(raw.subarray(OPEN_FIXED_PAYLOAD_BYTES + kindLength), false);
332
- return {
333
- logicalStreamID,
334
- fss2Hash: raw.slice(8, 40),
335
- kind,
336
- metadata,
337
- };
338
- }
339
- export function computeOpenHashV2(rawOpenPayload) {
340
- decodeOpenPayload(rawOpenPayload);
341
- return sha256(concat(encoder.encode("flowersec-v2-open\0"), u32be(rawOpenPayload.length), rawOpenPayload));
342
- }
343
- export function encodeOpenACKV2(openHash) {
344
- assertBytes("OPEN hash", openHash, 32);
345
- return openHash.slice();
346
- }
347
- export function decodeOpenACKV2(raw) {
348
- assertBytes("OPEN ACK", raw, 32);
349
- return raw.slice();
350
- }
351
- export function encodeOpenRejectV2(openHash, reason) {
352
- assertBytes("OPEN hash", openHash, 32);
353
- if (!Number.isInteger(reason) || reason < 1 || reason > 5) {
354
- throw new ProtocolV2Error("invalid OPEN reject reason");
355
- }
356
- const out = new Uint8Array(34);
357
- out.set(openHash);
358
- new DataView(out.buffer).setUint16(32, reason, false);
359
- return out;
360
- }
361
- export function decodeOpenRejectV2(raw) {
362
- if (raw.length !== 34)
363
- throw new ProtocolV2Error("invalid OPEN reject payload");
364
- const reason = new DataView(raw.buffer, raw.byteOffset, raw.byteLength).getUint16(32, false);
365
- if (reason === 0)
366
- throw new ProtocolV2Error("invalid OPEN reject reason");
367
- return { openHash: raw.slice(0, 32), reason, knownReason: reason >= 1 && reason <= 5 };
368
- }
369
- export function encodeStreamKeyUpdateACKV2(value) {
370
- assertLogicalStreamID(value.logicalStreamID);
371
- assertU64("stream rekey transition", value.transition);
372
- if (value.transition === 0n)
373
- throw new ProtocolV2Error("stream rekey transition must be non-zero");
374
- assertU32("stream rekey epoch", value.epoch);
375
- return concat(u64be(value.logicalStreamID), u64be(value.transition), u32be(value.epoch));
376
- }
377
- export function decodeStreamKeyUpdateACKV2(raw) {
378
- if (raw.length !== 20)
379
- throw new ProtocolV2Error("invalid STREAM_KEY_UPDATE_ACK payload");
380
- const value = {
381
- logicalStreamID: readU64be(raw, 0),
382
- transition: readU64be(raw, 8),
383
- epoch: readU32be(raw, 16),
384
- };
385
- assertLogicalStreamID(value.logicalStreamID);
386
- if (value.transition === 0n)
387
- throw new ProtocolV2Error("stream rekey transition must be non-zero");
388
- if (value.epoch === 0)
389
- throw new ProtocolV2Error("stream rekey epoch must be non-zero");
390
- return value;
391
- }
392
- export function buildRecordAAD(h3, logicalStreamID, direction, rawHeader) {
393
- assertBytes("H3", h3, 32);
394
- assertU64("logical stream ID", logicalStreamID);
395
- assertDirection(direction);
396
- decodeRecordHeader(rawHeader);
397
- return labelWith("flowersec-v2-record", h3, u64be(logicalStreamID), byte(direction), rawHeader);
398
- }
399
- export function sealRecord(suite, material, h3, logicalStreamID, direction, header, plaintext) {
400
- validateMaterial(material);
401
- if (plaintext.length + 16 !== header.ciphertextLength) {
402
- throw new ProtocolV2Error("FSR2 plaintext length does not match the header");
403
- }
404
- const rawHeader = encodeRecordHeader(header);
405
- const nonce = concat(material.noncePrefix, u64be(header.sequence));
406
- const aad = buildRecordAAD(h3, logicalStreamID, direction, rawHeader);
407
- return cipher(suite, material.recordKey, nonce, aad).encrypt(plaintext);
408
- }
409
- export function openRecord(suite, material, h3, logicalStreamID, direction, header, ciphertext) {
410
- validateMaterial(material);
411
- if (ciphertext.length !== header.ciphertextLength) {
412
- throw new ProtocolV2Error("FSR2 ciphertext length does not match the header");
413
- }
414
- const rawHeader = encodeRecordHeader(header);
415
- const nonce = concat(material.noncePrefix, u64be(header.sequence));
416
- const aad = buildRecordAAD(h3, logicalStreamID, direction, rawHeader);
417
- try {
418
- return cipher(suite, material.recordKey, nonce, aad).decrypt(ciphertext);
419
- }
420
- catch {
421
- throw new ProtocolV2Error("v2 record authentication failed");
422
- }
423
- }
424
- function cipher(suite, key, nonce, aad) {
425
- switch (suite) {
426
- case CipherSuiteV2.ChaCha20Poly1305:
427
- return chacha20poly1305(key, nonce, aad);
428
- case CipherSuiteV2.AES256GCM:
429
- return gcm(key, nonce, aad);
430
- default:
431
- throw new ProtocolV2Error("invalid v2 cipher suite");
432
- }
433
- }
434
- function validateMaterial(material) {
435
- assertBytes("record key", material.recordKey, 32);
436
- assertBytes("nonce prefix", material.noncePrefix, 4);
437
- }
438
- function validateRecordHeader(header) {
439
- assertU32("record epoch", header.epoch);
440
- assertU64("record sequence", header.sequence);
441
- if (!Number.isInteger(header.ciphertextLength) ||
442
- header.ciphertextLength < 16 ||
443
- header.ciphertextLength > MAX_CIPHERTEXT_BYTES) {
444
- throw new ProtocolV2Error("invalid FSR2 ciphertext length");
445
- }
446
- }
447
- function validateInnerPayload(type, length) {
448
- switch (type) {
449
- case InnerTypeV2.Open:
450
- if (length >= 1 && length <= MAX_OPEN_BYTES)
451
- return;
452
- break;
453
- case InnerTypeV2.Data:
454
- if (length >= 1 && length <= MAX_DATA_BYTES)
455
- return;
456
- break;
457
- case InnerTypeV2.FIN:
458
- case InnerTypeV2.SessionReady:
459
- case InnerTypeV2.SessionReadyACK:
460
- case InnerTypeV2.SessionReadyConfirm:
461
- if (length === 0)
462
- return;
463
- break;
464
- case InnerTypeV2.OpenACK:
465
- if (length === 32)
466
- return;
467
- break;
468
- case InnerTypeV2.OpenReject:
469
- if (length === 34)
470
- return;
471
- break;
472
- case InnerTypeV2.StreamKeyUpdate:
473
- if (length === 12)
474
- return;
475
- break;
476
- case InnerTypeV2.Ping:
477
- case InnerTypeV2.Pong:
478
- if (length === 8)
479
- return;
480
- break;
481
- case InnerTypeV2.SessionKeyUpdate:
482
- case InnerTypeV2.SessionKeyUpdateACK:
483
- case InnerTypeV2.StreamKeyUpdateACK:
484
- if (length === 20)
485
- return;
486
- break;
487
- case InnerTypeV2.StreamReset:
488
- case InnerTypeV2.GoAway:
489
- if (length === 10)
490
- return;
491
- break;
492
- case InnerTypeV2.SessionClose:
493
- if (length === 2)
494
- return;
495
- break;
496
- default:
497
- throw new ProtocolV2Error(`unknown FSR2 inner type ${type}`);
498
- }
499
- throw new ProtocolV2Error(`invalid FSR2 inner payload length for type ${type}`);
500
- }
501
- function expand32(prk, info) {
502
- return expand(sha256, prk, info, 32);
503
- }
504
- function labelWith(label, ...parts) {
505
- return concat(encoder.encode(label), byte(0), ...parts);
506
- }
507
- function concat(...parts) {
508
- const size = parts.reduce((total, part) => total + part.length, 0);
509
- const out = new Uint8Array(size);
510
- let offset = 0;
511
- for (const part of parts) {
512
- out.set(part, offset);
513
- offset += part.length;
514
- }
515
- return out;
516
- }
517
- function byte(value) {
518
- return Uint8Array.of(value);
519
- }
520
- function u32be(value) {
521
- assertU32("uint32", value);
522
- const out = new Uint8Array(4);
523
- new DataView(out.buffer).setUint32(0, value, false);
524
- return out;
525
- }
526
- function u64be(value) {
527
- assertU64("uint64", value);
528
- const out = new Uint8Array(8);
529
- new DataView(out.buffer).setBigUint64(0, value, false);
530
- return out;
531
- }
532
- function readU32be(value, offset) {
533
- return new DataView(value.buffer, value.byteOffset, value.byteLength).getUint32(offset, false);
534
- }
535
- function readU64be(value, offset) {
536
- return new DataView(value.buffer, value.byteOffset, value.byteLength).getBigUint64(offset, false);
537
- }
538
- function assertDirection(direction) {
539
- if (direction !== DirectionV2.ClientToServer &&
540
- direction !== DirectionV2.ServerToClient) {
541
- throw new ProtocolV2Error("invalid v2 direction");
542
- }
543
- }
544
- function assertLogicalStreamID(value) {
545
- assertU64("logical stream ID", value);
546
- if (value === 0n)
547
- throw new ProtocolV2Error("logical stream ID must be non-zero");
548
- }
549
- function assertU32(name, value) {
550
- if (!Number.isInteger(value) || value < 0 || value > MAX_UINT32) {
551
- throw new ProtocolV2Error(`${name} must be uint32`);
552
- }
553
- }
554
- function assertU64(name, value) {
555
- if (value < 0n || value > MAX_UINT64)
556
- throw new ProtocolV2Error(`${name} must be uint64`);
557
- }
558
- function assertBytes(name, value, length) {
559
- if (value.length !== length)
560
- throw new ProtocolV2Error(`${name} must be ${length} bytes`);
561
- }
562
- function bytesEqual(left, right) {
563
- if (left.length !== right.length)
564
- return false;
565
- let difference = 0;
566
- for (let index = 0; index < left.length; index++)
567
- difference |= left[index] ^ right[index];
568
- return difference === 0;
569
- }
570
- function validateOpenKind(value) {
571
- const encoded = encoder.encode(value);
572
- if (!validApplicationStreamKind(value)) {
573
- throw new ProtocolV2Error("invalid OPEN kind");
574
- }
575
- return encoded;
576
- }
577
- /** @internal */
578
- export function validApplicationStreamKind(value) {
579
- if (typeof value !== "string" ||
580
- !validOpenUnicodeString(value, MAX_OPEN_KIND_BYTES, false)) {
581
- return false;
582
- }
583
- const scalars = Array.from(value);
584
- return !(isUnicodeWhitespace(scalars[0].codePointAt(0)) ||
585
- isUnicodeWhitespace(scalars.at(-1).codePointAt(0)));
586
- }
587
- function canonicalMetadata(raw, allowEmpty) {
588
- if (raw.length === 0 && allowEmpty)
589
- return encoder.encode("{}");
590
- if (raw.length === 0 || raw.length > MAX_OPEN_METADATA_BYTES) {
591
- throw new ProtocolV2Error("invalid OPEN metadata length");
592
- }
593
- let text;
594
- try {
595
- text = strictDecoder.decode(raw);
596
- }
597
- catch {
598
- throw new ProtocolV2Error("OPEN metadata is not valid UTF-8");
599
- }
600
- let value;
601
- try {
602
- value = JSON.parse(text);
603
- }
604
- catch {
605
- throw new ProtocolV2Error("OPEN metadata is not valid JSON");
606
- }
607
- if (!isJSONObject(value))
608
- throw new ProtocolV2Error("OPEN metadata root must be an object");
609
- const canonical = canonicalStreamMetadataJSONV2Internal(value);
610
- if (canonical !== text ||
611
- encoder.encode(canonical).length > MAX_OPEN_METADATA_BYTES) {
612
- throw new ProtocolV2Error("OPEN metadata is not canonical JSON");
613
- }
614
- return encoder.encode(canonical);
615
- }
616
- /** @internal Validates a public metadata value against the exact OPEN contract. */
617
- export function canonicalStreamMetadataJSONV2Internal(value) {
618
- if (!isJSONObject(value))
619
- throw new ProtocolV2Error("OPEN metadata root must be an object");
620
- const state = { nodes: -1 };
621
- const canonical = canonicalValidatedMetadataJSONString(value, 1, state);
622
- if (encoder.encode(canonical).length > MAX_OPEN_METADATA_BYTES) {
623
- throw new ProtocolV2Error("OPEN metadata is too large");
624
- }
625
- return canonical;
626
- }
627
- function canonicalValidatedMetadataJSONString(value, depth, state) {
628
- if (depth > MAX_OPEN_METADATA_DEPTH)
629
- throw new ProtocolV2Error("OPEN metadata exceeds depth limit");
630
- state.nodes += 1;
631
- if (state.nodes > MAX_OPEN_METADATA_NODES)
632
- throw new ProtocolV2Error("OPEN metadata exceeds node limit");
633
- if (value === null)
634
- return "null";
635
- if (typeof value === "boolean")
636
- return value ? "true" : "false";
637
- if (typeof value === "number") {
638
- if (!Number.isSafeInteger(value) || Object.is(value, -0))
639
- throw new ProtocolV2Error("OPEN metadata number is not an I-JSON safe integer");
640
- return value.toString(10);
641
- }
642
- if (typeof value === "string") {
643
- if (!validOpenUnicodeString(value, MAX_OPEN_METADATA_STRING_BYTES, true)) {
644
- throw new ProtocolV2Error("invalid OPEN metadata string");
645
- }
646
- return quoteCanonicalJSONString(value);
647
- }
648
- if (Array.isArray(value)) {
649
- const length = value.length;
650
- if (length > MAX_OPEN_METADATA_ARRAY)
651
- throw new ProtocolV2Error("OPEN metadata array is too large");
652
- const items = new Array(length);
653
- for (let index = 0; index < length; index++) {
654
- const item = value[index];
655
- items[index] = canonicalValidatedMetadataJSONString(item, depth + 1, state);
656
- }
657
- return `[${items.join(",")}]`;
658
- }
659
- if (!isJSONObject(value))
660
- throw new ProtocolV2Error("unsupported OPEN metadata value");
661
- const keys = Object.keys(value).sort();
662
- if (keys.length > MAX_OPEN_METADATA_KEYS)
663
- throw new ProtocolV2Error("OPEN metadata object is too large");
664
- const members = new Array(keys.length);
665
- let index = 0;
666
- for (const key of keys) {
667
- if (!validOpenUnicodeString(key, MAX_OPEN_METADATA_KEY_BYTES, false)) {
668
- throw new ProtocolV2Error("invalid OPEN metadata key");
669
- }
670
- const item = value[key];
671
- members[index++] = `${quoteCanonicalJSONString(key)}:${canonicalValidatedMetadataJSONString(item, depth + 1, state)}`;
672
- }
673
- return `{${members.join(",")}}`;
674
- }
675
- function quoteCanonicalJSONString(value) {
676
- return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
677
- }
678
- function validOpenUnicodeString(value, maxBytes, allowEmpty) {
679
- const bytes = encoder.encode(value);
680
- if (bytes.length > maxBytes ||
681
- (!allowEmpty && bytes.length === 0) ||
682
- value.normalize("NFC") !== value)
683
- return false;
684
- for (const scalar of value) {
685
- const codePoint = scalar.codePointAt(0);
686
- if ((codePoint >= 0xd800 && codePoint <= 0xdfff) ||
687
- codePoint <= 0x1f ||
688
- (codePoint >= 0x7f && codePoint <= 0x9f) ||
689
- !unicode15_1Assigned(codePoint)) {
690
- return false;
691
- }
692
- }
693
- return true;
694
- }
695
- function unicode15_1Assigned(codePoint) {
696
- let low = 0;
697
- let high = UNICODE_15_1_ASSIGNED_RANGES.length - 1;
698
- while (low <= high) {
699
- const middle = (low + high) >>> 1;
700
- const [start, end] = UNICODE_15_1_ASSIGNED_RANGES[middle];
701
- if (codePoint < start)
702
- high = middle - 1;
703
- else if (codePoint > end)
704
- low = middle + 1;
705
- else
706
- return true;
707
- }
708
- return false;
709
- }
710
- function decodeUnicodeRanges(value) {
711
- if (value.length % 12 !== 0)
712
- throw new Error("invalid committed Unicode range table");
713
- const ranges = [];
714
- for (let offset = 0; offset < value.length; offset += 12) {
715
- ranges.push([
716
- Number.parseInt(value.slice(offset, offset + 6), 16),
717
- Number.parseInt(value.slice(offset + 6, offset + 12), 16),
718
- ]);
719
- }
720
- return ranges;
721
- }
722
- function isUnicodeWhitespace(codePoint) {
723
- return ((codePoint >= 0x0009 && codePoint <= 0x000d) ||
724
- codePoint === 0x0020 ||
725
- codePoint === 0x0085 ||
726
- codePoint === 0x00a0 ||
727
- codePoint === 0x1680 ||
728
- (codePoint >= 0x2000 && codePoint <= 0x200a) ||
729
- codePoint === 0x2028 ||
730
- codePoint === 0x2029 ||
731
- codePoint === 0x202f ||
732
- codePoint === 0x205f ||
733
- codePoint === 0x3000);
734
- }
735
- function isJSONObject(value) {
736
- return typeof value === "object" && value !== null && !Array.isArray(value);
737
- }