@t2000/sdk 5.19.0 → 5.20.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/index.cjs CHANGED
@@ -2113,6 +2113,64 @@ function verifyReceiptSignature(receipt, signingKeyHex) {
2113
2113
  return false;
2114
2114
  }
2115
2115
  }
2116
+ async function verifyTdxQuote(base, model, receiptWorkloadId) {
2117
+ let nonce;
2118
+ try {
2119
+ nonce = utils$1.bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32)));
2120
+ } catch {
2121
+ return { status: "skip", detail: "no secure RNG available", forged: false };
2122
+ }
2123
+ let report;
2124
+ try {
2125
+ const res = await fetch(
2126
+ `${base}/aci/attestation?model=${encodeURIComponent(model)}&nonce=${nonce}`
2127
+ );
2128
+ if (res.ok) {
2129
+ report = (await res.json()).report;
2130
+ }
2131
+ } catch {
2132
+ }
2133
+ const quoteHex = report?.attestation?.evidence?.quote;
2134
+ if (!quoteHex) {
2135
+ return {
2136
+ status: "skip",
2137
+ detail: "attestation report (with quote) unavailable \u2014 pass --model?",
2138
+ forged: false
2139
+ };
2140
+ }
2141
+ try {
2142
+ const { getCollateralAndVerify } = await import('@phala/dcap-qvl');
2143
+ const quoteBytes = utils$1.hexToBytes(quoteHex.replace(/^0x/, ""));
2144
+ const vr = await getCollateralAndVerify(quoteBytes);
2145
+ const td = vr.report.asTd10() ?? vr.report.asTd15()?.base ?? null;
2146
+ const reportData = td?.reportData;
2147
+ const signingAddr = report?.signing_address?.replace(/^0x/, "").toLowerCase();
2148
+ const addrBound = Boolean(
2149
+ reportData && signingAddr && utils$1.bytesToHex(reportData.slice(0, 20)) === signingAddr
2150
+ );
2151
+ const workloadMatch = report?.workload_id === receiptWorkloadId;
2152
+ const tcb = vr.status;
2153
+ const tcbBad = tcb === "Revoked" || tcb === "Unknown";
2154
+ const forged = !(addrBound && workloadMatch) || tcbBad;
2155
+ let detail;
2156
+ if (forged && tcbBad) {
2157
+ detail = `genuine TDX but TCB ${tcb}`;
2158
+ } else if (!addrBound) {
2159
+ detail = "report_data does NOT commit the report's signing address";
2160
+ } else if (!workloadMatch) {
2161
+ detail = "quote workload_id does not match the receipt's";
2162
+ } else {
2163
+ detail = `genuine Intel TDX (verified vs Intel collateral), TCB ${tcb}; report_data commits the attested signing address`;
2164
+ }
2165
+ return { status: forged ? "fail" : "pass", forged, tcbStatus: tcb, detail };
2166
+ } catch (e) {
2167
+ return {
2168
+ status: "fail",
2169
+ forged: false,
2170
+ detail: `could not verify the quote: ${e instanceof Error ? e.message : "error"}`
2171
+ };
2172
+ }
2173
+ }
2116
2174
  async function verifyReceipt(receiptId, opts = {}) {
2117
2175
  const base = opts.apiBase ?? DEFAULT_API_BASE;
2118
2176
  const network = opts.network ?? "mainnet";
@@ -2237,9 +2295,31 @@ async function verifyReceipt(receiptId, opts = {}) {
2237
2295
  detail: sigDetail,
2238
2296
  trust: sigStatus === "skip" ? "roadmap" : "trustless"
2239
2297
  });
2298
+ let quoteForged = false;
2299
+ if (opts.skipQuote) {
2300
+ checks.push({
2301
+ name: "TDX quote (DCAP)",
2302
+ status: "skip",
2303
+ detail: "skipped (--quick)",
2304
+ trust: "trustless"
2305
+ });
2306
+ } else {
2307
+ const q = await verifyTdxQuote(
2308
+ base,
2309
+ opts.model ?? "phala/glm-5.2",
2310
+ workloadId ?? ""
2311
+ );
2312
+ quoteForged = q.forged;
2313
+ checks.push({
2314
+ name: "TDX quote (DCAP)",
2315
+ status: q.status,
2316
+ detail: q.detail,
2317
+ trust: "trustless"
2318
+ });
2319
+ }
2240
2320
  return {
2241
2321
  receiptId,
2242
- verified: Boolean(wireHash && workloadId) && anchorVerified && !signatureForged,
2322
+ verified: Boolean(wireHash && workloadId) && anchorVerified && !signatureForged && !quoteForged,
2243
2323
  anchorVerified,
2244
2324
  checks,
2245
2325
  wireHash,