@storacha/encrypt-upload-client 1.1.56 → 1.1.58

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 (72) hide show
  1. package/dist/config/constants.d.ts +3 -3
  2. package/dist/config/constants.js +4 -3
  3. package/dist/config/env.d.ts +9 -6
  4. package/dist/config/service.d.ts +13 -13
  5. package/dist/core/client.d.ts +54 -41
  6. package/dist/core/client.js +68 -56
  7. package/dist/core/errors.d.ts +6 -6
  8. package/dist/core/metadata/encrypted-metadata.d.ts +13 -8
  9. package/dist/core/metadata/kms-metadata.d.ts +68 -36
  10. package/dist/core/metadata/lit-metadata.d.ts +63 -28
  11. package/dist/crypto/adapters/kms-crypto-adapter.d.ts +172 -137
  12. package/dist/crypto/adapters/lit-crypto-adapter.d.ts +107 -86
  13. package/dist/crypto/factories.browser.d.ts +9 -5
  14. package/dist/crypto/factories.browser.js +15 -7
  15. package/dist/crypto/factories.node.d.ts +13 -6
  16. package/dist/crypto/factories.node.js +19 -13
  17. package/dist/crypto/index.d.ts +5 -5
  18. package/dist/crypto/index.js +5 -5
  19. package/dist/crypto/symmetric/generic-aes-ctr-streaming-crypto.d.ts +58 -54
  20. package/dist/crypto/symmetric/generic-aes-ctr-streaming-crypto.js +174 -146
  21. package/dist/crypto/symmetric/node-aes-cbc-crypto.d.ts +36 -32
  22. package/dist/crypto/symmetric/node-aes-cbc-crypto.js +101 -95
  23. package/dist/examples/decrypt-test.d.ts +2 -2
  24. package/dist/examples/decrypt-test.js +78 -69
  25. package/dist/examples/encrypt-test.d.ts +5 -3
  26. package/dist/examples/encrypt-test.js +58 -55
  27. package/dist/handlers/decrypt-handler.d.ts +19 -5
  28. package/dist/handlers/encrypt-handler.d.ts +9 -3
  29. package/dist/handlers/encrypt-handler.js +93 -57
  30. package/dist/index.d.ts +2 -2
  31. package/dist/index.js +2 -2
  32. package/dist/protocols/lit.d.ts +33 -9
  33. package/dist/protocols/lit.js +134 -98
  34. package/dist/test/cid-verification.spec.d.ts +2 -2
  35. package/dist/test/cid-verification.spec.js +341 -313
  36. package/dist/test/crypto-compatibility.spec.d.ts +2 -2
  37. package/dist/test/crypto-compatibility.spec.js +184 -120
  38. package/dist/test/crypto-counter-security.spec.d.ts +2 -2
  39. package/dist/test/crypto-counter-security.spec.js +177 -138
  40. package/dist/test/crypto-streaming.spec.d.ts +2 -2
  41. package/dist/test/crypto-streaming.spec.js +208 -126
  42. package/dist/test/encrypted-metadata.spec.d.ts +2 -2
  43. package/dist/test/encrypted-metadata.spec.js +89 -62
  44. package/dist/test/factories.spec.d.ts +2 -2
  45. package/dist/test/factories.spec.js +275 -139
  46. package/dist/test/file-metadata.spec.d.ts +2 -2
  47. package/dist/test/file-metadata.spec.js +472 -416
  48. package/dist/test/fixtures/test-fixtures.d.ts +25 -20
  49. package/dist/test/fixtures/test-fixtures.js +61 -53
  50. package/dist/test/helpers/test-file-utils.d.ts +19 -14
  51. package/dist/test/helpers/test-file-utils.js +78 -76
  52. package/dist/test/https-enforcement.spec.d.ts +2 -2
  53. package/dist/test/https-enforcement.spec.js +278 -124
  54. package/dist/test/kms-crypto-adapter.spec.d.ts +2 -2
  55. package/dist/test/kms-crypto-adapter.spec.js +473 -304
  56. package/dist/test/lit-crypto-adapter.spec.d.ts +2 -2
  57. package/dist/test/lit-crypto-adapter.spec.js +206 -118
  58. package/dist/test/memory-efficiency.spec.d.ts +2 -2
  59. package/dist/test/memory-efficiency.spec.js +100 -87
  60. package/dist/test/mocks/key-manager.d.ts +71 -38
  61. package/dist/test/mocks/key-manager.js +129 -113
  62. package/dist/test/node-crypto-adapter.spec.d.ts +2 -2
  63. package/dist/test/node-crypto-adapter.spec.js +155 -102
  64. package/dist/test/node-generic-crypto-adapter.spec.d.ts +2 -2
  65. package/dist/test/node-generic-crypto-adapter.spec.js +134 -94
  66. package/dist/test/setup.d.ts +2 -2
  67. package/dist/test/setup.js +8 -9
  68. package/dist/tsconfig.spec.tsbuildinfo +1 -1
  69. package/dist/types.d.ts +219 -181
  70. package/dist/utils/file-metadata.d.ts +19 -13
  71. package/dist/utils.d.ts +14 -5
  72. package/package.json +4 -4
