@opentdf/sdk 0.3.0 → 0.3.2-beta.2277

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 (37) hide show
  1. package/dist/cjs/src/access.js +46 -1
  2. package/dist/cjs/src/nanotdf/Client.js +12 -6
  3. package/dist/cjs/src/opentdf.js +37 -6
  4. package/dist/cjs/src/version.js +1 -1
  5. package/dist/cjs/tdf3/src/assertions.js +5 -5
  6. package/dist/cjs/tdf3/src/client/index.js +20 -11
  7. package/dist/cjs/tdf3/src/tdf.js +19 -6
  8. package/dist/types/src/access.d.ts +1 -0
  9. package/dist/types/src/access.d.ts.map +1 -1
  10. package/dist/types/src/nanotdf/Client.d.ts +3 -1
  11. package/dist/types/src/nanotdf/Client.d.ts.map +1 -1
  12. package/dist/types/src/opentdf.d.ts +5 -1
  13. package/dist/types/src/opentdf.d.ts.map +1 -1
  14. package/dist/types/src/version.d.ts +1 -1
  15. package/dist/types/tdf3/src/assertions.d.ts +1 -1
  16. package/dist/types/tdf3/src/assertions.d.ts.map +1 -1
  17. package/dist/types/tdf3/src/client/index.d.ts +8 -3
  18. package/dist/types/tdf3/src/client/index.d.ts.map +1 -1
  19. package/dist/types/tdf3/src/models/manifest.d.ts +1 -1
  20. package/dist/types/tdf3/src/models/manifest.d.ts.map +1 -1
  21. package/dist/types/tdf3/src/tdf.d.ts.map +1 -1
  22. package/dist/web/src/access.js +45 -1
  23. package/dist/web/src/nanotdf/Client.js +13 -7
  24. package/dist/web/src/opentdf.js +38 -7
  25. package/dist/web/src/version.js +1 -1
  26. package/dist/web/tdf3/src/assertions.js +5 -5
  27. package/dist/web/tdf3/src/client/index.js +21 -12
  28. package/dist/web/tdf3/src/tdf.js +19 -6
  29. package/package.json +1 -1
  30. package/src/access.ts +48 -0
  31. package/src/nanotdf/Client.ts +22 -6
  32. package/src/opentdf.ts +58 -8
  33. package/src/version.ts +1 -1
  34. package/tdf3/src/assertions.ts +4 -4
  35. package/tdf3/src/client/index.ts +30 -11
  36. package/tdf3/src/models/manifest.ts +2 -1
  37. package/tdf3/src/tdf.ts +27 -10
@@ -39,6 +39,7 @@ import {
39
39
  EncryptParamsBuilder,
40
40
  } from './builders.js';
