@syncfusion/ej2-office-common 35.1.37

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 (147) hide show
  1. package/.eslintrc.json +263 -0
  2. package/.prettierrc.json +5 -0
  3. package/README.md +167 -0
  4. package/api-extractor.json +35 -0
  5. package/core.js +4 -0
  6. package/dist/ej2-office-common.umd.min.js +11 -0
  7. package/dist/ej2-office-common.umd.min.js.map +1 -0
  8. package/dist/es6/ej2-office-common.es2015.js +6585 -0
  9. package/dist/es6/ej2-office-common.es2015.js.map +1 -0
  10. package/dist/es6/ej2-office-common.es5.js +7955 -0
  11. package/dist/es6/ej2-office-common.es5.js.map +1 -0
  12. package/dist/global/ej2-office-common.min.js +11 -0
  13. package/dist/global/ej2-office-common.min.js.map +1 -0
  14. package/dist/global/index.d.ts +14 -0
  15. package/encryption.js +4 -0
  16. package/features.js +4 -0
  17. package/global.json +6 -0
  18. package/index.js +4 -0
  19. package/license +10 -0
  20. package/nuget.config +7 -0
  21. package/package.json +23 -0
  22. package/src/all.d.ts +41 -0
  23. package/src/all.js +38 -0
  24. package/src/core/index.d.ts +6 -0
  25. package/src/core/index.js +6 -0
  26. package/src/core/xml/index.d.ts +7 -0
  27. package/src/core/xml/index.js +6 -0
  28. package/src/core/xml/model.d.ts +71 -0
  29. package/src/core/xml/model.js +20 -0
  30. package/src/encryption/agile-constants.d.ts +61 -0
  31. package/src/encryption/agile-constants.js +71 -0
  32. package/src/encryption/agile-encryption-info.d.ts +46 -0
  33. package/src/encryption/agile-encryption-info.js +333 -0
  34. package/src/encryption/agile-password.d.ts +8 -0
  35. package/src/encryption/agile-password.js +58 -0
  36. package/src/encryption/cfb-reader.d.ts +11 -0
  37. package/src/encryption/cfb-reader.js +345 -0
  38. package/src/encryption/crypto-primitives.d.ts +74 -0
  39. package/src/encryption/crypto-primitives.js +302 -0
  40. package/src/encryption/decrypt-encrypted-package.d.ts +16 -0
  41. package/src/encryption/decrypt-encrypted-package.js +138 -0
  42. package/src/encryption/encryption-info-xml.d.ts +21 -0
  43. package/src/encryption/encryption-info-xml.js +282 -0
  44. package/src/encryption/errors.d.ts +66 -0
  45. package/src/encryption/errors.js +124 -0
  46. package/src/encryption/index.d.ts +35 -0
  47. package/src/encryption/index.js +100 -0
  48. package/src/features/diagrams/constants.d.ts +83 -0
  49. package/src/features/diagrams/constants.js +101 -0
  50. package/src/features/diagrams/diagram-data-model.d.ts +148 -0
  51. package/src/features/diagrams/diagram-data-model.js +446 -0
  52. package/src/features/diagrams/diagram-parsers.d.ts +28 -0
  53. package/src/features/diagrams/diagram-parsers.js +182 -0
  54. package/src/features/diagrams/diagram-serializers.d.ts +20 -0
  55. package/src/features/diagrams/diagram-serializers.js +110 -0
  56. package/src/features/diagrams/diagram-views.d.ts +60 -0
  57. package/src/features/diagrams/diagram-views.js +213 -0
  58. package/src/features/diagrams/element-tree.d.ts +55 -0
  59. package/src/features/diagrams/element-tree.js +197 -0
  60. package/src/features/diagrams/errors.d.ts +17 -0
  61. package/src/features/diagrams/errors.js +59 -0
  62. package/src/features/diagrams/index.d.ts +17 -0
  63. package/src/features/diagrams/index.js +17 -0
  64. package/src/features/diagrams/smart-art-catalog.d.ts +107 -0
  65. package/src/features/diagrams/smart-art-catalog.js +422 -0
  66. package/src/features/diagrams/smart-art-diagram.d.ts +96 -0
  67. package/src/features/diagrams/smart-art-diagram.js +258 -0
  68. package/src/features/index.d.ts +11 -0
  69. package/src/features/index.js +11 -0
  70. package/src/features/ink/constants.d.ts +54 -0
  71. package/src/features/ink/constants.js +54 -0
  72. package/src/features/ink/index.d.ts +18 -0
  73. package/src/features/ink/index.js +15 -0
  74. package/src/features/ink/ink-effects.d.ts +35 -0
  75. package/src/features/ink/ink-effects.js +45 -0
  76. package/src/features/ink/ink-model.d.ts +237 -0
  77. package/src/features/ink/ink-model.js +406 -0
  78. package/src/features/ink/ink-parser.d.ts +59 -0
  79. package/src/features/ink/ink-parser.js +671 -0
  80. package/src/features/ink/ink-serializer.d.ts +16 -0
  81. package/src/features/ink/ink-serializer.js +281 -0
  82. package/src/features/ink/ink-units.d.ts +33 -0
  83. package/src/features/ink/ink-units.js +92 -0
  84. package/src/features/ink/ink-xml.d.ts +26 -0
  85. package/src/features/ink/ink-xml.js +165 -0
  86. package/src/features/ink/trace-codec.d.ts +127 -0
  87. package/src/features/ink/trace-codec.js +266 -0
  88. package/src/features/mathml/constants.d.ts +47 -0
  89. package/src/features/mathml/constants.js +47 -0
  90. package/src/features/mathml/errors.d.ts +50 -0
  91. package/src/features/mathml/errors.js +69 -0
  92. package/src/features/mathml/index.d.ts +30 -0
  93. package/src/features/mathml/index.js +22 -0
  94. package/src/features/mathml/math-factory.d.ts +26 -0
  95. package/src/features/mathml/math-factory.js +568 -0
  96. package/src/features/mathml/model/controls.d.ts +896 -0
  97. package/src/features/mathml/model/controls.js +1541 -0
  98. package/src/features/mathml/model/enums.d.ts +153 -0
  99. package/src/features/mathml/model/enums.js +133 -0
  100. package/src/features/mathml/model/math-element.d.ts +173 -0
  101. package/src/features/mathml/model/math-element.js +315 -0
  102. package/src/features/mathml/model/roots.d.ts +82 -0
  103. package/src/features/mathml/model/roots.js +177 -0
  104. package/src/features/mathml/openxml.d.ts +56 -0
  105. package/src/features/mathml/openxml.js +87 -0
  106. package/src/features/mathml/parse/math-parser.d.ts +43 -0
  107. package/src/features/mathml/parse/math-parser.js +636 -0
  108. package/src/features/mathml/serialize/math-serializer.d.ts +34 -0
  109. package/src/features/mathml/serialize/math-serializer.js +749 -0
  110. package/src/features/smart-art/diagram-xml.d.ts +63 -0
  111. package/src/features/smart-art/diagram-xml.js +459 -0
  112. package/src/features/smart-art/errors.d.ts +24 -0
  113. package/src/features/smart-art/errors.js +47 -0
  114. package/src/features/smart-art/index.d.ts +26 -0
  115. package/src/features/smart-art/index.js +26 -0
  116. package/src/features/smart-art/minimal-samples.d.ts +18 -0
  117. package/src/features/smart-art/minimal-samples.js +40 -0
  118. package/src/features/smart-art/mutators.d.ts +60 -0
  119. package/src/features/smart-art/mutators.js +566 -0
  120. package/src/features/smart-art/namespaces.d.ts +153 -0
  121. package/src/features/smart-art/namespaces.js +163 -0
  122. package/src/features/smart-art/package-graph.d.ts +61 -0
  123. package/src/features/smart-art/package-graph.js +413 -0
  124. package/src/features/smart-art/parse-colors.d.ts +19 -0
  125. package/src/features/smart-art/parse-colors.js +39 -0
  126. package/src/features/smart-art/parse-data.d.ts +21 -0
  127. package/src/features/smart-art/parse-data.js +121 -0
  128. package/src/features/smart-art/parse-layout.d.ts +20 -0
  129. package/src/features/smart-art/parse-layout.js +40 -0
  130. package/src/features/smart-art/parse-rel-ids.d.ts +71 -0
  131. package/src/features/smart-art/parse-rel-ids.js +233 -0
  132. package/src/features/smart-art/parse-style.d.ts +19 -0
  133. package/src/features/smart-art/parse-style.js +39 -0
  134. package/src/features/smart-art/point-text.d.ts +80 -0
  135. package/src/features/smart-art/point-text.js +424 -0
  136. package/src/features/smart-art/register.d.ts +33 -0
  137. package/src/features/smart-art/register.js +95 -0
  138. package/src/features/smart-art/serialize.d.ts +40 -0
  139. package/src/features/smart-art/serialize.js +48 -0
  140. package/src/features/smart-art/types.d.ts +403 -0
  141. package/src/features/smart-art/types.js +28 -0
  142. package/src/global.js +1 -0
  143. package/src/index.d.ts +21 -0
  144. package/src/index.js +22 -0
  145. package/tsconfig.build.json +13 -0
  146. package/tsconfig.harness.json +32 -0
  147. package/tslint.json +111 -0
