@calimero-network/mero-js 19.25.0 → 19.26.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/dist/admin-api/admin-client.d.ts +4 -0
- package/dist/admin-api/admin-client.js +4 -0
- package/dist/admin-api/admin-types.d.ts +18 -0
- package/dist/admin-api/admin-types.js +0 -2
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +101 -5
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +101 -5
- package/dist/index.mjs.map +4 -4
- package/dist/sealed/index.d.ts +2 -0
- package/dist/sealed/index.js +1 -0
- package/dist/sealed/noise.js +11 -3
- package/dist/sealed/sealed.d.ts +14 -6
- package/dist/sealed/sealed.js +8 -1
- package/dist/sealed/verify.d.ts +109 -0
- package/dist/sealed/verify.js +116 -0
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -1848,6 +1848,10 @@ var AdminApiClient = class {
|
|
|
1848
1848
|
async teeAttest(request) {
|
|
1849
1849
|
return unwrap(await this.httpClient.post("/admin-api/tee/attest", request));
|
|
1850
1850
|
}
|
|
1851
|
+
/**
|
|
1852
|
+
* @deprecated Nodes no longer serve `/admin-api/tee/verify-quote` (removed in
|
|
1853
|
+
* core#3262), so this fails. Verify quotes with `createQuoteVerifier`.
|
|
1854
|
+
*/
|
|
1851
1855
|
async teeVerifyQuote(request) {
|
|
1852
1856
|
return unwrap(
|
|
1853
1857
|
await this.httpClient.post("/admin-api/tee/verify-quote", request)
|
|
@@ -6646,9 +6650,16 @@ async function initiate(remoteStatic, prologue, fixedEphemeral) {
|
|
|
6646
6650
|
}
|
|
6647
6651
|
async function x25519KeyPair(secret) {
|
|
6648
6652
|
if (!secret) {
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6653
|
+
let pair;
|
|
6654
|
+
try {
|
|
6655
|
+
pair = await crypto.subtle.generateKey({ name: "X25519" }, true, [
|
|
6656
|
+
"deriveBits"
|
|
6657
|
+
]);
|
|
6658
|
+
} catch (error) {
|
|
6659
|
+
throw new Error(
|
|
6660
|
+
`Sealed transport needs WebCrypto with X25519, which this runtime lacks (${error?.name ?? "no crypto.subtle"}). Current browsers and Node have it; in React Native, install react-native-quick-crypto as the global crypto.`
|
|
6661
|
+
);
|
|
6662
|
+
}
|
|
6652
6663
|
const publicKey = new Uint8Array(await crypto.subtle.exportKey("raw", pair.publicKey));
|
|
6653
6664
|
return { privateKey: pair.privateKey, publicKey };
|
|
6654
6665
|
}
|
|
@@ -6741,7 +6752,8 @@ async function fetchAttestedTransportKey(admin, verify, options = {}) {
|
|
|
6741
6752
|
const attested = await admin.teeAttest({
|
|
6742
6753
|
nonce: nonce2,
|
|
6743
6754
|
applicationId: options.applicationId,
|
|
6744
|
-
bindTransportKey: true
|
|
6755
|
+
bindTransportKey: true,
|
|
6756
|
+
...verify.includeCollateral ? { includeCollateral: true } : {}
|
|
6745
6757
|
});
|
|
6746
6758
|
if (!attested.transportPublicKey) {
|
|
6747
6759
|
throw new Error("The node did not report a transport key; it predates sealed transport");
|
|
@@ -6749,7 +6761,13 @@ async function fetchAttestedTransportKey(admin, verify, options = {}) {
|
|
|
6749
6761
|
const transportKey = fromHex(attested.transportPublicKey, "transportPublicKey", 32);
|
|
6750
6762
|
const inner = options.applicationHash ? fromHex(options.applicationHash, "applicationHash", 32) : new Uint8Array(32);
|
|
6751
6763
|
const reportDataSuffix = hex(await transportKeyBinding(inner, transportKey));
|
|
6752
|
-
|
|
6764
|
+
const verified = await verify({
|
|
6765
|
+
quoteB64: attested.quoteB64,
|
|
6766
|
+
nonce: nonce2,
|
|
6767
|
+
reportDataSuffix,
|
|
6768
|
+
collateral: attested.collateral
|
|
6769
|
+
});
|
|
6770
|
+
if (!verified) {
|
|
6753
6771
|
throw new Error("The attestation did not verify, so its transport key is not trusted");
|
|
6754
6772
|
}
|
|
6755
6773
|
return transportKey;
|
|
@@ -7011,6 +7029,83 @@ async function envelopeRefusal(response) {
|
|
|
7011
7029
|
return new SealedTransportError(response.status, code, message, retryAfterMs);
|
|
7012
7030
|
}
|
|
7013
7031
|
|
|
7032
|
+
// src/sealed/verify.ts
|
|
7033
|
+
var MEASUREMENT_HEX = /^[0-9a-f]{96}$/;
|
|
7034
|
+
function createQuoteVerifier(options) {
|
|
7035
|
+
const allowedMrtd = measurements(options.allowedMrtd, "allowedMrtd");
|
|
7036
|
+
if (allowedMrtd.length === 0) {
|
|
7037
|
+
throw new Error("allowedMrtd is empty, so no quote would ever be accepted");
|
|
7038
|
+
}
|
|
7039
|
+
const allowedRtmr = [
|
|
7040
|
+
measurements(options.allowedRtmr0 ?? [], "allowedRtmr0"),
|
|
7041
|
+
measurements(options.allowedRtmr1 ?? [], "allowedRtmr1"),
|
|
7042
|
+
measurements(options.allowedRtmr2 ?? [], "allowedRtmr2"),
|
|
7043
|
+
measurements(options.allowedRtmr3 ?? [], "allowedRtmr3")
|
|
7044
|
+
];
|
|
7045
|
+
const allowedStatuses = options.allowedTcbStatuses ?? ["UpToDate"];
|
|
7046
|
+
const now = options.now ?? Date.now;
|
|
7047
|
+
const verifier = async ({
|
|
7048
|
+
quoteB64,
|
|
7049
|
+
nonce: nonce2,
|
|
7050
|
+
reportDataSuffix,
|
|
7051
|
+
collateral
|
|
7052
|
+
}) => {
|
|
7053
|
+
const quote = fromBase64(quoteB64);
|
|
7054
|
+
const against = collateral ?? await options.fetchCollateral?.(quote);
|
|
7055
|
+
if (!against) {
|
|
7056
|
+
throw new Error(
|
|
7057
|
+
"The node sent no collateral for its quote, and no fetchCollateral was given to get it"
|
|
7058
|
+
);
|
|
7059
|
+
}
|
|
7060
|
+
let verified;
|
|
7061
|
+
try {
|
|
7062
|
+
verified = options.dcapVerify(quote, against, Math.floor(now() / 1e3));
|
|
7063
|
+
} catch (error) {
|
|
7064
|
+
throw new Error(`The quote did not verify: ${error?.message ?? String(error)}`);
|
|
7065
|
+
}
|
|
7066
|
+
if (verified.status === "Revoked" || !allowedStatuses.includes(verified.status)) {
|
|
7067
|
+
throw new Error(`The platform's TCB status is ${verified.status}, which is not accepted`);
|
|
7068
|
+
}
|
|
7069
|
+
const td = tdReport(verified.report);
|
|
7070
|
+
if (!allowedMrtd.includes(hex(td.mrTd))) {
|
|
7071
|
+
throw new Error(`MRTD ${hex(td.mrTd)} is not an image this verifier trusts`);
|
|
7072
|
+
}
|
|
7073
|
+
const registers = [td.rtMr0, td.rtMr1, td.rtMr2, td.rtMr3];
|
|
7074
|
+
registers.forEach((register, index) => {
|
|
7075
|
+
const allowed = allowedRtmr[index];
|
|
7076
|
+
if (allowed.length > 0 && !allowed.includes(hex(register))) {
|
|
7077
|
+
throw new Error(`RTMR${index} ${hex(register)} is not one this verifier trusts`);
|
|
7078
|
+
}
|
|
7079
|
+
});
|
|
7080
|
+
if (hex(td.reportData) !== `${nonce2}${reportDataSuffix}`.toLowerCase()) {
|
|
7081
|
+
throw new Error("The quote does not commit to this nonce and binding");
|
|
7082
|
+
}
|
|
7083
|
+
return true;
|
|
7084
|
+
};
|
|
7085
|
+
return Object.assign(verifier, { includeCollateral: true });
|
|
7086
|
+
}
|
|
7087
|
+
function measurements(values, label) {
|
|
7088
|
+
return values.map((value) => {
|
|
7089
|
+
const normalized = value.trim().toLowerCase();
|
|
7090
|
+
if (!MEASUREMENT_HEX.test(normalized)) {
|
|
7091
|
+
throw new Error(`${label} holds ${JSON.stringify(value)}, which is not a 48-byte hex measurement`);
|
|
7092
|
+
}
|
|
7093
|
+
return normalized;
|
|
7094
|
+
});
|
|
7095
|
+
}
|
|
7096
|
+
function tdReport(report) {
|
|
7097
|
+
const data = report.data;
|
|
7098
|
+
if (report.type === "td10" && data) return data;
|
|
7099
|
+
if (report.type === "td15" && data?.base) return data.base;
|
|
7100
|
+
throw new Error(`The quote is a ${report.type} quote, not a TDX one`);
|
|
7101
|
+
}
|
|
7102
|
+
function fromBase64(value) {
|
|
7103
|
+
const binary = atob(value);
|
|
7104
|
+
const bytes = new Uint8Array(binary.length);
|
|
7105
|
+
for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
|
|
7106
|
+
return bytes;
|
|
7107
|
+
}
|
|
7108
|
+
|
|
7014
7109
|
// src/namespace-op/namespace-op.ts
|
|
7015
7110
|
var SIGNED_NAMESPACE_OP_SCHEMA_VERSION = 8;
|
|
7016
7111
|
var NAMESPACE_SIGN_DOMAIN = new TextEncoder().encode("calimero.namespace.v1");
|
|
@@ -7386,6 +7481,7 @@ export {
|
|
|
7386
7481
|
createNodeAuthApiClient,
|
|
7387
7482
|
createNodeHttpClient,
|
|
7388
7483
|
createProofSigner,
|
|
7484
|
+
createQuoteVerifier,
|
|
7389
7485
|
createRetryableMethod,
|
|
7390
7486
|
createSealedFetch,
|
|
7391
7487
|
createTimeoutSignal,
|