@@ -1,7 +1,7 @@
1
- import './setup.js';
2
- import { test, describe } from 'node:test';
3
- import assert from 'node:assert';
4
- import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js';
1
+ import './setup.js'
2
+ import { test, describe } from 'node:test'
3
+ import assert from 'node:assert'
4
+ import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-aes-ctr-streaming-crypto.js'
5
5
  /**
6
6
  * Security tests for AES-CTR counter management
7
7
  *
@@ -9,139 +9,178 @@ import { GenericAesCtrStreamingCrypto } from '../src/crypto/symmetric/generic-ae
9
9
  * which is critical for AES-CTR security.
10
10
  */
11
11
  await describe('AES-CTR Counter Security', async () => {
12
- await test('should increment counter by blocks, not chunks', async () => {
13
- const crypto = new GenericAesCtrStreamingCrypto();
14
- // Test the incrementCounter function directly
15
- const baseCounter = new Uint8Array(16).fill(0);
16
- // Test counter increments for block counts
17
- const counter1 = crypto.incrementCounter(baseCounter, 0); // First block
18
- const counter2 = crypto.incrementCounter(baseCounter, 1); // Second block
19
- const counter3 = crypto.incrementCounter(baseCounter, 2); // Third block
20
- const counter4 = crypto.incrementCounter(baseCounter, 7); // Eighth block
21
- // Verify each counter is unique
22
- assert.notDeepEqual(counter1, counter2, 'Block 1 and 2 should have different counters');
23
- assert.notDeepEqual(counter2, counter3, 'Block 2 and 3 should have different counters');
24
- assert.notDeepEqual(counter3, counter4, 'Block 3 and 8 should have different counters');
25
- // Verify counter progression is correct
26
- assert.strictEqual(counter1[15], 0, 'First counter should be 0');
27
- assert.strictEqual(counter2[15], 1, 'Second counter should be 1');
28
- assert.strictEqual(counter3[15], 2, 'Third counter should be 2');
29
- assert.strictEqual(counter4[15], 7, 'Eighth counter should be 7');
30
- console.log('Counter increments by blocks correctly');
31
- });
32
- await test('should handle chunk sizes correctly', async () => {
33
- const crypto = new GenericAesCtrStreamingCrypto();
34
- // Test different chunk sizes and verify block calculations
35
- const testData = new Uint8Array(100).fill(0xaa); // 7 blocks (100 bytes = ceil(100/16) = 7)
36
- const blob = new Blob([testData]);
37
- const { key, iv, encryptedStream } = await crypto.encryptStream(blob);
38
- // Read encrypted data
39
- const reader = encryptedStream.getReader();
40
- let encryptedChunks = [];
41
- let done = false;
42
- while (!done) {
43
- const result = await reader.read();
44
- done = result.done;
45
- if (result.value) {
46
- encryptedChunks.push(result.value);
47
- }
12
+ await test('should increment counter by blocks, not chunks', async () => {
13
+ const crypto = new GenericAesCtrStreamingCrypto()
14
+ // Test the incrementCounter function directly
15
+ const baseCounter = new Uint8Array(16).fill(0)
16
+ // Test counter increments for block counts
17
+ const counter1 = crypto.incrementCounter(baseCounter, 0) // First block
18
+ const counter2 = crypto.incrementCounter(baseCounter, 1) // Second block
19
+ const counter3 = crypto.incrementCounter(baseCounter, 2) // Third block
20
+ const counter4 = crypto.incrementCounter(baseCounter, 7) // Eighth block
21
+ // Verify each counter is unique
22
+ assert.notDeepEqual(
23
+ counter1,
24
+ counter2,
25
+ 'Block 1 and 2 should have different counters'
26
+ )
27
+ assert.notDeepEqual(
28
+ counter2,
29
+ counter3,
30
+ 'Block 2 and 3 should have different counters'
31
+ )
32
+ assert.notDeepEqual(
33
+ counter3,
34
+ counter4,
35
+ 'Block 3 and 8 should have different counters'
36
+ )
37
+ // Verify counter progression is correct
38
+ assert.strictEqual(counter1[15], 0, 'First counter should be 0')
39
+ assert.strictEqual(counter2[15], 1, 'Second counter should be 1')
40
+ assert.strictEqual(counter3[15], 2, 'Third counter should be 2')
41
+ assert.strictEqual(counter4[15], 7, 'Eighth counter should be 7')
42
+ console.log('Counter increments by blocks correctly')
43
+ })
44
+ await test('should handle chunk sizes correctly', async () => {
45
+ const crypto = new GenericAesCtrStreamingCrypto()
46
+ // Test different chunk sizes and verify block calculations
47
+ const testData = new Uint8Array(100).fill(0xaa) // 7 blocks (100 bytes = ceil(100/16) = 7)
48
+ const blob = new Blob([testData])
49
+ const { key, iv, encryptedStream } = await crypto.encryptStream(blob)
50
+ // Read encrypted data
51
+ const reader = encryptedStream.getReader()
52
+ let encryptedChunks = []
53
+ let done = false
54
+ while (!done) {
55
+ const result = await reader.read()
56
+ done = result.done
57
+ if (result.value) {
58
+ encryptedChunks.push(result.value)
59
+ }
60
+ }
61
+ // Verify we got data
62
+ assert(encryptedChunks.length > 0, 'Should have encrypted chunks')
63
+ // Decrypt to verify correctness
64
+ const combinedEncrypted = new Uint8Array(
65
+ encryptedChunks.reduce((sum, chunk) => sum + chunk.length, 0)
66
+ )
67
+ let offset = 0
68
+ for (const chunk of encryptedChunks) {
69
+ combinedEncrypted.set(chunk, offset)
70
+ offset += chunk.length
71
+ }
72
+ const encryptedStream2 = new ReadableStream({
73
+ start(controller) {
74
+ controller.enqueue(combinedEncrypted)
75
+ controller.close()
76
+ },
77
+ })
78
+ const decryptedStream = await crypto.decryptStream(
79
+ encryptedStream2,
80
+ key,
81
+ iv
82
+ )
83
+ const decryptedReader = decryptedStream.getReader()
84
+ let decryptedChunks = []
85
+ done = false
86
+ while (!done) {
87
+ const result = await decryptedReader.read()
88
+ done = result.done
89
+ if (result.value) {
90
+ decryptedChunks.push(result.value)
91
+ }
92
+ }
93
+ // Combine decrypted chunks
94
+ const combinedDecrypted = new Uint8Array(
95
+ decryptedChunks.reduce((sum, chunk) => sum + chunk.length, 0)
96
+ )
97
+ offset = 0
98
+ for (const chunk of decryptedChunks) {
99
+ combinedDecrypted.set(chunk, offset)
100
+ offset += chunk.length
101
+ }
102
+ // Verify perfect round-trip
103
+ assert.deepStrictEqual(
104
+ combinedDecrypted,
105
+ testData,
106
+ 'Decrypt must produce exact original data'
107
+ )
108
+ console.log('Chunk handling with block-based counters works correctly')
109
+ })
110
+ await test('should prevent keystream reuse in different chunk sizes', async () => {
111
+ const crypto = new GenericAesCtrStreamingCrypto()
112
+ // Test with different chunk sizes that would have caused reuse with old implementation
113
+ const testSizes = [15, 16, 17, 32, 33, 64, 65]
114
+ for (const size of testSizes) {
115
+ const testData = new Uint8Array(size).fill(0xbb)
116
+ const blob = new Blob([testData])
117
+ const { key, iv, encryptedStream } = await crypto.encryptStream(blob)
118
+ // Read encrypted data
119
+ const reader = encryptedStream.getReader()
120
+ let encryptedData = new Uint8Array(0)
121
+ let done = false
122
+ while (!done) {
123
+ const result = await reader.read()
124
+ done = result.done
125
+ if (result.value) {
126
+ const combined = new Uint8Array(
127
+ encryptedData.length + result.value.length
128
+ )
129
+ combined.set(encryptedData)
130
+ combined.set(result.value, encryptedData.length)
131
+ encryptedData = combined
48
132
  }
49
- // Verify we got data
50
- assert(encryptedChunks.length > 0, 'Should have encrypted chunks');
51
- // Decrypt to verify correctness
52
- const combinedEncrypted = new Uint8Array(encryptedChunks.reduce((sum, chunk) => sum + chunk.length, 0));
53
- let offset = 0;
54
- for (const chunk of encryptedChunks) {
55
- combinedEncrypted.set(chunk, offset);
56
- offset += chunk.length;
133
+ }
134
+ // Decrypt and verify
135
+ const encryptedStream2 = new ReadableStream({
136
+ start(controller) {
137
+ controller.enqueue(encryptedData)
138
+ controller.close()
139
+ },
140
+ })
141
+ const decryptedStream = await crypto.decryptStream(
142
+ encryptedStream2,
143
+ key,
144
+ iv
145
+ )
146
+ const decryptedReader = decryptedStream.getReader()
147
+ let decryptedData = new Uint8Array(0)
148
+ done = false
149
+ while (!done) {
150
+ const result = await decryptedReader.read()
151
+ done = result.done
152
+ if (result.value) {
153
+ const combined = new Uint8Array(
154
+ decryptedData.length + result.value.length
155
+ )
156
+ combined.set(decryptedData)
157
+ combined.set(result.value, decryptedData.length)
158
+ decryptedData = combined
57
159
  }
58
- const encryptedStream2 = new ReadableStream({
59
- start(controller) {
60
- controller.enqueue(combinedEncrypted);
61
- controller.close();
62
- },
63
- });
64
- const decryptedStream = await crypto.decryptStream(encryptedStream2, key, iv);
65
- const decryptedReader = decryptedStream.getReader();
66
- let decryptedChunks = [];
67
- done = false;
68
- while (!done) {
69
- const result = await decryptedReader.read();
70
- done = result.done;
71
- if (result.value) {
72
- decryptedChunks.push(result.value);
73
- }
74
- }
75
- // Combine decrypted chunks
76
- const combinedDecrypted = new Uint8Array(decryptedChunks.reduce((sum, chunk) => sum + chunk.length, 0));
77
- offset = 0;
78
- for (const chunk of decryptedChunks) {
79
- combinedDecrypted.set(chunk, offset);
80
- offset += chunk.length;
81
- }
82
- // Verify perfect round-trip
83
- assert.deepStrictEqual(combinedDecrypted, testData, 'Decrypt must produce exact original data');
84
- console.log('Chunk handling with block-based counters works correctly');
85
- });
86
- await test('should prevent keystream reuse in different chunk sizes', async () => {
87
- const crypto = new GenericAesCtrStreamingCrypto();
88
- // Test with different chunk sizes that would have caused reuse with old implementation
89
- const testSizes = [15, 16, 17, 32, 33, 64, 65];
90
- for (const size of testSizes) {
91
- const testData = new Uint8Array(size).fill(0xbb);
92
- const blob = new Blob([testData]);
93
- const { key, iv, encryptedStream } = await crypto.encryptStream(blob);
94
- // Read encrypted data
95
- const reader = encryptedStream.getReader();
96
- let encryptedData = new Uint8Array(0);
97
- let done = false;
98
- while (!done) {
99
- const result = await reader.read();
100
- done = result.done;
101
- if (result.value) {
102
- const combined = new Uint8Array(encryptedData.length + result.value.length);
103
- combined.set(encryptedData);
104
- combined.set(result.value, encryptedData.length);
105
- encryptedData = combined;
106
- }
107
- }
108
- // Decrypt and verify
109
- const encryptedStream2 = new ReadableStream({
110
- start(controller) {
111
- controller.enqueue(encryptedData);
112
- controller.close();
113
- },
114
- });
115
- const decryptedStream = await crypto.decryptStream(encryptedStream2, key, iv);
116
- const decryptedReader = decryptedStream.getReader();
117
- let decryptedData = new Uint8Array(0);
118
- done = false;
119
- while (!done) {
120
- const result = await decryptedReader.read();
121
- done = result.done;
122
- if (result.value) {
123
- const combined = new Uint8Array(decryptedData.length + result.value.length);
124
- combined.set(decryptedData);
125
- combined.set(result.value, decryptedData.length);
126
- decryptedData = combined;
127
- }
128
- }
129
- assert.deepStrictEqual(decryptedData, testData, `Encryption/decryption failed for ${size}-byte chunk`);
130
- }
131
- console.log('No keystream reuse detected across different chunk sizes');
132
- });
133
- await test('should throw a clear error if Web Crypto API is not available', async () => {
134
- // Save and remove globalThis.crypto
135
- const originalCrypto = globalThis.crypto;
136
- try {
137
- // @ts-expect-error
138
- delete globalThis.crypto;
139
- assert.throws(() => new GenericAesCtrStreamingCrypto(), /Web Crypto API|crypto( is)? not available/i, 'Should throw if Web Crypto API is missing');
140
- }
141
- finally {
142
- // Restore globalThis.crypto
143
- globalThis.crypto = originalCrypto;
144
- }
145
- });
146
- });
147
- //# sourceMappingURL=crypto-counter-security.spec.js.map
160
+ }
161
+ assert.deepStrictEqual(
162
+ decryptedData,
163
+ testData,
164
+ `Encryption/decryption failed for ${size}-byte chunk`
165
+ )
166
+ }
167
+ console.log('No keystream reuse detected across different chunk sizes')
168
+ })
169
+ await test('should throw a clear error if Web Crypto API is not available', async () => {
170
+ // Save and remove globalThis.crypto
171
+ const originalCrypto = globalThis.crypto
172
+ try {
173
+ // @ts-expect-error
174
+ delete globalThis.crypto
175
+ assert.throws(
176
+ () => new GenericAesCtrStreamingCrypto(),
177
+ /Web Crypto API|crypto( is)? not available/i,
178
+ 'Should throw if Web Crypto API is missing'
179
+ )
180
+ } finally {
181
+ // Restore globalThis.crypto
182
+ globalThis.crypto = originalCrypto
183
+ }
184
+ })
185
+ })
186
+ //# sourceMappingURL=crypto-counter-security.spec.js.map
@@ -1,2 +1,2 @@
1
- export {};
2
- //# sourceMappingURL=crypto-streaming.spec.d.ts.map
1
+ export {}
2
+ //# sourceMappingURL=crypto-streaming.spec.d.ts.map