@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.d.cts CHANGED
@@ -112,6 +112,8 @@ interface VerifyOptions {
112
112
  /** Confidential model id for fetching the attested receipt-signing key
113
113
  * (default `phala/glm-5.2`; the gateway key is workload-wide). */
114
114
  model?: string;
115
+ /** Skip the local DCAP quote verification (the slower, network-bound check). */
116
+ skipQuote?: boolean;
115
117
  }
116
118
  /**
117
119
  * Verify a confidential response by its receipt id. Reads the signed receipt
package/dist/index.d.ts CHANGED
@@ -112,6 +112,8 @@ interface VerifyOptions {
112
112
  /** Confidential model id for fetching the attested receipt-signing key
113
113
  * (default `phala/glm-5.2`; the gateway key is workload-wide). */
114
114
  model?: string;
115
+ /** Skip the local DCAP quote verification (the slower, network-bound check). */
116
+ skipQuote?: boolean;
115
117
  }
116
118
  /**
117
119
  * Verify a confidential response by its receipt id. Reads the signed receipt
package/dist/index.js CHANGED
@@ -2107,6 +2107,64 @@ function verifyReceiptSignature(receipt, signingKeyHex) {
2107
2107
  return false;
2108
2108
  }
2109
2109
  }
2110
+ async function verifyTdxQuote(base, model, receiptWorkloadId) {
2111
+ let nonce;
2112
+ try {
2113
+ nonce = bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(32)));
2114
+ } catch {
2115
+ return { status: "skip", detail: "no secure RNG available", forged: false };
2116
+ }
2117
+ let report;
2118
+ try {
2119
+ const res = await fetch(
2120
+ `${base}/aci/attestation?model=${encodeURIComponent(model)}&nonce=${nonce}`
2121
+ );
2122
+ if (res.ok) {
2123
+ report = (await res.json()).report;
2124
+ }
2125
+ } catch {
2126
+ }
2127
+ const quoteHex = report?.attestation?.evidence?.quote;
2128
+ if (!quoteHex) {
2129
+ return {
2130
+ status: "skip",
2131
+ detail: "attestation report (with quote) unavailable \u2014 pass --model?",
2132
+ forged: false
2133
+ };
2134
+ }
2135
+ try {
2136
+ const { getCollateralAndVerify } = await import('@phala/dcap-qvl');
2137
+ const quoteBytes = hexToBytes(quoteHex.replace(/^0x/, ""));
2138
+ const vr = await getCollateralAndVerify(quoteBytes);
2139
+ const td = vr.report.asTd10() ?? vr.report.asTd15()?.base ?? null;
2140
+ const reportData = td?.reportData;
2141
+ const signingAddr = report?.signing_address?.replace(/^0x/, "").toLowerCase();
2142
+ const addrBound = Boolean(
2143
+ reportData && signingAddr && bytesToHex(reportData.slice(0, 20)) === signingAddr
2144
+ );
2145
+ const workloadMatch = report?.workload_id === receiptWorkloadId;
2146
+ const tcb = vr.status;
2147
+ const tcbBad = tcb === "Revoked" || tcb === "Unknown";
2148
+ const forged = !(addrBound && workloadMatch) || tcbBad;
2149
+ let detail;
2150
+ if (forged && tcbBad) {
2151
+ detail = `genuine TDX but TCB ${tcb}`;
2152
+ } else if (!addrBound) {
2153
+ detail = "report_data does NOT commit the report's signing address";
2154
+ } else if (!workloadMatch) {
2155
+ detail = "quote workload_id does not match the receipt's";
2156
+ } else {
2157
+ detail = `genuine Intel TDX (verified vs Intel collateral), TCB ${tcb}; report_data commits the attested signing address`;
2158
+ }
2159
+ return { status: forged ? "fail" : "pass", forged, tcbStatus: tcb, detail };
2160
+ } catch (e) {
2161
+ return {
2162
+ status: "fail",
2163
+ forged: false,
2164
+ detail: `could not verify the quote: ${e instanceof Error ? e.message : "error"}`
2165
+ };
2166
+ }
2167
+ }
2110
2168
  async function verifyReceipt(receiptId, opts = {}) {
2111
2169
  const base = opts.apiBase ?? DEFAULT_API_BASE;
2112
2170
  const network = opts.network ?? "mainnet";
@@ -2231,9 +2289,31 @@ async function verifyReceipt(receiptId, opts = {}) {
2231
2289
  detail: sigDetail,
2232
2290
  trust: sigStatus === "skip" ? "roadmap" : "trustless"
2233
2291
  });
2292
+ let quoteForged = false;
2293
+ if (opts.skipQuote) {
2294
+ checks.push({
2295
+ name: "TDX quote (DCAP)",
2296
+ status: "skip",
2297
+ detail: "skipped (--quick)",
2298
+ trust: "trustless"
2299
+ });
2300
+ } else {
2301
+ const q = await verifyTdxQuote(
2302
+ base,
2303
+ opts.model ?? "phala/glm-5.2",
2304
+ workloadId ?? ""
2305
+ );
2306
+ quoteForged = q.forged;
2307
+ checks.push({
2308
+ name: "TDX quote (DCAP)",
2309
+ status: q.status,
2310
+ detail: q.detail,
2311
+ trust: "trustless"
2312
+ });
2313
+ }
2234
2314
  return {
2235
2315
  receiptId,
2236
- verified: Boolean(wireHash && workloadId) && anchorVerified && !signatureForged,
2316
+ verified: Boolean(wireHash && workloadId) && anchorVerified && !signatureForged && !quoteForged,
2237
2317
  anchorVerified,
2238
2318
  checks,
2239
2319
  wireHash,