@zip.js/zip.js 2.5.3 → 2.5.7
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.
- package/dist/z-worker-fflate.js +1 -1
- package/dist/z-worker-pako.js +1 -1
- package/dist/z-worker.js +1 -1
- package/dist/zip-fs-full.js +470 -499
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +470 -499
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +470 -499
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +470 -499
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +1 -1
- package/index.d.ts +1 -1
- package/index.js +3 -3
- package/lib/core/{engine.js → codec-interface.js} +52 -50
- package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +55 -29
- package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
- package/lib/core/configuration.js +10 -1
- package/lib/core/io.js +102 -100
- package/lib/core/{codecs → streams}/aes-crypto-stream.js +68 -54
- package/lib/core/{codecs → streams}/codec-stream.js +6 -6
- package/lib/core/{codecs → streams/codecs}/crc32.js +0 -0
- package/lib/core/{codecs → streams/codecs}/deflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/inflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/sjcl.js +0 -0
- package/lib/core/{codecs → streams}/crc32-stream.js +3 -4
- package/lib/core/{codecs → streams}/zip-crypto-stream.js +28 -32
- package/lib/core/streams/zip-entry-stream.js +185 -0
- package/lib/core/z-worker-core.js +30 -15
- package/lib/core/zip-fs-core.js +1 -1
- package/lib/core/zip-reader.js +21 -12
- package/lib/core/zip-writer.js +33 -25
- package/lib/z-worker-fflate.js +4 -1
- package/lib/z-worker-inline.js +1 -1
- package/lib/z-worker.js +2 -2
- package/lib/zip-fflate-shim.js +4 -1
- package/lib/zip-fs.js +6 -2
- package/lib/zip-full-fflate.js +6 -3
- package/lib/zip-full.js +8 -5
- package/lib/zip-no-worker-deflate.js +7 -3
- package/lib/zip-no-worker-fflate-deflate.js +6 -2
- package/lib/zip-no-worker-fflate-inflate.js +6 -3
- package/lib/zip-no-worker-fflate.js +6 -3
- package/lib/zip-no-worker-inflate.js +7 -4
- package/lib/zip-no-worker.js +8 -5
- package/lib/zip.js +6 -3
- package/package.json +2 -8
- package/lib/core/codecs/codec.js +0 -246
package/lib/core/io.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Blob, FileReader, atob, btoa, XMLHttpRequest, document, fetch */
|
|
29
|
+
/* global Blob, FileReader, atob, btoa, XMLHttpRequest, document, fetch, ReadableStream, WritableStream */
|
|
30
30
|
|
|
31
31
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
32
32
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
@@ -40,6 +40,7 @@ const HTTP_HEADER_RANGE = "Range";
|
|
|
40
40
|
const HTTP_METHOD_HEAD = "HEAD";
|
|
41
41
|
const HTTP_METHOD_GET = "GET";
|
|
42
42
|
const HTTP_RANGE_UNIT = "bytes";
|
|
43
|
+
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
43
44
|
|
|
44
45
|
class Stream {
|
|
45
46
|
|
|
@@ -53,9 +54,39 @@ class Stream {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
class Reader extends Stream {
|
|
57
|
+
|
|
58
|
+
getStream({ offset, size, chunkSize } = { offset: 0, chunkSize: DEFAULT_CHUNK_SIZE }) {
|
|
59
|
+
const reader = this;
|
|
60
|
+
return new ReadableStream({
|
|
61
|
+
start() {
|
|
62
|
+
this.chunkOffset = 0;
|
|
63
|
+
},
|
|
64
|
+
async pull(controller) {
|
|
65
|
+
const { chunkOffset } = this;
|
|
66
|
+
controller.enqueue(await reader.readUint8Array(offset + chunkOffset, Math.min(chunkSize, size() - chunkOffset)));
|
|
67
|
+
if (chunkOffset + chunkSize > size()) {
|
|
68
|
+
controller.close();
|
|
69
|
+
} else {
|
|
70
|
+
this.chunkOffset += chunkSize;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
class WriterStream extends Stream {
|
|
78
|
+
|
|
79
|
+
getStream() {
|
|
80
|
+
const writer = this;
|
|
81
|
+
return new WritableStream({
|
|
82
|
+
write(chunk) {
|
|
83
|
+
return writer.writeUint8Array(chunk);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
56
87
|
}
|
|
57
88
|
|
|
58
|
-
class Writer extends
|
|
89
|
+
class Writer extends WriterStream {
|
|
59
90
|
|
|
60
91
|
writeUint8Array(array) {
|
|
61
92
|
this.size += array.length;
|
|
@@ -70,9 +101,10 @@ class TextReader extends Reader {
|
|
|
70
101
|
}
|
|
71
102
|
|
|
72
103
|
init() {
|
|
104
|
+
const reader = this;
|
|
73
105
|
super.init();
|
|
74
|
-
|
|
75
|
-
|
|
106
|
+
reader.blobReader.init();
|
|
107
|
+
reader.size = reader.blobReader.size;
|
|
76
108
|
}
|
|
77
109
|
|
|
78
110
|
readUint8Array(offset, length) {
|
|
@@ -94,14 +126,15 @@ class TextWriter extends Writer {
|
|
|
94
126
|
}
|
|
95
127
|
|
|
96
128
|
getData() {
|
|
97
|
-
|
|
98
|
-
|
|
129
|
+
const writer = this;
|
|
130
|
+
if (writer.blob.text) {
|
|
131
|
+
return writer.blob.text();
|
|
99
132
|
} else {
|
|
100
133
|
const reader = new FileReader();
|
|
101
134
|
return new Promise((resolve, reject) => {
|
|
102
135
|
reader.onload = event => resolve(event.target.result);
|
|
103
136
|
reader.onerror = () => reject(reader.error);
|
|
104
|
-
reader.readAsText(
|
|
137
|
+
reader.readAsText(writer.blob, writer.encoding);
|
|
105
138
|
});
|
|
106
139
|
}
|
|
107
140
|
}
|
|
@@ -111,19 +144,21 @@ class Data64URIReader extends Reader {
|
|
|
111
144
|
|
|
112
145
|
constructor(dataURI) {
|
|
113
146
|
super();
|
|
114
|
-
|
|
147
|
+
const reader = this;
|
|
148
|
+
reader.dataURI = dataURI;
|
|
115
149
|
let dataEnd = dataURI.length;
|
|
116
150
|
while (dataURI.charAt(dataEnd - 1) == "=") {
|
|
117
151
|
dataEnd--;
|
|
118
152
|
}
|
|
119
|
-
|
|
120
|
-
|
|
153
|
+
reader.dataStart = dataURI.indexOf(",") + 1;
|
|
154
|
+
reader.size = Math.floor((dataEnd - reader.dataStart) * 0.75);
|
|
121
155
|
}
|
|
122
156
|
|
|
123
157
|
readUint8Array(offset, length) {
|
|
124
158
|
const dataArray = new Uint8Array(length);
|
|
125
159
|
const start = Math.floor(offset / 3) * 4;
|
|
126
|
-
const
|
|
160
|
+
const dataStart = this.dataStart;
|
|
161
|
+
const bytes = atob(this.dataURI.substring(start + dataStart, Math.ceil((offset + length) / 3) * 4 + dataStart));
|
|
127
162
|
const delta = offset - Math.floor(start / 4) * 3;
|
|
128
163
|
for (let indexByte = delta; indexByte < delta + length; indexByte++) {
|
|
129
164
|
dataArray[indexByte - delta] = bytes.charCodeAt(indexByte);
|
|
@@ -142,20 +177,21 @@ class Data64URIWriter extends Writer {
|
|
|
142
177
|
|
|
143
178
|
writeUint8Array(array) {
|
|
144
179
|
super.writeUint8Array(array);
|
|
180
|
+
const writer = this;
|
|
145
181
|
let indexArray = 0;
|
|
146
|
-
let dataString =
|
|
147
|
-
const delta =
|
|
148
|
-
|
|
182
|
+
let dataString = writer.pending;
|
|
183
|
+
const delta = writer.pending.length;
|
|
184
|
+
writer.pending = "";
|
|
149
185
|
for (indexArray = 0; indexArray < (Math.floor((delta + array.length) / 3) * 3) - delta; indexArray++) {
|
|
150
186
|
dataString += String.fromCharCode(array[indexArray]);
|
|
151
187
|
}
|
|
152
188
|
for (; indexArray < array.length; indexArray++) {
|
|
153
|
-
|
|
189
|
+
writer.pending += String.fromCharCode(array[indexArray]);
|
|
154
190
|
}
|
|
155
191
|
if (dataString.length > 2) {
|
|
156
|
-
|
|
192
|
+
writer.data += btoa(dataString);
|
|
157
193
|
} else {
|
|
158
|
-
|
|
194
|
+
writer.pending = dataString;
|
|
159
195
|
}
|
|
160
196
|
}
|
|
161
197
|
|
|
@@ -173,14 +209,15 @@ class BlobReader extends Reader {
|
|
|
173
209
|
}
|
|
174
210
|
|
|
175
211
|
async readUint8Array(offset, length) {
|
|
176
|
-
|
|
177
|
-
|
|
212
|
+
const reader = this;
|
|
213
|
+
if (reader.blob.arrayBuffer) {
|
|
214
|
+
return new Uint8Array(await reader.blob.slice(offset, offset + length).arrayBuffer());
|
|
178
215
|
} else {
|
|
179
216
|
const reader = new FileReader();
|
|
180
217
|
return new Promise((resolve, reject) => {
|
|
181
218
|
reader.onload = event => resolve(new Uint8Array(event.target.result));
|
|
182
219
|
reader.onerror = () => reject(reader.error);
|
|
183
|
-
reader.readAsArrayBuffer(
|
|
220
|
+
reader.readAsArrayBuffer(reader.blob.slice(offset, offset + length));
|
|
184
221
|
});
|
|
185
222
|
}
|
|
186
223
|
}
|
|
@@ -197,21 +234,23 @@ class BlobWriter extends Writer {
|
|
|
197
234
|
|
|
198
235
|
writeUint8Array(array) {
|
|
199
236
|
super.writeUint8Array(array);
|
|
200
|
-
|
|
201
|
-
|
|
237
|
+
const writer = this;
|
|
238
|
+
if (writer.arrayBuffers.length == writer.arrayBuffersMaxlength) {
|
|
239
|
+
flushArrayBuffers(writer);
|
|
202
240
|
}
|
|
203
|
-
|
|
241
|
+
writer.arrayBuffers.push(array.buffer);
|
|
204
242
|
}
|
|
205
243
|
|
|
206
244
|
getData() {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
245
|
+
const writer = this;
|
|
246
|
+
if (!writer.blob) {
|
|
247
|
+
if (writer.arrayBuffers.length) {
|
|
248
|
+
flushArrayBuffers(writer);
|
|
210
249
|
}
|
|
211
|
-
|
|
212
|
-
initArrayBuffers(
|
|
250
|
+
writer.blob = writer.pendingBlob;
|
|
251
|
+
initArrayBuffers(writer);
|
|
213
252
|
}
|
|
214
|
-
return
|
|
253
|
+
return writer.blob;
|
|
215
254
|
}
|
|
216
255
|
}
|
|
217
256
|
|
|
@@ -229,78 +268,38 @@ class ReadableStreamReader {
|
|
|
229
268
|
|
|
230
269
|
constructor(readableStream) {
|
|
231
270
|
this.readableStream = readableStream;
|
|
232
|
-
this.reader = readableStream.getReader();
|
|
233
271
|
this.size = Infinity;
|
|
234
|
-
this.index = 0;
|
|
235
|
-
this.currentSize = 0;
|
|
236
|
-
this.pendingValue = new Uint8Array();
|
|
237
272
|
}
|
|
238
273
|
|
|
239
|
-
init() {
|
|
274
|
+
init(size) {
|
|
275
|
+
this.size = size;
|
|
240
276
|
this.initialized = true;
|
|
241
277
|
}
|
|
242
278
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
throw new Error(ERR_NOT_SEEKABLE_READER);
|
|
246
|
-
}
|
|
247
|
-
let data = new Uint8Array(length);
|
|
248
|
-
let size = 0, done;
|
|
249
|
-
do {
|
|
250
|
-
const result = await this.reader.read();
|
|
251
|
-
let { value } = result;
|
|
252
|
-
done = result.done;
|
|
253
|
-
if (value) {
|
|
254
|
-
this.currentSize += value.length;
|
|
255
|
-
} else {
|
|
256
|
-
value = this.pendingValue;
|
|
257
|
-
this.pendingValue = new Uint8Array();
|
|
258
|
-
}
|
|
259
|
-
if (this.pendingValue.length) {
|
|
260
|
-
const newValue = new Uint8Array(this.pendingValue.length + value.length);
|
|
261
|
-
newValue.set(this.pendingValue);
|
|
262
|
-
newValue.set(value, this.pendingValue.length);
|
|
263
|
-
this.pendingValue = new Uint8Array();
|
|
264
|
-
value = newValue;
|
|
265
|
-
}
|
|
266
|
-
if (size + value.length > length) {
|
|
267
|
-
data.set(value.subarray(0, length), size);
|
|
268
|
-
this.pendingValue = value.subarray(length);
|
|
269
|
-
size += length;
|
|
270
|
-
} else {
|
|
271
|
-
data.set(value, size);
|
|
272
|
-
size += value.length;
|
|
273
|
-
}
|
|
274
|
-
} while (size < length && !done);
|
|
275
|
-
if (done && this.size == Infinity) {
|
|
276
|
-
this.size = this.currentSize;
|
|
277
|
-
}
|
|
278
|
-
if (this.size < length) {
|
|
279
|
-
data = data.slice(0, this.size);
|
|
280
|
-
length = this.size;
|
|
281
|
-
}
|
|
282
|
-
this.index += length;
|
|
283
|
-
return data;
|
|
279
|
+
getStream() {
|
|
280
|
+
return this.readableStream;
|
|
284
281
|
}
|
|
285
282
|
}
|
|
286
283
|
|
|
287
284
|
class WritableStreamWriter extends Writer {
|
|
288
285
|
|
|
289
|
-
constructor(
|
|
286
|
+
constructor(writable) {
|
|
290
287
|
super();
|
|
291
|
-
|
|
292
|
-
|
|
288
|
+
const writer = this;
|
|
289
|
+
writer.writable = writable;
|
|
293
290
|
}
|
|
294
291
|
|
|
295
292
|
async writeUint8Array(array) {
|
|
296
293
|
await this.writer.ready;
|
|
297
|
-
return this.
|
|
294
|
+
return this.writable.getWriter().write(array);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
getStream() {
|
|
298
|
+
return this.writable;
|
|
298
299
|
}
|
|
299
300
|
|
|
300
301
|
async getData() {
|
|
301
|
-
|
|
302
|
-
await this.writer.close();
|
|
303
|
-
return this.writableStream;
|
|
302
|
+
return this.writable;
|
|
304
303
|
}
|
|
305
304
|
}
|
|
306
305
|
|
|
@@ -308,15 +307,16 @@ class FetchReader extends Reader {
|
|
|
308
307
|
|
|
309
308
|
constructor(url, options) {
|
|
310
309
|
super();
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
delete
|
|
318
|
-
delete
|
|
319
|
-
delete
|
|
310
|
+
const reader = this;
|
|
311
|
+
reader.url = url;
|
|
312
|
+
reader.preventHeadRequest = options.preventHeadRequest;
|
|
313
|
+
reader.useRangeHeader = options.useRangeHeader;
|
|
314
|
+
reader.forceRangeRequests = options.forceRangeRequests;
|
|
315
|
+
reader.options = Object.assign({}, options);
|
|
316
|
+
delete reader.options.preventHeadRequest;
|
|
317
|
+
delete reader.options.useRangeHeader;
|
|
318
|
+
delete reader.options.forceRangeRequests;
|
|
319
|
+
delete reader.options.useXHR;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
async init() {
|
|
@@ -333,11 +333,12 @@ class XHRReader extends Reader {
|
|
|
333
333
|
|
|
334
334
|
constructor(url, options) {
|
|
335
335
|
super();
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
336
|
+
const reader = this;
|
|
337
|
+
reader.url = url;
|
|
338
|
+
reader.preventHeadRequest = options.preventHeadRequest;
|
|
339
|
+
reader.useRangeHeader = options.useRangeHeader;
|
|
340
|
+
reader.forceRangeRequests = options.forceRangeRequests;
|
|
341
|
+
reader.options = options;
|
|
341
342
|
}
|
|
342
343
|
|
|
343
344
|
async init() {
|
|
@@ -540,10 +541,11 @@ class Uint8ArrayWriter extends Writer {
|
|
|
540
541
|
|
|
541
542
|
writeUint8Array(array) {
|
|
542
543
|
super.writeUint8Array(array);
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
544
|
+
const writer = this;
|
|
545
|
+
const previousArray = writer.array;
|
|
546
|
+
writer.array = new Uint8Array(previousArray.length + array.length);
|
|
547
|
+
writer.array.set(previousArray);
|
|
548
|
+
writer.array.set(array, previousArray.length);
|
|
547
549
|
}
|
|
548
550
|
|
|
549
551
|
getData() {
|
|
@@ -30,7 +30,13 @@
|
|
|
30
30
|
// deno-lint-ignore-file no-this-alias
|
|
31
31
|
|
|
32
32
|
import encodeText from "./../util/encode-text.js";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
cipher,
|
|
35
|
+
codec,
|
|
36
|
+
misc,
|
|
37
|
+
mode,
|
|
38
|
+
random
|
|
39
|
+
} from "./codecs/sjcl.js";
|
|
34
40
|
|
|
35
41
|
const ERR_INVALID_PASSWORD = "Invalid pasword";
|
|
36
42
|
const BLOCK_LENGTH = 16;
|
|
@@ -45,14 +51,19 @@ const SALT_LENGTH = [8, 12, 16];
|
|
|
45
51
|
const KEY_LENGTH = [16, 24, 32];
|
|
46
52
|
const SIGNATURE_LENGTH = 10;
|
|
47
53
|
const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
|
|
48
|
-
const
|
|
49
|
-
const
|
|
54
|
+
const UNDEFINED_TYPE = "undefined";
|
|
55
|
+
const FUNCTION_TYPE = "function";
|
|
56
|
+
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
57
|
+
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof crypto.subtle != UNDEFINED_TYPE;
|
|
58
|
+
const GET_RANDOM_VALUES_SUPPORTED = CRYPTO_API_SUPPORTED && typeof crypto.getRandomValues == FUNCTION_TYPE;
|
|
59
|
+
const IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof crypto.subtle.importKey == FUNCTION_TYPE;
|
|
60
|
+
const DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof crypto.subtle.deriveBits == FUNCTION_TYPE;
|
|
50
61
|
const codecBytes = codec.bytes;
|
|
51
62
|
const Aes = cipher.aes;
|
|
52
63
|
const CtrGladman = mode.ctrGladman;
|
|
53
64
|
const HmacSha1 = misc.hmacSha1;
|
|
54
65
|
|
|
55
|
-
class
|
|
66
|
+
class AESDecryptionStream extends TransformStream {
|
|
56
67
|
|
|
57
68
|
constructor(password, signed, strength) {
|
|
58
69
|
let stream;
|
|
@@ -67,23 +78,21 @@ class AESDecryptStream extends TransformStream {
|
|
|
67
78
|
});
|
|
68
79
|
},
|
|
69
80
|
async transform(chunk, controller) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
await aesCrypto.ready;
|
|
83
|
-
}
|
|
84
|
-
const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH));
|
|
85
|
-
controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true));
|
|
81
|
+
const aesCrypto = this;
|
|
82
|
+
if (aesCrypto.password) {
|
|
83
|
+
const password = aesCrypto.password;
|
|
84
|
+
aesCrypto.password = null;
|
|
85
|
+
const preamble = subarray(chunk, 0, SALT_LENGTH[aesCrypto.strength] + 2);
|
|
86
|
+
await createDecryptionKeys(aesCrypto, preamble, password);
|
|
87
|
+
aesCrypto.ctr = new CtrGladman(new Aes(aesCrypto.keys.key), Array.from(COUNTER_DEFAULT_VALUE));
|
|
88
|
+
aesCrypto.hmac = new HmacSha1(aesCrypto.keys.authentication);
|
|
89
|
+
chunk = subarray(chunk, SALT_LENGTH[aesCrypto.strength] + 2);
|
|
90
|
+
aesCrypto.resolveReady();
|
|
91
|
+
} else {
|
|
92
|
+
await aesCrypto.ready;
|
|
86
93
|
}
|
|
94
|
+
const output = new Uint8Array(chunk.length - SIGNATURE_LENGTH - ((chunk.length - SIGNATURE_LENGTH) % BLOCK_LENGTH));
|
|
95
|
+
controller.enqueue(append(aesCrypto, chunk, output, 0, SIGNATURE_LENGTH, true));
|
|
87
96
|
},
|
|
88
97
|
async flush(controller) {
|
|
89
98
|
const aesCrypto = this;
|
|
@@ -93,14 +102,14 @@ class AESDecryptStream extends TransformStream {
|
|
|
93
102
|
const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH);
|
|
94
103
|
let decryptedChunkArray = new Uint8Array(0);
|
|
95
104
|
if (chunkToDecrypt.length) {
|
|
96
|
-
const encryptedChunk =
|
|
105
|
+
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
97
106
|
aesCrypto.hmac.update(encryptedChunk);
|
|
98
|
-
const decryptedChunk = aesCrypto.
|
|
99
|
-
decryptedChunkArray =
|
|
107
|
+
const decryptedChunk = aesCrypto.ctr.update(encryptedChunk);
|
|
108
|
+
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
100
109
|
}
|
|
101
110
|
stream.valid = true;
|
|
102
111
|
if (aesCrypto.signed) {
|
|
103
|
-
const signature = subarray(
|
|
112
|
+
const signature = subarray(fromBits(codecBytes, aesCrypto.hmac.digest()), 0, SIGNATURE_LENGTH);
|
|
104
113
|
for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) {
|
|
105
114
|
if (signature[indexSignature] != originalSignature[indexSignature]) {
|
|
106
115
|
stream.valid = false;
|
|
@@ -114,7 +123,7 @@ class AESDecryptStream extends TransformStream {
|
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
class
|
|
126
|
+
class AESEncryptionStream extends TransformStream {
|
|
118
127
|
|
|
119
128
|
constructor(password, strength) {
|
|
120
129
|
let stream;
|
|
@@ -128,34 +137,32 @@ class AESEncryptStream extends TransformStream {
|
|
|
128
137
|
});
|
|
129
138
|
},
|
|
130
139
|
async transform(chunk, controller) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
await aesCrypto.ready;
|
|
143
|
-
}
|
|
144
|
-
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
145
|
-
output.set(preamble, 0);
|
|
146
|
-
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
140
|
+
const aesCrypto = this;
|
|
141
|
+
let preamble = new Uint8Array(0);
|
|
142
|
+
if (aesCrypto.password) {
|
|
143
|
+
const password = aesCrypto.password;
|
|
144
|
+
aesCrypto.password = null;
|
|
145
|
+
preamble = await createEncryptionKeys(aesCrypto, password);
|
|
146
|
+
aesCrypto.ctr = new CtrGladman(new Aes(aesCrypto.keys.key), Array.from(COUNTER_DEFAULT_VALUE));
|
|
147
|
+
aesCrypto.hmac = new HmacSha1(aesCrypto.keys.authentication);
|
|
148
|
+
aesCrypto.resolveReady();
|
|
149
|
+
} else {
|
|
150
|
+
await aesCrypto.ready;
|
|
147
151
|
}
|
|
152
|
+
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
153
|
+
output.set(preamble, 0);
|
|
154
|
+
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
148
155
|
},
|
|
149
156
|
async flush(controller) {
|
|
150
157
|
const aesCrypto = this;
|
|
151
158
|
await aesCrypto.ready;
|
|
152
159
|
let encryptedChunkArray = new Uint8Array(0);
|
|
153
160
|
if (aesCrypto.pending.length) {
|
|
154
|
-
const encryptedChunk = aesCrypto.
|
|
161
|
+
const encryptedChunk = aesCrypto.ctr.update(toBits(codecBytes, aesCrypto.pending));
|
|
155
162
|
aesCrypto.hmac.update(encryptedChunk);
|
|
156
|
-
encryptedChunkArray =
|
|
163
|
+
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
157
164
|
}
|
|
158
|
-
stream.signature =
|
|
165
|
+
stream.signature = fromBits(codecBytes, aesCrypto.hmac.digest()).slice(0, SIGNATURE_LENGTH);
|
|
159
166
|
controller.enqueue(concat(encryptedChunkArray, stream.signature));
|
|
160
167
|
}
|
|
161
168
|
});
|
|
@@ -164,8 +171,8 @@ class AESEncryptStream extends TransformStream {
|
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
export {
|
|
167
|
-
|
|
168
|
-
|
|
174
|
+
AESDecryptionStream,
|
|
175
|
+
AESEncryptionStream,
|
|
169
176
|
ERR_INVALID_PASSWORD
|
|
170
177
|
};
|
|
171
178
|
|
|
@@ -177,15 +184,15 @@ function append(aesCrypto, input, output, paddingStart, paddingEnd, verifySignat
|
|
|
177
184
|
}
|
|
178
185
|
let offset;
|
|
179
186
|
for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) {
|
|
180
|
-
const inputChunk =
|
|
187
|
+
const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH));
|
|
181
188
|
if (verifySignature) {
|
|
182
189
|
aesCrypto.hmac.update(inputChunk);
|
|
183
190
|
}
|
|
184
|
-
const outputChunk = aesCrypto.
|
|
191
|
+
const outputChunk = aesCrypto.ctr.update(inputChunk);
|
|
185
192
|
if (!verifySignature) {
|
|
186
193
|
aesCrypto.hmac.update(outputChunk);
|
|
187
194
|
}
|
|
188
|
-
output.set(
|
|
195
|
+
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
189
196
|
}
|
|
190
197
|
aesCrypto.pending = subarray(input, offset);
|
|
191
198
|
return output;
|
|
@@ -212,14 +219,14 @@ async function createKeys(target, password, salt) {
|
|
|
212
219
|
const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), basekey, 8 * ((KEY_LENGTH[target.strength] * 2) + 2));
|
|
213
220
|
const compositeKey = new Uint8Array(derivedBits);
|
|
214
221
|
target.keys = {
|
|
215
|
-
key:
|
|
216
|
-
authentication:
|
|
222
|
+
key: toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[target.strength])),
|
|
223
|
+
authentication: toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[target.strength], KEY_LENGTH[target.strength] * 2)),
|
|
217
224
|
passwordVerification: subarray(compositeKey, KEY_LENGTH[target.strength] * 2)
|
|
218
225
|
};
|
|
219
226
|
}
|
|
220
227
|
|
|
221
228
|
function getRandomValues(array) {
|
|
222
|
-
if (
|
|
229
|
+
if (GET_RANDOM_VALUES_SUPPORTED) {
|
|
223
230
|
return crypto.getRandomValues(array);
|
|
224
231
|
} else {
|
|
225
232
|
return random.getRandomValues(array);
|
|
@@ -227,7 +234,7 @@ function getRandomValues(array) {
|
|
|
227
234
|
}
|
|
228
235
|
|
|
229
236
|
function importKey(format, password, algorithm, extractable, keyUsages) {
|
|
230
|
-
if (
|
|
237
|
+
if (IMPORT_KEY_SUPPORTED) {
|
|
231
238
|
return crypto.subtle.importKey(format, password, algorithm, extractable, keyUsages);
|
|
232
239
|
} else {
|
|
233
240
|
return misc.importKey(password);
|
|
@@ -235,7 +242,7 @@ function importKey(format, password, algorithm, extractable, keyUsages) {
|
|
|
235
242
|
}
|
|
236
243
|
|
|
237
244
|
async function deriveBits(algorithm, baseKey, length) {
|
|
238
|
-
if (
|
|
245
|
+
if (DERIVE_BITS_SUPPORTED) {
|
|
239
246
|
return await crypto.subtle.deriveBits(algorithm, baseKey, length);
|
|
240
247
|
} else {
|
|
241
248
|
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
@@ -263,4 +270,11 @@ function expand(inputArray, length) {
|
|
|
263
270
|
|
|
264
271
|
function subarray(array, begin, end) {
|
|
265
272
|
return array.subarray(begin, end);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function fromBits(codecBytes, chunk) {
|
|
276
|
+
return codecBytes.fromBits(chunk);
|
|
277
|
+
}
|
|
278
|
+
function toBits(codecBytes, chunk) {
|
|
279
|
+
return codecBytes.toBits(chunk);
|
|
266
280
|
}
|
|
@@ -36,19 +36,19 @@
|
|
|
36
36
|
/* global TransformStream */
|
|
37
37
|
|
|
38
38
|
class CodecStream extends TransformStream {
|
|
39
|
+
|
|
39
40
|
constructor(Codec, options) {
|
|
41
|
+
let codec;
|
|
40
42
|
super({
|
|
41
43
|
start() {
|
|
42
|
-
|
|
44
|
+
codec = new Codec(options);
|
|
43
45
|
},
|
|
44
46
|
transform(chunk, controller) {
|
|
45
|
-
chunk =
|
|
46
|
-
|
|
47
|
-
controller.enqueue(chunk);
|
|
48
|
-
}
|
|
47
|
+
chunk = codec.append(chunk);
|
|
48
|
+
controller.enqueue(chunk);
|
|
49
49
|
},
|
|
50
50
|
flush(controller) {
|
|
51
|
-
const chunk =
|
|
51
|
+
const chunk = codec.flush();
|
|
52
52
|
if (chunk) {
|
|
53
53
|
controller.enqueue(chunk);
|
|
54
54
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -28,18 +28,17 @@
|
|
|
28
28
|
|
|
29
29
|
/* global TransformStream */
|
|
30
30
|
|
|
31
|
-
import Crc32 from "./crc32.js";
|
|
31
|
+
import Crc32 from "./codecs/crc32.js";
|
|
32
32
|
|
|
33
33
|
class Crc32Stream extends TransformStream {
|
|
34
|
+
|
|
34
35
|
constructor() {
|
|
35
36
|
super({
|
|
36
37
|
start() {
|
|
37
38
|
this.crc32 = new Crc32();
|
|
38
39
|
},
|
|
39
40
|
transform(chunk) {
|
|
40
|
-
|
|
41
|
-
this.crc32.append(chunk);
|
|
42
|
-
}
|
|
41
|
+
this.crc32.append(chunk);
|
|
43
42
|
},
|
|
44
43
|
flush(controller) {
|
|
45
44
|
const value = new Uint8Array(4);
|