@interop/was-client 0.34.0 → 0.35.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 +112 -0
- package/dist/Collection.d.ts +172 -1
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +368 -2
- package/dist/Collection.js.map +1 -1
- package/dist/codec.d.ts +101 -3
- package/dist/codec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.d.ts +34 -4
- package/dist/edv/EdvCodec.d.ts.map +1 -1
- package/dist/edv/EdvCodec.js +268 -42
- package/dist/edv/EdvCodec.js.map +1 -1
- package/dist/edv/docCipher.d.ts.map +1 -1
- package/dist/edv/docCipher.js +5 -9
- package/dist/edv/docCipher.js.map +1 -1
- package/dist/edv/hmacKey.d.ts +76 -0
- package/dist/edv/hmacKey.d.ts.map +1 -0
- package/dist/edv/hmacKey.js +105 -0
- package/dist/edv/hmacKey.js.map +1 -0
- package/dist/edv/index.d.ts +7 -0
- package/dist/edv/index.d.ts.map +1 -1
- package/dist/edv/index.js +6 -0
- package/dist/edv/index.js.map +1 -1
- package/dist/edv/recipients.d.ts +22 -3
- package/dist/edv/recipients.d.ts.map +1 -1
- package/dist/edv/recipients.js +197 -21
- package/dist/edv/recipients.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/codec.d.ts.map +1 -1
- package/dist/internal/codec.js +64 -3
- package/dist/internal/codec.js.map +1 -1
- package/dist/internal/content.d.ts +12 -0
- package/dist/internal/content.d.ts.map +1 -1
- package/dist/internal/content.js +18 -0
- package/dist/internal/content.js.map +1 -1
- package/dist/internal/indexSchema.d.ts +95 -0
- package/dist/internal/indexSchema.d.ts.map +1 -0
- package/dist/internal/indexSchema.js +120 -0
- package/dist/internal/indexSchema.js.map +1 -0
- package/dist/internal/paths.d.ts +6 -0
- package/dist/internal/paths.d.ts.map +1 -1
- package/dist/internal/paths.js +8 -0
- package/dist/internal/paths.js.map +1 -1
- package/dist/paths.d.ts +1 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +1 -1
- package/dist/paths.js.map +1 -1
- package/dist/types.d.ts +40 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docCipher.d.ts","sourceRoot":"","sources":["../../src/edv/docCipher.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"docCipher.d.ts","sourceRoot":"","sources":["../../src/edv/docCipher.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AAIrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAQ,MAAM,kBAAkB,CAAA;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAMzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAC7B,eAAe,EAChB,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;CAClC,GAAG,kBAAkB,CAcrB;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAwB,EACxB,UAAU,EACX,EAAE;IACD,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;IACnC,UAAU,EAAE,oBAAoB,CAAA;CACjC,GAAG,OAAO,CAAC,SAAS,CAAC,CAyGrB"}
|
package/dist/edv/docCipher.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { storedResponse } from '../internal/content.js';
|
|
1
2
|
import { KeyUnwrapError } from '../errors.js';
|
|
2
3
|
import { createEdvEncryption } from './EdvCodec.js';
|
|
3
4
|
// `isEncryptedEnvelope` and the `DocCipher` interface live in the crypto-free
|
|
@@ -30,20 +31,15 @@ export function ownerRecipient({ keyAgreementKey }) {
|
|
|
30
31
|
return { id, publicKeyMultibase, type };
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
* Presents a locally-held envelope to the codec seam as the
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* (so an ETag lookup resolves to "no validator") are the whole surface.
|
|
34
|
+
* Presents a locally-held envelope to the codec seam as the `ResponseLike` the
|
|
35
|
+
* seam is typed against. A replica's envelope never came from HTTP, so the
|
|
36
|
+
* shared stored-body adapter is the whole surface it needs.
|
|
37
37
|
*
|
|
38
38
|
* @param envelope {Json} the stored envelope
|
|
39
39
|
* @returns {ResponseLike}
|
|
40
40
|
*/
|
|
41
41
|
function envelopeResponse(envelope) {
|
|
42
|
-
return
|
|
43
|
-
data: envelope,
|
|
44
|
-
json: async () => envelope,
|
|
45
|
-
headers: { get: () => null }
|
|
46
|
-
};
|
|
42
|
+
return storedResponse(envelope);
|
|
47
43
|
}
|
|
48
44
|
/**
|
|
49
45
|
* Builds a {@link DocCipher} for one encrypted collection from a reader's key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docCipher.js","sourceRoot":"","sources":["../../src/edv/docCipher.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAG7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAGnD,8EAA8E;AAC9E,2EAA2E;AAC3E,6EAA6E;AAC7E,6EAA6E;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAEzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,eAAe,EAGhB;IACC,MAAM,EAAE,EAAE,EAAE,GAAG,eAAe,CAAA;IAC9B,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAGpC,CAAA;IACD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,kBAAkB,KAAK,QAAQ,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CACb,wEAAwE;YACtE,uEAAuE;YACvE,aAAa,CAChB,CAAA;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAA;AACzC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"docCipher.js","sourceRoot":"","sources":["../../src/edv/docCipher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { SHA256HMACKey } from '@interop/data-integrity-core';
|
|
2
|
+
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
3
|
+
import type { EncryptionWithHmac } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The key type tag a blinded-index HMAC key is declared with on the descriptor.
|
|
6
|
+
*/
|
|
7
|
+
export declare const HMAC_KEY_TYPE = "Sha256HmacKey2019";
|
|
8
|
+
/**
|
|
9
|
+
* The minimal blinding-key contract the codec needs: an `id` (stamped on an
|
|
10
|
+
* envelope's `indexed[].hmac.id`), a `type`, and HMAC sign/verify over bytes.
|
|
11
|
+
* Structural rather than nominal, so a keystore that custodies the HMAC key
|
|
12
|
+
* itself (or fronts a KMS) can supply its own implementation;
|
|
13
|
+
* {@link SHA256HMACKey} satisfies it, and so does the `IHMAC` contract
|
|
14
|
+
* `@interop/edv-client` blinds with (this narrows it: `id` and `type` are
|
|
15
|
+
* required here, since both are stamped on an envelope's `indexed` entries).
|
|
16
|
+
*/
|
|
17
|
+
export interface BlindingKey {
|
|
18
|
+
id: string;
|
|
19
|
+
type: string;
|
|
20
|
+
sign(options: {
|
|
21
|
+
data: Uint8Array;
|
|
22
|
+
}): Promise<Uint8Array>;
|
|
23
|
+
verify(options: {
|
|
24
|
+
data: Uint8Array;
|
|
25
|
+
signature: Uint8Array;
|
|
26
|
+
}): Promise<boolean>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Mints a fresh blinded-index HMAC key: 32 random bytes under a random
|
|
30
|
+
* `urn:uuid:` id. The caller wraps the returned `secret` to each recipient with
|
|
31
|
+
* {@link wrapEpochSecret} and installs `{ id, type, recipients }` on the
|
|
32
|
+
* descriptor's `hmac` member.
|
|
33
|
+
*
|
|
34
|
+
* @returns {Promise<{ id: string, type: string, secret: Uint8Array }>}
|
|
35
|
+
*/
|
|
36
|
+
export declare function mintHmacKey(): Promise<{
|
|
37
|
+
id: string;
|
|
38
|
+
type: string;
|
|
39
|
+
secret: Uint8Array;
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Rebuilds the concrete HMAC key from its raw secret -- what a reader does once
|
|
43
|
+
* it has unwrapped the secret from its descriptor entry. The secret is imported
|
|
44
|
+
* as a standard `oct` JWK, the serialization {@link SHA256HMACKey.from} accepts.
|
|
45
|
+
*
|
|
46
|
+
* @param options {object}
|
|
47
|
+
* @param options.id {string} the key id (`indexed[].hmac.id`)
|
|
48
|
+
* @param options.secret {Uint8Array} the raw 32-byte HMAC secret
|
|
49
|
+
* @returns {Promise<SHA256HMACKey>}
|
|
50
|
+
*/
|
|
51
|
+
export declare function hmacKeyFromSecret({ id, secret }: {
|
|
52
|
+
id: string;
|
|
53
|
+
secret: Uint8Array;
|
|
54
|
+
}): Promise<SHA256HMACKey>;
|
|
55
|
+
/**
|
|
56
|
+
* Resolves the collection's blinding key from its `encryption` descriptor with
|
|
57
|
+
* a reader's own key-agreement key. Returns `null` when the descriptor declares
|
|
58
|
+
* no `hmac` member -- the collection is simply not indexable (installed at
|
|
59
|
+
* provisioning or never).
|
|
60
|
+
*
|
|
61
|
+
* Fails closed when the descriptor DOES declare one but this key-agreement key
|
|
62
|
+
* unwraps no entry: a current recipient must be able to blind, so a missing or
|
|
63
|
+
* corrupt entry is an {@link EncryptionError} rather than a silent
|
|
64
|
+
* "unindexable" downgrade that would write envelopes nobody can find.
|
|
65
|
+
*
|
|
66
|
+
* @param options {object}
|
|
67
|
+
* @param options.encryption {EncryptionWithHmac} the Collection's descriptor
|
|
68
|
+
* @param options.keyAgreementKey {IKeyAgreementKey} the reader's own KAK; its
|
|
69
|
+
* `id` must match an `hmac.recipients` entry's `kid`
|
|
70
|
+
* @returns {Promise<SHA256HMACKey | null>}
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveHmacKey({ encryption, keyAgreementKey }: {
|
|
73
|
+
encryption: EncryptionWithHmac;
|
|
74
|
+
keyAgreementKey: IKeyAgreementKey;
|
|
75
|
+
}): Promise<SHA256HMACKey | null>;
|
|
76
|
+
//# sourceMappingURL=hmacKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmacKey.d.ts","sourceRoot":"","sources":["../../src/edv/hmacKey.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAEpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAGrD;;GAEG;AACH,eAAO,MAAM,aAAa,sBAAsB,CAAA;AAEhD;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACxD,MAAM,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,SAAS,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC/E;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC;IAC3C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,CAAA;CACnB,CAAC,CAGD;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,EAAE,EACF,MAAM,EACP,EAAE;IACD,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,UAAU,CAAA;CACnB,GAAG,OAAO,CAAC,aAAa,CAAC,CAUzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAAC,EACnC,UAAU,EACV,eAAe,EAChB,EAAE;IACD,UAAU,EAAE,kBAAkB,CAAA;IAC9B,eAAe,EAAE,gBAAgB,CAAA;CAClC,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAqBhC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The blinded-index HMAC key of an encrypted Collection: minting it, rebuilding
|
|
6
|
+
* it from its raw secret, and resolving it from the `encryption` descriptor
|
|
7
|
+
* with a reader's own key-agreement key.
|
|
8
|
+
*
|
|
9
|
+
* A blinded index lets the server match a query without learning what it
|
|
10
|
+
* matched: attribute names and values are HMAC-SHA-256 tags under a
|
|
11
|
+
* per-collection key, so equal plaintext blinds to equal tokens and nothing
|
|
12
|
+
* else. That is why the key never rotates -- tokens must compare across the
|
|
13
|
+
* collection's whole history -- and why it is installed at provisioning or
|
|
14
|
+
* never: retro-fitting a key would leave every already-written envelope
|
|
15
|
+
* unindexed.
|
|
16
|
+
*
|
|
17
|
+
* Distribution reuses the epoch machinery verbatim: the 32-byte HMAC secret is
|
|
18
|
+
* wrapped to each recipient's X25519 key-agreement key with
|
|
19
|
+
* {@link wrapEpochSecret} (`ECDH-ES+A256KW`) and stored as a JWE `recipients`
|
|
20
|
+
* entry on the descriptor's `hmac` member, exactly as an epoch secret is stored
|
|
21
|
+
* on an epoch. There is deliberately no separate wrap primitive here: one wrap
|
|
22
|
+
* shape, one review surface.
|
|
23
|
+
*
|
|
24
|
+
* Removing a recipient drops its wrap entry but leaves the key itself alone, so
|
|
25
|
+
* a removed recipient keeps the blinding key -- an accepted, documented
|
|
26
|
+
* revocation asymmetry (it can confirm guessed attribute values if the server
|
|
27
|
+
* colludes).
|
|
28
|
+
*/
|
|
29
|
+
import { base64urlnopad } from '@scure/base';
|
|
30
|
+
import { SHA256HMACKey } from '@interop/data-integrity-core';
|
|
31
|
+
import { EncryptionError } from '../errors.js';
|
|
32
|
+
import { unwrapEpochSecret } from './epochCrypto.js';
|
|
33
|
+
/**
|
|
34
|
+
* The key type tag a blinded-index HMAC key is declared with on the descriptor.
|
|
35
|
+
*/
|
|
36
|
+
export const HMAC_KEY_TYPE = 'Sha256HmacKey2019';
|
|
37
|
+
/**
|
|
38
|
+
* Mints a fresh blinded-index HMAC key: 32 random bytes under a random
|
|
39
|
+
* `urn:uuid:` id. The caller wraps the returned `secret` to each recipient with
|
|
40
|
+
* {@link wrapEpochSecret} and installs `{ id, type, recipients }` on the
|
|
41
|
+
* descriptor's `hmac` member.
|
|
42
|
+
*
|
|
43
|
+
* @returns {Promise<{ id: string, type: string, secret: Uint8Array }>}
|
|
44
|
+
*/
|
|
45
|
+
export async function mintHmacKey() {
|
|
46
|
+
const secret = crypto.getRandomValues(new Uint8Array(32));
|
|
47
|
+
return { id: `urn:uuid:${crypto.randomUUID()}`, type: HMAC_KEY_TYPE, secret };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rebuilds the concrete HMAC key from its raw secret -- what a reader does once
|
|
51
|
+
* it has unwrapped the secret from its descriptor entry. The secret is imported
|
|
52
|
+
* as a standard `oct` JWK, the serialization {@link SHA256HMACKey.from} accepts.
|
|
53
|
+
*
|
|
54
|
+
* @param options {object}
|
|
55
|
+
* @param options.id {string} the key id (`indexed[].hmac.id`)
|
|
56
|
+
* @param options.secret {Uint8Array} the raw 32-byte HMAC secret
|
|
57
|
+
* @returns {Promise<SHA256HMACKey>}
|
|
58
|
+
*/
|
|
59
|
+
export async function hmacKeyFromSecret({ id, secret }) {
|
|
60
|
+
return SHA256HMACKey.from({
|
|
61
|
+
id,
|
|
62
|
+
type: HMAC_KEY_TYPE,
|
|
63
|
+
secretKeyJwk: {
|
|
64
|
+
kty: 'oct',
|
|
65
|
+
k: base64urlnopad.encode(secret),
|
|
66
|
+
alg: 'HS256'
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolves the collection's blinding key from its `encryption` descriptor with
|
|
72
|
+
* a reader's own key-agreement key. Returns `null` when the descriptor declares
|
|
73
|
+
* no `hmac` member -- the collection is simply not indexable (installed at
|
|
74
|
+
* provisioning or never).
|
|
75
|
+
*
|
|
76
|
+
* Fails closed when the descriptor DOES declare one but this key-agreement key
|
|
77
|
+
* unwraps no entry: a current recipient must be able to blind, so a missing or
|
|
78
|
+
* corrupt entry is an {@link EncryptionError} rather than a silent
|
|
79
|
+
* "unindexable" downgrade that would write envelopes nobody can find.
|
|
80
|
+
*
|
|
81
|
+
* @param options {object}
|
|
82
|
+
* @param options.encryption {EncryptionWithHmac} the Collection's descriptor
|
|
83
|
+
* @param options.keyAgreementKey {IKeyAgreementKey} the reader's own KAK; its
|
|
84
|
+
* `id` must match an `hmac.recipients` entry's `kid`
|
|
85
|
+
* @returns {Promise<SHA256HMACKey | null>}
|
|
86
|
+
*/
|
|
87
|
+
export async function resolveHmacKey({ encryption, keyAgreementKey }) {
|
|
88
|
+
const hmac = encryption.hmac;
|
|
89
|
+
if (!hmac) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const entry = hmac.recipients?.find(recipient => recipient.header.kid === keyAgreementKey.id);
|
|
93
|
+
const secret = entry
|
|
94
|
+
? await unwrapEpochSecret({ entry, keyAgreementKey })
|
|
95
|
+
: null;
|
|
96
|
+
if (!secret) {
|
|
97
|
+
throw new EncryptionError('This collection declares a blinded-index key ' +
|
|
98
|
+
`("${hmac.id}") that this client's key-agreement key ` +
|
|
99
|
+
`("${keyAgreementKey.id}") cannot unwrap (no recipient entry names ` +
|
|
100
|
+
'it, or its entry is corrupt). Re-add this reader with addRecipient, ' +
|
|
101
|
+
'or supply the correct key-agreement key.');
|
|
102
|
+
}
|
|
103
|
+
return hmacKeyFromSecret({ id: hmac.id, secret });
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=hmacKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmacKey.js","sourceRoot":"","sources":["../../src/edv/hmacKey.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAA;AAkBhD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAK/B,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IACzD,OAAO,EAAE,EAAE,EAAE,YAAY,MAAM,CAAC,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAA;AAC/E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,EAAE,EACF,MAAM,EAIP;IACC,OAAO,aAAa,CAAC,IAAI,CAAC;QACxB,EAAE;QACF,IAAI,EAAE,aAAa;QACnB,YAAY,EAAE;YACZ,GAAG,EAAE,KAAK;YACV,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC;YAChC,GAAG,EAAE,OAAO;SACb;KACF,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EACnC,UAAU,EACV,eAAe,EAIhB;IACC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAA;IAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CACjC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,eAAe,CAAC,EAAE,CACzD,CAAA;IACD,MAAM,MAAM,GAAG,KAAK;QAClB,CAAC,CAAC,MAAM,iBAAiB,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;QACrD,CAAC,CAAC,IAAI,CAAA;IACR,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,eAAe,CACvB,+CAA+C;YAC7C,KAAK,IAAI,CAAC,EAAE,0CAA0C;YACtD,KAAK,eAAe,CAAC,EAAE,6CAA6C;YACpE,sEAAsE;YACtE,0CAA0C,CAC7C,CAAA;IACH,CAAC;IACD,OAAO,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;AACnD,CAAC"}
|
package/dist/edv/index.d.ts
CHANGED
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
* Description by default, or any `EncryptionDescriptorStore` -- e.g.
|
|
29
29
|
* `resourceDescriptorStore` for a descriptor hosted as a plain JSON Resource.
|
|
30
30
|
*
|
|
31
|
+
* A collection provisioned with `ensureFirstEpoch({ blindedIndex: true })` also
|
|
32
|
+
* carries a blinded-index HMAC key, distributed to recipients exactly like an
|
|
33
|
+
* epoch key (see `hmacKey.ts`). It is installed at provisioning or never, and
|
|
34
|
+
* never rotates.
|
|
35
|
+
*
|
|
31
36
|
* `x25519RecipientFromDidKey` is the one rule for turning a grantee named only
|
|
32
37
|
* by its Ed25519 `did:key` controller into a `RecipientPublicKey`, so a
|
|
33
38
|
* recipient key is always derived from an identifier both sides already hold
|
|
@@ -45,6 +50,8 @@ export type { EncryptionDescriptorStore } from './descriptorStore.js';
|
|
|
45
50
|
export { mintEpoch, epochKeyIdFor, unwrapEpochSecret, wrapEpochSecret } from './epochCrypto.js';
|
|
46
51
|
export { resolveEpochKeys } from './epochKeys.js';
|
|
47
52
|
export type { ResolvedEpochKeys } from './epochKeys.js';
|
|
53
|
+
export { HMAC_KEY_TYPE, mintHmacKey, hmacKeyFromSecret, resolveHmacKey } from './hmacKey.js';
|
|
54
|
+
export type { BlindingKey } from './hmacKey.js';
|
|
48
55
|
export { createEdvDocCipher, ownerRecipient, UnknownEpochError, isEncryptedEnvelope } from './docCipher.js';
|
|
49
56
|
export type { DocCipher } from './docCipher.js';
|
|
50
57
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/edv/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/edv/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/edv/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7D,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,gBAAgB,EACjB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EACL,eAAe,EACf,yBAAyB,EAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AACrE,OAAO,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,eAAe,EAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EACL,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,cAAc,EACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/edv/index.js
CHANGED
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
* Description by default, or any `EncryptionDescriptorStore` -- e.g.
|
|
29
29
|
* `resourceDescriptorStore` for a descriptor hosted as a plain JSON Resource.
|
|
30
30
|
*
|
|
31
|
+
* A collection provisioned with `ensureFirstEpoch({ blindedIndex: true })` also
|
|
32
|
+
* carries a blinded-index HMAC key, distributed to recipients exactly like an
|
|
33
|
+
* epoch key (see `hmacKey.ts`). It is installed at provisioning or never, and
|
|
34
|
+
* never rotates.
|
|
35
|
+
*
|
|
31
36
|
* `x25519RecipientFromDidKey` is the one rule for turning a grantee named only
|
|
32
37
|
* by its Ed25519 `did:key` controller into a `RecipientPublicKey`, so a
|
|
33
38
|
* recipient key is always derived from an identifier both sides already hold
|
|
@@ -41,5 +46,6 @@ export { isEd25519DidKey, x25519RecipientFromDidKey } from './didKeyRecipient.js
|
|
|
41
46
|
export { collectionDescriptorStore, resourceDescriptorStore } from './descriptorStore.js';
|
|
42
47
|
export { mintEpoch, epochKeyIdFor, unwrapEpochSecret, wrapEpochSecret } from './epochCrypto.js';
|
|
43
48
|
export { resolveEpochKeys } from './epochKeys.js';
|
|
49
|
+
export { HMAC_KEY_TYPE, mintHmacKey, hmacKeyFromSecret, resolveHmacKey } from './hmacKey.js';
|
|
44
50
|
export { createEdvDocCipher, ownerRecipient, UnknownEpochError, isEncryptedEnvelope } from './docCipher.js';
|
|
45
51
|
//# sourceMappingURL=index.js.map
|
package/dist/edv/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/edv/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/edv/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,gBAAgB,EACjB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,eAAe,EACf,yBAAyB,EAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,eAAe,EAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEjD,OAAO,EACL,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,cAAc,EACf,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,gBAAgB,CAAA"}
|
package/dist/edv/recipients.d.ts
CHANGED
|
@@ -70,14 +70,22 @@ export type { RecipientPublicKey } from './epochCrypto.js';
|
|
|
70
70
|
* @param [options.store] {EncryptionDescriptorStore} an explicit descriptor store
|
|
71
71
|
* @param options.recipients {RecipientPublicKey[]} the initial readers' public
|
|
72
72
|
* key-agreement keys (each `id` is the reader's `kid`)
|
|
73
|
+
* @param [options.blindedIndex] {boolean} install the collection's
|
|
74
|
+
* blinded-index HMAC key alongside epoch[0], wrapped to the same initial
|
|
75
|
+
* recipients (default `false`). Greenfield only: the key is installed at
|
|
76
|
+
* provisioning or never -- asking for it on a descriptor that already carries
|
|
77
|
+
* an epoch roster without one throws {@link EncryptionError}, while a
|
|
78
|
+
* descriptor that already carries one is adopted as-is (so a torn
|
|
79
|
+
* provisioning run still heals by re-running this with the same option).
|
|
73
80
|
* @returns {Promise<{ descriptor: CollectionEncryption, installed: boolean }>}
|
|
74
81
|
* the collection's epoch-bearing descriptor, and whether this call installed
|
|
75
82
|
* its epoch[0] (`false` means an existing roster was adopted)
|
|
76
83
|
*/
|
|
77
|
-
export declare function ensureFirstEpoch({ collection, store, recipients }: {
|
|
84
|
+
export declare function ensureFirstEpoch({ collection, store, recipients, blindedIndex }: {
|
|
78
85
|
collection?: Collection;
|
|
79
86
|
store?: EncryptionDescriptorStore;
|
|
80
87
|
recipients: RecipientPublicKey[];
|
|
88
|
+
blindedIndex?: boolean;
|
|
81
89
|
}): Promise<{
|
|
82
90
|
descriptor: CollectionEncryption;
|
|
83
91
|
installed: boolean;
|
|
@@ -126,8 +134,10 @@ export declare function initRecipients({ collection, store, recipients, epoch: p
|
|
|
126
134
|
* included. No rotation happens -- **adds are cheap, removals rotate.**
|
|
127
135
|
*
|
|
128
136
|
* The caller must itself be a recipient of every epoch (its `owner` key unwraps
|
|
129
|
-
* each epoch key, which is then re-wrapped to the new reader).
|
|
130
|
-
* a
|
|
137
|
+
* each epoch key, which is then re-wrapped to the new reader). Where the
|
|
138
|
+
* descriptor also carries a blinded-index HMAC key, the new reader receives
|
|
139
|
+
* that key the same way, in the same write. Written back with a
|
|
140
|
+
* compare-and-swap, retried on a concurrent change.
|
|
131
141
|
*
|
|
132
142
|
* @param options {object}
|
|
133
143
|
* @param [options.collection] {Collection} the collection whose Description
|
|
@@ -177,6 +187,11 @@ export declare function addRecipient({ collection, store, recipient, owner }: {
|
|
|
177
187
|
* reader keeps every earlier epoch's key and can still decrypt any pre-rotation
|
|
178
188
|
* resource whose ciphertext it gets. Neither half alone removes a reader.
|
|
179
189
|
*
|
|
190
|
+
* Where the descriptor carries a blinded-index HMAC key, the removed reader's
|
|
191
|
+
* wrap entry is dropped from it in the same write -- housekeeping only. That
|
|
192
|
+
* key never rotates (blinded tokens must compare across the collection's whole
|
|
193
|
+
* history), so the removed reader keeps the blinding key it already holds.
|
|
194
|
+
*
|
|
180
195
|
* @param options {object}
|
|
181
196
|
* @param [options.collection] {Collection} the collection whose Description
|
|
182
197
|
* hosts the descriptor; exactly one of `collection` / `store`
|
|
@@ -237,6 +252,10 @@ export declare function removeRecipient({ collection, store, space, recipientId,
|
|
|
237
252
|
* The rotation ceiling is unchanged: nothing is re-encrypted, so a retired
|
|
238
253
|
* key still opens every pre-rotation epoch it was a recipient of.
|
|
239
254
|
*
|
|
255
|
+
* A blinded-index HMAC key on the descriptor follows the same shape in the same
|
|
256
|
+
* write: the incoming recipient gains a wrap entry, the retiring kid(s) lose
|
|
257
|
+
* theirs, and the key itself never rotates.
|
|
258
|
+
*
|
|
240
259
|
* @param options {object}
|
|
241
260
|
* @param [options.collection] {Collection} the collection whose Description
|
|
242
261
|
* hosts the descriptor; exactly one of `collection` / `store`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipients.d.ts","sourceRoot":"","sources":["../../src/edv/recipients.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"recipients.d.ts","sourceRoot":"","sources":["../../src/edv/recipients.ts"],"names":[],"mappings":"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"}
|