@@ -0,0 +1,302 @@
1
+ /*
2
+ * Hash / HMAC / AES-CBC primitives for Agile OFFCRYPTO.
3
+ *
4
+ * @remarks
5
+ * [MS-OFFCRYPTO] §2.3.4.11–§2.3.4.15 pads AES-CBC plaintexts with **0x00** to
6
+ * `blockSize`, not PKCS #7. Node's Web Crypto `AES-CBC` decrypt expects PKCS #7
7
+ * and rejects Office ciphertexts. This module therefore uses the **Node.js
8
+ * built-in** `node:crypto` (`createHash`, `createHmac`, `createDecipheriv` with
9
+ * `setAutoPadding(false)`). That is a platform API, not a new npm dependency
10
+ * (ADR / dependencies policy). No third-party crypto packages.
11
+ *
12
+ * Supported for v1: AES-128/192/256 + CBC; SHA-1 / SHA-256 / SHA-384 / SHA-512.
13
+ * Symbols re-exported from the encryption package entry are public; keep
14
+ * `@private`
15
+ * only on helpers that are not part of that surface.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ var __values = (this && this.__values) || function (o) {
20
+ var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
21
+ if (m) return m.call(o);
22
+ return {
23
+ next: function () {
24
+ if (o && i >= o.length) o = void 0;
25
+ return { value: o && o[i++], done: !o };
26
+ }
27
+ };
28
+ };
29
+ import { UnsupportedEncryptionError } from './errors';
30
+ import { IV_PAD_BYTE, KEY_PAD_BYTE } from './agile-constants';
31
+ function __nodeCrypto() {
32
+ try {
33
+ return require('crypto');
34
+ }
35
+ catch (e) {
36
+ throw new Error('Node crypto is required for Agile encryption');
37
+ }
38
+ }
39
+ var _a = __nodeCrypto(), createCipheriv = _a.createCipheriv, createDecipheriv = _a.createDecipheriv, createHash = _a.createHash, createHmac = _a.createHmac;
40
+ var HASH_TO_NODE = {
41
+ 'SHA-1': 'sha1',
42
+ SHA256: 'sha256',
43
+ SHA384: 'sha384',
44
+ SHA512: 'sha512',
45
+ };
46
+ var HASH_DIGEST_BYTES = {
47
+ 'SHA-1': 20,
48
+ SHA256: 32,
49
+ SHA384: 48,
50
+ SHA512: 64,
51
+ };
52
+ /**
53
+ * Maps OFFCRYPTO hashAlgorithm attribute to an internal name.
54
+ *
55
+ * @throws {UnsupportedEncryptionError} When the algorithm is not in the v1 set.
56
+ */
57
+ export function resolveHashAlgorithm(name) {
58
+ switch (name) {
59
+ case 'SHA-1':
60
+ case 'SHA1':
61
+ return 'SHA-1';
62
+ case 'SHA256':
63
+ return 'SHA256';
64
+ case 'SHA384':
65
+ return 'SHA384';
66
+ case 'SHA512':
67
+ return 'SHA512';
68
+ default:
69
+ throw new UnsupportedEncryptionError("Unsupported OFFCRYPTO hashAlgorithm: " + sanitizeAlgToken(name));
70
+ }
71
+ }
72
+ /**
73
+ * Validates cipherAlgorithm + cipherChaining for v1 (AES + CBC only).
74
+ *
75
+ * @throws {UnsupportedEncryptionError} When not AES/CBC.
76
+ */
77
+ export function assertSupportedCipher(cipherAlgorithm, cipherChaining) {
78
+ if (cipherAlgorithm !== 'AES') {
79
+ throw new UnsupportedEncryptionError("Unsupported OFFCRYPTO cipherAlgorithm: " + sanitizeAlgToken(cipherAlgorithm));
80
+ }
81
+ if (cipherChaining !== 'ChainingModeCBC') {
82
+ throw new UnsupportedEncryptionError("Unsupported OFFCRYPTO cipherChaining: " + sanitizeAlgToken(cipherChaining));
83
+ }
84
+ }
85
+ /**
86
+ * Validates AES keyBits (128 / 192 / 256).
87
+ *
88
+ * @throws {UnsupportedEncryptionError} When key length is not a supported AES size.
89
+ */
90
+ export function assertAesKeyBits(keyBits) {
91
+ if (keyBits !== 128 && keyBits !== 192 && keyBits !== 256) {
92
+ throw new UnsupportedEncryptionError("Unsupported OFFCRYPTO AES keyBits: " + String(keyBits));
93
+ }
94
+ }
95
+ /** Digest length in bytes for a resolved hash algorithm. */
96
+ export function hashDigestLength(hash) {
97
+ return HASH_DIGEST_BYTES[hash];
98
+ }
99
+ /** One-shot hash. */
100
+ export function hashBytes(hash, data) {
101
+ var h = createHash(HASH_TO_NODE[hash]);
102
+ h.update(data);
103
+ return new Uint8Array(h.digest());
104
+ }
105
+ /** HMAC over message with key (DataIntegrity §2.3.4.14). */
106
+ export function hmacBytes(hash, key, message) {
107
+ var h = createHmac(HASH_TO_NODE[hash], Buffer.from(key));
108
+ h.update(message);
109
+ return new Uint8Array(h.digest());
110
+ }
111
+ /**
112
+ * Concatenates byte arrays.
113
+ *
114
+ * @public
115
+ */
116
+ export function concatBytes() {
117
+ var parts = [];
118
+ for (var _i = 0; _i < arguments.length; _i++) {
119
+ parts[_i] = arguments[_i];
120
+ }
121
+ var e_1, _a, e_2, _b;
122
+ var total = 0;
123
+ try {
124
+ for (var parts_1 = __values(parts), parts_1_1 = parts_1.next(); !parts_1_1.done; parts_1_1 = parts_1.next()) {
125
+ var p = parts_1_1.value;
126
+ total += p.byteLength;
127
+ }
128
+ }
129
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
130
+ finally {
131
+ try {
132
+ if (parts_1_1 && !parts_1_1.done && (_a = parts_1.return)) _a.call(parts_1);
133
+ }
134
+ finally { if (e_1) throw e_1.error; }
135
+ }
136
+ var out = new Uint8Array(total);
137
+ var offset = 0;
138
+ try {
139
+ for (var parts_2 = __values(parts), parts_2_1 = parts_2.next(); !parts_2_1.done; parts_2_1 = parts_2.next()) {
140
+ var p = parts_2_1.value;
141
+ out.set(p, offset);
142
+ offset += p.byteLength;
143
+ }
144
+ }
145
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
146
+ finally {
147
+ try {
148
+ if (parts_2_1 && !parts_2_1.done && (_b = parts_2.return)) _b.call(parts_2);
149
+ }
150
+ finally { if (e_2) throw e_2.error; }
151
+ }
152
+ return out;
153
+ }
154
+ /**
155
+ * Encodes a JavaScript string as UTF-16LE (Unicode password bytes, §2.3.4.11).
156
+ */
157
+ export function encodePasswordUtf16Le(password) {
158
+ var out = new Uint8Array(password.length * 2);
159
+ for (var i = 0; i < password.length; i++) {
160
+ var code = password.charCodeAt(i);
161
+ out[i * 2] = code & 0xff;
162
+ out[i * 2 + 1] = (code >>> 8) & 0xff;
163
+ }
164
+ return out;
165
+ }
166
+ /**
167
+ * Password-based encryption key (§2.3.4.11).
168
+ *
169
+ * H0 = H(salt + password); Hn = H(iterator LE u32 + Hn-1) for spinCount iterations;
170
+ * Hfinal = H(Hn + blockKey); pad/truncate to keyBits/8 with 0x36.
171
+ */
172
+ export function deriveAgileKey(hash, salt, passwordUtf16Le, spinCount, blockKey, keyBits) {
173
+ var hn = hashBytes(hash, concatBytes(salt, passwordUtf16Le));
174
+ var iterator = new Uint8Array(4);
175
+ var iteratorView = new DataView(iterator.buffer);
176
+ for (var i = 0; i < spinCount; i++) {
177
+ iteratorView.setUint32(0, i, true);
178
+ hn = hashBytes(hash, concatBytes(iterator, hn));
179
+ }
180
+ var hfinal = hashBytes(hash, concatBytes(hn, blockKey));
181
+ return padOrTruncate(hfinal, keyBits / 8, KEY_PAD_BYTE);
182
+ }
183
+ /**
184
+ * Initialization vector (§2.3.4.12).
185
+ *
186
+ * With blockKey: IV = H(keySalt + blockKey); without: IV = keySalt.
187
+ * Pad/truncate to blockSize with 0x36.
188
+ */
189
+ export function deriveAgileIv(hash, keySalt, blockKey, blockSize) {
190
+ var raw = blockKey === undefined ? keySalt : hashBytes(hash, concatBytes(keySalt, blockKey));
191
+ return padOrTruncate(raw, blockSize, IV_PAD_BYTE);
192
+ }
193
+ /**
194
+ * AES-CBC decrypt with zero padding (no PKCS #7 strip).
195
+ *
196
+ * @param key - AES key (16/24/32 bytes).
197
+ * @param iv - IV of blockSize bytes (AES block is 16; OFFCRYPTO blockSize is 16 for AES).
198
+ * @param ciphertext - Length MUST be a multiple of 16.
199
+ * @returns Plaintext of the same length as ciphertext (including zero pad).
200
+ */
201
+ export function aesCbcDecrypt(key, iv, ciphertext) {
202
+ if (ciphertext.byteLength === 0) {
203
+ return new Uint8Array(0);
204
+ }
205
+ if (ciphertext.byteLength % 16 !== 0) {
206
+ throw new UnsupportedEncryptionError('OFFCRYPTO AES-CBC ciphertext length is not block-aligned');
207
+ }
208
+ if (iv.byteLength !== 16) {
209
+ throw new UnsupportedEncryptionError('OFFCRYPTO AES-CBC IV must be 16 bytes');
210
+ }
211
+ var algo = aesAlgorithmName(key.byteLength);
212
+ var decipher = createDecipheriv(algo, Buffer.from(key), Buffer.from(iv));
213
+ decipher.setAutoPadding(false);
214
+ var part1 = decipher.update(Buffer.from(ciphertext));
215
+ var part2 = decipher.final();
216
+ if (part2.byteLength === 0) {
217
+ return new Uint8Array(part1);
218
+ }
219
+ var out = new Uint8Array(part1.byteLength + part2.byteLength);
220
+ out.set(part1, 0);
221
+ out.set(part2, part1.byteLength);
222
+ return out;
223
+ }
224
+ /**
225
+ * AES-CBC encrypt with zero padding (no PKCS #7).
226
+ *
227
+ * @remarks
228
+ * Used by test fixture builders and host encrypt harnesses. Same zero-pad
229
+ * rules as decrypt ([MS-OFFCRYPTO] §2.3.4.13 / §2.3.4.15).
230
+ *
231
+ * @public
232
+ */
233
+ export function aesCbcEncrypt(key, iv, plaintext) {
234
+ if (iv.byteLength !== 16) {
235
+ throw new UnsupportedEncryptionError('OFFCRYPTO AES-CBC IV must be 16 bytes');
236
+ }
237
+ var blockSize = 16;
238
+ var paddedLen = plaintext.byteLength === 0
239
+ ? blockSize
240
+ : Math.ceil(plaintext.byteLength / blockSize) * blockSize;
241
+ var padded = new Uint8Array(paddedLen);
242
+ padded.set(plaintext, 0);
243
+ // remaining bytes stay 0x00 (Agile zero-pad, §2.3.4.13 / §2.3.4.15).
244
+ var algo = aesAlgorithmName(key.byteLength);
245
+ var cipher = createCipheriv(algo, Buffer.from(key), Buffer.from(iv));
246
+ cipher.setAutoPadding(false);
247
+ var part1 = cipher.update(Buffer.from(padded));
248
+ var part2 = cipher.final();
249
+ if (part2.byteLength === 0) {
250
+ return new Uint8Array(part1);
251
+ }
252
+ var out = new Uint8Array(part1.byteLength + part2.byteLength);
253
+ out.set(part1, 0);
254
+ out.set(part2, part1.byteLength);
255
+ return out;
256
+ }
257
+ /**
258
+ * Constant-time comparison of two equal-length buffers.
259
+ * Returns false when lengths differ (not constant-time on length).
260
+ */
261
+ export function timingSafeEqual(a, b) {
262
+ if (a.byteLength !== b.byteLength) {
263
+ return false;
264
+ }
265
+ var diff = 0;
266
+ for (var i = 0; i < a.byteLength; i++) {
267
+ // Lengths already equal; index is in range. Avoid non-null assertions.
268
+ var left = (a[i] != null ? a[i] : 0);
269
+ var right = (b[i] != null ? b[i] : 0);
270
+ diff |= left ^ right;
271
+ }
272
+ return diff === 0;
273
+ }
274
+ function padOrTruncate(data, size, padByte) {
275
+ if (data.byteLength === size) {
276
+ return data;
277
+ }
278
+ if (data.byteLength > size) {
279
+ return data.subarray(0, size);
280
+ }
281
+ var out = new Uint8Array(size);
282
+ out.set(data, 0);
283
+ out.fill(padByte, data.byteLength);
284
+ return out;
285
+ }
286
+ function aesAlgorithmName(keyBytes) {
287
+ switch (keyBytes) {
288
+ case 16:
289
+ return 'aes-128-cbc';
290
+ case 24:
291
+ return 'aes-192-cbc';
292
+ case 32:
293
+ return 'aes-256-cbc';
294
+ default:
295
+ throw new UnsupportedEncryptionError('Unsupported AES key length');
296
+ }
297
+ }
298
+ /** Strip control chars so algorithm tokens cannot smuggle secrets into messages. */
299
+ function sanitizeAlgToken(token) {
300
+ var cleaned = token.replace(/[^\w.\-:/+]/g, '').slice(0, 64);
301
+ return cleaned.length > 0 ? cleaned : '(unrecognized)';
302
+ }
@@ -0,0 +1,16 @@
1
+ import { DecryptSecurityLimits } from './errors';
2
+ import { AgileDataIntegrity, AgileKeyData } from './agile-encryption-info';
3
+ /**
4
+ * Decrypts EncryptedPackage ciphertext to plain OPC ZIP bytes.
5
+ *
6
+ * @param encryptedPackage - Full EncryptedPackage stream bytes.
7
+ * @param secretKey - Intermediate key from password unlock (keyBits/8).
8
+ * @param keyData - KeyData from EncryptionInfo.
9
+ * @param dataIntegrity - Optional integrity structure.
10
+ * @param limits - Security limits (single-part / total uncompressed caps).
11
+ *
12
+ * @throws {PackageLimitError} When StreamSize or ciphertext exceeds limits.
13
+ * @throws {InvalidPasswordError} When DataIntegrity HMAC fails (fail-closed).
14
+ * @throws {EncryptedPackageError} When stream structure is invalid.
15
+ */
16
+ export declare function decryptEncryptedPackageStream(encryptedPackage: Uint8Array, secretKey: Uint8Array, keyData: AgileKeyData, dataIntegrity: AgileDataIntegrity | undefined, limits: DecryptSecurityLimits): Uint8Array;
@@ -0,0 +1,138 @@
1
+ /*
2
+ * Decrypt EncryptedPackage stream ([MS-OFFCRYPTO] §2.3.4.4, §2.3.4.15)
3
+ * and optional DataIntegrity HMAC (§2.3.4.14).
4
+ *
5
+ * @remarks
6
+ * Layout: 8-byte little-endian StreamSize (u64) + encrypted payload.
7
+ * Payload is segmented in 4096-byte blocks; each segment uses blockKey =
8
+ * segment number as LE u32 with KeyData.saltValue for the IV
9
+ * (§2.3.4.12 / §2.3.4.15). Secret key is the intermediate key from the
10
+ * password key encryptor.
11
+ *
12
+ * DataIntegrity: decrypt encryptedHmacKey with blockKey BLOCK_KEY_HMAC_KEY
13
+ * and KeyData; decrypt encryptedHmacValue with BLOCK_KEY_HMAC_VALUE; HMAC
14
+ * the **entire** EncryptedPackage stream (including StreamSize prefix)
15
+ * with KeyData.hashAlgorithm; compare → fail closed as InvalidPasswordError.
16
+ *
17
+ * @private
18
+ */
19
+ import { EncryptedPackageError, InvalidPasswordError, PackageLimitError, } from './errors';
20
+ import { BLOCK_KEY_HMAC_KEY, BLOCK_KEY_HMAC_VALUE, ENCRYPTED_PACKAGE_SEGMENT_SIZE, } from './agile-constants';
21
+ import { aesCbcDecrypt, deriveAgileIv, hashDigestLength, hmacBytes, timingSafeEqual, } from './crypto-primitives';
22
+ var STREAM_SIZE_BYTES = 8;
23
+ /**
24
+ * Decrypts EncryptedPackage ciphertext to plain OPC ZIP bytes.
25
+ *
26
+ * @param encryptedPackage - Full EncryptedPackage stream bytes.
27
+ * @param secretKey - Intermediate key from password unlock (keyBits/8).
28
+ * @param keyData - KeyData from EncryptionInfo.
29
+ * @param dataIntegrity - Optional integrity structure.
30
+ * @param limits - Security limits (single-part / total uncompressed caps).
31
+ *
32
+ * @throws {PackageLimitError} When StreamSize or ciphertext exceeds limits.
33
+ * @throws {InvalidPasswordError} When DataIntegrity HMAC fails (fail-closed).
34
+ * @throws {EncryptedPackageError} When stream structure is invalid.
35
+ */
36
+ export function decryptEncryptedPackageStream(encryptedPackage, secretKey, keyData, dataIntegrity, limits) {
37
+ if (encryptedPackage.byteLength < STREAM_SIZE_BYTES) {
38
+ throw new EncryptedPackageError('EncryptedPackage stream is truncated');
39
+ }
40
+ // Hard cap ciphertext before any crypto work.
41
+ var maxCipher = Math.max(limits.singlePartUncompressedBytes, limits.totalUncompressedBytes);
42
+ if (encryptedPackage.byteLength >
43
+ maxCipher + STREAM_SIZE_BYTES + ENCRYPTED_PACKAGE_SEGMENT_SIZE) {
44
+ throw new PackageLimitError('singlePartUncompressedBytes', {
45
+ actual: encryptedPackage.byteLength,
46
+ });
47
+ }
48
+ var view = new DataView(encryptedPackage.buffer, encryptedPackage.byteOffset, encryptedPackage.byteLength);
49
+ // StreamSize is u64 LE; JS safe integer covers realistic packages under limits.
50
+ var streamSizeLow = view.getUint32(0, true);
51
+ var streamSizeHigh = view.getUint32(4, true);
52
+ if (streamSizeHigh !== 0) {
53
+ throw new PackageLimitError('singlePartUncompressedBytes', {
54
+ actual: Number.MAX_SAFE_INTEGER,
55
+ });
56
+ }
57
+ var streamSize = streamSizeLow;
58
+ if (streamSize > limits.singlePartUncompressedBytes) {
59
+ throw new PackageLimitError('singlePartUncompressedBytes', { actual: streamSize });
60
+ }
61
+ if (streamSize > limits.totalUncompressedBytes) {
62
+ throw new PackageLimitError('totalUncompressedBytes', { actual: streamSize });
63
+ }
64
+ var ciphertext = encryptedPackage.subarray(STREAM_SIZE_BYTES);
65
+ if (ciphertext.byteLength === 0 && streamSize > 0) {
66
+ throw new EncryptedPackageError('EncryptedPackage has StreamSize but no ciphertext');
67
+ }
68
+ // DataIntegrity over entire EncryptedPackage including StreamSize (§2.3.4.14).
69
+ if (dataIntegrity !== undefined) {
70
+ verifyDataIntegrity(encryptedPackage, secretKey, keyData, dataIntegrity);
71
+ }
72
+ var plain = decryptSegments(ciphertext, secretKey, keyData);
73
+ if (plain.byteLength < streamSize) {
74
+ throw new EncryptedPackageError('Decrypted EncryptedPackage is shorter than StreamSize');
75
+ }
76
+ return plain.subarray(0, streamSize);
77
+ }
78
+ function decryptSegments(ciphertext, secretKey, keyData) {
79
+ var segmentSize = ENCRYPTED_PACKAGE_SEGMENT_SIZE;
80
+ var blockSize = keyData.blockSize;
81
+ var out = new Uint8Array(ciphertext.byteLength);
82
+ var outOffset = 0;
83
+ var segmentIndex = 0;
84
+ var offset = 0;
85
+ while (offset < ciphertext.byteLength) {
86
+ var remaining = ciphertext.byteLength - offset;
87
+ // Last segment may be shorter but must still be block-aligned (zero-pad encrypt).
88
+ var segmentLen = remaining > segmentSize ? segmentSize : remaining;
89
+ // If not last full logical segment and remaining > segmentSize we took segmentSize.
90
+ // Ciphertext of each segment is rounded up to blockSize on encrypt; remaining should
91
+ // already be multiple of blockSize for every piece.
92
+ if (segmentLen % blockSize !== 0) {
93
+ // Pad expectation: encryptor wrote full blocks; tolerate by rounding down if corrupt.
94
+ throw new EncryptedPackageError('EncryptedPackage segment is not block-aligned');
95
+ }
96
+ var segmentCt = ciphertext.subarray(offset, offset + segmentLen);
97
+ var blockKey = segmentBlockKey(segmentIndex);
98
+ var iv = deriveAgileIv(keyData.hashAlgorithm, keyData.saltValue, blockKey, blockSize);
99
+ var segmentPt = aesCbcDecrypt(secretKey, iv, segmentCt);
100
+ out.set(segmentPt, outOffset);
101
+ outOffset += segmentPt.byteLength;
102
+ offset += segmentLen;
103
+ segmentIndex += 1;
104
+ }
105
+ return out.subarray(0, outOffset);
106
+ }
107
+ function segmentBlockKey(segmentIndex) {
108
+ var buf = new Uint8Array(4);
109
+ new DataView(buf.buffer).setUint32(0, segmentIndex >>> 0, true);
110
+ return buf;
111
+ }
112
+ /**
113
+ * §2.3.4.14 DataIntegrity verification.
114
+ *
115
+ * Fail-closed: HMAC mismatch → InvalidPasswordError (same public class as wrong
116
+ * password; do not leak integrity vs password distinction).
117
+ */
118
+ function verifyDataIntegrity(encryptedPackage, secretKey, keyData, dataIntegrity) {
119
+ var hashAlgorithm = keyData.hashAlgorithm, saltValue = keyData.saltValue, blockSize = keyData.blockSize;
120
+ var ivHmacKey = deriveAgileIv(hashAlgorithm, saltValue, BLOCK_KEY_HMAC_KEY, blockSize);
121
+ var hmacKeyDecrypted = aesCbcDecrypt(secretKey, ivHmacKey, dataIntegrity.encryptedHmacKey);
122
+ // HMAC key length is hash digest size; truncated after decrypt (zero-padded block).
123
+ var digestLen = hashDigestLength(hashAlgorithm);
124
+ if (hmacKeyDecrypted.byteLength < digestLen) {
125
+ throw new InvalidPasswordError();
126
+ }
127
+ var hmacKey = hmacKeyDecrypted.subarray(0, digestLen);
128
+ var ivHmacValue = deriveAgileIv(hashAlgorithm, saltValue, BLOCK_KEY_HMAC_VALUE, blockSize);
129
+ var hmacValueDecrypted = aesCbcDecrypt(secretKey, ivHmacValue, dataIntegrity.encryptedHmacValue);
130
+ if (hmacValueDecrypted.byteLength < digestLen) {
131
+ throw new InvalidPasswordError();
132
+ }
133
+ var expectedHmac = hmacValueDecrypted.subarray(0, digestLen);
134
+ var actualHmac = hmacBytes(hashAlgorithm, hmacKey, encryptedPackage);
135
+ if (!timingSafeEqual(actualHmac.subarray(0, digestLen), expectedHmac)) {
136
+ throw new InvalidPasswordError();
137
+ }
138
+ }
@@ -0,0 +1,21 @@
1
+ import { DecryptSecurityLimits } from './errors';
2
+ /** Parsed element node used by Agile EncryptionInfo mapping. */
3
+ export interface XmlElement {
4
+ readonly kind: 'element';
5
+ readonly localName: string;
6
+ readonly namespaceUri: string;
7
+ readonly attributes: ReadonlyArray<XmlAttribute>;
8
+ readonly children: ReadonlyArray<XmlElement>;
9
+ }
10
+ export interface XmlAttribute {
11
+ readonly localName: string;
12
+ readonly namespaceUri: string;
13
+ readonly value: string;
14
+ }
15
+ /**
16
+ * Parses EncryptionInfo UTF-8 XML into a single root element tree.
17
+ *
18
+ * @throws {EncryptedPackageError} Malformed XML.
19
+ * @throws {PackageLimitError} Nesting / attribute / text limits.
20
+ */
21
+ export declare function parseEncryptionInfoXml(xmlText: string, limits: DecryptSecurityLimits, partName?: string): XmlElement;