@reclaimprotocol/attestor-core 5.0.1-beta.2 → 5.0.1-beta.22
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/browser/resources/attestor-browser.min.mjs +4512 -0
- package/lib/avs/abis/avsDirectoryABI.js +338 -341
- package/lib/avs/abis/delegationABI.js +1 -4
- package/lib/avs/abis/registryABI.js +719 -722
- package/lib/avs/client/create-claim-on-avs.js +129 -157
- package/lib/avs/config.js +18 -24
- package/lib/avs/contracts/ReclaimServiceManager.js +1 -0
- package/lib/avs/contracts/common.js +1 -0
- package/lib/avs/contracts/factories/ReclaimServiceManager__factory.js +1139 -1156
- package/lib/avs/contracts/factories/index.js +4 -4
- package/lib/avs/contracts/index.js +2 -6
- package/lib/avs/types/index.js +1 -0
- package/lib/avs/utils/contracts.js +30 -50
- package/lib/avs/utils/register.js +75 -70
- package/lib/avs/utils/tasks.js +38 -45
- package/lib/client/create-claim.js +402 -431
- package/lib/client/tunnels/make-rpc-tcp-tunnel.js +46 -48
- package/lib/client/tunnels/make-rpc-tls-tunnel.js +125 -121
- package/lib/client/utils/attestor-pool.js +23 -22
- package/lib/client/utils/client-socket.js +86 -109
- package/lib/client/utils/message-handler.js +79 -89
- package/lib/config/index.js +40 -58
- package/lib/external-rpc/benchmark.js +61 -74
- package/lib/external-rpc/event-bus.js +12 -15
- package/lib/external-rpc/handle-incoming-msg.js +216 -225
- package/lib/external-rpc/jsc-polyfills/1.js +70 -68
- package/lib/external-rpc/jsc-polyfills/2.js +17 -12
- package/lib/external-rpc/jsc-polyfills/event.js +10 -15
- package/lib/external-rpc/jsc-polyfills/index.js +2 -2
- package/lib/external-rpc/jsc-polyfills/ws.js +77 -79
- package/lib/external-rpc/setup-browser.js +28 -28
- package/lib/external-rpc/setup-jsc.js +17 -17
- package/lib/external-rpc/types.js +1 -0
- package/lib/external-rpc/utils.js +89 -89
- package/lib/external-rpc/zk.js +55 -50
- package/lib/index.js +2 -6
- package/lib/mechain/abis/governanceABI.js +457 -460
- package/lib/mechain/abis/taskABI.js +502 -505
- package/lib/mechain/client/create-claim-on-mechain.js +24 -29
- package/lib/mechain/constants/index.js +3 -8
- package/lib/mechain/types/index.js +1 -0
- package/lib/proto/api.js +4200 -4087
- package/lib/proto/tee-bundle.js +1261 -1241
- package/lib/providers/http/index.js +616 -603
- package/lib/providers/http/patch-parse5-tree.js +27 -29
- package/lib/providers/http/utils.js +289 -248
- package/lib/providers/index.js +3 -6
- package/lib/server/create-server.js +89 -91
- package/lib/server/handlers/claimTeeBundle.js +231 -211
- package/lib/server/handlers/claimTunnel.js +66 -73
- package/lib/server/handlers/completeClaimOnChain.js +20 -25
- package/lib/server/handlers/createClaimOnChain.js +21 -27
- package/lib/server/handlers/createTaskOnMechain.js +40 -50
- package/lib/server/handlers/createTunnel.js +85 -90
- package/lib/server/handlers/disconnectTunnel.js +4 -7
- package/lib/server/handlers/fetchCertificateBytes.js +37 -53
- package/lib/server/handlers/index.js +21 -24
- package/lib/server/handlers/init.js +27 -28
- package/lib/server/handlers/toprf.js +13 -16
- package/lib/server/socket.js +97 -100
- package/lib/server/tunnels/make-tcp-tunnel.js +161 -186
- package/lib/server/utils/apm.js +32 -25
- package/lib/server/utils/assert-valid-claim-request.js +305 -334
- package/lib/server/utils/config-env.js +2 -2
- package/lib/server/utils/dns.js +12 -18
- package/lib/server/utils/gcp-attestation.js +233 -181
- package/lib/server/utils/generics.d.ts +1 -1
- package/lib/server/utils/generics.js +43 -37
- package/lib/server/utils/iso.js +253 -256
- package/lib/server/utils/keep-alive.js +36 -36
- package/lib/server/utils/nitro-attestation.js +295 -220
- package/lib/server/utils/oprf-raw.js +48 -55
- package/lib/server/utils/process-handshake.js +200 -218
- package/lib/server/utils/proxy-session.js +5 -5
- package/lib/server/utils/tee-oprf-mpc-verification.js +82 -78
- package/lib/server/utils/tee-oprf-verification.js +165 -142
- package/lib/server/utils/tee-transcript-reconstruction.js +176 -129
- package/lib/server/utils/tee-verification.js +397 -334
- package/lib/server/utils/validation.js +30 -37
- package/lib/types/bgp.js +1 -0
- package/lib/types/claims.js +1 -0
- package/lib/types/client.js +1 -0
- package/lib/types/general.js +1 -0
- package/lib/types/handlers.js +1 -0
- package/lib/types/providers.d.ts +3 -2
- package/lib/types/providers.gen.js +9 -15
- package/lib/types/providers.js +1 -0
- package/lib/types/rpc.js +1 -0
- package/lib/types/signatures.d.ts +1 -2
- package/lib/types/signatures.js +1 -0
- package/lib/types/tunnel.js +1 -0
- package/lib/types/zk.js +1 -0
- package/lib/utils/auth.js +54 -66
- package/lib/utils/b64-json.js +15 -15
- package/lib/utils/bgp-listener.js +107 -111
- package/lib/utils/claims.js +89 -80
- package/lib/utils/env.js +13 -17
- package/lib/utils/error.js +43 -47
- package/lib/utils/generics.js +284 -235
- package/lib/utils/http-parser.js +232 -187
- package/lib/utils/logger.js +80 -71
- package/lib/utils/prepare-packets.js +69 -67
- package/lib/utils/redactions.js +163 -121
- package/lib/utils/retries.js +22 -24
- package/lib/utils/signatures/eth.js +29 -28
- package/lib/utils/signatures/index.js +5 -10
- package/lib/utils/socket-base.js +84 -88
- package/lib/utils/tls.js +28 -28
- package/lib/utils/ws.js +19 -19
- package/lib/utils/zk.js +542 -582
- package/package.json +12 -5
- package/lib/external-rpc/global.d.js +0 -0
- package/lib/scripts/build-browser.d.ts +0 -1
- package/lib/scripts/build-jsc.d.ts +0 -1
- package/lib/scripts/build-lib.d.ts +0 -1
- package/lib/scripts/check-avs-registration.d.ts +0 -1
- package/lib/scripts/check-avs-registration.js +0 -28
- package/lib/scripts/fallbacks/crypto.d.ts +0 -1
- package/lib/scripts/fallbacks/crypto.js +0 -4
- package/lib/scripts/fallbacks/empty.d.ts +0 -3
- package/lib/scripts/fallbacks/empty.js +0 -4
- package/lib/scripts/fallbacks/re2.d.ts +0 -1
- package/lib/scripts/fallbacks/re2.js +0 -7
- package/lib/scripts/fallbacks/snarkjs.d.ts +0 -1
- package/lib/scripts/fallbacks/snarkjs.js +0 -10
- package/lib/scripts/fallbacks/stwo.d.ts +0 -6
- package/lib/scripts/fallbacks/stwo.js +0 -159
- package/lib/scripts/generate-provider-types.d.ts +0 -5
- package/lib/scripts/generate-provider-types.js +0 -101
- package/lib/scripts/generate-receipt.d.ts +0 -9
- package/lib/scripts/generate-receipt.js +0 -101
- package/lib/scripts/generate-toprf-keys.d.ts +0 -1
- package/lib/scripts/generate-toprf-keys.js +0 -24
- package/lib/scripts/jsc-cli-rpc.d.ts +0 -1
- package/lib/scripts/jsc-cli-rpc.js +0 -35
- package/lib/scripts/register-avs-operator.d.ts +0 -1
- package/lib/scripts/register-avs-operator.js +0 -3
- package/lib/scripts/start-server.d.ts +0 -1
- package/lib/scripts/start-server.js +0 -11
- package/lib/scripts/update-avs-metadata.d.ts +0 -1
- package/lib/scripts/update-avs-metadata.js +0 -20
- package/lib/scripts/utils.d.ts +0 -1
- package/lib/scripts/utils.js +0 -10
- package/lib/scripts/whitelist-operator.d.ts +0 -1
- package/lib/scripts/whitelist-operator.js +0 -16
package/lib/utils/generics.js
CHANGED
|
@@ -1,268 +1,317 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
CONTENT_TYPE_MAP,
|
|
4
|
-
crypto,
|
|
5
|
-
decryptWrappedRecord,
|
|
6
|
-
PACKET_TYPE,
|
|
7
|
-
SUPPORTED_CIPHER_SUITE_MAP,
|
|
8
|
-
uint8ArrayToBinaryStr,
|
|
9
|
-
uint8ArrayToDataView
|
|
10
|
-
} from "@reclaimprotocol/tls";
|
|
11
|
-
import { REDACTION_CHAR_CODE } from "@reclaimprotocol/zk-symmetric-crypto";
|
|
1
|
+
import { areUint8ArraysEqual, CONTENT_TYPE_MAP, crypto, decryptWrappedRecord, PACKET_TYPE, SUPPORTED_CIPHER_SUITE_MAP, uint8ArrayToBinaryStr, uint8ArrayToDataView } from '@reclaimprotocol/tls';
|
|
2
|
+
import { REDACTION_CHAR_CODE } from '@reclaimprotocol/zk-symmetric-crypto';
|
|
12
3
|
import { RPCMessage, RPCMessages } from "../proto/api.js";
|
|
13
|
-
const DEFAULT_REDACTION_DATA = new Uint8Array(4)
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
const DEFAULT_REDACTION_DATA = new Uint8Array(4)
|
|
5
|
+
.fill(REDACTION_CHAR_CODE);
|
|
6
|
+
export { uint8ArrayToBinaryStr };
|
|
7
|
+
/**
|
|
8
|
+
* Decodes a Uint8Array to a UTF-8 string.
|
|
9
|
+
*/
|
|
10
|
+
export function uint8ArrayToStr(arr) {
|
|
11
|
+
return new TextDecoder().decode(arr);
|
|
16
12
|
}
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Encodes a UTF-8 string to a Uint8Array.
|
|
15
|
+
*/
|
|
16
|
+
export function strToUint8Array(str) {
|
|
17
|
+
return new TextEncoder().encode(str);
|
|
19
18
|
}
|
|
20
|
-
function getTranscriptString(receipt) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
export function getTranscriptString(receipt) {
|
|
20
|
+
const applMsgs = extractApplicationDataFromTranscript(receipt);
|
|
21
|
+
const strList = [];
|
|
22
|
+
for (const { message, sender } of applMsgs) {
|
|
23
|
+
const content = uint8ArrayToStr(message);
|
|
24
|
+
if (strList[strList.length - 1]?.startsWith(sender)) {
|
|
25
|
+
strList[strList.length - 1] += content;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
strList.push(`${sender}: ${content}`);
|
|
29
|
+
}
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
return strList.join("\n");
|
|
31
|
+
return strList.join('\n');
|
|
32
32
|
}
|
|
33
|
-
const unixTimestampSeconds = () => Math.floor(Date.now() /
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
export const unixTimestampSeconds = () => Math.floor(Date.now() / 1000);
|
|
34
|
+
/**
|
|
35
|
+
* Find index of needle in haystack
|
|
36
|
+
*/
|
|
37
|
+
export function findIndexInUint8Array(haystack, needle) {
|
|
38
|
+
for (let i = 0; i < haystack.length; i++) {
|
|
39
|
+
if (areUint8ArraysEqual(haystack.slice(i, i + needle.length), needle)) {
|
|
40
|
+
return i;
|
|
41
|
+
}
|
|
38
42
|
}
|
|
39
|
-
|
|
40
|
-
return -1;
|
|
41
|
-
}
|
|
42
|
-
function getZkAlgorithmForCipherSuite(cipherSuite) {
|
|
43
|
-
if (cipherSuite.includes("CHACHA20")) {
|
|
44
|
-
return "chacha20";
|
|
45
|
-
}
|
|
46
|
-
if (cipherSuite.includes("AES_256_GCM")) {
|
|
47
|
-
return "aes-256-ctr";
|
|
48
|
-
}
|
|
49
|
-
if (cipherSuite.includes("AES_128_GCM")) {
|
|
50
|
-
return "aes-128-ctr";
|
|
51
|
-
}
|
|
52
|
-
throw new Error(`${cipherSuite} not supported for ZK ops`);
|
|
43
|
+
return -1;
|
|
53
44
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Fetch the ZK algorithm for the specified cipher suite
|
|
47
|
+
*/
|
|
48
|
+
export function getZkAlgorithmForCipherSuite(cipherSuite) {
|
|
49
|
+
if (cipherSuite.includes('CHACHA20')) {
|
|
50
|
+
return 'chacha20';
|
|
51
|
+
}
|
|
52
|
+
if (cipherSuite.includes('AES_256_GCM')) {
|
|
53
|
+
return 'aes-256-ctr';
|
|
54
|
+
}
|
|
55
|
+
if (cipherSuite.includes('AES_128_GCM')) {
|
|
56
|
+
return 'aes-128-ctr';
|
|
57
|
+
}
|
|
58
|
+
throw new Error(`${cipherSuite} not supported for ZK ops`);
|
|
63
59
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Get the pure ciphertext without any MAC,
|
|
62
|
+
* or authentication tag,
|
|
63
|
+
* @param content content w/o header
|
|
64
|
+
* @param cipherSuite
|
|
65
|
+
*/
|
|
66
|
+
export function getPureCiphertext(content, cipherSuite) {
|
|
67
|
+
// assert that the cipher suite is supported
|
|
68
|
+
getZkAlgorithmForCipherSuite(cipherSuite);
|
|
69
|
+
// 16 => auth tag length
|
|
70
|
+
content = content.slice(0, -16);
|
|
71
|
+
const { ivLength: fixedIvLength, } = SUPPORTED_CIPHER_SUITE_MAP[cipherSuite];
|
|
72
|
+
// 12 => total IV length
|
|
73
|
+
const recordIvLength = 12 - fixedIvLength;
|
|
74
|
+
// record IV is prefixed to the ciphertext
|
|
75
|
+
content = content.slice(recordIvLength);
|
|
76
|
+
return content;
|
|
71
77
|
}
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Get the 8 byte IV part that's stored in the record for some cipher suites
|
|
80
|
+
* @param content content w/o header
|
|
81
|
+
* @param cipherSuite
|
|
82
|
+
*/
|
|
83
|
+
export function getRecordIV(content, cipherSuite) {
|
|
84
|
+
// assert that the cipher suite is supported
|
|
85
|
+
getZkAlgorithmForCipherSuite(cipherSuite);
|
|
86
|
+
const { ivLength: fixedIvLength, } = SUPPORTED_CIPHER_SUITE_MAP[cipherSuite];
|
|
87
|
+
// 12 => total IV length
|
|
88
|
+
const recordIvLength = 12 - fixedIvLength;
|
|
89
|
+
return content.slice(0, recordIvLength);
|
|
74
90
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
91
|
+
export function getProviderValue(params, fn, secretParams) {
|
|
92
|
+
return typeof fn === 'function'
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
? fn(params, secretParams)
|
|
95
|
+
: fn;
|
|
77
96
|
}
|
|
78
|
-
function
|
|
79
|
-
|
|
97
|
+
export function generateRpcMessageId() {
|
|
98
|
+
return uint8ArrayToDataView(crypto.randomBytes(4)).getUint32(0);
|
|
80
99
|
}
|
|
81
|
-
|
|
82
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Random session ID for a WebSocket client.
|
|
102
|
+
*/
|
|
103
|
+
export function generateSessionId() {
|
|
104
|
+
return generateRpcMessageId();
|
|
83
105
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Random ID for a tunnel.
|
|
108
|
+
*/
|
|
109
|
+
export function generateTunnelId() {
|
|
110
|
+
return generateRpcMessageId();
|
|
88
111
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
direction: "request"
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
if (key.endsWith("Response")) {
|
|
97
|
-
return {
|
|
98
|
-
type: key.slice(0, -8),
|
|
99
|
-
direction: "response"
|
|
100
|
-
};
|
|
101
|
-
}
|
|
112
|
+
export function makeRpcEvent(type, data) {
|
|
113
|
+
const ev = new Event(type);
|
|
114
|
+
ev.data = data;
|
|
115
|
+
return ev;
|
|
102
116
|
}
|
|
103
|
-
|
|
104
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Get the RPC type from the key.
|
|
119
|
+
* For eg. "claimTunnelRequest" ->
|
|
120
|
+
* { type: 'claimTunnel', direction: 'request' }
|
|
121
|
+
*/
|
|
122
|
+
export function getRpcTypeFromKey(key) {
|
|
123
|
+
if (key.endsWith('Request')) {
|
|
124
|
+
return {
|
|
125
|
+
type: key.slice(0, -7),
|
|
126
|
+
direction: 'request'
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (key.endsWith('Response')) {
|
|
130
|
+
return {
|
|
131
|
+
type: key.slice(0, -8),
|
|
132
|
+
direction: 'response'
|
|
133
|
+
};
|
|
134
|
+
}
|
|
105
135
|
}
|
|
106
|
-
|
|
107
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Get the RPC response type from the RPC type.
|
|
138
|
+
* For eg. "claimTunnel" -> "claimTunnelResponse"
|
|
139
|
+
*/
|
|
140
|
+
export function getRpcResponseType(type) {
|
|
141
|
+
return `${type}Response`;
|
|
108
142
|
}
|
|
109
|
-
|
|
110
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Get the RPC request type from the RPC type.
|
|
145
|
+
* For eg. "claimTunnel" -> "claimTunnelRequest"
|
|
146
|
+
*/
|
|
147
|
+
export function getRpcRequestType(type) {
|
|
148
|
+
return `${type}Request`;
|
|
111
149
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return data;
|
|
118
|
-
}
|
|
119
|
-
if (typeof data === "string") {
|
|
120
|
-
return strToUint8Array(data);
|
|
121
|
-
}
|
|
122
|
-
if (typeof Blob !== "undefined" && data instanceof Blob) {
|
|
123
|
-
return new Uint8Array(await data.arrayBuffer());
|
|
124
|
-
}
|
|
125
|
-
throw new Error("unsupported data: " + String(data));
|
|
150
|
+
export function isApplicationData(packet, tlsVersion) {
|
|
151
|
+
return packet.type === 'ciphertext'
|
|
152
|
+
&& (packet.contentType === 'APPLICATION_DATA'
|
|
153
|
+
|| (packet.data[0] === PACKET_TYPE.WRAPPED_RECORD
|
|
154
|
+
&& tlsVersion === 'TLS1_2'));
|
|
126
155
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
for (const key in msg) {
|
|
135
|
-
if (!msg[key]) {
|
|
136
|
-
continue;
|
|
156
|
+
/**
|
|
157
|
+
* Convert the received data from a WS to a Uint8Array
|
|
158
|
+
*/
|
|
159
|
+
export async function extractArrayBufferFromWsData(data) {
|
|
160
|
+
if (data instanceof ArrayBuffer) {
|
|
161
|
+
return new Uint8Array(data);
|
|
137
162
|
}
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
163
|
+
// uint8array/Buffer
|
|
164
|
+
if (data instanceof Uint8Array
|
|
165
|
+
|| (typeof data === 'object' && data && 'buffer' in data)) {
|
|
166
|
+
return data;
|
|
141
167
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
function extractApplicationDataFromTranscript({ transcript, tlsVersion }) {
|
|
146
|
-
const msgs = [];
|
|
147
|
-
for (const m of transcript) {
|
|
148
|
-
let message;
|
|
149
|
-
if (m.redacted) {
|
|
150
|
-
if (!m.plaintextLength) {
|
|
151
|
-
message = DEFAULT_REDACTION_DATA;
|
|
152
|
-
} else {
|
|
153
|
-
const len = tlsVersion === "TLS1_3" ? m.plaintextLength - 1 : m.plaintextLength;
|
|
154
|
-
message = new Uint8Array(len).fill(REDACTION_CHAR_CODE);
|
|
155
|
-
}
|
|
156
|
-
} else if (tlsVersion === "TLS1_3") {
|
|
157
|
-
const contentType = m.message[m.message.length - 1];
|
|
158
|
-
if (contentType !== CONTENT_TYPE_MAP["APPLICATION_DATA"]) {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
message = m.message.slice(0, -1);
|
|
162
|
-
} else if (m.recordHeader[0] === PACKET_TYPE.WRAPPED_RECORD) {
|
|
163
|
-
message = m.message;
|
|
164
|
-
} else {
|
|
165
|
-
continue;
|
|
168
|
+
if (typeof data === 'string') {
|
|
169
|
+
return strToUint8Array(data);
|
|
166
170
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
171
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob) {
|
|
172
|
+
return new Uint8Array(await data.arrayBuffer());
|
|
173
|
+
}
|
|
174
|
+
throw new Error('unsupported data: ' + String(data));
|
|
170
175
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Check if the RPC message is a request or a response.
|
|
178
|
+
*/
|
|
179
|
+
export function getRpcRequest(msg) {
|
|
180
|
+
if (msg.requestError) {
|
|
181
|
+
return {
|
|
182
|
+
direction: 'response',
|
|
183
|
+
type: 'error'
|
|
184
|
+
};
|
|
176
185
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
break;
|
|
186
|
+
for (const key in msg) {
|
|
187
|
+
if (!msg[key]) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const rpcType = getRpcTypeFromKey(key);
|
|
191
|
+
if (!rpcType) {
|
|
192
|
+
continue;
|
|
185
193
|
}
|
|
186
|
-
|
|
187
|
-
} else {
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
} else {
|
|
191
|
-
continue;
|
|
194
|
+
return rpcType;
|
|
192
195
|
}
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Finds all application data messages in a transcript
|
|
199
|
+
* and returns them. Removes the "contentType" suffix from the message.
|
|
200
|
+
* in TLS 1.3
|
|
201
|
+
*/
|
|
202
|
+
export function extractApplicationDataFromTranscript({ transcript, tlsVersion }) {
|
|
203
|
+
const msgs = [];
|
|
204
|
+
for (const m of transcript) {
|
|
205
|
+
let message;
|
|
206
|
+
// redacted msgs but with a valid packet header
|
|
207
|
+
// can be considered application data messages
|
|
208
|
+
if (m.redacted) {
|
|
209
|
+
if (!m.plaintextLength) {
|
|
210
|
+
message = DEFAULT_REDACTION_DATA;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const len = tlsVersion === 'TLS1_3'
|
|
214
|
+
// remove content type suffix
|
|
215
|
+
? m.plaintextLength - 1
|
|
216
|
+
: m.plaintextLength;
|
|
217
|
+
message = new Uint8Array(len)
|
|
218
|
+
.fill(REDACTION_CHAR_CODE);
|
|
219
|
+
}
|
|
220
|
+
// otherwise, we need to check the content type
|
|
221
|
+
}
|
|
222
|
+
else if (tlsVersion === 'TLS1_3') {
|
|
223
|
+
const contentType = m.message[m.message.length - 1];
|
|
224
|
+
if (contentType !== CONTENT_TYPE_MAP['APPLICATION_DATA']) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
message = m.message.slice(0, -1);
|
|
228
|
+
}
|
|
229
|
+
else if (m.recordHeader[0] === PACKET_TYPE.WRAPPED_RECORD) {
|
|
230
|
+
message = m.message;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
msgs.push({ message, sender: m.sender });
|
|
195
236
|
}
|
|
196
|
-
msgs
|
|
197
|
-
}
|
|
198
|
-
return msgs;
|
|
237
|
+
return msgs;
|
|
199
238
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
239
|
+
export function extractHandshakeFromTranscript({ transcript, tlsVersion }) {
|
|
240
|
+
const msgs = [];
|
|
241
|
+
for (const [i, m] of transcript.entries()) {
|
|
242
|
+
if (m.redacted) {
|
|
243
|
+
break; // stop at first encrypted message
|
|
244
|
+
}
|
|
245
|
+
let message;
|
|
246
|
+
if (m.recordHeader[0] === PACKET_TYPE.HELLO) {
|
|
247
|
+
message = m.message;
|
|
248
|
+
}
|
|
249
|
+
else if (m.recordHeader[0] === PACKET_TYPE.WRAPPED_RECORD) {
|
|
250
|
+
if (tlsVersion === 'TLS1_3') {
|
|
251
|
+
const contentType = m.message[m.message.length - 1];
|
|
252
|
+
if (contentType !== CONTENT_TYPE_MAP['HANDSHAKE']) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
message = m.message.slice(0, -1);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (!message.length) {
|
|
265
|
+
throw new Error('unsupported handshake message');
|
|
266
|
+
}
|
|
267
|
+
msgs.push({ message, sender: m.sender, index: i });
|
|
213
268
|
}
|
|
214
|
-
|
|
269
|
+
return msgs;
|
|
270
|
+
}
|
|
271
|
+
export async function decryptDirect(directReveal, cipherSuite, recordHeader, serverTlsVersion, content) {
|
|
272
|
+
const { key, iv, recordNumber } = directReveal;
|
|
273
|
+
const { cipher } = SUPPORTED_CIPHER_SUITE_MAP[cipherSuite];
|
|
274
|
+
const importedKey = await crypto.importKey(cipher, key);
|
|
275
|
+
return await decryptWrappedRecord(content, {
|
|
276
|
+
iv,
|
|
277
|
+
key: importedKey,
|
|
278
|
+
recordHeader,
|
|
279
|
+
recordNumber,
|
|
280
|
+
version: serverTlsVersion,
|
|
281
|
+
cipherSuite,
|
|
282
|
+
});
|
|
215
283
|
}
|
|
216
|
-
function packRpcMessages(...msgs) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
284
|
+
export function packRpcMessages(...msgs) {
|
|
285
|
+
return RPCMessages.create({
|
|
286
|
+
messages: msgs.map(msg => (RPCMessage.create({
|
|
287
|
+
...msg,
|
|
288
|
+
id: msg.id || generateRpcMessageId()
|
|
289
|
+
})))
|
|
290
|
+
});
|
|
223
291
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Converts an Ethers struct (an array w named keys) to
|
|
294
|
+
* a plain object. Recursively converts all structs inside.
|
|
295
|
+
* Required to correctly JSON.stringify the struct.
|
|
296
|
+
*/
|
|
297
|
+
export function ethersStructToPlainObject(struct) {
|
|
298
|
+
if (!Array.isArray(struct)) {
|
|
299
|
+
return struct;
|
|
300
|
+
}
|
|
301
|
+
const namedKeys = Object.keys(struct)
|
|
302
|
+
.filter(key => isNaN(Number(key)));
|
|
303
|
+
// seems to be an actual array
|
|
304
|
+
if (!namedKeys.length) {
|
|
305
|
+
return struct.map(ethersStructToPlainObject);
|
|
306
|
+
}
|
|
307
|
+
const obj = {};
|
|
308
|
+
for (const key of namedKeys) {
|
|
309
|
+
obj[key] = ethersStructToPlainObject(struct[key]);
|
|
310
|
+
}
|
|
311
|
+
return obj;
|
|
237
312
|
}
|
|
238
|
-
function isTls13Suite(suite) {
|
|
239
|
-
|
|
313
|
+
export function isTls13Suite(suite) {
|
|
314
|
+
return suite === 'TLS_AES_128_GCM_SHA256'
|
|
315
|
+
|| suite === 'TLS_AES_256_GCM_SHA384'
|
|
316
|
+
|| suite === 'TLS_CHACHA20_POLY1305_SHA256';
|
|
240
317
|
}
|
|
241
|
-
export {
|
|
242
|
-
decryptDirect,
|
|
243
|
-
ethersStructToPlainObject,
|
|
244
|
-
extractApplicationDataFromTranscript,
|
|
245
|
-
extractArrayBufferFromWsData,
|
|
246
|
-
extractHandshakeFromTranscript,
|
|
247
|
-
findIndexInUint8Array,
|
|
248
|
-
generateRpcMessageId,
|
|
249
|
-
generateSessionId,
|
|
250
|
-
generateTunnelId,
|
|
251
|
-
getProviderValue,
|
|
252
|
-
getPureCiphertext,
|
|
253
|
-
getRecordIV,
|
|
254
|
-
getRpcRequest,
|
|
255
|
-
getRpcRequestType,
|
|
256
|
-
getRpcResponseType,
|
|
257
|
-
getRpcTypeFromKey,
|
|
258
|
-
getTranscriptString,
|
|
259
|
-
getZkAlgorithmForCipherSuite,
|
|
260
|
-
isApplicationData,
|
|
261
|
-
isTls13Suite,
|
|
262
|
-
makeRpcEvent,
|
|
263
|
-
packRpcMessages,
|
|
264
|
-
strToUint8Array,
|
|
265
|
-
uint8ArrayToBinaryStr,
|
|
266
|
-
uint8ArrayToStr,
|
|
267
|
-
unixTimestampSeconds
|
|
268
|
-
};
|