41
41
  import {
42
+ fetchKeyAccessServers,
42
43
  type KasPublicKeyInfo,
43
44
  keyAlgorithmToPublicKeyAlgorithm,
44
45
  OriginAllowList,
@@ -125,7 +126,7 @@ export interface ClientConfig {
125
126
  clientId?: string;
126
127
  dpopEnabled?: boolean;
127
128
  dpopKeys?: Promise<CryptoKeyPair>;
128
- kasEndpoint?: string;
129
+ kasEndpoint: string;
129
130
  /**
130
131
  * Service to use to look up ABAC. Used during autoconfigure. Defaults to
131
132
  * kasEndpoint without the trailing `/kas` path segment, if present.
@@ -133,9 +134,11 @@ export interface ClientConfig {
133
134
  policyEndpoint?: string;
134
135
  /**
135
136
  * List of allowed KASes to connect to for rewrap requests.
136
- * Defaults to `[kasEndpoint]`.
137
+ * Defaults to `[]`.
137
138
  */
138
139
  allowedKases?: string[];
140
+ // Platform URL to use to lookup allowed KASes when allowedKases is empty
141
+ platformUrl?: string;
139
142
  ignoreAllowList?: boolean;
140
143
  easEndpoint?: string;
141
144
  // DEPRECATED Ignored
@@ -237,7 +240,12 @@ export class Client {
237
240
  * List of allowed KASes to connect to for rewrap requests.
238
241
  * Defaults to `[this.kasEndpoint]`.
239
242
  */
240
- readonly allowedKases: OriginAllowList;
243
+ readonly allowedKases?: OriginAllowList;
244
+
245
+ /**
246
+ * URL of the platform, required to fetch list of allowed KASes when allowedKases is empty
247
+ */
248
+ readonly platformUrl?: string;
241
249
 
242
250
  readonly kasKeys: Record<string, Promise<KasPublicKeyInfo>[]> = {};
243
251
 
@@ -287,6 +295,14 @@ export class Client {
287
295
  this.kasEndpoint = clientConfig.keyRewrapEndpoint.replace(/\/rewrap$/, '');
288
296
  }
289
297
  this.kasEndpoint = rstrip(this.kasEndpoint, '/');
298
+
299
+ if (!validateSecureUrl(this.kasEndpoint)) {
300
+ throw new ConfigurationError(`Invalid KAS endpoint [${this.kasEndpoint}]`);
301
+ }
302
+ if (config.platformUrl) {
303
+ this.platformUrl = config.platformUrl;
304
+ }
305
+
290
306
  if (clientConfig.policyEndpoint) {
291
307
  this.policyEndpoint = rstrip(clientConfig.policyEndpoint, '/');
292
308
  } else if (this.kasEndpoint.endsWith('/kas')) {
@@ -299,16 +315,12 @@ export class Client {
299
315
  clientConfig.allowedKases,
300
316
  !!clientConfig.ignoreAllowList
301
317
  );
302
- if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.allows(kasOrigin)) {
303
- throw new ConfigurationError(`Invalid KAS endpoint [${this.kasEndpoint}]`);
304
- }
305
- } else {
306
- if (!validateSecureUrl(this.kasEndpoint)) {
318
+ if (!this.allowedKases.allows(kasOrigin)) {
319
+ // TODO PR: ask if in this cases it makes more sense to add defaultKASEndpoint to the allow list if the allowList is not empty but doesn't have the defaultKas
307
320
  throw new ConfigurationError(
308
- `Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases`
321
+ `Invalid KAS endpoint [${this.kasEndpoint}]. When allowedKases is set, defaultKASEndpoint needs to be in the allow list`
309
322
  );
310
323
  }
311
- this.allowedKases = new OriginAllowList([kasOrigin], !!clientConfig.ignoreAllowList);
312
324
  }
313
325
 
314
326
  this.authProvider = config.authProvider;
@@ -381,6 +393,7 @@ export class Client {
381
393
  windowSize = DEFAULT_SEGMENT_SIZE,
382
394
  keyMiddleware = defaultKeyMiddleware,
383
395
  streamMiddleware = async (stream: DecoratedReadableStream) => stream,
396
+ tdfSpecVersion,
384
397
  wrappingKeyAlgorithm = 'rsa:2048',
385
398
  } = opts;
386
399
  const scope = opts.scope ?? { attributes: [], dissem: [] };
@@ -444,6 +457,7 @@ export class Client {
444
457
  ? maxByteLimit
445
458
  : opts.byteLimit;
446
459
  const encryptionInformation = new SplitKey(new AesGcmCipher(this.cryptoService));
460
+ // TODO KAS: check here
447
461
  const splits: SplitStep[] = splitPlan?.length
448
462
  ? splitPlan
449
463
  : [{ kas: opts.defaultKASEndpoint ?? this.kasEndpoint }];
@@ -498,6 +512,7 @@ export class Client {
498
512
  keyForEncryption,
499
513
  keyForManifest,
500
514
  assertionConfigs: opts.assertionConfigs,
515
+ tdfSpecVersion,
501
516
  };
502
517
 
503
518
  return (streamMiddleware as EncryptStreamMiddleware)(await writeStream(ecfg));
@@ -529,8 +544,12 @@ export class Client {
529
544
  throw new ConfigurationError('AuthProvider missing');
530
545
  }
531
546
  const chunker = await makeChunkable(source);
532
- if (!allowList) {
547
+ if (!allowList && this.allowedKases) {
533
548
  allowList = this.allowedKases;
549
+ } else if (this.platformUrl) {
550
+ allowList = await fetchKeyAccessServers(this.platformUrl, this.authProvider);
551
+ } else {
552
+ throw new ConfigurationError('platformUrl is required when allowedKases is empty');
534
553
  }
535
554
 
536
555
  // Await in order to catch any errors from this call.
@@ -6,7 +6,8 @@ export type Manifest = {
6
6
  payload: Payload;
7
7
  encryptionInformation: EncryptionInformation;
8
8
  assertions: Assertion[];
9
- schemaVersion: string;
9
+ // Required in later versions, optional prior to 4.3.0
10
+ schemaVersion?: string;
10
11
  // Deprecated
11
12
  tdf_spec_version?: string;
12
13
  };
package/tdf3/src/tdf.ts CHANGED
@@ -287,8 +287,8 @@ async function _generateManifest(
287
287
  keyInfo: KeyInfo,
288
288
  encryptionInformation: SplitKey,
289
289
  policy: Policy,
290
- mimeType: string | undefined,
291
- targetSpecVersion: string | undefined
290
+ mimeType?: string,
291
+ targetSpecVersion?: string
292
292
  ): Promise<Manifest> {
293
293
  // (maybe) Fields are quoted to avoid renaming
294
294
  const payload: Payload = {
@@ -301,13 +301,19 @@ async function _generateManifest(
301
301
 
302
302
  const encryptionInformationStr = await encryptionInformation.write(policy, keyInfo);
303
303
  const assertions: assertions.Assertion[] = [];
304
- return {
304
+ const partial = {
305
305
  payload,
306
306
  // generate the manifest first, then insert integrity information into it
307
307
  encryptionInformation: encryptionInformationStr,
308
308
  assertions: assertions,
309
- // when `targetSpecVersion` is provided, overrides the tdfSpecVersion
310
- schemaVersion: targetSpecVersion || tdfSpecVersion,
309
+ };
310
+ const schemaVersion = targetSpecVersion || tdfSpecVersion;
311
+ if (schemaVersion === '4.2.2') {
312
+ return partial;
313
+ }
314
+ return {
315
+ ...partial,
316
+ schemaVersion,
311
317
  };
312
318
  }
313
319
 
@@ -401,7 +407,7 @@ export async function writeStream(cfg: EncryptConfiguration): Promise<DecoratedR
401
407
  cfg.encryptionInformation,
402
408
  cfg.policy,
403
409
  cfg.mimeType,
404
- cfg.tdfSpecVersion ?? '4.3.0'
410
+ cfg.tdfSpecVersion
405
411
  );
406
412
 
407
413
  if (!manifest) {
@@ -531,10 +537,14 @@ export async function writeStream(cfg: EncryptConfiguration): Promise<DecoratedR
531
537
  alg: 'HS256',
532
538
  key: new Uint8Array(cfg.keyForEncryption.unwrappedKeyBinary.asArrayBuffer()),
533
539
  };
534
- const assertion = await assertions.CreateAssertion(aggregateHash, {
535
- ...assertionConfig,
536
- signingKey,
537
- });
540
+ const assertion = await assertions.CreateAssertion(
541
+ aggregateHash,
542
+ {
543
+ ...assertionConfig,
544
+ signingKey,
545
+ },
546
+ cfg.tdfSpecVersion
547
+ );
538
548
 
539
549
  // Add signed assertion to the signedAssertions array
540
550
  signedAssertions.push(assertion);
@@ -981,6 +991,13 @@ export async function readStream(cfg: DecryptConfiguration) {
981
991
  return decryptStreamFrom(cfg, overview);
982
992
  }
983
993
 
994
+ // TODO: potentially might need fixing here
995
+ // By the time this function is called the allow list will be already set.
996
+ // Verify that this function is not exported in the sdk and only exported for internal use
997
+ // Verify this during tests and PR
998
+ // Remove this comment before merging!
999
+ // https://www.youtube.com/watch?v=NGrLb6W5YOM
1000
+ // Don't leave me here all by myself!
984
1001
  export async function decryptStreamFrom(
985
1002
  cfg: DecryptConfiguration,
986
1003
  { manifest, zipReader, centralDirectory }: InspectedTDFOverview