@floegence/flowersec-core 3.2.1 → 4.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.
- package/README.md +57 -200
- package/THIRD_PARTY_NOTICES.md +11 -11
- package/dist/browser/index.d.ts +0 -5
- package/dist/browser/index.js +0 -3
- package/dist/cli.js +93 -64
- package/dist/facade.d.ts +0 -17
- package/dist/facade.js +0 -11
- package/dist/generated/unicode151.d.ts +2 -0
- package/dist/generated/unicode151.js +83 -0
- package/dist/interop/proxyServerPeer.js +34 -20
- package/dist/interop/serverParityPeer.js +11 -252
- package/dist/node/acceptor.d.ts +1 -57
- package/dist/node/acceptor.js +3 -420
- package/dist/node/acceptorV3.js +2 -2
- package/dist/node/connectSessionV3.js +2 -2
- package/dist/node/index.d.ts +2 -17
- package/dist/node/index.js +1 -9
- package/dist/node/nativeTransportAddon.d.ts +7 -36
- package/dist/node/nativeTransportAddon.js +7 -27
- package/dist/node/proxyServer.d.ts +2 -2
- package/dist/node/proxyServer.js +2 -2
- package/dist/node/rawQuicAdapterV3.d.ts +2 -2
- package/dist/node/rawQuicAdapterV3.js +1 -1
- package/dist/node/rawQuicServerV3.d.ts +2 -2
- package/dist/node/rawQuicServerV3.js +1 -1
- package/dist/node/rawQuicTls.d.ts +2 -0
- package/dist/node/{rawQuicAdapter.js → rawQuicTls.js} +30 -45
- package/dist/node/tunnelRuntimeV3.js +2 -2
- package/dist/proxy/integration.d.ts +5 -5
- package/dist/proxy/integration.js +2 -2
- package/dist/public/streamHandlers.d.ts +0 -3
- package/dist/public/streamHandlers.js +2 -4
- package/dist/public/streamMetadata.js +2 -2
- package/dist/runtime/errors.d.ts +2 -2
- package/dist/testSupport/tlsFixture.d.ts +2 -0
- package/dist/testSupport/tlsFixture.js +8 -0
- package/dist/utils/errors.d.ts +0 -2
- package/dist/utils/errors.js +0 -80
- package/dist/v3/artifact.js +17 -3
- package/dist/v3/carrier.d.ts +2 -2
- package/dist/v3/protocol.js +2 -103
- package/dist/v3/retryDisposition.d.ts +2 -2
- package/dist/v3/retryDisposition.js +0 -7
- package/dist/vendor/tr46.d.ts +4 -0
- package/dist/vendor/tr46.js +37 -32
- package/package.json +19 -17
- package/sbom/cyclonedx.json +62 -62
- package/sbom/spdx.json +65 -65
- package/dist/browser/connectSession.d.ts +0 -13
- package/dist/browser/connectSession.js +0 -40
- package/dist/browser/runtimeCapability.d.ts +0 -13
- package/dist/browser/runtimeCapability.js +0 -27
- package/dist/browser/sessionRuntime.d.ts +0 -2
- package/dist/browser/sessionRuntime.js +0 -21
- package/dist/browser/v2.d.ts +0 -3
- package/dist/browser/v2.js +0 -2
- package/dist/browser/webTransportClient.d.ts +0 -8
- package/dist/browser/webTransportClient.js +0 -55
- package/dist/connectionController.d.ts +0 -55
- package/dist/connectionController.js +0 -441
- package/dist/connector/adapters/rawQuicCandidate.d.ts +0 -5
- package/dist/connector/adapters/rawQuicCandidate.js +0 -71
- package/dist/connector/adapters/webSocketCandidate.d.ts +0 -7
- package/dist/connector/adapters/webSocketCandidate.js +0 -116
- package/dist/connector/adapters/webTransportCandidate.d.ts +0 -5
- package/dist/connector/adapters/webTransportCandidate.js +0 -73
- package/dist/connector/admissionCommit.d.ts +0 -31
- package/dist/connector/admissionCommit.js +0 -239
- package/dist/connector/sessionAcceptor.d.ts +0 -38
- package/dist/connector/sessionAcceptor.js +0 -158
- package/dist/connector/sessionConfig.d.ts +0 -3
- package/dist/connector/sessionConfig.js +0 -30
- package/dist/connector/sessionConnector.d.ts +0 -47
- package/dist/connector/sessionConnector.js +0 -606
- package/dist/node/connectSession.d.ts +0 -23
- package/dist/node/connectSession.js +0 -93
- package/dist/node/controlplane.d.ts +0 -137
- package/dist/node/controlplane.js +0 -443
- package/dist/node/rawQuicAdapter.d.ts +0 -9
- package/dist/node/rawQuicServer.d.ts +0 -24
- package/dist/node/rawQuicServer.js +0 -37
- package/dist/node/runtimeCapability.d.ts +0 -14
- package/dist/node/runtimeCapability.js +0 -24
- package/dist/node/sessionRuntime.d.ts +0 -2
- package/dist/node/sessionRuntime.js +0 -13
- package/dist/node/tunnelRuntime.d.ts +0 -42
- package/dist/node/tunnelRuntime.js +0 -559
- package/dist/node/v2.d.ts +0 -11
- package/dist/node/v2.js +0 -6
- package/dist/node/webSocketServer.d.ts +0 -24
- package/dist/node/webSocketServer.js +0 -135
- package/dist/public/artifact.d.ts +0 -11
- package/dist/public/artifact.js +0 -44
- package/dist/public/artifactLease.d.ts +0 -10
- package/dist/public/artifactLease.js +0 -41
- package/dist/public/connectError.d.ts +0 -6
- package/dist/public/connectError.js +0 -9
- package/dist/transport/webSocketAdapter.d.ts +0 -31
- package/dist/transport/webSocketAdapter.js +0 -370
- package/dist/transport/webTransportAdapter.d.ts +0 -27
- package/dist/transport/webTransportAdapter.js +0 -534
- package/dist/v2/admissionError.d.ts +0 -4
- package/dist/v2/admissionError.js +0 -8
- package/dist/v2/artifact.d.ts +0 -128
- package/dist/v2/artifact.js +0 -1131
- package/dist/v2/artifactLease.d.ts +0 -1
- package/dist/v2/artifactLease.js +0 -7
- package/dist/v2/capability.d.ts +0 -29
- package/dist/v2/capability.js +0 -190
- package/dist/v2/carrier.d.ts +0 -84
- package/dist/v2/carrier.js +0 -411
- package/dist/v2/contract.d.ts +0 -46
- package/dist/v2/contract.js +0 -1
- package/dist/v2/handshake.d.ts +0 -80
- package/dist/v2/handshake.js +0 -470
- package/dist/v2/index.d.ts +0 -14
- package/dist/v2/index.js +0 -7
- package/dist/v2/opaqueArtifact.d.ts +0 -1
- package/dist/v2/opaqueArtifact.js +0 -2
- package/dist/v2/protocol.d.ts +0 -99
- package/dist/v2/protocol.js +0 -737
- package/dist/v2/publicSession.d.ts +0 -1
- package/dist/v2/publicSession.js +0 -281
- package/dist/v2/retryDisposition.d.ts +0 -16
- package/dist/v2/retryDisposition.js +0 -30
- package/dist/v2/session.d.ts +0 -310
- package/dist/v2/session.js +0 -2127
- package/dist/v2/streamLifetimeLedger.d.ts +0 -31
- package/dist/v2/streamLifetimeLedger.js +0 -131
- package/dist/v2/streamMetadata.d.ts +0 -1
- package/dist/v2/streamMetadata.js +0 -7
- package/dist/v2/unreliableMessage.d.ts +0 -43
- package/dist/v2/unreliableMessage.js +0 -254
package/dist/v2/handshake.js
DELETED
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
import { x25519 } from "@noble/curves/ed25519.js";
|
|
2
|
-
import { p256 } from "@noble/curves/nist.js";
|
|
3
|
-
import { expand, extract } from "@noble/hashes/hkdf.js";
|
|
4
|
-
import { hmac } from "@noble/hashes/hmac.js";
|
|
5
|
-
import { sha256 } from "@noble/hashes/sha2.js";
|
|
6
|
-
import { base64urlDecode, base64urlEncode } from "../utils/base64url.js";
|
|
7
|
-
import { concatBytes, readU32be, u32be } from "../utils/bin.js";
|
|
8
|
-
import { CipherSuiteV2, ProtocolV2Error } from "./protocol.js";
|
|
9
|
-
const encoder = new TextEncoder();
|
|
10
|
-
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
11
|
-
const CONTROL_PREFACE_BYTES = 16;
|
|
12
|
-
const HANDSHAKE_HEADER_BYTES = 12;
|
|
13
|
-
const MAX_HANDSHAKE_PAYLOAD_BYTES = 8_192;
|
|
14
|
-
const registryIDPattern = /^[A-Za-z0-9._~-]+$/;
|
|
15
|
-
const KNOWN_FEATURES_V2 = 0x00000001;
|
|
16
|
-
export var HandshakeMessageTypeV2;
|
|
17
|
-
(function (HandshakeMessageTypeV2) {
|
|
18
|
-
HandshakeMessageTypeV2[HandshakeMessageTypeV2["ClientInit"] = 1] = "ClientInit";
|
|
19
|
-
HandshakeMessageTypeV2[HandshakeMessageTypeV2["ServerFinished"] = 2] = "ServerFinished";
|
|
20
|
-
HandshakeMessageTypeV2[HandshakeMessageTypeV2["ClientFinished"] = 3] = "ClientFinished";
|
|
21
|
-
})(HandshakeMessageTypeV2 || (HandshakeMessageTypeV2 = {}));
|
|
22
|
-
export function encodeControlPrefaceV2() {
|
|
23
|
-
const out = new Uint8Array(CONTROL_PREFACE_BYTES);
|
|
24
|
-
out.set(encoder.encode("FSC2"));
|
|
25
|
-
out[4] = 2;
|
|
26
|
-
out[5] = 1;
|
|
27
|
-
return out;
|
|
28
|
-
}
|
|
29
|
-
export function parseControlPrefaceV2(raw) {
|
|
30
|
-
if (raw.length !== CONTROL_PREFACE_BYTES ||
|
|
31
|
-
raw[0] !== 0x46 || raw[1] !== 0x53 || raw[2] !== 0x43 || raw[3] !== 0x32 ||
|
|
32
|
-
raw[4] !== 2 || raw[5] !== 1 || raw.subarray(6).some((value) => value !== 0)) {
|
|
33
|
-
throw new ProtocolV2Error("invalid FSC2 control preface");
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function encodeHandshakeFrameV2(type, payload) {
|
|
37
|
-
if (type < HandshakeMessageTypeV2.ClientInit ||
|
|
38
|
-
type > HandshakeMessageTypeV2.ClientFinished ||
|
|
39
|
-
payload.length < 1 ||
|
|
40
|
-
payload.length > MAX_HANDSHAKE_PAYLOAD_BYTES) {
|
|
41
|
-
throw new ProtocolV2Error("invalid FSH2 handshake frame");
|
|
42
|
-
}
|
|
43
|
-
const out = new Uint8Array(HANDSHAKE_HEADER_BYTES + payload.length);
|
|
44
|
-
out.set(encoder.encode("FSH2"));
|
|
45
|
-
out[4] = 2;
|
|
46
|
-
out[5] = type;
|
|
47
|
-
out.set(u32be(payload.length), 8);
|
|
48
|
-
out.set(payload, HANDSHAKE_HEADER_BYTES);
|
|
49
|
-
return out;
|
|
50
|
-
}
|
|
51
|
-
export function decodeHandshakeFrameV2(raw) {
|
|
52
|
-
if (raw.length < HANDSHAKE_HEADER_BYTES ||
|
|
53
|
-
raw[0] !== 0x46 || raw[1] !== 0x53 || raw[2] !== 0x48 || raw[3] !== 0x32 ||
|
|
54
|
-
raw[4] !== 2 || raw[6] !== 0 || raw[7] !== 0) {
|
|
55
|
-
throw new ProtocolV2Error("invalid FSH2 handshake frame");
|
|
56
|
-
}
|
|
57
|
-
const type = raw[5];
|
|
58
|
-
const length = readU32be(raw, 8);
|
|
59
|
-
if (type < HandshakeMessageTypeV2.ClientInit ||
|
|
60
|
-
type > HandshakeMessageTypeV2.ClientFinished ||
|
|
61
|
-
length < 1 || length > MAX_HANDSHAKE_PAYLOAD_BYTES ||
|
|
62
|
-
raw.length !== HANDSHAKE_HEADER_BYTES + length) {
|
|
63
|
-
throw new ProtocolV2Error("invalid FSH2 handshake frame");
|
|
64
|
-
}
|
|
65
|
-
const payload = raw.slice(HANDSHAKE_HEADER_BYTES);
|
|
66
|
-
try {
|
|
67
|
-
decoder.decode(payload);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
throw new ProtocolV2Error("invalid FSH2 UTF-8 payload");
|
|
71
|
-
}
|
|
72
|
-
return { type, payload, raw: raw.slice() };
|
|
73
|
-
}
|
|
74
|
-
export function encodeClientInitV2(message) {
|
|
75
|
-
validateClientInit(message);
|
|
76
|
-
return encodeCanonicalHandshake(HandshakeMessageTypeV2.ClientInit, {
|
|
77
|
-
channel_id: message.channelID,
|
|
78
|
-
client_admission_binding_b64u: encode32(message.clientAdmissionBinding),
|
|
79
|
-
client_endpoint_instance_id: message.clientEndpointInstanceID,
|
|
80
|
-
client_eph_pub_b64u: base64urlEncode(message.clientEphemeralPublic),
|
|
81
|
-
client_role: message.clientRole,
|
|
82
|
-
max_inbound_streams: message.maxInboundStreams,
|
|
83
|
-
nonce_c_b64u: encode32(message.nonceC),
|
|
84
|
-
profile: message.profile,
|
|
85
|
-
selected_features: message.selectedFeatures,
|
|
86
|
-
session_contract_hash_b64u: encode32(message.sessionContractHash),
|
|
87
|
-
suite: message.suite,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
export function decodeClientInitV2(raw) {
|
|
91
|
-
const value = decodeCanonicalObject(raw, HandshakeMessageTypeV2.ClientInit, [
|
|
92
|
-
"channel_id", "client_admission_binding_b64u", "client_endpoint_instance_id", "client_eph_pub_b64u",
|
|
93
|
-
"client_role", "max_inbound_streams", "nonce_c_b64u", "profile", "selected_features",
|
|
94
|
-
"session_contract_hash_b64u", "suite",
|
|
95
|
-
]);
|
|
96
|
-
const message = {
|
|
97
|
-
profile: requireString(value.profile),
|
|
98
|
-
channelID: requireString(value.channel_id),
|
|
99
|
-
sessionContractHash: decode32(value.session_contract_hash_b64u),
|
|
100
|
-
clientRole: requireInteger(value.client_role, 1),
|
|
101
|
-
suite: requireSuite(value.suite),
|
|
102
|
-
clientEphemeralPublic: decodeBase64(value.client_eph_pub_b64u),
|
|
103
|
-
nonceC: decode32(value.nonce_c_b64u),
|
|
104
|
-
selectedFeatures: requireInteger(value.selected_features, 0xffffffff),
|
|
105
|
-
maxInboundStreams: requireInteger(value.max_inbound_streams, 0xffff),
|
|
106
|
-
clientAdmissionBinding: decode32(value.client_admission_binding_b64u),
|
|
107
|
-
clientEndpointInstanceID: requireString(value.client_endpoint_instance_id),
|
|
108
|
-
};
|
|
109
|
-
validateClientInit(message);
|
|
110
|
-
requireCanonical(raw, encodeClientInitV2(message));
|
|
111
|
-
return message;
|
|
112
|
-
}
|
|
113
|
-
export function encodeServerFinishedCoreV2(core, suite) {
|
|
114
|
-
const normalized = { ...core, suite };
|
|
115
|
-
validateServerCore(normalized);
|
|
116
|
-
return encodeCanonicalHandshake(HandshakeMessageTypeV2.ServerFinished, serverCoreWire(normalized));
|
|
117
|
-
}
|
|
118
|
-
export function encodeServerFinishedV2(message, suite) {
|
|
119
|
-
const core = { ...message.core, suite };
|
|
120
|
-
validateServerCore(core);
|
|
121
|
-
assertBytes("server confirm", message.serverConfirm, 32);
|
|
122
|
-
return encodeCanonicalHandshake(HandshakeMessageTypeV2.ServerFinished, {
|
|
123
|
-
handshake_id: base64urlEncode(core.handshakeID),
|
|
124
|
-
max_inbound_streams: core.maxInboundStreams,
|
|
125
|
-
nonce_s_b64u: encode32(core.nonceS),
|
|
126
|
-
selected_features: core.selectedFeatures,
|
|
127
|
-
server_admission_binding_b64u: encode32(core.serverAdmissionBinding),
|
|
128
|
-
server_confirm_b64u: encode32(message.serverConfirm),
|
|
129
|
-
server_endpoint_instance_id: core.serverEndpointInstanceID,
|
|
130
|
-
server_eph_pub_b64u: base64urlEncode(core.serverEphemeralPublic),
|
|
131
|
-
session_contract_hash_b64u: encode32(core.sessionContractHash),
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
export function decodeServerFinishedV2(raw, suite) {
|
|
135
|
-
const value = decodeCanonicalObject(raw, HandshakeMessageTypeV2.ServerFinished, [
|
|
136
|
-
"handshake_id", "max_inbound_streams", "nonce_s_b64u", "selected_features",
|
|
137
|
-
"server_admission_binding_b64u", "server_confirm_b64u", "server_endpoint_instance_id",
|
|
138
|
-
"server_eph_pub_b64u", "session_contract_hash_b64u",
|
|
139
|
-
]);
|
|
140
|
-
const core = {
|
|
141
|
-
suite,
|
|
142
|
-
handshakeID: decodeBase64(value.handshake_id),
|
|
143
|
-
serverEphemeralPublic: decodeBase64(value.server_eph_pub_b64u),
|
|
144
|
-
nonceS: decode32(value.nonce_s_b64u),
|
|
145
|
-
sessionContractHash: decode32(value.session_contract_hash_b64u),
|
|
146
|
-
selectedFeatures: requireInteger(value.selected_features, 0xffffffff),
|
|
147
|
-
maxInboundStreams: requireInteger(value.max_inbound_streams, 0xffff),
|
|
148
|
-
serverAdmissionBinding: decode32(value.server_admission_binding_b64u),
|
|
149
|
-
serverEndpointInstanceID: requireString(value.server_endpoint_instance_id),
|
|
150
|
-
};
|
|
151
|
-
const message = { core, serverConfirm: decode32(value.server_confirm_b64u) };
|
|
152
|
-
validateServerCore(core);
|
|
153
|
-
requireCanonical(raw, encodeServerFinishedV2(message, suite));
|
|
154
|
-
return message;
|
|
155
|
-
}
|
|
156
|
-
export function encodeClientFinishedCoreV2(handshakeID) {
|
|
157
|
-
validateHandshakeID(handshakeID);
|
|
158
|
-
return encodeCanonicalHandshake(HandshakeMessageTypeV2.ClientFinished, {
|
|
159
|
-
handshake_id: base64urlEncode(handshakeID),
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
export function encodeClientFinishedV2(message) {
|
|
163
|
-
validateHandshakeID(message.handshakeID);
|
|
164
|
-
assertBytes("client confirm", message.clientConfirm, 32);
|
|
165
|
-
return encodeCanonicalHandshake(HandshakeMessageTypeV2.ClientFinished, {
|
|
166
|
-
client_confirm_b64u: encode32(message.clientConfirm),
|
|
167
|
-
handshake_id: base64urlEncode(message.handshakeID),
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
export function decodeClientFinishedV2(raw) {
|
|
171
|
-
const value = decodeCanonicalObject(raw, HandshakeMessageTypeV2.ClientFinished, [
|
|
172
|
-
"client_confirm_b64u", "handshake_id",
|
|
173
|
-
]);
|
|
174
|
-
const message = {
|
|
175
|
-
handshakeID: decodeBase64(value.handshake_id),
|
|
176
|
-
clientConfirm: decode32(value.client_confirm_b64u),
|
|
177
|
-
};
|
|
178
|
-
validateHandshakeID(message.handshakeID);
|
|
179
|
-
requireCanonical(raw, encodeClientFinishedV2(message));
|
|
180
|
-
return message;
|
|
181
|
-
}
|
|
182
|
-
export function generateEphemeralKeyV2(suite, entropy) {
|
|
183
|
-
let privateKey;
|
|
184
|
-
if (suite === CipherSuiteV2.ChaCha20Poly1305) {
|
|
185
|
-
privateKey = requireEntropy(entropy, 32);
|
|
186
|
-
}
|
|
187
|
-
else if (suite === CipherSuiteV2.AES256GCM) {
|
|
188
|
-
do
|
|
189
|
-
privateKey = requireEntropy(entropy, 32);
|
|
190
|
-
while (!p256.utils.isValidSecretKey(privateKey));
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
return invalidSuite();
|
|
194
|
-
}
|
|
195
|
-
return { privateKey, publicKey: ephemeralPublicKeyV2(suite, privateKey) };
|
|
196
|
-
}
|
|
197
|
-
function requireEntropy(entropy, length) {
|
|
198
|
-
const output = entropy(length);
|
|
199
|
-
assertBytes("session entropy", output, length);
|
|
200
|
-
return output.slice();
|
|
201
|
-
}
|
|
202
|
-
export function ephemeralPublicKeyV2(suite, privateKey) {
|
|
203
|
-
assertBytes("ephemeral private key", privateKey, 32);
|
|
204
|
-
try {
|
|
205
|
-
if (suite === CipherSuiteV2.ChaCha20Poly1305)
|
|
206
|
-
return x25519.getPublicKey(privateKey);
|
|
207
|
-
if (suite === CipherSuiteV2.AES256GCM)
|
|
208
|
-
return p256.getPublicKey(privateKey, false);
|
|
209
|
-
}
|
|
210
|
-
catch {
|
|
211
|
-
throw new ProtocolV2Error("invalid v2 ephemeral private key");
|
|
212
|
-
}
|
|
213
|
-
return invalidSuite();
|
|
214
|
-
}
|
|
215
|
-
export function computeSharedSecretV2(suite, privateKey, peerPublicKey) {
|
|
216
|
-
assertBytes("ephemeral private key", privateKey, 32);
|
|
217
|
-
validateEphemeralPublic(suite, peerPublicKey);
|
|
218
|
-
let shared;
|
|
219
|
-
try {
|
|
220
|
-
if (suite === CipherSuiteV2.ChaCha20Poly1305) {
|
|
221
|
-
shared = x25519.getSharedSecret(privateKey, peerPublicKey);
|
|
222
|
-
}
|
|
223
|
-
else if (suite === CipherSuiteV2.AES256GCM) {
|
|
224
|
-
const point = p256.getSharedSecret(privateKey, peerPublicKey, false);
|
|
225
|
-
if (point.length !== 65 || point[0] !== 4)
|
|
226
|
-
throw new Error("invalid P-256 point");
|
|
227
|
-
shared = point.slice(1, 33);
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
return invalidSuite();
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
catch {
|
|
234
|
-
throw new ProtocolV2Error("invalid v2 ECDH shared secret");
|
|
235
|
-
}
|
|
236
|
-
if (shared.length !== 32 || shared.every((value) => value === 0)) {
|
|
237
|
-
throw new ProtocolV2Error("invalid v2 ECDH shared secret");
|
|
238
|
-
}
|
|
239
|
-
return shared;
|
|
240
|
-
}
|
|
241
|
-
export function deriveHandshakePRKV2(psk, sharedSecret) {
|
|
242
|
-
assertBytes("handshake PSK", psk, 32);
|
|
243
|
-
assertBytes("ECDH shared secret", sharedSecret, 32);
|
|
244
|
-
if (sharedSecret.every((value) => value === 0))
|
|
245
|
-
throw new ProtocolV2Error("invalid v2 ECDH shared secret");
|
|
246
|
-
return extract(sha256, sharedSecret, psk);
|
|
247
|
-
}
|
|
248
|
-
export function computeHandshakeH0V2(fsc2Raw, clientInitRaw) {
|
|
249
|
-
parseControlPrefaceV2(fsc2Raw);
|
|
250
|
-
decodeClientInitV2(clientInitRaw);
|
|
251
|
-
return sha256(concatBytes([
|
|
252
|
-
encoder.encode("flowersec-v2-handshake\0"),
|
|
253
|
-
fsc2Raw,
|
|
254
|
-
lengthPrefixed(clientInitRaw),
|
|
255
|
-
]));
|
|
256
|
-
}
|
|
257
|
-
export function computeHandshakeH1V2(h0, serverCoreRaw) {
|
|
258
|
-
assertBytes("H0", h0, 32);
|
|
259
|
-
const frame = decodeHandshakeFrameV2(serverCoreRaw);
|
|
260
|
-
if (frame.type !== HandshakeMessageTypeV2.ServerFinished)
|
|
261
|
-
throw new ProtocolV2Error("invalid v2 transcript");
|
|
262
|
-
return sha256(concatBytes([h0, lengthPrefixed(serverCoreRaw)]));
|
|
263
|
-
}
|
|
264
|
-
export function computeServerConfirmV2(handshakePRK, h1) {
|
|
265
|
-
return computeConfirm(handshakePRK, h1, "flowersec v2 server finished");
|
|
266
|
-
}
|
|
267
|
-
export function computeHandshakeH2V2(h1, serverFinishedRaw, clientCoreRaw) {
|
|
268
|
-
assertBytes("H1", h1, 32);
|
|
269
|
-
if (decodeHandshakeFrameV2(serverFinishedRaw).type !== HandshakeMessageTypeV2.ServerFinished ||
|
|
270
|
-
decodeHandshakeFrameV2(clientCoreRaw).type !== HandshakeMessageTypeV2.ClientFinished) {
|
|
271
|
-
throw new ProtocolV2Error("invalid v2 transcript");
|
|
272
|
-
}
|
|
273
|
-
return sha256(concatBytes([h1, lengthPrefixed(serverFinishedRaw), lengthPrefixed(clientCoreRaw)]));
|
|
274
|
-
}
|
|
275
|
-
export function computeClientConfirmV2(handshakePRK, h2) {
|
|
276
|
-
return computeConfirm(handshakePRK, h2, "flowersec v2 client finished");
|
|
277
|
-
}
|
|
278
|
-
export function computeHandshakeH3V2(h2, clientFinishedRaw) {
|
|
279
|
-
assertBytes("H2", h2, 32);
|
|
280
|
-
decodeClientFinishedV2(clientFinishedRaw);
|
|
281
|
-
return sha256(concatBytes([h2, lengthPrefixed(clientFinishedRaw)]));
|
|
282
|
-
}
|
|
283
|
-
export function deriveSessionPRKV2(h3, handshakePRK) {
|
|
284
|
-
assertBytes("H3", h3, 32);
|
|
285
|
-
assertBytes("handshake PRK", handshakePRK, 32);
|
|
286
|
-
return extract(sha256, handshakePRK, h3);
|
|
287
|
-
}
|
|
288
|
-
export function validateClientInitV2(message, expected) {
|
|
289
|
-
validateClientInit(message);
|
|
290
|
-
if (message.channelID !== expected.channelID ||
|
|
291
|
-
message.suite !== expected.suite ||
|
|
292
|
-
message.maxInboundStreams !== expected.maxInboundStreams ||
|
|
293
|
-
!bytesEqual(message.sessionContractHash, expected.sessionContractHash) ||
|
|
294
|
-
!validAdmissionBinding(expected.path, message.clientAdmissionBinding, expected.admissionBinding) ||
|
|
295
|
-
!validExpectedEndpoint(expected.path, message.clientEndpointInstanceID, expected.expectedEndpointInstanceID)) {
|
|
296
|
-
throw new ProtocolV2Error("v2 handshake binding mismatch");
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
export function validateServerFinishedV2(message, expected) {
|
|
300
|
-
validateServerCore(message.core);
|
|
301
|
-
if (message.core.suite !== expected.suite ||
|
|
302
|
-
message.core.maxInboundStreams !== expected.maxInboundStreams ||
|
|
303
|
-
!bytesEqual(message.core.sessionContractHash, expected.sessionContractHash) ||
|
|
304
|
-
!validAdmissionBinding(expected.path, message.core.serverAdmissionBinding, expected.admissionBinding) ||
|
|
305
|
-
!validExpectedEndpoint(expected.path, message.core.serverEndpointInstanceID, expected.expectedEndpointInstanceID)) {
|
|
306
|
-
throw new ProtocolV2Error("v2 handshake binding mismatch");
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
function serverCoreWire(core) {
|
|
310
|
-
return {
|
|
311
|
-
handshake_id: base64urlEncode(core.handshakeID),
|
|
312
|
-
max_inbound_streams: core.maxInboundStreams,
|
|
313
|
-
nonce_s_b64u: encode32(core.nonceS),
|
|
314
|
-
selected_features: core.selectedFeatures,
|
|
315
|
-
server_admission_binding_b64u: encode32(core.serverAdmissionBinding),
|
|
316
|
-
server_endpoint_instance_id: core.serverEndpointInstanceID,
|
|
317
|
-
server_eph_pub_b64u: base64urlEncode(core.serverEphemeralPublic),
|
|
318
|
-
session_contract_hash_b64u: encode32(core.sessionContractHash),
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
function validateClientInit(message) {
|
|
322
|
-
if (message.profile !== "flowersec/2" ||
|
|
323
|
-
!validRegistryID(message.channelID, false) ||
|
|
324
|
-
message.clientRole !== 1 ||
|
|
325
|
-
(message.selectedFeatures & ~KNOWN_FEATURES_V2) !== 0 ||
|
|
326
|
-
message.maxInboundStreams < 1 || message.maxInboundStreams > 128 ||
|
|
327
|
-
!validRegistryID(message.clientEndpointInstanceID, true)) {
|
|
328
|
-
throw new ProtocolV2Error("invalid v2 client init");
|
|
329
|
-
}
|
|
330
|
-
assertBytes("session contract hash", message.sessionContractHash, 32);
|
|
331
|
-
assertBytes("client nonce", message.nonceC, 32);
|
|
332
|
-
assertBytes("client admission binding", message.clientAdmissionBinding, 32);
|
|
333
|
-
validateEphemeralPublic(message.suite, message.clientEphemeralPublic);
|
|
334
|
-
}
|
|
335
|
-
function validateServerCore(core) {
|
|
336
|
-
validateHandshakeID(core.handshakeID);
|
|
337
|
-
if ((core.selectedFeatures & ~KNOWN_FEATURES_V2) !== 0 ||
|
|
338
|
-
core.maxInboundStreams < 1 || core.maxInboundStreams > 128 ||
|
|
339
|
-
!validRegistryID(core.serverEndpointInstanceID, true)) {
|
|
340
|
-
throw new ProtocolV2Error("invalid v2 server finished");
|
|
341
|
-
}
|
|
342
|
-
assertBytes("session contract hash", core.sessionContractHash, 32);
|
|
343
|
-
assertBytes("server nonce", core.nonceS, 32);
|
|
344
|
-
assertBytes("server admission binding", core.serverAdmissionBinding, 32);
|
|
345
|
-
validateEphemeralPublic(core.suite, core.serverEphemeralPublic);
|
|
346
|
-
}
|
|
347
|
-
function validateEphemeralPublic(suite, value) {
|
|
348
|
-
try {
|
|
349
|
-
if (suite === CipherSuiteV2.ChaCha20Poly1305) {
|
|
350
|
-
assertBytes("X25519 public key", value, 32);
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
if (suite === CipherSuiteV2.AES256GCM) {
|
|
354
|
-
if (value.length !== 65 || value[0] !== 4)
|
|
355
|
-
throw new Error("invalid P-256 public key");
|
|
356
|
-
p256.Point.fromBytes(value);
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
catch {
|
|
361
|
-
throw new ProtocolV2Error("invalid v2 ephemeral public key");
|
|
362
|
-
}
|
|
363
|
-
invalidSuite();
|
|
364
|
-
}
|
|
365
|
-
function encodeCanonicalHandshake(type, value) {
|
|
366
|
-
return encodeHandshakeFrameV2(type, encoder.encode(JSON.stringify(value)));
|
|
367
|
-
}
|
|
368
|
-
function decodeCanonicalObject(raw, type, fields) {
|
|
369
|
-
const frame = decodeHandshakeFrameV2(raw);
|
|
370
|
-
if (frame.type !== type)
|
|
371
|
-
throw new ProtocolV2Error("unexpected FSH2 message type");
|
|
372
|
-
let value;
|
|
373
|
-
try {
|
|
374
|
-
value = JSON.parse(decoder.decode(frame.payload));
|
|
375
|
-
}
|
|
376
|
-
catch {
|
|
377
|
-
throw new ProtocolV2Error("invalid FSH2 JSON payload");
|
|
378
|
-
}
|
|
379
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
380
|
-
throw new ProtocolV2Error("invalid FSH2 JSON object");
|
|
381
|
-
}
|
|
382
|
-
const object = value;
|
|
383
|
-
const keys = Object.keys(object);
|
|
384
|
-
if (keys.length !== fields.length || fields.some((field) => !Object.hasOwn(object, field))) {
|
|
385
|
-
throw new ProtocolV2Error("invalid FSH2 JSON fields");
|
|
386
|
-
}
|
|
387
|
-
return object;
|
|
388
|
-
}
|
|
389
|
-
function requireCanonical(actual, canonical) {
|
|
390
|
-
if (!bytesEqual(actual, canonical))
|
|
391
|
-
throw new ProtocolV2Error("non-canonical FSH2 message");
|
|
392
|
-
}
|
|
393
|
-
function requireString(value) {
|
|
394
|
-
if (typeof value !== "string")
|
|
395
|
-
throw new ProtocolV2Error("invalid FSH2 string");
|
|
396
|
-
return value;
|
|
397
|
-
}
|
|
398
|
-
function requireInteger(value, max) {
|
|
399
|
-
if (!Number.isInteger(value) || value < 0 || value > max) {
|
|
400
|
-
throw new ProtocolV2Error("invalid FSH2 integer");
|
|
401
|
-
}
|
|
402
|
-
return value;
|
|
403
|
-
}
|
|
404
|
-
function requireSuite(value) {
|
|
405
|
-
if (value !== CipherSuiteV2.ChaCha20Poly1305 && value !== CipherSuiteV2.AES256GCM)
|
|
406
|
-
return invalidSuite();
|
|
407
|
-
return value;
|
|
408
|
-
}
|
|
409
|
-
function decodeBase64(value) {
|
|
410
|
-
const text = requireString(value);
|
|
411
|
-
try {
|
|
412
|
-
return base64urlDecode(text);
|
|
413
|
-
}
|
|
414
|
-
catch {
|
|
415
|
-
throw new ProtocolV2Error("invalid FSH2 base64url");
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
function decode32(value) {
|
|
419
|
-
const decoded = decodeBase64(value);
|
|
420
|
-
assertBytes("FSH2 field", decoded, 32);
|
|
421
|
-
return decoded;
|
|
422
|
-
}
|
|
423
|
-
function encode32(value) {
|
|
424
|
-
assertBytes("FSH2 field", value, 32);
|
|
425
|
-
return base64urlEncode(value);
|
|
426
|
-
}
|
|
427
|
-
function validateHandshakeID(value) {
|
|
428
|
-
if (value.length < 16 || value.length > 32)
|
|
429
|
-
throw new ProtocolV2Error("invalid v2 handshake ID");
|
|
430
|
-
}
|
|
431
|
-
function computeConfirm(handshakePRK, transcript, label) {
|
|
432
|
-
assertBytes("handshake PRK", handshakePRK, 32);
|
|
433
|
-
assertBytes("handshake transcript", transcript, 32);
|
|
434
|
-
const key = expand(sha256, handshakePRK, concatBytes([encoder.encode(label), transcript]), 32);
|
|
435
|
-
return hmac(sha256, key, transcript);
|
|
436
|
-
}
|
|
437
|
-
function lengthPrefixed(raw) {
|
|
438
|
-
return concatBytes([u32be(raw.length), raw]);
|
|
439
|
-
}
|
|
440
|
-
function validRegistryID(value, allowEmpty) {
|
|
441
|
-
return (allowEmpty && value === "") || (value.length >= 1 && value.length <= 128 && registryIDPattern.test(value));
|
|
442
|
-
}
|
|
443
|
-
function validAdmissionBinding(path, actual, expected) {
|
|
444
|
-
assertBytes("actual admission binding", actual, 32);
|
|
445
|
-
assertBytes("expected admission binding", expected, 32);
|
|
446
|
-
if (path === "direct" || !expected.every((value) => value === 0))
|
|
447
|
-
return bytesEqual(actual, expected);
|
|
448
|
-
return !actual.every((value) => value === 0);
|
|
449
|
-
}
|
|
450
|
-
function validExpectedEndpoint(path, actual, expected) {
|
|
451
|
-
if (path === "direct")
|
|
452
|
-
return actual === "" && expected === "";
|
|
453
|
-
return validRegistryID(actual, false) && validRegistryID(expected, false) && actual === expected;
|
|
454
|
-
}
|
|
455
|
-
function bytesEqual(left, right) {
|
|
456
|
-
if (left.length !== right.length)
|
|
457
|
-
return false;
|
|
458
|
-
let difference = 0;
|
|
459
|
-
for (let index = 0; index < left.length; index++)
|
|
460
|
-
difference |= left[index] ^ right[index];
|
|
461
|
-
return difference === 0;
|
|
462
|
-
}
|
|
463
|
-
function assertBytes(name, value, length) {
|
|
464
|
-
if (!(value instanceof Uint8Array) || value.length !== length) {
|
|
465
|
-
throw new ProtocolV2Error(`${name} must be ${length} bytes`);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
function invalidSuite() {
|
|
469
|
-
throw new ProtocolV2Error("invalid v2 cipher suite");
|
|
470
|
-
}
|
package/dist/v2/index.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export type { ByteStream, IncomingStream, JsonObject, JsonPrimitive, JsonValue, OperationOptions, RpcPeer, RpcResult, SessionErrorCode, StreamOpenOptions, UnreliableMessageChannel, UnreliableMessageSendOptions, UnreliableMessageSendResult, SessionTermination, Session, } from "../public/contract.js";
|
|
2
|
-
export { SessionError, UnreliableMessageError } from "../public/contract.js";
|
|
3
|
-
export { createStreamMetadata, StreamMetadataError } from "../public/streamMetadata.js";
|
|
4
|
-
export type { StreamMetadata } from "../public/streamMetadata.js";
|
|
5
|
-
export { HandlerRegistrationError, LegacyStreamHandlers as StreamHandlers, } from "../public/streamHandlers.js";
|
|
6
|
-
export type { StreamHandler, StreamHandlerOptions, } from "../public/streamHandlers.js";
|
|
7
|
-
export { ArtifactLeaseError, createArtifactLease, } from "../public/artifactLease.js";
|
|
8
|
-
export type { ArtifactLease } from "../public/artifactLease.js";
|
|
9
|
-
export { Artifact, ArtifactError, parseArtifact } from "../public/artifact.js";
|
|
10
|
-
export type { ArtifactErrorCode } from "../public/artifact.js";
|
|
11
|
-
export type { ConnectErrorCode } from "../public/connectError.js";
|
|
12
|
-
export { ConnectError } from "../public/connectError.js";
|
|
13
|
-
export { ConnectionControllerError } from "../connectionController.js";
|
|
14
|
-
export type { ArtifactSource, ArtifactSourceResult, ConnectionController, ConnectionControllerFailure, ConnectionControllerOptions, ConnectionSnapshot, ConnectionState, RetryDisposition, } from "../connectionController.js";
|
package/dist/v2/index.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export { SessionError, UnreliableMessageError } from "../public/contract.js";
|
|
2
|
-
export { createStreamMetadata, StreamMetadataError } from "../public/streamMetadata.js";
|
|
3
|
-
export { HandlerRegistrationError, LegacyStreamHandlers as StreamHandlers, } from "../public/streamHandlers.js";
|
|
4
|
-
export { ArtifactLeaseError, createArtifactLease, } from "../public/artifactLease.js";
|
|
5
|
-
export { Artifact, ArtifactError, parseArtifact } from "../public/artifact.js";
|
|
6
|
-
export { ConnectError } from "../public/connectError.js";
|
|
7
|
-
export { ConnectionControllerError } from "../connectionController.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/v2/protocol.d.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
export declare class ProtocolV2Error extends Error {
|
|
2
|
-
}
|
|
3
|
-
export declare enum DirectionV2 {
|
|
4
|
-
ClientToServer = 1,
|
|
5
|
-
ServerToClient = 2
|
|
6
|
-
}
|
|
7
|
-
export declare enum CipherSuiteV2 {
|
|
8
|
-
ChaCha20Poly1305 = 1,
|
|
9
|
-
AES256GCM = 2
|
|
10
|
-
}
|
|
11
|
-
export type EpochRootsV2 = Readonly<{
|
|
12
|
-
epochSecret: Uint8Array;
|
|
13
|
-
controlRoot: Uint8Array;
|
|
14
|
-
streamRoot: Uint8Array;
|
|
15
|
-
setupRoot: Uint8Array;
|
|
16
|
-
rekeyRoot: Uint8Array;
|
|
17
|
-
}>;
|
|
18
|
-
export type RecordMaterialV2 = Readonly<{
|
|
19
|
-
secret: Uint8Array;
|
|
20
|
-
recordKey: Uint8Array;
|
|
21
|
-
noncePrefix: Uint8Array;
|
|
22
|
-
}>;
|
|
23
|
-
export type SetupPrefaceV2 = Readonly<{
|
|
24
|
-
openerRole: 1 | 2;
|
|
25
|
-
logicalStreamID: bigint;
|
|
26
|
-
initialSendEpoch: number;
|
|
27
|
-
setupMAC: Uint8Array;
|
|
28
|
-
}>;
|
|
29
|
-
export type RecordHeaderV2 = Readonly<{
|
|
30
|
-
epoch: number;
|
|
31
|
-
sequence: bigint;
|
|
32
|
-
ciphertextLength: number;
|
|
33
|
-
}>;
|
|
34
|
-
export type OpenPayloadV2 = Readonly<{
|
|
35
|
-
logicalStreamID: bigint;
|
|
36
|
-
fss2Hash: Uint8Array;
|
|
37
|
-
kind: string;
|
|
38
|
-
metadata: Uint8Array;
|
|
39
|
-
}>;
|
|
40
|
-
export declare enum InnerTypeV2 {
|
|
41
|
-
Open = 1,
|
|
42
|
-
OpenACK = 2,
|
|
43
|
-
OpenReject = 3,
|
|
44
|
-
Data = 4,
|
|
45
|
-
FIN = 5,
|
|
46
|
-
StreamKeyUpdate = 6,
|
|
47
|
-
SessionReady = 16,
|
|
48
|
-
Ping = 17,
|
|
49
|
-
Pong = 18,
|
|
50
|
-
SessionKeyUpdate = 19,
|
|
51
|
-
StreamReset = 20,
|
|
52
|
-
GoAway = 21,
|
|
53
|
-
SessionClose = 22,
|
|
54
|
-
SessionReadyACK = 23,
|
|
55
|
-
SessionKeyUpdateACK = 24,
|
|
56
|
-
StreamKeyUpdateACK = 25,
|
|
57
|
-
SessionReadyConfirm = 26
|
|
58
|
-
}
|
|
59
|
-
export type InnerRecordV2 = Readonly<{
|
|
60
|
-
type: InnerTypeV2;
|
|
61
|
-
payload: Uint8Array;
|
|
62
|
-
}>;
|
|
63
|
-
export type OpenRejectV2 = Readonly<{
|
|
64
|
-
openHash: Uint8Array;
|
|
65
|
-
reason: number;
|
|
66
|
-
knownReason: boolean;
|
|
67
|
-
}>;
|
|
68
|
-
export type StreamKeyUpdateACKV2 = Readonly<{
|
|
69
|
-
logicalStreamID: bigint;
|
|
70
|
-
transition: bigint;
|
|
71
|
-
epoch: number;
|
|
72
|
-
}>;
|
|
73
|
-
export declare function deriveEpochZero(sessionPRK: Uint8Array, direction: DirectionV2): EpochRootsV2;
|
|
74
|
-
export declare function deriveEpochRoots(epochSecret: Uint8Array): EpochRootsV2;
|
|
75
|
-
export declare function deriveNextEpoch(rekeyRoot: Uint8Array, h3: Uint8Array, direction: DirectionV2, nextEpoch: number): Uint8Array;
|
|
76
|
-
export declare function deriveStreamMaterial(streamRoot: Uint8Array, h3: Uint8Array, logicalStreamID: bigint, direction: DirectionV2, epoch: number): RecordMaterialV2;
|
|
77
|
-
export declare function deriveControlMaterial(controlRoot: Uint8Array, h3: Uint8Array, direction: DirectionV2, epoch: number): RecordMaterialV2;
|
|
78
|
-
export declare function computeSetupMAC(setupRoot: Uint8Array, h3: Uint8Array, preface: SetupPrefaceV2): Uint8Array;
|
|
79
|
-
export declare function encodeSetupPreface(preface: SetupPrefaceV2): Uint8Array;
|
|
80
|
-
export declare function decodeSetupPrefaceV2(raw: Uint8Array): SetupPrefaceV2;
|
|
81
|
-
export declare function verifySetupMAC(setupRoot: Uint8Array, h3: Uint8Array, preface: SetupPrefaceV2): boolean;
|
|
82
|
-
export declare function computeFSS2HashV2(raw: Uint8Array): Uint8Array;
|
|
83
|
-
export declare function encodeRecordHeader(header: RecordHeaderV2): Uint8Array;
|
|
84
|
-
export declare function decodeRecordHeader(raw: Uint8Array): RecordHeaderV2;
|
|
85
|
-
export declare function buildDataInner(payload: Uint8Array): Uint8Array;
|
|
86
|
-
export declare function encodeInnerRecordV2(type: InnerTypeV2, payload: Uint8Array): Uint8Array;
|
|
87
|
-
export declare function decodeInnerRecordV2(raw: Uint8Array): InnerRecordV2;
|
|
88
|
-
export declare function encodeOpenPayload(payload: OpenPayloadV2): Uint8Array;
|
|
89
|
-
export declare function decodeOpenPayload(raw: Uint8Array): OpenPayloadV2;
|
|
90
|
-
export declare function computeOpenHashV2(rawOpenPayload: Uint8Array): Uint8Array;
|
|
91
|
-
export declare function encodeOpenACKV2(openHash: Uint8Array): Uint8Array;
|
|
92
|
-
export declare function decodeOpenACKV2(raw: Uint8Array): Uint8Array;
|
|
93
|
-
export declare function encodeOpenRejectV2(openHash: Uint8Array, reason: number): Uint8Array;
|
|
94
|
-
export declare function decodeOpenRejectV2(raw: Uint8Array): OpenRejectV2;
|
|
95
|
-
export declare function encodeStreamKeyUpdateACKV2(value: StreamKeyUpdateACKV2): Uint8Array;
|
|
96
|
-
export declare function decodeStreamKeyUpdateACKV2(raw: Uint8Array): StreamKeyUpdateACKV2;
|
|
97
|
-
export declare function buildRecordAAD(h3: Uint8Array, logicalStreamID: bigint, direction: DirectionV2, rawHeader: Uint8Array): Uint8Array;
|
|
98
|
-
export declare function sealRecord(suite: CipherSuiteV2, material: RecordMaterialV2, h3: Uint8Array, logicalStreamID: bigint, direction: DirectionV2, header: RecordHeaderV2, plaintext: Uint8Array): Uint8Array;
|
|
99
|
-
export declare function openRecord(suite: CipherSuiteV2, material: RecordMaterialV2, h3: Uint8Array, logicalStreamID: bigint, direction: DirectionV2, header: RecordHeaderV2, ciphertext: Uint8Array): Uint8Array;
|