@interop/wallet-core 0.39.0 → 0.41.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/README.md +5 -3
- package/dist/clients/listing.d.ts +4 -3
- package/dist/clients/listing.d.ts.map +1 -1
- package/dist/clients/listing.js.map +1 -1
- package/dist/clients/policy.d.ts +3 -2
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +3 -3
- package/dist/clients/policy.js.map +1 -1
- package/dist/clients/revocation.d.ts +14 -4
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +32 -22
- package/dist/clients/revocation.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts +30 -2
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +44 -4
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/enrollment/index.d.ts +4 -1
- package/dist/enrollment/index.d.ts.map +1 -1
- package/dist/enrollment/index.js +4 -1
- package/dist/enrollment/index.js.map +1 -1
- package/dist/keyring/fetch.d.ts +2 -1
- package/dist/keyring/fetch.d.ts.map +1 -1
- package/dist/keyring/fetch.js +7 -2
- package/dist/keyring/fetch.js.map +1 -1
- package/dist/keyring/index.d.ts +16 -9
- package/dist/keyring/index.d.ts.map +1 -1
- package/dist/keyring/index.js +15 -8
- package/dist/keyring/index.js.map +1 -1
- package/dist/keyring/kdf.d.ts +3 -1
- package/dist/keyring/kdf.d.ts.map +1 -1
- package/dist/keyring/kdf.js +16 -2
- package/dist/keyring/kdf.js.map +1 -1
- package/dist/keyring/record.d.ts +236 -50
- package/dist/keyring/record.d.ts.map +1 -1
- package/dist/keyring/record.js +348 -46
- package/dist/keyring/record.js.map +1 -1
- package/dist/keyring/unlockSpace.d.ts +25 -0
- package/dist/keyring/unlockSpace.d.ts.map +1 -1
- package/dist/keyring/unlockSpace.js +31 -2
- package/dist/keyring/unlockSpace.js.map +1 -1
- package/dist/keys/index.d.ts +4 -2
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +2 -1
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts +18 -1
- package/dist/keys/rosterLogStore.d.ts.map +1 -1
- package/dist/keys/rosterLogStore.js +34 -6
- package/dist/keys/rosterLogStore.js.map +1 -1
- package/dist/keys/userKeyCascade.d.ts +10 -3
- package/dist/keys/userKeyCascade.d.ts.map +1 -1
- package/dist/keys/userKeyCascade.js +10 -4
- package/dist/keys/userKeyCascade.js.map +1 -1
- package/dist/keys/userKeyRoster.d.ts +39 -24
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +28 -77
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/recovery/index.d.ts +16 -3
- package/dist/recovery/index.d.ts.map +1 -1
- package/dist/recovery/index.js +14 -2
- package/dist/recovery/index.js.map +1 -1
- package/dist/recovery/recoveryCode.d.ts +7 -0
- package/dist/recovery/recoveryCode.d.ts.map +1 -1
- package/dist/recovery/recoveryCode.js +10 -0
- package/dist/recovery/recoveryCode.js.map +1 -1
- package/dist/recovery/recoveryDelegation.d.ts +120 -0
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -0
- package/dist/recovery/recoveryDelegation.js +216 -0
- package/dist/recovery/recoveryDelegation.js.map +1 -0
- package/dist/recovery/recoveryRecord.d.ts +138 -46
- package/dist/recovery/recoveryRecord.d.ts.map +1 -1
- package/dist/recovery/recoveryRecord.js +231 -30
- package/dist/recovery/recoveryRecord.js.map +1 -1
- package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
- package/dist/recovery/recoveryWebvh.js +20 -14
- package/dist/recovery/recoveryWebvh.js.map +1 -1
- package/dist/request/index.d.ts +1 -1
- package/dist/request/index.js +1 -1
- package/dist/request/matching.d.ts +24 -5
- package/dist/request/matching.d.ts.map +1 -1
- package/dist/request/matching.js +36 -39
- package/dist/request/matching.js.map +1 -1
- package/dist/request/walletInput.d.ts.map +1 -1
- package/dist/request/walletInput.js +3 -6
- package/dist/request/walletInput.js.map +1 -1
- package/dist/resourceLog/controller.d.ts +7 -4
- package/dist/resourceLog/controller.d.ts.map +1 -1
- package/dist/resourceLog/controller.js +17 -35
- package/dist/resourceLog/controller.js.map +1 -1
- package/dist/resourceLog/index.d.ts +1 -0
- package/dist/resourceLog/index.d.ts.map +1 -1
- package/dist/resourceLog/index.js +1 -0
- package/dist/resourceLog/index.js.map +1 -1
- package/dist/resourceLog/seal.d.ts +9 -1
- package/dist/resourceLog/seal.d.ts.map +1 -1
- package/dist/resourceLog/seal.js +21 -11
- package/dist/resourceLog/seal.js.map +1 -1
- package/dist/resourceLog/verify.d.ts.map +1 -1
- package/dist/resourceLog/verify.js +26 -9
- package/dist/resourceLog/verify.js.map +1 -1
- package/dist/resourceLog/vmFragment.d.ts +33 -0
- package/dist/resourceLog/vmFragment.d.ts.map +1 -0
- package/dist/resourceLog/vmFragment.js +39 -0
- package/dist/resourceLog/vmFragment.js.map +1 -0
- package/dist/space/publicLink.d.ts +2 -0
- package/dist/space/publicLink.d.ts.map +1 -1
- package/dist/space/publicLink.js +13 -1
- package/dist/space/publicLink.js.map +1 -1
- package/dist/space/wasLink.d.ts +5 -0
- package/dist/space/wasLink.d.ts.map +1 -1
- package/dist/space/wasLink.js +7 -2
- package/dist/space/wasLink.js.map +1 -1
- package/dist/webvh/didWeb.d.ts +3 -11
- package/dist/webvh/didWeb.d.ts.map +1 -1
- package/dist/webvh/didWeb.js +5 -1
- package/dist/webvh/didWeb.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +72 -1
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +111 -12
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +9 -2
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +8 -2
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/keyAgreement.d.ts +56 -0
- package/dist/webvh/keyAgreement.d.ts.map +1 -0
- package/dist/webvh/keyAgreement.js +47 -0
- package/dist/webvh/keyAgreement.js.map +1 -0
- package/dist/webvh/listClients.d.ts +69 -18
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +141 -36
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +21 -11
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +31 -14
- package/dist/webvh/revokeClient.js.map +1 -1
- package/dist/webvh/verifyLog.d.ts.map +1 -1
- package/dist/webvh/verifyLog.js +5 -1
- package/dist/webvh/verifyLog.js.map +1 -1
- package/package.json +4 -4
package/dist/keys/index.d.ts
CHANGED
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
* `seal()` appends the idempotent backstop entry when the log's head still
|
|
27
27
|
* anchors before the account document's latest membership change.
|
|
28
28
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
29
|
-
* the enrollment wrap
|
|
29
|
+
* the enrollment wrap and the roster read. A retiring rotation names no kid:
|
|
30
|
+
* it converges onto the account document instead.
|
|
30
31
|
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
31
32
|
* cascade torn between the document edit and the roster rotation: a roster
|
|
32
33
|
* recipient the document no longer keys is rotated away from.
|
|
@@ -54,7 +55,8 @@ export type { ClientKeyRecord, ClientKeyRecordJson, EnrolledClientKeyRecord } fr
|
|
|
54
55
|
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterLogSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster } from './userKeyRoster.js';
|
|
55
56
|
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
56
57
|
export type { CollectionUserKeyRotationOutcome, UserKeyCascadeResult } from './userKeyCascade.js';
|
|
57
|
-
export type { UserKeyRosterReadResult
|
|
58
|
+
export type { UserKeyRosterReadResult } from './userKeyRoster.js';
|
|
59
|
+
export type { KeyAgreementDocument } from '../webvh/keyAgreement.js';
|
|
58
60
|
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
59
61
|
export { EPOCH_CONFIGURATION_STATE_TYPE, isSealableDescriptorStore, logGovernedDescriptorStore } from './rosterLogStore.js';
|
|
60
62
|
export type { SealableEncryptionDescriptorStore } from './rosterLogStore.js';
|
package/dist/keys/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC5D,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,gCAAgC,EAChC,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AACjE,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAEpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,iCAAiC,EAAE,MAAM,qBAAqB,CAAA;AAE5E,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/keys/index.js
CHANGED
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
* `seal()` appends the idempotent backstop entry when the log's head still
|
|
27
27
|
* anchors before the account document's latest membership change.
|
|
28
28
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
29
|
-
* the enrollment wrap
|
|
29
|
+
* the enrollment wrap and the roster read. A retiring rotation names no kid:
|
|
30
|
+
* it converges onto the account document instead.
|
|
30
31
|
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
31
32
|
* cascade torn between the document edit and the roster rotation: a roster
|
|
32
33
|
* recipient the document no longer keys is rotated away from.
|
package/dist/keys/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG5D,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAQ5B,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -11,9 +11,22 @@ export { EPOCH_CONFIGURATION_STATE_TYPE };
|
|
|
11
11
|
* still anchors before the controller's latest membership change --
|
|
12
12
|
* `'sealed'` -- and writing nothing when the log is already sealed, absent,
|
|
13
13
|
* or has no membership change to seal against -- `'noop'`.
|
|
14
|
+
*
|
|
15
|
+
* `setControllerFloor()` is the post-edit freshness contract: a ceremony that
|
|
16
|
+
* just extended the account log (a revocation about to rotate the roster)
|
|
17
|
+
* hands the store the controller view built from that post-edit log, and the
|
|
18
|
+
* store's subsequent operations never resolve to anything staler. The
|
|
19
|
+
* injected `resolveController` still wins whenever it is at or past the floor
|
|
20
|
+
* (it may be fresher -- a concurrent enrollment), so the floor supersedes
|
|
21
|
+
* only a stale cached view, which would otherwise anchor the rotation before
|
|
22
|
+
* the edit and leave the log unsealed with the seal backstop blind to the
|
|
23
|
+
* removal.
|
|
14
24
|
*/
|
|
15
25
|
export interface SealableEncryptionDescriptorStore extends EncryptionDescriptorStore {
|
|
16
26
|
seal(): Promise<'sealed' | 'noop'>;
|
|
27
|
+
setControllerFloor(options: {
|
|
28
|
+
controller: ResourceLogController;
|
|
29
|
+
}): void;
|
|
17
30
|
}
|
|
18
31
|
/**
|
|
19
32
|
* Whether a descriptor store is log-governed and sealable -- the guard the
|
|
@@ -31,7 +44,11 @@ export declare function isSealableDescriptorStore(store: EncryptionDescriptorSto
|
|
|
31
44
|
* The controller view is resolved per operation (never held), so a caller
|
|
32
45
|
* that just edited the account document -- a revocation about to rotate the
|
|
33
46
|
* roster -- writes entries anchored at the post-edit head it now verifies,
|
|
34
|
-
* which is exactly what makes its rotation the sealing append.
|
|
47
|
+
* which is exactly what makes its rotation the sealing append. The revocation
|
|
48
|
+
* orchestrator does not leave that freshness to the injected resolver's
|
|
49
|
+
* wiring: it calls `setControllerFloor` with the view built from the edit's
|
|
50
|
+
* own post-edit log, and a resolver still serving a stale cached view is
|
|
51
|
+
* superseded by it (see the interface doc).
|
|
35
52
|
*
|
|
36
53
|
* @param options {object}
|
|
37
54
|
* @param options.log {ResourceLogStore} the log's transport seam
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterLogStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAQL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,EAAE,8BAA8B,EAAE,CAAA;AAEzC
|
|
1
|
+
{"version":3,"file":"rosterLogStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAQL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,EAAE,8BAA8B,EAAE,CAAA;AAEzC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iCAAkC,SAAQ,yBAAyB;IAClF,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAA;IAClC,kBAAkB,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,qBAAqB,CAAA;KAAE,GAAG,IAAI,CAAA;CACzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,yBAAyB,GAC/B,KAAK,IAAI,iCAAiC,CAK5C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,iBAAiB,EACjB,QAAQ,EACR,MAAM,EACP,EAAE;IACD,GAAG,EAAE,gBAAgB,CAAA;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvD,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,GAAG,iCAAiC,CAgJpC"}
|
|
@@ -21,7 +21,11 @@ export function isSealableDescriptorStore(store) {
|
|
|
21
21
|
* The controller view is resolved per operation (never held), so a caller
|
|
22
22
|
* that just edited the account document -- a revocation about to rotate the
|
|
23
23
|
* roster -- writes entries anchored at the post-edit head it now verifies,
|
|
24
|
-
* which is exactly what makes its rotation the sealing append.
|
|
24
|
+
* which is exactly what makes its rotation the sealing append. The revocation
|
|
25
|
+
* orchestrator does not leave that freshness to the injected resolver's
|
|
26
|
+
* wiring: it calls `setControllerFloor` with the view built from the edit's
|
|
27
|
+
* own post-edit log, and a resolver still serving a stale cached view is
|
|
28
|
+
* superseded by it (see the interface doc).
|
|
25
29
|
*
|
|
26
30
|
* @param options {object}
|
|
27
31
|
* @param options.log {ResourceLogStore} the log's transport seam
|
|
@@ -39,6 +43,22 @@ export function logGovernedDescriptorStore({ log, resolveController, pinStore, s
|
|
|
39
43
|
// a replace builds its entry on that head, pinned to the same read's etag,
|
|
40
44
|
// so a stale head loses the CAS instead of forking.
|
|
41
45
|
let lastVerified = null;
|
|
46
|
+
// The freshness floor a post-edit ceremony set (see the interface doc).
|
|
47
|
+
let controllerFloor = null;
|
|
48
|
+
async function currentController() {
|
|
49
|
+
const resolved = await resolveController();
|
|
50
|
+
if (controllerFloor === null) {
|
|
51
|
+
return resolved;
|
|
52
|
+
}
|
|
53
|
+
const floorHead = controllerFloor.versionIds[controllerFloor.versionIds.length - 1];
|
|
54
|
+
// A resolved view carrying the floor's head version is at or past the
|
|
55
|
+
// floor (the controller-log version list is append-only) and wins; one
|
|
56
|
+
// that does not is a stale cache the floor supersedes.
|
|
57
|
+
if (floorHead !== undefined && !resolved.versionIds.includes(floorHead)) {
|
|
58
|
+
return controllerFloor;
|
|
59
|
+
}
|
|
60
|
+
return resolved;
|
|
61
|
+
}
|
|
42
62
|
function toState(descriptor) {
|
|
43
63
|
const { history: _history, ...rest } = descriptor;
|
|
44
64
|
return { ...rest, type: EPOCH_CONFIGURATION_STATE_TYPE };
|
|
@@ -56,7 +76,7 @@ export function logGovernedDescriptorStore({ log, resolveController, pinStore, s
|
|
|
56
76
|
}
|
|
57
77
|
return {
|
|
58
78
|
async read() {
|
|
59
|
-
const controller = await
|
|
79
|
+
const controller = await currentController();
|
|
60
80
|
const current = await readResourceLog({
|
|
61
81
|
store: log,
|
|
62
82
|
controller,
|
|
@@ -90,7 +110,7 @@ export function logGovernedDescriptorStore({ log, resolveController, pinStore, s
|
|
|
90
110
|
if (lastVerified.terminal) {
|
|
91
111
|
throw new ResourceLogClosedError({ nextLog: lastVerified.terminal });
|
|
92
112
|
}
|
|
93
|
-
const controller = await
|
|
113
|
+
const controller = await currentController();
|
|
94
114
|
const entry = await buildResourceLogEntry({
|
|
95
115
|
head: lastVerified.head,
|
|
96
116
|
state: toState(descriptor),
|
|
@@ -103,7 +123,7 @@ export function logGovernedDescriptorStore({ log, resolveController, pinStore, s
|
|
|
103
123
|
await settle({ entry, controller });
|
|
104
124
|
},
|
|
105
125
|
async create(descriptor) {
|
|
106
|
-
const controller = await
|
|
126
|
+
const controller = await currentController();
|
|
107
127
|
const genesis = await buildResourceLogGenesis({
|
|
108
128
|
state: toState(descriptor),
|
|
109
129
|
method: RESOURCE_LOG_METHOD,
|
|
@@ -116,18 +136,26 @@ export function logGovernedDescriptorStore({ log, resolveController, pinStore, s
|
|
|
116
136
|
await settle({ entry: genesis, controller });
|
|
117
137
|
},
|
|
118
138
|
async seal() {
|
|
119
|
-
const controller = await
|
|
139
|
+
const controller = await currentController();
|
|
140
|
+
// Reuse the log view the most recent read or confirmed append on this
|
|
141
|
+
// store instance verified: a rotation that just appended anchors past
|
|
142
|
+
// the removal, so the sweep resolves noop with no re-fetch, and a stale
|
|
143
|
+
// view is safe (sealResourceLog's append path re-reads before writing).
|
|
120
144
|
const { sealed, verified } = await sealResourceLog({
|
|
121
145
|
store: log,
|
|
122
146
|
controller,
|
|
123
147
|
expectedMethod: RESOURCE_LOG_METHOD,
|
|
124
148
|
pinStore,
|
|
125
|
-
signer
|
|
149
|
+
signer,
|
|
150
|
+
...(lastVerified === null ? {} : { verified: lastVerified })
|
|
126
151
|
});
|
|
127
152
|
if (verified !== null) {
|
|
128
153
|
lastVerified = verified;
|
|
129
154
|
}
|
|
130
155
|
return sealed ? 'sealed' : 'noop';
|
|
156
|
+
},
|
|
157
|
+
setControllerFloor({ controller }) {
|
|
158
|
+
controllerFloor = controller;
|
|
131
159
|
}
|
|
132
160
|
};
|
|
133
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterLogStore.js","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,aAAa,EACb,mBAAmB,EAEpB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,iBAAiB,EAKlB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAA;AAE5E,OAAO,EAAE,8BAA8B,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"rosterLogStore.js","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,12 @@
|
|
|
22
22
|
* The cascade is rotation-only: every encrypted collection's descriptor
|
|
23
23
|
* carries an epoch roster from provisioning (`ensureWalletSpaceEpochs`), so a
|
|
24
24
|
* descriptor met without epochs can only mean a tampering or pre-provisioning
|
|
25
|
-
* host and is refused fail-closed.
|
|
25
|
+
* host and is refused fail-closed. A descriptor whose `currentEpoch` names no
|
|
26
|
+
* epoch in its own list is refused the same way (the shape
|
|
27
|
+
* `readUserKeyRoster` refuses on the roster itself): collection descriptors
|
|
28
|
+
* arrive host-served with no server-side epoch invariants, so a mismatched
|
|
29
|
+
* pair is a configuration no enrolled client authenticated, never something
|
|
30
|
+
* to evaluate against the last epoch. No construction anywhere installs a
|
|
26
31
|
* user-key secret as a collection epoch secret, which is what keeps a
|
|
27
32
|
* collection-epoch escrow (an App Connect grant, a share) from ever handing a
|
|
28
33
|
* grantee the user key itself.
|
|
@@ -88,9 +93,11 @@ export type CollectionUserKeyRotationOutcome = 'noop' | 'sealed' | 'escrowed' |
|
|
|
88
93
|
* so the store's seal backstop runs here (`sealed` when it appended);
|
|
89
94
|
* rotated and escrowed writes seal by construction, anchored at the
|
|
90
95
|
* caller's current controller head.
|
|
91
|
-
* - **No epochs
|
|
96
|
+
* - **No epochs**, or a `currentEpoch` naming no epoch in the descriptor's
|
|
97
|
+
* own list: refused fail-closed (see the module doc) -- provisioning
|
|
92
98
|
* installs every encrypted collection's epoch[0], so the cascade never
|
|
93
|
-
* mints a first epoch
|
|
99
|
+
* mints a first epoch, and never guesses which epoch an inconsistent
|
|
100
|
+
* descriptor meant.
|
|
94
101
|
*
|
|
95
102
|
* The pull axis is deliberately a no-op here: a user key rotation follows a
|
|
96
103
|
* document edit (client revocation, code retirement) that already killed the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userKeyCascade.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"userKeyCascade.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAML,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAoB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAE7D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,kBAAkB,CAKrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,wBAAwB,CAAC,EAC7C,UAAU,EACV,qBAAqB,EACtB,EAAE;IACD,UAAU,EAAE,oBAAoB,CAAA;IAChC,qBAAqB,EAAE,gBAAgB,CAAA;CACxC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAkBrB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,gCAAgC,GAC1C,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,KAAK,EACL,OAAO,EACP,WAAW,EACZ,EAAE;IACD,KAAK,EAAE,yBAAyB,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,OAAO,EAAE,CAAA;CACvB,GAAG,OAAO,CAAC,gCAAgC,CAAC,CA0G5C;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAA;IAC1D,MAAM,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CACxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,2BAA2B,CAAC,EAChD,aAAa,EACb,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,OAAO,EACR,EAAE;IACD,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,yBAAyB,CAAA;IAC7D,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACxD,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwBhC"}
|
|
@@ -65,9 +65,11 @@ export async function unwrapUserKeyGenerations({ descriptor, clientKeyAgreementK
|
|
|
65
65
|
* so the store's seal backstop runs here (`sealed` when it appended);
|
|
66
66
|
* rotated and escrowed writes seal by construction, anchored at the
|
|
67
67
|
* caller's current controller head.
|
|
68
|
-
* - **No epochs
|
|
68
|
+
* - **No epochs**, or a `currentEpoch` naming no epoch in the descriptor's
|
|
69
|
+
* own list: refused fail-closed (see the module doc) -- provisioning
|
|
69
70
|
* installs every encrypted collection's epoch[0], so the cascade never
|
|
70
|
-
* mints a first epoch
|
|
71
|
+
* mints a first epoch, and never guesses which epoch an inconsistent
|
|
72
|
+
* descriptor meant.
|
|
71
73
|
*
|
|
72
74
|
* The pull axis is deliberately a no-op here: a user key rotation follows a
|
|
73
75
|
* document edit (client revocation, code retirement) that already killed the
|
|
@@ -95,8 +97,12 @@ export async function rotateCollectionEpochsToUserKey({ store, userKey, generati
|
|
|
95
97
|
'epoch-less descriptor can only come from a tampering or ' +
|
|
96
98
|
'pre-provisioning host; refusing to rotate it.');
|
|
97
99
|
}
|
|
98
|
-
const currentEpoch = descriptor.epochs.find(epoch => epoch.id === descriptor.currentEpoch)
|
|
99
|
-
|
|
100
|
+
const currentEpoch = descriptor.epochs.find(epoch => epoch.id === descriptor.currentEpoch);
|
|
101
|
+
if (!currentEpoch) {
|
|
102
|
+
throw new Error("The collection descriptor's currentEpoch names no epoch in its own " +
|
|
103
|
+
'epochs list. No enrolled client authenticated such a configuration; ' +
|
|
104
|
+
'refusing to evaluate it against any other epoch.');
|
|
105
|
+
}
|
|
100
106
|
const currentKids = new Set(currentEpoch.recipients.map(entry => entry.header.kid));
|
|
101
107
|
const staleKids = staleGenerations
|
|
102
108
|
.map(generation => epochKeyIdFor(generation.id))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userKeyCascade.js","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"userKeyCascade.js","sourceRoot":"","sources":["../../src/keys/userKeyCascade.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,7 +50,8 @@
|
|
|
50
50
|
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
51
51
|
import type { CollectionEncryption } from '@interop/was-client';
|
|
52
52
|
import { type EncryptionDescriptorStore, type RecipientPublicKey } from '@interop/was-client/edv';
|
|
53
|
-
import type
|
|
53
|
+
import { type ResourceLogSigner } from '../resourceLog/index.js';
|
|
54
|
+
import type { KeyAgreementDocument } from '../webvh/keyAgreement.js';
|
|
54
55
|
import { type ICapabilityAgent } from '../webvh/zcap.js';
|
|
55
56
|
import type { UserKey } from './userKey.js';
|
|
56
57
|
/**
|
|
@@ -83,21 +84,6 @@ export declare class UserKeyRosterContinuityError extends Error {
|
|
|
83
84
|
export declare class UserKeyRosterUnwrapError extends Error {
|
|
84
85
|
constructor(message: string);
|
|
85
86
|
}
|
|
86
|
-
/**
|
|
87
|
-
* The subset of a resolved DID document the recipient resolver consumes: the
|
|
88
|
-
* `keyAgreement` relation (VM references or embedded VMs) and the
|
|
89
|
-
* `verificationMethod` list references resolve against.
|
|
90
|
-
*/
|
|
91
|
-
export interface RosterRecipientDocument {
|
|
92
|
-
keyAgreement?: Array<string | {
|
|
93
|
-
id?: string;
|
|
94
|
-
publicKeyMultibase?: string;
|
|
95
|
-
}>;
|
|
96
|
-
verificationMethod?: Array<{
|
|
97
|
-
id?: string;
|
|
98
|
-
publicKeyMultibase?: string;
|
|
99
|
-
}>;
|
|
100
|
-
}
|
|
101
87
|
/**
|
|
102
88
|
* The roster's log signer: signs each roster log append with this client's
|
|
103
89
|
* own Ed25519 signing key, named by its public multibase -- exactly the
|
|
@@ -143,13 +129,23 @@ export declare function rosterRecipientKid({ signingKeyMultibase, keyAgreementKe
|
|
|
143
129
|
* resolves `null` -- the was-client skip contract -- so the entry is dropped
|
|
144
130
|
* from the fresh epoch and never receives a wrap.
|
|
145
131
|
*
|
|
132
|
+
* The match is over EVERY key-agreement method the document publishes
|
|
133
|
+
* ({@link resolvedKeyAgreementMethods} filtered by nothing more than "carries a
|
|
134
|
+
* public key multibase"), deliberately including the unmarked ones. That is
|
|
135
|
+
* where this predicate parts company with `markedKeyAgreementMethods`, which
|
|
136
|
+
* hard-requires a client's controller marker: a recovery code's key-agreement
|
|
137
|
+
* method is published unmarked by design, so that client listings and
|
|
138
|
+
* revocations never match it, and it must keep its user key wrap through every
|
|
139
|
+
* rotation. Filtering by the marker here would drop every recovery code from
|
|
140
|
+
* each rotated epoch.
|
|
141
|
+
*
|
|
146
142
|
* @param options {object}
|
|
147
|
-
* @param options.document {
|
|
143
|
+
* @param options.document {KeyAgreementDocument} the locally verified
|
|
148
144
|
* did:webvh document (never a server-supplied roster field)
|
|
149
145
|
* @returns {function} a `resolveRecipientKey` for `removeRecipient`
|
|
150
146
|
*/
|
|
151
147
|
export declare function userKeyRosterRecipientResolver({ document }: {
|
|
152
|
-
document:
|
|
148
|
+
document: KeyAgreementDocument;
|
|
153
149
|
}): (kid: string) => Promise<RecipientPublicKey | null>;
|
|
154
150
|
/**
|
|
155
151
|
* Ensures the roster exists, create-if-absent: an absent roster is initialized
|
|
@@ -218,7 +214,7 @@ export declare function addUserKeyRosterRecipient({ store, recipient, ownerKeyAg
|
|
|
218
214
|
* @param options {object}
|
|
219
215
|
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
220
216
|
* store
|
|
221
|
-
* @param options.document {
|
|
217
|
+
* @param options.document {KeyAgreementDocument} the locally verified
|
|
222
218
|
* did:webvh document, AFTER the removal edit
|
|
223
219
|
* @param options.retireRecipientId {string} the removed recipient's roster
|
|
224
220
|
* kid
|
|
@@ -226,7 +222,7 @@ export declare function addUserKeyRosterRecipient({ store, recipient, ownerKeyAg
|
|
|
226
222
|
*/
|
|
227
223
|
export declare function rotateUserKeyRoster({ store, document, retireRecipientId }: {
|
|
228
224
|
store: EncryptionDescriptorStore;
|
|
229
|
-
document:
|
|
225
|
+
document: KeyAgreementDocument;
|
|
230
226
|
retireRecipientId: string;
|
|
231
227
|
}): Promise<CollectionEncryption>;
|
|
232
228
|
/**
|
|
@@ -258,7 +254,7 @@ export declare function rotateUserKeyRoster({ store, document, retireRecipientId
|
|
|
258
254
|
* @param options {object}
|
|
259
255
|
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
260
256
|
* store
|
|
261
|
-
* @param options.document {
|
|
257
|
+
* @param options.document {KeyAgreementDocument} the locally verified
|
|
262
258
|
* did:webvh document -- the recipient source of record
|
|
263
259
|
* @param [options.descriptor] {CollectionEncryption} a descriptor the caller
|
|
264
260
|
* has just read (a login-time roster read), to save a re-read; omitted, the
|
|
@@ -269,7 +265,7 @@ export declare function rotateUserKeyRoster({ store, document, retireRecipientId
|
|
|
269
265
|
*/
|
|
270
266
|
export declare function convergeUserKeyRosterToDocument({ store, document, descriptor }: {
|
|
271
267
|
store: EncryptionDescriptorStore;
|
|
272
|
-
document:
|
|
268
|
+
document: KeyAgreementDocument;
|
|
273
269
|
descriptor?: CollectionEncryption;
|
|
274
270
|
}): Promise<{
|
|
275
271
|
rotated: boolean;
|
|
@@ -316,18 +312,37 @@ export interface UserKeyRosterReadResult {
|
|
|
316
312
|
* path; the result's `rotated` is then true (the user key was adopted from the
|
|
317
313
|
* roster).
|
|
318
314
|
*
|
|
315
|
+
* A caller that just performed a verified roster operation on the same store
|
|
316
|
+
* -- a rotation, or a read moments ago -- may thread that operation's
|
|
317
|
+
* descriptor in as `descriptor`, skipping this read's own fetch: provenance
|
|
318
|
+
* (step 1) is then the earlier operation's, while continuity and possession
|
|
319
|
+
* still run here. That is a within-one-operation reuse, not a cache -- a
|
|
320
|
+
* genuinely distinct acquisition reads the store and re-verifies as always.
|
|
321
|
+
*
|
|
319
322
|
* @param options {object}
|
|
320
323
|
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
321
324
|
* store
|
|
325
|
+
* @param [options.descriptor] {CollectionEncryption} a descriptor a verified
|
|
326
|
+
* operation on the same store just resolved (the return of
|
|
327
|
+
* {@link rotateUserKeyRoster}); supplied, the store is not read
|
|
322
328
|
* @param [options.userKey] {UserKey} this client's cached user key, when it holds one
|
|
323
329
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
324
330
|
* (identity) key-agreement key, unwrapping a rotated epoch
|
|
325
331
|
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
326
332
|
* roster epoch, when this client has seen the roster before
|
|
327
|
-
* @returns {Promise<UserKeyRosterReadResult | null>}
|
|
333
|
+
* @returns {Promise<UserKeyRosterReadResult | null>} `null` only on an
|
|
334
|
+
* absent roster, which a supplied `descriptor` rules out
|
|
328
335
|
*/
|
|
329
|
-
export declare function readUserKeyRoster(
|
|
336
|
+
export declare function readUserKeyRoster(options: {
|
|
330
337
|
store: EncryptionDescriptorStore;
|
|
338
|
+
descriptor: CollectionEncryption;
|
|
339
|
+
userKey?: UserKey;
|
|
340
|
+
clientKeyAgreementKey: IKeyAgreementKey;
|
|
341
|
+
pinnedEpochId?: string | null;
|
|
342
|
+
}): Promise<UserKeyRosterReadResult>;
|
|
343
|
+
export declare function readUserKeyRoster(options: {
|
|
344
|
+
store: EncryptionDescriptorStore;
|
|
345
|
+
descriptor?: CollectionEncryption;
|
|
331
346
|
userKey?: UserKey;
|
|
332
347
|
clientKeyAgreementKey: IKeyAgreementKey;
|
|
333
348
|
pinnedEpochId?: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userKeyRoster.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyRoster.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAML,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"userKeyRoster.d.ts","sourceRoot":"","sources":["../../src/keys/userKeyRoster.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EAML,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAE9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C;;;;;GAKG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,aAAa,EAAE,MAAM,CAAA;gBACT,EAAE,aAAa,EAAE,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE;CAQzD;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,gBAAgB,CAAA;CAC3B,GAAG,iBAAiB,CAgBpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,mBAAmB,EACnB,wBAAwB,EACzB,EAAE;IACD,mBAAmB,EAAE,MAAM,CAAA;IAC3B,wBAAwB,EAAE,MAAM,CAAA;CACjC,GAAG,MAAM,CAET;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,oBAAoB,CAAA;CAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAsBtD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,KAAK,EACL,OAAO,EACP,qBAAqB,EACtB,EAAE;IACD,KAAK,EAAE,yBAAyB,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,qBAAqB,EAAE,gBAAgB,CAAA;CACxC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAUhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,KAAK,EACL,SAAS,EACT,oBAAoB,EACrB,EAAE;IACD,KAAK,EAAE,yBAAyB,CAAA;IAChC,SAAS,EAAE,kBAAkB,CAAA;IAC7B,oBAAoB,EAAE,gBAAgB,CAAA;CACvC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0BhC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,KAAK,EACL,QAAQ,EACR,iBAAiB,EAClB,EAAE;IACD,KAAK,EAAE,yBAAyB,CAAA;IAChC,QAAQ,EAAE,oBAAoB,CAAA;IAC9B,iBAAiB,EAAE,MAAM,CAAA;CAC1B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAOhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,KAAK,EACL,QAAQ,EACR,UAAU,EACX,EAAE;IACD,KAAK,EAAE,yBAAyB,CAAA;IAChC,QAAQ,EAAE,oBAAoB,CAAA;IAC9B,UAAU,CAAC,EAAE,oBAAoB,CAAA;CAClC,GAAG,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAA;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,UAAU,EAAE,oBAAoB,GAAG,IAAI,CAAA;CACxC,CAAC,CAgDD;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,oBAAoB,CAAA;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,KAAK,EAAE,yBAAyB,CAAA;IAChC,UAAU,EAAE,oBAAoB,CAAA;IAChC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAA;AACpC,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,KAAK,EAAE,yBAAyB,CAAA;IAChC,UAAU,CAAC,EAAE,oBAAoB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAA"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { addRecipient, initRecipients, ownerRecipient, removeRecipient, unwrapEpochSecret } from '@interop/was-client/edv';
|
|
2
|
+
import { vmFragmentOf } from '../resourceLog/index.js';
|
|
3
|
+
import { resolvedKeyAgreementMethods } from '../webvh/keyAgreement.js';
|
|
2
4
|
import { clientSigningKeyMultibase } from '../webvh/zcap.js';
|
|
3
5
|
/**
|
|
4
6
|
* Thrown when a served roster fails its client-side consistency checks: a
|
|
@@ -83,19 +85,6 @@ export function userKeyRosterLogSigner({ keyAgent }) {
|
|
|
83
85
|
export function rosterRecipientKid({ signingKeyMultibase, keyAgreementKeyMultibase }) {
|
|
84
86
|
return `did:key:${signingKeyMultibase}#${keyAgreementKeyMultibase}`;
|
|
85
87
|
}
|
|
86
|
-
/**
|
|
87
|
-
* The fragment after the last `#` of a key/VM id -- for the ids this roster
|
|
88
|
-
* handles (did:key KAK ids, `<did>#<multibase>` VM ids) that fragment is the
|
|
89
|
-
* key's public multibase, which is what makes kid-to-VM matching key-material
|
|
90
|
-
* equality rather than string equality across id formats.
|
|
91
|
-
*
|
|
92
|
-
* @param id {string}
|
|
93
|
-
* @returns {string | undefined}
|
|
94
|
-
*/
|
|
95
|
-
function multibaseFragmentOf(id) {
|
|
96
|
-
const hash = id.lastIndexOf('#');
|
|
97
|
-
return hash === -1 ? undefined : id.slice(hash + 1);
|
|
98
|
-
}
|
|
99
88
|
/**
|
|
100
89
|
* Builds the recipient resolver for roster rotations, backed by a locally
|
|
101
90
|
* verified did:webvh document -- the enforcement point for "the roster
|
|
@@ -106,35 +95,32 @@ function multibaseFragmentOf(id) {
|
|
|
106
95
|
* resolves `null` -- the was-client skip contract -- so the entry is dropped
|
|
107
96
|
* from the fresh epoch and never receives a wrap.
|
|
108
97
|
*
|
|
98
|
+
* The match is over EVERY key-agreement method the document publishes
|
|
99
|
+
* ({@link resolvedKeyAgreementMethods} filtered by nothing more than "carries a
|
|
100
|
+
* public key multibase"), deliberately including the unmarked ones. That is
|
|
101
|
+
* where this predicate parts company with `markedKeyAgreementMethods`, which
|
|
102
|
+
* hard-requires a client's controller marker: a recovery code's key-agreement
|
|
103
|
+
* method is published unmarked by design, so that client listings and
|
|
104
|
+
* revocations never match it, and it must keep its user key wrap through every
|
|
105
|
+
* rotation. Filtering by the marker here would drop every recovery code from
|
|
106
|
+
* each rotated epoch.
|
|
107
|
+
*
|
|
109
108
|
* @param options {object}
|
|
110
|
-
* @param options.document {
|
|
109
|
+
* @param options.document {KeyAgreementDocument} the locally verified
|
|
111
110
|
* did:webvh document (never a server-supplied roster field)
|
|
112
111
|
* @returns {function} a `resolveRecipientKey` for `removeRecipient`
|
|
113
112
|
*/
|
|
114
113
|
export function userKeyRosterRecipientResolver({ document }) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
for (const method of document.verificationMethod ?? []) {
|
|
119
|
-
if (typeof method?.id === 'string') {
|
|
120
|
-
byId.set(method.id, method);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const keyAgreementMethods = [];
|
|
124
|
-
for (const entry of document.keyAgreement ?? []) {
|
|
125
|
-
const method = typeof entry === 'string' ? byId.get(entry) : entry;
|
|
126
|
-
if (method && typeof method.publicKeyMultibase === 'string') {
|
|
127
|
-
keyAgreementMethods.push(method);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
114
|
+
const keyAgreementMethods = resolvedKeyAgreementMethods({
|
|
115
|
+
doc: document
|
|
116
|
+
}).filter(method => typeof method.publicKeyMultibase === 'string');
|
|
130
117
|
return async function resolveRecipientKey(kid) {
|
|
131
|
-
const fragment =
|
|
118
|
+
const fragment = vmFragmentOf(kid);
|
|
132
119
|
if (!fragment) {
|
|
133
120
|
return null;
|
|
134
121
|
}
|
|
135
122
|
const match = keyAgreementMethods.find(method => method.publicKeyMultibase === fragment ||
|
|
136
|
-
(typeof method.id === 'string' &&
|
|
137
|
-
multibaseFragmentOf(method.id) === fragment));
|
|
123
|
+
(typeof method.id === 'string' && vmFragmentOf(method.id) === fragment));
|
|
138
124
|
if (!match) {
|
|
139
125
|
// No document verification method backs this roster entry: drop it.
|
|
140
126
|
return null;
|
|
@@ -231,7 +217,7 @@ export async function addUserKeyRosterRecipient({ store, recipient, ownerKeyAgre
|
|
|
231
217
|
* @param options {object}
|
|
232
218
|
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
233
219
|
* store
|
|
234
|
-
* @param options.document {
|
|
220
|
+
* @param options.document {KeyAgreementDocument} the locally verified
|
|
235
221
|
* did:webvh document, AFTER the removal edit
|
|
236
222
|
* @param options.retireRecipientId {string} the removed recipient's roster
|
|
237
223
|
* kid
|
|
@@ -274,7 +260,7 @@ export async function rotateUserKeyRoster({ store, document, retireRecipientId }
|
|
|
274
260
|
* @param options {object}
|
|
275
261
|
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
276
262
|
* store
|
|
277
|
-
* @param options.document {
|
|
263
|
+
* @param options.document {KeyAgreementDocument} the locally verified
|
|
278
264
|
* did:webvh document -- the recipient source of record
|
|
279
265
|
* @param [options.descriptor] {CollectionEncryption} a descriptor the caller
|
|
280
266
|
* has just read (a login-time roster read), to save a re-read; omitted, the
|
|
@@ -325,50 +311,15 @@ export async function convergeUserKeyRosterToDocument({ store, document, descrip
|
|
|
325
311
|
});
|
|
326
312
|
return { rotated: true, staleRecipientIds, descriptor: rotated };
|
|
327
313
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
* every epoch this read can deliver was signed onto the log by an
|
|
337
|
-
* enrolled client. (The detached `epochsSig` this step used to verify on
|
|
338
|
-
* the adopt path is retired; the entry proof covers every read.)
|
|
339
|
-
* 2. **Continuity**: the served epochs must contain the pinned latest-seen
|
|
340
|
-
* epoch, and `currentEpoch` must not precede it in the append-only list
|
|
341
|
-
* (`UserKeyRosterContinuityError` -- the rollback/replay refusal).
|
|
342
|
-
* 3. **Possession**: `currentEpoch === userKey.id` confirms the cached user key
|
|
343
|
-
* current; otherwise the current epoch was rotated by another client and
|
|
344
|
-
* this client's wrap is unwrapped with its own key-agreement key
|
|
345
|
-
* (`UserKeyRosterUnwrapError` when it holds none).
|
|
346
|
-
*
|
|
347
|
-
* A rotated read returns the fresh user key; its Ed25519 signing seed does not
|
|
348
|
-
* travel through the roster (the roster wraps the key-agreement secret
|
|
349
|
-
* alone), so the returned user key carries none.
|
|
350
|
-
*
|
|
351
|
-
* A caller with no cached user key at all -- a freshly enrolled client making
|
|
352
|
-
* its first post-enrollment read -- omits `userKey` and always takes the unwrap
|
|
353
|
-
* path; the result's `rotated` is then true (the user key was adopted from the
|
|
354
|
-
* roster).
|
|
355
|
-
*
|
|
356
|
-
* @param options {object}
|
|
357
|
-
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
358
|
-
* store
|
|
359
|
-
* @param [options.userKey] {UserKey} this client's cached user key, when it holds one
|
|
360
|
-
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
361
|
-
* (identity) key-agreement key, unwrapping a rotated epoch
|
|
362
|
-
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
363
|
-
* roster epoch, when this client has seen the roster before
|
|
364
|
-
* @returns {Promise<UserKeyRosterReadResult | null>}
|
|
365
|
-
*/
|
|
366
|
-
export async function readUserKeyRoster({ store, userKey, clientKeyAgreementKey, pinnedEpochId }) {
|
|
367
|
-
const current = await store.read();
|
|
368
|
-
if (current === null) {
|
|
369
|
-
return null;
|
|
314
|
+
export async function readUserKeyRoster({ store, descriptor: knownDescriptor, userKey, clientKeyAgreementKey, pinnedEpochId }) {
|
|
315
|
+
let descriptor = knownDescriptor;
|
|
316
|
+
if (!descriptor) {
|
|
317
|
+
const current = await store.read();
|
|
318
|
+
if (current === null) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
descriptor = current.descriptor;
|
|
370
322
|
}
|
|
371
|
-
const descriptor = current.descriptor;
|
|
372
323
|
const epochIds = (descriptor.epochs ?? []).map(epoch => epoch.id);
|
|
373
324
|
const currentIndex = descriptor.currentEpoch
|
|
374
325
|
? epochIds.indexOf(descriptor.currentEpoch)
|