@peerbit/blocks-interface 2.1.2 → 2.1.3

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/README.md CHANGED
@@ -1,3 +1,15 @@
1
1
  # Direct block interface
2
2
 
3
3
  Message types for the Block swap/share protocol
4
+
5
+ ## Verifying opaque block bytes
6
+
7
+ Use `verifyBlockBytes` when a transport or store only needs to validate and
8
+ forward opaque bytes. It checks the CID version, codec code, and multihash
9
+ without decoding the block value. Logical decoding should happen later, at the
10
+ consumer boundary, after the bytes are authenticated.
11
+
12
+ `checkDecodeBlock` also verifies the digest before invoking a codec. A matching
13
+ DAG-CBOR block can still allocate its decoded object graph, so callers handling
14
+ attacker-selected CIDs should prefer `verifyBlockBytes` unless they explicitly
15
+ need the logical value and enforce suitable resource bounds.
@@ -12,8 +12,26 @@ export declare const codecMap: {
12
12
  raw: typeof raw;
13
13
  "dag-cbor": typeof dagCbor;
14
14
  };
15
+ export type VerifyBlockBytesOptions = {
16
+ hasher?: MultihashHasher<number>;
17
+ /**
18
+ * The codec expected by the caller. Only its multicodec code is consulted;
19
+ * verification deliberately does not decode untrusted block bytes.
20
+ */
21
+ codec?: {
22
+ code: number;
23
+ };
24
+ };
15
25
  export declare const cidifyString: (str: string) => CID;
16
26
  export declare const stringifyCid: (cid: any) => string;
