@dwn-protocol/id-sdk 0.2.5 → 0.2.6
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/package.json +2 -3
- package/src/agent/app-data-store.ts +0 -365
- package/src/agent/did-manager.ts +0 -393
- package/src/agent/dwn-manager.ts +0 -548
- package/src/agent/identity-manager.ts +0 -165
- package/src/agent/index.ts +0 -19
- package/src/agent/json-rpc.ts +0 -107
- package/src/agent/key-manager.ts +0 -302
- package/src/agent/kms-local.ts +0 -412
- package/src/agent/outbox.ts +0 -128
- package/src/agent/rpc-client.ts +0 -223
- package/src/agent/store-managed-did.ts +0 -295
- package/src/agent/store-managed-identity.ts +0 -243
- package/src/agent/store-managed-key.ts +0 -754
- package/src/agent/sync-manager.ts +0 -631
- package/src/agent/test-managed-agent.ts +0 -299
- package/src/agent/types/agent.ts +0 -145
- package/src/agent/types/managed-key.ts +0 -442
- package/src/agent/utils.ts +0 -190
- package/src/common/convert.ts +0 -424
- package/src/common/index.ts +0 -9
- package/src/common/multicodec.ts +0 -176
- package/src/common/object.ts +0 -43
- package/src/common/stores.ts +0 -125
- package/src/common/stream-node.ts +0 -381
- package/src/common/stream.ts +0 -406
- package/src/common/type-utils.ts +0 -117
- package/src/common/types.ts +0 -48
- package/src/credentials/credential-bbs.ts +0 -419
- package/src/credentials/credential.ts +0 -324
- package/src/credentials/index.ts +0 -5
- package/src/credentials/presentation.ts +0 -182
- package/src/credentials/status-list.ts +0 -365
- package/src/credentials/utils.ts +0 -58
- package/src/credentials/validators.ts +0 -52
- package/src/crypto/algorithms-api/aes/base.ts +0 -49
- package/src/crypto/algorithms-api/aes/ctr.ts +0 -51
- package/src/crypto/algorithms-api/aes/index.ts +0 -2
- package/src/crypto/algorithms-api/crypto-algorithm.ts +0 -127
- package/src/crypto/algorithms-api/crypto-key.ts +0 -56
- package/src/crypto/algorithms-api/ec/base.ts +0 -39
- package/src/crypto/algorithms-api/ec/ecdh.ts +0 -53
- package/src/crypto/algorithms-api/ec/ecdsa.ts +0 -37
- package/src/crypto/algorithms-api/ec/eddsa.ts +0 -30
- package/src/crypto/algorithms-api/ec/index.ts +0 -4
- package/src/crypto/algorithms-api/errors.ts +0 -29
- package/src/crypto/algorithms-api/index.ts +0 -6
- package/src/crypto/algorithms-api/pbkdf/index.ts +0 -1
- package/src/crypto/algorithms-api/pbkdf/pbkdf2.ts +0 -91
- package/src/crypto/crypto-algorithms/aes-ctr.ts +0 -70
- package/src/crypto/crypto-algorithms/bbs.ts +0 -110
- package/src/crypto/crypto-algorithms/ecdh.ts +0 -115
- package/src/crypto/crypto-algorithms/ecdsa.ts +0 -111
- package/src/crypto/crypto-algorithms/eddsa.ts +0 -110
- package/src/crypto/crypto-algorithms/index.ts +0 -6
- package/src/crypto/crypto-algorithms/pbkdf2.ts +0 -54
- package/src/crypto/crypto-primitives/aes-ctr.ts +0 -131
- package/src/crypto/crypto-primitives/aes-gcm.ts +0 -138
- package/src/crypto/crypto-primitives/bbs.ts +0 -183
- package/src/crypto/crypto-primitives/concat-kdf.ts +0 -207
- package/src/crypto/crypto-primitives/ed25519.ts +0 -201
- package/src/crypto/crypto-primitives/index.ts +0 -10
- package/src/crypto/crypto-primitives/pbkdf2.ts +0 -78
- package/src/crypto/crypto-primitives/secp256k1.ts +0 -322
- package/src/crypto/crypto-primitives/x25519.ts +0 -101
- package/src/crypto/crypto-primitives/xchacha20-poly1305.ts +0 -46
- package/src/crypto/crypto-primitives/xchacha20.ts +0 -34
- package/src/crypto/index.ts +0 -8
- package/src/crypto/jose.ts +0 -948
- package/src/crypto/types/crypto-key.ts +0 -4
- package/src/crypto/types/iddwn-crypto.ts +0 -119
- package/src/crypto/utils.ts +0 -200
- package/src/did-api.ts +0 -72
- package/src/dids/dht.ts +0 -412
- package/src/dids/did-dht.ts +0 -436
- package/src/dids/did-ion.ts +0 -613
- package/src/dids/did-key.ts +0 -791
- package/src/dids/did-resolver.ts +0 -107
- package/src/dids/index.ts +0 -9
- package/src/dids/resolver-cache-level.ts +0 -82
- package/src/dids/resolver-cache-noop.ts +0 -25
- package/src/dids/types.ts +0 -278
- package/src/dids/utils.ts +0 -129
- package/src/dwn-api.ts +0 -584
- package/src/iddwn.ts +0 -241
- package/src/identity-agent/index.ts +0 -270
- package/src/index.ts +0 -26
- package/src/interfaces/metadata.ts +0 -163
- package/src/interfaces/queue.ts +0 -108
- package/src/interfaces/services.ts +0 -122
- package/src/interfaces/transactions.ts +0 -220
- package/src/protocol.ts +0 -68
- package/src/proxy-agent/index.ts +0 -255
- package/src/record.ts +0 -521
- package/src/service-options.ts +0 -62
- package/src/typings/decentralized-identity__ion-pow-sdk.d.ts +0 -7
- package/src/user-agent/index.ts +0 -295
- package/src/utils.ts +0 -29
- package/src/vc-api.ts +0 -505
package/src/agent/kms-local.ts
DELETED
|
@@ -1,412 +0,0 @@
|
|
|
1
|
-
import type { IDCrypto } from '../crypto/index.js';
|
|
2
|
-
import type { RequireOnly } from '../common/index.js';
|
|
3
|
-
|
|
4
|
-
import * as cryptoUtils from '../crypto/utils.js';
|
|
5
|
-
import {
|
|
6
|
-
EcdhAlgorithm,
|
|
7
|
-
EcdsaAlgorithm,
|
|
8
|
-
EdDsaAlgorithm,
|
|
9
|
-
AesCtrAlgorithm,
|
|
10
|
-
CryptoAlgorithm,
|
|
11
|
-
} from '../crypto/index.js';
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
ManagedKey,
|
|
15
|
-
PortableKey,
|
|
16
|
-
SignOptions,
|
|
17
|
-
VerifyOptions,
|
|
18
|
-
DecryptOptions,
|
|
19
|
-
EncryptOptions,
|
|
20
|
-
ManagedKeyPair,
|
|
21
|
-
ManagedKeyStore,
|
|
22
|
-
GenerateKeyType,
|
|
23
|
-
PortableKeyPair,
|
|
24
|
-
ImportKeyOptions,
|
|
25
|
-
UpdateKeyOptions,
|
|
26
|
-
DeriveBitsOptions,
|
|
27
|
-
ManagedPrivateKey,
|
|
28
|
-
GenerateKeyOptions,
|
|
29
|
-
KeyManagementSystem,
|
|
30
|
-
GenerateKeyOptionTypes,
|
|
31
|
-
} from './types/managed-key.js';
|
|
32
|
-
|
|
33
|
-
import { isManagedKey, isManagedKeyPair } from './utils.js';
|
|
34
|
-
import { KeyStoreMemory, PrivateKeyStoreMemory } from './store-managed-key.js';
|
|
35
|
-
import { IDManagedAgent } from './types/agent.js';
|
|
36
|
-
|
|
37
|
-
export type AlgorithmImplementation = typeof CryptoAlgorithm & { new(): CryptoAlgorithm; };
|
|
38
|
-
|
|
39
|
-
export type AlgorithmImplementations = {
|
|
40
|
-
[algorithmName: string]: AlgorithmImplementation;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export type KmsOptions = {
|
|
44
|
-
agent?: IDManagedAgent;
|
|
45
|
-
cryptoAlgorithms?: AlgorithmImplementations;
|
|
46
|
-
keyStore?: ManagedKeyStore<string, ManagedKey | ManagedKeyPair>;
|
|
47
|
-
kmsName: string;
|
|
48
|
-
privateKeyStore?: ManagedKeyStore<string, ManagedPrivateKey>;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Map key operations to algorithm specs to implementations.
|
|
52
|
-
export const defaultAlgorithms: AlgorithmImplementations = {
|
|
53
|
-
'AES-CTR' : AesCtrAlgorithm,
|
|
54
|
-
ECDH : EcdhAlgorithm,
|
|
55
|
-
ECDSA : EcdsaAlgorithm,
|
|
56
|
-
EdDSA : EdDsaAlgorithm,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export class LocalKms implements KeyManagementSystem {
|
|
60
|
-
/**
|
|
61
|
-
* Holds the instance of a `IDManagedAgent` that represents the current
|
|
62
|
-
* execution context for the `KeyManager`. This agent is utilized
|
|
63
|
-
* to interact with other agent components. It's vital
|
|
64
|
-
* to ensure this instance is set to correctly contextualize
|
|
65
|
-
* operations within the broader agent framework.
|
|
66
|
-
*/
|
|
67
|
-
private _agent?: IDManagedAgent;
|
|
68
|
-
private _name: string;
|
|
69
|
-
private _keyStore: ManagedKeyStore<string, ManagedKey | ManagedKeyPair>;
|
|
70
|
-
private _privateKeyStore: ManagedKeyStore<string, ManagedPrivateKey>;
|
|
71
|
-
private _supportedAlgorithms: Map<string, AlgorithmImplementation> = new Map();
|
|
72
|
-
|
|
73
|
-
constructor(options: KmsOptions) {
|
|
74
|
-
const { agent, kmsName, keyStore, privateKeyStore } = options;
|
|
75
|
-
this._agent = agent;
|
|
76
|
-
this._name = kmsName;
|
|
77
|
-
this._keyStore = keyStore ?? new KeyStoreMemory();
|
|
78
|
-
this._privateKeyStore = privateKeyStore ?? new PrivateKeyStoreMemory();
|
|
79
|
-
|
|
80
|
-
// Merge the default and custom algorithms and register with the KMS.
|
|
81
|
-
const cryptoAlgorithms = {...defaultAlgorithms, ...options.cryptoAlgorithms};
|
|
82
|
-
this.registerSupportedAlgorithms(cryptoAlgorithms);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Retrieves the `IDManagedAgent` execution context.
|
|
87
|
-
* If the `agent` instance proprety is undefined, it will throw an error.
|
|
88
|
-
*
|
|
89
|
-
* @returns The `IDManagedAgent` instance that represents the current execution
|
|
90
|
-
* context.
|
|
91
|
-
*
|
|
92
|
-
* @throws Will throw an error if the `agent` instance property is undefined.
|
|
93
|
-
*/
|
|
94
|
-
get agent(): IDManagedAgent {
|
|
95
|
-
if (this._agent === undefined) {
|
|
96
|
-
throw new Error('KeyManager: Unable to determine agent execution context.');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return this._agent;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
set agent(agent: IDManagedAgent) {
|
|
103
|
-
this._agent = agent;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async decrypt(options: DecryptOptions): Promise<Uint8Array> {
|
|
107
|
-
const { algorithm, data, keyRef } = options;
|
|
108
|
-
|
|
109
|
-
// Retrieve the ManagedKey from the KMS key metadata store.
|
|
110
|
-
const key = await this.getKey({ keyRef });
|
|
111
|
-
|
|
112
|
-
if (isManagedKey(key)) {
|
|
113
|
-
const privateManagedKey = await this._privateKeyStore.getKey({
|
|
114
|
-
id : key.id,
|
|
115
|
-
agent : this.agent
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
if (privateManagedKey !== undefined) {
|
|
119
|
-
// Construct a CryptoKey object from the key metadata and private key material.
|
|
120
|
-
const privateCryptoKey = this.toCryptoKey({ ...key, material: privateManagedKey.material });
|
|
121
|
-
|
|
122
|
-
// Decrypt the data.
|
|
123
|
-
const cryptoAlgorithm = this.getAlgorithm(algorithm);
|
|
124
|
-
const plaintext = cryptoAlgorithm.decrypt({ algorithm, key: privateCryptoKey, data });
|
|
125
|
-
|
|
126
|
-
return plaintext;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
throw new Error(`Operation failed: 'decrypt'. Key not found: ${keyRef}`);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async deriveBits(options: DeriveBitsOptions): Promise<Uint8Array> {
|
|
134
|
-
let { algorithm, baseKeyRef, length } = options;
|
|
135
|
-
|
|
136
|
-
// Retrieve the ManagedKeyPair from the KMS key metadata store.
|
|
137
|
-
const ownKeyPair = await this.getKey({ keyRef: baseKeyRef });
|
|
138
|
-
|
|
139
|
-
if (isManagedKeyPair(ownKeyPair)) {
|
|
140
|
-
const privateManagedKey = await this._privateKeyStore.getKey({
|
|
141
|
-
id : ownKeyPair.privateKey.id,
|
|
142
|
-
agent : this.agent
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
if (privateManagedKey !== undefined) {
|
|
146
|
-
// Construct a CryptoKey object from the key metadata and private key material.
|
|
147
|
-
const privateCryptoKey = this.toCryptoKey({ ...ownKeyPair.privateKey, material: privateManagedKey.material });
|
|
148
|
-
|
|
149
|
-
// Derive the shared secret.
|
|
150
|
-
const cryptoAlgorithm = this.getAlgorithm(algorithm);
|
|
151
|
-
const sharedSecret = cryptoAlgorithm.deriveBits({ algorithm, baseKey: privateCryptoKey, length: length ?? null });
|
|
152
|
-
|
|
153
|
-
return sharedSecret;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
throw new Error(`Operation failed: 'deriveBits'. Key not found: ${baseKeyRef}`);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async encrypt(options: EncryptOptions): Promise<Uint8Array> {
|
|
161
|
-
const { algorithm, data, keyRef } = options;
|
|
162
|
-
|
|
163
|
-
// Retrieve the ManagedKey from the KMS key metadata store.
|
|
164
|
-
const key = await this.getKey({ keyRef });
|
|
165
|
-
|
|
166
|
-
if (isManagedKey(key)) {
|
|
167
|
-
const privateManagedKey = await this._privateKeyStore.getKey({
|
|
168
|
-
id : key.id,
|
|
169
|
-
agent : this.agent
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
if (privateManagedKey !== undefined) {
|
|
173
|
-
// Construct a CryptoKey object from the key metadata and private key material.
|
|
174
|
-
const privateCryptoKey = this.toCryptoKey({ ...key, material: privateManagedKey.material });
|
|
175
|
-
|
|
176
|
-
// Encrypt the data.
|
|
177
|
-
const cryptoAlgorithm = this.getAlgorithm(algorithm);
|
|
178
|
-
const ciphertext = cryptoAlgorithm.encrypt({ algorithm, key: privateCryptoKey, data });
|
|
179
|
-
|
|
180
|
-
return ciphertext;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
throw new Error(`Operation failed: 'encrypt'. Key not found: ${keyRef}`);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
async generateKey<T extends GenerateKeyOptionTypes>(options: GenerateKeyOptions<T>): Promise<GenerateKeyType<T>> {
|
|
188
|
-
let { algorithm, alias, extractable, keyUsages, metadata } = options;
|
|
189
|
-
|
|
190
|
-
// Get crypto algorithm implementation.
|
|
191
|
-
const cryptoAlgorithm = this.getAlgorithm(algorithm);
|
|
192
|
-
|
|
193
|
-
// Generate the key.
|
|
194
|
-
extractable ??= true; // Default to extractable if not specified.
|
|
195
|
-
const cryptoKey: any = await cryptoAlgorithm.generateKey({ algorithm, extractable, keyUsages });
|
|
196
|
-
|
|
197
|
-
// Create a ManagedKey or ManagedKeyPair using the generated key and store the private key material.
|
|
198
|
-
let managedKeyOrKeyPair: GenerateKeyType<T>;
|
|
199
|
-
if (cryptoUtils.isCryptoKeyPair(cryptoKey)) {
|
|
200
|
-
const privateKeyType = cryptoKey.privateKey.type as IDCrypto.PrivateKeyType;
|
|
201
|
-
const id = await this._privateKeyStore.importKey({
|
|
202
|
-
key : { material: cryptoKey.privateKey.material, type: privateKeyType},
|
|
203
|
-
agent : this.agent
|
|
204
|
-
});
|
|
205
|
-
const managedKeyPair: ManagedKeyPair = {
|
|
206
|
-
privateKey : this.toManagedKey({ ...cryptoKey.privateKey, id, alias, metadata }),
|
|
207
|
-
publicKey : this.toManagedKey({ ...cryptoKey.publicKey, material: cryptoKey.publicKey.material, id, alias, metadata })
|
|
208
|
-
};
|
|
209
|
-
managedKeyOrKeyPair = managedKeyPair as GenerateKeyType<T>;
|
|
210
|
-
} else {
|
|
211
|
-
const keyType = cryptoKey.type as IDCrypto.PrivateKeyType;
|
|
212
|
-
const id = await this._privateKeyStore.importKey({
|
|
213
|
-
key : { material: cryptoKey.material, type: keyType },
|
|
214
|
-
agent : this.agent
|
|
215
|
-
});
|
|
216
|
-
managedKeyOrKeyPair = this.toManagedKey({ ...cryptoKey, id, alias, metadata }) as GenerateKeyType<T>;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Store the ManagedKey or ManagedKeyPair in the KMS key store.
|
|
220
|
-
await this._keyStore.importKey({ key: managedKeyOrKeyPair, agent: this.agent });
|
|
221
|
-
|
|
222
|
-
return managedKeyOrKeyPair;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
async getKey(options: { keyRef: string }): Promise<ManagedKey | ManagedKeyPair | undefined> {
|
|
226
|
-
const keyOrKeyPair = this._keyStore.getKey({ id: options.keyRef, agent: this.agent });
|
|
227
|
-
return keyOrKeyPair;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async importKey(options: PortableKeyPair): Promise<ManagedKeyPair>;
|
|
231
|
-
async importKey(options: PortableKey): Promise<ManagedKey>;
|
|
232
|
-
async importKey(options: ImportKeyOptions): Promise<ManagedKey | ManagedKeyPair> {
|
|
233
|
-
|
|
234
|
-
if ('privateKey' in options) {
|
|
235
|
-
// Asymmetric key pair import.
|
|
236
|
-
const { privateKey, publicKey } = options;
|
|
237
|
-
if (privateKey.type === 'public' && publicKey.type === 'private')
|
|
238
|
-
throw new Error(`Import failed due to private and public key mismatch`);
|
|
239
|
-
if (!(privateKey.type === 'private' && publicKey.type === 'public'))
|
|
240
|
-
throw new TypeError(`Out of range: '${privateKey.type}, ${publicKey.type}'. Must be 'private, public'`);
|
|
241
|
-
const id = await this._privateKeyStore.importKey({
|
|
242
|
-
key : { material: privateKey.material, type: privateKey.type },
|
|
243
|
-
agent : this.agent
|
|
244
|
-
});
|
|
245
|
-
const managedKeyPair = {
|
|
246
|
-
privateKey : this.toManagedKey({ ...privateKey, id, material: undefined }),
|
|
247
|
-
publicKey : this.toManagedKey({ ...publicKey, material: publicKey.material, id })
|
|
248
|
-
};
|
|
249
|
-
await this._keyStore.importKey({ key: managedKeyPair, agent: this.agent });
|
|
250
|
-
return managedKeyPair;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const keyType = options.type;
|
|
254
|
-
switch (keyType) {
|
|
255
|
-
case 'private': {
|
|
256
|
-
// Asymmetric private key import.
|
|
257
|
-
const material = options.material;
|
|
258
|
-
const id = await this._privateKeyStore.importKey({
|
|
259
|
-
key : { material, type: keyType },
|
|
260
|
-
agent : this.agent
|
|
261
|
-
});
|
|
262
|
-
const privateManagedKey = this.toManagedKey({ ...options, material: undefined, id });
|
|
263
|
-
await this._keyStore.importKey({ key: privateManagedKey, agent: this.agent });
|
|
264
|
-
return privateManagedKey;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
case 'public': {
|
|
268
|
-
// Asymmetric public key import.
|
|
269
|
-
const material = options.material;
|
|
270
|
-
const publicManagedKey = this.toManagedKey({ ...options, material, id: '' });
|
|
271
|
-
publicManagedKey.id = await this._keyStore.importKey({ key: publicManagedKey, agent: this.agent });
|
|
272
|
-
return publicManagedKey;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
case 'secret': {
|
|
276
|
-
// Symmetric secret key import.
|
|
277
|
-
const material = options.material;
|
|
278
|
-
const id = await this._privateKeyStore.importKey({
|
|
279
|
-
key : { material, type: keyType },
|
|
280
|
-
agent : this.agent
|
|
281
|
-
});
|
|
282
|
-
const secretManagedKey = this.toManagedKey({ ...options, material: undefined, id });
|
|
283
|
-
await this._keyStore.importKey({ key: secretManagedKey, agent: this.agent });
|
|
284
|
-
return secretManagedKey;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
default:
|
|
288
|
-
throw new TypeError(`Out of range: '${keyType}'. Must be one of 'private, public, secret'`);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async sign(options: SignOptions): Promise<Uint8Array> {
|
|
293
|
-
const { algorithm, data, keyRef } = options;
|
|
294
|
-
|
|
295
|
-
// Retrieve the ManagedKeyPair from the KMS key metadata store.
|
|
296
|
-
const keyPair = await this.getKey({ keyRef });
|
|
297
|
-
|
|
298
|
-
if (isManagedKeyPair(keyPair)) {
|
|
299
|
-
const privateManagedKey = await this._privateKeyStore.getKey({
|
|
300
|
-
id : keyPair.privateKey.id,
|
|
301
|
-
agent : this.agent
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
if (privateManagedKey !== undefined) {
|
|
305
|
-
// Construct a CryptoKey object from the key metadata and private key material.
|
|
306
|
-
const privateCryptoKey = this.toCryptoKey({ ...keyPair.privateKey, material: privateManagedKey.material });
|
|
307
|
-
|
|
308
|
-
// Sign the data.
|
|
309
|
-
const cryptoAlgorithm = this.getAlgorithm(algorithm);
|
|
310
|
-
const signature = cryptoAlgorithm.sign({ algorithm, key: privateCryptoKey, data });
|
|
311
|
-
|
|
312
|
-
return signature;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
throw new Error(`Operation failed: 'sign'. Key not found: ${keyRef}`);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
async updateKey(options: UpdateKeyOptions): Promise<boolean> {
|
|
320
|
-
const { keyRef, alias, metadata } = options;
|
|
321
|
-
|
|
322
|
-
const keyOrKeyPair = await this.getKey({ keyRef });
|
|
323
|
-
|
|
324
|
-
if (!keyOrKeyPair) {
|
|
325
|
-
throw new Error(`Key not found: '${keyRef}'`);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const keyId = (isManagedKeyPair(keyOrKeyPair))
|
|
329
|
-
? keyOrKeyPair.publicKey.id
|
|
330
|
-
: keyOrKeyPair.id;
|
|
331
|
-
|
|
332
|
-
// Update the KMS key metadata store.
|
|
333
|
-
return this._keyStore.updateKey({ id: keyId, alias, metadata, agent: this.agent });
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
async verify(options: VerifyOptions): Promise<boolean> {
|
|
337
|
-
const { algorithm, data, keyRef, signature } = options;
|
|
338
|
-
|
|
339
|
-
// Retrieve the ManagedKeyPair from the KMS key metadata store.
|
|
340
|
-
const keyPair = await this.getKey({ keyRef });
|
|
341
|
-
|
|
342
|
-
if (isManagedKeyPair(keyPair)) {
|
|
343
|
-
if (keyPair.publicKey.material === undefined) {
|
|
344
|
-
throw new Error(`Required property missing: 'material'`);
|
|
345
|
-
}
|
|
346
|
-
// Construct a CryptoKey object from the key metadata and private key material.
|
|
347
|
-
const publicCryptoKey = this.toCryptoKey({
|
|
348
|
-
...keyPair.publicKey,
|
|
349
|
-
material: keyPair.publicKey.material
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// Verify the signature and data.
|
|
353
|
-
const cryptoAlgorithm = this.getAlgorithm(algorithm);
|
|
354
|
-
const isValid = cryptoAlgorithm.verify({ algorithm, key: publicCryptoKey, signature, data });
|
|
355
|
-
|
|
356
|
-
return isValid;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
throw new Error(`Operation failed: 'verify'. Key not found: ${keyRef}`);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
private getAlgorithm(algorithmIdentifier: IDCrypto.AlgorithmIdentifier): CryptoAlgorithm {
|
|
363
|
-
cryptoUtils.checkRequiredProperty({ property: 'name', inObject: algorithmIdentifier });
|
|
364
|
-
const algorithm = this._supportedAlgorithms.get(algorithmIdentifier.name.toUpperCase());
|
|
365
|
-
|
|
366
|
-
if (algorithm === undefined) {
|
|
367
|
-
throw new Error(`The algorithm '${algorithmIdentifier.name}' is not supported`);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return algorithm.create();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
private registerSupportedAlgorithms(cryptoAlgorithms: AlgorithmImplementations): void {
|
|
374
|
-
for (const [name, implementation] of Object.entries(cryptoAlgorithms)) {
|
|
375
|
-
// Add the algorithm name and its implementation to the supported algorithms map,
|
|
376
|
-
// upper-cased to allow for case-insensitive.
|
|
377
|
-
this._supportedAlgorithms.set(name.toUpperCase(), implementation);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
private toCryptoKey(managedKey:
|
|
382
|
-
RequireOnly<ManagedKey, 'algorithm' | 'extractable' | 'material' | 'type' | 'usages'>
|
|
383
|
-
): IDCrypto.CryptoKey {
|
|
384
|
-
|
|
385
|
-
const cryptoKey: IDCrypto.CryptoKey = {
|
|
386
|
-
algorithm : managedKey.algorithm,
|
|
387
|
-
extractable : managedKey.extractable,
|
|
388
|
-
material : managedKey.material,
|
|
389
|
-
type : managedKey.type,
|
|
390
|
-
usages : managedKey.usages
|
|
391
|
-
};
|
|
392
|
-
|
|
393
|
-
return cryptoKey;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
private toManagedKey(options: Omit<IDCrypto.CryptoKey, 'material'> & RequireOnly<ManagedKey, 'id'>): ManagedKey {
|
|
397
|
-
const managedKey: ManagedKey = {
|
|
398
|
-
id : options.id,
|
|
399
|
-
algorithm : options.algorithm,
|
|
400
|
-
alias : options.alias,
|
|
401
|
-
extractable : options.extractable,
|
|
402
|
-
kms : this._name,
|
|
403
|
-
material : (options.type === 'public') ? options.material : undefined,
|
|
404
|
-
metadata : options.metadata,
|
|
405
|
-
state : 'Enabled',
|
|
406
|
-
type : options.type,
|
|
407
|
-
usages : options.usages
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
return managedKey;
|
|
411
|
-
}
|
|
412
|
-
}
|
package/src/agent/outbox.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import type { AbstractLevel } from 'abstract-level';
|
|
2
|
-
import { Level } from 'level';
|
|
3
|
-
import type { IDManagedAgent } from './types/agent.js';
|
|
4
|
-
import type { DwnRpcRequest } from './rpc-client.js';
|
|
5
|
-
import { Convert } from '../common/index.js';
|
|
6
|
-
|
|
7
|
-
type LevelDatabase = AbstractLevel<string | Buffer | Uint8Array, string, string>;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Serialized entry stored in the outbox for replay. Uses the same shape as
|
|
11
|
-
* the RPC payload so replay is a single sendDwnRequest per endpoint.
|
|
12
|
-
*/
|
|
13
|
-
export type OutboxEntryPayload = {
|
|
14
|
-
targetDid: string;
|
|
15
|
-
dwnUrls: string[];
|
|
16
|
-
message: Record<string, unknown>;
|
|
17
|
-
dataBase64?: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type OutboxOptions = {
|
|
21
|
-
agent?: IDManagedAgent;
|
|
22
|
-
dataPath?: string;
|
|
23
|
-
db?: LevelDatabase;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Persists outbound DWN send requests that failed due to network and replays
|
|
28
|
-
* them when draining. Entries are stored in FIFO order (by key).
|
|
29
|
-
*/
|
|
30
|
-
export class Outbox {
|
|
31
|
-
private _agent?: IDManagedAgent;
|
|
32
|
-
private _store: LevelDatabase;
|
|
33
|
-
|
|
34
|
-
constructor(options: OutboxOptions = {}) {
|
|
35
|
-
const { agent, dataPath = 'data/AGENT/OUTBOX', db } = options;
|
|
36
|
-
this._agent = agent;
|
|
37
|
-
if (db) {
|
|
38
|
-
this._store = db.sublevel('outbox') as LevelDatabase;
|
|
39
|
-
} else {
|
|
40
|
-
this._store = new Level(dataPath) as LevelDatabase;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get agent(): IDManagedAgent {
|
|
45
|
-
if (this._agent === undefined) {
|
|
46
|
-
throw new Error('Outbox: Unable to determine agent execution context.');
|
|
47
|
-
}
|
|
48
|
-
return this._agent;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
set agent(agent: IDManagedAgent) {
|
|
52
|
-
this._agent = agent;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Enqueue a failed send for later replay. Payload must be the serializable
|
|
57
|
-
* form (message object and optional data as base64).
|
|
58
|
-
*/
|
|
59
|
-
async enqueue(entry: OutboxEntryPayload): Promise<void> {
|
|
60
|
-
const key = `seq-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
61
|
-
const value = JSON.stringify(entry);
|
|
62
|
-
await this._store.put(key, value);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Try each queued item: for each entry, try each dwnUrl until one succeeds;
|
|
67
|
-
* on success delete from queue; on total failure leave in queue for next drain.
|
|
68
|
-
*/
|
|
69
|
-
async drain(): Promise<void> {
|
|
70
|
-
const agent = this.agent;
|
|
71
|
-
const entries: [string, OutboxEntryPayload][] = [];
|
|
72
|
-
|
|
73
|
-
for await (const [key, value] of this._store.iterator()) {
|
|
74
|
-
if (!key.startsWith('seq-')) continue;
|
|
75
|
-
try {
|
|
76
|
-
const payload = JSON.parse(value as string) as OutboxEntryPayload;
|
|
77
|
-
entries.push([key, payload]);
|
|
78
|
-
} catch {
|
|
79
|
-
// Skip malformed entries
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
for (const [key, payload] of entries) {
|
|
84
|
-
const { targetDid, dwnUrls, message, dataBase64 } = payload;
|
|
85
|
-
let sent = false;
|
|
86
|
-
|
|
87
|
-
for (const dwnUrl of dwnUrls) {
|
|
88
|
-
try {
|
|
89
|
-
const request: DwnRpcRequest = {
|
|
90
|
-
dwnUrl,
|
|
91
|
-
targetDid,
|
|
92
|
-
message,
|
|
93
|
-
...(dataBase64 !== undefined
|
|
94
|
-
? {
|
|
95
|
-
data: new Blob([
|
|
96
|
-
new Uint8Array(Convert.base64Url(dataBase64).toUint8Array()),
|
|
97
|
-
]),
|
|
98
|
-
}
|
|
99
|
-
: {}),
|
|
100
|
-
};
|
|
101
|
-
await agent.rpcClient.sendDwnRequest(request);
|
|
102
|
-
sent = true;
|
|
103
|
-
break;
|
|
104
|
-
} catch {
|
|
105
|
-
// Try next endpoint
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (sent) {
|
|
110
|
-
await this._store.del(key);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Clear all queued entries (for tests or reset).
|
|
117
|
-
*/
|
|
118
|
-
async clear(): Promise<void> {
|
|
119
|
-
const keys: string[] = [];
|
|
120
|
-
for await (const [key] of this._store.iterator()) {
|
|
121
|
-
if (key.startsWith('seq-')) keys.push(key);
|
|
122
|
-
}
|
|
123
|
-
await this._store.batch(keys.map((key) => ({ type: 'del' as const, key })) as any);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** @deprecated Use OutboxEntryPayload */
|
|
128
|
-
export type OutboxEntry = OutboxEntryPayload;
|