@keetanetwork/anchor 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.
Files changed (76) hide show
  1. package/.done +0 -0
  2. package/LICENSE +35 -0
  3. package/client/index.d.ts +10 -0
  4. package/client/index.d.ts.map +1 -0
  5. package/client/index.js +11 -0
  6. package/client/index.js.map +1 -0
  7. package/config.d.ts +10 -0
  8. package/config.d.ts.map +1 -0
  9. package/config.js +36 -0
  10. package/config.js.map +1 -0
  11. package/lib/certificates.d.ts +106 -0
  12. package/lib/certificates.d.ts.map +1 -0
  13. package/lib/certificates.js +463 -0
  14. package/lib/certificates.js.map +1 -0
  15. package/lib/encrypted-container.d.ts +106 -0
  16. package/lib/encrypted-container.d.ts.map +1 -0
  17. package/lib/encrypted-container.js +594 -0
  18. package/lib/encrypted-container.js.map +1 -0
  19. package/lib/index.d.ts +5 -0
  20. package/lib/index.d.ts.map +1 -0
  21. package/lib/index.js +5 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/log/common.d.ts +35 -0
  24. package/lib/log/common.d.ts.map +1 -0
  25. package/lib/log/common.js +19 -0
  26. package/lib/log/common.js.map +1 -0
  27. package/lib/log/index.d.ts +59 -0
  28. package/lib/log/index.d.ts.map +1 -0
  29. package/lib/log/index.js +207 -0
  30. package/lib/log/index.js.map +1 -0
  31. package/lib/log/target_console.d.ts +13 -0
  32. package/lib/log/target_console.d.ts.map +1 -0
  33. package/lib/log/target_console.js +44 -0
  34. package/lib/log/target_console.js.map +1 -0
  35. package/lib/resolver.d.ts +308 -0
  36. package/lib/resolver.d.ts.map +1 -0
  37. package/lib/resolver.js +1429 -0
  38. package/lib/resolver.js.map +1 -0
  39. package/lib/utils/array.d.ts +10 -0
  40. package/lib/utils/array.d.ts.map +1 -0
  41. package/lib/utils/array.js +12 -0
  42. package/lib/utils/array.js.map +1 -0
  43. package/lib/utils/asn1.d.ts +13 -0
  44. package/lib/utils/asn1.d.ts.map +1 -0
  45. package/lib/utils/asn1.js +8 -0
  46. package/lib/utils/asn1.js.map +1 -0
  47. package/lib/utils/buffer.d.ts +4 -0
  48. package/lib/utils/buffer.d.ts.map +1 -0
  49. package/lib/utils/buffer.js +3 -0
  50. package/lib/utils/buffer.js.map +1 -0
  51. package/lib/utils/crypto.d.ts +4 -0
  52. package/lib/utils/crypto.d.ts.map +1 -0
  53. package/lib/utils/crypto.js +4 -0
  54. package/lib/utils/crypto.js.map +1 -0
  55. package/lib/utils/index.d.ts +5 -0
  56. package/lib/utils/index.d.ts.map +1 -0
  57. package/lib/utils/index.js +5 -0
  58. package/lib/utils/index.js.map +1 -0
  59. package/lib/utils/json.d.ts +8 -0
  60. package/lib/utils/json.d.ts.map +1 -0
  61. package/lib/utils/json.js +164 -0
  62. package/lib/utils/json.js.map +1 -0
  63. package/lib/utils/never.d.ts +8 -0
  64. package/lib/utils/never.d.ts.map +1 -0
  65. package/lib/utils/never.js +14 -0
  66. package/lib/utils/never.js.map +1 -0
  67. package/npm-shrinkwrap.json +16517 -0
  68. package/package.json +42 -0
  69. package/services/kyc/client.d.ts +139 -0
  70. package/services/kyc/client.d.ts.map +1 -0
  71. package/services/kyc/client.js +390 -0
  72. package/services/kyc/client.js.map +1 -0
  73. package/services/kyc/common.d.ts +65 -0
  74. package/services/kyc/common.d.ts.map +1 -0
  75. package/services/kyc/common.js +2 -0
  76. package/services/kyc/common.js.map +1 -0
