@calimero-network/mero-js 19.27.0 → 20.0.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.mjs CHANGED
@@ -7065,17 +7065,32 @@ async function defaultNonceSource(deviceSecret) {
7065
7065
 
7066
7066
  // src/sealed/verify.ts
7067
7067
  var MEASUREMENT_HEX = /^[0-9a-f]{96}$/;
7068
+ var REGISTERS = ["mrtd", "rtmr0", "rtmr1", "rtmr2", "rtmr3"];
7068
7069
  function createQuoteVerifier(options) {
7069
- const allowedMrtd = measurements(options.allowedMrtd, "allowedMrtd");
7070
- if (allowedMrtd.length === 0) {
7071
- throw new Error("allowedMrtd is empty, so no quote would ever be accepted");
7072
- }
7070
+ const allowedMrtd = measurements(options.allowedMrtd ?? [], "allowedMrtd");
7071
+ const allowedImages = (options.allowedMeasurements ?? []).map((image, index) => {
7072
+ const label = `allowedMeasurements[${index}]`;
7073
+ return REGISTERS.map((register) => measurements([image?.[register] ?? ""], `${label}.${register}`)[0]).join();
7074
+ });
7073
7075
  const allowedRtmr = [
7074
7076
  measurements(options.allowedRtmr0 ?? [], "allowedRtmr0"),
7075
7077
  measurements(options.allowedRtmr1 ?? [], "allowedRtmr1"),
7076
7078
  measurements(options.allowedRtmr2 ?? [], "allowedRtmr2"),
7077
7079
  measurements(options.allowedRtmr3 ?? [], "allowedRtmr3")
7078
7080
  ];
7081
+ if (options.allowedMeasurements !== void 0 && allowedImages.length === 0) {
7082
+ throw new Error("allowedMeasurements is empty, so no quote would ever be accepted");
7083
+ }
7084
+ if (allowedImages.length === 0) {
7085
+ if (allowedMrtd.length === 0) {
7086
+ throw new Error("No image is trusted: give allowedMeasurements, or allowedMrtd with allowedRtmr1-3");
7087
+ }
7088
+ if (allowedRtmr.slice(1).some((list) => list.length === 0)) {
7089
+ throw new Error(
7090
+ "allowedMrtd alone does not name an image: the MRTD measures the TD firmware, which images share, and the image is in RTMR1-3. Give allowedMeasurements, or allowedRtmr1-3 too"
7091
+ );
7092
+ }
7093
+ }
7079
7094
  const allowedStatuses = options.allowedTcbStatuses ?? ["UpToDate"];
7080
7095
  const now = options.now ?? Date.now;
7081
7096
  const verifier = async ({
@@ -7101,8 +7116,14 @@ function createQuoteVerifier(options) {
7101
7116
  throw new Error(`The platform's TCB status is ${verified.status}, which is not accepted`);
7102
7117
  }
7103
7118
  const td = tdReport(verified.report);
7104
- if (!allowedMrtd.includes(hex(td.mrTd))) {
7105
- throw new Error(`MRTD ${hex(td.mrTd)} is not an image this verifier trusts`);
7119
+ const measured = [td.mrTd, td.rtMr0, td.rtMr1, td.rtMr2, td.rtMr3].map((register) => hex(register));
7120
+ if (allowedImages.length > 0 && !allowedImages.includes(measured.join())) {
7121
+ throw new Error(
7122
+ `The measurements (MRTD ${measured[0]}, RTMR0-3 ${measured.slice(1).join(", ")}) are not an image this verifier trusts`
7123
+ );
7124
+ }
7125
+ if (allowedMrtd.length > 0 && !allowedMrtd.includes(measured[0])) {
7126
+ throw new Error(`MRTD ${measured[0]} is not an image this verifier trusts`);
7106
7127
  }
7107
7128
  const registers = [td.rtMr0, td.rtMr1, td.rtMr2, td.rtMr3];
7108
7129
  registers.forEach((register, index) => {
@@ -7139,6 +7160,51 @@ function fromBase64(value) {
7139
7160
  for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
7140
7161
  return bytes;
7141
7162
  }
7163
+ var TCB_STATUSES = [
7164
+ "UpToDate",
7165
+ "SWHardeningNeeded",
7166
+ "ConfigurationNeeded",
7167
+ "ConfigurationAndSWHardeningNeeded",
7168
+ "OutOfDate",
7169
+ "OutOfDateConfigurationNeeded"
7170
+ ];
7171
+ function trustedMeasurementsFromReleases(releases, { profile }) {
7172
+ if (releases.length === 0) {
7173
+ throw new Error("No release given, so no image would be trusted");
7174
+ }
7175
+ let statuses;
7176
+ const allowedMeasurements = releases.map((release, index) => {
7177
+ const name = release?.tag ?? `releases[${index}]`;
7178
+ if (release?.role !== void 0 && release.role !== "node") {
7179
+ throw new Error(`${name} lists the measurements of a ${release.role}, not of a node image`);
7180
+ }
7181
+ const image = release?.profiles?.[profile];
7182
+ if (!image) {
7183
+ const known = Object.keys(release?.profiles ?? {}).join(", ") || "none";
7184
+ throw new Error(`${name} has no profile ${JSON.stringify(profile)} (it has: ${known})`);
7185
+ }
7186
+ const accepted = (image.allowed_tcb_statuses ?? ["uptodate"]).map((status) => tcbStatus(status, name));
7187
+ statuses = statuses === void 0 ? accepted : statuses.filter((status) => accepted.includes(status));
7188
+ return {
7189
+ mrtd: image.mrtd,
7190
+ rtmr0: image.rtmr0,
7191
+ rtmr1: image.rtmr1,
7192
+ rtmr2: image.rtmr2,
7193
+ rtmr3: image.rtmr3
7194
+ };
7195
+ });
7196
+ if (!statuses || statuses.length === 0) {
7197
+ throw new Error("The releases given accept no TCB status in common");
7198
+ }
7199
+ return { allowedMeasurements, allowedTcbStatuses: statuses };
7200
+ }
7201
+ function tcbStatus(status, release) {
7202
+ const known = TCB_STATUSES.find((candidate) => candidate.toLowerCase() === String(status).toLowerCase());
7203
+ if (!known) {
7204
+ throw new Error(`${release} accepts TCB status ${JSON.stringify(status)}, which this verifier does not know`);
7205
+ }
7206
+ return known;
7207
+ }
7142
7208
 
7143
7209
  // src/namespace-op/namespace-op.ts
7144
7210
  var SIGNED_NAMESPACE_OP_SCHEMA_VERSION = 8;
@@ -7333,17 +7399,14 @@ function audienceLabel(audience) {
7333
7399
  }
7334
7400
  async function login(config) {
7335
7401
  const baseUrl = config.nodeUrl.replace(/\/+$/, "");
7336
- const doFetch = config.fetch ?? globalThis.fetch;
7337
7402
  const timeoutMs = config.timeoutMs ?? 1e4;
7338
7403
  const request = async (path, init) => {
7339
7404
  const controller = new AbortController();
7340
7405
  const timer = setTimeout(() => controller.abort(), timeoutMs);
7341
7406
  let response;
7342
7407
  try {
7343
- response = await doFetch(`${baseUrl}${path}`, {
7344
- ...init,
7345
- signal: controller.signal
7346
- });
7408
+ const requestInit = { ...init, signal: controller.signal };
7409
+ response = config.fetch ? await config.fetch(`${baseUrl}${path}`, requestInit) : await globalThis.fetch(`${baseUrl}${path}`, requestInit);
7347
7410
  } catch (err) {
7348
7411
  throw new HTTPError(
7349
7412
  0,
@@ -7548,6 +7611,7 @@ export {
7548
7611
  signRoutingChallenge,
7549
7612
  signWarrant,
7550
7613
  transportKeyBinding,
7614
+ trustedMeasurementsFromReleases,
7551
7615
  withCap,
7552
7616
  withRetry,
7553
7617
  withoutCap