@syncular/core 0.63.0 → 0.64.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/dist/crypto.d.ts +20 -7
- package/dist/crypto.js +24 -8
- package/package.json +1 -1
- package/src/crypto.ts +33 -9
package/dist/crypto.d.ts
CHANGED
|
@@ -10,14 +10,25 @@ export declare const NONCE_LENGTH = 12;
|
|
|
10
10
|
export declare const KEY_LENGTH = 32;
|
|
11
11
|
/**
|
|
12
12
|
* Client-local decrypt failure (SPEC.md §5.11, §10.3). Never on the wire —
|
|
13
|
-
* the `client.` family is client-only. Raised at the apply seam
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* the `client.` family is client-only. Raised at the apply seam. A `keyId`
|
|
14
|
+
* the keyring does not hold is `client.encryption_key_missing` with
|
|
15
|
+
* `details` naming the key id (and the table at the apply seam); an unknown
|
|
16
|
+
* envelope version, GCM auth failure (wrong key), a malformed envelope, or a
|
|
17
|
+
* post-decrypt value-parse failure is `client.decrypt_failed`. Not
|
|
18
|
+
* retryable.
|
|
16
19
|
*/
|
|
17
20
|
export declare class DecryptError extends Error {
|
|
18
21
|
readonly name = "DecryptError";
|
|
19
|
-
readonly code
|
|
22
|
+
readonly code: 'client.decrypt_failed' | 'client.encryption_key_missing';
|
|
20
23
|
readonly retryable = false;
|
|
24
|
+
readonly details: {
|
|
25
|
+
readonly table?: string | undefined;
|
|
26
|
+
readonly keyId: string;
|
|
27
|
+
} | undefined;
|
|
28
|
+
constructor(message: string, missingKey?: {
|
|
29
|
+
readonly table?: string | undefined;
|
|
30
|
+
readonly keyId: string;
|
|
31
|
+
});
|
|
21
32
|
}
|
|
22
33
|
/**
|
|
23
34
|
* Client-local encrypt failure (SPEC.md §5.11, §10.3). Never on the wire.
|
|
@@ -65,7 +76,9 @@ export declare function decodeEnvelope(bytes: Uint8Array): Envelope;
|
|
|
65
76
|
export declare function encryptValue(declaredType: DeclaredType, value: PlainValue, keyId: string, key: Uint8Array, nonceSource?: NonceSource): Promise<Uint8Array>;
|
|
66
77
|
/**
|
|
67
78
|
* Decrypt a §5.11 envelope back to a declared-type value. `keyProvider`
|
|
68
|
-
* resolves the envelope's `keyId` to key bytes
|
|
69
|
-
*
|
|
79
|
+
* resolves the envelope's `keyId` to key bytes. A missing key is a
|
|
80
|
+
* {@link DecryptError} coded `client.encryption_key_missing` whose details
|
|
81
|
+
* name the key id and, when given, `table`; a GCM tag mismatch is
|
|
82
|
+
* `client.decrypt_failed`.
|
|
70
83
|
*/
|
|
71
|
-
export declare function decryptValue(declaredType: DeclaredType, envelopeBytes: Uint8Array, keyProvider: (keyId: string) => Uint8Array | undefined): Promise<PlainValue>;
|
|
84
|
+
export declare function decryptValue(declaredType: DeclaredType, envelopeBytes: Uint8Array, keyProvider: (keyId: string) => Uint8Array | undefined, table?: string): Promise<PlainValue>;
|
package/dist/crypto.js
CHANGED
|
@@ -22,14 +22,25 @@ export const NONCE_LENGTH = 12;
|
|
|
22
22
|
export const KEY_LENGTH = 32;
|
|
23
23
|
/**
|
|
24
24
|
* Client-local decrypt failure (SPEC.md §5.11, §10.3). Never on the wire —
|
|
25
|
-
* the `client.` family is client-only. Raised at the apply seam
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* the `client.` family is client-only. Raised at the apply seam. A `keyId`
|
|
26
|
+
* the keyring does not hold is `client.encryption_key_missing` with
|
|
27
|
+
* `details` naming the key id (and the table at the apply seam); an unknown
|
|
28
|
+
* envelope version, GCM auth failure (wrong key), a malformed envelope, or a
|
|
29
|
+
* post-decrypt value-parse failure is `client.decrypt_failed`. Not
|
|
30
|
+
* retryable.
|
|
28
31
|
*/
|
|
29
32
|
export class DecryptError extends Error {
|
|
30
33
|
name = 'DecryptError';
|
|
31
|
-
code
|
|
34
|
+
code;
|
|
32
35
|
retryable = false;
|
|
36
|
+
details;
|
|
37
|
+
constructor(message, missingKey) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.code = missingKey
|
|
40
|
+
? 'client.encryption_key_missing'
|
|
41
|
+
: 'client.decrypt_failed';
|
|
42
|
+
this.details = missingKey;
|
|
43
|
+
}
|
|
33
44
|
}
|
|
34
45
|
/**
|
|
35
46
|
* Client-local encrypt failure (SPEC.md §5.11, §10.3). Never on the wire.
|
|
@@ -240,14 +251,19 @@ export async function encryptValue(declaredType, value, keyId, key, nonceSource
|
|
|
240
251
|
}
|
|
241
252
|
/**
|
|
242
253
|
* Decrypt a §5.11 envelope back to a declared-type value. `keyProvider`
|
|
243
|
-
* resolves the envelope's `keyId` to key bytes
|
|
244
|
-
*
|
|
254
|
+
* resolves the envelope's `keyId` to key bytes. A missing key is a
|
|
255
|
+
* {@link DecryptError} coded `client.encryption_key_missing` whose details
|
|
256
|
+
* name the key id and, when given, `table`; a GCM tag mismatch is
|
|
257
|
+
* `client.decrypt_failed`.
|
|
245
258
|
*/
|
|
246
|
-
export async function decryptValue(declaredType, envelopeBytes, keyProvider) {
|
|
259
|
+
export async function decryptValue(declaredType, envelopeBytes, keyProvider, table) {
|
|
247
260
|
const envelope = decodeEnvelope(envelopeBytes);
|
|
248
261
|
const key = keyProvider(envelope.keyId);
|
|
249
262
|
if (key === undefined) {
|
|
250
|
-
throw new DecryptError(
|
|
263
|
+
throw new DecryptError('no key for the envelope keyId', {
|
|
264
|
+
table,
|
|
265
|
+
keyId: envelope.keyId,
|
|
266
|
+
});
|
|
251
267
|
}
|
|
252
268
|
const cryptoKey = await importAesKey(key);
|
|
253
269
|
let plaintext;
|
package/package.json
CHANGED
package/src/crypto.ts
CHANGED
|
@@ -39,14 +39,34 @@ export const KEY_LENGTH = 32;
|
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* Client-local decrypt failure (SPEC.md §5.11, §10.3). Never on the wire —
|
|
42
|
-
* the `client.` family is client-only. Raised at the apply seam
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* the `client.` family is client-only. Raised at the apply seam. A `keyId`
|
|
43
|
+
* the keyring does not hold is `client.encryption_key_missing` with
|
|
44
|
+
* `details` naming the key id (and the table at the apply seam); an unknown
|
|
45
|
+
* envelope version, GCM auth failure (wrong key), a malformed envelope, or a
|
|
46
|
+
* post-decrypt value-parse failure is `client.decrypt_failed`. Not
|
|
47
|
+
* retryable.
|
|
45
48
|
*/
|
|
46
49
|
export class DecryptError extends Error {
|
|
47
50
|
override readonly name = 'DecryptError';
|
|
48
|
-
readonly code
|
|
51
|
+
readonly code: 'client.decrypt_failed' | 'client.encryption_key_missing';
|
|
49
52
|
readonly retryable = false;
|
|
53
|
+
readonly details:
|
|
54
|
+
| { readonly table?: string | undefined; readonly keyId: string }
|
|
55
|
+
| undefined;
|
|
56
|
+
|
|
57
|
+
constructor(
|
|
58
|
+
message: string,
|
|
59
|
+
missingKey?: {
|
|
60
|
+
readonly table?: string | undefined;
|
|
61
|
+
readonly keyId: string;
|
|
62
|
+
},
|
|
63
|
+
) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.code = missingKey
|
|
66
|
+
? 'client.encryption_key_missing'
|
|
67
|
+
: 'client.decrypt_failed';
|
|
68
|
+
this.details = missingKey;
|
|
69
|
+
}
|
|
50
70
|
}
|
|
51
71
|
|
|
52
72
|
/**
|
|
@@ -313,20 +333,24 @@ export async function encryptValue(
|
|
|
313
333
|
|
|
314
334
|
/**
|
|
315
335
|
* Decrypt a §5.11 envelope back to a declared-type value. `keyProvider`
|
|
316
|
-
* resolves the envelope's `keyId` to key bytes
|
|
317
|
-
*
|
|
336
|
+
* resolves the envelope's `keyId` to key bytes. A missing key is a
|
|
337
|
+
* {@link DecryptError} coded `client.encryption_key_missing` whose details
|
|
338
|
+
* name the key id and, when given, `table`; a GCM tag mismatch is
|
|
339
|
+
* `client.decrypt_failed`.
|
|
318
340
|
*/
|
|
319
341
|
export async function decryptValue(
|
|
320
342
|
declaredType: DeclaredType,
|
|
321
343
|
envelopeBytes: Uint8Array,
|
|
322
344
|
keyProvider: (keyId: string) => Uint8Array | undefined,
|
|
345
|
+
table?: string,
|
|
323
346
|
): Promise<PlainValue> {
|
|
324
347
|
const envelope = decodeEnvelope(envelopeBytes);
|
|
325
348
|
const key = keyProvider(envelope.keyId);
|
|
326
349
|
if (key === undefined) {
|
|
327
|
-
throw new DecryptError(
|
|
328
|
-
|
|
329
|
-
|
|
350
|
+
throw new DecryptError('no key for the envelope keyId', {
|
|
351
|
+
table,
|
|
352
|
+
keyId: envelope.keyId,
|
|
353
|
+
});
|
|
330
354
|
}
|
|
331
355
|
const cryptoKey = await importAesKey(key);
|
|
332
356
|
let plaintext: Uint8Array;
|