@zip.js/zip.js 2.13.0 → 2.14.0
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/BENCHMARKS.md +46 -1
- package/deno.json +1 -1
- package/dist/zip-core-external.js +594 -935
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +461 -908
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +601 -938
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +468 -911
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +601 -938
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +470 -913
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +604 -941
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +463 -910
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-module.wasm +0 -0
- package/dist/zip-native.js +463 -910
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker-native.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +597 -938
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +470 -913
- package/index-native.min.js +1 -1
- package/index.cjs +604 -941
- package/index.d.cts +58 -12
- package/index.d.ts +58 -12
- package/index.min.js +1 -1
- package/lib/core/codec-worker-web.js +35 -11
- package/lib/core/codec-worker.js +33 -23
- package/lib/core/io.js +29 -21
- package/lib/core/streams/aes-crypto-stream.js +58 -99
- package/lib/core/streams/codecs/aes-hmac-sha1.js +348 -0
- package/lib/core/streams/zlib-wasm/aes-hmac-sha1-wasm.js +106 -0
- package/lib/core/streams/zlib-wasm/zlib-streams-loader.js +4 -0
- package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-base.js +15 -9
- package/lib/core/web-worker-inline-native.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/web-worker-wasm.js +2 -0
- package/lib/core/zip-fs.js +7 -3
- package/lib/core/zip-writer.js +1 -2
- package/lib/core/zlib-streams-inline.js +1 -1
- package/lib/zip-module-wasm-base.js +3 -1
- package/package.json +1 -1
- package/lib/core/streams/codecs/sjcl.js +0 -795
package/dist/zip-fs-core.js
CHANGED
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
T[k][n] = (previous >>> 8) ^ T[0][previous & 0xFF];
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
|
-
const [T0, T1, T2, T3, T4, T5, T6, T7] = T;
|
|
576
|
+
const [T0$1, T1$1, T2$1, T3$1, T4, T5, T6, T7] = T;
|
|
577
577
|
|
|
578
578
|
class Crc32 {
|
|
579
579
|
|
|
@@ -595,12 +595,12 @@
|
|
|
595
595
|
const a = crc ^ view.getInt32(offset, true);
|
|
596
596
|
const b = view.getInt32(offset + 4, true);
|
|
597
597
|
crc = T7[a & 0xFF] ^ T6[(a >>> 8) & 0xFF] ^ T5[(a >>> 16) & 0xFF] ^ T4[(a >>> 24) & 0xFF] ^
|
|
598
|
-
T3[b & 0xFF] ^ T2[(b >>> 8) & 0xFF] ^ T1[(b >>> 16) & 0xFF] ^ T0[(b >>> 24) & 0xFF];
|
|
598
|
+
T3$1[b & 0xFF] ^ T2$1[(b >>> 8) & 0xFF] ^ T1$1[(b >>> 16) & 0xFF] ^ T0$1[(b >>> 24) & 0xFF];
|
|
599
599
|
}
|
|
600
600
|
}
|
|
601
601
|
// Remaining tail (and non-typed inputs) byte-at-a-time with the base table.
|
|
602
602
|
for (; offset < length; offset++) {
|
|
603
|
-
crc = (crc >>> 8) ^ T0[(crc ^ data[offset]) & 0xFF];
|
|
603
|
+
crc = (crc >>> 8) ^ T0$1[(crc ^ data[offset]) & 0xFF];
|
|
604
604
|
}
|
|
605
605
|
this.crc = crc;
|
|
606
606
|
}
|
|
@@ -704,794 +704,349 @@
|
|
|
704
704
|
}
|
|
705
705
|
}
|
|
706
706
|
|
|
707
|
-
// Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
|
|
708
|
-
|
|
709
|
-
// deno-lint-ignore-file no-this-alias
|
|
710
|
-
|
|
711
707
|
/*
|
|
712
|
-
|
|
713
|
-
* license or under the GNU GPL, version 2.0.
|
|
714
|
-
*/
|
|
715
|
-
|
|
716
|
-
/** @fileOverview Javascript cryptography implementation.
|
|
717
|
-
*
|
|
718
|
-
* Crush to remove comments, shorten variable names and
|
|
719
|
-
* generally reduce transmission size.
|
|
720
|
-
*
|
|
721
|
-
* @author Emily Stark
|
|
722
|
-
* @author Mike Hamburg
|
|
723
|
-
* @author Dan Boneh
|
|
724
|
-
*/
|
|
725
|
-
|
|
726
|
-
/*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
|
|
727
|
-
|
|
728
|
-
/** @fileOverview Arrays of bits, encoded as arrays of Numbers.
|
|
729
|
-
*
|
|
730
|
-
* @author Emily Stark
|
|
731
|
-
* @author Mike Hamburg
|
|
732
|
-
* @author Dan Boneh
|
|
733
|
-
*/
|
|
734
|
-
|
|
735
|
-
/**
|
|
736
|
-
* Arrays of bits, encoded as arrays of Numbers.
|
|
737
|
-
* @namespace
|
|
738
|
-
* @description
|
|
739
|
-
* <p>
|
|
740
|
-
* These objects are the currency accepted by SJCL's crypto functions.
|
|
741
|
-
* </p>
|
|
742
|
-
*
|
|
743
|
-
* <p>
|
|
744
|
-
* Most of our crypto primitives operate on arrays of 4-byte words internally,
|
|
745
|
-
* but many of them can take arguments that are not a multiple of 4 bytes.
|
|
746
|
-
* This library encodes arrays of bits (whose size need not be a multiple of 8
|
|
747
|
-
* bits) as arrays of 32-bit words. The bits are packed, big-endian, into an
|
|
748
|
-
* array of words, 32 bits at a time. Since the words are double-precision
|
|
749
|
-
* floating point numbers, they fit some extra data. We use this (in a private,
|
|
750
|
-
* possibly-changing manner) to encode the number of bits actually present
|
|
751
|
-
* in the last word of the array.
|
|
752
|
-
* </p>
|
|
753
|
-
*
|
|
754
|
-
* <p>
|
|
755
|
-
* Because bitwise ops clear this out-of-band data, these arrays can be passed
|
|
756
|
-
* to ciphers like AES which want arrays of words.
|
|
757
|
-
* </p>
|
|
758
|
-
*/
|
|
759
|
-
const bitArray = {
|
|
760
|
-
/**
|
|
761
|
-
* Concatenate two bit arrays.
|
|
762
|
-
* @param {bitArray} a1 The first array.
|
|
763
|
-
* @param {bitArray} a2 The second array.
|
|
764
|
-
* @return {bitArray} The concatenation of a1 and a2.
|
|
765
|
-
*/
|
|
766
|
-
concat(a1, a2) {
|
|
767
|
-
if (a1.length === 0 || a2.length === 0) {
|
|
768
|
-
return a1.concat(a2);
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
const last = a1[a1.length - 1], shift = bitArray.getPartial(last);
|
|
772
|
-
if (shift === 32) {
|
|
773
|
-
return a1.concat(a2);
|
|
774
|
-
} else {
|
|
775
|
-
return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1));
|
|
776
|
-
}
|
|
777
|
-
},
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* Find the length of an array of bits.
|
|
781
|
-
* @param {bitArray} a The array.
|
|
782
|
-
* @return {Number} The length of a, in bits.
|
|
783
|
-
*/
|
|
784
|
-
bitLength(a) {
|
|
785
|
-
const l = a.length;
|
|
786
|
-
if (l === 0) {
|
|
787
|
-
return 0;
|
|
788
|
-
}
|
|
789
|
-
const x = a[l - 1];
|
|
790
|
-
return (l - 1) * 32 + bitArray.getPartial(x);
|
|
791
|
-
},
|
|
792
|
-
|
|
793
|
-
/**
|
|
794
|
-
* Truncate an array.
|
|
795
|
-
* @param {bitArray} a The array.
|
|
796
|
-
* @param {Number} len The length to truncate to, in bits.
|
|
797
|
-
* @return {bitArray} A new array, truncated to len bits.
|
|
798
|
-
*/
|
|
799
|
-
clamp(a, len) {
|
|
800
|
-
if (a.length * 32 < len) {
|
|
801
|
-
return a;
|
|
802
|
-
}
|
|
803
|
-
a = a.slice(0, Math.ceil(len / 32));
|
|
804
|
-
const l = a.length;
|
|
805
|
-
len = len & 31;
|
|
806
|
-
if (l > 0 && len) {
|
|
807
|
-
a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1);
|
|
808
|
-
}
|
|
809
|
-
return a;
|
|
810
|
-
},
|
|
811
|
-
|
|
812
|
-
/**
|
|
813
|
-
* Make a partial word for a bit array.
|
|
814
|
-
* @param {Number} len The number of bits in the word.
|
|
815
|
-
* @param {Number} x The bits.
|
|
816
|
-
* @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
|
|
817
|
-
* @return {Number} The partial word.
|
|
818
|
-
*/
|
|
819
|
-
partial(len, x, _end) {
|
|
820
|
-
if (len === 32) {
|
|
821
|
-
return x;
|
|
822
|
-
}
|
|
823
|
-
return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000;
|
|
824
|
-
},
|
|
708
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
825
709
|
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
* @param {Number} x The partial word.
|
|
829
|
-
* @return {Number} The number of bits used by the partial word.
|
|
830
|
-
*/
|
|
831
|
-
getPartial(x) {
|
|
832
|
-
return Math.round(x / 0x10000000000) || 32;
|
|
833
|
-
},
|
|
710
|
+
Redistribution and use in source and binary forms, with or without
|
|
711
|
+
modification, are permitted provided that the following conditions are met:
|
|
834
712
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
* @param {Number} shift The number of bits to shift.
|
|
838
|
-
* @param {Number} [carry=0] A byte to carry in
|
|
839
|
-
* @param {bitArray} [out=[]] An array to prepend to the output.
|
|
840
|
-
* @private
|
|
841
|
-
*/
|
|
842
|
-
_shiftRight(a, shift, carry, out) {
|
|
843
|
-
if (out === undefined) {
|
|
844
|
-
out = [];
|
|
845
|
-
}
|
|
713
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
714
|
+
this list of conditions and the following disclaimer.
|
|
846
715
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
851
|
-
if (shift === 0) {
|
|
852
|
-
return out.concat(a);
|
|
853
|
-
}
|
|
716
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
717
|
+
notice, this list of conditions and the following disclaimer in
|
|
718
|
+
the documentation and/or other materials provided with the distribution.
|
|
854
719
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
carry = a[i] << (32 - shift);
|
|
858
|
-
}
|
|
859
|
-
const last2 = a.length ? a[a.length - 1] : 0;
|
|
860
|
-
const shift2 = bitArray.getPartial(last2);
|
|
861
|
-
out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1));
|
|
862
|
-
return out;
|
|
863
|
-
}
|
|
864
|
-
};
|
|
720
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
721
|
+
derived from this software without specific prior written permission.
|
|
865
722
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
723
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
724
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
725
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
726
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
727
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
728
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
729
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
730
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
731
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
732
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
871
733
|
*/
|
|
872
734
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
tmp = 0;
|
|
904
|
-
}
|
|
735
|
+
const BLOCK_LENGTH$1 = 16;
|
|
736
|
+
const ROUND_KEYS_LENGTH = 60;
|
|
737
|
+
const SHA1_BLOCK_LENGTH = 64;
|
|
738
|
+
const SHA1_DIGEST_LENGTH = 20;
|
|
739
|
+
const SHA1_SCHEDULE_LENGTH = 80;
|
|
740
|
+
const SHA1_LENGTH_OFFSET = 56;
|
|
741
|
+
const SHA1_PADDING = new Uint8Array([0x80]);
|
|
742
|
+
const SHA1_ZERO = new Uint8Array(1);
|
|
743
|
+
const SHA1_INITIAL_STATE = new Int32Array([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
|
|
744
|
+
const HMAC_INNER_PADDING = 0x36;
|
|
745
|
+
const HMAC_OUTER_PADDING = 0x5c;
|
|
746
|
+
const S_BOX = new Uint8Array(256);
|
|
747
|
+
const T0 = new Int32Array(256);
|
|
748
|
+
const T1 = new Int32Array(256);
|
|
749
|
+
const T2 = new Int32Array(256);
|
|
750
|
+
const T3 = new Int32Array(256);
|
|
751
|
+
|
|
752
|
+
let tablesInitialized = false;
|
|
753
|
+
|
|
754
|
+
function createEngine$1(key, authenticationKey) {
|
|
755
|
+
initTables();
|
|
756
|
+
const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
|
|
757
|
+
const rounds = expandKey(key, roundKeys);
|
|
758
|
+
const counter = new Uint8Array(BLOCK_LENGTH$1);
|
|
759
|
+
const keystream = new Int32Array(BLOCK_LENGTH$1 / 4);
|
|
760
|
+
const hmac = createHmac(authenticationKey);
|
|
761
|
+
return {
|
|
762
|
+
process(data, decrypt) {
|
|
763
|
+
if (decrypt) {
|
|
764
|
+
hmac.update(data, 0, data.length);
|
|
905
765
|
}
|
|
906
|
-
|
|
907
|
-
|
|
766
|
+
encrypt(data);
|
|
767
|
+
if (!decrypt) {
|
|
768
|
+
hmac.update(data, 0, data.length);
|
|
908
769
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
};
|
|
913
|
-
|
|
914
|
-
const hash = {};
|
|
915
|
-
|
|
916
|
-
/**
|
|
917
|
-
* Context for a SHA-1 operation in progress.
|
|
918
|
-
* @constructor
|
|
919
|
-
*/
|
|
920
|
-
hash.sha1 = class {
|
|
921
|
-
constructor(hash) {
|
|
922
|
-
const sha1 = this;
|
|
923
|
-
/**
|
|
924
|
-
* The hash's block size, in bits.
|
|
925
|
-
* @constant
|
|
926
|
-
*/
|
|
927
|
-
sha1.blockSize = 512;
|
|
928
|
-
/**
|
|
929
|
-
* The SHA-1 initialization vector.
|
|
930
|
-
* @private
|
|
931
|
-
*/
|
|
932
|
-
sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
|
|
933
|
-
/**
|
|
934
|
-
* The SHA-1 hash key.
|
|
935
|
-
* @private
|
|
936
|
-
*/
|
|
937
|
-
sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
|
|
938
|
-
if (hash) {
|
|
939
|
-
sha1._h = hash._h.slice(0);
|
|
940
|
-
sha1._buffer = hash._buffer.slice(0);
|
|
941
|
-
sha1._length = hash._length;
|
|
942
|
-
} else {
|
|
943
|
-
sha1.reset();
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
/**
|
|
948
|
-
* Reset the hash state.
|
|
949
|
-
* @return this
|
|
950
|
-
*/
|
|
951
|
-
reset() {
|
|
952
|
-
const sha1 = this;
|
|
953
|
-
sha1._h = sha1._init.slice(0);
|
|
954
|
-
sha1._buffer = [];
|
|
955
|
-
sha1._length = 0;
|
|
956
|
-
return sha1;
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
/**
|
|
960
|
-
* Input several words to the hash.
|
|
961
|
-
* @param {bitArray|String} data the data to hash.
|
|
962
|
-
* @return this
|
|
963
|
-
*/
|
|
964
|
-
update(data) {
|
|
965
|
-
const sha1 = this;
|
|
966
|
-
if (typeof data === "string") {
|
|
967
|
-
data = codec.utf8String.toBits(data);
|
|
968
|
-
}
|
|
969
|
-
const b = sha1._buffer = bitArray.concat(sha1._buffer, data);
|
|
970
|
-
const ol = sha1._length;
|
|
971
|
-
const nl = sha1._length = ol + bitArray.bitLength(data);
|
|
972
|
-
if (nl > 9007199254740991) {
|
|
973
|
-
throw new Error("Cannot hash more than 2^53 - 1 bits");
|
|
974
|
-
}
|
|
975
|
-
const c = new Uint32Array(b);
|
|
976
|
-
let j = 0;
|
|
977
|
-
for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl;
|
|
978
|
-
i += sha1.blockSize) {
|
|
979
|
-
sha1._block(c.subarray(16 * j, 16 * (j + 1)));
|
|
980
|
-
j += 1;
|
|
981
|
-
}
|
|
982
|
-
b.splice(0, 16 * j);
|
|
983
|
-
return sha1;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
/**
|
|
987
|
-
* Complete hashing and output the hash value.
|
|
988
|
-
* @return {bitArray} The hash value, an array of 5 big-endian words. TODO
|
|
989
|
-
*/
|
|
990
|
-
finalize() {
|
|
991
|
-
const sha1 = this;
|
|
992
|
-
let b = sha1._buffer;
|
|
993
|
-
const h = sha1._h;
|
|
994
|
-
|
|
995
|
-
// Round out and push the buffer
|
|
996
|
-
b = bitArray.concat(b, [bitArray.partial(1, 1)]);
|
|
997
|
-
// Round out the buffer to a multiple of 16 words, less the 2 length words.
|
|
998
|
-
for (let i = b.length + 2; i & 15; i++) {
|
|
999
|
-
b.push(0);
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
// append the length
|
|
1003
|
-
b.push(Math.floor(sha1._length / 0x100000000));
|
|
1004
|
-
b.push(sha1._length | 0);
|
|
1005
|
-
|
|
1006
|
-
while (b.length) {
|
|
1007
|
-
sha1._block(b.splice(0, 16));
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
sha1.reset();
|
|
1011
|
-
return h;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* The SHA-1 logical functions f(0), f(1), ..., f(79).
|
|
1016
|
-
* @private
|
|
1017
|
-
*/
|
|
1018
|
-
_f(t, b, c, d) {
|
|
1019
|
-
if (t <= 19) {
|
|
1020
|
-
return (b & c) | (~b & d);
|
|
1021
|
-
} else if (t <= 39) {
|
|
1022
|
-
return b ^ c ^ d;
|
|
1023
|
-
} else if (t <= 59) {
|
|
1024
|
-
return (b & c) | (b & d) | (c & d);
|
|
1025
|
-
} else if (t <= 79) {
|
|
1026
|
-
return b ^ c ^ d;
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
/**
|
|
1031
|
-
* Circular left-shift operator.
|
|
1032
|
-
* @private
|
|
1033
|
-
*/
|
|
1034
|
-
_S(n, x) {
|
|
1035
|
-
return (x << n) | (x >>> 32 - n);
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
/**
|
|
1039
|
-
* Perform one cycle of SHA-1.
|
|
1040
|
-
* @param {Uint32Array|bitArray} words one block of words.
|
|
1041
|
-
* @private
|
|
1042
|
-
*/
|
|
1043
|
-
_block(words) {
|
|
1044
|
-
const sha1 = this;
|
|
1045
|
-
const h = sha1._h;
|
|
1046
|
-
// When words is passed to _block, it has 16 elements. SHA1 _block
|
|
1047
|
-
// function extends words with new elements (at the end there are 80 elements).
|
|
1048
|
-
// The problem is that if we use Uint32Array instead of Array,
|
|
1049
|
-
// the length of Uint32Array cannot be changed. Thus, we replace words with a
|
|
1050
|
-
// normal Array here.
|
|
1051
|
-
const w = Array(80); // do not use Uint32Array here as the instantiation is slower
|
|
1052
|
-
for (let j = 0; j < 16; j++) {
|
|
1053
|
-
w[j] = words[j];
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
let a = h[0];
|
|
1057
|
-
let b = h[1];
|
|
1058
|
-
let c = h[2];
|
|
1059
|
-
let d = h[3];
|
|
1060
|
-
let e = h[4];
|
|
1061
|
-
|
|
1062
|
-
for (let t = 0; t <= 79; t++) {
|
|
1063
|
-
if (t >= 16) {
|
|
1064
|
-
w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
|
|
1065
|
-
}
|
|
1066
|
-
const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] +
|
|
1067
|
-
sha1._key[Math.floor(t / 20)]) | 0;
|
|
1068
|
-
e = d;
|
|
1069
|
-
d = c;
|
|
1070
|
-
c = sha1._S(30, b);
|
|
1071
|
-
b = a;
|
|
1072
|
-
a = tmp;
|
|
770
|
+
},
|
|
771
|
+
digest() {
|
|
772
|
+
return hmac.digest();
|
|
1073
773
|
}
|
|
774
|
+
};
|
|
1074
775
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
776
|
+
function encrypt(data) {
|
|
777
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
778
|
+
const length = data.length;
|
|
779
|
+
let offset = 0;
|
|
780
|
+
for (; offset + BLOCK_LENGTH$1 <= length; offset += BLOCK_LENGTH$1) {
|
|
781
|
+
nextKeystream();
|
|
782
|
+
view.setInt32(offset, view.getInt32(offset) ^ keystream[0]);
|
|
783
|
+
view.setInt32(offset + 4, view.getInt32(offset + 4) ^ keystream[1]);
|
|
784
|
+
view.setInt32(offset + 8, view.getInt32(offset + 8) ^ keystream[2]);
|
|
785
|
+
view.setInt32(offset + 12, view.getInt32(offset + 12) ^ keystream[3]);
|
|
786
|
+
}
|
|
787
|
+
if (offset < length) {
|
|
788
|
+
nextKeystream();
|
|
789
|
+
for (let indexByte = 0; offset < length; offset++, indexByte++) {
|
|
790
|
+
data[offset] ^= keystream[indexByte >> 2] >>> (24 - 8 * (indexByte & 3));
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
function nextKeystream() {
|
|
796
|
+
for (let indexByte = 0; indexByte < BLOCK_LENGTH$1; indexByte++) {
|
|
797
|
+
counter[indexByte]++;
|
|
798
|
+
if (counter[indexByte] !== 0) {
|
|
799
|
+
break;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
let s0 = ((counter[0] << 24) | (counter[1] << 16) | (counter[2] << 8) | counter[3]) ^ roundKeys[0];
|
|
803
|
+
let s1 = ((counter[4] << 24) | (counter[5] << 16) | (counter[6] << 8) | counter[7]) ^ roundKeys[1];
|
|
804
|
+
let s2 = ((counter[8] << 24) | (counter[9] << 16) | (counter[10] << 8) | counter[11]) ^ roundKeys[2];
|
|
805
|
+
let s3 = ((counter[12] << 24) | (counter[13] << 16) | (counter[14] << 8) | counter[15]) ^ roundKeys[3];
|
|
806
|
+
let indexKey = 4;
|
|
807
|
+
for (let round = 1; round < rounds; round++, indexKey += 4) {
|
|
808
|
+
const t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[indexKey];
|
|
809
|
+
const t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[indexKey + 1];
|
|
810
|
+
const t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[indexKey + 2];
|
|
811
|
+
const t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[indexKey + 3];
|
|
812
|
+
s0 = t0;
|
|
813
|
+
s1 = t1;
|
|
814
|
+
s2 = t2;
|
|
815
|
+
s3 = t3;
|
|
816
|
+
}
|
|
817
|
+
keystream[0] = ((S_BOX[s0 >>> 24] << 24) | (S_BOX[(s1 >>> 16) & 255] << 16) | (S_BOX[(s2 >>> 8) & 255] << 8) | S_BOX[s3 & 255]) ^ roundKeys[indexKey];
|
|
818
|
+
keystream[1] = ((S_BOX[s1 >>> 24] << 24) | (S_BOX[(s2 >>> 16) & 255] << 16) | (S_BOX[(s3 >>> 8) & 255] << 8) | S_BOX[s0 & 255]) ^ roundKeys[indexKey + 1];
|
|
819
|
+
keystream[2] = ((S_BOX[s2 >>> 24] << 24) | (S_BOX[(s3 >>> 16) & 255] << 16) | (S_BOX[(s0 >>> 8) & 255] << 8) | S_BOX[s1 & 255]) ^ roundKeys[indexKey + 2];
|
|
820
|
+
keystream[3] = ((S_BOX[s3 >>> 24] << 24) | (S_BOX[(s0 >>> 16) & 255] << 16) | (S_BOX[(s1 >>> 8) & 255] << 8) | S_BOX[s2 & 255]) ^ roundKeys[indexKey + 3];
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
function pbkdf2(password, salt, iterations, length) {
|
|
825
|
+
const hmac = createHmac(password);
|
|
826
|
+
const result = new Uint8Array(length);
|
|
827
|
+
const block = new Uint8Array(salt.length + 4);
|
|
828
|
+
const blockView = new DataView(block.buffer);
|
|
829
|
+
block.set(salt);
|
|
830
|
+
for (let indexBlock = 1, offset = 0; offset < length; indexBlock++, offset += SHA1_DIGEST_LENGTH) {
|
|
831
|
+
blockView.setUint32(salt.length, indexBlock);
|
|
832
|
+
hmac.update(block, 0, block.length);
|
|
833
|
+
let previous = hmac.digest();
|
|
834
|
+
const output = previous.slice();
|
|
835
|
+
for (let iteration = 1; iteration < iterations; iteration++) {
|
|
836
|
+
hmac.update(previous, 0, SHA1_DIGEST_LENGTH);
|
|
837
|
+
previous = hmac.digest();
|
|
838
|
+
for (let indexByte = 0; indexByte < SHA1_DIGEST_LENGTH; indexByte++) {
|
|
839
|
+
output[indexByte] ^= previous[indexByte];
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
result.set(output.subarray(0, Math.min(SHA1_DIGEST_LENGTH, length - offset)), offset);
|
|
1080
843
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
/** @fileOverview Low-level AES implementation.
|
|
1084
|
-
*
|
|
1085
|
-
* This file contains a low-level implementation of AES, optimized for
|
|
1086
|
-
* size and for efficiency on several browsers. It is based on
|
|
1087
|
-
* OpenSSL's aes_core.c, a public-domain implementation by Vincent
|
|
1088
|
-
* Rijmen, Antoon Bosselaers and Paulo Barreto.
|
|
1089
|
-
*
|
|
1090
|
-
* An older version of this implementation is available in the public
|
|
1091
|
-
* domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh,
|
|
1092
|
-
* Stanford University 2008-2010 and BSD-licensed for liability
|
|
1093
|
-
* reasons.
|
|
1094
|
-
*
|
|
1095
|
-
* @author Emily Stark
|
|
1096
|
-
* @author Mike Hamburg
|
|
1097
|
-
* @author Dan Boneh
|
|
1098
|
-
*/
|
|
1099
|
-
|
|
1100
|
-
const cipher = {};
|
|
1101
|
-
|
|
1102
|
-
/**
|
|
1103
|
-
* Schedule out an AES key for both encryption and decryption. This
|
|
1104
|
-
* is a low-level class. Use a cipher mode to do bulk encryption.
|
|
1105
|
-
*
|
|
1106
|
-
* @constructor
|
|
1107
|
-
* @param {Array} key The key as an array of 4, 6 or 8 words.
|
|
1108
|
-
*/
|
|
1109
|
-
cipher.aes = class {
|
|
1110
|
-
constructor(key) {
|
|
1111
|
-
/**
|
|
1112
|
-
* The expanded S-box and inverse S-box tables. These will be computed
|
|
1113
|
-
* on the client so that we don't have to send them down the wire.
|
|
1114
|
-
*
|
|
1115
|
-
* There are two tables, _tables[0] is for encryption and
|
|
1116
|
-
* _tables[1] is for decryption.
|
|
1117
|
-
*
|
|
1118
|
-
* The first 4 sub-tables are the expanded S-box with MixColumns. The
|
|
1119
|
-
* last (_tables[01][4]) is the S-box itself.
|
|
1120
|
-
*
|
|
1121
|
-
* @private
|
|
1122
|
-
*/
|
|
1123
|
-
const aes = this;
|
|
1124
|
-
aes._tables = [[[], [], [], [], []], [[], [], [], [], []]];
|
|
1125
|
-
|
|
1126
|
-
if (!aes._tables[0][0][0]) {
|
|
1127
|
-
aes._precompute();
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
const sbox = aes._tables[0][4];
|
|
1131
|
-
const decTable = aes._tables[1];
|
|
1132
|
-
const keyLen = key.length;
|
|
1133
|
-
|
|
1134
|
-
let i, encKey, decKey, rcon = 1;
|
|
1135
|
-
|
|
1136
|
-
if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
|
|
1137
|
-
throw new Error("invalid aes key size");
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
aes._key = [encKey = key.slice(0), decKey = []];
|
|
1141
|
-
|
|
1142
|
-
// schedule encryption keys
|
|
1143
|
-
for (i = keyLen; i < 4 * keyLen + 28; i++) {
|
|
1144
|
-
let tmp = encKey[i - 1];
|
|
1145
|
-
|
|
1146
|
-
// apply sbox
|
|
1147
|
-
if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
|
|
1148
|
-
tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
|
|
1149
|
-
|
|
1150
|
-
// shift rows and add rcon
|
|
1151
|
-
if (i % keyLen === 0) {
|
|
1152
|
-
tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
|
|
1153
|
-
rcon = rcon << 1 ^ (rcon >> 7) * 283;
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
encKey[i] = encKey[i - keyLen] ^ tmp;
|
|
1158
|
-
}
|
|
844
|
+
return result;
|
|
845
|
+
}
|
|
1159
846
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
decTable[1][sbox[tmp >> 16 & 255]] ^
|
|
1168
|
-
decTable[2][sbox[tmp >> 8 & 255]] ^
|
|
1169
|
-
decTable[3][sbox[tmp & 255]];
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
|
-
// public
|
|
1174
|
-
/* Something like this might appear here eventually
|
|
1175
|
-
name: "AES",
|
|
1176
|
-
blockSize: 4,
|
|
1177
|
-
keySizes: [4,6,8],
|
|
1178
|
-
*/
|
|
1179
|
-
|
|
1180
|
-
/**
|
|
1181
|
-
* Encrypt an array of 4 big-endian words.
|
|
1182
|
-
* @param {Array} data The plaintext.
|
|
1183
|
-
* @return {Array} The ciphertext.
|
|
1184
|
-
*/
|
|
1185
|
-
encrypt(data) {
|
|
1186
|
-
return this._crypt(data, 0);
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
/**
|
|
1190
|
-
* Decrypt an array of 4 big-endian words.
|
|
1191
|
-
* @param {Array} data The ciphertext.
|
|
1192
|
-
* @return {Array} The plaintext.
|
|
1193
|
-
*/
|
|
1194
|
-
decrypt(data) {
|
|
1195
|
-
return this._crypt(data, 1);
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
/**
|
|
1199
|
-
* Expand the S-box tables.
|
|
1200
|
-
*
|
|
1201
|
-
* @private
|
|
1202
|
-
*/
|
|
1203
|
-
_precompute() {
|
|
1204
|
-
const encTable = this._tables[0];
|
|
1205
|
-
const decTable = this._tables[1];
|
|
1206
|
-
const sbox = encTable[4];
|
|
1207
|
-
const sboxInv = decTable[4];
|
|
1208
|
-
const d = [];
|
|
1209
|
-
const th = [];
|
|
1210
|
-
let xInv, x2, x4, x8;
|
|
1211
|
-
|
|
1212
|
-
// Compute double and third tables
|
|
1213
|
-
for (let i = 0; i < 256; i++) {
|
|
1214
|
-
th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
|
|
1218
|
-
// Compute sbox
|
|
1219
|
-
let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
|
|
1220
|
-
s = s >> 8 ^ s & 255 ^ 99;
|
|
1221
|
-
sbox[x] = s;
|
|
1222
|
-
sboxInv[s] = x;
|
|
1223
|
-
|
|
1224
|
-
// Compute MixColumns
|
|
1225
|
-
x8 = d[x4 = d[x2 = d[x]]];
|
|
1226
|
-
let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
|
|
1227
|
-
let tEnc = d[s] * 0x101 ^ s * 0x1010100;
|
|
1228
|
-
|
|
1229
|
-
for (let i = 0; i < 4; i++) {
|
|
1230
|
-
encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
|
|
1231
|
-
decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
// Compactify. Considerable speedup on Firefox.
|
|
1236
|
-
for (let i = 0; i < 5; i++) {
|
|
1237
|
-
encTable[i] = encTable[i].slice(0);
|
|
1238
|
-
decTable[i] = decTable[i].slice(0);
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
|
-
/**
|
|
1243
|
-
* Encryption and decryption core.
|
|
1244
|
-
* @param {Array} input Four words to be encrypted or decrypted.
|
|
1245
|
-
* @param dir The direction, 0 for encrypt and 1 for decrypt.
|
|
1246
|
-
* @return {Array} The four encrypted or decrypted words.
|
|
1247
|
-
* @private
|
|
1248
|
-
*/
|
|
1249
|
-
_crypt(input, dir) {
|
|
1250
|
-
if (input.length !== 4) {
|
|
1251
|
-
throw new Error("invalid aes block size");
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
const key = this._key[dir];
|
|
1255
|
-
|
|
1256
|
-
const nInnerRounds = key.length / 4 - 2;
|
|
1257
|
-
const out = [0, 0, 0, 0];
|
|
1258
|
-
const table = this._tables[dir];
|
|
1259
|
-
|
|
1260
|
-
// load up the tables
|
|
1261
|
-
const t0 = table[0];
|
|
1262
|
-
const t1 = table[1];
|
|
1263
|
-
const t2 = table[2];
|
|
1264
|
-
const t3 = table[3];
|
|
1265
|
-
const sbox = table[4];
|
|
1266
|
-
|
|
1267
|
-
// state variables a,b,c,d are loaded with pre-whitened data
|
|
1268
|
-
let a = input[0] ^ key[0];
|
|
1269
|
-
let b = input[dir ? 3 : 1] ^ key[1];
|
|
1270
|
-
let c = input[2] ^ key[2];
|
|
1271
|
-
let d = input[dir ? 1 : 3] ^ key[3];
|
|
1272
|
-
let kIndex = 4;
|
|
1273
|
-
let a2, b2, c2;
|
|
1274
|
-
|
|
1275
|
-
// Inner rounds. Cribbed from OpenSSL.
|
|
1276
|
-
for (let i = 0; i < nInnerRounds; i++) {
|
|
1277
|
-
a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
|
|
1278
|
-
b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
|
|
1279
|
-
c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
|
|
1280
|
-
d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
|
|
1281
|
-
kIndex += 4;
|
|
1282
|
-
a = a2; b = b2; c = c2;
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
// Last round.
|
|
1286
|
-
for (let i = 0; i < 4; i++) {
|
|
1287
|
-
out[dir ? 3 & -i : i] =
|
|
1288
|
-
sbox[a >>> 24] << 24 ^
|
|
1289
|
-
sbox[b >> 16 & 255] << 16 ^
|
|
1290
|
-
sbox[c >> 8 & 255] << 8 ^
|
|
1291
|
-
sbox[d & 255] ^
|
|
1292
|
-
key[kIndex++];
|
|
1293
|
-
a2 = a; a = b; b = c; c = d; d = a2;
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
return out;
|
|
847
|
+
function createHmac(key) {
|
|
848
|
+
const sha1 = createSha1();
|
|
849
|
+
const innerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
850
|
+
const outerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
851
|
+
if (key.length > SHA1_BLOCK_LENGTH) {
|
|
852
|
+
sha1.update(key, 0, key.length);
|
|
853
|
+
key = sha1.digest();
|
|
1297
854
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
* Special thanks to Roy Nicholson for pointing out a bug in our
|
|
1303
|
-
* implementation.
|
|
1304
|
-
*
|
|
1305
|
-
* @author Emily Stark
|
|
1306
|
-
* @author Mike Hamburg
|
|
1307
|
-
* @author Dan Boneh
|
|
1308
|
-
*/
|
|
1309
|
-
|
|
1310
|
-
/** Brian Gladman's CTR Mode.
|
|
1311
|
-
* @constructor
|
|
1312
|
-
* @param {Object} _prf The aes instance to generate key.
|
|
1313
|
-
* @param {bitArray} _iv The iv for ctr mode, it must be 128 bits.
|
|
1314
|
-
*/
|
|
1315
|
-
|
|
1316
|
-
const mode = {};
|
|
1317
|
-
|
|
1318
|
-
/**
|
|
1319
|
-
* Brian Gladman's CTR Mode.
|
|
1320
|
-
* @namespace
|
|
1321
|
-
*/
|
|
1322
|
-
mode.ctrGladman = class {
|
|
1323
|
-
constructor(prf, iv) {
|
|
1324
|
-
this._prf = prf;
|
|
1325
|
-
this._initIv = iv;
|
|
1326
|
-
this._iv = iv;
|
|
855
|
+
for (let indexByte = 0; indexByte < SHA1_BLOCK_LENGTH; indexByte++) {
|
|
856
|
+
const keyByte = indexByte < key.length ? key[indexByte] : 0;
|
|
857
|
+
innerKey[indexByte] = keyByte ^ HMAC_INNER_PADDING;
|
|
858
|
+
outerKey[indexByte] = keyByte ^ HMAC_OUTER_PADDING;
|
|
1327
859
|
}
|
|
860
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
861
|
+
return {
|
|
862
|
+
update(data, offset, length) {
|
|
863
|
+
sha1.update(data, offset, length);
|
|
864
|
+
},
|
|
865
|
+
digest() {
|
|
866
|
+
const innerDigest = sha1.digest();
|
|
867
|
+
sha1.update(outerKey, 0, SHA1_BLOCK_LENGTH);
|
|
868
|
+
sha1.update(innerDigest, 0, SHA1_DIGEST_LENGTH);
|
|
869
|
+
const result = sha1.digest();
|
|
870
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
871
|
+
return result;
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
}
|
|
1328
875
|
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
876
|
+
function createSha1() {
|
|
877
|
+
const state = new Int32Array(SHA1_INITIAL_STATE);
|
|
878
|
+
const schedule = new Int32Array(SHA1_SCHEDULE_LENGTH);
|
|
879
|
+
const block = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
880
|
+
const blockView = new DataView(block.buffer);
|
|
881
|
+
const lengthBytes = new Uint8Array(8);
|
|
882
|
+
let blockLength = 0;
|
|
883
|
+
let totalLength = 0;
|
|
884
|
+
return {
|
|
885
|
+
update,
|
|
886
|
+
digest
|
|
887
|
+
};
|
|
1332
888
|
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
889
|
+
function update(data, offset, length) {
|
|
890
|
+
const end = offset + length;
|
|
891
|
+
totalLength += length;
|
|
892
|
+
if (blockLength) {
|
|
893
|
+
while (offset < end && blockLength < SHA1_BLOCK_LENGTH) {
|
|
894
|
+
block[blockLength++] = data[offset++];
|
|
895
|
+
}
|
|
896
|
+
if (blockLength == SHA1_BLOCK_LENGTH) {
|
|
897
|
+
compress(blockView, 0);
|
|
898
|
+
blockLength = 0;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (offset + SHA1_BLOCK_LENGTH <= end) {
|
|
902
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
903
|
+
for (; offset + SHA1_BLOCK_LENGTH <= end; offset += SHA1_BLOCK_LENGTH) {
|
|
904
|
+
compress(view, offset);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
while (offset < end) {
|
|
908
|
+
block[blockLength++] = data[offset++];
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
function digest() {
|
|
913
|
+
const bits = totalLength * 8;
|
|
914
|
+
const high = Math.floor(bits / 0x100000000);
|
|
915
|
+
const low = bits >>> 0;
|
|
916
|
+
update(SHA1_PADDING, 0, 1);
|
|
917
|
+
while (blockLength != SHA1_LENGTH_OFFSET) {
|
|
918
|
+
update(SHA1_ZERO, 0, 1);
|
|
919
|
+
}
|
|
920
|
+
lengthBytes[0] = high >>> 24;
|
|
921
|
+
lengthBytes[1] = high >>> 16;
|
|
922
|
+
lengthBytes[2] = high >>> 8;
|
|
923
|
+
lengthBytes[3] = high;
|
|
924
|
+
lengthBytes[4] = low >>> 24;
|
|
925
|
+
lengthBytes[5] = low >>> 16;
|
|
926
|
+
lengthBytes[6] = low >>> 8;
|
|
927
|
+
lengthBytes[7] = low;
|
|
928
|
+
update(lengthBytes, 0, 8);
|
|
929
|
+
const result = new Uint8Array(SHA1_DIGEST_LENGTH);
|
|
930
|
+
const resultView = new DataView(result.buffer);
|
|
931
|
+
for (let indexWord = 0; indexWord < state.length; indexWord++) {
|
|
932
|
+
resultView.setInt32(4 * indexWord, state[indexWord]);
|
|
933
|
+
}
|
|
934
|
+
state.set(SHA1_INITIAL_STATE);
|
|
935
|
+
blockLength = 0;
|
|
936
|
+
totalLength = 0;
|
|
937
|
+
return result;
|
|
1338
938
|
}
|
|
1339
939
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
let b2 = (word >> 8) & 0xff;
|
|
1344
|
-
let b3 = word & 0xff;
|
|
1345
|
-
|
|
1346
|
-
if (b1 === 0xff) { // overflow b1
|
|
1347
|
-
b1 = 0;
|
|
1348
|
-
if (b2 === 0xff) {
|
|
1349
|
-
b2 = 0;
|
|
1350
|
-
if (b3 === 0xff) {
|
|
1351
|
-
b3 = 0;
|
|
1352
|
-
} else {
|
|
1353
|
-
++b3;
|
|
1354
|
-
}
|
|
1355
|
-
} else {
|
|
1356
|
-
++b2;
|
|
1357
|
-
}
|
|
1358
|
-
} else {
|
|
1359
|
-
++b1;
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
word = 0;
|
|
1363
|
-
word += (b1 << 16);
|
|
1364
|
-
word += (b2 << 8);
|
|
1365
|
-
word += b3;
|
|
1366
|
-
} else {
|
|
1367
|
-
word += (0x01 << 24);
|
|
940
|
+
function compress(view, offset) {
|
|
941
|
+
for (let index = 0; index < 16; index++) {
|
|
942
|
+
schedule[index] = view.getInt32(offset + 4 * index);
|
|
1368
943
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
incCounter(counter) {
|
|
1373
|
-
if ((counter[0] = this.incWord(counter[0])) === 0) {
|
|
1374
|
-
// encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
|
|
1375
|
-
counter[1] = this.incWord(counter[1]);
|
|
944
|
+
for (let index = 16; index < SHA1_SCHEDULE_LENGTH; index++) {
|
|
945
|
+
const word = schedule[index - 3] ^ schedule[index - 8] ^ schedule[index - 14] ^ schedule[index - 16];
|
|
946
|
+
schedule[index] = (word << 1) | (word >>> 31);
|
|
1376
947
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
let
|
|
1381
|
-
|
|
1382
|
-
|
|
948
|
+
let a = state[0];
|
|
949
|
+
let b = state[1];
|
|
950
|
+
let c = state[2];
|
|
951
|
+
let d = state[3];
|
|
952
|
+
let e = state[4];
|
|
953
|
+
let t;
|
|
954
|
+
for (let index = 0; index < 20; index++) {
|
|
955
|
+
t = (((a << 5) | (a >>> 27)) + ((b & c) | (~b & d)) + e + 0x5A827999 + schedule[index]) | 0;
|
|
956
|
+
e = d;
|
|
957
|
+
d = c;
|
|
958
|
+
c = (b << 30) | (b >>> 2);
|
|
959
|
+
b = a;
|
|
960
|
+
a = t;
|
|
1383
961
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
data[i + 3] ^= e[3];
|
|
962
|
+
for (let index = 20; index < 40; index++) {
|
|
963
|
+
t = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + schedule[index]) | 0;
|
|
964
|
+
e = d;
|
|
965
|
+
d = c;
|
|
966
|
+
c = (b << 30) | (b >>> 2);
|
|
967
|
+
b = a;
|
|
968
|
+
a = t;
|
|
1392
969
|
}
|
|
1393
|
-
|
|
970
|
+
for (let index = 40; index < 60; index++) {
|
|
971
|
+
t = (((a << 5) | (a >>> 27)) + ((b & c) | (b & d) | (c & d)) + e + 0x8F1BBCDC + schedule[index]) | 0;
|
|
972
|
+
e = d;
|
|
973
|
+
d = c;
|
|
974
|
+
c = (b << 30) | (b >>> 2);
|
|
975
|
+
b = a;
|
|
976
|
+
a = t;
|
|
977
|
+
}
|
|
978
|
+
for (let index = 60; index < SHA1_SCHEDULE_LENGTH; index++) {
|
|
979
|
+
t = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + schedule[index]) | 0;
|
|
980
|
+
e = d;
|
|
981
|
+
d = c;
|
|
982
|
+
c = (b << 30) | (b >>> 2);
|
|
983
|
+
b = a;
|
|
984
|
+
a = t;
|
|
985
|
+
}
|
|
986
|
+
state[0] = (state[0] + a) | 0;
|
|
987
|
+
state[1] = (state[1] + b) | 0;
|
|
988
|
+
state[2] = (state[2] + c) | 0;
|
|
989
|
+
state[3] = (state[3] + d) | 0;
|
|
990
|
+
state[4] = (state[4] + e) | 0;
|
|
1394
991
|
}
|
|
1395
|
-
}
|
|
992
|
+
}
|
|
1396
993
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
const arrayBuffer = new ArrayBuffer(byteLength);
|
|
1409
|
-
const out = new DataView(arrayBuffer);
|
|
1410
|
-
let outLength = 0;
|
|
1411
|
-
const b = bitArray;
|
|
1412
|
-
salt = codec.bytes.toBits(salt);
|
|
1413
|
-
for (k = 1; outLength < (byteLength || 1); k++) {
|
|
1414
|
-
u = ui = prf.encrypt(b.concat(salt, [k]));
|
|
1415
|
-
for (i = 1; i < count; i++) {
|
|
1416
|
-
ui = prf.encrypt(ui);
|
|
1417
|
-
for (j = 0; j < ui.length; j++) {
|
|
1418
|
-
u[j] ^= ui[j];
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
|
|
1422
|
-
out.setInt32(outLength, u[i]);
|
|
1423
|
-
outLength += 4;
|
|
994
|
+
function initTables() {
|
|
995
|
+
if (!tablesInitialized) {
|
|
996
|
+
let p = 1;
|
|
997
|
+
let q = 1;
|
|
998
|
+
do {
|
|
999
|
+
p = (p ^ (p << 1) ^ ((p & 0x80) ? 0x1b : 0)) & 255;
|
|
1000
|
+
q = (q ^ (q << 1)) & 255;
|
|
1001
|
+
q = (q ^ (q << 2)) & 255;
|
|
1002
|
+
q = (q ^ (q << 4)) & 255;
|
|
1003
|
+
if (q & 0x80) {
|
|
1004
|
+
q ^= 0x09;
|
|
1424
1005
|
}
|
|
1006
|
+
S_BOX[p] = (q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)) ^ 0x63) & 255;
|
|
1007
|
+
} while (p != 1);
|
|
1008
|
+
S_BOX[0] = 0x63;
|
|
1009
|
+
for (let index = 0; index < 256; index++) {
|
|
1010
|
+
const s = S_BOX[index];
|
|
1011
|
+
const s2 = multiplyByTwo(s);
|
|
1012
|
+
const t = (s2 << 24) | (s << 16) | (s << 8) | (s2 ^ s);
|
|
1013
|
+
T0[index] = t;
|
|
1014
|
+
T1[index] = (t >>> 8) | (t << 24);
|
|
1015
|
+
T2[index] = (t >>> 16) | (t << 16);
|
|
1016
|
+
T3[index] = (t >>> 24) | (t << 8);
|
|
1425
1017
|
}
|
|
1426
|
-
|
|
1018
|
+
tablesInitialized = true;
|
|
1427
1019
|
}
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
/** @fileOverview HMAC implementation.
|
|
1431
|
-
*
|
|
1432
|
-
* @author Emily Stark
|
|
1433
|
-
* @author Mike Hamburg
|
|
1434
|
-
* @author Dan Boneh
|
|
1435
|
-
*/
|
|
1436
|
-
|
|
1437
|
-
/** HMAC with the specified hash function.
|
|
1438
|
-
* @constructor
|
|
1439
|
-
* @param {bitArray} key the key for HMAC.
|
|
1440
|
-
* @param {Object} [Hash=hash.sha1] The hash function to use.
|
|
1441
|
-
*/
|
|
1442
|
-
misc.hmacSha1 = class {
|
|
1443
|
-
|
|
1444
|
-
constructor(key) {
|
|
1445
|
-
const hmac = this;
|
|
1446
|
-
const Hash = hmac._hash = hash.sha1;
|
|
1447
|
-
const exKey = [[], []];
|
|
1448
|
-
hmac._baseHash = [new Hash(), new Hash()];
|
|
1449
|
-
const bs = hmac._baseHash[0].blockSize / 32;
|
|
1450
|
-
|
|
1451
|
-
if (key.length > bs) {
|
|
1452
|
-
key = new Hash().update(key).finalize();
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1455
|
-
for (let i = 0; i < bs; i++) {
|
|
1456
|
-
exKey[0][i] = key[i] ^ 0x36363636;
|
|
1457
|
-
exKey[1][i] = key[i] ^ 0x5C5C5C5C;
|
|
1458
|
-
}
|
|
1020
|
+
}
|
|
1459
1021
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
hmac._updated = false;
|
|
1022
|
+
function expandKey(key, roundKeys) {
|
|
1023
|
+
const keyWords = key.length >> 2;
|
|
1024
|
+
const rounds = keyWords + 6;
|
|
1025
|
+
const total = 4 * (rounds + 1);
|
|
1026
|
+
let roundConstant = 1;
|
|
1027
|
+
for (let index = 0; index < keyWords; index++) {
|
|
1028
|
+
roundKeys[index] = (key[4 * index] << 24) | (key[4 * index + 1] << 16) | (key[4 * index + 2] << 8) | key[4 * index + 3];
|
|
1468
1029
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1030
|
+
for (let index = keyWords; index < total; index++) {
|
|
1031
|
+
let word = roundKeys[index - 1];
|
|
1032
|
+
if (index % keyWords == 0) {
|
|
1033
|
+
word = substituteWord((word << 8) | (word >>> 24)) ^ (roundConstant << 24);
|
|
1034
|
+
roundConstant = multiplyByTwo(roundConstant);
|
|
1035
|
+
} else if (keyWords > 6 && index % keyWords == 4) {
|
|
1036
|
+
word = substituteWord(word);
|
|
1037
|
+
}
|
|
1038
|
+
roundKeys[index] = roundKeys[index - keyWords] ^ word;
|
|
1474
1039
|
}
|
|
1040
|
+
return rounds;
|
|
1041
|
+
}
|
|
1475
1042
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
const result = new (hmac._hash)(hmac._baseHash[1]).update(w).finalize();
|
|
1480
|
-
|
|
1481
|
-
hmac.reset();
|
|
1482
|
-
|
|
1483
|
-
return result;
|
|
1484
|
-
}
|
|
1043
|
+
function substituteWord(word) {
|
|
1044
|
+
return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
|
|
1045
|
+
}
|
|
1485
1046
|
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
return this.digest(data);
|
|
1490
|
-
} else {
|
|
1491
|
-
throw new Error("encrypt on already updated hmac called!");
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
};
|
|
1047
|
+
function multiplyByTwo(value) {
|
|
1048
|
+
return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
|
|
1049
|
+
}
|
|
1495
1050
|
|
|
1496
1051
|
/*
|
|
1497
1052
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
@@ -1546,8 +1101,8 @@
|
|
|
1546
1101
|
1. Redistributions of source code must retain the above copyright notice,
|
|
1547
1102
|
this list of conditions and the following disclaimer.
|
|
1548
1103
|
|
|
1549
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
1550
|
-
notice, this list of conditions and the following disclaimer in
|
|
1104
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
1105
|
+
notice, this list of conditions and the following disclaimer in
|
|
1551
1106
|
the documentation and/or other materials provided with the distribution.
|
|
1552
1107
|
|
|
1553
1108
|
3. The names of the authors may not be used to endorse or promote products
|
|
@@ -1571,24 +1126,21 @@
|
|
|
1571
1126
|
const PBKDF2_ALGORITHM = { name: "PBKDF2" };
|
|
1572
1127
|
const HASH_ALGORITHM = { name: "HMAC" };
|
|
1573
1128
|
const HASH_FUNCTION = "SHA-1";
|
|
1129
|
+
const PBKDF2_ITERATIONS = 1000;
|
|
1574
1130
|
const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
|
|
1575
|
-
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations:
|
|
1131
|
+
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: PBKDF2_ITERATIONS, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
|
|
1576
1132
|
const DERIVED_BITS_USAGE = ["deriveBits"];
|
|
1577
1133
|
const SALT_LENGTH = [8, 12, 16];
|
|
1578
1134
|
const KEY_LENGTH = [16, 24, 32];
|
|
1579
1135
|
const AUTHENTICATION_CODE_LENGTH = 10;
|
|
1580
|
-
const
|
|
1136
|
+
const PASSWORD_VERIFICATION_LENGTH = 2;
|
|
1581
1137
|
// deno-lint-ignore valid-typeof
|
|
1582
1138
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
1583
1139
|
const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
|
|
1584
1140
|
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
|
|
1585
|
-
const codecBytes = codec.bytes;
|
|
1586
|
-
const Aes = cipher.aes;
|
|
1587
|
-
const CtrGladman = mode.ctrGladman;
|
|
1588
|
-
const HmacSha1 = misc.hmacSha1;
|
|
1589
1141
|
|
|
1590
|
-
let
|
|
1591
|
-
let
|
|
1142
|
+
let DERIVE_BITS_SUPPORTED = SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE && typeof subtle.deriveBits == FUNCTION_TYPE;
|
|
1143
|
+
let createEngine = createEngine$1;
|
|
1592
1144
|
|
|
1593
1145
|
class AESDecryptionStream extends TransformStream {
|
|
1594
1146
|
|
|
@@ -1606,9 +1158,10 @@
|
|
|
1606
1158
|
ready
|
|
1607
1159
|
} = aesCrypto;
|
|
1608
1160
|
if (password) {
|
|
1609
|
-
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] +
|
|
1610
|
-
chunk = subarray(chunk, SALT_LENGTH[strength] +
|
|
1161
|
+
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH));
|
|
1162
|
+
chunk = subarray(chunk, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH);
|
|
1611
1163
|
if (checkPasswordOnly) {
|
|
1164
|
+
disposeEngine(aesCrypto);
|
|
1612
1165
|
controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
|
|
1613
1166
|
} else {
|
|
1614
1167
|
resolveReady();
|
|
@@ -1621,23 +1174,16 @@
|
|
|
1621
1174
|
},
|
|
1622
1175
|
async flush(controller) {
|
|
1623
1176
|
const {
|
|
1624
|
-
|
|
1625
|
-
hmac,
|
|
1177
|
+
engine,
|
|
1626
1178
|
pendingInput,
|
|
1627
1179
|
ready
|
|
1628
1180
|
} = this;
|
|
1629
|
-
if (
|
|
1181
|
+
if (engine) {
|
|
1630
1182
|
await ready;
|
|
1631
|
-
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1632
1183
|
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
hmac.update(encryptedChunk);
|
|
1637
|
-
const decryptedChunk = ctr.update(encryptedChunk);
|
|
1638
|
-
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
1639
|
-
}
|
|
1640
|
-
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1184
|
+
const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
|
|
1185
|
+
engine.process(decryptedChunkArray, true);
|
|
1186
|
+
const authenticationCode = engine.digest();
|
|
1641
1187
|
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1642
1188
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1643
1189
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
@@ -1647,6 +1193,9 @@
|
|
|
1647
1193
|
}
|
|
1648
1194
|
controller.enqueue(decryptedChunkArray);
|
|
1649
1195
|
}
|
|
1196
|
+
},
|
|
1197
|
+
cancel() {
|
|
1198
|
+
disposeEngine(this);
|
|
1650
1199
|
}
|
|
1651
1200
|
});
|
|
1652
1201
|
}
|
|
@@ -1676,26 +1225,24 @@
|
|
|
1676
1225
|
}
|
|
1677
1226
|
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
1678
1227
|
output.set(preamble, 0);
|
|
1679
|
-
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
1228
|
+
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
|
|
1680
1229
|
},
|
|
1681
1230
|
async flush(controller) {
|
|
1682
1231
|
const {
|
|
1683
|
-
|
|
1684
|
-
hmac,
|
|
1232
|
+
engine,
|
|
1685
1233
|
pendingInput,
|
|
1686
1234
|
ready
|
|
1687
1235
|
} = this;
|
|
1688
|
-
if (
|
|
1236
|
+
if (engine) {
|
|
1689
1237
|
await ready;
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
hmac.update(encryptedChunk);
|
|
1694
|
-
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
1695
|
-
}
|
|
1696
|
-
const authenticationCode = fromBits(codecBytes, hmac.digest()).slice(0, AUTHENTICATION_CODE_LENGTH);
|
|
1238
|
+
const encryptedChunkArray = new Uint8Array(pendingInput);
|
|
1239
|
+
engine.process(encryptedChunkArray, false);
|
|
1240
|
+
const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1697
1241
|
controller.enqueue(concat(encryptedChunkArray, authenticationCode));
|
|
1698
1242
|
}
|
|
1243
|
+
},
|
|
1244
|
+
cancel() {
|
|
1245
|
+
disposeEngine(this);
|
|
1699
1246
|
}
|
|
1700
1247
|
});
|
|
1701
1248
|
}
|
|
@@ -1710,30 +1257,23 @@
|
|
|
1710
1257
|
});
|
|
1711
1258
|
}
|
|
1712
1259
|
|
|
1713
|
-
function append(aesCrypto, input, output, paddingStart, paddingEnd,
|
|
1260
|
+
function append(aesCrypto, input, output, paddingStart, paddingEnd, decrypt) {
|
|
1714
1261
|
const {
|
|
1715
|
-
|
|
1716
|
-
hmac,
|
|
1262
|
+
engine,
|
|
1717
1263
|
pendingInput
|
|
1718
1264
|
} = aesCrypto;
|
|
1719
1265
|
if (pendingInput.length) {
|
|
1720
1266
|
input = concat(pendingInput, input);
|
|
1721
1267
|
}
|
|
1722
1268
|
const inputLength = input.length - paddingEnd;
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
const
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
if (!verifyAuthenticationCode) {
|
|
1732
|
-
hmac.update(outputChunk);
|
|
1733
|
-
}
|
|
1734
|
-
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
1735
|
-
}
|
|
1736
|
-
aesCrypto.pendingInput = subarray(input, offset);
|
|
1269
|
+
const alignedLength = inputLength - (inputLength % BLOCK_LENGTH);
|
|
1270
|
+
output = expand(output, paddingStart + alignedLength);
|
|
1271
|
+
if (alignedLength) {
|
|
1272
|
+
const chunk = subarray(output, paddingStart, paddingStart + alignedLength);
|
|
1273
|
+
chunk.set(subarray(input, 0, alignedLength));
|
|
1274
|
+
engine.process(chunk, decrypt);
|
|
1275
|
+
}
|
|
1276
|
+
aesCrypto.pendingInput = subarray(input, alignedLength);
|
|
1737
1277
|
return output;
|
|
1738
1278
|
}
|
|
1739
1279
|
|
|
@@ -1741,10 +1281,17 @@
|
|
|
1741
1281
|
const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
|
|
1742
1282
|
const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
|
|
1743
1283
|
if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
|
|
1284
|
+
disposeEngine(decrypt);
|
|
1744
1285
|
throw new Error(ERR_INVALID_PASSWORD);
|
|
1745
1286
|
}
|
|
1746
1287
|
}
|
|
1747
1288
|
|
|
1289
|
+
function disposeEngine({ engine }) {
|
|
1290
|
+
if (engine && engine.dispose) {
|
|
1291
|
+
engine.dispose();
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1748
1295
|
async function createEncryptionKeys(encrypt, strength, password) {
|
|
1749
1296
|
const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength]));
|
|
1750
1297
|
const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
|
|
@@ -1753,48 +1300,22 @@
|
|
|
1753
1300
|
|
|
1754
1301
|
async function createKeys$1(aesCrypto, strength, password, salt) {
|
|
1755
1302
|
aesCrypto.password = null;
|
|
1756
|
-
const
|
|
1757
|
-
const
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2));
|
|
1761
|
-
const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2);
|
|
1762
|
-
Object.assign(aesCrypto, {
|
|
1763
|
-
keys: {
|
|
1764
|
-
key,
|
|
1765
|
-
authentication,
|
|
1766
|
-
passwordVerification
|
|
1767
|
-
},
|
|
1768
|
-
ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)),
|
|
1769
|
-
hmac: new HmacSha1(authentication)
|
|
1770
|
-
});
|
|
1771
|
-
return passwordVerification;
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
async function importKey(format, password, algorithm, extractable, keyUsages) {
|
|
1775
|
-
if (IMPORT_KEY_SUPPORTED) {
|
|
1776
|
-
try {
|
|
1777
|
-
return await subtle.importKey(format, password, algorithm, extractable, keyUsages);
|
|
1778
|
-
} catch {
|
|
1779
|
-
IMPORT_KEY_SUPPORTED = false;
|
|
1780
|
-
return misc.importKey(password);
|
|
1781
|
-
}
|
|
1782
|
-
} else {
|
|
1783
|
-
return misc.importKey(password);
|
|
1784
|
-
}
|
|
1303
|
+
const keyLength = KEY_LENGTH[strength];
|
|
1304
|
+
const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
|
|
1305
|
+
aesCrypto.engine = createEngine(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
|
|
1306
|
+
return subarray(compositeKey, keyLength * 2);
|
|
1785
1307
|
}
|
|
1786
1308
|
|
|
1787
|
-
async function
|
|
1309
|
+
async function deriveKey(password, salt, length) {
|
|
1788
1310
|
if (DERIVE_BITS_SUPPORTED) {
|
|
1789
1311
|
try {
|
|
1790
|
-
|
|
1312
|
+
const baseKey = await subtle.importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
|
|
1313
|
+
return new Uint8Array(await subtle.deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, length * 8));
|
|
1791
1314
|
} catch {
|
|
1792
1315
|
DERIVE_BITS_SUPPORTED = false;
|
|
1793
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1794
1316
|
}
|
|
1795
|
-
} else {
|
|
1796
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1797
1317
|
}
|
|
1318
|
+
return pbkdf2(password, salt, PBKDF2_ITERATIONS, length);
|
|
1798
1319
|
}
|
|
1799
1320
|
|
|
1800
1321
|
function encodePassword(password, rawPassword) {
|
|
@@ -1818,13 +1339,6 @@
|
|
|
1818
1339
|
return array.subarray(begin, end);
|
|
1819
1340
|
}
|
|
1820
1341
|
|
|
1821
|
-
function fromBits(codecBytes, chunk) {
|
|
1822
|
-
return codecBytes.fromBits(chunk);
|
|
1823
|
-
}
|
|
1824
|
-
function toBits(codecBytes, chunk) {
|
|
1825
|
-
return codecBytes.toBits(chunk);
|
|
1826
|
-
}
|
|
1827
|
-
|
|
1828
1342
|
/*
|
|
1829
1343
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
1830
1344
|
|
|
@@ -2764,11 +2278,18 @@
|
|
|
2764
2278
|
return true;
|
|
2765
2279
|
}
|
|
2766
2280
|
if (FallbackStream) {
|
|
2281
|
+
return await loadModule(config);
|
|
2282
|
+
}
|
|
2283
|
+
return false;
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
async function loadModule(config) {
|
|
2287
|
+
if (initModule) {
|
|
2767
2288
|
try {
|
|
2768
2289
|
await initModule(config);
|
|
2769
2290
|
return true;
|
|
2770
2291
|
} catch {
|
|
2771
|
-
|
|
2292
|
+
// ignored
|
|
2772
2293
|
}
|
|
2773
2294
|
}
|
|
2774
2295
|
return false;
|
|
@@ -2811,26 +2332,27 @@
|
|
|
2811
2332
|
terminate() {
|
|
2812
2333
|
return new Promise(resolve => {
|
|
2813
2334
|
const { worker, busy } = workerData;
|
|
2814
|
-
if (
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2335
|
+
if (busy) {
|
|
2336
|
+
workerData.resolveTerminated = resolve;
|
|
2337
|
+
} else {
|
|
2338
|
+
if (worker) {
|
|
2818
2339
|
worker.terminate();
|
|
2819
|
-
|
|
2340
|
+
workerData.worker = null;
|
|
2820
2341
|
}
|
|
2821
|
-
workerData.interface = null;
|
|
2822
|
-
} else {
|
|
2823
2342
|
resolve();
|
|
2824
2343
|
}
|
|
2344
|
+
workerData.interface = null;
|
|
2825
2345
|
});
|
|
2826
2346
|
},
|
|
2827
2347
|
onTaskFinished() {
|
|
2828
2348
|
if (workerData.busy) {
|
|
2829
|
-
const { resolveTerminated } = workerData;
|
|
2349
|
+
const { resolveTerminated, worker } = workerData;
|
|
2830
2350
|
if (resolveTerminated) {
|
|
2831
2351
|
workerData.resolveTerminated = null;
|
|
2832
|
-
|
|
2833
|
-
|
|
2352
|
+
if (worker) {
|
|
2353
|
+
workerData.terminated = true;
|
|
2354
|
+
worker.terminate();
|
|
2355
|
+
}
|
|
2834
2356
|
resolveTerminated();
|
|
2835
2357
|
}
|
|
2836
2358
|
workerData.busy = false;
|
|
@@ -2887,28 +2409,23 @@
|
|
|
2887
2409
|
}
|
|
2888
2410
|
|
|
2889
2411
|
async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
|
|
2890
|
-
let codecStream, chunkStream;
|
|
2412
|
+
let codecStream, chunkStream, modulePromise;
|
|
2891
2413
|
try {
|
|
2892
2414
|
if (options.compressed && !options.format) {
|
|
2893
2415
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
2894
2416
|
const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
|
|
2895
2417
|
const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
|
|
2896
2418
|
if (!options.useCompressionStream) {
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
} catch {
|
|
2900
|
-
if (!FallbackStream || FallbackStream.requiresModule) {
|
|
2901
|
-
options.useCompressionStream = true;
|
|
2902
|
-
}
|
|
2419
|
+
if (!await moduleLoaded() && (!FallbackStream || FallbackStream.requiresModule)) {
|
|
2420
|
+
options.useCompressionStream = true;
|
|
2903
2421
|
}
|
|
2904
2422
|
} else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
|
|
2905
|
-
|
|
2906
|
-
await initModule(config);
|
|
2907
|
-
} catch {
|
|
2908
|
-
// ignored
|
|
2909
|
-
}
|
|
2423
|
+
await moduleLoaded();
|
|
2910
2424
|
}
|
|
2911
2425
|
}
|
|
2426
|
+
if (options.encrypted && !options.zipCrypto) {
|
|
2427
|
+
await moduleLoaded();
|
|
2428
|
+
}
|
|
2912
2429
|
codecStream = new CodecStream(options, config);
|
|
2913
2430
|
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2914
2431
|
await readable
|
|
@@ -2941,6 +2458,13 @@
|
|
|
2941
2458
|
} finally {
|
|
2942
2459
|
onTaskFinished();
|
|
2943
2460
|
}
|
|
2461
|
+
|
|
2462
|
+
function moduleLoaded() {
|
|
2463
|
+
if (!modulePromise) {
|
|
2464
|
+
modulePromise = loadModule(config);
|
|
2465
|
+
}
|
|
2466
|
+
return modulePromise;
|
|
2467
|
+
}
|
|
2944
2468
|
}
|
|
2945
2469
|
|
|
2946
2470
|
/*
|
|
@@ -3047,7 +2571,7 @@
|
|
|
3047
2571
|
rejectResult = error => {
|
|
3048
2572
|
const { outputSize, workerOptions } = workerData;
|
|
3049
2573
|
workerOptions.outputSize = outputSize;
|
|
3050
|
-
if (isErrorObject(error)
|
|
2574
|
+
if (isErrorObject(error)) {
|
|
3051
2575
|
try {
|
|
3052
2576
|
error.outputSize = outputSize;
|
|
3053
2577
|
} catch {
|
|
@@ -3061,12 +2585,14 @@
|
|
|
3061
2585
|
reader: null,
|
|
3062
2586
|
writer: null,
|
|
3063
2587
|
outputSize: 0,
|
|
2588
|
+
destinationFailed: false,
|
|
2589
|
+
destinationError: null,
|
|
3064
2590
|
resolveResult,
|
|
3065
2591
|
rejectResult,
|
|
3066
2592
|
result
|
|
3067
2593
|
});
|
|
3068
2594
|
const { readable, options } = workerData;
|
|
3069
|
-
const { writable, closed, abortPipe } = watchClosedStream(workerData.writable);
|
|
2595
|
+
const { writable, closed, abortPipe } = watchClosedStream(workerData.writable, workerData);
|
|
3070
2596
|
let streamsTransferred;
|
|
3071
2597
|
try {
|
|
3072
2598
|
streamsTransferred = sendMessage({
|
|
@@ -3109,7 +2635,18 @@
|
|
|
3109
2635
|
} catch {
|
|
3110
2636
|
// ignored
|
|
3111
2637
|
}
|
|
3112
|
-
|
|
2638
|
+
const { outputSize, workerOptions, destinationFailed, destinationError } = workerData;
|
|
2639
|
+
workerOptions.outputSize = outputSize;
|
|
2640
|
+
const workerFailed = isErrorObject(error) && (error.codecImportFailed || error.workerStartupFailed);
|
|
2641
|
+
const reportedError = destinationFailed && !workerFailed ? destinationError : error;
|
|
2642
|
+
if (isErrorObject(reportedError)) {
|
|
2643
|
+
try {
|
|
2644
|
+
reportedError.outputSize = outputSize;
|
|
2645
|
+
} catch {
|
|
2646
|
+
// ignored
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
throw reportedError;
|
|
3113
2650
|
}
|
|
3114
2651
|
|
|
3115
2652
|
async function closeWritable() {
|
|
@@ -3123,12 +2660,27 @@
|
|
|
3123
2660
|
}
|
|
3124
2661
|
}
|
|
3125
2662
|
|
|
3126
|
-
function watchClosedStream(writableSource) {
|
|
2663
|
+
function watchClosedStream(writableSource, workerData) {
|
|
3127
2664
|
const abortController = new AbortController();
|
|
3128
|
-
|
|
2665
|
+
let aborting;
|
|
2666
|
+
const { writable, readable } = new TransformStream({
|
|
2667
|
+
transform(chunk, controller) {
|
|
2668
|
+
workerData.outputSize += chunk.length;
|
|
2669
|
+
controller.enqueue(chunk);
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
3129
2672
|
const closed = readable.pipeTo(writableSource, { preventClose: true, preventAbort: true, signal: abortController.signal });
|
|
3130
|
-
closed.catch(
|
|
3131
|
-
|
|
2673
|
+
closed.catch(error => {
|
|
2674
|
+
if (!aborting) {
|
|
2675
|
+
Object.assign(workerData, { destinationFailed: true, destinationError: error });
|
|
2676
|
+
}
|
|
2677
|
+
});
|
|
2678
|
+
return {
|
|
2679
|
+
writable, closed, abortPipe: () => {
|
|
2680
|
+
aborting = true;
|
|
2681
|
+
abortController.abort();
|
|
2682
|
+
}
|
|
2683
|
+
};
|
|
3132
2684
|
}
|
|
3133
2685
|
|
|
3134
2686
|
function releaseWorkerStreams(workerData) {
|
|
@@ -3326,9 +2878,6 @@
|
|
|
3326
2878
|
const stale = () => workerData.generation != generation;
|
|
3327
2879
|
try {
|
|
3328
2880
|
if (error) {
|
|
3329
|
-
if (error.outputSize !== UNDEFINED_VALUE) {
|
|
3330
|
-
workerData.outputSize = error.outputSize;
|
|
3331
|
-
}
|
|
3332
2881
|
fail(getResponseError(error, errorValue));
|
|
3333
2882
|
} else {
|
|
3334
2883
|
if (type == MESSAGE_PULL) {
|
|
@@ -3341,7 +2890,6 @@
|
|
|
3341
2890
|
const chunk = new Uint8Array(value);
|
|
3342
2891
|
await writer.ready;
|
|
3343
2892
|
await writer.write(chunk);
|
|
3344
|
-
workerData.outputSize += chunk.length;
|
|
3345
2893
|
if (!stale()) {
|
|
3346
2894
|
sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
|
|
3347
2895
|
}
|
|
@@ -4073,16 +3621,14 @@
|
|
|
4073
3621
|
combineSizeEocd
|
|
4074
3622
|
} = httpReader;
|
|
4075
3623
|
if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
|
|
4076
|
-
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -
|
|
3624
|
+
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
|
|
4077
3625
|
const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
|
|
4078
3626
|
if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
|
|
4079
3627
|
throw new Error(ERR_HTTP_RANGE);
|
|
4080
3628
|
} else {
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
httpReader.eocdCache = eocdCache;
|
|
4085
|
-
}
|
|
3629
|
+
let eocdCache;
|
|
3630
|
+
if (combineSizeEocd && response.status == 206) {
|
|
3631
|
+
eocdCache = new Uint8Array(await response.arrayBuffer());
|
|
4086
3632
|
}
|
|
4087
3633
|
setResourceValidators(httpReader, response);
|
|
4088
3634
|
const contentSize = getContentRangeSize(response);
|
|
@@ -4091,6 +3637,9 @@
|
|
|
4091
3637
|
} else {
|
|
4092
3638
|
httpReader.size = contentSize;
|
|
4093
3639
|
}
|
|
3640
|
+
if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
|
|
3641
|
+
httpReader.eocdCache = eocdCache;
|
|
3642
|
+
}
|
|
4094
3643
|
}
|
|
4095
3644
|
} else {
|
|
4096
3645
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
@@ -4106,25 +3655,23 @@
|
|
|
4106
3655
|
options
|
|
4107
3656
|
} = httpReader;
|
|
4108
3657
|
if (useRangeHeader || forceRangeRequests) {
|
|
4109
|
-
if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
|
|
4110
|
-
return eocdCache;
|
|
4111
|
-
}
|
|
4112
3658
|
if (index >= size || length === 0) {
|
|
4113
3659
|
return EMPTY_UINT8_ARRAY;
|
|
4114
3660
|
} else {
|
|
4115
3661
|
if (index + length > size) {
|
|
4116
3662
|
length = size - index;
|
|
4117
3663
|
}
|
|
3664
|
+
if (eocdCache && index >= size - eocdCache.length) {
|
|
3665
|
+
const cacheIndex = index - (size - eocdCache.length);
|
|
3666
|
+
return eocdCache.slice(cacheIndex, cacheIndex + length);
|
|
3667
|
+
}
|
|
4118
3668
|
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
|
|
4119
3669
|
if (response.status != 206) {
|
|
4120
3670
|
throw new Error(ERR_HTTP_RANGE);
|
|
4121
3671
|
}
|
|
4122
|
-
const
|
|
4123
|
-
if (
|
|
4124
|
-
|
|
4125
|
-
if (!Number.isNaN(rangeStart) && rangeStart != index) {
|
|
4126
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4127
|
-
}
|
|
3672
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3673
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
|
|
3674
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4128
3675
|
}
|
|
4129
3676
|
checkResourceValidators(httpReader, response);
|
|
4130
3677
|
setResourceValidators(httpReader, response);
|
|
@@ -4184,12 +3731,9 @@
|
|
|
4184
3731
|
if (response.status != 206) {
|
|
4185
3732
|
throw new Error(ERR_HTTP_RANGE);
|
|
4186
3733
|
}
|
|
4187
|
-
const
|
|
4188
|
-
if (
|
|
4189
|
-
|
|
4190
|
-
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
4191
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4192
|
-
}
|
|
3734
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3735
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
|
|
3736
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4193
3737
|
}
|
|
4194
3738
|
checkResourceValidators(httpReader, response);
|
|
4195
3739
|
setResourceValidators(httpReader, response);
|
|
@@ -4205,6 +3749,16 @@
|
|
|
4205
3749
|
}
|
|
4206
3750
|
}
|
|
4207
3751
|
|
|
3752
|
+
function getContentRangeOffset(response) {
|
|
3753
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3754
|
+
if (contentRangeHeader) {
|
|
3755
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
3756
|
+
if (!Number.isNaN(rangeStart)) {
|
|
3757
|
+
return rangeStart;
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
|
|
4208
3762
|
function getContentRangeSize(response) {
|
|
4209
3763
|
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
4210
3764
|
if (contentRangeHeader) {
|
|
@@ -6724,7 +6278,6 @@
|
|
|
6724
6278
|
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6725
6279
|
rawExtraField,
|
|
6726
6280
|
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6727
|
-
extendedTimestamp: false,
|
|
6728
6281
|
headerArray,
|
|
6729
6282
|
headerView
|
|
6730
6283
|
});
|
|
@@ -7468,7 +7021,7 @@
|
|
|
7468
7021
|
}
|
|
7469
7022
|
}
|
|
7470
7023
|
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7471
|
-
if (emptyEntry &&
|
|
7024
|
+
if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7472
7025
|
dataDescriptor = false;
|
|
7473
7026
|
}
|
|
7474
7027
|
const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
|
|
@@ -9078,7 +8631,7 @@
|
|
|
9078
8631
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9079
8632
|
*/
|
|
9080
8633
|
|
|
9081
|
-
const VERSION = "2.
|
|
8634
|
+
const VERSION = "2.14.0";
|
|
9082
8635
|
|
|
9083
8636
|
/*
|
|
9084
8637
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9998,12 +9551,16 @@
|
|
|
9998
9551
|
let directoryEntry = parent;
|
|
9999
9552
|
if (name) {
|
|
10000
9553
|
directoryEntry = parent.getChildByName(name);
|
|
10001
|
-
if (directoryEntry && !directoryEntry.directory) {
|
|
9554
|
+
if (directoryEntry && (!directoryEntry.directory || directoryEntry.data)) {
|
|
10002
9555
|
if (duplicates == DUPLICATES_KEEP_FIRST) {
|
|
10003
9556
|
continue;
|
|
10004
9557
|
} else if (duplicates == DUPLICATES_KEEP_LAST) {
|
|
10005
|
-
|
|
10006
|
-
|
|
9558
|
+
if (directoryEntry.directory) {
|
|
9559
|
+
directoryEntry.data = entry;
|
|
9560
|
+
} else {
|
|
9561
|
+
this.fs.remove(directoryEntry);
|
|
9562
|
+
directoryEntry = UNDEFINED_VALUE;
|
|
9563
|
+
}
|
|
10007
9564
|
} else {
|
|
10008
9565
|
throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
|
|
10009
9566
|
}
|