@reclaimprotocol/attestor-core 5.0.1-beta.13 → 5.0.1-beta.16
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/lib/external-rpc/index.js +17321 -3
- package/lib/index.d.ts +1 -0
- package/lib/index.js +15391 -11
- package/lib/scripts/build-browser-debug.d.ts +1 -0
- package/package.json +1 -1
- package/lib/avs/abis/avsDirectoryABI.js +0 -343
- package/lib/avs/abis/delegationABI.js +0 -4
- package/lib/avs/abis/registryABI.js +0 -728
- package/lib/avs/client/create-claim-on-avs.js +0 -168
- package/lib/avs/config.js +0 -26
- package/lib/avs/contracts/ReclaimServiceManager.js +0 -0
- package/lib/avs/contracts/common.js +0 -0
- package/lib/avs/contracts/factories/ReclaimServiceManager__factory.js +0 -1183
- package/lib/avs/contracts/factories/index.js +0 -4
- package/lib/avs/contracts/index.js +0 -6
- package/lib/avs/types/index.js +0 -0
- package/lib/avs/utils/contracts.js +0 -53
- package/lib/avs/utils/register.js +0 -74
- package/lib/avs/utils/tasks.js +0 -48
- package/lib/client/create-claim.js +0 -461
- package/lib/client/index.js +0 -3
- package/lib/client/tunnels/make-rpc-tcp-tunnel.js +0 -53
- package/lib/client/tunnels/make-rpc-tls-tunnel.js +0 -127
- package/lib/client/utils/attestor-pool.js +0 -24
- package/lib/client/utils/client-socket.js +0 -120
- package/lib/client/utils/message-handler.js +0 -97
- package/lib/config/index.js +0 -62
- package/lib/external-rpc/benchmark.js +0 -82
- package/lib/external-rpc/event-bus.js +0 -17
- package/lib/external-rpc/handle-incoming-msg.js +0 -241
- package/lib/external-rpc/jsc-polyfills/1.js +0 -80
- package/lib/external-rpc/jsc-polyfills/2.js +0 -15
- package/lib/external-rpc/jsc-polyfills/event.js +0 -19
- package/lib/external-rpc/jsc-polyfills/index.js +0 -2
- package/lib/external-rpc/jsc-polyfills/ws.js +0 -83
- package/lib/external-rpc/setup-browser.js +0 -33
- package/lib/external-rpc/setup-jsc.js +0 -22
- package/lib/external-rpc/types.js +0 -0
- package/lib/external-rpc/utils.js +0 -100
- package/lib/external-rpc/zk.js +0 -58
- package/lib/mechain/abis/governanceABI.js +0 -461
- package/lib/mechain/abis/taskABI.js +0 -512
- package/lib/mechain/client/create-claim-on-mechain.js +0 -33
- package/lib/mechain/client/index.js +0 -1
- package/lib/mechain/constants/index.js +0 -8
- package/lib/mechain/index.js +0 -2
- package/lib/mechain/types/index.js +0 -0
- package/lib/proto/api.js +0 -4250
- package/lib/proto/tee-bundle.js +0 -1296
- package/lib/providers/http/index.js +0 -640
- package/lib/providers/http/patch-parse5-tree.js +0 -34
- package/lib/providers/http/utils.js +0 -283
- package/lib/providers/index.js +0 -7
- package/lib/scripts/build-browser.js +0 -38
- package/lib/scripts/build-jsc.js +0 -47
- package/lib/scripts/build-lib.js +0 -47
- package/lib/scripts/check-avs-registration.js +0 -28
- package/lib/scripts/fallbacks/crypto.js +0 -4
- package/lib/scripts/fallbacks/empty.js +0 -4
- package/lib/scripts/fallbacks/re2.js +0 -7
- package/lib/scripts/fallbacks/snarkjs.js +0 -10
- package/lib/scripts/fallbacks/stwo.js +0 -159
- package/lib/scripts/generate-provider-types.js +0 -101
- package/lib/scripts/generate-receipt.js +0 -101
- package/lib/scripts/generate-toprf-keys.js +0 -24
- package/lib/scripts/jsc-cli-rpc.js +0 -35
- package/lib/scripts/register-avs-operator.js +0 -3
- package/lib/scripts/start-server.js +0 -11
- package/lib/scripts/update-avs-metadata.js +0 -20
- package/lib/scripts/utils.js +0 -10
- package/lib/scripts/whitelist-operator.js +0 -16
- package/lib/server/create-server.js +0 -105
- package/lib/server/handlers/claimTeeBundle.js +0 -232
- package/lib/server/handlers/claimTunnel.js +0 -80
- package/lib/server/handlers/completeClaimOnChain.js +0 -29
- package/lib/server/handlers/createClaimOnChain.js +0 -32
- package/lib/server/handlers/createTaskOnMechain.js +0 -57
- package/lib/server/handlers/createTunnel.js +0 -98
- package/lib/server/handlers/disconnectTunnel.js +0 -8
- package/lib/server/handlers/fetchCertificateBytes.js +0 -57
- package/lib/server/handlers/index.js +0 -25
- package/lib/server/handlers/init.js +0 -33
- package/lib/server/handlers/toprf.js +0 -19
- package/lib/server/index.js +0 -4
- package/lib/server/socket.js +0 -112
- package/lib/server/tunnels/make-tcp-tunnel.js +0 -202
- package/lib/server/utils/apm.js +0 -29
- package/lib/server/utils/assert-valid-claim-request.js +0 -354
- package/lib/server/utils/config-env.js +0 -4
- package/lib/server/utils/dns.js +0 -24
- package/lib/server/utils/gcp-attestation.js +0 -237
- package/lib/server/utils/generics.js +0 -45
- package/lib/server/utils/iso.js +0 -259
- package/lib/server/utils/keep-alive.js +0 -38
- package/lib/server/utils/nitro-attestation.js +0 -249
- package/lib/server/utils/oprf-raw.js +0 -61
- package/lib/server/utils/process-handshake.js +0 -233
- package/lib/server/utils/proxy-session.js +0 -6
- package/lib/server/utils/tee-oprf-mpc-verification.js +0 -86
- package/lib/server/utils/tee-oprf-verification.js +0 -151
- package/lib/server/utils/tee-transcript-reconstruction.js +0 -140
- package/lib/server/utils/tee-verification.js +0 -358
- package/lib/server/utils/validation.js +0 -45
- package/lib/types/bgp.js +0 -0
- package/lib/types/claims.js +0 -0
- package/lib/types/client.js +0 -0
- package/lib/types/general.js +0 -0
- package/lib/types/handlers.js +0 -0
- package/lib/types/index.js +0 -10
- package/lib/types/providers.gen.js +0 -16
- package/lib/types/providers.js +0 -0
- package/lib/types/rpc.js +0 -0
- package/lib/types/signatures.js +0 -0
- package/lib/types/tunnel.js +0 -0
- package/lib/types/zk.js +0 -0
- package/lib/utils/auth.js +0 -71
- package/lib/utils/b64-json.js +0 -17
- package/lib/utils/bgp-listener.js +0 -123
- package/lib/utils/claims.js +0 -89
- package/lib/utils/env.js +0 -19
- package/lib/utils/error.js +0 -54
- package/lib/utils/generics.js +0 -268
- package/lib/utils/http-parser.js +0 -201
- package/lib/utils/index.js +0 -13
- package/lib/utils/logger.js +0 -82
- package/lib/utils/prepare-packets.js +0 -69
- package/lib/utils/redactions.js +0 -135
- package/lib/utils/retries.js +0 -26
- package/lib/utils/signatures/eth.js +0 -31
- package/lib/utils/signatures/index.js +0 -12
- package/lib/utils/socket-base.js +0 -96
- package/lib/utils/tls.js +0 -58
- package/lib/utils/ws.js +0 -22
- package/lib/utils/zk.js +0 -625
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
2
|
-
import { Socket } from "net";
|
|
3
|
-
import { CONNECTION_TIMEOUT_MS } from "#src/config/index.js";
|
|
4
|
-
import { resolveHostnames } from "#src/server/utils/dns.js";
|
|
5
|
-
import { isValidCountryCode } from "#src/server/utils/iso.js";
|
|
6
|
-
import { isValidProxySessionId } from "#src/server/utils/proxy-session.js";
|
|
7
|
-
import { getEnvVariable } from "#src/utils/env.js";
|
|
8
|
-
import { AttestorError } from "#src/utils/index.js";
|
|
9
|
-
const HTTPS_PROXY_URL = getEnvVariable("HTTPS_PROXY_URL");
|
|
10
|
-
const makeTcpTunnel = async ({
|
|
11
|
-
onClose,
|
|
12
|
-
onMessage,
|
|
13
|
-
logger,
|
|
14
|
-
...opts
|
|
15
|
-
}) => {
|
|
16
|
-
const transcript = [];
|
|
17
|
-
const socket = await connectTcp({ ...opts, logger });
|
|
18
|
-
let closed = false;
|
|
19
|
-
socket.on("data", (message) => {
|
|
20
|
-
if (closed) {
|
|
21
|
-
logger.warn("socket is closed, dropping message");
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
onMessage?.(message);
|
|
25
|
-
transcript.push({ sender: "server", message });
|
|
26
|
-
});
|
|
27
|
-
socket.once("close", () => onSocketClose(void 0));
|
|
28
|
-
return {
|
|
29
|
-
socket,
|
|
30
|
-
transcript,
|
|
31
|
-
createRequest: opts,
|
|
32
|
-
async write(data) {
|
|
33
|
-
transcript.push({ sender: "client", message: data });
|
|
34
|
-
await new Promise((resolve, reject) => {
|
|
35
|
-
socket.write(data, (err) => {
|
|
36
|
-
if (err) {
|
|
37
|
-
reject(err);
|
|
38
|
-
} else {
|
|
39
|
-
resolve();
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
},
|
|
44
|
-
close(err) {
|
|
45
|
-
if (closed) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
socket.destroy(err);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
function onSocketClose(err) {
|
|
52
|
-
if (closed) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
logger.debug({ err }, "closing socket");
|
|
56
|
-
closed = true;
|
|
57
|
-
onClose?.(err);
|
|
58
|
-
onClose = void 0;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
async function connectTcp({ host, port, geoLocation, proxySessionId, logger }) {
|
|
62
|
-
let connectTimeout;
|
|
63
|
-
let socket;
|
|
64
|
-
try {
|
|
65
|
-
await new Promise(async (resolve, reject) => {
|
|
66
|
-
try {
|
|
67
|
-
connectTimeout = setTimeout(
|
|
68
|
-
() => reject(
|
|
69
|
-
new AttestorError(
|
|
70
|
-
"ERROR_NETWORK_ERROR",
|
|
71
|
-
"Server connection timed out"
|
|
72
|
-
)
|
|
73
|
-
),
|
|
74
|
-
CONNECTION_TIMEOUT_MS
|
|
75
|
-
);
|
|
76
|
-
socket = await getSocket({
|
|
77
|
-
host,
|
|
78
|
-
port,
|
|
79
|
-
geoLocation,
|
|
80
|
-
proxySessionId,
|
|
81
|
-
logger
|
|
82
|
-
});
|
|
83
|
-
socket.once("connect", resolve);
|
|
84
|
-
socket.once("error", reject);
|
|
85
|
-
socket.once("end", () => reject(
|
|
86
|
-
new AttestorError(
|
|
87
|
-
"ERROR_NETWORK_ERROR",
|
|
88
|
-
"connection closed"
|
|
89
|
-
)
|
|
90
|
-
));
|
|
91
|
-
} catch (err) {
|
|
92
|
-
reject(err);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
logger.debug({ addr: `${host}:${port}` }, "connected");
|
|
96
|
-
return socket;
|
|
97
|
-
} catch (err) {
|
|
98
|
-
socket?.end();
|
|
99
|
-
throw err;
|
|
100
|
-
} finally {
|
|
101
|
-
clearTimeout(connectTimeout);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
async function getSocket(opts) {
|
|
105
|
-
const { logger } = opts;
|
|
106
|
-
try {
|
|
107
|
-
return await _getSocket(opts);
|
|
108
|
-
} catch (err) {
|
|
109
|
-
if (!(err instanceof AttestorError) || err.data?.code !== 403) {
|
|
110
|
-
throw err;
|
|
111
|
-
}
|
|
112
|
-
const addrs = await resolveHostnames(opts.host);
|
|
113
|
-
logger.info(
|
|
114
|
-
{ addrs, host: opts.host },
|
|
115
|
-
"failed to connect due to restricted IP, trying via raw addr"
|
|
116
|
-
);
|
|
117
|
-
for (const addr of addrs) {
|
|
118
|
-
try {
|
|
119
|
-
return await _getSocket({ ...opts, host: addr });
|
|
120
|
-
} catch (err2) {
|
|
121
|
-
logger.error(
|
|
122
|
-
{ addr, err: err2 },
|
|
123
|
-
"failed to connect to host"
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
throw err;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async function _getSocket({
|
|
131
|
-
host,
|
|
132
|
-
port,
|
|
133
|
-
geoLocation,
|
|
134
|
-
proxySessionId,
|
|
135
|
-
logger
|
|
136
|
-
}) {
|
|
137
|
-
const socket = new Socket();
|
|
138
|
-
if ((proxySessionId || geoLocation) && !HTTPS_PROXY_URL) {
|
|
139
|
-
logger.warn(
|
|
140
|
-
{ geoLocation, proxySessionId },
|
|
141
|
-
"geoLocation or proxySessionId provided but no proxy URL found"
|
|
142
|
-
);
|
|
143
|
-
geoLocation = "";
|
|
144
|
-
proxySessionId = "";
|
|
145
|
-
}
|
|
146
|
-
if (!geoLocation && !proxySessionId) {
|
|
147
|
-
socket.connect({ host, port });
|
|
148
|
-
return socket;
|
|
149
|
-
}
|
|
150
|
-
if (!isValidCountryCode(geoLocation)) {
|
|
151
|
-
throw AttestorError.badRequest(
|
|
152
|
-
`Geolocation "${geoLocation}" is invalid. Must be 2 letter ISO country code`,
|
|
153
|
-
{ geoLocation }
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
if (proxySessionId && !isValidProxySessionId(proxySessionId)) {
|
|
157
|
-
throw AttestorError.badRequest(
|
|
158
|
-
`proxySessionId "${proxySessionId}" is invalid. Must be a lowercase alphanumeric string of length 8-14 characters. eg. "mystring12345", "something1234".`,
|
|
159
|
-
{ proxySessionId }
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
const agentUrl = HTTPS_PROXY_URL.replace(
|
|
163
|
-
"{{geoLocation}}",
|
|
164
|
-
geoLocation?.toLowerCase() || ""
|
|
165
|
-
).replace(
|
|
166
|
-
"{{proxySessionId}}",
|
|
167
|
-
proxySessionId ? `-session-${proxySessionId}` : ""
|
|
168
|
-
);
|
|
169
|
-
const agent = new HttpsProxyAgent(agentUrl);
|
|
170
|
-
const waitForProxyRes = new Promise((resolve) => {
|
|
171
|
-
socket.once("proxyConnect", resolve);
|
|
172
|
-
});
|
|
173
|
-
const proxySocket = await agent.connect(
|
|
174
|
-
// ignore, because https-proxy-agent
|
|
175
|
-
// expects an http request object
|
|
176
|
-
// @ts-ignore
|
|
177
|
-
socket,
|
|
178
|
-
{ host, port, timeout: CONNECTION_TIMEOUT_MS }
|
|
179
|
-
);
|
|
180
|
-
const res = await waitForProxyRes;
|
|
181
|
-
if (res.statusCode !== 200) {
|
|
182
|
-
logger.error(
|
|
183
|
-
{ geoLocation, proxySessionId, res },
|
|
184
|
-
"Proxy geo location or session id failed"
|
|
185
|
-
);
|
|
186
|
-
throw new AttestorError(
|
|
187
|
-
"ERROR_PROXY_ERROR",
|
|
188
|
-
`Proxy via ${geoLocation ? `geo location "${geoLocation}"` : ""}${geoLocation && proxySessionId ? ", or " : ""}${proxySessionId ? `session id "${proxySessionId}"` : ""} failed with status code: ${res.statusCode}, message: ${res.statusText}`,
|
|
189
|
-
{
|
|
190
|
-
code: res.statusCode,
|
|
191
|
-
message: res.statusText
|
|
192
|
-
}
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
process.nextTick(() => {
|
|
196
|
-
proxySocket.emit("connect");
|
|
197
|
-
});
|
|
198
|
-
return proxySocket;
|
|
199
|
-
}
|
|
200
|
-
export {
|
|
201
|
-
makeTcpTunnel
|
|
202
|
-
};
|
package/lib/server/utils/apm.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import ElasticAPM from "elastic-apm-node";
|
|
2
|
-
import { getEnvVariable } from "#src/utils/env.js";
|
|
3
|
-
import { logger } from "#src/utils/logger.js";
|
|
4
|
-
let apm;
|
|
5
|
-
function getApm() {
|
|
6
|
-
if (!getEnvVariable("ELASTIC_APM_SERVER_URL") || !getEnvVariable("ELASTIC_APM_SECRET_TOKEN")) {
|
|
7
|
-
logger.info(
|
|
8
|
-
"ELASTIC_APM_SERVER_URL or ELASTIC_APM_SECRET_TOKEN not found in env, APM agent not initialised"
|
|
9
|
-
);
|
|
10
|
-
return void 0;
|
|
11
|
-
}
|
|
12
|
-
if (!apm) {
|
|
13
|
-
const sampleRate = +(getEnvVariable("ELASTIC_APM_SAMPLE_RATE") || "0.1");
|
|
14
|
-
apm = ElasticAPM.start({
|
|
15
|
-
serviceName: "reclaim_attestor",
|
|
16
|
-
serviceVersion: "4.0.0",
|
|
17
|
-
transactionSampleRate: sampleRate,
|
|
18
|
-
instrumentIncomingHTTPRequests: true,
|
|
19
|
-
usePathAsTransactionName: true,
|
|
20
|
-
instrument: true,
|
|
21
|
-
captureHeaders: true
|
|
22
|
-
});
|
|
23
|
-
logger.info("initialised APM agent");
|
|
24
|
-
}
|
|
25
|
-
return apm;
|
|
26
|
-
}
|
|
27
|
-
export {
|
|
28
|
-
getApm
|
|
29
|
-
};
|
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
import { areUint8ArraysEqual, concatenateUint8Arrays } from "@reclaimprotocol/tls";
|
|
2
|
-
import { ClaimTunnelRequest, TranscriptMessageSenderType } from "#src/proto/api.js";
|
|
3
|
-
import { providers } from "#src/providers/index.js";
|
|
4
|
-
import { niceParseJsonObject } from "#src/server/utils/generics.js";
|
|
5
|
-
import { computeOPRFRaw } from "#src/server/utils/oprf-raw.js";
|
|
6
|
-
import { processHandshake } from "#src/server/utils/process-handshake.js";
|
|
7
|
-
import { assertValidateProviderParams } from "#src/server/utils/validation.js";
|
|
8
|
-
import {
|
|
9
|
-
AttestorError,
|
|
10
|
-
binaryHashToStr,
|
|
11
|
-
canonicalStringify,
|
|
12
|
-
decryptDirect,
|
|
13
|
-
extractApplicationDataFromTranscript,
|
|
14
|
-
hashProviderParams,
|
|
15
|
-
SIGNATURES,
|
|
16
|
-
verifyZkPacket
|
|
17
|
-
} from "#src/utils/index.js";
|
|
18
|
-
import { getEngineString } from "#src/utils/zk.js";
|
|
19
|
-
async function assertValidClaimRequest(request, metadata, logger) {
|
|
20
|
-
const {
|
|
21
|
-
data,
|
|
22
|
-
signatures: { requestSignature } = {},
|
|
23
|
-
zkEngine,
|
|
24
|
-
fixedServerIV,
|
|
25
|
-
fixedClientIV
|
|
26
|
-
} = request;
|
|
27
|
-
if (!data) {
|
|
28
|
-
throw new AttestorError(
|
|
29
|
-
"ERROR_INVALID_CLAIM",
|
|
30
|
-
"No info provided on claim request"
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
if (!requestSignature?.length) {
|
|
34
|
-
throw new AttestorError(
|
|
35
|
-
"ERROR_INVALID_CLAIM",
|
|
36
|
-
"No signature provided on claim request"
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
const serialisedReq = ClaimTunnelRequest.encode({ ...request, signatures: void 0 }).finish();
|
|
40
|
-
const { verify: verifySig } = SIGNATURES[metadata.signatureType];
|
|
41
|
-
const verified = await verifySig(serialisedReq, requestSignature, data.owner);
|
|
42
|
-
if (!verified) {
|
|
43
|
-
throw new AttestorError(
|
|
44
|
-
"ERROR_INVALID_CLAIM",
|
|
45
|
-
"Invalid signature on claim request"
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
const receipt = await decryptTranscript(
|
|
49
|
-
request.transcript,
|
|
50
|
-
logger,
|
|
51
|
-
getEngineString(zkEngine),
|
|
52
|
-
fixedServerIV,
|
|
53
|
-
fixedClientIV
|
|
54
|
-
);
|
|
55
|
-
const reqHost = request.request?.host;
|
|
56
|
-
if (receipt.hostname !== reqHost) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
`Expected server name ${reqHost}, got ${receipt.hostname}`
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
const applData = extractApplicationDataFromTranscript(receipt);
|
|
62
|
-
const newData = await assertValidProviderTranscript(
|
|
63
|
-
applData,
|
|
64
|
-
data,
|
|
65
|
-
logger,
|
|
66
|
-
{ version: metadata.clientVersion },
|
|
67
|
-
receipt.oprfRawReplacements
|
|
68
|
-
);
|
|
69
|
-
if (newData !== data) {
|
|
70
|
-
logger.info({ newData }, "updated claim info");
|
|
71
|
-
}
|
|
72
|
-
return newData;
|
|
73
|
-
}
|
|
74
|
-
async function assertValidProviderTranscript(applData, info, logger, providerCtx, oprfRawReplacements) {
|
|
75
|
-
const providerName = info.provider;
|
|
76
|
-
const provider = providers[providerName];
|
|
77
|
-
if (!provider) {
|
|
78
|
-
throw new AttestorError(
|
|
79
|
-
"ERROR_INVALID_CLAIM",
|
|
80
|
-
`Unsupported provider: ${providerName}`
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
let params = niceParseJsonObject(info.parameters, "params");
|
|
84
|
-
const ctx = niceParseJsonObject(info.context, "context");
|
|
85
|
-
if (oprfRawReplacements?.length) {
|
|
86
|
-
let strParams = canonicalStringify(params) ?? "{}";
|
|
87
|
-
for (const { originalText, nullifierText } of oprfRawReplacements) {
|
|
88
|
-
strParams = strParams.replaceAll(originalText, nullifierText);
|
|
89
|
-
}
|
|
90
|
-
params = JSON.parse(strParams);
|
|
91
|
-
info.parameters = strParams;
|
|
92
|
-
logger.debug(
|
|
93
|
-
{ replacements: oprfRawReplacements.length },
|
|
94
|
-
"applied oprf-raw parameter replacements"
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
assertValidateProviderParams(providerName, params);
|
|
98
|
-
const rslt = await provider.assertValidProviderReceipt({
|
|
99
|
-
receipt: applData,
|
|
100
|
-
params,
|
|
101
|
-
logger,
|
|
102
|
-
ctx: providerCtx
|
|
103
|
-
});
|
|
104
|
-
ctx.providerHash = hashProviderParams(params);
|
|
105
|
-
const extractedParameters = rslt?.extractedParameters || {};
|
|
106
|
-
if (Object.keys(extractedParameters).length) {
|
|
107
|
-
ctx.extractedParameters = extractedParameters;
|
|
108
|
-
}
|
|
109
|
-
info.context = canonicalStringify(ctx) ?? "";
|
|
110
|
-
return info;
|
|
111
|
-
}
|
|
112
|
-
function assertTranscriptsMatch(clientTranscript, tunnelTranscript) {
|
|
113
|
-
const clientSends = concatenateUint8Arrays(
|
|
114
|
-
clientTranscript.filter((m) => m.sender === TranscriptMessageSenderType.TRANSCRIPT_MESSAGE_SENDER_TYPE_CLIENT).map((m) => m.message)
|
|
115
|
-
);
|
|
116
|
-
const tunnelSends = concatenateUint8Arrays(
|
|
117
|
-
tunnelTranscript.filter((m) => m.sender === "client").map((m) => m.message)
|
|
118
|
-
);
|
|
119
|
-
if (!areUint8ArraysEqual(clientSends, tunnelSends)) {
|
|
120
|
-
throw AttestorError.badRequest(
|
|
121
|
-
"Outgoing messages from client do not match the tunnel transcript"
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
const clientRecvs = concatenateUint8Arrays(
|
|
125
|
-
clientTranscript.filter((m) => m.sender === TranscriptMessageSenderType.TRANSCRIPT_MESSAGE_SENDER_TYPE_SERVER).map((m) => m.message)
|
|
126
|
-
);
|
|
127
|
-
const tunnelRecvs = concatenateUint8Arrays(
|
|
128
|
-
tunnelTranscript.filter((m) => m.sender === "server").map((m) => m.message)
|
|
129
|
-
).slice(0, clientRecvs.length);
|
|
130
|
-
if (!areUint8ArraysEqual(clientRecvs, tunnelRecvs)) {
|
|
131
|
-
throw AttestorError.badRequest(
|
|
132
|
-
"Incoming messages from server do not match the tunnel transcript"
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
async function decryptTranscript(transcript, logger, zkEngine, serverIV, clientIV) {
|
|
137
|
-
const {
|
|
138
|
-
tlsVersion,
|
|
139
|
-
cipherSuite,
|
|
140
|
-
hostname,
|
|
141
|
-
nextMsgIndex
|
|
142
|
-
} = await processHandshake(transcript, logger);
|
|
143
|
-
let clientRecordNumber = tlsVersion === "TLS1_3" ? -1 : 0;
|
|
144
|
-
let serverRecordNumber = clientRecordNumber;
|
|
145
|
-
transcript = transcript.slice(nextMsgIndex);
|
|
146
|
-
const overshotMap = {};
|
|
147
|
-
const decryptedTranscript = [];
|
|
148
|
-
const oprfRawReplacements = [];
|
|
149
|
-
const pendingOprfRaw = {};
|
|
150
|
-
for (const [i, {
|
|
151
|
-
sender,
|
|
152
|
-
message,
|
|
153
|
-
reveal: { zkReveal, directReveal } = {}
|
|
154
|
-
}] of transcript.entries()) {
|
|
155
|
-
try {
|
|
156
|
-
await decryptMessage(sender, message, directReveal, zkReveal, i);
|
|
157
|
-
} catch (error) {
|
|
158
|
-
const err = new AttestorError(
|
|
159
|
-
"ERROR_INVALID_CLAIM",
|
|
160
|
-
`error in handling packet at idx ${i}: ${error}`,
|
|
161
|
-
{ packetIdx: i, error }
|
|
162
|
-
);
|
|
163
|
-
if (error.stack) {
|
|
164
|
-
err.stack = error.stack;
|
|
165
|
-
}
|
|
166
|
-
throw err;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
const remainingPending = Object.keys(pendingOprfRaw);
|
|
170
|
-
if (remainingPending.length) {
|
|
171
|
-
throw new AttestorError(
|
|
172
|
-
"ERROR_INVALID_CLAIM",
|
|
173
|
-
`oprf-raw cross-block markers incomplete: pending for packets ${remainingPending.join(", ")}`
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
transcript: decryptedTranscript,
|
|
178
|
-
hostname,
|
|
179
|
-
tlsVersion,
|
|
180
|
-
oprfRawReplacements: oprfRawReplacements.length ? oprfRawReplacements : void 0
|
|
181
|
-
};
|
|
182
|
-
async function decryptMessage(sender, message, directReveal, zkReveal, i) {
|
|
183
|
-
const isServer = sender === TranscriptMessageSenderType.TRANSCRIPT_MESSAGE_SENDER_TYPE_SERVER;
|
|
184
|
-
const recordHeader = message.slice(0, 5);
|
|
185
|
-
const content = getWithoutHeader(message);
|
|
186
|
-
if (isServer) {
|
|
187
|
-
serverRecordNumber++;
|
|
188
|
-
} else {
|
|
189
|
-
clientRecordNumber++;
|
|
190
|
-
}
|
|
191
|
-
let redacted = true;
|
|
192
|
-
let plaintext = void 0;
|
|
193
|
-
let plaintextLength;
|
|
194
|
-
if (directReveal?.key?.length) {
|
|
195
|
-
const result = await decryptDirect(
|
|
196
|
-
directReveal,
|
|
197
|
-
cipherSuite,
|
|
198
|
-
recordHeader,
|
|
199
|
-
tlsVersion,
|
|
200
|
-
content
|
|
201
|
-
);
|
|
202
|
-
plaintext = result.plaintext;
|
|
203
|
-
redacted = false;
|
|
204
|
-
plaintextLength = plaintext.length;
|
|
205
|
-
} else if (zkReveal?.proofs?.length) {
|
|
206
|
-
const iv = sender === TranscriptMessageSenderType.TRANSCRIPT_MESSAGE_SENDER_TYPE_SERVER ? serverIV : clientIV;
|
|
207
|
-
const recordNumber = isServer ? serverRecordNumber : clientRecordNumber;
|
|
208
|
-
const result = await verifyZkPacket(
|
|
209
|
-
{
|
|
210
|
-
ciphertext: content,
|
|
211
|
-
zkReveal,
|
|
212
|
-
iv,
|
|
213
|
-
recordNumber,
|
|
214
|
-
toprfOvershotNullifier: overshotMap[i]?.data,
|
|
215
|
-
getNextPacket(overshot) {
|
|
216
|
-
const nextIdx = transcript.findIndex((t, j) => t.sender === sender && j > i);
|
|
217
|
-
if (nextIdx < 0) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
overshotMap[nextIdx] = { data: overshot };
|
|
221
|
-
return getWithoutHeader(transcript[nextIdx].message);
|
|
222
|
-
},
|
|
223
|
-
logger,
|
|
224
|
-
cipherSuite,
|
|
225
|
-
zkEngine
|
|
226
|
-
}
|
|
227
|
-
);
|
|
228
|
-
plaintext = result.redactedPlaintext;
|
|
229
|
-
const pendingForThis = pendingOprfRaw[i];
|
|
230
|
-
if (pendingForThis && zkReveal?.overshotOprfRawLength) {
|
|
231
|
-
const overshootLen = zkReveal.overshotOprfRawLength;
|
|
232
|
-
const overshootData = plaintext.slice(0, overshootLen);
|
|
233
|
-
const fullData = concatenateUint8Arrays([
|
|
234
|
-
pendingForThis.partialData,
|
|
235
|
-
overshootData
|
|
236
|
-
]);
|
|
237
|
-
const expectedLen = pendingForThis.dataLocation.length;
|
|
238
|
-
if (fullData.length !== expectedLen) {
|
|
239
|
-
throw new AttestorError(
|
|
240
|
-
"ERROR_INVALID_CLAIM",
|
|
241
|
-
`oprf-raw cross-block length mismatch: got ${fullData.length}, expected ${expectedLen}`
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
const oprfResults = await computeOPRFRaw(
|
|
245
|
-
fullData,
|
|
246
|
-
[{ dataLocation: { fromIndex: 0, length: fullData.length } }],
|
|
247
|
-
logger
|
|
248
|
-
);
|
|
249
|
-
if (oprfResults.length) {
|
|
250
|
-
const { nullifier } = oprfResults[0];
|
|
251
|
-
const originalText = new TextDecoder().decode(fullData);
|
|
252
|
-
const nullifierStr = binaryHashToStr(nullifier, fullData.length);
|
|
253
|
-
oprfRawReplacements.push({ originalText, nullifierText: nullifierStr });
|
|
254
|
-
const nullifierBytes = new TextEncoder().encode(nullifierStr);
|
|
255
|
-
const overshootNullifier = nullifierBytes.slice(pendingForThis.partialData.length);
|
|
256
|
-
plaintext.set(overshootNullifier, 0);
|
|
257
|
-
const prevPkt = decryptedTranscript[pendingForThis.originPktIdx];
|
|
258
|
-
if (prevPkt) {
|
|
259
|
-
const firstPartNullifier = nullifierBytes.slice(0, pendingForThis.partialData.length);
|
|
260
|
-
prevPkt.message.set(firstPartNullifier, pendingForThis.dataLocation.fromIndex);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
delete pendingOprfRaw[i];
|
|
264
|
-
}
|
|
265
|
-
if (result.oprfRawMarkers?.length) {
|
|
266
|
-
const { markersThisPacket, pendingMarker } = separateOprfRawMarkers(
|
|
267
|
-
result.oprfRawMarkers,
|
|
268
|
-
plaintext.length,
|
|
269
|
-
() => transcript.findIndex((t, j) => t.sender === sender && j > i),
|
|
270
|
-
decryptedTranscript.length,
|
|
271
|
-
logger
|
|
272
|
-
);
|
|
273
|
-
if (pendingMarker) {
|
|
274
|
-
pendingMarker.pending.partialData.set(
|
|
275
|
-
plaintext.slice(pendingMarker.pending.dataLocation.fromIndex)
|
|
276
|
-
);
|
|
277
|
-
pendingOprfRaw[pendingMarker.nextIdx] = pendingMarker.pending;
|
|
278
|
-
}
|
|
279
|
-
if (markersThisPacket.length) {
|
|
280
|
-
const pt = plaintext;
|
|
281
|
-
const oprfResults = await computeOPRFRaw(pt, markersThisPacket, logger);
|
|
282
|
-
const originalTexts = oprfResults.map(({ dataLocation }) => new TextDecoder().decode(
|
|
283
|
-
pt.slice(dataLocation.fromIndex, dataLocation.fromIndex + dataLocation.length)
|
|
284
|
-
));
|
|
285
|
-
for (const [idx, { dataLocation, nullifier }] of oprfResults.entries()) {
|
|
286
|
-
const originalText = originalTexts[idx];
|
|
287
|
-
const nullifierStr = binaryHashToStr(nullifier, dataLocation.length);
|
|
288
|
-
oprfRawReplacements.push({ originalText, nullifierText: nullifierStr });
|
|
289
|
-
const nullifierBytes = new TextEncoder().encode(nullifierStr);
|
|
290
|
-
pt.set(nullifierBytes, dataLocation.fromIndex);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
redacted = false;
|
|
295
|
-
plaintextLength = plaintext.length;
|
|
296
|
-
} else {
|
|
297
|
-
plaintext = content;
|
|
298
|
-
plaintextLength = plaintext.length;
|
|
299
|
-
}
|
|
300
|
-
decryptedTranscript.push({
|
|
301
|
-
sender: sender === TranscriptMessageSenderType.TRANSCRIPT_MESSAGE_SENDER_TYPE_CLIENT ? "client" : "server",
|
|
302
|
-
redacted,
|
|
303
|
-
message: plaintext,
|
|
304
|
-
recordHeader,
|
|
305
|
-
plaintextLength
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
function getWithoutHeader(message) {
|
|
310
|
-
return message.slice(5);
|
|
311
|
-
}
|
|
312
|
-
function separateOprfRawMarkers(markers, plaintextLength, findNextPacketIdx, currentTranscriptLength, logger) {
|
|
313
|
-
const markersThisPacket = [];
|
|
314
|
-
let pendingMarker;
|
|
315
|
-
for (const marker of markers) {
|
|
316
|
-
const dataLocation = marker.dataLocation;
|
|
317
|
-
if (!dataLocation) {
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
const { fromIndex, length } = dataLocation;
|
|
321
|
-
const endInPacket = fromIndex + length;
|
|
322
|
-
if (endInPacket <= plaintextLength) {
|
|
323
|
-
markersThisPacket.push({ dataLocation });
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
const nextIdx = findNextPacketIdx();
|
|
327
|
-
if (nextIdx < 0) {
|
|
328
|
-
throw new AttestorError(
|
|
329
|
-
"ERROR_INVALID_CLAIM",
|
|
330
|
-
"oprf-raw marker spans packets but no next packet found"
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
pendingMarker = {
|
|
334
|
-
nextIdx,
|
|
335
|
-
pending: {
|
|
336
|
-
partialData: new Uint8Array(plaintextLength - fromIndex),
|
|
337
|
-
dataLocation: { fromIndex, length },
|
|
338
|
-
originPktIdx: currentTranscriptLength
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
logger.debug(
|
|
342
|
-
{ fromIndex, length, partialLen: plaintextLength - fromIndex, nextIdx },
|
|
343
|
-
"oprf-raw marker spans packets, storing partial data"
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
return { markersThisPacket, pendingMarker };
|
|
347
|
-
}
|
|
348
|
-
export {
|
|
349
|
-
assertTranscriptsMatch,
|
|
350
|
-
assertValidClaimRequest,
|
|
351
|
-
assertValidProviderTranscript,
|
|
352
|
-
decryptTranscript,
|
|
353
|
-
getWithoutHeader
|
|
354
|
-
};
|
package/lib/server/utils/dns.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { resolve, setServers } from "dns";
|
|
2
|
-
import { DNS_SERVERS } from "#src/config/index.js";
|
|
3
|
-
setDnsServers();
|
|
4
|
-
async function resolveHostnames(hostname) {
|
|
5
|
-
return new Promise((_resolve, reject) => {
|
|
6
|
-
resolve(hostname, (err, addresses) => {
|
|
7
|
-
if (err) {
|
|
8
|
-
reject(
|
|
9
|
-
new Error(
|
|
10
|
-
`Could not resolve hostname: ${hostname}, ${err.message}`
|
|
11
|
-
)
|
|
12
|
-
);
|
|
13
|
-
} else {
|
|
14
|
-
_resolve(addresses);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
function setDnsServers() {
|
|
20
|
-
setServers(DNS_SERVERS);
|
|
21
|
-
}
|
|
22
|
-
export {
|
|
23
|
-
resolveHostnames
|
|
24
|
-
};
|