@cello-protocol/daemon 0.0.53 → 0.0.55
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/agent-handlers.d.ts +57 -0
- package/dist/agent-handlers.d.ts.map +1 -0
- package/dist/agent-handlers.js +360 -0
- package/dist/agent-handlers.js.map +1 -0
- package/dist/agent-id-migration.d.ts.map +1 -1
- package/dist/agent-id-migration.js +1 -0
- package/dist/agent-id-migration.js.map +1 -1
- package/dist/agent-loader.d.ts +3 -4
- package/dist/agent-loader.d.ts.map +1 -1
- package/dist/agent-loader.js +3 -4
- package/dist/agent-loader.js.map +1 -1
- package/dist/cbor-blob-migration.d.ts +8 -0
- package/dist/cbor-blob-migration.d.ts.map +1 -0
- package/dist/cbor-blob-migration.js +115 -0
- package/dist/cbor-blob-migration.js.map +1 -0
- package/dist/close-session-handler.d.ts +41 -0
- package/dist/close-session-handler.d.ts.map +1 -0
- package/dist/close-session-handler.js +399 -0
- package/dist/close-session-handler.js.map +1 -0
- package/dist/consortium-bootstrap.d.ts +83 -0
- package/dist/consortium-bootstrap.d.ts.map +1 -0
- package/dist/consortium-bootstrap.js +120 -0
- package/dist/consortium-bootstrap.js.map +1 -0
- package/dist/contact-handlers.d.ts +56 -0
- package/dist/contact-handlers.d.ts.map +1 -0
- package/dist/contact-handlers.js +303 -0
- package/dist/contact-handlers.js.map +1 -0
- package/dist/content-park-client.d.ts.map +1 -1
- package/dist/content-park-client.js +7 -7
- package/dist/content-park-client.js.map +1 -1
- package/dist/content-park.d.ts +15 -0
- package/dist/content-park.d.ts.map +1 -0
- package/dist/content-park.js +227 -0
- package/dist/content-park.js.map +1 -0
- package/dist/daemon.d.ts +4 -10
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +430 -4563
- package/dist/daemon.js.map +1 -1
- package/dist/db-identity-store.d.ts +31 -35
- package/dist/db-identity-store.d.ts.map +1 -1
- package/dist/db-identity-store.js +62 -66
- package/dist/db-identity-store.js.map +1 -1
- package/dist/directory-bootstrap.d.ts +27 -31
- package/dist/directory-bootstrap.d.ts.map +1 -1
- package/dist/directory-bootstrap.js +18 -21
- package/dist/directory-bootstrap.js.map +1 -1
- package/dist/frame-values.d.ts +3 -0
- package/dist/frame-values.d.ts.map +1 -0
- package/dist/frame-values.js +73 -0
- package/dist/frame-values.js.map +1 -0
- package/dist/identity-migration.d.ts +8 -8
- package/dist/identity-migration.d.ts.map +1 -1
- package/dist/identity-migration.js +30 -31
- package/dist/identity-migration.js.map +1 -1
- package/dist/inbound-seal-request.d.ts +17 -0
- package/dist/inbound-seal-request.d.ts.map +1 -0
- package/dist/inbound-seal-request.js +155 -0
- package/dist/inbound-seal-request.js.map +1 -0
- package/dist/inbound-sessions.d.ts +54 -0
- package/dist/inbound-sessions.d.ts.map +1 -0
- package/dist/inbound-sessions.js +603 -0
- package/dist/inbound-sessions.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -10
- package/dist/index.js.map +1 -1
- package/dist/initiate-session-handler.d.ts +22 -0
- package/dist/initiate-session-handler.d.ts.map +1 -0
- package/dist/initiate-session-handler.js +150 -0
- package/dist/initiate-session-handler.js.map +1 -0
- package/dist/network-directory-node.d.ts +6 -6
- package/dist/network-directory-node.d.ts.map +1 -1
- package/dist/network-directory-node.js +29 -28
- package/dist/network-directory-node.js.map +1 -1
- package/dist/notification-handlers.d.ts +32 -0
- package/dist/notification-handlers.d.ts.map +1 -0
- package/dist/notification-handlers.js +73 -0
- package/dist/notification-handlers.js.map +1 -0
- package/dist/outbound-sessions.d.ts +54 -0
- package/dist/outbound-sessions.d.ts.map +1 -0
- package/dist/outbound-sessions.js +429 -0
- package/dist/outbound-sessions.js.map +1 -0
- package/dist/park-envelope.d.ts.map +1 -1
- package/dist/park-envelope.js +3 -2
- package/dist/park-envelope.js.map +1 -1
- package/dist/register-handler.d.ts +35 -0
- package/dist/register-handler.d.ts.map +1 -0
- package/dist/register-handler.js +179 -0
- package/dist/register-handler.js.map +1 -0
- package/dist/registration-manager.d.ts.map +1 -1
- package/dist/registration-manager.js +3 -6
- package/dist/registration-manager.js.map +1 -1
- package/dist/relay-receipt-store.d.ts.map +1 -1
- package/dist/relay-receipt-store.js +1 -2
- package/dist/relay-receipt-store.js.map +1 -1
- package/dist/retry-queue.d.ts +18 -60
- package/dist/retry-queue.d.ts.map +1 -1
- package/dist/retry-queue.js +46 -97
- package/dist/retry-queue.js.map +1 -1
- package/dist/seal-coordinator.d.ts +47 -0
- package/dist/seal-coordinator.d.ts.map +1 -0
- package/dist/seal-coordinator.js +551 -0
- package/dist/seal-coordinator.js.map +1 -0
- package/dist/seal-flows.d.ts +50 -0
- package/dist/seal-flows.d.ts.map +1 -0
- package/dist/seal-flows.js +454 -0
- package/dist/seal-flows.js.map +1 -0
- package/dist/seal-frontier-verify.d.ts +9 -9
- package/dist/seal-frontier-verify.d.ts.map +1 -1
- package/dist/seal-frontier-verify.js +11 -12
- package/dist/seal-frontier-verify.js.map +1 -1
- package/dist/seal-leaf.d.ts +58 -0
- package/dist/seal-leaf.d.ts.map +1 -0
- package/dist/seal-leaf.js +111 -0
- package/dist/seal-leaf.js.map +1 -0
- package/dist/seal-receipt-upgrade.d.ts +1 -1
- package/dist/seal-receipt-upgrade.js +1 -1
- package/dist/seal-upgrade.d.ts +10 -10
- package/dist/seal-upgrade.d.ts.map +1 -1
- package/dist/seal-upgrade.js +23 -24
- package/dist/seal-upgrade.js.map +1 -1
- package/dist/session-assignment-parser.d.ts +16 -19
- package/dist/session-assignment-parser.d.ts.map +1 -1
- package/dist/session-assignment-parser.js +30 -29
- package/dist/session-assignment-parser.js.map +1 -1
- package/dist/session-ceremony.d.ts +3 -6
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +7 -9
- package/dist/session-ceremony.js.map +1 -1
- package/dist/session-connection-gater.d.ts +4 -2
- package/dist/session-connection-gater.d.ts.map +1 -1
- package/dist/session-connection-gater.js +16 -10
- package/dist/session-connection-gater.js.map +1 -1
- package/dist/session-content-handlers.d.ts +25 -0
- package/dist/session-content-handlers.d.ts.map +1 -0
- package/dist/session-content-handlers.js +436 -0
- package/dist/session-content-handlers.js.map +1 -0
- package/dist/session-name.d.ts +35 -0
- package/dist/session-name.d.ts.map +1 -0
- package/dist/session-name.js +60 -0
- package/dist/session-name.js.map +1 -0
- package/dist/session-node-manager.d.ts +47 -62
- package/dist/session-node-manager.d.ts.map +1 -1
- package/dist/session-node-manager.js +297 -97
- package/dist/session-node-manager.js.map +1 -1
- package/dist/session-read-handlers.d.ts +38 -0
- package/dist/session-read-handlers.d.ts.map +1 -0
- package/dist/session-read-handlers.js +233 -0
- package/dist/session-read-handlers.js.map +1 -0
- package/dist/session-relay-client.d.ts +8 -8
- package/dist/session-relay-client.d.ts.map +1 -1
- package/dist/session-relay-client.js +44 -46
- package/dist/session-relay-client.js.map +1 -1
- package/dist/session-tree.d.ts +11 -23
- package/dist/session-tree.d.ts.map +1 -1
- package/dist/session-tree.js +14 -26
- package/dist/session-tree.js.map +1 -1
- package/dist/signaling-connect.d.ts +13 -5
- package/dist/signaling-connect.d.ts.map +1 -1
- package/dist/signaling-connect.js +55 -13
- package/dist/signaling-connect.js.map +1 -1
- package/dist/sqlcipher-db.d.ts +18 -19
- package/dist/sqlcipher-db.d.ts.map +1 -1
- package/dist/sqlcipher-db.js +30 -30
- package/dist/sqlcipher-db.js.map +1 -1
- package/dist/telegram-doorbell.d.ts +38 -0
- package/dist/telegram-doorbell.d.ts.map +1 -0
- package/dist/telegram-doorbell.js +139 -0
- package/dist/telegram-doorbell.js.map +1 -0
- package/dist/types.d.ts +86 -79
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/dist/vocabulary.d.ts +30 -30
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +41 -49
- package/dist/vocabulary.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seal-frontier-verify.js","sourceRoot":"","sources":["../src/seal-frontier-verify.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"seal-frontier-verify.js","sourceRoot":"","sources":["../src/seal-frontier-verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { SealInterruptedLeaf } from "@cello-protocol/protocol-types";
|
|
2
|
+
import type { KeyProvider } from "@cello-protocol/crypto";
|
|
3
|
+
export type SealLeafVerifyReason = "nonce_mismatch" | "leaf_count_mismatch" | "leaf_signature_invalid";
|
|
4
|
+
/**
|
|
5
|
+
* M7-SESSION-001 (H-1): canonical byte encoding of a SEAL-INTERRUPTED leaf for
|
|
6
|
+
* Ed25519 signing/verification. Field order is fixed and deterministic. Both the
|
|
7
|
+
* initiator and the responder, and the verifier, MUST use exactly this encoding —
|
|
8
|
+
* any drift causes silent signature-verification failure.
|
|
9
|
+
*/
|
|
10
|
+
export declare function canonicalSealInterruptedLeafBytes(leaf: {
|
|
11
|
+
type: string;
|
|
12
|
+
sessionId: string;
|
|
13
|
+
leafCount: number;
|
|
14
|
+
merkleRootAtInterruption: string;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
signerPubkey: string;
|
|
17
|
+
}): Uint8Array;
|
|
18
|
+
/**
|
|
19
|
+
* M7-SESSION-001 (H-1): construct and K_local-sign a SEAL-INTERRUPTED leaf.
|
|
20
|
+
* The private key never leaves keyProvider — only the Ed25519 signature is returned.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildSignedSealInterruptedLeaf(keyProvider: KeyProvider, opts: {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
leafCount: number;
|
|
25
|
+
merkleRootAtInterruption: string;
|
|
26
|
+
signerPubkeyHex: string;
|
|
27
|
+
}): Promise<SealInterruptedLeaf>;
|
|
28
|
+
/**
|
|
29
|
+
* M7-SESSION-001 / DAEMON-004: verify a counterparty's SEAL-INTERRUPTED ack leaf.
|
|
30
|
+
*
|
|
31
|
+
* Shared by BOTH the interrupted-seal flow (SESSION-001) and the active-session
|
|
32
|
+
* seal flow (DAEMON-004 finding #1) so the two paths perform an identical
|
|
33
|
+
* bilateral check. Returns a generic reason; each caller maps it to its own
|
|
34
|
+
* reason codes / observability events / guidance.
|
|
35
|
+
*
|
|
36
|
+
* Checks, in order:
|
|
37
|
+
* 1. L-2: the ack echoes the exact nonce we sent (replay / stale-response guard).
|
|
38
|
+
* 2. leafCount agreement: the counterparty's leafCount equals our own — an
|
|
39
|
+
* independent value, so a genuine divergence in transcript length is caught.
|
|
40
|
+
* 3. SI-002 / SI-003: the leaf carries a valid Ed25519 signature produced by the
|
|
41
|
+
* counterparty's OWN key (signerPubkey must equal the expected counterparty).
|
|
42
|
+
*
|
|
43
|
+
* Crypto: Ed25519 RFC 8032.
|
|
44
|
+
*/
|
|
45
|
+
export declare function verifyCounterpartySealLeaf(opts: {
|
|
46
|
+
leaf: Record<string, unknown>;
|
|
47
|
+
sentNonce: string;
|
|
48
|
+
ackNonce: string | null;
|
|
49
|
+
ownLeafCount: number;
|
|
50
|
+
expectedCounterpartyPubkey: string;
|
|
51
|
+
}): {
|
|
52
|
+
ok: true;
|
|
53
|
+
} | {
|
|
54
|
+
ok: false;
|
|
55
|
+
reason: SealLeafVerifyReason;
|
|
56
|
+
error: string;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=seal-leaf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seal-leaf.d.ts","sourceRoot":"","sources":["../src/seal-leaf.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAE1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,qBAAqB,GAAG,wBAAwB,CAAC;AAEvG;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,UAAU,CAWb;AAED;;;GAGG;AACH,wBAAsB,8BAA8B,CAClD,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,EAAE,MAAM,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,mBAAmB,CAAC,CAW9B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B,EAAE,MAAM,CAAC;CACpC,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAoD5E"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SEAL-INTERRUPTED leaf: canonical bytes, K_local signing, and counterparty verification.
|
|
3
|
+
*
|
|
4
|
+
* The canonical encoding is the load-bearing part. Field order is fixed and deterministic, and the
|
|
5
|
+
* initiator, the responder and the verifier MUST all use exactly this encoding — any drift causes a
|
|
6
|
+
* SILENT signature-verification failure, which is the worst kind. That is why these three live
|
|
7
|
+
* together in one file: they are one agreement about bytes, and splitting them is how they drift.
|
|
8
|
+
*
|
|
9
|
+
* The private key never leaves the KeyProvider. Only the Ed25519 signature comes back.
|
|
10
|
+
*/
|
|
11
|
+
import { Buffer } from "node:buffer";
|
|
12
|
+
import { verify as ed25519Verify } from "@cello-protocol/crypto";
|
|
13
|
+
/**
|
|
14
|
+
* M7-SESSION-001 (H-1): canonical byte encoding of a SEAL-INTERRUPTED leaf for
|
|
15
|
+
* Ed25519 signing/verification. Field order is fixed and deterministic. Both the
|
|
16
|
+
* initiator and the responder, and the verifier, MUST use exactly this encoding —
|
|
17
|
+
* any drift causes silent signature-verification failure.
|
|
18
|
+
*/
|
|
19
|
+
export function canonicalSealInterruptedLeafBytes(leaf) {
|
|
20
|
+
return new TextEncoder().encode(JSON.stringify({
|
|
21
|
+
type: leaf.type,
|
|
22
|
+
sessionId: leaf.sessionId,
|
|
23
|
+
leafCount: leaf.leafCount,
|
|
24
|
+
merkleRootAtInterruption: leaf.merkleRootAtInterruption,
|
|
25
|
+
timestamp: leaf.timestamp,
|
|
26
|
+
signerPubkey: leaf.signerPubkey,
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* M7-SESSION-001 (H-1): construct and K_local-sign a SEAL-INTERRUPTED leaf.
|
|
31
|
+
* The private key never leaves keyProvider — only the Ed25519 signature is returned.
|
|
32
|
+
*/
|
|
33
|
+
export async function buildSignedSealInterruptedLeaf(keyProvider, opts) {
|
|
34
|
+
const partial = {
|
|
35
|
+
type: "SEAL_INTERRUPTED",
|
|
36
|
+
sessionId: opts.sessionId,
|
|
37
|
+
leafCount: opts.leafCount,
|
|
38
|
+
merkleRootAtInterruption: opts.merkleRootAtInterruption,
|
|
39
|
+
timestamp: Date.now(),
|
|
40
|
+
signerPubkey: opts.signerPubkeyHex,
|
|
41
|
+
};
|
|
42
|
+
const sig = await keyProvider.sign(canonicalSealInterruptedLeafBytes(partial));
|
|
43
|
+
return { ...partial, signature: Buffer.from(sig).toString("hex") };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* M7-SESSION-001 / DAEMON-004: verify a counterparty's SEAL-INTERRUPTED ack leaf.
|
|
47
|
+
*
|
|
48
|
+
* Shared by BOTH the interrupted-seal flow (SESSION-001) and the active-session
|
|
49
|
+
* seal flow (DAEMON-004 finding #1) so the two paths perform an identical
|
|
50
|
+
* bilateral check. Returns a generic reason; each caller maps it to its own
|
|
51
|
+
* reason codes / observability events / guidance.
|
|
52
|
+
*
|
|
53
|
+
* Checks, in order:
|
|
54
|
+
* 1. L-2: the ack echoes the exact nonce we sent (replay / stale-response guard).
|
|
55
|
+
* 2. leafCount agreement: the counterparty's leafCount equals our own — an
|
|
56
|
+
* independent value, so a genuine divergence in transcript length is caught.
|
|
57
|
+
* 3. SI-002 / SI-003: the leaf carries a valid Ed25519 signature produced by the
|
|
58
|
+
* counterparty's OWN key (signerPubkey must equal the expected counterparty).
|
|
59
|
+
*
|
|
60
|
+
* Crypto: Ed25519 RFC 8032.
|
|
61
|
+
*/
|
|
62
|
+
export function verifyCounterpartySealLeaf(opts) {
|
|
63
|
+
const { leaf, sentNonce, ackNonce, ownLeafCount, expectedCounterpartyPubkey } = opts;
|
|
64
|
+
// 1. L-2: the counterparty MUST echo the exact nonce we sent.
|
|
65
|
+
if (ackNonce !== sentNonce) {
|
|
66
|
+
return { ok: false, reason: "nonce_mismatch", error: "ack nonce did not match the request nonce" };
|
|
67
|
+
}
|
|
68
|
+
// 2. leafCount agreement against our own independent count.
|
|
69
|
+
const cpLeafCount = typeof leaf["leafCount"] === "number" ? leaf["leafCount"] : null;
|
|
70
|
+
if (cpLeafCount !== ownLeafCount) {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
reason: "leaf_count_mismatch",
|
|
74
|
+
error: `counterparty leafCount ${String(cpLeafCount)} != own leafCount ${ownLeafCount}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// 3. SI-002/SI-003: verify the counterparty's Ed25519 signature on its OWN leaf.
|
|
78
|
+
try {
|
|
79
|
+
const signerPubkeyHex = typeof leaf["signerPubkey"] === "string" ? leaf["signerPubkey"] : null;
|
|
80
|
+
const signatureHex = typeof leaf["signature"] === "string" ? leaf["signature"] : null;
|
|
81
|
+
if (!signerPubkeyHex || !signatureHex) {
|
|
82
|
+
throw new Error("leaf missing signerPubkey or signature");
|
|
83
|
+
}
|
|
84
|
+
if (signerPubkeyHex !== expectedCounterpartyPubkey) {
|
|
85
|
+
throw new Error(`leaf signerPubkey ${signerPubkeyHex.slice(0, 16)} does not match counterparty ${expectedCounterpartyPubkey.slice(0, 16)}`);
|
|
86
|
+
}
|
|
87
|
+
const canonicalLeaf = {
|
|
88
|
+
type: leaf["type"],
|
|
89
|
+
sessionId: leaf["sessionId"],
|
|
90
|
+
leafCount: leaf["leafCount"],
|
|
91
|
+
merkleRootAtInterruption: leaf["merkleRootAtInterruption"],
|
|
92
|
+
timestamp: leaf["timestamp"],
|
|
93
|
+
signerPubkey: leaf["signerPubkey"],
|
|
94
|
+
};
|
|
95
|
+
const leafBytes = new TextEncoder().encode(JSON.stringify(canonicalLeaf));
|
|
96
|
+
const pubkeyBytes = new Uint8Array(Buffer.from(signerPubkeyHex, "hex"));
|
|
97
|
+
const sigBytes = new Uint8Array(Buffer.from(signatureHex, "hex"));
|
|
98
|
+
if (!ed25519Verify(pubkeyBytes, leafBytes, sigBytes)) {
|
|
99
|
+
return { ok: false, reason: "leaf_signature_invalid", error: "Ed25519 signature verification failed on SEAL-INTERRUPTED leaf" };
|
|
100
|
+
}
|
|
101
|
+
return { ok: true };
|
|
102
|
+
}
|
|
103
|
+
catch (verifyErr) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
reason: "leaf_signature_invalid",
|
|
107
|
+
error: verifyErr instanceof Error ? verifyErr.message : String(verifyErr),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=seal-leaf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seal-leaf.js","sourceRoot":"","sources":["../src/seal-leaf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAKjE;;;;;GAKG;AACH,MAAM,UAAU,iCAAiC,CAAC,IAOjD;IACC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAC7B,IAAI,CAAC,SAAS,CAAC;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,wBAAwB,EAAE,IAAI,CAAC,wBAAwB;QACvD,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,WAAwB,EACxB,IAKC;IAED,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,kBAA2B;QACjC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,wBAAwB,EAAE,IAAI,CAAC,wBAAwB;QACvD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,YAAY,EAAE,IAAI,CAAC,eAAe;KACnC,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/E,OAAO,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAM1C;IACC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,0BAA0B,EAAE,GAAG,IAAI,CAAC;IAErF,8DAA8D;IAC9D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,2CAA2C,EAAE,CAAC;IACrG,CAAC;IAED,4DAA4D;IAC5D,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,WAAW,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,qBAAqB;YAC7B,KAAK,EAAE,0BAA0B,MAAM,CAAC,WAAW,CAAC,qBAAqB,YAAY,EAAE;SACxF,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,cAAc,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3G,MAAM,YAAY,GAAG,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,WAAW,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAClG,IAAI,CAAC,eAAe,IAAI,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,eAAe,KAAK,0BAA0B,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CACb,qBAAqB,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,gCAAgC,0BAA0B,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAC3H,CAAC;QACJ,CAAC;QACD,MAAM,aAAa,GAAG;YACpB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAClB,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC;YAC5B,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC;YAC5B,wBAAwB,EAAE,IAAI,CAAC,0BAA0B,CAAC;YAC1D,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC;YAC5B,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC;SACnC,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;QAC1E,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;YACrD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,EAAE,KAAK,EAAE,gEAAgE,EAAE,CAAC;QAClI,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,SAAkB,EAAE,CAAC;QAC5B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,wBAAwB;YAChC,KAAK,EAAE,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;SAC1E,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Client-side bilateral upgrade of a stored seal receipt.
|
|
3
3
|
*
|
|
4
4
|
* When the previously-absent party (B) ratifies a unilateral seal and the directory confirms the
|
|
5
5
|
* upgrade to bilateral (seal_upgrade_confirmed, cryptographically verified via verifyUpgradeConfirmedCert),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Client-side bilateral upgrade of a stored seal receipt.
|
|
3
3
|
*
|
|
4
4
|
* When the previously-absent party (B) ratifies a unilateral seal and the directory confirms the
|
|
5
5
|
* upgrade to bilateral (seal_upgrade_confirmed, cryptographically verified via verifyUpgradeConfirmedCert),
|
package/dist/seal-upgrade.d.ts
CHANGED
|
@@ -3,22 +3,22 @@ import type { Logger } from "./types.js";
|
|
|
3
3
|
import type { DaemonRegistrationPersistence } from "./registration-persistence.js";
|
|
4
4
|
/**
|
|
5
5
|
* Domain separator for the upgrade-ack TBS. B's daemon and the directory MUST build byte-identical
|
|
6
|
-
* bytes — same domain string, same cbor-x encoder options (tagUint8Array:false)
|
|
7
|
-
*
|
|
6
|
+
* bytes — same domain string, same cbor-x encoder options (tagUint8Array:false); the directory side
|
|
7
|
+
* must be kept byte-identical. Domain separation prevents replay as any other CELLO signature.
|
|
8
8
|
*/
|
|
9
9
|
export declare const SEAL_UPGRADE_ACK_DOMAIN = "cello-seal-upgrade-ack-v1";
|
|
10
10
|
/** The exact upgrade-ack TBS B signs / the directory + present party verify. */
|
|
11
11
|
export declare function buildSealUpgradeAckTbs(sessionId: Uint8Array, sealedRoot: Uint8Array): Uint8Array;
|
|
12
|
-
/** Verifiability of a session for B to ratify a unilateral seal — the SAME bar as the
|
|
12
|
+
/** Verifiability of a session for B to ratify a unilateral seal — the SAME bar as the auto-ack. */
|
|
13
13
|
export interface SealUpgradeReadiness {
|
|
14
14
|
known: boolean;
|
|
15
15
|
tampered: boolean;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* THE KERNEL DECISION. B may sign its ratification ONLY when it genuinely possesses + integrity-
|
|
19
|
-
* verified the content behind R1.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* verified the content behind R1. A session B has no record of (content_unrecoverable) or whose
|
|
20
|
+
* content cross-check flagged tamper (content_tamper) is REFUSED. Verified-but-disliked content is
|
|
21
|
+
* NOT a refusal — disagreement ≠ unverifiable.
|
|
22
22
|
*/
|
|
23
23
|
export declare function evaluateSealUpgrade(readiness: SealUpgradeReadiness): {
|
|
24
24
|
proceed: true;
|
|
@@ -33,7 +33,7 @@ export interface AttemptSealUpgradeDeps {
|
|
|
33
33
|
/** B's session verifiability for this session (SessionNodeManager.getSealUpgradeReadiness). */
|
|
34
34
|
getReadiness: (agentName: string, sessionIdHex: string) => SealUpgradeReadiness;
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* The number of content leaves B holds for this session (SessionNodeManager.getSessionTree
|
|
37
37
|
* (...).size()). R1 has leaf_count leaves = content leaves + A's single SEAL ctrl leaf, so B's
|
|
38
38
|
* content tree must hold at least leaf_count-1 leaves or B is missing content it would over-attest.
|
|
39
39
|
*/
|
|
@@ -61,10 +61,10 @@ export interface VerifyUpgradeConfirmedDeps {
|
|
|
61
61
|
logger: Logger;
|
|
62
62
|
agentName: string;
|
|
63
63
|
agentPubkeyHex: string;
|
|
64
|
-
/**
|
|
64
|
+
/** DB-backed identity persistence (the FROST share for cert verification). */
|
|
65
65
|
persistence: DaemonRegistrationPersistence;
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* The counterparty pubkey (hex) of the LOCAL session record for sessionIdHex, or null if this
|
|
68
68
|
* agent has no such session. Binds the cert's present/returning pubkeys to the REAL participants so
|
|
69
69
|
* a malicious directory cannot sign the ack with a throwaway key and force a state transition on a
|
|
70
70
|
* session we are in (or push a confirmed frame for a session we never had).
|
|
@@ -72,7 +72,7 @@ export interface VerifyUpgradeConfirmedDeps {
|
|
|
72
72
|
getCounterpartyHex: (agentName: string, sessionIdHex: string) => string | null;
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
75
|
+
* Dual-attestation verify. NEVER trust the directory's "bilateral" claim.
|
|
76
76
|
*
|
|
77
77
|
* - ALWAYS verify the RETURNING attestation (B's ack) over R1 — proves B genuinely ratified, catches
|
|
78
78
|
* a directory that fabricated or swapped B's signature. The load-bearing check (anyone can do it).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seal-upgrade.d.ts","sourceRoot":"","sources":["../src/seal-upgrade.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAEnF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"seal-upgrade.d.ts","sourceRoot":"","sources":["../src/seal-upgrade.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAEnF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CAEhG;AAMD,mGAAmG;AACnG,MAAM,WAAW,oBAAoB;IAAG,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE;AAE3E;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,oBAAoB,GAC9B;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,YAAY,EAAE,uBAAuB,GAAG,gBAAgB,CAAA;CAAE,CAIlG;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,+FAA+F;IAC/F,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,oBAAoB,CAAC;IAChF;;;;OAIG;IACH,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IACzE,oGAAoG;IACpG,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,4DAA4D;IAC5D,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IAC/D,mEAAmE;IACnE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqE7C;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,EAAE,6BAA6B,CAAC;IAC3C;;;;;OAKG;IACH,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAChF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,0BAA0B,EAChC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DvF"}
|
package/dist/seal-upgrade.js
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The returning-absent-party seal upgrade. It lives outside daemon.ts so the KERNEL (content-
|
|
3
|
+
* possession gate) and the dual-attestation verify run under adversarial unit tests with the REAL
|
|
4
|
+
* bodies, not just the happy path.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* When the previously-ABSENT party B returns, it RATIFIES the existing unilateral sealed root R1 (it
|
|
7
|
+
* does NOT re-seal a new root). B signs an ack over CBOR([SEAL_UPGRADE_ACK_DOMAIN, session_id,
|
|
8
|
+
* sealed_root]) with its K_local. The directory verifies it and writes a SUPERSEDING bilateral
|
|
9
|
+
* notarization. Both parties verify the dual-attestation cert before accepting bilateral.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { encodeCbor } from "@cello-protocol/protocol-types";
|
|
12
12
|
import { verify as ed25519Verify } from "@cello-protocol/crypto";
|
|
13
13
|
import { verifyUnilateralCertificate } from "./session-ceremony.js";
|
|
14
14
|
/**
|
|
15
15
|
* Domain separator for the upgrade-ack TBS. B's daemon and the directory MUST build byte-identical
|
|
16
|
-
* bytes — same domain string, same cbor-x encoder options (tagUint8Array:false)
|
|
17
|
-
*
|
|
16
|
+
* bytes — same domain string, same cbor-x encoder options (tagUint8Array:false); the directory side
|
|
17
|
+
* must be kept byte-identical. Domain separation prevents replay as any other CELLO signature.
|
|
18
18
|
*/
|
|
19
19
|
export const SEAL_UPGRADE_ACK_DOMAIN = "cello-seal-upgrade-ack-v1";
|
|
20
|
-
const UPGRADE_CBOR_ENC = new Encoder({ tagUint8Array: false });
|
|
21
20
|
/** The exact upgrade-ack TBS B signs / the directory + present party verify. */
|
|
22
21
|
export function buildSealUpgradeAckTbs(sessionId, sealedRoot) {
|
|
23
|
-
return
|
|
22
|
+
return encodeCbor([SEAL_UPGRADE_ACK_DOMAIN, sessionId, sealedRoot]);
|
|
24
23
|
}
|
|
25
24
|
function toU8(v) {
|
|
26
25
|
return v instanceof Uint8Array ? v : Buffer.isBuffer(v) ? new Uint8Array(v) : null;
|
|
27
26
|
}
|
|
28
27
|
/**
|
|
29
28
|
* THE KERNEL DECISION. B may sign its ratification ONLY when it genuinely possesses + integrity-
|
|
30
|
-
* verified the content behind R1.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
29
|
+
* verified the content behind R1. A session B has no record of (content_unrecoverable) or whose
|
|
30
|
+
* content cross-check flagged tamper (content_tamper) is REFUSED. Verified-but-disliked content is
|
|
31
|
+
* NOT a refusal — disagreement ≠ unverifiable.
|
|
33
32
|
*/
|
|
34
33
|
export function evaluateSealUpgrade(readiness) {
|
|
35
34
|
if (!readiness.known)
|
|
@@ -66,11 +65,11 @@ export async function attemptSealUpgrade(deps, sessionIdHex, frame) {
|
|
|
66
65
|
deps.logger[level]("session.seal.upgrade.refused", { sessionId: sessionIdHex, reason: decision.refuseReason });
|
|
67
66
|
return { sent: false, reason: decision.refuseReason };
|
|
68
67
|
}
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
68
|
+
// KERNEL completeness: B must hold the FULL content behind R1, not merely a tamper-free subset.
|
|
69
|
+
// R1 = root over [content leaves..., A's SEAL ctrl leaf], so leaf_count counts the content leaves
|
|
70
|
+
// + 1; B's content tree must hold >= leaf_count-1. Refuse if B recovered an INCOMPLETE transcript —
|
|
71
|
+
// never over-attest to content B did not fully receive. This count gate is the bar until exact
|
|
72
|
+
// root-reproduction (canonical-sequence reconciliation) lands.
|
|
74
73
|
const contentLeaves = deps.getContentLeafCount(deps.agentName, sessionIdHex);
|
|
75
74
|
if (contentLeaves < leafCount - 1) {
|
|
76
75
|
deps.logger.warn("session.seal.upgrade.refused", {
|
|
@@ -93,7 +92,7 @@ export async function attemptSealUpgrade(deps, sessionIdHex, frame) {
|
|
|
93
92
|
returning_pubkey: returningPubkey,
|
|
94
93
|
ack_signature: ackSig,
|
|
95
94
|
// forwarded (from the notification cert) so the directory relays it → the present party rebuilds
|
|
96
|
-
// the seal TBS and verifies its own attestation
|
|
95
|
+
// the seal TBS and verifies its own attestation.
|
|
97
96
|
leaf_count: leafCount,
|
|
98
97
|
});
|
|
99
98
|
if (!sent.ok) {
|
|
@@ -112,7 +111,7 @@ export async function attemptSealUpgrade(deps, sessionIdHex, frame) {
|
|
|
112
111
|
}
|
|
113
112
|
}
|
|
114
113
|
/**
|
|
115
|
-
*
|
|
114
|
+
* Dual-attestation verify. NEVER trust the directory's "bilateral" claim.
|
|
116
115
|
*
|
|
117
116
|
* - ALWAYS verify the RETURNING attestation (B's ack) over R1 — proves B genuinely ratified, catches
|
|
118
117
|
* a directory that fabricated or swapped B's signature. The load-bearing check (anyone can do it).
|
|
@@ -139,7 +138,7 @@ export async function verifyUpgradeConfirmedCert(deps, sessionIdHex, frame) {
|
|
|
139
138
|
deps.logger.warn("session.seal.upgrade.cert.invalid", { sessionId: sessionIdHex, reason: "malformed_confirmed" });
|
|
140
139
|
return { ok: false, reason: "malformed_confirmed" };
|
|
141
140
|
}
|
|
142
|
-
//
|
|
141
|
+
// Bind the cert's present/returning pubkeys to the REAL participants of OUR session record.
|
|
143
142
|
// The pair {present, returning} must equal {self, our counterparty}; otherwise a single untrusted
|
|
144
143
|
// directory could sign the ack with an attacker-chosen key and drive a B-side state transition, or
|
|
145
144
|
// push a confirmed frame for a session we never had. We must hold the session locally to accept.
|
|
@@ -156,7 +155,7 @@ export async function verifyUpgradeConfirmedCert(deps, sessionIdHex, frame) {
|
|
|
156
155
|
deps.logger.warn("session.seal.upgrade.cert.invalid", { sessionId: sessionIdHex, reason: "participant_mismatch" });
|
|
157
156
|
return { ok: false, reason: "participant_mismatch" };
|
|
158
157
|
}
|
|
159
|
-
// 1. Returning attestation (the returning party's ack) over R1 — the
|
|
158
|
+
// 1. Returning attestation (the returning party's ack) over R1 — the kernel check. returningPubkey
|
|
160
159
|
// is now proven to be a real participant of this session (self or counterparty), not attacker-chosen.
|
|
161
160
|
const ackTbs = buildSealUpgradeAckTbs(sessionId, sealedRoot);
|
|
162
161
|
if (!ed25519Verify(returningPubkey, ackTbs, returningSig)) {
|
package/dist/seal-upgrade.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seal-upgrade.js","sourceRoot":"","sources":["../src/seal-upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"seal-upgrade.js","sourceRoot":"","sources":["../src/seal-upgrade.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session assignment parsing
|
|
2
|
+
* Session assignment parsing.
|
|
3
3
|
*
|
|
4
4
|
* Decodes a raw CBOR-decoded `assignment` object (from a directory
|
|
5
|
-
* `session_assignment` frame) into a typed SessionAssignment. Shape-validates
|
|
5
|
+
* `session_assignment` frame) into a typed SessionAssignment. Shape-validates ONLY;
|
|
6
6
|
* the FROST/single signature is verified downstream by the transport/session layer
|
|
7
|
-
* against the directory's pinned key.
|
|
8
|
-
*
|
|
9
|
-
* core/client stack, so the proven logic lives here.
|
|
7
|
+
* against the directory's pinned key. The logic lives here in the daemon because the
|
|
8
|
+
* daemon must NOT import the core/client stack.
|
|
10
9
|
*/
|
|
11
10
|
import type { SessionAssignment } from "@cello-protocol/protocol-types";
|
|
12
11
|
/**
|
|
@@ -14,10 +13,6 @@ import type { SessionAssignment } from "@cello-protocol/protocol-types";
|
|
|
14
13
|
* Returns null if any required field is missing or malformed.
|
|
15
14
|
*/
|
|
16
15
|
export declare function parseSessionAssignment(raw: Record<string, unknown>): SessionAssignment | null;
|
|
17
|
-
/**
|
|
18
|
-
* Map a raw `session_request_error` frame's reason to a stable negotiator reason code.
|
|
19
|
-
* Distinct cause → distinct code (M7 error discipline); unknown → directory_unreachable.
|
|
20
|
-
*/
|
|
21
16
|
export interface DiscoveryLookupResultParsed {
|
|
22
17
|
state: "online" | "offline" | "unknown_agent";
|
|
23
18
|
/** Non-empty only when state = "online" (length 1 until the k>1 homing knob lands). */
|
|
@@ -35,14 +30,17 @@ export declare function parseDiscoveryLookupResult(frame: Record<string, unknown
|
|
|
35
30
|
* Unknown reasons collapse to the same retryable "lookup_failed".
|
|
36
31
|
*/
|
|
37
32
|
export declare function discoveryLookupErrorReason(_frame: Record<string, unknown>): string;
|
|
33
|
+
/**
|
|
34
|
+
* Map a raw `session_request_error` frame's reason to a stable negotiator reason code.
|
|
35
|
+
* Distinct cause → distinct code; an unknown reason collapses to directory_unreachable.
|
|
36
|
+
*/
|
|
38
37
|
export declare function sessionRequestErrorReason(frame: Record<string, unknown>): string;
|
|
39
38
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* returned verbatim or null, never repaired.
|
|
39
|
+
* The receiver's wire boundary, validated ONCE here so downstream code can never
|
|
40
|
+
* observe an invalid moniker. Absent ≠ invalid: an absent field is an older client
|
|
41
|
+
* (silent, rejected: false); a present-but-invalid value means the sender runs
|
|
42
|
+
* modified code (rejected: true — the caller logs `moniker.rejected`, never the raw
|
|
43
|
+
* value). Reject, never strip: the value is returned verbatim or null, never repaired.
|
|
46
44
|
*/
|
|
47
45
|
export declare function extractOfferedMoniker(raw: Record<string, unknown>): {
|
|
48
46
|
offeredMoniker: string | null;
|
|
@@ -51,10 +49,9 @@ export declare function extractOfferedMoniker(raw: Record<string, unknown>): {
|
|
|
51
49
|
reason?: "not_string" | "length" | "charset";
|
|
52
50
|
};
|
|
53
51
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* stored value somehow fails validation.
|
|
52
|
+
* Defense-in-depth re-validation of the initiator's own outbound name. Returns
|
|
53
|
+
* undefined (field OMITTED from the wire, never an empty string) when there is no
|
|
54
|
+
* name or the stored value somehow fails validation.
|
|
58
55
|
*/
|
|
59
56
|
export declare function resolveOutboundMoniker(outboundName: string | null): string | undefined;
|
|
60
57
|
//# sourceMappingURL=session-assignment-parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-assignment-parser.d.ts","sourceRoot":"","sources":["../src/session-assignment-parser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session-assignment-parser.d.ts","sourceRoot":"","sources":["../src/session-assignment-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAoCxE;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,GAAG,IAAI,CAsE7F;AAID,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,eAAe,CAAC;IAC9C,uFAAuF;IACvF,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,2BAA2B,GAAG,IAAI,CAK7G;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAIlF;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CA0BhF;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC9C,CAeA;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAGtF"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session assignment parsing
|
|
2
|
+
* Session assignment parsing.
|
|
3
3
|
*
|
|
4
4
|
* Decodes a raw CBOR-decoded `assignment` object (from a directory
|
|
5
|
-
* `session_assignment` frame) into a typed SessionAssignment. Shape-validates
|
|
5
|
+
* `session_assignment` frame) into a typed SessionAssignment. Shape-validates ONLY;
|
|
6
6
|
* the FROST/single signature is verified downstream by the transport/session layer
|
|
7
|
-
* against the directory's pinned key.
|
|
8
|
-
*
|
|
9
|
-
* core/client stack, so the proven logic lives here.
|
|
7
|
+
* against the directory's pinned key. The logic lives here in the daemon because the
|
|
8
|
+
* daemon must NOT import the core/client stack.
|
|
10
9
|
*/
|
|
11
10
|
function toU8Safe(v) {
|
|
12
11
|
if (v instanceof Uint8Array)
|
|
@@ -63,10 +62,10 @@ export function parseSessionAssignment(raw) {
|
|
|
63
62
|
const dirSig = toU8Safe(raw["directory_signature"]);
|
|
64
63
|
if (!dirSig || dirSig.length !== 64)
|
|
65
64
|
return null;
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
65
|
+
// The per-node directory signature over the relay TBS. Optional — absent on older assignments and on
|
|
66
|
+
// direct-mode sessions. When present it must be a valid 64-byte sig; a malformed value is dropped to
|
|
67
|
+
// undefined (the session then has no relay assignment to present, which surfaces as a relay-witness
|
|
68
|
+
// gap, not a hard failure).
|
|
70
69
|
const relayDirSigRaw = toU8Safe(raw["relay_directory_signature"]);
|
|
71
70
|
const relayDirSig = relayDirSigRaw && relayDirSigRaw.length === 64 ? relayDirSigRaw : undefined;
|
|
72
71
|
const tsRaw = raw["session_timestamp"];
|
|
@@ -86,7 +85,7 @@ export function parseSessionAssignment(raw) {
|
|
|
86
85
|
if (!directoryEndpoint)
|
|
87
86
|
return null;
|
|
88
87
|
const sigType = typeof raw["signature_type"] === "string" ? raw["signature_type"] : "single";
|
|
89
|
-
//
|
|
88
|
+
// Session peer IDs + transport mode — undefined when absent (an older peer omits them).
|
|
90
89
|
const initiatorSessionPeerId = typeof raw["initiator_session_peer_id"] === "string" && raw["initiator_session_peer_id"] !== ""
|
|
91
90
|
? raw["initiator_session_peer_id"]
|
|
92
91
|
: undefined;
|
|
@@ -143,6 +142,10 @@ export function discoveryLookupErrorReason(_frame) {
|
|
|
143
142
|
// function (not a constant) so a future reason set slots in without touching call sites.
|
|
144
143
|
return "lookup_failed";
|
|
145
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Map a raw `session_request_error` frame's reason to a stable negotiator reason code.
|
|
147
|
+
* Distinct cause → distinct code; an unknown reason collapses to directory_unreachable.
|
|
148
|
+
*/
|
|
146
149
|
export function sessionRequestErrorReason(frame) {
|
|
147
150
|
const reason = frame["reason"];
|
|
148
151
|
const known = new Set([
|
|
@@ -158,27 +161,26 @@ export function sessionRequestErrorReason(frame) {
|
|
|
158
161
|
"no_connection",
|
|
159
162
|
"connection_id_required",
|
|
160
163
|
"session_request_missing_peer_id",
|
|
161
|
-
"agent_revoked", //
|
|
162
|
-
"agent_suspended", //
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
164
|
+
"agent_revoked", // the target (or initiator) agent is revoked
|
|
165
|
+
"agent_suspended", // the target/initiator is PAUSED (reversible suspend)
|
|
166
|
+
// The directory fails closed instead of FROST-signing an endpoint-less assignment — the target
|
|
167
|
+
// never accepted the session_offer. Distinct from target_offline: the target IS connected to the
|
|
168
|
+
// directory, it just cannot serve this session (e.g. its standing receiver has not come up).
|
|
169
|
+
// Omitting it here collapses the cause to `directory_unreachable`, blaming the DIRECTORY for a
|
|
170
|
+
// healthy directory and a COUNTERPARTY that declined — the wrong subsystem, which is what makes
|
|
171
|
+
// such bugs cost days.
|
|
169
172
|
"counterparty_did_not_accept",
|
|
170
173
|
]);
|
|
171
174
|
return typeof reason === "string" && known.has(reason) ? reason : "directory_unreachable";
|
|
172
175
|
}
|
|
173
|
-
// ───
|
|
176
|
+
// ─── The offer-moniker validation seams ──────────────────────────
|
|
174
177
|
import { validateMoniker } from "@cello-protocol/protocol-types";
|
|
175
178
|
/**
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* returned verbatim or null, never repaired.
|
|
179
|
+
* The receiver's wire boundary, validated ONCE here so downstream code can never
|
|
180
|
+
* observe an invalid moniker. Absent ≠ invalid: an absent field is an older client
|
|
181
|
+
* (silent, rejected: false); a present-but-invalid value means the sender runs
|
|
182
|
+
* modified code (rejected: true — the caller logs `moniker.rejected`, never the raw
|
|
183
|
+
* value). Reject, never strip: the value is returned verbatim or null, never repaired.
|
|
182
184
|
*/
|
|
183
185
|
export function extractOfferedMoniker(raw) {
|
|
184
186
|
if (!("moniker" in raw) || raw["moniker"] === undefined) {
|
|
@@ -197,10 +199,9 @@ export function extractOfferedMoniker(raw) {
|
|
|
197
199
|
: { offeredMoniker: null, rejected: true, reason: "charset" };
|
|
198
200
|
}
|
|
199
201
|
/**
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* stored value somehow fails validation.
|
|
202
|
+
* Defense-in-depth re-validation of the initiator's own outbound name. Returns
|
|
203
|
+
* undefined (field OMITTED from the wire, never an empty string) when there is no
|
|
204
|
+
* name or the stored value somehow fails validation.
|
|
204
205
|
*/
|
|
205
206
|
export function resolveOutboundMoniker(outboundName) {
|
|
206
207
|
if (outboundName === null)
|