@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 +12 -0
- package/dist/src/block.d.ts +18 -0
- package/dist/src/block.d.ts.map +1 -1
- package/dist/src/block.js +30 -13
- package/dist/src/block.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
- package/src/block.ts +48 -14
- package/src/index.ts +2 -0
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.
|
package/dist/src/block.d.ts
CHANGED
|
@@ -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;
|
package/dist/src/block.d.ts.map
CHANGED
|
@@ -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,
|
|
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 {
|
|
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
|
-
|
|
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) {
|
package/dist/src/block.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAc,
|
|
1
|
+
{"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/block.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -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
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -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
|
package/dist/src/index.js.map
CHANGED
|
@@ -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
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,
|
|
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
|
-
|
|
103
|
+
return createUnsafe({
|
|
66
104
|
bytes,
|
|
105
|
+
cid: resolved,
|
|
67
106
|
codec,
|
|
68
|
-
|
|
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>,
|