routex-settlement 0.1.1
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/index.d.ts +21 -0
- package/index.js +402 -0
- package/package.json +38 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class KeySettlement {
|
|
2
|
+
private _url;
|
|
3
|
+
private _onErrorResponse;
|
|
4
|
+
private _secretKey;
|
|
5
|
+
private _requirements;
|
|
6
|
+
private _yaxiSigningKeys;
|
|
7
|
+
private _serverKey?;
|
|
8
|
+
private _measurement?;
|
|
9
|
+
constructor(url: URL, onErrorResponse: (response: Response) => void);
|
|
10
|
+
private _settle;
|
|
11
|
+
measurement(): Uint8Array | undefined;
|
|
12
|
+
private _getServerKey;
|
|
13
|
+
getBase64SessionId(settlementHeaders?: HeadersInit): Promise<string>;
|
|
14
|
+
seal(plaintext: Uint8Array, settlementHeaders?: HeadersInit): Promise<Uint8Array>;
|
|
15
|
+
unseal(ciphertext: Uint8Array): Uint8Array;
|
|
16
|
+
private _verifyAttestation;
|
|
17
|
+
private _verifyReport;
|
|
18
|
+
private _verifyVcekChain;
|
|
19
|
+
}
|
|
20
|
+
export declare function binaryStringToBytes(binaryString: string): Uint8Array<ArrayBuffer>;
|
|
21
|
+
export declare function bytesToBinaryString(bytes: Uint8Array): string;
|
package/index.js
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { chacha20poly1305 } from "@noble/ciphers/chacha";
|
|
11
|
+
import { bytesToUtf8 } from "@noble/ciphers/utils";
|
|
12
|
+
import { bytesToNumberLE, equalBytes } from "@noble/curves/abstract/utils";
|
|
13
|
+
import { ed25519, x25519 } from "@noble/curves/ed25519";
|
|
14
|
+
import { blake2b } from "@noble/hashes/blake2b";
|
|
15
|
+
import { p384 } from "@noble/curves/p384";
|
|
16
|
+
import { hkdf } from "@noble/hashes/hkdf";
|
|
17
|
+
import { wrapConstructor } from "@noble/hashes/utils";
|
|
18
|
+
import { sha256 } from "@noble/hashes/sha2";
|
|
19
|
+
import * as x509 from "@peculiar/x509";
|
|
20
|
+
import { AsnConvert } from "@peculiar/asn1-schema";
|
|
21
|
+
import { SubjectPublicKeyInfo } from "@peculiar/asn1-x509";
|
|
22
|
+
const REQUIREMENTS = {
|
|
23
|
+
Genoa: {
|
|
24
|
+
minCommittedVersion: [0x1, 0x37, 0x26],
|
|
25
|
+
minCommitedTcbSnp: 0x16,
|
|
26
|
+
},
|
|
27
|
+
Milan: {
|
|
28
|
+
minCommittedVersion: [0x1, 0x37, 0x16],
|
|
29
|
+
minCommitedTcbSnp: 0x17,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const YAXI_SIGNING_KEYS = {
|
|
33
|
+
"AhrUXsV/XAvIE24RQ/Vt/zXoLodvjXoWD2fhLGuRM7U=": new Uint8Array([
|
|
34
|
+
101, 188, 76, 33, 245, 155, 42, 79, 214, 181, 125, 49, 68, 133, 87, 232,
|
|
35
|
+
123, 91, 209, 21, 239, 36, 195, 215, 82, 140, 160, 195, 236, 111, 180, 226,
|
|
36
|
+
]),
|
|
37
|
+
"D30zRYe8Ug9732b4Pe2BAwWAXn/T5Nss2HJOp3kLC1w=": new Uint8Array([
|
|
38
|
+
8, 203, 107, 97, 17, 140, 16, 240, 29, 197, 104, 26, 179, 115, 86, 2, 210,
|
|
39
|
+
73, 107, 211, 46, 34, 89, 174, 117, 193, 126, 215, 12, 133, 106, 37,
|
|
40
|
+
]),
|
|
41
|
+
};
|
|
42
|
+
const ROOT_STORE = new x509.X509ChainBuilder({
|
|
43
|
+
certificates: [
|
|
44
|
+
// ARK-Genoa
|
|
45
|
+
new x509.X509Certificate(`
|
|
46
|
+
-----BEGIN CERTIFICATE-----
|
|
47
|
+
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
|
|
82
|
+
-----END CERTIFICATE-----
|
|
83
|
+
`),
|
|
84
|
+
// SEV-Genoa
|
|
85
|
+
new x509.X509Certificate(`
|
|
86
|
+
-----BEGIN CERTIFICATE-----
|
|
87
|
+
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
|
|
121
|
+
/wMz1R1BHg==
|
|
122
|
+
-----END CERTIFICATE-----
|
|
123
|
+
`),
|
|
124
|
+
// ARK-Milan
|
|
125
|
+
new x509.X509Certificate(`
|
|
126
|
+
-----BEGIN CERTIFICATE-----
|
|
127
|
+
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
|
|
162
|
+
-----END CERTIFICATE-----
|
|
163
|
+
`),
|
|
164
|
+
// SEV-Milan
|
|
165
|
+
new x509.X509Certificate(`
|
|
166
|
+
-----BEGIN CERTIFICATE-----
|
|
167
|
+
MIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC
|
|
168
|
+
BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS
|
|
169
|
+
BgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg
|
|
170
|
+
Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
|
|
171
|
+
Y2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy
|
|
172
|
+
MTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS
|
|
173
|
+
BgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j
|
|
174
|
+
ZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG
|
|
175
|
+
9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg
|
|
176
|
+
W41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta
|
|
177
|
+
1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2
|
|
178
|
+
SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0
|
|
179
|
+
60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05
|
|
180
|
+
gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg
|
|
181
|
+
bKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs
|
|
182
|
+
+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi
|
|
183
|
+
Qi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ
|
|
184
|
+
eTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18
|
|
185
|
+
fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j
|
|
186
|
+
WhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI
|
|
187
|
+
rFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG
|
|
188
|
+
KWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG
|
|
189
|
+
SIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI
|
|
190
|
+
AWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel
|
|
191
|
+
ETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw
|
|
192
|
+
STjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK
|
|
193
|
+
dHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq
|
|
194
|
+
zT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp
|
|
195
|
+
KGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e
|
|
196
|
+
pmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq
|
|
197
|
+
HnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh
|
|
198
|
+
3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn
|
|
199
|
+
JZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH
|
|
200
|
+
CViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4
|
|
201
|
+
AFZEAwoKCQ==
|
|
202
|
+
-----END CERTIFICATE-----
|
|
203
|
+
`),
|
|
204
|
+
],
|
|
205
|
+
});
|
|
206
|
+
export class KeySettlement {
|
|
207
|
+
constructor(url, onErrorResponse) {
|
|
208
|
+
this._requirements = REQUIREMENTS;
|
|
209
|
+
this._yaxiSigningKeys = YAXI_SIGNING_KEYS;
|
|
210
|
+
this._url = url;
|
|
211
|
+
this._onErrorResponse = onErrorResponse;
|
|
212
|
+
this._secretKey = x25519.utils.randomPrivateKey();
|
|
213
|
+
}
|
|
214
|
+
_settle(headers) {
|
|
215
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
216
|
+
const response = yield fetch(this._url, {
|
|
217
|
+
method: "POST",
|
|
218
|
+
headers: headers,
|
|
219
|
+
body: JSON.stringify({
|
|
220
|
+
publicKey: btoa(bytesToBinaryString(x25519.getPublicKey(this._secretKey))),
|
|
221
|
+
}),
|
|
222
|
+
});
|
|
223
|
+
if (response.status >= 400) {
|
|
224
|
+
throw yield this._onErrorResponse(response);
|
|
225
|
+
}
|
|
226
|
+
const responseData = yield response.json();
|
|
227
|
+
const measurement = yield this._verifyAttestation(responseData);
|
|
228
|
+
const settlementBoxMessage = JSON.parse(bytesToUtf8(this.unseal(binaryStringToBytes(atob(responseData.chachaBox)))));
|
|
229
|
+
this._serverKey = [
|
|
230
|
+
binaryStringToBytes(atob(settlementBoxMessage.publicKey)),
|
|
231
|
+
settlementBoxMessage.sessionId,
|
|
232
|
+
];
|
|
233
|
+
this._measurement = measurement;
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
measurement() {
|
|
237
|
+
return this._measurement;
|
|
238
|
+
}
|
|
239
|
+
_getServerKey(settlementHeaders) {
|
|
240
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
241
|
+
if (this._serverKey == null) {
|
|
242
|
+
yield this._settle(settlementHeaders);
|
|
243
|
+
}
|
|
244
|
+
return this._serverKey;
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
getBase64SessionId() {
|
|
248
|
+
return __awaiter(this, arguments, void 0, function* (settlementHeaders = {}) {
|
|
249
|
+
return (yield this._getServerKey(settlementHeaders))[1];
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
seal(plaintext_1) {
|
|
253
|
+
return __awaiter(this, arguments, void 0, function* (plaintext, settlementHeaders = {}) {
|
|
254
|
+
const serverPublicKey = (yield this._getServerKey(settlementHeaders))[0];
|
|
255
|
+
const tagLength = 16;
|
|
256
|
+
const ephemeralSecretKey = x25519.utils.randomPrivateKey();
|
|
257
|
+
const ephemeralPublicKey = x25519.getPublicKey(ephemeralSecretKey);
|
|
258
|
+
const nonce = _getSealNonce(ephemeralPublicKey, serverPublicKey);
|
|
259
|
+
const info = _getInfo(ephemeralPublicKey, serverPublicKey);
|
|
260
|
+
const cipher = _createCipher(serverPublicKey, ephemeralSecretKey, info, nonce);
|
|
261
|
+
const ciphertext = new Uint8Array(ephemeralPublicKey.length + tagLength + plaintext.length);
|
|
262
|
+
ciphertext.set(ephemeralPublicKey);
|
|
263
|
+
ciphertext.set(cipher.encrypt(plaintext), ephemeralPublicKey.length);
|
|
264
|
+
return ciphertext;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
unseal(ciphertext) {
|
|
268
|
+
const ephemeralPublicKey = ciphertext.subarray(0, 32);
|
|
269
|
+
const publicKey = x25519.getPublicKey(this._secretKey);
|
|
270
|
+
const nonce = _getSealNonce(ephemeralPublicKey, publicKey);
|
|
271
|
+
const info = _getInfo(ephemeralPublicKey, publicKey);
|
|
272
|
+
const cipher = _createCipher(ephemeralPublicKey, this._secretKey, info, nonce);
|
|
273
|
+
return cipher.decrypt(ciphertext.subarray(32));
|
|
274
|
+
}
|
|
275
|
+
_verifyAttestation(response) {
|
|
276
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
+
const attestationReport = binaryStringToBytes(atob(response.attestationReport));
|
|
278
|
+
yield this._verifyReport(attestationReport, response.vcek);
|
|
279
|
+
if (!equalBytes(attestationReport.slice(REPORT_OFFSETS.reportData, REPORT_OFFSETS.reportData + 32), sha256(binaryStringToBytes(atob(response.chachaBox))))) {
|
|
280
|
+
throw new Error("Data in attestation report doesn't match chacha box");
|
|
281
|
+
}
|
|
282
|
+
const encoder = new TextEncoder();
|
|
283
|
+
const launchMeasurement = binaryStringToBytes(atob(response.systemVersion.launchMeasurement));
|
|
284
|
+
const input = new Uint8Array([
|
|
285
|
+
...encoder.encode(response.systemVersion.kind),
|
|
286
|
+
...encoder.encode(response.systemVersion.generation.toString()),
|
|
287
|
+
...encoder.encode(response.systemVersion.createdAt.replace("Z", "+00:00")),
|
|
288
|
+
...encoder.encode(response.systemVersion.ref),
|
|
289
|
+
...launchMeasurement,
|
|
290
|
+
]);
|
|
291
|
+
const key = this._yaxiSigningKeys[response.systemVersion.signature.keyId];
|
|
292
|
+
if (key == null) {
|
|
293
|
+
throw new Error("The system version's signature key is unknown");
|
|
294
|
+
}
|
|
295
|
+
if (!ed25519.verify(binaryStringToBytes(atob(response.systemVersion.signature.value)), input, key)) {
|
|
296
|
+
throw new Error("Verification failed: Invalid system version signature");
|
|
297
|
+
}
|
|
298
|
+
if (!equalBytes(attestationReport.slice(REPORT_OFFSETS.measurement, REPORT_OFFSETS.measurement + 48), launchMeasurement)) {
|
|
299
|
+
throw new Error("Reported measurement doesn't match expected measurement");
|
|
300
|
+
}
|
|
301
|
+
return launchMeasurement;
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
_verifyReport(attestationReport, vcekChain) {
|
|
305
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
const { requirements, publicKey } = yield this._verifyVcekChain(vcekChain);
|
|
307
|
+
const sig = {
|
|
308
|
+
r: bytesToNumberLE(attestationReport.slice(REPORT_OFFSETS.signatureR, REPORT_OFFSETS.signatureR + 48)),
|
|
309
|
+
s: bytesToNumberLE(attestationReport.slice(REPORT_OFFSETS.signatureS, REPORT_OFFSETS.signatureS + 48)),
|
|
310
|
+
};
|
|
311
|
+
if (!p384.verify(sig, attestationReport.slice(0, 672), new Uint8Array(publicKey), { prehash: true })) {
|
|
312
|
+
throw new Error("Verification failed: Invalid attestation report signature");
|
|
313
|
+
}
|
|
314
|
+
if ((attestationReport[REPORT_OFFSETS.platInfo] & (1 << 5)) == 0) {
|
|
315
|
+
throw new Error("Verification failed: Alias check complete is false");
|
|
316
|
+
}
|
|
317
|
+
if ([
|
|
318
|
+
attestationReport[REPORT_OFFSETS.committedMajor],
|
|
319
|
+
attestationReport[REPORT_OFFSETS.committedMinor],
|
|
320
|
+
attestationReport[REPORT_OFFSETS.committedBuild],
|
|
321
|
+
] < requirements.minCommittedVersion) {
|
|
322
|
+
throw new Error("Verification failed: Firmware version too small");
|
|
323
|
+
}
|
|
324
|
+
if (attestationReport[REPORT_OFFSETS.committedTcbSnp] <
|
|
325
|
+
requirements.minCommitedTcbSnp) {
|
|
326
|
+
throw new Error("Verification failed: SNP patch level too small");
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
_verifyVcekChain(vcek) {
|
|
331
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
332
|
+
let cert;
|
|
333
|
+
try {
|
|
334
|
+
cert = new x509.X509Certificate(vcek);
|
|
335
|
+
}
|
|
336
|
+
catch (e) {
|
|
337
|
+
throw new Error(`Invalid VCEK: ${e}\n\nVCEK: ${vcek}`);
|
|
338
|
+
}
|
|
339
|
+
const chain = yield ROOT_STORE.build(cert);
|
|
340
|
+
if (chain.length != 3) {
|
|
341
|
+
throw new Error(`Certificate chain verification failed\n\nChain: ${chain}`);
|
|
342
|
+
}
|
|
343
|
+
const productExt = chain[0].extensions.find((ext) => ext.type == "1.3.6.1.4.1.3704.1.2");
|
|
344
|
+
if (!productExt) {
|
|
345
|
+
throw new Error(`Could not find product name\n\nExtensions: ${chain[0].extensions}`);
|
|
346
|
+
}
|
|
347
|
+
const product = String.fromCharCode(...new Uint8Array(productExt.value.slice(2))).split("-", 1)[0];
|
|
348
|
+
if (!(product in this._requirements)) {
|
|
349
|
+
throw new Error(`Unexpected product: ${product}`);
|
|
350
|
+
}
|
|
351
|
+
const subjectPublicKeyInfo = AsnConvert.parse(chain[0].publicKey.rawData, SubjectPublicKeyInfo);
|
|
352
|
+
return {
|
|
353
|
+
requirements: this._requirements[product],
|
|
354
|
+
publicKey: new Uint8Array(subjectPublicKeyInfo.subjectPublicKey),
|
|
355
|
+
};
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
export function binaryStringToBytes(binaryString) {
|
|
360
|
+
const byteArray = new Uint8Array(binaryString.length);
|
|
361
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
362
|
+
byteArray[i] = binaryString.charCodeAt(i);
|
|
363
|
+
}
|
|
364
|
+
return byteArray;
|
|
365
|
+
}
|
|
366
|
+
export function bytesToBinaryString(bytes) {
|
|
367
|
+
let binaryString = "";
|
|
368
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
369
|
+
binaryString += String.fromCharCode(bytes[i]);
|
|
370
|
+
}
|
|
371
|
+
return binaryString;
|
|
372
|
+
}
|
|
373
|
+
function _createCipher(publicKey, secretKey, info, nonce) {
|
|
374
|
+
const sharedSecret = x25519.getSharedSecret(secretKey, publicKey);
|
|
375
|
+
const key = hkdf(wrapConstructor(() => blake2b.create({ dkLen: 64 })), sharedSecret, Uint8Array.from([]), info, 32);
|
|
376
|
+
return chacha20poly1305(key, nonce);
|
|
377
|
+
}
|
|
378
|
+
function _getInfo(ephemeralPublicKey, recipientPublicKey) {
|
|
379
|
+
const info = new Uint8Array(ephemeralPublicKey.length + recipientPublicKey.length);
|
|
380
|
+
info.set(ephemeralPublicKey);
|
|
381
|
+
info.set(recipientPublicKey, ephemeralPublicKey.length);
|
|
382
|
+
return info;
|
|
383
|
+
}
|
|
384
|
+
function _getSealNonce(ephemeralPublicKey, recipientPublicKey) {
|
|
385
|
+
return blake2b
|
|
386
|
+
.create({ dkLen: 12 })
|
|
387
|
+
.update(ephemeralPublicKey)
|
|
388
|
+
.update(recipientPublicKey)
|
|
389
|
+
.digest();
|
|
390
|
+
}
|
|
391
|
+
const REPORT_OFFSETS = {
|
|
392
|
+
sigAlgo: 52,
|
|
393
|
+
platInfo: 64,
|
|
394
|
+
reportData: 80,
|
|
395
|
+
measurement: 144,
|
|
396
|
+
committedTcbSnp: 486,
|
|
397
|
+
committedBuild: 492,
|
|
398
|
+
committedMinor: 493,
|
|
399
|
+
committedMajor: 494,
|
|
400
|
+
signatureR: 672,
|
|
401
|
+
signatureS: 744,
|
|
402
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "routex-settlement",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Key settlement for the YAXI routex client",
|
|
5
|
+
"homepage": "https://yaxi.tech",
|
|
6
|
+
"author": "YAXI GmbH",
|
|
7
|
+
"license": "UNLICENSED",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"module": "./index.js",
|
|
10
|
+
"exports": "./index.js",
|
|
11
|
+
"types": "./index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"index.d.ts",
|
|
14
|
+
"index.js"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc --build",
|
|
18
|
+
"clean": "tsc --build --clean",
|
|
19
|
+
"lint": "eslint",
|
|
20
|
+
"test": "tsc --build && NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@noble/ciphers": "^1.2.1",
|
|
24
|
+
"@noble/curves": "^1.8.1",
|
|
25
|
+
"@noble/hashes": "^1.7.1",
|
|
26
|
+
"@peculiar/asn1-schema": "^2.3.15",
|
|
27
|
+
"@peculiar/asn1-x509": "^2.3.15",
|
|
28
|
+
"@peculiar/x509": "^1.12.3"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/js": "^9.21.0",
|
|
32
|
+
"eslint": "^9.21.0",
|
|
33
|
+
"globals": "^16.0.0",
|
|
34
|
+
"jest": "^29.7.0",
|
|
35
|
+
"typescript": "^5.7.3",
|
|
36
|
+
"typescript-eslint": "^8.24.1"
|
|
37
|
+
}
|
|
38
|
+
}
|