@opentdf/sdk 0.2.0-beta.1758 → 0.2.0-beta.1941

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 (265) hide show
  1. package/README.md +45 -38
  2. package/dist/cjs/src/access.js +47 -11
  3. package/dist/cjs/src/auth/auth.js +5 -5
  4. package/dist/cjs/src/auth/oidc-clientcredentials-provider.js +1 -1
  5. package/dist/cjs/src/auth/oidc-externaljwt-provider.js +1 -1
  6. package/dist/cjs/src/auth/oidc-refreshtoken-provider.js +1 -1
  7. package/dist/cjs/src/auth/oidc.js +1 -1
  8. package/dist/cjs/src/auth/providers.js +1 -1
  9. package/dist/cjs/src/concurrency.js +3 -4
  10. package/dist/cjs/src/encodings/base64.js +4 -4
  11. package/dist/cjs/src/encodings/hex.js +5 -6
  12. package/dist/cjs/src/encodings/index.js +18 -8
  13. package/dist/cjs/src/errors.js +1 -1
  14. package/dist/cjs/src/index.js +28 -318
  15. package/dist/cjs/src/nanoclients.js +285 -0
  16. package/dist/cjs/src/nanoindex.js +47 -0
  17. package/dist/cjs/src/nanotdf/Client.js +18 -8
  18. package/dist/cjs/src/nanotdf/NanoTDF.js +1 -1
  19. package/dist/cjs/src/nanotdf/decrypt.js +2 -2
  20. package/dist/cjs/src/nanotdf/encrypt-dataset.js +2 -2
  21. package/dist/cjs/src/nanotdf/encrypt.js +2 -2
  22. package/dist/cjs/src/nanotdf/helpers/calculateByCurve.js +3 -4
  23. package/dist/cjs/src/nanotdf/helpers/getHkdfSalt.js +2 -2
  24. package/dist/cjs/src/nanotdf/models/Ciphers.js +3 -3
  25. package/dist/cjs/src/nanotdf/models/EcCurves.js +3 -3
  26. package/dist/cjs/src/nanotdf/models/Header.js +1 -1
  27. package/dist/cjs/src/nanotdf/models/Payload.js +1 -1
  28. package/dist/cjs/src/nanotdf/models/Policy/AbstractPolicy.js +1 -1
  29. package/dist/cjs/src/nanotdf/models/Policy/EmbeddedPolicy.js +1 -1
  30. package/dist/cjs/src/nanotdf/models/Policy/PolicyFactory.js +1 -1
  31. package/dist/cjs/src/nanotdf/models/ResourceLocator.js +1 -1
  32. package/dist/cjs/src/nanotdf/models/Signature.js +1 -1
  33. package/dist/cjs/src/nanotdf-crypto/ciphers.js +1 -1
  34. package/dist/cjs/src/nanotdf-crypto/decrypt.js +2 -2
  35. package/dist/cjs/src/nanotdf-crypto/digest.js +2 -2
  36. package/dist/cjs/src/nanotdf-crypto/ecdsaSignature.js +4 -5
  37. package/dist/cjs/src/nanotdf-crypto/encrypt.js +2 -2
  38. package/dist/cjs/src/nanotdf-crypto/exportCryptoKey.js +2 -2
  39. package/dist/cjs/src/nanotdf-crypto/generateKeyPair.js +2 -2
  40. package/dist/cjs/src/nanotdf-crypto/generateRandomNumber.js +2 -2
  41. package/dist/cjs/src/nanotdf-crypto/index.js +21 -13
  42. package/dist/cjs/src/nanotdf-crypto/keyAgreement.js +10 -8
  43. package/dist/cjs/src/nanotdf-crypto/pemPublicToCrypto.js +20 -11
  44. package/dist/cjs/src/opentdf.js +243 -0
  45. package/dist/cjs/src/policy/api.js +2 -3
  46. package/dist/cjs/src/policy/granter.js +3 -4
  47. package/dist/cjs/src/seekable.js +157 -0
  48. package/dist/cjs/src/tdf/AttributeObject.js +2 -4
  49. package/dist/cjs/src/tdf/Policy.js +1 -2
  50. package/dist/cjs/src/utils.js +12 -14
  51. package/dist/cjs/src/version.js +6 -2
  52. package/dist/cjs/tdf3/index.js +27 -15
  53. package/dist/cjs/tdf3/src/assertions.js +25 -11
  54. package/dist/cjs/tdf3/src/binary.js +1 -1
  55. package/dist/cjs/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
  56. package/dist/cjs/tdf3/src/ciphers/symmetric-cipher-base.js +1 -1
  57. package/dist/cjs/tdf3/src/client/DecoratedReadableStream.js +7 -74
  58. package/dist/cjs/tdf3/src/client/builders.js +26 -22
  59. package/dist/cjs/tdf3/src/client/index.js +88 -61
  60. package/dist/cjs/tdf3/src/client/validation.js +3 -3
  61. package/dist/cjs/tdf3/src/crypto/crypto-utils.js +1 -1
  62. package/dist/cjs/tdf3/src/crypto/index.js +18 -18
  63. package/dist/cjs/tdf3/src/index.js +22 -11
  64. package/dist/cjs/tdf3/src/models/attribute-set.js +1 -1
  65. package/dist/cjs/tdf3/src/models/encryption-information.js +3 -3
  66. package/dist/cjs/tdf3/src/models/key-access.js +67 -35
  67. package/dist/cjs/tdf3/src/models/policy.js +3 -3
  68. package/dist/cjs/tdf3/src/tdf.js +177 -151
  69. package/dist/cjs/tdf3/src/utils/buffer-crc32.js +2 -3
  70. package/dist/cjs/tdf3/src/utils/index.js +30 -28
  71. package/dist/cjs/tdf3/src/utils/keysplit.js +4 -5
  72. package/dist/cjs/tdf3/src/utils/unwrap.js +21 -0
  73. package/dist/cjs/tdf3/src/utils/zip-reader.js +4 -4
  74. package/dist/cjs/tdf3/src/utils/zip-writer.js +4 -4
  75. package/dist/types/src/access.d.ts +3 -0
  76. package/dist/types/src/access.d.ts.map +1 -1
  77. package/dist/types/src/auth/providers.d.ts.map +1 -1
  78. package/dist/types/src/index.d.ts +5 -136
  79. package/dist/types/src/index.d.ts.map +1 -1
  80. package/dist/types/src/nanoclients.d.ts +107 -0
  81. package/dist/types/src/nanoclients.d.ts.map +1 -0
  82. package/dist/types/src/nanoindex.d.ts +5 -0
  83. package/dist/types/src/nanoindex.d.ts.map +1 -0
  84. package/dist/types/src/nanotdf/enum/CipherEnum.d.ts +1 -1
  85. package/dist/types/src/nanotdf/enum/CipherEnum.d.ts.map +1 -1
  86. package/dist/types/src/nanotdf/enum/PolicyTypeEnum.d.ts +1 -1
  87. package/dist/types/src/nanotdf/enum/PolicyTypeEnum.d.ts.map +1 -1
  88. package/dist/types/src/nanotdf/models/DefaultParams.d.ts +1 -1
  89. package/dist/types/src/nanotdf/models/ResourceLocator.d.ts.map +1 -1
  90. package/dist/types/src/nanotdf-crypto/generateKeyPair.d.ts +1 -1
  91. package/dist/types/src/nanotdf-crypto/generateKeyPair.d.ts.map +1 -1
  92. package/dist/types/src/nanotdf-crypto/generateRandomNumber.d.ts +1 -1
  93. package/dist/types/src/nanotdf-crypto/generateRandomNumber.d.ts.map +1 -1
  94. package/dist/types/src/nanotdf-crypto/index.d.ts +2 -3
  95. package/dist/types/src/nanotdf-crypto/index.d.ts.map +1 -1
  96. package/dist/types/src/nanotdf-crypto/keyAgreement.d.ts.map +1 -1
  97. package/dist/types/src/opentdf.d.ts +106 -0
  98. package/dist/types/src/opentdf.d.ts.map +1 -0
  99. package/dist/types/src/seekable.d.ts +39 -0
  100. package/dist/types/src/seekable.d.ts.map +1 -0
  101. package/dist/types/src/tdf/AttributeObject.d.ts +0 -2
  102. package/dist/types/src/tdf/AttributeObject.d.ts.map +1 -1
  103. package/dist/types/src/tdf/NanoTDF/NanoTDF.d.ts +2 -2
  104. package/dist/types/src/tdf/NanoTDF/NanoTDF.d.ts.map +1 -1
  105. package/dist/types/src/tdf/Policy.d.ts.map +1 -1
  106. package/dist/types/src/tdf/PolicyObject.d.ts +0 -1
  107. package/dist/types/src/tdf/PolicyObject.d.ts.map +1 -1
  108. package/dist/types/src/utils.d.ts +0 -1
  109. package/dist/types/src/utils.d.ts.map +1 -1
  110. package/dist/types/src/version.d.ts +4 -0
  111. package/dist/types/src/version.d.ts.map +1 -1
  112. package/dist/types/tdf3/index.d.ts +3 -2
  113. package/dist/types/tdf3/index.d.ts.map +1 -1
  114. package/dist/types/tdf3/src/assertions.d.ts +3 -3
  115. package/dist/types/tdf3/src/assertions.d.ts.map +1 -1
  116. package/dist/types/tdf3/src/client/DecoratedReadableStream.d.ts +1 -13
  117. package/dist/types/tdf3/src/client/DecoratedReadableStream.d.ts.map +1 -1
  118. package/dist/types/tdf3/src/client/builders.d.ts +43 -37
  119. package/dist/types/tdf3/src/client/builders.d.ts.map +1 -1
  120. package/dist/types/tdf3/src/client/index.d.ts +8 -9
  121. package/dist/types/tdf3/src/client/index.d.ts.map +1 -1
  122. package/dist/types/tdf3/src/client/validation.d.ts +3 -3
  123. package/dist/types/tdf3/src/client/validation.d.ts.map +1 -1
  124. package/dist/types/tdf3/src/crypto/crypto-utils.d.ts.map +1 -1
  125. package/dist/types/tdf3/src/index.d.ts +1 -1
  126. package/dist/types/tdf3/src/index.d.ts.map +1 -1
  127. package/dist/types/tdf3/src/models/key-access.d.ts +63 -15
  128. package/dist/types/tdf3/src/models/key-access.d.ts.map +1 -1
  129. package/dist/types/tdf3/src/models/manifest.d.ts +2 -0
  130. package/dist/types/tdf3/src/models/manifest.d.ts.map +1 -1
  131. package/dist/types/tdf3/src/models/policy.d.ts +0 -1
  132. package/dist/types/tdf3/src/models/policy.d.ts.map +1 -1
  133. package/dist/types/tdf3/src/tdf.d.ts +20 -24
  134. package/dist/types/tdf3/src/tdf.d.ts.map +1 -1
  135. package/dist/types/tdf3/src/utils/index.d.ts +0 -2
  136. package/dist/types/tdf3/src/utils/index.d.ts.map +1 -1
  137. package/dist/types/tdf3/src/utils/unwrap.d.ts +2 -0
  138. package/dist/types/tdf3/src/utils/unwrap.d.ts.map +1 -0
  139. package/dist/types/tdf3/src/utils/zip-reader.d.ts +1 -1
  140. package/dist/types/tdf3/src/utils/zip-reader.d.ts.map +1 -1
  141. package/dist/types/tdf3/src/utils/zip-writer.d.ts +2 -2
  142. package/dist/web/src/access.js +40 -7
  143. package/dist/web/src/auth/auth.js +1 -1
  144. package/dist/web/src/auth/oidc-clientcredentials-provider.js +1 -1
  145. package/dist/web/src/auth/oidc-externaljwt-provider.js +1 -1
  146. package/dist/web/src/auth/oidc-refreshtoken-provider.js +1 -1
  147. package/dist/web/src/auth/oidc.js +1 -1
  148. package/dist/web/src/auth/providers.js +1 -1
  149. package/dist/web/src/concurrency.js +1 -1
  150. package/dist/web/src/encodings/base64.js +1 -1
  151. package/dist/web/src/encodings/hex.js +1 -1
  152. package/dist/web/src/errors.js +1 -1
  153. package/dist/web/src/index.js +6 -310
  154. package/dist/web/src/nanoclients.js +280 -0
  155. package/dist/web/src/nanoindex.js +5 -0
  156. package/dist/web/src/nanotdf/Client.js +1 -1
  157. package/dist/web/src/nanotdf/NanoTDF.js +1 -1
  158. package/dist/web/src/nanotdf/encrypt-dataset.js +1 -1
  159. package/dist/web/src/nanotdf/encrypt.js +1 -1
  160. package/dist/web/src/nanotdf/models/Ciphers.js +1 -1
  161. package/dist/web/src/nanotdf/models/EcCurves.js +1 -1
  162. package/dist/web/src/nanotdf/models/Header.js +1 -1
  163. package/dist/web/src/nanotdf/models/Payload.js +1 -1
  164. package/dist/web/src/nanotdf/models/Policy/AbstractPolicy.js +1 -1
  165. package/dist/web/src/nanotdf/models/Policy/EmbeddedPolicy.js +1 -1
  166. package/dist/web/src/nanotdf/models/Policy/PolicyFactory.js +1 -1
  167. package/dist/web/src/nanotdf/models/ResourceLocator.js +1 -1
  168. package/dist/web/src/nanotdf/models/Signature.js +1 -1
  169. package/dist/web/src/nanotdf-crypto/ciphers.js +1 -1
  170. package/dist/web/src/nanotdf-crypto/ecdsaSignature.js +1 -1
  171. package/dist/web/src/nanotdf-crypto/generateKeyPair.js +2 -2
  172. package/dist/web/src/nanotdf-crypto/generateRandomNumber.js +2 -2
  173. package/dist/web/src/nanotdf-crypto/index.js +3 -4
  174. package/dist/web/src/nanotdf-crypto/keyAgreement.js +9 -6
  175. package/dist/web/src/nanotdf-crypto/pemPublicToCrypto.js +1 -1
  176. package/dist/web/src/opentdf.js +234 -0
  177. package/dist/web/src/policy/api.js +1 -1
  178. package/dist/web/src/policy/granter.js +1 -1
  179. package/dist/web/src/seekable.js +148 -0
  180. package/dist/web/src/tdf/AttributeObject.js +1 -2
  181. package/dist/web/src/tdf/Policy.js +1 -2
  182. package/dist/web/src/utils.js +2 -3
  183. package/dist/web/src/version.js +5 -1
  184. package/dist/web/tdf3/index.js +3 -2
  185. package/dist/web/tdf3/src/assertions.js +21 -6
  186. package/dist/web/tdf3/src/binary.js +1 -1
  187. package/dist/web/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
  188. package/dist/web/tdf3/src/ciphers/symmetric-cipher-base.js +1 -1
  189. package/dist/web/tdf3/src/client/DecoratedReadableStream.js +4 -68
  190. package/dist/web/tdf3/src/client/builders.js +26 -22
  191. package/dist/web/tdf3/src/client/index.js +69 -52
  192. package/dist/web/tdf3/src/client/validation.js +1 -1
  193. package/dist/web/tdf3/src/crypto/crypto-utils.js +1 -1
  194. package/dist/web/tdf3/src/crypto/index.js +1 -1
  195. package/dist/web/tdf3/src/index.js +2 -2
  196. package/dist/web/tdf3/src/models/attribute-set.js +1 -1
  197. package/dist/web/tdf3/src/models/encryption-information.js +3 -3
  198. package/dist/web/tdf3/src/models/key-access.js +47 -24
  199. package/dist/web/tdf3/src/models/policy.js +1 -1
  200. package/dist/web/tdf3/src/tdf.js +149 -130
  201. package/dist/web/tdf3/src/utils/buffer-crc32.js +1 -1
  202. package/dist/web/tdf3/src/utils/index.js +1 -5
  203. package/dist/web/tdf3/src/utils/keysplit.js +1 -1
  204. package/dist/web/tdf3/src/utils/unwrap.js +18 -0
  205. package/dist/web/tdf3/src/utils/zip-reader.js +1 -1
  206. package/dist/web/tdf3/src/utils/zip-writer.js +1 -1
  207. package/package.json +45 -42
  208. package/src/access.ts +37 -1
  209. package/src/index.ts +5 -435
  210. package/src/nanoclients.ts +405 -0
  211. package/src/nanoindex.ts +4 -0
  212. package/src/nanotdf-crypto/generateKeyPair.ts +1 -1
  213. package/src/nanotdf-crypto/generateRandomNumber.ts +1 -1
  214. package/src/nanotdf-crypto/index.ts +2 -3
  215. package/src/nanotdf-crypto/keyAgreement.ts +14 -7
  216. package/src/opentdf.ts +441 -0
  217. package/{tdf3/src/utils/chunkers.ts → src/seekable.ts} +69 -20
  218. package/src/tdf/AttributeObject.ts +0 -3
  219. package/src/tdf/Policy.ts +0 -1
  220. package/src/tdf/PolicyObject.ts +0 -1
  221. package/src/utils.ts +1 -3
  222. package/src/version.ts +5 -0
  223. package/tdf3/index.ts +14 -2
  224. package/tdf3/src/assertions.ts +33 -8
  225. package/tdf3/src/client/DecoratedReadableStream.ts +2 -78
  226. package/tdf3/src/client/builders.ts +44 -26
  227. package/tdf3/src/client/index.ts +101 -86
  228. package/tdf3/src/index.ts +1 -1
  229. package/tdf3/src/models/encryption-information.ts +2 -2
  230. package/tdf3/src/models/key-access.ts +120 -38
  231. package/tdf3/src/models/manifest.ts +3 -0
  232. package/tdf3/src/models/policy.ts +0 -1
  233. package/tdf3/src/tdf.ts +251 -207
  234. package/tdf3/src/utils/index.ts +0 -5
  235. package/tdf3/src/utils/unwrap.ts +17 -0
  236. package/tdf3/src/utils/zip-reader.ts +1 -1
  237. package/dist/cjs/src/nanotdf-crypto/importRawKey.js +0 -18
  238. package/dist/cjs/tdf3/src/templates/default.html.js +0 -98
  239. package/dist/cjs/tdf3/src/templates/escaper.js +0 -15
  240. package/dist/cjs/tdf3/src/templates/index.js +0 -12
  241. package/dist/cjs/tdf3/src/utils/chunkers.js +0 -114
  242. package/dist/cjs/tdf3/src/version.js +0 -6
  243. package/dist/types/src/nanotdf-crypto/importRawKey.d.ts +0 -13
  244. package/dist/types/src/nanotdf-crypto/importRawKey.d.ts.map +0 -1
  245. package/dist/types/tdf3/src/templates/default.html.d.ts +0 -8
  246. package/dist/types/tdf3/src/templates/default.html.d.ts.map +0 -1
  247. package/dist/types/tdf3/src/templates/escaper.d.ts +0 -6
  248. package/dist/types/tdf3/src/templates/escaper.d.ts.map +0 -1
  249. package/dist/types/tdf3/src/templates/index.d.ts +0 -3
  250. package/dist/types/tdf3/src/templates/index.d.ts.map +0 -1
  251. package/dist/types/tdf3/src/utils/chunkers.d.ts +0 -29
  252. package/dist/types/tdf3/src/utils/chunkers.d.ts.map +0 -1
  253. package/dist/types/tdf3/src/version.d.ts +0 -3
  254. package/dist/types/tdf3/src/version.d.ts.map +0 -1
  255. package/dist/web/src/nanotdf-crypto/importRawKey.js +0 -15
  256. package/dist/web/tdf3/src/templates/default.html.js +0 -96
  257. package/dist/web/tdf3/src/templates/escaper.js +0 -10
  258. package/dist/web/tdf3/src/templates/index.js +0 -3
  259. package/dist/web/tdf3/src/utils/chunkers.js +0 -107
  260. package/dist/web/tdf3/src/version.js +0 -3
  261. package/src/nanotdf-crypto/importRawKey.ts +0 -19
  262. package/tdf3/src/templates/default.html.ts +0 -105
  263. package/tdf3/src/templates/escaper.ts +0 -10
  264. package/tdf3/src/templates/index.ts +0 -2
  265. package/tdf3/src/version.ts +0 -2
