@opentdf/sdk 0.9.0-beta.92 → 0.9.0-beta.93
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/cjs/src/access/access-fetch.js +1 -2
- package/dist/cjs/src/access/access-rpc.js +1 -3
- package/dist/cjs/src/access.js +1 -14
- package/dist/cjs/src/auth/auth.js +13 -10
- package/dist/cjs/src/auth/dpop.js +121 -0
- package/dist/cjs/src/auth/oidc-clientcredentials-provider.js +37 -3
- package/dist/cjs/src/auth/oidc-externaljwt-provider.js +37 -3
- package/dist/cjs/src/auth/oidc-refreshtoken-provider.js +37 -3
- package/dist/cjs/src/auth/oidc.js +10 -8
- package/dist/cjs/src/auth/providers.js +35 -12
- package/dist/cjs/src/crypto/index.js +16 -2
- package/dist/cjs/src/crypto/pemPublicToCrypto.js +17 -11
- package/dist/cjs/src/opentdf.js +40 -10
- package/dist/cjs/tdf3/index.js +4 -2
- package/dist/cjs/tdf3/src/assertions.js +71 -31
- package/dist/cjs/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
- package/dist/cjs/tdf3/src/ciphers/symmetric-cipher-base.js +4 -2
- package/dist/cjs/tdf3/src/client/index.js +23 -33
- package/dist/cjs/tdf3/src/crypto/crypto-utils.js +12 -5
- package/dist/cjs/tdf3/src/crypto/declarations.js +1 -1
- package/dist/cjs/tdf3/src/crypto/index.js +849 -88
- package/dist/cjs/tdf3/src/crypto/jose/jwt-claims-set.js +11 -0
- package/dist/cjs/tdf3/src/crypto/jose/validate-crit.js +8 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/buffer_utils.js +41 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/epoch.js +6 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/is_object.js +21 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.js +112 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/secs.js +60 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/validate_crit.js +38 -0
- package/dist/cjs/tdf3/src/crypto/jose/vendor/util/errors.js +135 -0
- package/dist/cjs/tdf3/src/crypto/jwt.js +183 -0
- package/dist/cjs/tdf3/src/crypto/salt.js +14 -8
- package/dist/cjs/tdf3/src/models/encryption-information.js +17 -20
- package/dist/cjs/tdf3/src/models/key-access.js +43 -63
- package/dist/cjs/tdf3/src/tdf.js +75 -75
- package/dist/cjs/tdf3/src/utils/index.js +5 -39
- package/dist/types/src/access/access-fetch.d.ts.map +1 -1
- package/dist/types/src/access/access-rpc.d.ts.map +1 -1
- package/dist/types/src/access.d.ts +0 -5
- package/dist/types/src/access.d.ts.map +1 -1
- package/dist/types/src/auth/auth.d.ts +9 -6
- package/dist/types/src/auth/auth.d.ts.map +1 -1
- package/dist/types/src/auth/dpop.d.ts +60 -0
- package/dist/types/src/auth/dpop.d.ts.map +1 -0
- package/dist/types/src/auth/oidc-clientcredentials-provider.d.ts +3 -2
- package/dist/types/src/auth/oidc-clientcredentials-provider.d.ts.map +1 -1
- package/dist/types/src/auth/oidc-externaljwt-provider.d.ts +3 -2
- package/dist/types/src/auth/oidc-externaljwt-provider.d.ts.map +1 -1
- package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts +3 -2
- package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts.map +1 -1
- package/dist/types/src/auth/oidc.d.ts +6 -4
- package/dist/types/src/auth/oidc.d.ts.map +1 -1
- package/dist/types/src/auth/providers.d.ts +5 -4
- package/dist/types/src/auth/providers.d.ts.map +1 -1
- package/dist/types/src/crypto/index.d.ts +2 -1
- package/dist/types/src/crypto/index.d.ts.map +1 -1
- package/dist/types/src/crypto/pemPublicToCrypto.d.ts +18 -0
- package/dist/types/src/crypto/pemPublicToCrypto.d.ts.map +1 -1
- package/dist/types/src/opentdf.d.ts +13 -4
- package/dist/types/src/opentdf.d.ts.map +1 -1
- package/dist/types/tdf3/index.d.ts +3 -3
- package/dist/types/tdf3/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/assertions.d.ts +23 -8
- package/dist/types/tdf3/src/assertions.d.ts.map +1 -1
- package/dist/types/tdf3/src/ciphers/aes-gcm-cipher.d.ts +3 -3
- package/dist/types/tdf3/src/ciphers/aes-gcm-cipher.d.ts.map +1 -1
- package/dist/types/tdf3/src/ciphers/symmetric-cipher-base.d.ts +4 -4
- package/dist/types/tdf3/src/ciphers/symmetric-cipher-base.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/builders.d.ts +2 -2
- package/dist/types/tdf3/src/client/builders.d.ts.map +1 -1
- package/dist/types/tdf3/src/client/index.d.ts +6 -5
- package/dist/types/tdf3/src/client/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/crypto/crypto-utils.d.ts +14 -4
- package/dist/types/tdf3/src/crypto/crypto-utils.d.ts.map +1 -1
- package/dist/types/tdf3/src/crypto/declarations.d.ts +283 -18
- package/dist/types/tdf3/src/crypto/declarations.d.ts.map +1 -1
- package/dist/types/tdf3/src/crypto/index.d.ts +105 -28
- package/dist/types/tdf3/src/crypto/index.d.ts.map +1 -1
- package/dist/types/tdf3/src/crypto/jose/jwt-claims-set.d.ts +3 -0
- package/dist/types/tdf3/src/crypto/jose/jwt-claims-set.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/validate-crit.d.ts +5 -0
- package/dist/types/tdf3/src/crypto/jose/validate-crit.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/buffer_utils.d.ts +6 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/buffer_utils.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/epoch.d.ts +3 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/epoch.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/is_object.d.ts +3 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/is_object.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.d.ts +3 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/secs.d.ts +3 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/secs.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/validate_crit.d.ts +3 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/lib/validate_crit.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/util/errors.d.ts +76 -0
- package/dist/types/tdf3/src/crypto/jose/vendor/util/errors.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/jwt.d.ts +76 -0
- package/dist/types/tdf3/src/crypto/jwt.d.ts.map +1 -0
- package/dist/types/tdf3/src/crypto/salt.d.ts +6 -1
- package/dist/types/tdf3/src/crypto/salt.d.ts.map +1 -1
- package/dist/types/tdf3/src/models/encryption-information.d.ts +4 -4
- package/dist/types/tdf3/src/models/encryption-information.d.ts.map +1 -1
- package/dist/types/tdf3/src/models/key-access.d.ts +8 -5
- package/dist/types/tdf3/src/models/key-access.d.ts.map +1 -1
- package/dist/types/tdf3/src/tdf.d.ts +8 -8
- package/dist/types/tdf3/src/tdf.d.ts.map +1 -1
- package/dist/types/tdf3/src/utils/index.d.ts +4 -3
- package/dist/types/tdf3/src/utils/index.d.ts.map +1 -1
- package/dist/web/src/access/access-fetch.js +3 -4
- package/dist/web/src/access/access-rpc.js +3 -5
- package/dist/web/src/access.js +1 -13
- package/dist/web/src/auth/auth.js +13 -10
- package/dist/web/src/auth/dpop.js +118 -0
- package/dist/web/src/auth/oidc-clientcredentials-provider.js +4 -3
- package/dist/web/src/auth/oidc-externaljwt-provider.js +4 -3
- package/dist/web/src/auth/oidc-refreshtoken-provider.js +4 -3
- package/dist/web/src/auth/oidc.js +11 -9
- package/dist/web/src/auth/providers.js +13 -12
- package/dist/web/src/crypto/index.js +4 -2
- package/dist/web/src/crypto/pemPublicToCrypto.js +11 -9
- package/dist/web/src/opentdf.js +7 -10
- package/dist/web/tdf3/index.js +3 -2
- package/dist/web/tdf3/src/assertions.js +71 -31
- package/dist/web/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
- package/dist/web/tdf3/src/ciphers/symmetric-cipher-base.js +4 -2
- package/dist/web/tdf3/src/client/index.js +25 -35
- package/dist/web/tdf3/src/crypto/crypto-utils.js +12 -5
- package/dist/web/tdf3/src/crypto/declarations.js +1 -1
- package/dist/web/tdf3/src/crypto/index.js +830 -84
- package/dist/web/tdf3/src/crypto/jose/jwt-claims-set.js +5 -0
- package/dist/web/tdf3/src/crypto/jose/validate-crit.js +3 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/lib/buffer_utils.js +35 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/lib/epoch.js +4 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/lib/is_object.js +19 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.js +107 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/lib/secs.js +58 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/lib/validate_crit.js +36 -0
- package/dist/web/tdf3/src/crypto/jose/vendor/util/errors.js +117 -0
- package/dist/web/tdf3/src/crypto/jwt.js +174 -0
- package/dist/web/tdf3/src/crypto/salt.js +13 -7
- package/dist/web/tdf3/src/models/encryption-information.js +11 -14
- package/dist/web/tdf3/src/models/key-access.js +44 -31
- package/dist/web/tdf3/src/tdf.js +71 -71
- package/dist/web/tdf3/src/utils/index.js +5 -6
- package/package.json +11 -4
- package/src/access/access-fetch.ts +2 -8
- package/src/access/access-rpc.ts +0 -7
- package/src/access.ts +0 -17
- package/src/auth/auth.ts +21 -12
- package/src/auth/dpop.ts +222 -0
- package/src/auth/oidc-clientcredentials-provider.ts +23 -15
- package/src/auth/oidc-externaljwt-provider.ts +23 -15
- package/src/auth/oidc-refreshtoken-provider.ts +23 -15
- package/src/auth/oidc.ts +21 -10
- package/src/auth/providers.ts +46 -29
- package/src/crypto/index.ts +21 -1
- package/src/crypto/pemPublicToCrypto.ts +11 -9
- package/src/opentdf.ts +19 -14
- package/tdf3/index.ts +32 -5
- package/tdf3/src/assertions.ts +99 -30
- package/tdf3/src/ciphers/aes-gcm-cipher.ts +7 -2
- package/tdf3/src/ciphers/symmetric-cipher-base.ts +7 -4
- package/tdf3/src/client/builders.ts +2 -2
- package/tdf3/src/client/index.ts +60 -59
- package/tdf3/src/crypto/crypto-utils.ts +15 -8
- package/tdf3/src/crypto/declarations.ts +338 -22
- package/tdf3/src/crypto/index.ts +1021 -118
- package/tdf3/src/crypto/jose/jwt-claims-set.ts +10 -0
- package/tdf3/src/crypto/jose/validate-crit.ts +9 -0
- package/tdf3/src/crypto/jose/vendor/lib/buffer_utils.ts +34 -0
- package/tdf3/src/crypto/jose/vendor/lib/epoch.ts +3 -0
- package/tdf3/src/crypto/jose/vendor/lib/is_object.ts +18 -0
- package/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.ts +106 -0
- package/tdf3/src/crypto/jose/vendor/lib/secs.ts +57 -0
- package/tdf3/src/crypto/jose/vendor/lib/validate_crit.ts +35 -0
- package/tdf3/src/crypto/jose/vendor/util/errors.ts +101 -0
- package/tdf3/src/crypto/jwt.ts +256 -0
- package/tdf3/src/crypto/salt.ts +16 -8
- package/tdf3/src/models/encryption-information.ts +14 -21
- package/tdf3/src/models/key-access.ts +57 -41
- package/tdf3/src/tdf.ts +110 -93
- package/tdf3/src/utils/index.ts +5 -6
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { keySplit } from '../utils/index.js';
|
|
2
1
|
import { base64, hex } from '../../../src/encodings/index.js';
|
|
3
2
|
import { Binary } from '../binary.js';
|
|
4
3
|
import { ConfigurationError } from '../../../src/errors.js';
|
|
@@ -10,26 +9,24 @@ export class SplitKey {
|
|
|
10
9
|
}
|
|
11
10
|
async generateKey() {
|
|
12
11
|
const unwrappedKey = await this.cipher.generateKey();
|
|
13
|
-
const unwrappedKeyBinary = Binary.fromString(hex.decode(unwrappedKey));
|
|
14
12
|
const unwrappedKeyIvBinary = await this.generateIvBinary();
|
|
15
|
-
return {
|
|
13
|
+
return { unwrappedKey, unwrappedKeyIvBinary };
|
|
16
14
|
}
|
|
17
|
-
async encrypt(contentBinary,
|
|
15
|
+
async encrypt(contentBinary, key, ivBinaryOptional) {
|
|
18
16
|
const ivBinary = ivBinaryOptional || (await this.generateIvBinary());
|
|
19
|
-
return this.cipher.encrypt(contentBinary,
|
|
17
|
+
return this.cipher.encrypt(contentBinary, key, ivBinary);
|
|
20
18
|
}
|
|
21
|
-
async decrypt(content,
|
|
22
|
-
return this.cipher.decrypt(content,
|
|
19
|
+
async decrypt(content, key) {
|
|
20
|
+
return this.cipher.decrypt(content, key);
|
|
23
21
|
}
|
|
24
22
|
async getKeyAccessObjects(policy, keyInfo) {
|
|
25
23
|
const splitIds = [...new Set(this.keyAccess.map(({ sid }) => sid))].sort((a = '', b = '') => a.localeCompare(b));
|
|
26
|
-
const
|
|
27
|
-
const splitsByName = Object.fromEntries(splitIds.map((sid, index) => [sid,
|
|
24
|
+
const unwrappedKeySplits = await this.cryptoService.splitSymmetricKey(keyInfo.unwrappedKey, splitIds.length);
|
|
25
|
+
const splitsByName = Object.fromEntries(splitIds.map((sid, index) => [sid, unwrappedKeySplits[index]]));
|
|
28
26
|
const keyAccessObjects = [];
|
|
29
27
|
for (const item of this.keyAccess) {
|
|
30
28
|
// use the key split to encrypt metadata for each key access object
|
|
31
|
-
const
|
|
32
|
-
const unwrappedKeySplitBinary = Binary.fromArrayBuffer(unwrappedKeySplitBuffer.buffer);
|
|
29
|
+
const unwrappedKeySplit = splitsByName[item.sid || ''];
|
|
33
30
|
const metadata = item.metadata || '';
|
|
34
31
|
const metadataStr = (typeof metadata === 'object'
|
|
35
32
|
? JSON.stringify(metadata)
|
|
@@ -39,13 +36,13 @@ export class SplitKey {
|
|
|
39
36
|
throw new ConfigurationError("KAO generation failure: metadata isn't a string or object");
|
|
40
37
|
});
|
|
41
38
|
const metadataBinary = Binary.fromArrayBuffer(new TextEncoder().encode(metadataStr));
|
|
42
|
-
const encryptedMetadataResult = await this.encrypt(metadataBinary,
|
|
39
|
+
const encryptedMetadataResult = await this.encrypt(metadataBinary, unwrappedKeySplit, keyInfo.unwrappedKeyIvBinary);
|
|
43
40
|
const encryptedMetadataOb = {
|
|
44
41
|
ciphertext: base64.encode(encryptedMetadataResult.payload.asString()),
|
|
45
42
|
iv: base64.encode(keyInfo.unwrappedKeyIvBinary.asString()),
|
|
46
43
|
};
|
|
47
44
|
const encryptedMetadataStr = JSON.stringify(encryptedMetadataOb);
|
|
48
|
-
const keyAccessObject = await item.write(policy,
|
|
45
|
+
const keyAccessObject = await item.write(policy, unwrappedKeySplit, encryptedMetadataStr);
|
|
49
46
|
keyAccessObjects.push(keyAccessObject);
|
|
50
47
|
}
|
|
51
48
|
return keyAccessObjects;
|
|
@@ -83,4 +80,4 @@ export class SplitKey {
|
|
|
83
80
|
};
|
|
84
81
|
}
|
|
85
82
|
}
|
|
86
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdGlvbi1pbmZvcm1hdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RkZjMvc3JjL21vZGVscy9lbmNyeXB0aW9uLWluZm9ybWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQVd0QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQXNDNUQsTUFBTSxPQUFPLFFBQVE7SUFJbkIsWUFBNEIsTUFBdUI7UUFBdkIsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7UUFDakQsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDO1FBQzFDLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVztRQUNmLE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyRCxNQUFNLG9CQUFvQixHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDM0QsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxDQUFDO0lBQ2hELENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTyxDQUNYLGFBQXFCLEVBQ3JCLEdBQWlCLEVBQ2pCLGdCQUF5QjtRQUV6QixNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQztRQUNyRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBbUIsRUFBRSxH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
|
|
@@ -1,42 +1,50 @@
|
|
|
1
1
|
import { base64, hex } from '../../../src/encodings/index.js';
|
|
2
|
-
import { generateRandomNumber } from '../../../src/crypto/generateRandomNumber.js';
|
|
3
|
-
import { keyAgreement } from '../../../src/crypto/keyAgreement.js';
|
|
4
|
-
import { pemPublicToCrypto } from '../../../src/crypto/pemPublicToCrypto.js';
|
|
5
|
-
import { cryptoPublicToPem } from '../../../src/utils.js';
|
|
6
2
|
import { Binary } from '../binary.js';
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
3
|
+
import { getZtdfSalt } from '../crypto/salt.js';
|
|
4
|
+
import { Algorithms } from '../ciphers/index.js';
|
|
9
5
|
export const schemaVersion = '1.0';
|
|
10
6
|
export class ECWrapped {
|
|
11
|
-
constructor(url, kid, publicKey, metadata, sid) {
|
|
7
|
+
constructor(url, kid, publicKey, metadata, cryptoService, sid) {
|
|
12
8
|
this.url = url;
|
|
13
9
|
this.kid = kid;
|
|
14
10
|
this.publicKey = publicKey;
|
|
15
11
|
this.metadata = metadata;
|
|
12
|
+
this.cryptoService = cryptoService;
|
|
16
13
|
this.sid = sid;
|
|
17
14
|
this.type = 'ec-wrapped';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
namedCurve: 'P-256',
|
|
21
|
-
}, false, ['deriveBits', 'deriveKey']);
|
|
15
|
+
// Generate EC key pair using CryptoService - returns opaque keys
|
|
16
|
+
this.ephemeralKeyPair = this.cryptoService.generateECKeyPair('P-256');
|
|
22
17
|
}
|
|
23
18
|
async write(policy, dek, encryptedMetadataStr) {
|
|
24
19
|
const policyStr = JSON.stringify(policy);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const kek = await keyAgreement(ek.privateKey, clientPublicKey, {
|
|
30
|
-
hkdfSalt: await ztdfSalt,
|
|
31
|
-
hkdfHash: 'SHA-256',
|
|
20
|
+
const ek = await this.ephemeralKeyPair;
|
|
21
|
+
// Import KAS public key from PEM
|
|
22
|
+
const kasPublicKey = await this.cryptoService.importPublicKey(this.publicKey, {
|
|
23
|
+
usage: 'derive',
|
|
32
24
|
});
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
25
|
+
// Derive encryption key using ECDH + HKDF via CryptoService
|
|
26
|
+
const derivedKey = await this.cryptoService.deriveKeyFromECDH(ek.privateKey, kasPublicKey, {
|
|
27
|
+
hash: 'SHA-256',
|
|
28
|
+
salt: await getZtdfSalt(this.cryptoService),
|
|
29
|
+
});
|
|
30
|
+
// Generate random IV
|
|
31
|
+
const iv = await this.cryptoService.randomBytes(12);
|
|
32
|
+
// Encrypt DEK using derived key with AES-GCM
|
|
33
|
+
// Payload is SymmetricKey (the DEK), key is SymmetricKey (derived from ECDH)
|
|
34
|
+
const encryptResult = await this.cryptoService.encrypt(dek, derivedKey, Binary.fromArrayBuffer(iv.buffer), Algorithms.AES_256_GCM);
|
|
35
|
+
// Combine IV, ciphertext, and authTag to form the wrapped key.
|
|
36
|
+
const ciphertext = new Uint8Array(encryptResult.payload.asArrayBuffer());
|
|
37
|
+
const authTag = encryptResult.authTag
|
|
38
|
+
? new Uint8Array(encryptResult.authTag.asArrayBuffer())
|
|
39
|
+
: new Uint8Array(0);
|
|
40
|
+
const entityWrappedKey = new Uint8Array(iv.length + ciphertext.length + authTag.length);
|
|
36
41
|
entityWrappedKey.set(iv);
|
|
37
|
-
entityWrappedKey.set(
|
|
38
|
-
|
|
39
|
-
const
|
|
42
|
+
entityWrappedKey.set(ciphertext, iv.length);
|
|
43
|
+
entityWrappedKey.set(authTag, iv.length + ciphertext.length);
|
|
44
|
+
const policyBinding = hex.encodeArrayBuffer((await this.cryptoService.hmac(new TextEncoder().encode(base64.encode(policyStr)), dek))
|
|
45
|
+
.buffer);
|
|
46
|
+
// Export ephemeral public key to PEM for manifest
|
|
47
|
+
const ephemeralPublicKeyPem = await this.cryptoService.exportPublicKeyPem(ek.publicKey);
|
|
40
48
|
const kao = {
|
|
41
49
|
type: 'ec-wrapped',
|
|
42
50
|
url: this.url,
|
|
@@ -48,7 +56,7 @@ export class ECWrapped {
|
|
|
48
56
|
hash: base64.encode(policyBinding),
|
|
49
57
|
},
|
|
50
58
|
schemaVersion,
|
|
51
|
-
ephemeralPublicKey:
|
|
59
|
+
ephemeralPublicKey: ephemeralPublicKeyPem,
|
|
52
60
|
};
|
|
53
61
|
if (this.kid) {
|
|
54
62
|
kao.kid = this.kid;
|
|
@@ -61,19 +69,24 @@ export class ECWrapped {
|
|
|
61
69
|
}
|
|
62
70
|
}
|
|
63
71
|
export class Wrapped {
|
|
64
|
-
constructor(url, kid, publicKey, metadata, sid) {
|
|
72
|
+
constructor(url, kid, publicKey, metadata, cryptoService, sid) {
|
|
65
73
|
this.url = url;
|
|
66
74
|
this.kid = kid;
|
|
67
75
|
this.publicKey = publicKey;
|
|
68
76
|
this.metadata = metadata;
|
|
77
|
+
this.cryptoService = cryptoService;
|
|
69
78
|
this.sid = sid;
|
|
70
79
|
this.type = 'wrapped';
|
|
71
80
|
}
|
|
72
|
-
async write(policy,
|
|
81
|
+
async write(policy, key, encryptedMetadataStr) {
|
|
73
82
|
const policyStr = JSON.stringify(policy);
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
83
|
+
// Import KAS public key from PEM
|
|
84
|
+
const kasPublicKey = await this.cryptoService.importPublicKey(this.publicKey, {
|
|
85
|
+
usage: 'encrypt',
|
|
86
|
+
});
|
|
87
|
+
const wrappedKeyBinary = await this.cryptoService.encryptWithPublicKey(key, kasPublicKey);
|
|
88
|
+
const policyBinding = hex.encodeArrayBuffer((await this.cryptoService.hmac(new TextEncoder().encode(base64.encode(policyStr)), key))
|
|
89
|
+
.buffer);
|
|
77
90
|
this.keyAccessObject = {
|
|
78
91
|
type: 'wrapped',
|
|
79
92
|
url: this.url,
|
|
@@ -95,4 +108,4 @@ export class Wrapped {
|
|
|
95
108
|
return this.keyAccessObject;
|
|
96
109
|
}
|
|
97
110
|
}
|
|
98
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
111
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5LWFjY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3RkZjMvc3JjL21vZGVscy9rZXktYWNjZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBS2pELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUM7QUFFbkMsTUFBTSxPQUFPLFNBQVM7SUFLcEIsWUFDa0IsR0FBVyxFQUNYLEdBQXVCLEVBQ3ZCLFNBQWlCLEVBQ2pCLFFBQWlCLEVBQ2pCLGFBQTRCLEVBQzVCLEdBQVk7UUFMWixRQUFHLEdBQUgsR0FBRyxDQUFRO1FBQ1gsUUFBRyxHQUFILEdBQUcsQ0FBb0I7UUFDdkIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFTO1FBQ2pCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLFFBQUcsR0FBSCxHQUFHLENBQVM7UUFWckIsU0FBSSxHQUFHLFlBQVksQ0FBQztRQVkzQixpRUFBaUU7UUFDakUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFLLENBQ1QsTUFBYyxFQUNkLEdBQWlCLEVBQ2pCLG9CQUE0QjtRQUU1QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRXZDLGlDQUFp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
|