mindoodb 0.0.1
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 +263 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts +5 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts.map +1 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js +17 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js.map +1 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +111 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +237 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts +78 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -0
- package/dist/appendonlystores/network/HttpTransport.js +356 -0
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +131 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +248 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -0
- package/dist/appendonlystores/network/index.d.ts +8 -0
- package/dist/appendonlystores/network/index.d.ts.map +1 -0
- package/dist/appendonlystores/network/index.js +21 -0
- package/dist/appendonlystores/network/index.js.map +1 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.d.ts +14 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.d.ts.map +1 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.js +30 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.js.map +1 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +26 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/core/BaseMindooDB.d.ts +182 -0
- package/dist/core/BaseMindooDB.d.ts.map +1 -0
- package/dist/core/BaseMindooDB.js +1701 -0
- package/dist/core/BaseMindooDB.js.map +1 -0
- package/dist/core/BaseMindooTenant.d.ts +155 -0
- package/dist/core/BaseMindooTenant.d.ts.map +1 -0
- package/dist/core/BaseMindooTenant.js +673 -0
- package/dist/core/BaseMindooTenant.js.map +1 -0
- package/dist/core/BaseMindooTenantDirectory.d.ts +99 -0
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -0
- package/dist/core/BaseMindooTenantDirectory.js +776 -0
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -0
- package/dist/core/BaseMindooTenantFactory.d.ts +91 -0
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -0
- package/dist/core/BaseMindooTenantFactory.js +297 -0
- package/dist/core/BaseMindooTenantFactory.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +111 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +293 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts +78 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -0
- package/dist/core/appendonlystores/network/AuthenticationService.js +297 -0
- package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +174 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.js +3 -0
- package/dist/core/appendonlystores/network/NetworkTransport.js.map +1 -0
- package/dist/core/appendonlystores/network/types.d.ts +135 -0
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -0
- package/dist/core/appendonlystores/network/types.js +35 -0
- package/dist/core/appendonlystores/network/types.js.map +1 -0
- package/dist/core/appendonlystores/types.d.ts +157 -0
- package/dist/core/appendonlystores/types.d.ts.map +1 -0
- package/dist/core/appendonlystores/types.js +3 -0
- package/dist/core/appendonlystores/types.js.map +1 -0
- package/dist/core/crypto/CryptoAdapter.d.ts +19 -0
- package/dist/core/crypto/CryptoAdapter.d.ts.map +1 -0
- package/dist/core/crypto/CryptoAdapter.js +3 -0
- package/dist/core/crypto/CryptoAdapter.js.map +1 -0
- package/dist/core/crypto/MindooDocSigner.d.ts +106 -0
- package/dist/core/crypto/MindooDocSigner.d.ts.map +1 -0
- package/dist/core/crypto/MindooDocSigner.js +192 -0
- package/dist/core/crypto/MindooDocSigner.js.map +1 -0
- package/dist/core/crypto/RSAEncryption.d.ts +62 -0
- package/dist/core/crypto/RSAEncryption.d.ts.map +1 -0
- package/dist/core/crypto/RSAEncryption.js +167 -0
- package/dist/core/crypto/RSAEncryption.js.map +1 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +53 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.d.ts +33 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.js +27 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.js.map +1 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts +31 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.js +3 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.js.map +1 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +52 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +106 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts +44 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.js +107 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.js.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts +28 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js +133 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualView.d.ts +109 -0
- package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualView.js +504 -0
- package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts +59 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.js +70 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.d.ts +49 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.js +69 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +121 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +365 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts +131 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js +236 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.d.ts +330 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.js +1010 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.js.map +1 -0
- package/dist/core/indexing/virtualviews/index.d.ts +53 -0
- package/dist/core/indexing/virtualviews/index.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/index.js +89 -0
- package/dist/core/indexing/virtualviews/index.js.map +1 -0
- package/dist/core/indexing/virtualviews/types.d.ts +115 -0
- package/dist/core/indexing/virtualviews/types.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/types.js +175 -0
- package/dist/core/indexing/virtualviews/types.js.map +1 -0
- package/dist/core/keys/KeyBag.d.ts +122 -0
- package/dist/core/keys/KeyBag.d.ts.map +1 -0
- package/dist/core/keys/KeyBag.js +401 -0
- package/dist/core/keys/KeyBag.js.map +1 -0
- package/dist/core/types.d.ts +1004 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/userid/index.d.ts +53 -0
- package/dist/core/userid/index.d.ts.map +1 -0
- package/dist/core/userid/index.js +3 -0
- package/dist/core/userid/index.js.map +1 -0
- package/dist/core/utils/idGeneration.d.ts +109 -0
- package/dist/core/utils/idGeneration.d.ts.map +1 -0
- package/dist/core/utils/idGeneration.js +182 -0
- package/dist/core/utils/idGeneration.js.map +1 -0
- package/dist/core/utils/index.d.ts +5 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/index.js +19 -0
- package/dist/core/utils/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/node/crypto/NodeCryptoAdapter.d.ts +16 -0
- package/dist/node/crypto/NodeCryptoAdapter.d.ts.map +1 -0
- package/dist/node/crypto/NodeCryptoAdapter.js +53 -0
- package/dist/node/crypto/NodeCryptoAdapter.js.map +1 -0
- package/dist/node/index.d.ts +3 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +26 -0
- package/dist/node/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeyBag = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The KeyBag is used to store encryption keys that the current user has access to
|
|
6
|
+
* in order to decrypt document changes stored in the AppendOnlyStore.
|
|
7
|
+
* Supports key rotation by storing multiple versions per keyId (newest first).
|
|
8
|
+
*/
|
|
9
|
+
class KeyBag {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new KeyBag instance.
|
|
12
|
+
*
|
|
13
|
+
* @param userEncryptionKey The encrypted user encryption key
|
|
14
|
+
* @param userEncryptionKeyPassword The password to decrypt the user encryption key
|
|
15
|
+
* @param cryptoAdapter The crypto adapter to use for encryption and decryption
|
|
16
|
+
*/
|
|
17
|
+
constructor(userEncryptionKey, userEncryptionKeyPassword, cryptoAdapter) {
|
|
18
|
+
this.keys = new Map();
|
|
19
|
+
this.userEncryptionKey = userEncryptionKey;
|
|
20
|
+
this.userEncryptionKeyPassword = userEncryptionKeyPassword;
|
|
21
|
+
this.cryptoAdapter = cryptoAdapter;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reads a key from the key bag.
|
|
25
|
+
* Returns the newest key (based on createdAt) or the first key if no timestamps are available.
|
|
26
|
+
*
|
|
27
|
+
* @param keyId The ID of the key to read
|
|
28
|
+
* @return The exported key, or null if not found
|
|
29
|
+
*/
|
|
30
|
+
async get(keyId) {
|
|
31
|
+
const keyEntries = this.keys.get(keyId);
|
|
32
|
+
if (!keyEntries || keyEntries.length === 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
// Sort by createdAt (newest first), then return the first one
|
|
36
|
+
const sorted = [...keyEntries].sort((a, b) => {
|
|
37
|
+
const aTime = a.createdAt ?? 0;
|
|
38
|
+
const bTime = b.createdAt ?? 0;
|
|
39
|
+
return bTime - aTime; // Descending order (newest first)
|
|
40
|
+
});
|
|
41
|
+
return sorted[0].key;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Gets all keys for a given keyId, sorted by createdAt (newest first).
|
|
45
|
+
* Useful for trying multiple keys during decryption (key rotation support).
|
|
46
|
+
*
|
|
47
|
+
* @param keyId The ID of the keys to read
|
|
48
|
+
* @return Array of keys sorted by createdAt (newest first), or empty array if not found
|
|
49
|
+
*/
|
|
50
|
+
async getAllKeys(keyId) {
|
|
51
|
+
const keyEntries = this.keys.get(keyId);
|
|
52
|
+
if (!keyEntries || keyEntries.length === 0) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
// Sort by createdAt (newest first)
|
|
56
|
+
const sorted = [...keyEntries].sort((a, b) => {
|
|
57
|
+
const aTime = a.createdAt ?? 0;
|
|
58
|
+
const bTime = b.createdAt ?? 0;
|
|
59
|
+
return bTime - aTime; // Descending order (newest first)
|
|
60
|
+
});
|
|
61
|
+
return sorted.map(entry => entry.key);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Sets a key in the key bag.
|
|
65
|
+
* Adds the key to the array of keys for this keyId (supports key rotation).
|
|
66
|
+
*
|
|
67
|
+
* @param keyId The ID of the key
|
|
68
|
+
* @param key The key bytes
|
|
69
|
+
* @param createdAt Optional creation timestamp (milliseconds since Unix epoch)
|
|
70
|
+
*/
|
|
71
|
+
async set(keyId, key, createdAt) {
|
|
72
|
+
const keyEntries = this.keys.get(keyId) || [];
|
|
73
|
+
keyEntries.push({ key, createdAt });
|
|
74
|
+
this.keys.set(keyId, keyEntries);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Decrypts an encrypted private key with the given password and imports it into the key bag.
|
|
78
|
+
* Adds the key to the array of keys for this keyId (supports key rotation).
|
|
79
|
+
*
|
|
80
|
+
* @param keyId The ID to store the decrypted key under
|
|
81
|
+
* @param key The encrypted private key to decrypt
|
|
82
|
+
* @param password The password to decrypt the key
|
|
83
|
+
* @param saltString Optional salt string for key derivation. Defaults to "default".
|
|
84
|
+
* Use "default" for keys created by createSymmetricEncryptedPrivateKey.
|
|
85
|
+
* Keys exported via encryptAndExportKey use keyId as salt, so pass keyId explicitly.
|
|
86
|
+
* @return A promise that resolves when the key is decrypted and stored
|
|
87
|
+
*/
|
|
88
|
+
async decryptAndImportKey(keyId, key, password, saltString) {
|
|
89
|
+
const salt = saltString ?? "default";
|
|
90
|
+
const decryptedKeyBytes = await this.decryptPrivateKey(key, password, salt);
|
|
91
|
+
const keyEntries = this.keys.get(keyId) || [];
|
|
92
|
+
keyEntries.push({
|
|
93
|
+
key: new Uint8Array(decryptedKeyBytes),
|
|
94
|
+
createdAt: key.createdAt
|
|
95
|
+
});
|
|
96
|
+
this.keys.set(keyId, keyEntries);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Encrypts a key from the key bag with the given password and exports it as an EncryptedPrivateKey.
|
|
100
|
+
* Returns the newest key (based on createdAt) or the first key if no timestamps are available.
|
|
101
|
+
*
|
|
102
|
+
* @param keyId The ID of the key to encrypt and export
|
|
103
|
+
* @param password The password to encrypt the key with
|
|
104
|
+
* @return A promise that resolves to the encrypted private key, or null if the key is not found
|
|
105
|
+
*/
|
|
106
|
+
async encryptAndExportKey(keyId, password) {
|
|
107
|
+
const key = await this.get(keyId);
|
|
108
|
+
if (!key) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
// Get the createdAt timestamp from the newest key entry
|
|
112
|
+
const keyEntries = this.keys.get(keyId);
|
|
113
|
+
if (!keyEntries || keyEntries.length === 0) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
// Sort by createdAt (newest first) to get the timestamp
|
|
117
|
+
const sorted = [...keyEntries].sort((a, b) => {
|
|
118
|
+
const aTime = a.createdAt ?? 0;
|
|
119
|
+
const bTime = b.createdAt ?? 0;
|
|
120
|
+
return bTime - aTime; // Descending order (newest first)
|
|
121
|
+
});
|
|
122
|
+
const createdAt = sorted[0].createdAt;
|
|
123
|
+
// Encrypt the key using the same pattern as decryptPrivateKey
|
|
124
|
+
const encryptedKey = await this.encryptPrivateKey(key, password, keyId);
|
|
125
|
+
// Include the createdAt timestamp if available
|
|
126
|
+
if (createdAt !== undefined) {
|
|
127
|
+
encryptedKey.createdAt = createdAt;
|
|
128
|
+
}
|
|
129
|
+
return encryptedKey;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Deletes all keys for a given keyId from the key bag.
|
|
133
|
+
*
|
|
134
|
+
* @param keyId The ID of the keys to delete
|
|
135
|
+
* @return A promise that resolves when the keys are deleted
|
|
136
|
+
*/
|
|
137
|
+
async deleteKey(keyId) {
|
|
138
|
+
this.keys.delete(keyId);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Lists all key IDs in the key bag.
|
|
142
|
+
*
|
|
143
|
+
* @return A promise that resolves to an array of key IDs
|
|
144
|
+
*/
|
|
145
|
+
async listKeys() {
|
|
146
|
+
return Array.from(this.keys.keys());
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Save the key bag to a binary data blob, encrypted with the user encryption key.
|
|
150
|
+
*
|
|
151
|
+
* @return A promise that resolves to the encrypted binary data (Uint8Array)
|
|
152
|
+
*/
|
|
153
|
+
async save() {
|
|
154
|
+
console.log(`[KeyBag] Saving key bag with ${this.keys.size} keys`);
|
|
155
|
+
// Serialize the map to JSON and convert to Uint8Array
|
|
156
|
+
// Convert Uint8Array values to base64 strings for JSON serialization
|
|
157
|
+
// Support multiple keys per keyId with createdAt timestamps
|
|
158
|
+
const mapArray = Array.from(this.keys.entries()).map(([keyId, keyEntries]) => [
|
|
159
|
+
keyId,
|
|
160
|
+
keyEntries.map(entry => ({
|
|
161
|
+
key: this.uint8ArrayToBase64(entry.key),
|
|
162
|
+
createdAt: entry.createdAt
|
|
163
|
+
}))
|
|
164
|
+
]);
|
|
165
|
+
const jsonString = JSON.stringify(mapArray);
|
|
166
|
+
const plaintext = new TextEncoder().encode(jsonString);
|
|
167
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
168
|
+
// Bind getRandomValues to maintain 'this' context
|
|
169
|
+
const randomValues = this.cryptoAdapter.getRandomValues.bind(this.cryptoAdapter);
|
|
170
|
+
// Derive an AES-GCM key using PBKDF2 with the user encryption key's salt
|
|
171
|
+
// Use the salt from the user encryption key as part of the key derivation
|
|
172
|
+
const userKeySaltBytes = this.base64ToUint8Array(this.userEncryptionKey.salt);
|
|
173
|
+
// Combine with a fixed string to differentiate from other key derivations
|
|
174
|
+
const saltStringBytes = new TextEncoder().encode("key-bag-encryption");
|
|
175
|
+
const combinedSalt = new Uint8Array(userKeySaltBytes.length + saltStringBytes.length);
|
|
176
|
+
combinedSalt.set(userKeySaltBytes);
|
|
177
|
+
combinedSalt.set(saltStringBytes, userKeySaltBytes.length);
|
|
178
|
+
// Use the user's password as input for PBKDF2
|
|
179
|
+
const passwordInput = new TextEncoder().encode(`${this.userEncryptionKeyPassword}:key-bag-encryption`);
|
|
180
|
+
const passwordKey = await subtle.importKey("raw", passwordInput, "PBKDF2", false, ["deriveKey"]);
|
|
181
|
+
// Derive AES-GCM key using PBKDF2
|
|
182
|
+
const derivedKey = await subtle.deriveKey({
|
|
183
|
+
name: "PBKDF2",
|
|
184
|
+
salt: combinedSalt,
|
|
185
|
+
iterations: 310000, // OWASP-recommended PBKDF2 iterations for PBKDF2-SHA256
|
|
186
|
+
hash: "SHA-256",
|
|
187
|
+
}, passwordKey, {
|
|
188
|
+
name: "AES-GCM",
|
|
189
|
+
length: 256,
|
|
190
|
+
}, false, ["encrypt"]);
|
|
191
|
+
// Generate IV for AES-GCM
|
|
192
|
+
const ivArray = new Uint8Array(12); // 12 bytes for AES-GCM
|
|
193
|
+
randomValues(ivArray);
|
|
194
|
+
const iv = new Uint8Array(ivArray);
|
|
195
|
+
// Encrypt the plaintext
|
|
196
|
+
const encrypted = await subtle.encrypt({
|
|
197
|
+
name: "AES-GCM",
|
|
198
|
+
iv: iv,
|
|
199
|
+
tagLength: 128,
|
|
200
|
+
}, derivedKey, plaintext.buffer);
|
|
201
|
+
// Extract ciphertext and tag
|
|
202
|
+
const encryptedArray = new Uint8Array(encrypted);
|
|
203
|
+
const tagLength = 16; // 128 bits = 16 bytes
|
|
204
|
+
const ciphertext = encryptedArray.slice(0, encryptedArray.length - tagLength);
|
|
205
|
+
const tag = encryptedArray.slice(encryptedArray.length - tagLength);
|
|
206
|
+
// Combine IV + tag + ciphertext
|
|
207
|
+
// Format: IV (12 bytes) + tag (16 bytes) + ciphertext (variable)
|
|
208
|
+
const result = new Uint8Array(12 + 16 + ciphertext.length);
|
|
209
|
+
result.set(iv, 0);
|
|
210
|
+
result.set(tag, 12);
|
|
211
|
+
result.set(ciphertext, 12 + 16);
|
|
212
|
+
console.log(`[KeyBag] Saved key bag (${plaintext.length} -> ${result.length} bytes)`);
|
|
213
|
+
return result;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Load the key bag from a binary data blob, decrypted with the user encryption key.
|
|
217
|
+
*
|
|
218
|
+
* @param encryptedData The encrypted binary data to load (Uint8Array)
|
|
219
|
+
* @return A promise that resolves when the keys are loaded
|
|
220
|
+
*/
|
|
221
|
+
async load(encryptedData) {
|
|
222
|
+
console.log(`[KeyBag] Loading key bag`);
|
|
223
|
+
if (encryptedData.length < 28) {
|
|
224
|
+
throw new Error("Encrypted data too short (missing IV and tag)");
|
|
225
|
+
}
|
|
226
|
+
// Extract IV, tag, and ciphertext
|
|
227
|
+
const iv = encryptedData.slice(0, 12);
|
|
228
|
+
const tag = encryptedData.slice(12, 28);
|
|
229
|
+
const ciphertext = encryptedData.slice(28);
|
|
230
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
231
|
+
// Derive the same AES-GCM key (same process as encryption)
|
|
232
|
+
const userKeySaltBytes = this.base64ToUint8Array(this.userEncryptionKey.salt);
|
|
233
|
+
// Combine with the same fixed string as encryption
|
|
234
|
+
const saltStringBytes = new TextEncoder().encode("key-bag-encryption");
|
|
235
|
+
const combinedSalt = new Uint8Array(userKeySaltBytes.length + saltStringBytes.length);
|
|
236
|
+
combinedSalt.set(userKeySaltBytes);
|
|
237
|
+
combinedSalt.set(saltStringBytes, userKeySaltBytes.length);
|
|
238
|
+
// Use the user's password as input for PBKDF2 (same as encryption)
|
|
239
|
+
const passwordInput = new TextEncoder().encode(`${this.userEncryptionKeyPassword}:key-bag-encryption`);
|
|
240
|
+
const passwordKey = await subtle.importKey("raw", passwordInput, "PBKDF2", false, ["deriveKey"]);
|
|
241
|
+
// Derive AES-GCM key using PBKDF2 (same parameters as encryption)
|
|
242
|
+
const derivedKey = await subtle.deriveKey({
|
|
243
|
+
name: "PBKDF2",
|
|
244
|
+
salt: combinedSalt,
|
|
245
|
+
iterations: 310000, // OWASP-recommended PBKDF2 iterations for PBKDF2-SHA256
|
|
246
|
+
hash: "SHA-256",
|
|
247
|
+
}, passwordKey, {
|
|
248
|
+
name: "AES-GCM",
|
|
249
|
+
length: 256,
|
|
250
|
+
}, false, ["decrypt"]);
|
|
251
|
+
// Combine ciphertext and tag
|
|
252
|
+
const encryptedDataWithTag = new Uint8Array(ciphertext.length + tag.length);
|
|
253
|
+
encryptedDataWithTag.set(ciphertext);
|
|
254
|
+
encryptedDataWithTag.set(tag, ciphertext.length);
|
|
255
|
+
// Decrypt
|
|
256
|
+
const decrypted = await subtle.decrypt({
|
|
257
|
+
name: "AES-GCM",
|
|
258
|
+
iv: iv,
|
|
259
|
+
tagLength: 128,
|
|
260
|
+
}, derivedKey, encryptedDataWithTag.buffer);
|
|
261
|
+
// Deserialize JSON to map
|
|
262
|
+
const decryptedArray = new Uint8Array(decrypted);
|
|
263
|
+
const jsonString = new TextDecoder().decode(decryptedArray);
|
|
264
|
+
const mapArray = JSON.parse(jsonString);
|
|
265
|
+
// Convert base64 strings back to Uint8Array arrays
|
|
266
|
+
// Support multiple keys per keyId with createdAt timestamps
|
|
267
|
+
this.keys = new Map(mapArray.map(([keyId, keyEntries]) => [
|
|
268
|
+
keyId,
|
|
269
|
+
keyEntries.map(entry => ({
|
|
270
|
+
key: this.base64ToUint8Array(entry.key),
|
|
271
|
+
createdAt: entry.createdAt
|
|
272
|
+
}))
|
|
273
|
+
]));
|
|
274
|
+
console.log(`[KeyBag] Loaded key bag (${encryptedData.length} -> ${this.keys.size} keys)`);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Internal method to decrypt a private key using password-based key derivation.
|
|
278
|
+
*
|
|
279
|
+
* @param encryptedKey The encrypted private key
|
|
280
|
+
* @param password The password to decrypt the key
|
|
281
|
+
* @param saltString The salt string for key derivation (e.g., keyId)
|
|
282
|
+
* @returns The decrypted private key as ArrayBuffer
|
|
283
|
+
*/
|
|
284
|
+
async decryptPrivateKey(encryptedKey, password, saltString) {
|
|
285
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
286
|
+
// Decode base64 strings
|
|
287
|
+
const ciphertext = this.base64ToUint8Array(encryptedKey.ciphertext);
|
|
288
|
+
const iv = this.base64ToUint8Array(encryptedKey.iv);
|
|
289
|
+
const tag = this.base64ToUint8Array(encryptedKey.tag);
|
|
290
|
+
const saltBytes = this.base64ToUint8Array(encryptedKey.salt);
|
|
291
|
+
// Derive key from password using PBKDF2
|
|
292
|
+
// Combine the stored salt bytes with the salt string for additional security
|
|
293
|
+
const saltStringBytes = new TextEncoder().encode(saltString);
|
|
294
|
+
const combinedSalt = new Uint8Array(saltBytes.length + saltStringBytes.length);
|
|
295
|
+
combinedSalt.set(saltBytes);
|
|
296
|
+
combinedSalt.set(saltStringBytes, saltBytes.length);
|
|
297
|
+
const passwordKey = await subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveBits", "deriveKey"]);
|
|
298
|
+
const derivedKey = await subtle.deriveKey({
|
|
299
|
+
name: "PBKDF2",
|
|
300
|
+
salt: combinedSalt,
|
|
301
|
+
iterations: encryptedKey.iterations,
|
|
302
|
+
hash: "SHA-256",
|
|
303
|
+
}, passwordKey, {
|
|
304
|
+
name: "AES-GCM",
|
|
305
|
+
length: 256,
|
|
306
|
+
}, false, ["decrypt"]);
|
|
307
|
+
// Combine ciphertext and tag (GCM authentication tag is separate)
|
|
308
|
+
const encryptedData = new Uint8Array(ciphertext.length + tag.length);
|
|
309
|
+
encryptedData.set(ciphertext);
|
|
310
|
+
encryptedData.set(tag, ciphertext.length);
|
|
311
|
+
// Decrypt the private key
|
|
312
|
+
const decrypted = await subtle.decrypt({
|
|
313
|
+
name: "AES-GCM",
|
|
314
|
+
iv: iv,
|
|
315
|
+
tagLength: 128,
|
|
316
|
+
}, derivedKey, encryptedData.buffer);
|
|
317
|
+
return decrypted;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Internal method to encrypt a private key using password-based key derivation.
|
|
321
|
+
* This is the reverse of decryptPrivateKey().
|
|
322
|
+
*
|
|
323
|
+
* @param privateKeyBytes The private key bytes to encrypt
|
|
324
|
+
* @param password The password to encrypt the key with
|
|
325
|
+
* @param saltString The salt string for key derivation (e.g., keyId)
|
|
326
|
+
* @returns The encrypted private key
|
|
327
|
+
*/
|
|
328
|
+
async encryptPrivateKey(privateKeyBytes, password, saltString) {
|
|
329
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
330
|
+
// Bind getRandomValues to maintain 'this' context
|
|
331
|
+
const randomValues = this.cryptoAdapter.getRandomValues.bind(this.cryptoAdapter);
|
|
332
|
+
// Generate random salt and IV
|
|
333
|
+
const saltArray = new Uint8Array(16); // 16 bytes salt
|
|
334
|
+
randomValues(saltArray);
|
|
335
|
+
const salt = new Uint8Array(saltArray);
|
|
336
|
+
const ivArray = new Uint8Array(12); // 12 bytes for AES-GCM
|
|
337
|
+
randomValues(ivArray);
|
|
338
|
+
const iv = new Uint8Array(ivArray);
|
|
339
|
+
// Combine salt with saltString for key derivation (same as decryption)
|
|
340
|
+
const saltStringBytes = new TextEncoder().encode(saltString);
|
|
341
|
+
const combinedSalt = new Uint8Array(salt.length + saltStringBytes.length);
|
|
342
|
+
combinedSalt.set(salt);
|
|
343
|
+
combinedSalt.set(saltStringBytes, salt.length);
|
|
344
|
+
// Derive encryption key from password using PBKDF2
|
|
345
|
+
const passwordKey = await subtle.importKey("raw", new TextEncoder().encode(password), "PBKDF2", false, ["deriveBits", "deriveKey"]);
|
|
346
|
+
const iterations = 310000; // OWASP-recommended PBKDF2 iterations for PBKDF2-SHA256
|
|
347
|
+
const derivedKey = await subtle.deriveKey({
|
|
348
|
+
name: "PBKDF2",
|
|
349
|
+
salt: combinedSalt,
|
|
350
|
+
iterations: iterations,
|
|
351
|
+
hash: "SHA-256",
|
|
352
|
+
}, passwordKey, {
|
|
353
|
+
name: "AES-GCM",
|
|
354
|
+
length: 256,
|
|
355
|
+
}, false, ["encrypt"]);
|
|
356
|
+
// Encrypt the private key
|
|
357
|
+
const encrypted = await subtle.encrypt({
|
|
358
|
+
name: "AES-GCM",
|
|
359
|
+
iv: iv,
|
|
360
|
+
tagLength: 128,
|
|
361
|
+
}, derivedKey, privateKeyBytes.buffer);
|
|
362
|
+
// Extract ciphertext and tag from encrypted data
|
|
363
|
+
// AES-GCM appends the tag at the end
|
|
364
|
+
const encryptedArray = new Uint8Array(encrypted);
|
|
365
|
+
const tagLength = 16; // 128 bits = 16 bytes
|
|
366
|
+
const ciphertext = encryptedArray.slice(0, encryptedArray.length - tagLength);
|
|
367
|
+
const tag = encryptedArray.slice(encryptedArray.length - tagLength);
|
|
368
|
+
// Create encrypted key structure
|
|
369
|
+
const encryptedKey = {
|
|
370
|
+
ciphertext: this.uint8ArrayToBase64(ciphertext),
|
|
371
|
+
iv: this.uint8ArrayToBase64(iv),
|
|
372
|
+
tag: this.uint8ArrayToBase64(tag),
|
|
373
|
+
salt: this.uint8ArrayToBase64(salt),
|
|
374
|
+
iterations: iterations,
|
|
375
|
+
};
|
|
376
|
+
return encryptedKey;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Helper method to convert base64 string to Uint8Array
|
|
380
|
+
*/
|
|
381
|
+
base64ToUint8Array(base64) {
|
|
382
|
+
const binary = atob(base64);
|
|
383
|
+
const bytes = new Uint8Array(binary.length);
|
|
384
|
+
for (let i = 0; i < binary.length; i++) {
|
|
385
|
+
bytes[i] = binary.charCodeAt(i);
|
|
386
|
+
}
|
|
387
|
+
return bytes;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Helper method to convert Uint8Array to base64 string
|
|
391
|
+
*/
|
|
392
|
+
uint8ArrayToBase64(bytes) {
|
|
393
|
+
let binary = "";
|
|
394
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
395
|
+
binary += String.fromCharCode(bytes[i]);
|
|
396
|
+
}
|
|
397
|
+
return btoa(binary);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
exports.KeyBag = KeyBag;
|
|
401
|
+
//# sourceMappingURL=KeyBag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyBag.js","sourceRoot":"","sources":["../../../src/core/keys/KeyBag.ts"],"names":[],"mappings":"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"}
|