@@ -0,0 +1,463 @@
1
+ import * as KeetaNetClient from '@keetanetwork/keetanet-client';
2
+ import * as ASN1 from './utils/asn1.js';
3
+ import { Buffer } from './utils/buffer.js';
4
+ import crypto from './utils/crypto.js';
5
+ import { assertNever } from './utils/never.js';
6
+ /* -----MOVE TO NODE AND ASN1NAPIRS----- */
7
+ function getOID(name, oidDB) {
8
+ if (name in oidDB) {
9
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
10
+ const oid = oidDB[name];
11
+ if (oid === undefined) {
12
+ throw (new Error('internal error: OID was undefined'));
13
+ }
14
+ return (oid);
15
+ }
16
+ else {
17
+ throw (new Error('Unknown algorithm'));
18
+ }
19
+ }
20
+ function lookupByOID(oid, oidDB) {
21
+ for (const [key, value] of Object.entries(oidDB)) {
22
+ if (key === oid) {
23
+ return (key);
24
+ }
25
+ if (value === oid) {
26
+ return (key);
27
+ }
28
+ }
29
+ throw (new Error(`Unknown OID: ${oid}`));
30
+ }
31
+ /* -----END MOVE TO NODE AND ASN1NAPIRS----- */
32
+ function toJSON(data) {
33
+ const retval = JSON.parse(JSON.stringify(data, function (key, convertedValue) {
34
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
35
+ const value = this[key];
36
+ if (typeof value === 'object' && value !== null) {
37
+ if ('publicKeyString' in value && typeof value.publicKeyString === 'object' && value.publicKeyString !== null) {
38
+ if ('get' in value.publicKeyString && typeof value.publicKeyString.get === 'function') {
39
+ /*
40
+ * If the value has a publicKeyString property that is an
41
+ * object with a get method, we assume it is a KeetaNetAccount
42
+ * or similar object and we return the public key string
43
+ */
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
45
+ const publicKeyString = value.publicKeyString.get();
46
+ if (typeof publicKeyString === 'string') {
47
+ return (publicKeyString);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ if (Buffer.isBuffer(value)) {
53
+ return (value.toString('base64'));
54
+ }
55
+ if (typeof value === 'bigint') {
56
+ return (value.toString());
57
+ }
58
+ return (convertedValue);
59
+ }));
60
+ return (retval);
61
+ }
62
+ /*
63
+ * Because our public interfaces are ArrayBuffers we often need to convert
64
+ * Buffers to ArrayBuffers -- an alias to the Node function to do that
65
+ */
66
+ const bufferToArrayBuffer = KeetaNetClient.lib.Utils.Helper.bufferToArrayBuffer.bind(KeetaNetClient.lib.Utils.Helper);
67
+ /**
68
+ * Sensitive Attribute Schema
69
+ *
70
+ * ASN.1 Schema:
71
+ * SensitiveAttributes DEFINITIONS ::= BEGIN
72
+ * SensitiveAttribute ::= SEQUENCE {
73
+ * version INTEGER { v1(0) },
74
+ * cipher SEQUENCE {
75
+ * algorithm OBJECT IDENTIFIER,
76
+ * ivOrNonce OCTET STRING,
77
+ * key OCTET STRING
78
+ * },
79
+ * hashedValue SEQUENCE {
80
+ * encryptedSalt OCTET STRING,
81
+ * algorithm OBJECT IDENTIFIER,
82
+ * value OCTET STRING
83
+ * },
84
+ * encryptedValue OCTET STRING
85
+ * }
86
+ * END
87
+ *
88
+ * https://keeta.notion.site/Keeta-KYC-Certificate-Extensions-13e5da848e588042bdcef81fc40458b7
89
+ *
90
+ * @internal
91
+ */
92
+ const SensitiveAttributeSchemaInternal = [
93
+ 0n,
94
+ [
95
+ ASN1.ValidateASN1.IsOID,
96
+ ASN1.ValidateASN1.IsOctetString,
97
+ ASN1.ValidateASN1.IsOctetString
98
+ ],
99
+ [
100
+ ASN1.ValidateASN1.IsOctetString,
101
+ ASN1.ValidateASN1.IsOID,
102
+ ASN1.ValidateASN1.IsOctetString
103
+ ],
104
+ ASN1.ValidateASN1.IsOctetString
105
+ ];
106
+ /*
107
+ * Database of permitted algorithms and their OIDs
108
+ */
109
+ const sensitiveAttributeOIDDB = {
110
+ 'aes-256-gcm': '2.16.840.1.101.3.4.1.46',
111
+ 'aes-256-cbc': '2.16.840.1.101.3.4.1.42',
112
+ 'sha2-256': '2.16.840.1.101.3.4.2.1',
113
+ 'sha3-256': '2.16.840.1.101.3.4.2.8'
114
+ };
115
+ class SensitiveAttributeBuilder {
116
+ #account;
117
+ #value;
118
+ constructor(account, value) {
119
+ this.#account = account;
120
+ if (value) {
121
+ this.set(value);
122
+ }
123
+ }
124
+ set(value) {
125
+ if (Buffer.isBuffer(value)) {
126
+ this.#value = value;
127
+ }
128
+ else if (typeof value === 'string') {
129
+ this.#value = Buffer.from(value, 'utf-8');
130
+ }
131
+ else {
132
+ this.#value = Buffer.from(value);
133
+ }
134
+ return (this);
135
+ }
136
+ async build() {
137
+ if (this.#value === undefined) {
138
+ throw (new Error('Value not set'));
139
+ }
140
+ const salt = crypto.randomBytes(32);
141
+ const hashingAlgorithm = KeetaNetClient.lib.Utils.Hash.HashFunctionName;
142
+ const publicKey = Buffer.from(this.#account.publicKey.get());
143
+ const cipher = 'aes-256-gcm';
144
+ const key = crypto.randomBytes(32);
145
+ const nonce = crypto.randomBytes(12);
146
+ const encryptedKey = await this.#account.encrypt(key);
147
+ function encrypt(value) {
148
+ const cipherObject = crypto.createCipheriv(cipher, key, nonce);
149
+ let retval = cipherObject.update(value);
150
+ retval = Buffer.concat([retval, cipherObject.final()]);
151
+ return (retval);
152
+ }
153
+ const encryptedValue = encrypt(this.#value);
154
+ const encryptedSalt = encrypt(salt);
155
+ const saltedValue = Buffer.concat([salt, publicKey, encryptedValue, this.#value]);
156
+ const hashedAndSaltedValue = KeetaNetClient.lib.Utils.Hash.Hash(saltedValue);
157
+ const attributeStructure = [
158
+ /* Version */
159
+ 0n,
160
+ /* Cipher Details */
161
+ [
162
+ /* Algorithm */
163
+ { type: 'oid', oid: getOID(cipher, sensitiveAttributeOIDDB) },
164
+ /* IV or Nonce */
165
+ nonce,
166
+ /* Symmetric key, encrypted with the public key of the account */
167
+ Buffer.from(encryptedKey)
168
+ ],
169
+ /* Hashed Value */
170
+ [
171
+ /* Encrypted Salt */
172
+ Buffer.from(encryptedSalt),
173
+ /* Hashing Algorithm */
174
+ { type: 'oid', oid: getOID(hashingAlgorithm, sensitiveAttributeOIDDB) },
175
+ /* Hash of <Encrypted Salt> || <Public Key> || <Value> */
176
+ Buffer.from(hashedAndSaltedValue)
177
+ ],
178
+ /* Encrypted Value, encrypted with the Cipher above */
179
+ encryptedValue
180
+ ];
181
+ const encodedAttributeObject = ASN1.JStoASN1(attributeStructure);
182
+ const retval = encodedAttributeObject.toBER();
183
+ return (retval);
184
+ }
185
+ }
186
+ class SensitiveAttribute {
187
+ #account;
188
+ #info;
189
+ constructor(account, data) {
190
+ this.#account = account;
191
+ this.#info = this.decode(data);
192
+ }
193
+ decode(data) {
194
+ if (Buffer.isBuffer(data)) {
195
+ data = bufferToArrayBuffer(data);
196
+ }
197
+ const dataObject = new ASN1.BufferStorageASN1(data, SensitiveAttributeSchemaInternal);
198
+ const decodedAttribute = dataObject.getASN1();
199
+ const decodedVersion = decodedAttribute[0] + 1n;
200
+ if (decodedVersion !== 1n) {
201
+ throw (new Error(`Unsupported Sensitive Attribute version (${decodedVersion})`));
202
+ }
203
+ return ({
204
+ version: decodedVersion,
205
+ publicKey: this.#account.publicKeyString.get(),
206
+ cipher: {
207
+ algorithm: lookupByOID(decodedAttribute[1][0].oid, sensitiveAttributeOIDDB),
208
+ iv: decodedAttribute[1][1],
209
+ key: decodedAttribute[1][2]
210
+ },
211
+ hashedValue: {
212
+ encryptedSalt: decodedAttribute[2][0],
213
+ algorithm: lookupByOID(decodedAttribute[2][1].oid, sensitiveAttributeOIDDB),
214
+ value: decodedAttribute[2][2]
215
+ },
216
+ encryptedValue: decodedAttribute[3]
217
+ });
218
+ }
219
+ async #decryptValue(value) {
220
+ const decryptedKey = await this.#account.decrypt(this.#info.cipher.key);
221
+ const algorithm = this.#info.cipher.algorithm;
222
+ const iv = this.#info.cipher.iv;
223
+ const cipher = crypto.createDecipheriv(algorithm, Buffer.from(decryptedKey), iv);
224
+ const decryptedValue = cipher.update(value);
225
+ return (decryptedValue);
226
+ }
227
+ /**
228
+ * Get the value of the sensitive attribute
229
+ *
230
+ * This will decrypt the value using the account's private key
231
+ * and return the value as an ArrayBuffer
232
+ *
233
+ * Since sensitive attributes are binary blobs, this returns an
234
+ * ArrayBuffer
235
+ */
236
+ async get() {
237
+ const decryptedValue = await this.#decryptValue(this.#info.encryptedValue);
238
+ return (bufferToArrayBuffer(decryptedValue));
239
+ }
240
+ /**
241
+ * Get the value of the sensitive attribute as a string after being
242
+ * interpreted as UTF-8 ( @see SensitiveAttribute.get for more information)
243
+ */
244
+ async getString() {
245
+ const value = await this.get();
246
+ return (Buffer.from(value).toString('utf-8'));
247
+ }
248
+ /**
249
+ * Generate a proof that a sensitive attribute is a given value,
250
+ * which can be validated by a third party using the certificate
251
+ * and the `validateProof` method
252
+ */
253
+ async proove() {
254
+ const value = await this.get();
255
+ const salt = await this.#decryptValue(this.#info.hashedValue.encryptedSalt);
256
+ return ({
257
+ value: Buffer.from(value).toString('base64'),
258
+ hash: {
259
+ salt: salt.toString('base64')
260
+ }
261
+ });
262
+ }
263
+ /**
264
+ * Validate the proof that a sensitive attribute is a given value
265
+ */
266
+ async validateProof(proof) {
267
+ const plaintextValue = Buffer.from(proof.value, 'base64');
268
+ const proofSaltBuffer = Buffer.from(proof.hash.salt, 'base64');
269
+ const publicKeyBuffer = Buffer.from(this.#account.publicKey.get());
270
+ const encryptedValue = this.#info.encryptedValue;
271
+ const hashedAndSaltedValue = KeetaNetClient.lib.Utils.Hash.Hash(Buffer.concat([proofSaltBuffer, publicKeyBuffer, encryptedValue, plaintextValue]));
272
+ const hashedAndSaltedValueBuffer = Buffer.from(hashedAndSaltedValue);
273
+ return (this.#info.hashedValue.value.equals(hashedAndSaltedValueBuffer));
274
+ }
275
+ toJSON() {
276
+ return (toJSON(this.#info));
277
+ }
278
+ }
279
+ /**
280
+ * Database of attributes
281
+ */
282
+ const CertificateAttributeOIDDB = {
283
+ 'fullName': '1.3.6.1.4.1.62675.1.0',
284
+ 'dateOfBirth': '1.3.6.1.4.1.62675.1.1',
285
+ 'address': '1.3.6.1.4.1.62675.1.2',
286
+ 'email': '1.3.6.1.4.1.62675.1.3',
287
+ 'phoneNumber': '1.3.6.1.4.1.62675.1.4'
288
+ };
289
+ /**
290
+ * ASN.1 Schema for Certificate KYC Attributes Extension
291
+ *
292
+ * KYCAttributes DEFINITIONS ::= BEGIN
293
+ * KYCAttributes ::= SEQUENCE OF Attribute
294
+ * Attribute ::= SEQUENCE {
295
+ * -- Name of the attribute
296
+ * name OBJECT IDENTIFIER,
297
+ * -- Value of this attribute
298
+ * value CHOICE {
299
+ * -- A plain value, not sensitive
300
+ * plainValue [0] IMPLICIT OCTET STRING,
301
+ * -- A sensitive value, encoded as a SensitiveAttribute in DER encoding
302
+ * sensitiveValue [1] IMPLICIT OCTET STRING
303
+ * }
304
+ * }
305
+ * END
306
+ *
307
+ * https://keeta.notion.site/Keeta-KYC-Certificate-Extensions-13e5da848e588042bdcef81fc40458b7
308
+ *
309
+ */
310
+ const CertificateKYCAttributeSchemaValidation = {
311
+ sequenceOf: [ASN1.ValidateASN1.IsOID, {
312
+ choice: [
313
+ { type: 'context', value: 0, kind: 'implicit', contains: ASN1.ValidateASN1.IsOctetString },
314
+ { type: 'context', value: 1, kind: 'implicit', contains: ASN1.ValidateASN1.IsOctetString }
315
+ ]
316
+ }]
317
+ };
318
+ export class CertificateBuilder extends KeetaNetClient.lib.Utils.Certificate.CertificateBuilder {
319
+ #attributes = {};
320
+ /**
321
+ * Map the parameters from the public interface to the internal
322
+ * (Certificate library) interface
323
+ */
324
+ static mapParams(params) {
325
+ const paramsCopy = { ...params };
326
+ let subjectPublicKey;
327
+ if (paramsCopy.subject) {
328
+ subjectPublicKey = paramsCopy.subject;
329
+ delete (paramsCopy.subject);
330
+ }
331
+ const retval = paramsCopy;
332
+ if (subjectPublicKey) {
333
+ retval.subjectPublicKey = subjectPublicKey;
334
+ }
335
+ return (retval);
336
+ }
337
+ constructor(params) {
338
+ super(CertificateBuilder.mapParams(params));
339
+ }
340
+ /**
341
+ * Set a KYC Attribute to a given value
342
+ */
343
+ setAttribute(name, sensitive, value) {
344
+ this.#attributes[name] = { sensitive, value };
345
+ }
346
+ async addExtensions(...args) {
347
+ const retval = await super.addExtensions(...args);
348
+ const subject = args[0].subjectPublicKey;
349
+ /* Encode the attributes */
350
+ const certAttributes = [];
351
+ for (const [name, attribute] of Object.entries(this.#attributes)) {
352
+ if (!(name in CertificateAttributeOIDDB)) {
353
+ throw (new Error(`Unknown attribute: ${name}`));
354
+ }
355
+ /*
356
+ * Since we are iteratively building the certificate, we
357
+ * can assume that the attribute is always present in
358
+ * the object
359
+ */
360
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
361
+ const nameOID = CertificateAttributeOIDDB[name];
362
+ let value;
363
+ if (attribute.sensitive) {
364
+ const sensitiveAttribute = new SensitiveAttributeBuilder(subject, attribute.value);
365
+ value = Buffer.from(await sensitiveAttribute.build());
366
+ }
367
+ else {
368
+ if (typeof attribute.value === 'string') {
369
+ value = Buffer.from(attribute.value, 'utf-8');
370
+ }
371
+ else {
372
+ value = Buffer.from(attribute.value);
373
+ }
374
+ }
375
+ certAttributes.push([{
376
+ type: 'oid',
377
+ oid: nameOID
378
+ }, {
379
+ type: 'context',
380
+ kind: 'implicit',
381
+ value: attribute.sensitive ? 1 : 0,
382
+ contains: value
383
+ }]);
384
+ }
385
+ if (certAttributes.length > 0) {
386
+ retval.push(KeetaNetClient.lib.Utils.Certificate.CertificateBuilder.extension('1.3.6.1.4.1.62675.0.0', certAttributes));
387
+ }
388
+ return (retval);
389
+ }
390
+ /**
391
+ * Create a Certificate object from the builder
392
+ *
393
+ * The parameters passed in are merged with the parameters passed in
394
+ * when constructing the builder
395
+ */
396
+ async build(params) {
397
+ const paramsCopy = CertificateBuilder.mapParams(params);
398
+ const certificate = await super.buildDER(paramsCopy);
399
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
400
+ const certificateObject = new Certificate(certificate, {
401
+ /**
402
+ * Specify the moment as `null` to avoid validation
403
+ * of the certificate's validity period. We don't
404
+ * care if the certificate is expired or not for
405
+ * the purposes of this builder.
406
+ */
407
+ moment: null
408
+ });
409
+ return (certificateObject);
410
+ }
411
+ }
412
+ export class Certificate extends KeetaNetClient.lib.Utils.Certificate.Certificate {
413
+ subjectKey;
414
+ static Builder = CertificateBuilder;
415
+ /**
416
+ * User KYC Attributes
417
+ */
418
+ attributes = {};
419
+ constructor(input, options) {
420
+ super(input, options);
421
+ this.subjectKey = options?.subjectKey ?? this.subjectPublicKey;
422
+ super.finalizeConstruction();
423
+ }
424
+ finalizeConstruction() {
425
+ /* Do nothing, we call the super method in the constructor */
426
+ }
427
+ processExtension(id, value) {
428
+ if (super.processExtension(id, value)) {
429
+ return (true);
430
+ }
431
+ if (id === '1.3.6.1.4.1.62675.0.0') {
432
+ const attributesRaw = new ASN1.BufferStorageASN1(value, CertificateKYCAttributeSchemaValidation).getASN1();
433
+ for (const attribute of attributesRaw) {
434
+ const name = lookupByOID(attribute[0].oid, CertificateAttributeOIDDB);
435
+ const valueKind = attribute[1].value;
436
+ const value = bufferToArrayBuffer(attribute[1].contains);
437
+ switch (valueKind) {
438
+ case 0:
439
+ /* Plain Value */
440
+ this.attributes[name] = { sensitive: false, value: value };
441
+ break;
442
+ case 1:
443
+ /* Sensitive Value */
444
+ this.attributes[name] = {
445
+ sensitive: true,
446
+ value: new SensitiveAttribute(this.subjectKey, value)
447
+ };
448
+ break;
449
+ default:
450
+ assertNever(valueKind);
451
+ }
452
+ }
453
+ return (true);
454
+ }
455
+ return (false);
456
+ }
457
+ }
458
+ /** @internal */
459
+ export const _Testing = {
460
+ SensitiveAttributeBuilder,
461
+ SensitiveAttribute
462
+ };
463
+ //# sourceMappingURL=certificates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certificates.js","sourceRoot":"","sources":["../../src/lib/certificates.ts"],"names":[],"mappings":"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","sourcesContent":["import * as KeetaNetClient from '@keetanetwork/keetanet-client';\nimport * as ASN1 from './utils/asn1.js';\nimport { Buffer } from './utils/buffer.js';\nimport crypto from './utils/crypto.js';\nimport { assertNever } from './utils/never.js';\n\n/* ENUM */\ntype AccountKeyAlgorithm = InstanceType<typeof KeetaNetClient.lib.Account>['keyType'];\n\n/**\n * An alias for the KeetaNetAccount type\n */\ntype KeetaNetAccount = ReturnType<typeof KeetaNetClient.lib.Account.fromSeed<AccountKeyAlgorithm>>;\n\n/* -----MOVE TO NODE AND ASN1NAPIRS----- */\nfunction getOID(name: string, oidDB: { [name: string]: string }) {\n\tif (name in oidDB) {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\tconst oid = oidDB[name as keyof typeof oidDB];\n\t\tif (oid === undefined) {\n\t\t\tthrow(new Error('internal error: OID was undefined'));\n\t\t}\n\n\t\treturn(oid);\n\t} else {\n\t\tthrow(new Error('Unknown algorithm'));\n\t}\n}\n\nfunction lookupByOID(oid: string, oidDB: { [name: string]: string }) {\n\tfor (const [key, value] of Object.entries(oidDB)) {\n\t\tif (key === oid) {\n\t\t\treturn(key);\n\t\t}\n\n\t\tif (value === oid) {\n\t\t\treturn(key);\n\t\t}\n\t}\n\n\tthrow(new Error(`Unknown OID: ${oid}`));\n}\n/* -----END MOVE TO NODE AND ASN1NAPIRS----- */\n\nfunction toJSON(data: unknown): unknown {\n\tconst retval: unknown = JSON.parse(JSON.stringify(data, function(key, convertedValue: unknown) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\tconst value: unknown = this[key];\n\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tif ('publicKeyString' in value && typeof value.publicKeyString === 'object' && value.publicKeyString !== null) {\n\t\t\t\tif ('get' in value.publicKeyString && typeof value.publicKeyString.get === 'function') {\n\t\t\t\t\t/*\n\t\t\t\t\t * If the value has a publicKeyString property that is an\n\t\t\t\t\t * object with a get method, we assume it is a KeetaNetAccount\n\t\t\t\t\t * or similar object and we return the public key string\n\t\t\t\t\t */\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call\n\t\t\t\t\tconst publicKeyString: unknown = value.publicKeyString.get();\n\t\t\t\t\tif (typeof publicKeyString === 'string') {\n\t\t\t\t\t\treturn(publicKeyString);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (Buffer.isBuffer(value)) {\n\t\t\treturn(value.toString('base64'));\n\t\t}\n\t\tif (typeof value === 'bigint') {\n\t\t\treturn(value.toString());\n\t\t}\n\n\t\treturn(convertedValue);\n\t}));\n\n\treturn(retval);\n}\n\n/*\n * Because our public interfaces are ArrayBuffers we often need to convert\n * Buffers to ArrayBuffers -- an alias to the Node function to do that\n */\nconst bufferToArrayBuffer = KeetaNetClient.lib.Utils.Helper.bufferToArrayBuffer.bind(KeetaNetClient.lib.Utils.Helper);\n\n/**\n * Sensitive Attribute Schema\n *\n * ASN.1 Schema:\n * SensitiveAttributes DEFINITIONS ::= BEGIN\n * SensitiveAttribute ::= SEQUENCE {\n * version INTEGER { v1(0) },\n * cipher SEQUENCE {\n * algorithm OBJECT IDENTIFIER,\n * ivOrNonce OCTET STRING,\n * key OCTET STRING\n * },\n * hashedValue SEQUENCE {\n * encryptedSalt OCTET STRING,\n * algorithm OBJECT IDENTIFIER,\n * value OCTET STRING\n * },\n * encryptedValue OCTET STRING\n * }\n * END\n *\n * https://keeta.notion.site/Keeta-KYC-Certificate-Extensions-13e5da848e588042bdcef81fc40458b7\n *\n * @internal\n */\nconst SensitiveAttributeSchemaInternal: [\n\tversion: 0n,\n\tcipher: [\n\t\talgorithm: typeof ASN1.ValidateASN1.IsOID,\n\t\tiv: typeof ASN1.ValidateASN1.IsOctetString,\n\t\tkey: typeof ASN1.ValidateASN1.IsOctetString\n\t],\n\thashedValue: [\n\t\tencryptedSalt: typeof ASN1.ValidateASN1.IsOctetString,\n\t\talgorithm: typeof ASN1.ValidateASN1.IsOID,\n\t\tvalue: typeof ASN1.ValidateASN1.IsOctetString\n\t],\n\tencryptedValue: typeof ASN1.ValidateASN1.IsOctetString\n] = [\n\t0n,\n\t[\n\t\tASN1.ValidateASN1.IsOID,\n\t\tASN1.ValidateASN1.IsOctetString,\n\t\tASN1.ValidateASN1.IsOctetString\n\t],\n\t[\n\t\tASN1.ValidateASN1.IsOctetString,\n\t\tASN1.ValidateASN1.IsOID,\n\t\tASN1.ValidateASN1.IsOctetString\n\t],\n\tASN1.ValidateASN1.IsOctetString\n];\n\n/**\n * The Sensitive Attribute Schema\n *\n * @internal\n */\ntype SensitiveAttributeSchema = ASN1.SchemaMap<typeof SensitiveAttributeSchemaInternal>;\n\n/*\n * Database of permitted algorithms and their OIDs\n */\nconst sensitiveAttributeOIDDB = {\n\t'aes-256-gcm': '2.16.840.1.101.3.4.1.46',\n\t'aes-256-cbc': '2.16.840.1.101.3.4.1.42',\n\t'sha2-256': '2.16.840.1.101.3.4.2.1',\n\t'sha3-256': '2.16.840.1.101.3.4.2.8'\n};\n\nclass SensitiveAttributeBuilder {\n\treadonly #account: KeetaNetAccount;\n\t#value: Buffer | undefined;\n\n\tconstructor(account: KeetaNetAccount, value?: Buffer | ArrayBuffer | string) {\n\t\tthis.#account = account;\n\n\t\tif (value) {\n\t\t\tthis.set(value);\n\t\t}\n\t}\n\n\tset(value: Buffer | ArrayBuffer | string) {\n\t\tif (Buffer.isBuffer(value)) {\n\t\t\tthis.#value = value;\n\t\t} else if (typeof value === 'string') {\n\t\t\tthis.#value = Buffer.from(value, 'utf-8');\n\t\t} else {\n\t\t\tthis.#value = Buffer.from(value);\n\t\t}\n\n\t\treturn(this);\n\t}\n\n\tasync build() {\n\t\tif (this.#value === undefined) {\n\t\t\tthrow(new Error('Value not set'));\n\t\t}\n\n\t\tconst salt = crypto.randomBytes(32);\n\n\t\tconst hashingAlgorithm = KeetaNetClient.lib.Utils.Hash.HashFunctionName;\n\t\tconst publicKey = Buffer.from(this.#account.publicKey.get());\n\n\t\tconst cipher = 'aes-256-gcm';\n\t\tconst key = crypto.randomBytes(32);\n\t\tconst nonce = crypto.randomBytes(12);\n\t\tconst encryptedKey = await this.#account.encrypt(key);\n\n\t\tfunction encrypt(value: Buffer) {\n\t\t\tconst cipherObject = crypto.createCipheriv(cipher, key, nonce);\n\t\t\tlet retval = cipherObject.update(value);\n\t\t\tretval = Buffer.concat([retval, cipherObject.final()]);\n\t\t\treturn(retval);\n\t\t}\n\n\t\tconst encryptedValue = encrypt(this.#value);\n\t\tconst encryptedSalt = encrypt(salt);\n\n\t\tconst saltedValue = Buffer.concat([salt, publicKey, encryptedValue, this.#value]);\n\t\tconst hashedAndSaltedValue = KeetaNetClient.lib.Utils.Hash.Hash(saltedValue);\n\n\t\tconst attributeStructure: SensitiveAttributeSchema = [\n\t\t\t/* Version */\n\t\t\t0n,\n\t\t\t/* Cipher Details */\n\t\t\t[\n\t\t\t\t/* Algorithm */\n\t\t\t\t{ type: 'oid', oid: getOID(cipher, sensitiveAttributeOIDDB) },\n\t\t\t\t/* IV or Nonce */\n\t\t\t\tnonce,\n\t\t\t\t/* Symmetric key, encrypted with the public key of the account */\n\t\t\t\tBuffer.from(encryptedKey)\n\t\t\t],\n\t\t\t/* Hashed Value */\n\t\t\t[\n\t\t\t\t/* Encrypted Salt */\n\t\t\t\tBuffer.from(encryptedSalt),\n\t\t\t\t/* Hashing Algorithm */\n\t\t\t\t{ type: 'oid', oid: getOID(hashingAlgorithm, sensitiveAttributeOIDDB) },\n\t\t\t\t/* Hash of <Encrypted Salt> || <Public Key> || <Value> */\n\t\t\t\tBuffer.from(hashedAndSaltedValue)\n\t\t\t],\n\t\t\t/* Encrypted Value, encrypted with the Cipher above */\n\t\t\tencryptedValue\n\t\t];\n\t\tconst encodedAttributeObject = ASN1.JStoASN1(attributeStructure);\n\n\t\tconst retval = encodedAttributeObject.toBER();\n\n\t\treturn(retval);\n\t}\n}\n\nclass SensitiveAttribute {\n\treadonly #account: KeetaNetAccount;\n\treadonly #info: ReturnType<SensitiveAttribute['decode']>;\n\n\tconstructor(account: KeetaNetAccount, data: Buffer | ArrayBuffer) {\n\t\tthis.#account = account;\n\t\tthis.#info = this.decode(data);\n\t}\n\n\tprivate decode(data: Buffer | ArrayBuffer) {\n\t\tif (Buffer.isBuffer(data)) {\n\t\t\tdata = bufferToArrayBuffer(data);\n\t\t}\n\n\t\tconst dataObject = new ASN1.BufferStorageASN1(data, SensitiveAttributeSchemaInternal);\n\t\tconst decodedAttribute = dataObject.getASN1();\n\n\t\tconst decodedVersion = decodedAttribute[0] + 1n;\n\t\tif (decodedVersion !== 1n) {\n\t\t\tthrow(new Error(`Unsupported Sensitive Attribute version (${decodedVersion})`));\n\t\t}\n\n\t\treturn({\n\t\t\tversion: decodedVersion,\n\t\t\tpublicKey: this.#account.publicKeyString.get(),\n\t\t\tcipher: {\n\t\t\t\talgorithm: lookupByOID(decodedAttribute[1][0].oid, sensitiveAttributeOIDDB),\n\t\t\t\tiv: decodedAttribute[1][1],\n\t\t\t\tkey: decodedAttribute[1][2]\n\t\t\t},\n\t\t\thashedValue: {\n\t\t\t\tencryptedSalt: decodedAttribute[2][0],\n\t\t\t\talgorithm: lookupByOID(decodedAttribute[2][1].oid, sensitiveAttributeOIDDB),\n\t\t\t\tvalue: decodedAttribute[2][2]\n\t\t\t},\n\t\t\tencryptedValue: decodedAttribute[3]\n\t\t});\n\t}\n\n\tasync #decryptValue(value: Buffer) {\n\t\tconst decryptedKey = await this.#account.decrypt(this.#info.cipher.key);\n\t\tconst algorithm = this.#info.cipher.algorithm;\n\t\tconst iv = this.#info.cipher.iv;\n\n\t\tconst cipher = crypto.createDecipheriv(algorithm, Buffer.from(decryptedKey), iv);\n\t\tconst decryptedValue = cipher.update(value);\n\n\t\treturn(decryptedValue);\n\t}\n\n\t/**\n\t * Get the value of the sensitive attribute\n\t *\n\t * This will decrypt the value using the account's private key\n\t * and return the value as an ArrayBuffer\n\t *\n\t * Since sensitive attributes are binary blobs, this returns an\n\t * ArrayBuffer\n\t */\n\tasync get(): Promise<ArrayBuffer> {\n\t\tconst decryptedValue = await this.#decryptValue(this.#info.encryptedValue);\n\n\t\treturn(bufferToArrayBuffer(decryptedValue));\n\t}\n\n\t/**\n\t * Get the value of the sensitive attribute as a string after being\n\t * interpreted as UTF-8 ( @see SensitiveAttribute.get for more information)\n\t */\n\tasync getString(): Promise<string> {\n\t\tconst value = await this.get();\n\t\treturn(Buffer.from(value).toString('utf-8'));\n\t}\n\n\t/**\n\t * Generate a proof that a sensitive attribute is a given value,\n\t * which can be validated by a third party using the certificate\n\t * and the `validateProof` method\n\t */\n\tasync proove(): Promise<{ value: string; hash: { salt: string }}> {\n\t\tconst value = await this.get();\n\t\tconst salt = await this.#decryptValue(this.#info.hashedValue.encryptedSalt);\n\n\t\treturn({\n\t\t\tvalue: Buffer.from(value).toString('base64'),\n\t\t\thash: {\n\t\t\t\tsalt: salt.toString('base64')\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Validate the proof that a sensitive attribute is a given value\n\t */\n\tasync validateProof(proof: Awaited<ReturnType<this['proove']>>): Promise<boolean> {\n\t\tconst plaintextValue = Buffer.from(proof.value, 'base64');\n\t\tconst proofSaltBuffer = Buffer.from(proof.hash.salt, 'base64');\n\n\t\tconst publicKeyBuffer = Buffer.from(this.#account.publicKey.get());\n\t\tconst encryptedValue = this.#info.encryptedValue;\n\n\t\tconst hashedAndSaltedValue = KeetaNetClient.lib.Utils.Hash.Hash(Buffer.concat([proofSaltBuffer, publicKeyBuffer, encryptedValue, plaintextValue]));\n\t\tconst hashedAndSaltedValueBuffer = Buffer.from(hashedAndSaltedValue);\n\n\t\treturn(this.#info.hashedValue.value.equals(hashedAndSaltedValueBuffer));\n\t}\n\n\ttoJSON(): unknown/* XXX:TODO */ {\n\t\treturn(toJSON(this.#info));\n\t}\n}\n\n/**\n * Database of attributes\n */\nconst CertificateAttributeOIDDB = {\n\t'fullName': '1.3.6.1.4.1.62675.1.0',\n\t'dateOfBirth': '1.3.6.1.4.1.62675.1.1',\n\t'address': '1.3.6.1.4.1.62675.1.2',\n\t'email': '1.3.6.1.4.1.62675.1.3',\n\t'phoneNumber': '1.3.6.1.4.1.62675.1.4'\n};\ntype CertificateAttributeNames = keyof typeof CertificateAttributeOIDDB;\n\ntype BaseCertificateBuilderParams = NonNullable<ConstructorParameters<typeof KeetaNetClient.lib.Utils.Certificate.CertificateBuilder>[0]>;\ntype CertificateBuilderParams = Required<Pick<BaseCertificateBuilderParams, 'issuer' | 'validFrom' | 'validTo' | 'serial' | 'hashLib' | 'issuerDN' | 'subjectDN' | 'isCA'> & {\n\t/**\n\t * The key of the subject -- used for Sensitive Attributes as well\n\t * as the certificate Subject\n\t */\n\tsubject: BaseCertificateBuilderParams['subjectPublicKey'];\n}>;\n\n/**\n * ASN.1 Schema for Certificate KYC Attributes Extension\n *\n * KYCAttributes DEFINITIONS ::= BEGIN\n * KYCAttributes ::= SEQUENCE OF Attribute\n * Attribute ::= SEQUENCE {\n * -- Name of the attribute\n * name OBJECT IDENTIFIER,\n * -- Value of this attribute\n * value CHOICE {\n * -- A plain value, not sensitive\n * plainValue [0] IMPLICIT OCTET STRING,\n * -- A sensitive value, encoded as a SensitiveAttribute in DER encoding\n * sensitiveValue [1] IMPLICIT OCTET STRING\n * }\n * }\n * END\n *\n * https://keeta.notion.site/Keeta-KYC-Certificate-Extensions-13e5da848e588042bdcef81fc40458b7\n *\n */\nconst CertificateKYCAttributeSchemaValidation = {\n\tsequenceOf: [ASN1.ValidateASN1.IsOID, {\n\t\tchoice: [\n\t\t\t{ type: 'context' as const, value: 0 as const, kind: 'implicit' as const, contains: ASN1.ValidateASN1.IsOctetString },\n\t\t\t{ type: 'context' as const, value: 1 as const, kind: 'implicit' as const, contains: ASN1.ValidateASN1.IsOctetString }\n\t\t]\n\t}]\n} satisfies ASN1.Schema;\n\n/** @internal */\ntype CertificateKYCAttributeSchema = ASN1.SchemaMap<typeof CertificateKYCAttributeSchemaValidation>;\n\nexport class CertificateBuilder extends KeetaNetClient.lib.Utils.Certificate.CertificateBuilder {\n\treadonly #attributes: { [name: string]: { sensitive: boolean; value: ArrayBuffer | string }} = {};\n\n\t/**\n\t * Map the parameters from the public interface to the internal\n\t * (Certificate library) interface\n\t */\n\tprivate static mapParams(params?: Partial<CertificateBuilderParams>): Partial<BaseCertificateBuilderParams> {\n\t\tconst paramsCopy = { ...params };\n\t\tlet subjectPublicKey;\n\t\tif (paramsCopy.subject) {\n\t\t\tsubjectPublicKey = paramsCopy.subject;\n\t\t\tdelete(paramsCopy.subject);\n\t\t}\n\t\tconst retval: Partial<BaseCertificateBuilderParams> = paramsCopy;\n\t\tif (subjectPublicKey) {\n\t\t\tretval.subjectPublicKey = subjectPublicKey;\n\t\t}\n\t\treturn(retval);\n\t}\n\n\tconstructor(params?: Partial<CertificateBuilderParams>) {\n\t\tsuper(CertificateBuilder.mapParams(params));\n\t}\n\n\t/**\n\t * Set a KYC Attribute to a given value\n\t */\n\tsetAttribute(name: CertificateAttributeNames, sensitive: boolean, value: ArrayBuffer | string): void {\n\t\tthis.#attributes[name] = { sensitive, value };\n\t}\n\n\tprotected async addExtensions(...args: Parameters<InstanceType<typeof KeetaNetClient.lib.Utils.Certificate.CertificateBuilder>['addExtensions']>): ReturnType<InstanceType<typeof KeetaNetClient.lib.Utils.Certificate.CertificateBuilder>['addExtensions']> {\n\t\tconst retval = await super.addExtensions(...args);\n\n\t\tconst subject = args[0].subjectPublicKey;\n\n\t\t/* Encode the attributes */\n\t\tconst certAttributes: CertificateKYCAttributeSchema = [];\n\t\tfor (const [name, attribute] of Object.entries(this.#attributes)) {\n\t\t\tif (!(name in CertificateAttributeOIDDB)) {\n\t\t\t\tthrow(new Error(`Unknown attribute: ${name}`));\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Since we are iteratively building the certificate, we\n\t\t\t * can assume that the attribute is always present in\n\t\t\t * the object\n\t\t\t */\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tconst nameOID = CertificateAttributeOIDDB[name as keyof typeof CertificateAttributeOIDDB];\n\n\t\t\tlet value: Buffer;\n\t\t\tif (attribute.sensitive) {\n\t\t\t\tconst sensitiveAttribute = new SensitiveAttributeBuilder(subject, attribute.value);\n\t\t\t\tvalue = Buffer.from(await sensitiveAttribute.build());\n\t\t\t} else {\n\t\t\t\tif (typeof attribute.value === 'string') {\n\t\t\t\t\tvalue = Buffer.from(attribute.value, 'utf-8');\n\t\t\t\t} else {\n\t\t\t\t\tvalue = Buffer.from(attribute.value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcertAttributes.push([{\n\t\t\t\ttype: 'oid',\n\t\t\t\toid: nameOID\n\t\t\t}, {\n\t\t\t\ttype: 'context',\n\t\t\t\tkind: 'implicit',\n\t\t\t\tvalue: attribute.sensitive ? 1 : 0,\n\t\t\t\tcontains: value\n\t\t\t}]);\n\t\t}\n\n\t\tif (certAttributes.length > 0) {\n\t\t\tretval.push(\n\t\t\t\tKeetaNetClient.lib.Utils.Certificate.CertificateBuilder.extension('1.3.6.1.4.1.62675.0.0', certAttributes)\n\t\t\t);\n\t\t}\n\n\t\treturn(retval);\n\t}\n\n\t/**\n\t * Create a Certificate object from the builder\n\t *\n\t * The parameters passed in are merged with the parameters passed in\n\t * when constructing the builder\n\t */\n\tasync build(params?: Partial<CertificateBuilderParams>): Promise<Certificate> {\n\t\tconst paramsCopy = CertificateBuilder.mapParams(params);\n\t\tconst certificate = await super.buildDER(paramsCopy);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\tconst certificateObject = new Certificate(certificate, {\n\t\t\t/**\n\t\t\t * Specify the moment as `null` to avoid validation\n\t\t\t * of the certificate's validity period. We don't\n\t\t\t * care if the certificate is expired or not for\n\t\t\t * the purposes of this builder.\n\t\t\t */\n\t\t\tmoment: null\n\t\t});\n\n\t\treturn(certificateObject);\n\t}\n}\n\nexport class Certificate extends KeetaNetClient.lib.Utils.Certificate.Certificate {\n\tprivate readonly subjectKey: KeetaNetAccount;\n\tstatic readonly Builder: typeof CertificateBuilder = CertificateBuilder;\n\n\t/**\n\t * User KYC Attributes\n\t */\n\treadonly attributes: {\n\t\t[name: string]: {\n\t\t\tsensitive: true;\n\t\t\tvalue: SensitiveAttribute;\n\t\t} | {\n\t\t\tsensitive: false;\n\t\t\tvalue: ArrayBuffer;\n\t\t}\n\t} = {};\n\n\tconstructor(input: ConstructorParameters<typeof KeetaNetClient.lib.Utils.Certificate.Certificate>[0], options?: ConstructorParameters<typeof KeetaNetClient.lib.Utils.Certificate.Certificate>[1] & { subjectKey?: KeetaNetAccount }) {\n\t\tsuper(input, options);\n\n\t\tthis.subjectKey = options?.subjectKey ?? this.subjectPublicKey;\n\n\t\tsuper.finalizeConstruction();\n\t}\n\n\tprotected finalizeConstruction(): void {\n\t\t/* Do nothing, we call the super method in the constructor */\n\t}\n\n\tprotected processExtension(id: string, value: ArrayBuffer): boolean {\n\t\tif (super.processExtension(id, value)) {\n\t\t\treturn(true);\n\t\t}\n\n\t\tif (id === '1.3.6.1.4.1.62675.0.0') {\n\t\t\tconst attributesRaw = new ASN1.BufferStorageASN1(value, CertificateKYCAttributeSchemaValidation).getASN1();\n\n\t\t\tfor (const attribute of attributesRaw) {\n\t\t\t\tconst name = lookupByOID(attribute[0].oid, CertificateAttributeOIDDB);\n\t\t\t\tconst valueKind = attribute[1].value;\n\t\t\t\tconst value = bufferToArrayBuffer(attribute[1].contains);\n\n\t\t\t\tswitch (valueKind) {\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\t/* Plain Value */\n\t\t\t\t\t\tthis.attributes[name] = { sensitive: false, value: value };\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t/* Sensitive Value */\n\t\t\t\t\t\tthis.attributes[name] = {\n\t\t\t\t\t\t\tsensitive: true,\n\t\t\t\t\t\t\tvalue: new SensitiveAttribute(this.subjectKey, value)\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tassertNever(valueKind);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn(true);\n\t\t}\n\n\t\treturn(false);\n\t}\n}\n\n/** @internal */\nexport const _Testing = {\n\tSensitiveAttributeBuilder,\n\tSensitiveAttribute\n};\n"]}
@@ -0,0 +1,106 @@
1
+ import { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';
2
+ import { Buffer } from './utils/buffer.js';
3
+ declare const Account: typeof KeetaNetLib.Account;
4
+ type Account = InstanceType<typeof KeetaNetLib.Account>;
5
+ type CipherOptions = {
6
+ /**
7
+ * The symmetric cipher key (if any)
8
+ */
9
+ cipherKey: Buffer | undefined;
10
+ /**
11
+ * The symmetric cipher IV (if any)
12
+ */
13
+ cipherIV: Buffer | undefined;
14
+ /**
15
+ * The symmetric cipher algorithm
16
+ */
17
+ cipherAlgo: string;
18
+ };
19
+ type EncryptedContainerInfo = Pick<CipherOptions, 'cipherAlgo'> & {
20
+ /**
21
+ * Set of accounts which can access the data
22
+ */
23
+ principals: Account[];
24
+ };
25
+ type UnencryptedContainerInfo = {
26
+ /**
27
+ * Unencrypted container should not have any principals
28
+ */
29
+ principals: null;
30
+ };
31
+ export declare class EncryptedContainer {
32
+ #private;
33
+ private static readonly algorithm;
34
+ /**
35
+ * Encryption details
36
+ */
37
+ protected _internalState: EncryptedContainerInfo | UnencryptedContainerInfo;
38
+ constructor(principals: Account[] | null);
39
+ get encrypted(): boolean;
40
+ /**
41
+ * Create an instance of the EncryptedContainer from an encrypted blob,
42
+ * it will need to be decryptable with one of the specified principals
43
+ *
44
+ * After decryption happens, the list of principals with access to the
45
+ * resource will be reset to what is contained within the encrypted
46
+ * container
47
+ */
48
+ static fromEncryptedBuffer(data: Buffer, principals: Account[]): EncryptedContainer;
49
+ static fromEncodedBuffer(data: Buffer, principals: Account[] | null): EncryptedContainer;
50
+ /**
51
+ * Create an instance of the EncryptedContainer from a plaintext.
52
+ *
53
+ * It will be decryptable by any one of the specified principals
54
+ *
55
+ * @param data The plaintext data to encrypt or encode
56
+ * @param principals The list of principals who can access the data if it is null then the data is not encrypted
57
+ * @param locked If true, the plaintext data will not be accessible from this instance; otherwise it will be -- default depends on principals
58
+ * @returns The EncryptedContainer instance with the plaintext data and principals set
59
+ */
60
+ static fromPlaintext(data: string | Buffer, principals: Account[] | null, locked?: boolean): EncryptedContainer;
61
+ /**
62
+ * Set the plaintext buffer to the specified value
63
+ */
64
+ setPlaintext(data: string | Buffer): void;
65
+ private get _encoded();
66
+ private get _plaintext();
67
+ /**
68
+ * Grant access to the secret for account(s) synchronously. This
69
+ * assumes the plaintext has already been computed and will fail
70
+ * if it is not
71
+ */
72
+ grantAccessSync(accounts: Account[] | Account): void;
73
+ /**
74
+ * Grant access to the secret for account(s).
75
+ */
76
+ grantAccess(accounts: Account[] | Account): Promise<void>;
77
+ /**
78
+ * Revoke access to the secret for an account synchronously. This
79
+ * assumes the plaintext has already been computed and will fail
80
+ * if it is not
81
+ */
82
+ revokeAccessSync(account: Account): void;
83
+ /**
84
+ * Revoke access to the secret for an account
85
+ */
86
+ revokeAccess(account: Account): Promise<void>;
87
+ /**
88
+ * Disable access to the plaintext from this instance
89
+ */
90
+ disablePlaintext(): void;
91
+ /**
92
+ * Get the plaintext for this instance
93
+ */
94
+ getPlaintext(): Promise<Buffer>;
95
+ /**
96
+ * Get the serializable buffer which can be stored and reconstructed
97
+ */
98
+ getEncodedBuffer(): Promise<Buffer>;
99
+ /**
100
+ * Get the list of accounts which have access to read the plaintext of
101
+ * this container
102
+ */
103
+ get principals(): Account[];
104
+ }
105
+ export default EncryptedContainer;
106
+ //# sourceMappingURL=encrypted-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypted-container.d.ts","sourceRoot":"","sources":["../../src/lib/encrypted-container.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAKnE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAO3C,QAAA,MAAM,OAAO,EAAE,OAAO,WAAW,CAAC,OAA6B,CAAC;AAChE,KAAK,OAAO,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AA0FxD,KAAK,aAAa,GAAG;IACpB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACnB,CAAA;AA0TD,KAAK,sBAAsB,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG;IACjE;;OAEG;IACH,UAAU,EAAE,OAAO,EAAE,CAAC;CACtB,CAAA;AAED,KAAK,wBAAwB,GAAG;IAC/B;;OAEG;IACH,UAAU,EAAE,IAAI,CAAC;CACjB,CAAA;AAED,qBAAa,kBAAkB;;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAOlD;;OAEG;IACH,SAAS,CAAC,cAAc,EAAE,sBAAsB,GAAG,wBAAwB,CAAC;gBAUhE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAI;IAcxC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAMD;;;;;;;OAOG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,kBAAkB;IASnF,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAI,GAAG,kBAAkB;IASxF;;;;;;;;;OASG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,kBAAkB;IAmB/G;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAezC,OAAO,KAAK,QAAQ,GAMnB;IAED,OAAO,KAAK,UAAU,GAMrB;IA8JD;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,GAAG,IAAI;IAmBpD;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/D;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAiBxC;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAIxB;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAmBrC;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAezC;;;OAGG;IACH,IAAI,UAAU,IAAI,OAAO,EAAE,CAM1B;CACD;AAQD,eAAe,kBAAkB,CAAC"}