@enbox/dwn-sdk-js 0.0.4 → 0.0.5
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/browser.mjs +135 -0
- package/dist/browser.mjs.map +7 -0
- package/dist/esm/generated/precompiled-validators.js +640 -510
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/auth.js +6 -1
- package/dist/esm/src/core/auth.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +3 -0
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization.js +4 -0
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/dwn.js +14 -0
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +13 -0
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +121 -66
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +1 -1
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +1 -1
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +1 -0
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +2 -0
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write.js +28 -45
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js +9 -1
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/smt/smt-utils.js +1 -1
- package/dist/esm/src/smt/smt-utils.js.map +1 -1
- package/dist/esm/src/types/records-types.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +221 -78
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +6 -7
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +12 -10
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +33 -44
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +26 -21
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/records-tags.spec.js +5 -5
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +120 -2
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +25 -26
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +103 -0
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +124 -10
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +3 -2
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +43 -34
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +4 -4
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +21 -24
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption.spec.js +69 -66
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +1 -0
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +28 -7
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/auth.d.ts +3 -1
- package/dist/types/src/core/auth.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +3 -0
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts +12 -0
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
- package/dist/types/src/handlers/records-subscribe.d.ts +17 -28
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +4 -4
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-delete.d.ts +4 -0
- package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +4 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write.d.ts +23 -53
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/jose/jws/general/verifier.d.ts.map +1 -1
- package/dist/types/src/types/encryption-types.d.ts +9 -8
- package/dist/types/src/types/encryption-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +65 -16
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +7 -26
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/src/utils/encryption.d.ts +157 -28
- package/dist/types/src/utils/encryption.d.ts.map +1 -1
- package/dist/types/src/utils/hd-key.d.ts +2 -3
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +3 -4
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
- package/dist/types/tests/utils/test-data-generator.d.ts +7 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/package.json +8 -19
- package/src/core/auth.ts +12 -1
- package/src/core/dwn-error.ts +3 -0
- package/src/core/protocol-authorization.ts +8 -0
- package/src/dwn.ts +15 -0
- package/src/handlers/protocols-configure.ts +4 -4
- package/src/handlers/records-delete.ts +12 -0
- package/src/handlers/records-subscribe.ts +174 -75
- package/src/handlers/records-write.ts +1 -1
- package/src/index.ts +4 -4
- package/src/interfaces/protocols-configure.ts +5 -5
- package/src/interfaces/records-delete.ts +9 -3
- package/src/interfaces/records-subscribe.ts +6 -1
- package/src/interfaces/records-write.ts +33 -105
- package/src/jose/jws/general/verifier.ts +11 -1
- package/src/smt/smt-utils.ts +1 -1
- package/src/types/encryption-types.ts +9 -8
- package/src/types/protocols-types.ts +72 -18
- package/src/types/records-types.ts +7 -29
- package/src/utils/encryption.ts +346 -88
- package/src/utils/hd-key.ts +9 -10
- package/src/utils/protocols.ts +15 -13
- package/src/utils/records.ts +47 -55
- package/dist/bundles/dwn.js +0 -151
package/src/utils/records.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DerivedPrivateJwk } from './hd-key.js';
|
|
2
|
+
import type { Jwk } from '@enbox/crypto';
|
|
2
3
|
import type { KeyDecrypter } from '../types/encryption-types.js';
|
|
3
4
|
import type { Filter, KeyValues, StartsWithFilter } from '../types/query-types.js';
|
|
4
5
|
import type { GenericMessage, GenericSignaturePayload, MessageSort } from '../types/message-types.js';
|
|
@@ -12,8 +13,8 @@ import { Jws } from './jws.js';
|
|
|
12
13
|
import { Message } from '../core/message.js';
|
|
13
14
|
import { PermissionGrant } from '../protocols/permission-grant.js';
|
|
14
15
|
import { removeUndefinedProperties } from './object.js';
|
|
15
|
-
import { Secp256k1 } from './secp256k1.js';
|
|
16
16
|
import { SortDirection } from '../types/query-types.js';
|
|
17
|
+
import { X25519 } from '@enbox/crypto';
|
|
17
18
|
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
18
19
|
import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
|
|
19
20
|
import { HdKey, KeyDerivationScheme } from './hd-key.js';
|
|
@@ -39,7 +40,7 @@ export class Records {
|
|
|
39
40
|
* Decrypts the encrypted data in a message reply.
|
|
40
41
|
*
|
|
41
42
|
* Overload 1 (callback-based): Accepts a KeyDecrypter that performs
|
|
42
|
-
* HKDF derivation +
|
|
43
|
+
* HKDF derivation + ECDH-ES key agreement + AES Key Unwrap internally.
|
|
43
44
|
*/
|
|
44
45
|
public static async decrypt(
|
|
45
46
|
recordsWrite: RecordsWriteMessage,
|
|
@@ -48,7 +49,7 @@ export class Records {
|
|
|
48
49
|
): Promise<ReadableStream<Uint8Array>>;
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
|
-
* Overload 2 (raw-key
|
|
52
|
+
* Overload 2 (raw-key): Takes DerivedPrivateJwk directly.
|
|
52
53
|
* @param ancestorPrivateKey Any ancestor private key in the key derivation path.
|
|
53
54
|
*/
|
|
54
55
|
public static async decrypt(
|
|
@@ -64,72 +65,64 @@ export class Records {
|
|
|
64
65
|
cipherStream: ReadableStream<Uint8Array>,
|
|
65
66
|
): Promise<ReadableStream<Uint8Array>> {
|
|
66
67
|
const { encryption } = recordsWrite;
|
|
68
|
+
if (encryption === undefined) {
|
|
69
|
+
throw new DwnError(
|
|
70
|
+
DwnErrorCode.RecordsDecryptNoMatchingKeyEncryptedFound,
|
|
71
|
+
'Message does not have an encryption property.'
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
67
75
|
const isCallback = 'decrypt' in keyOrDecrypter;
|
|
68
76
|
|
|
69
|
-
//
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
// Parse the JWE protected header to determine the content encryption algorithm
|
|
78
|
+
const protectedHeader = Encryption.parseProtectedHeader(encryption.protected);
|
|
79
|
+
const enc = protectedHeader.enc;
|
|
80
|
+
|
|
81
|
+
// Find matching recipient entry by rootKeyId and derivationScheme
|
|
82
|
+
const matchingRecipient = encryption.recipients.find(r =>
|
|
83
|
+
r.header.kid === keyOrDecrypter.rootKeyId &&
|
|
84
|
+
r.header.derivationScheme === keyOrDecrypter.derivationScheme
|
|
73
85
|
);
|
|
74
|
-
if (
|
|
86
|
+
if (matchingRecipient === undefined) {
|
|
75
87
|
throw new DwnError(
|
|
76
88
|
DwnErrorCode.RecordsDecryptNoMatchingKeyEncryptedFound,
|
|
77
|
-
`Unable to find a
|
|
89
|
+
`Unable to find a JWE recipient matching key \
|
|
78
90
|
with ID '${keyOrDecrypter.rootKeyId}' and '${keyOrDecrypter.derivationScheme}' derivation scheme.`
|
|
79
91
|
);
|
|
80
92
|
}
|
|
81
93
|
|
|
82
|
-
// Construct the full derivation path
|
|
94
|
+
// Construct the full derivation path
|
|
83
95
|
const fullDerivationPath = Records.constructKeyDerivationPath(
|
|
84
|
-
|
|
96
|
+
matchingRecipient.header.derivationScheme, recordsWrite,
|
|
85
97
|
);
|
|
86
98
|
|
|
87
|
-
let
|
|
99
|
+
let cek: Uint8Array;
|
|
88
100
|
|
|
89
101
|
if (isCallback) {
|
|
90
|
-
// Callback-based: delegate HKDF +
|
|
91
|
-
const encryptedKeyBytes = Encoder.base64UrlToBytes(
|
|
92
|
-
matchingEncryptedKey.encryptedKey,
|
|
93
|
-
);
|
|
94
|
-
const ephemeralPublicKeyBytes = Secp256k1.publicJwkToBytes(
|
|
95
|
-
matchingEncryptedKey.ephemeralPublicKey,
|
|
96
|
-
);
|
|
97
|
-
const iv = Encoder.base64UrlToBytes(
|
|
98
|
-
matchingEncryptedKey.initializationVector,
|
|
99
|
-
);
|
|
100
|
-
const mac = Encoder.base64UrlToBytes(
|
|
101
|
-
matchingEncryptedKey.messageAuthenticationCode,
|
|
102
|
-
);
|
|
102
|
+
// Callback-based: delegate HKDF + ECDH-ES + AES Key Unwrap to the KeyDecrypter
|
|
103
|
+
const encryptedKeyBytes = Encoder.base64UrlToBytes(matchingRecipient.encrypted_key);
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
ephemeralPublicKey
|
|
107
|
-
initializationVector : iv,
|
|
108
|
-
messageAuthenticationCode : mac,
|
|
105
|
+
cek = await keyOrDecrypter.decrypt(fullDerivationPath, {
|
|
106
|
+
encryptedKey : encryptedKeyBytes,
|
|
107
|
+
ephemeralPublicKey : matchingRecipient.header.epk,
|
|
109
108
|
});
|
|
110
109
|
} else {
|
|
111
|
-
// Raw-key path
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
ephemeralPublicKey,
|
|
122
|
-
initializationVector : keyEncryptionInitializationVector,
|
|
123
|
-
messageAuthenticationCode,
|
|
124
|
-
privateKey : leafPrivateKey
|
|
125
|
-
});
|
|
110
|
+
// Raw-key path: derive the leaf private key, then ECDH-ES + AES Key Unwrap
|
|
111
|
+
const leafPrivateKeyBytes = await Records.derivePrivateKey(keyOrDecrypter, fullDerivationPath);
|
|
112
|
+
const leafPrivateKeyJwk = await X25519.bytesToPrivateKey({ privateKeyBytes: leafPrivateKeyBytes });
|
|
113
|
+
const wrappedKeyBytes = Encoder.base64UrlToBytes(matchingRecipient.encrypted_key);
|
|
114
|
+
|
|
115
|
+
cek = await Encryption.ecdhEsUnwrapKey(
|
|
116
|
+
leafPrivateKeyJwk,
|
|
117
|
+
matchingRecipient.header.epk as Jwk,
|
|
118
|
+
wrappedKeyBytes,
|
|
119
|
+
);
|
|
126
120
|
}
|
|
127
121
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const
|
|
132
|
-
const plaintextStream = await Encryption.aes256CtrDecrypt(dataEncryptionKey, dataEncryptionInitializationVector, cipherStream);
|
|
122
|
+
// AEAD decrypt data using the CEK
|
|
123
|
+
const iv = Encoder.base64UrlToBytes(encryption.iv);
|
|
124
|
+
const tag = Encoder.base64UrlToBytes(encryption.tag);
|
|
125
|
+
const plaintextStream = await Encryption.aeadDecryptStream(enc, cek, iv, cipherStream, tag);
|
|
133
126
|
|
|
134
127
|
return plaintextStream;
|
|
135
128
|
}
|
|
@@ -256,15 +249,14 @@ export class Records {
|
|
|
256
249
|
|
|
257
250
|
/**
|
|
258
251
|
* Derives a descendant private key given an ancestor private key and the full absolute derivation path.
|
|
259
|
-
*
|
|
260
|
-
* so we will only derive SECP256K1 key without additional conditional checks
|
|
252
|
+
* Uses X25519 keys for encryption key derivation.
|
|
261
253
|
*/
|
|
262
254
|
public static async derivePrivateKey(ancestorPrivateKey: DerivedPrivateJwk, fullDescendantDerivationPath: string[]): Promise<Uint8Array> {
|
|
263
255
|
const crv = 'crv' in ancestorPrivateKey.derivedPrivateKey ? ancestorPrivateKey.derivedPrivateKey.crv : undefined;
|
|
264
|
-
if (crv !== '
|
|
256
|
+
if (crv !== 'X25519') {
|
|
265
257
|
throw new DwnError(
|
|
266
258
|
DwnErrorCode.RecordsDerivePrivateKeyUnSupportedCurve,
|
|
267
|
-
`Curve ${crv} is not supported.`
|
|
259
|
+
`Curve '${crv}' is not supported for encryption key derivation. Expected 'X25519'.`
|
|
268
260
|
);
|
|
269
261
|
}
|
|
270
262
|
|
|
@@ -273,7 +265,7 @@ export class Records {
|
|
|
273
265
|
Records.validateAncestorKeyAndDescentKeyDerivationPathsMatch(ancestorPrivateKeyDerivationPath, fullDescendantDerivationPath);
|
|
274
266
|
|
|
275
267
|
const subDerivationPath = fullDescendantDerivationPath.slice(ancestorPrivateKeyDerivationPath.length);
|
|
276
|
-
const ancestorPrivateKeyBytes =
|
|
268
|
+
const ancestorPrivateKeyBytes = await X25519.privateKeyToBytes({ privateKey: ancestorPrivateKey.derivedPrivateKey });
|
|
277
269
|
const leafPrivateKey = await HdKey.derivePrivateKeyBytes(ancestorPrivateKeyBytes, subDerivationPath);
|
|
278
270
|
|
|
279
271
|
return leafPrivateKey;
|