package/src/index.ts CHANGED
@@ -1,436 +1,6 @@
1
- import {
2
- Client,
3
- NanoTDF,
4
- Header,
5
- encrypt,
6
- decrypt,
7
- encryptDataset,
8
- getHkdfSalt,
9
- DefaultParams,
10
- } from './nanotdf/index.js';
11
- import { keyAgreement } from './nanotdf-crypto/index.js';
12
- import { Policy } from './tdf/Policy.js';
13
- import { type TypedArray } from './tdf/TypedArray.js';
14
- import { createAttribute } from './tdf/AttributeObject.js';
15
- import { fetchECKasPubKey } from './access.js';
16
- import { ClientConfig } from './nanotdf/Client.js';
17
- import { ConfigurationError } from './errors.js';
18
- export { attributeFQNsAsValues } from './policy/api.js';
19
-
20
- // Define the EncryptOptions type
21
- export type EncryptOptions = {
22
- ecdsaBinding: boolean;
23
- };
24
-
25
- // Define default options
26
- const defaultOptions: EncryptOptions = {
27
- ecdsaBinding: false,
28
- };
29
-
30
- /**
31
- * NanoTDF SDK Client
32
- *
33
- * @example
34
- * ```
35
- * import { clientSecretAuthProvider, NanoTDFClient } from '@opentdf/sdk';
36
- *
37
- * const OIDC_ENDPOINT = 'http://localhost:65432/auth/realms/opentdf-demo';
38
- * const KAS_URL = 'http://localhost:65432/api/kas/';
39
- *
40
- * const ciphertext = '...';
41
- * const client = new NanoTDFClient({
42
- * authProvider: await clientSecretAuthProvider({
43
- * clientId: 'tdf-client',
44
- * clientSecret: '123-456',
45
- * oidcOrigin: OIDC_ENDPOINT,
46
- * }),
47
- * kasEndpoint: KAS_URL
48
- * }
49
- * );
50
- * client.decrypt(ciphertext)
51
- * .then(plaintext => {
52
- * console.log('Plaintext', plaintext);
53
- * })
54
- * .catch(err => {
55
- * console.error('Some error occurred', err);
56
- * })
57
- */
58
- export class NanoTDFClient extends Client {
59
- /**
60
- * Decrypt ciphertext
61
- *
62
- * Pass a base64 string, TypedArray, or ArrayBuffer ciphertext and get a promise which resolves plaintext
63
- *
64
- * @param ciphertext Ciphertext to decrypt
65
- */
66
- async decrypt(ciphertext: string | TypedArray | ArrayBuffer): Promise<ArrayBuffer> {
67
- // Parse ciphertext
68
- const nanotdf = NanoTDF.from(ciphertext);
69
-
70
- // TODO: The version number should be fetched from the API
71
- const version = '0.0.1';
72
- const kasUrl = nanotdf.header.getKasRewrapUrl();
73
-
74
- // Rewrap key on every request
75
- const ukey = await this.rewrapKey(
76
- nanotdf.header.toBuffer(),
77
- kasUrl,
78
- nanotdf.header.magicNumberVersion,
79
- version
80
- );
81
-
82
- if (!ukey) {
83
- throw new Error('internal: key rewrap failure');
84
- }
85
- // Return decrypt promise
86
- return decrypt(ukey, nanotdf);
87
- }
88
-
89
- /**
90
- * Decrypt ciphertext of the legacy TDF, with the older, smaller i.v. calculation.
91
- *
92
- * Pass a base64 string, TypedArray, or ArrayBuffer ciphertext and get a promise which resolves plaintext
93
- *
94
- * @param ciphertext Ciphertext to decrypt
95
- */
96
- async decryptLegacyTDF(ciphertext: string | TypedArray | ArrayBuffer): Promise<ArrayBuffer> {
97
- // Parse ciphertext
98
- const nanotdf = NanoTDF.from(ciphertext, undefined, true);
99
- const legacyVersion = '0.0.0';
100
- // Rewrap key on every request
101
- const key = await this.rewrapKey(
102
- nanotdf.header.toBuffer(),
103
- nanotdf.header.getKasRewrapUrl(),
104
- nanotdf.header.magicNumberVersion,
105
- legacyVersion
106
- );
107
-
108
- if (!key) {
109
- throw new Error('internal: failed unwrap');
110
- }
111
- // Return decrypt promise
112
- return decrypt(key, nanotdf);
113
- }
114
-
115
- /**
116
- * Encrypts the given data using the NanoTDF encryption scheme.
117
- *
118
- * @param {string | TypedArray | ArrayBuffer} data - The data to be encrypted.
119
- * @param {EncryptOptions} [options=defaultOptions] - The encryption options (currently unused).
120
- * @returns {Promise<ArrayBuffer>} A promise that resolves to the encrypted data as an ArrayBuffer.
121
- * @throws {Error} If the initialization vector is not a number.
122
- */
123
- async encrypt(
124
- data: string | TypedArray | ArrayBuffer,
125
- options?: EncryptOptions
126
- ): Promise<ArrayBuffer> {
127
- // For encrypt always generate the client ephemeralKeyPair
128
- const ephemeralKeyPair = await this.ephemeralKeyPair;
129
- const initializationVector = this.iv;
130
-
131
- if (typeof initializationVector !== 'number') {
132
- throw new ConfigurationError(
133
- 'NanoTDF clients are single use. Please generate a new client and keypair.'
134
- );
135
- }
136
- delete this.iv;
137
-
138
- if (!this.kasPubKey) {
139
- this.kasPubKey = await fetchECKasPubKey(this.kasUrl);
140
- }
141
-
142
- // Create a policy for the tdf
143
- const policy = new Policy();
144
-
145
- // Add data attributes.
146
- for (const dataAttribute of this.dataAttributes) {
147
- const attribute = await createAttribute(dataAttribute, this.kasPubKey, this.kasUrl);
148
- policy.addAttribute(attribute);
149
- }
150
-
151
- if (this.dissems.length == 0 && this.dataAttributes.length == 0) {
152
- console.warn(
153
- 'This policy has an empty attributes list and an empty dissemination list. This will allow any entity with a valid Entity Object to access this TDF.'
154
- );
155
- }
156
-
157
- // Encrypt the policy.
158
- const policyObjectAsStr = policy.toJSON();
159
-
160
- // IV is always '1', since the new keypair is generated on encrypt
161
- // using the same key is fine.
162
- const lengthAsUint32 = new Uint32Array(1);
163
- lengthAsUint32[0] = initializationVector;
164
-
165
- const lengthAsUint24 = new Uint8Array(lengthAsUint32.buffer);
166
-
167
- // NOTE: We are only interested in only first 3 bytes.
168
- const payloadIV = new Uint8Array(12).fill(0);
169
- payloadIV[9] = lengthAsUint24[2];
170
- payloadIV[10] = lengthAsUint24[1];
171
- payloadIV[11] = lengthAsUint24[0];
172
-
173
- const mergedOptions: EncryptOptions = { ...defaultOptions, ...options };
174
- return encrypt(
175
- policyObjectAsStr,
176
- this.kasPubKey,
177
- ephemeralKeyPair,
178
- payloadIV,
179
- data,
180
- mergedOptions.ecdsaBinding
181
- );
182
- }
183
- }
184
-
185
- export type DatasetConfig = ClientConfig & {
186
- maxKeyIterations?: number;
187
- };
188
-
189
- /**
190
- * NanoTDF Dataset SDK Client
191
- *
192
- *
193
- * @example
194
- * ```
195
- * import { clientSecretAuthProvider, NanoTDFDatasetClient } from '@opentdf/sdk';
196
- *
197
- * const OIDC_ENDPOINT = 'http://localhost:65432/auth/realms/tdf';
198
- * const KAS_URL = 'http://localhost:65432/api/kas/';
199
- *
200
- * const ciphertext = '...';
201
- * const client = new NanoTDFDatasetClient({
202
- * authProvider: await clientSecretAuthProvider({
203
- * clientId: 'tdf-client',
204
- * clientSecret: '123-456',
205
- * exchange: 'client',
206
- * oidcOrigin: OIDC_ENDPOINT,
207
- * }),
208
- * kasEndpoint: KAS_URL,
209
- * });
210
- * const plaintext = client.decrypt(ciphertext);
211
- * console.log('Plaintext', plaintext);
212
- * ```
213
- */
214
- export class NanoTDFDatasetClient extends Client {
215
- // Total unique IVs(2^24 -1) used for encrypting the nano tdf payloads
216
- // IV starts from 1 since the 0 IV is reserved for policy encryption
217
- static readonly NTDF_MAX_KEY_ITERATIONS = 8388606;
218
-
219
- private maxKeyIteration: number;
220
- private keyIterationCount: number;
221
- private cachedEphemeralKey?: Uint8Array;
222
- private unwrappedKey?: CryptoKey;
223
- private symmetricKey?: CryptoKey;
224
- private cachedHeader?: Header;
225
- private ecdsaBinding: boolean;
226
-
227
- /**
228
- * Create new NanoTDF Dataset Client
229
- *
230
- * The Ephemeral Key Pair can either be provided or will be generate when fetching the entity object. Once set it
231
- * cannot be changed. If a new ephemeral key is desired it a new client should be initialized.
232
- * There is no performance impact for creating a new client IFF the ephemeral key pair is provided.
233
- *
234
- * @param clientConfig OIDC client credentials
235
- * @param kasUrl Key access service URL
236
- * @param ephemeralKeyPair (optional) ephemeral key pair to use
237
- * @param maxKeyIterations Max iteration to performe without a key rotation
238
- */
239
- constructor(opts: DatasetConfig) {
240
- if (
241
- opts.maxKeyIterations &&
242
- opts.maxKeyIterations > NanoTDFDatasetClient.NTDF_MAX_KEY_ITERATIONS
243
- ) {
244
- throw new ConfigurationError(
245
- `key iteration exceeds max iterations(${NanoTDFDatasetClient.NTDF_MAX_KEY_ITERATIONS})`
246
- );
247
- }
248
- super(opts);
249
-
250
- this.maxKeyIteration = opts.maxKeyIterations || NanoTDFDatasetClient.NTDF_MAX_KEY_ITERATIONS;
251
- this.keyIterationCount = 0;
252
- }
253
-
254
- /**
255
- * Encrypt data
256
- *
257
- * Pass a string, TypedArray, or ArrayBuffer data and get a promise which resolves ciphertext
258
- *
259
- * @param data to decrypt
260
- */
261
- async encrypt(
262
- data: string | TypedArray | ArrayBuffer,
263
- options?: EncryptOptions
264
- ): Promise<ArrayBuffer> {
265
- // Intial encrypt
266
- if (this.keyIterationCount == 0) {
267
- const mergedOptions: EncryptOptions = { ...defaultOptions, ...options };
268
- this.ecdsaBinding = mergedOptions.ecdsaBinding;
269
- // For encrypt always generate the client ephemeralKeyPair
270
- const ephemeralKeyPair = await this.ephemeralKeyPair;
271
-
272
- if (!this.kasPubKey) {
273
- this.kasPubKey = await fetchECKasPubKey(this.kasUrl);
274
- }
275
-
276
- // Create a policy for the tdf
277
- const policy = new Policy();
278
-
279
- // Add data attributes.
280
- for (const dataAttribute of this.dataAttributes) {
281
- const attribute = await createAttribute(dataAttribute, this.kasPubKey, this.kasUrl);
282
- policy.addAttribute(attribute);
283
- }
284
-
285
- if (this.dissems.length == 0 || this.dataAttributes.length == 0) {
286
- console.warn(
287
- 'This policy has an empty attributes list and an empty dissemination list. This will allow any entity with a valid Entity Object to access this TDF.'
288
- );
289
- }
290
-
291
- // Encrypt the policy.
292
- const policyObjectAsStr = policy.toJSON();
293
-
294
- const ivVector = this.generateIV();
295
-
296
- // Generate a symmetric key.
297
- this.symmetricKey = await keyAgreement(
298
- ephemeralKeyPair.privateKey,
299
- await this.kasPubKey.key,
300
- await getHkdfSalt(DefaultParams.magicNumberVersion)
301
- );
302
-
303
- const nanoTDFBuffer = await encrypt(
304
- policyObjectAsStr,
305
- this.kasPubKey,
306
- ephemeralKeyPair,
307
- ivVector,
308
- data,
309
- this.ecdsaBinding
310
- );
311
-
312
- // Cache the header and increment the key iteration
313
- if (!this.cachedHeader) {
314
- const nanoTDF = NanoTDF.from(nanoTDFBuffer);
315
- this.cachedHeader = nanoTDF.header;
316
- }
317
-
318
- this.keyIterationCount += 1;
319
-
320
- return nanoTDFBuffer;
321
- }
322
-
323
- this.keyIterationCount += 1;
324
-
325
- if (!this.cachedHeader) {
326
- throw new ConfigurationError('invalid dataset client: empty nanoTDF header');
327
- }
328
- if (!this.symmetricKey) {
329
- throw new ConfigurationError('invalid dataset client: empty dek');
330
- }
331
-
332
- this.keyIterationCount += 1;
333
- if (this.keyIterationCount == this.maxKeyIteration) {
334
- // reset the key iteration
335
- this.keyIterationCount = 0;
336
- }
337
-
338
- const ivVector = this.generateIV();
339
-
340
- return encryptDataset(this.symmetricKey, this.cachedHeader, ivVector, data);
341
- }
342
-
343
- /**
344
- * Decrypt ciphertext
345
- *
346
- * Pass a base64 string, TypedArray, or ArrayBuffer ciphertext and get a promise which resolves plaintext
347
- *
348
- * @param ciphertext Ciphertext to decrypt
349
- */
350
- async decrypt(ciphertext: string | TypedArray | ArrayBuffer): Promise<ArrayBuffer> {
351
- // Parse ciphertext
352
- const nanotdf = NanoTDF.from(ciphertext);
353
-
354
- if (!this.cachedEphemeralKey) {
355
- // First decrypt
356
- return this.rewrapAndDecrypt(nanotdf);
357
- }
358
-
359
- // Other encrypts
360
- if (this.cachedEphemeralKey.toString() == nanotdf.header.ephemeralPublicKey.toString()) {
361
- const ukey = this.unwrappedKey;
362
- if (!ukey) {
363
- // These should have thrown already.
364
- throw new Error('internal: key rewrap failure');
365
- }
366
- // Return decrypt promise
367
- return decrypt(ukey, nanotdf);
368
- } else {
369
- return this.rewrapAndDecrypt(nanotdf);
370
- }
371
- }
372
-
373
- async rewrapAndDecrypt(nanotdf: NanoTDF) {
374
- // TODO: The version number should be fetched from the API
375
- const version = '0.0.1';
376
- // Rewrap key on every request
377
- const ukey = await this.rewrapKey(
378
- nanotdf.header.toBuffer(),
379
- nanotdf.header.getKasRewrapUrl(),
380
- nanotdf.header.magicNumberVersion,
381
- version
382
- );
383
- if (!ukey) {
384
- // These should have thrown already.
385
- throw new Error('internal: key rewrap failure');
386
- }
387
-
388
- this.cachedEphemeralKey = nanotdf.header.ephemeralPublicKey;
389
- this.unwrappedKey = ukey;
390
-
391
- // Return decrypt promise
392
- return decrypt(ukey, nanotdf);
393
- }
394
-
395
- generateIV(): Uint8Array {
396
- const iv = this.iv;
397
- if (iv === undefined) {
398
- // iv has passed the maximum iteration count for this dek
399
- throw new ConfigurationError('dataset full');
400
- }
401
- // assert iv ∈ ℤ ∩ (0, 2^24)
402
- if (!Number.isInteger(iv) || iv <= 0 || 0xff_ffff < iv) {
403
- // Something has fiddled with the iv outside of the expected behavior
404
- // could indicate a race condition, e.g. if two workers or handlers are
405
- // processing the file at once, for example.
406
- throw new Error('internal: invalid state');
407
- }
408
-
409
- const lengthAsUint32 = new Uint32Array(1);
410
- lengthAsUint32[0] = iv;
411
-
412
- const lengthAsUint24 = new Uint8Array(lengthAsUint32.buffer);
413
-
414
- // NOTE: We are only interested in only first 3 bytes.
415
- const ivVector = new Uint8Array(Client.IV_SIZE).fill(0);
416
- ivVector[9] = lengthAsUint24[2];
417
- ivVector[10] = lengthAsUint24[1];
418
- ivVector[11] = lengthAsUint24[0];
419
-
420
- // Increment the IV
421
- if (iv == 0xff_ffff) {
422
- delete this.iv;
423
- } else {
424
- this.iv = iv + 1;
425
- }
426
-
427
- return ivVector;
428
- }
429
- }
430
-
431
- /**
432
- * Authorization for connecting authZ tokens to
433
- * remote requests.
434
- */
1
+ export { type AuthProvider, type HttpMethod, HttpRequest, withHeaders } from './auth/auth.js';
435
2
  export * as AuthProviders from './auth/providers.js';
436
- export { version, clientType } from './version.js';
3
+ export { attributeFQNsAsValues } from './policy/api.js';
4
+ export { version, clientType, tdfSpecVersion } from './version.js';
5
+ export * from './opentdf.js';
6
+ export * from './seekable.js';