27
+ /**
28
+ * Verify that bytes match a CID without decoding their logical value.
29
+ *
30
+ * This is the appropriate boundary for transports and block stores that only
31
+ * move opaque bytes. In particular, it prevents a mismatching DAG-CBOR payload
32
+ * from allocating a decoded object graph before its digest is rejected.
33
+ */
34
+ export declare const verifyBlockBytes: (expectedCID: CID | string, bytes: Uint8Array, options?: VerifyBlockBytesOptions) => Promise<CID>;
17
35
  export declare const checkDecodeBlock: (expectedCID: CID | string, bytes: Uint8Array, options: {
18
36
  hasher?: any;
19
37
  codec?: any;
@@ -1 +1 @@
1
- {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,KAAK,KAAK,EAAkB,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAOrE,eAAO,MAAM,aAAa,6DAAS,CAAC;AAEpC,eAAO,MAAM,UAAU;;;CAGtB,CAAC;AACF,eAAO,MAAM,QAAQ;;;CAGpB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,GAM1C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,GAAG,KAAG,MASvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC5B,aAAa,GAAG,GAAG,MAAM,EACzB,OAAO,UAAU,EACjB,SAAS;IAAE,MAAM,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAA;CAAE,KACpC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CA2BnC,CAAC;AACF,eAAO,MAAM,aAAa,GAAU,CAAC,EACpC,OAAO,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9B,QAAQ,MAAM,EAAE,KACd,OAAO,CAAC,CAAC,CAiBX,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,MAAM,EAAE,QAazE,CAAC;AAEF,eAAO,MAAM,WAAW,GACvB,OAAO,GAAG,EACV,QAAQ,MAAM,EACd,UAAU;IACT,MAAM,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,KACC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CASnC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,OAAO,UAAU;;;EAYtD,CAAC"}
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,KAAK,KAAK,EAAwB,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAOrE,eAAO,MAAM,aAAa,6DAAS,CAAC;AAEpC,eAAO,MAAM,UAAU;;;CAGtB,CAAC;AACF,eAAO,MAAM,QAAQ;;;CAGpB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,GAM1C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,GAAG,KAAG,MASvC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAC5B,aAAa,GAAG,GAAG,MAAM,EACzB,OAAO,UAAU,EACjB,UAAS,uBAA4B,KACnC,OAAO,CAAC,GAAG,CAkBb,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC5B,aAAa,GAAG,GAAG,MAAM,EACzB,OAAO,UAAU,EACjB,SAAS;IAAE,MAAM,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAA;CAAE,KACpC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAqBnC,CAAC;AACF,eAAO,MAAM,aAAa,GAAU,CAAC,EACpC,OAAO,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9B,QAAQ,MAAM,EAAE,KACd,OAAO,CAAC,CAAC,CAiBX,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,MAAM,EAAE,QAazE,CAAC;AAEF,eAAO,MAAM,WAAW,GACvB,OAAO,GAAG,EACV,QAAQ,MAAM,EACd,UAAU;IACT,MAAM,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,KACC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CASnC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,OAAO,UAAU;;;EAYtD,CAAC"}
package/dist/src/block.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as dagCbor from "@ipld/dag-cbor";
2
2
  import { CID } from "multiformats";
3
3
  import { base58btc } from "multiformats/bases/base58";
4
- import { decode, encode } from "multiformats/block";
4
+ import { createUnsafe, encode } from "multiformats/block";
5
5
  import * as raw from "multiformats/codecs/raw";
6
6
  import { sha256 } from "multiformats/hashes/sha2";
7
7
  const unsupportedCodecError = () => new Error("unsupported codec");
@@ -30,31 +30,48 @@ export const stringifyCid = (cid) => {
30
30
  }
31
31
  return cid.toString(defaultBase);
32
32
  };
33
+ /**
34
+ * Verify that bytes match a CID without decoding their logical value.
35
+ *
36
+ * This is the appropriate boundary for transports and block stores that only
37
+ * move opaque bytes. In particular, it prevents a mismatching DAG-CBOR payload
38
+ * from allocating a decoded object graph before its digest is rejected.
39
+ */
40
+ export const verifyBlockBytes = async (expectedCID, bytes, options = {}) => {
41
+ const cidObject = typeof expectedCID === "string" ? cidifyString(expectedCID) : expectedCID;
42
+ const codec = options.codec || codecCodes[cidObject.code];
43
+ if (!codec) {
44
+ throw unsupportedCodecError();
45
+ }
46
+ if (codec.code !== cidObject.code) {
47
+ throw new Error("CID codec does not match");
48
+ }
49
+ const digest = await (options.hasher || defaultHasher).digest(bytes);
50
+ const resolved = CID.create(cidObject.version, codec.code, digest);
51
+ if (!resolved.equals(cidObject)) {
52
+ throw new Error("CID does not match");
53
+ }
54
+ return resolved;
55
+ };
33
56
  export const checkDecodeBlock = async (expectedCID, bytes, options) => {
34
57
  const cidObject = typeof expectedCID === "string" ? cidifyString(expectedCID) : expectedCID;
35
58
  const codec = options.codec || codecCodes[cidObject.code];
59
+ const resolved = await verifyBlockBytes(cidObject, bytes, {
60
+ codec,
61
+ hasher: options.hasher,
62
+ });
36
63
  if (codec?.code === raw.code) {
37
- const hasher = options?.hasher || defaultHasher;
38
- const digest = await hasher.digest(bytes);
39
- const resolved = CID.create(cidObject.version, raw.code, digest);
40
- if (!resolved.equals(cidObject)) {
41
- throw new Error("CID does not match");
42
- }
43
64
  return {
44
65
  bytes,
45
66
  cid: resolved,
46
67
  value: bytes,
47
68
  };
48
69
  }
49
- const block = await decode({
70
+ return createUnsafe({
50
71
  bytes,
72
+ cid: resolved,
51
73
  codec,
52
- hasher: options?.hasher || defaultHasher,
53
74
  });
54
- if (!block.cid.equals(cidObject)) {
55
- throw new Error("CID does not match");
56
- }
57
- return block;
58
75
  };
59
76
  export const getBlockValue = async (block, links) => {
60
77
  if (block.cid.code === dagCbor.code) {
@@ -1 +1 @@
1
- {"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"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"}
@@ -49,5 +49,6 @@ export interface Blocks extends WaitForPeer {
49
49
  size(): MaybePromise<number>;
50
50
  persisted(): MaybePromise<boolean>;
51
51
  }
52
- export { cidifyString, stringifyCid, createBlock, getBlockValue, calculateRawCid, checkDecodeBlock, codecCodes, defaultHasher, codecMap, } from "./block.js";
52
+ export { cidifyString, stringifyCid, createBlock, getBlockValue, calculateRawCid, checkDecodeBlock, verifyBlockBytes, codecCodes, defaultHasher, codecMap, } from "./block.js";
53
+ export type { VerifyBlockBytesOptions } from "./block.js";
53
54
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG;IACxB,MAAM,CAAC,EACJ;QACA,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACjB,GACD,OAAO,CAAC;CACX,CAAC;AACF,MAAM,MAAM,UAAU,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAEtC,MAAM,WAAW,MAAO,SAAQ,WAAW;IAC1C,GAAG,CACF,IAAI,EAAE,UAAU,GAAG;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAClE,YAAY,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,CAAC,CACP,IAAI,EAAE,KAAK,CAAC,UAAU,GAAG;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,GACzE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAChE,YAAY,CAAC,CACZ,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,GACtD,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACxC;;;;;OAKG;IACH,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC7E,OAAO,CAAC,CACP,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,UAAU,GAClB,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC;IAC/C;;;;OAIG;IACH,aAAa,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvD,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;CACnC;AAED,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,GACR,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG;IACxB,MAAM,CAAC,EACJ;QACA,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACjB,GACD,OAAO,CAAC;CACX,CAAC;AACF,MAAM,MAAM,UAAU,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAEtC,MAAM,WAAW,MAAO,SAAQ,WAAW;IAC1C,GAAG,CACF,IAAI,EAAE,UAAU,GAAG;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAClE,YAAY,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,CAAC,CACP,IAAI,EAAE,KAAK,CAAC,UAAU,GAAG;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,GACzE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAChE,YAAY,CAAC,CACZ,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,GACtD,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACxC;;;;;OAKG;IACH,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC7E,OAAO,CAAC,CACP,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,UAAU,GAClB,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC;IAC/C;;;;OAIG;IACH,aAAa,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvD,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,QAAQ,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;CACnC;AAED,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,GACR,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import {} from "@peerbit/stream-interface";
2
2
  import {} from "multiformats/block";
3
- export { cidifyString, stringifyCid, createBlock, getBlockValue, calculateRawCid, checkDecodeBlock, codecCodes, defaultHasher, codecMap, } from "./block.js";
3
+ export { cidifyString, stringifyCid, createBlock, getBlockValue, calculateRawCid, checkDecodeBlock, verifyBlockBytes, codecCodes, defaultHasher, codecMap, } from "./block.js";
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAc,MAAM,oBAAoB,CAAC;AA2DhD,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,GACR,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAc,MAAM,oBAAoB,CAAC;AA2DhD,OAAO,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,GACR,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/blocks-interface",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Block store streaming",
5
5
  "type": "module",
6
6
  "sideEffects": false,
package/src/block.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as dagCbor from "@ipld/dag-cbor";
2
2
  import { CID } from "multiformats";
3
3
  import { base58btc } from "multiformats/bases/base58";
4
- import { type Block, decode, encode } from "multiformats/block";
4
+ import { type Block, createUnsafe, encode } from "multiformats/block";
5
5
  import * as raw from "multiformats/codecs/raw";
6
6
  import type { MultihashHasher } from "multiformats/hashes/interface";
7
7
  import { sha256 } from "multiformats/hashes/sha2";
@@ -21,6 +21,15 @@ export const codecMap = {
21
21
  "dag-cbor": dagCbor,
22
22
  };
23
23
 
24
+ export type VerifyBlockBytesOptions = {
25
+ hasher?: MultihashHasher<number>;
26
+ /**
27
+ * The codec expected by the caller. Only its multicodec code is consulted;
28
+ * verification deliberately does not decode untrusted block bytes.
29
+ */
30
+ codec?: { code: number };
31
+ };
32
+
24
33
  export const cidifyString = (str: string): CID => {
25
34
  if (!str) {
26
35
  return str as any as CID; // TODO fix types
@@ -40,6 +49,37 @@ export const stringifyCid = (cid: any): string => {
40
49
  return cid.toString(defaultBase);
41
50
  };
42
51
 
52
+ /**
53
+ * Verify that bytes match a CID without decoding their logical value.
54
+ *
55
+ * This is the appropriate boundary for transports and block stores that only
56
+ * move opaque bytes. In particular, it prevents a mismatching DAG-CBOR payload
57
+ * from allocating a decoded object graph before its digest is rejected.
58
+ */
59
+ export const verifyBlockBytes = async (
60
+ expectedCID: CID | string,
61
+ bytes: Uint8Array,
62
+ options: VerifyBlockBytesOptions = {},
63
+ ): Promise<CID> => {
64
+ const cidObject =
65
+ typeof expectedCID === "string" ? cidifyString(expectedCID) : expectedCID;
66
+ const codec =
67
+ options.codec || codecCodes[cidObject.code as keyof typeof codecCodes];
68
+ if (!codec) {
69
+ throw unsupportedCodecError();
70
+ }
71
+ if (codec.code !== cidObject.code) {
72
+ throw new Error("CID codec does not match");
73
+ }
74
+
75
+ const digest = await (options.hasher || defaultHasher).digest(bytes);
76
+ const resolved = CID.create(cidObject.version, codec.code, digest);
77
+ if (!resolved.equals(cidObject)) {
78
+ throw new Error("CID does not match");
79
+ }
80
+ return resolved;
81
+ };
82
+
43
83
  export const checkDecodeBlock = async (
44
84
  expectedCID: CID | string,
45
85
  bytes: Uint8Array,
@@ -49,28 +89,22 @@ export const checkDecodeBlock = async (
49
89
  typeof expectedCID === "string" ? cidifyString(expectedCID) : expectedCID;
50
90
  const codec =
51
91
  options.codec || codecCodes[cidObject.code as keyof typeof codecCodes];
92
+ const resolved = await verifyBlockBytes(cidObject, bytes, {
93
+ codec,
94
+ hasher: options.hasher,
95
+ });
52
96
  if (codec?.code === raw.code) {
53
- const hasher = options?.hasher || defaultHasher;
54
- const digest = await hasher.digest(bytes);
55
- const resolved = CID.create(cidObject.version, raw.code, digest);
56
- if (!resolved.equals(cidObject)) {
57
- throw new Error("CID does not match");
58
- }
59
97
  return {
60
98
  bytes,
61
99
  cid: resolved,
62
100
  value: bytes,
63
101
  } as Block<Uint8Array, typeof raw.code, number, 1>;
64
102
  }
65
- const block = await decode({
103
+ return createUnsafe({
66
104
  bytes,
105
+ cid: resolved,
67
106
  codec,
68
- hasher: options?.hasher || defaultHasher,
69
- });
70
- if (!block.cid.equals(cidObject)) {
71
- throw new Error("CID does not match");
72
- }
73
- return block as Block<any, any, any, 1>;
107
+ }) as Block<any, any, any, 1>;
74
108
  };
75
109
  export const getBlockValue = async <T>(
76
110
  block: Block<T, any, any, any>,
package/src/index.ts CHANGED
@@ -65,7 +65,9 @@ export {
65
65
  getBlockValue,
66
66
  calculateRawCid,
67
67
  checkDecodeBlock,
68
+ verifyBlockBytes,
68
69
  codecCodes,
69
70
  defaultHasher,
70
71
  codecMap,
71
72
  } from "./block.js";
73
+ export type { VerifyBlockBytesOptions } from "./block.js";