@zip.js/zip.js 2.13.1 → 2.14.1
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 +349 -416
- package/deno.json +1 -1
- package/dist/zip-core-external.js +761 -945
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +626 -911
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +768 -948
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +633 -914
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +768 -948
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +635 -916
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +771 -951
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +628 -913
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-module.wasm +0 -0
- package/dist/zip-native.js +628 -913
- 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 +764 -948
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +635 -916
- package/index-native.min.js +1 -1
- package/index.cjs +771 -951
- package/index.d.cts +52 -12
- package/index.d.ts +52 -12
- package/index.min.js +1 -1
- package/lib/core/codec-worker.js +37 -26
- 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 +486 -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.js +2 -7
- 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-reader.js +53 -6
- 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,487 @@
|
|
|
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
|
-
|
|
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 = 16;
|
|
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 keystream = new Int32Array(BLOCK_LENGTH$1 / 4);
|
|
759
|
+
const hmac = createHmac(authenticationKey);
|
|
760
|
+
let counter0 = 0;
|
|
761
|
+
let counter1 = 0;
|
|
762
|
+
let counter2 = 0;
|
|
763
|
+
let counter3 = 0;
|
|
764
|
+
return {
|
|
765
|
+
process(data, decrypt) {
|
|
766
|
+
if (decrypt) {
|
|
767
|
+
hmac.update(data, 0, data.length);
|
|
905
768
|
}
|
|
906
|
-
|
|
907
|
-
|
|
769
|
+
encrypt(data);
|
|
770
|
+
if (!decrypt) {
|
|
771
|
+
hmac.update(data, 0, data.length);
|
|
908
772
|
}
|
|
909
|
-
|
|
773
|
+
},
|
|
774
|
+
digest() {
|
|
775
|
+
return hmac.digest();
|
|
910
776
|
}
|
|
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;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
h[0] = (h[0] + a) | 0;
|
|
1076
|
-
h[1] = (h[1] + b) | 0;
|
|
1077
|
-
h[2] = (h[2] + c) | 0;
|
|
1078
|
-
h[3] = (h[3] + d) | 0;
|
|
1079
|
-
h[4] = (h[4] + e) | 0;
|
|
1080
|
-
}
|
|
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
|
-
}
|
|
777
|
+
};
|
|
1156
778
|
|
|
1157
|
-
|
|
779
|
+
function encrypt(data) {
|
|
780
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
781
|
+
const length = data.length;
|
|
782
|
+
let offset = 0;
|
|
783
|
+
for (; offset + BLOCK_LENGTH$1 <= length; offset += BLOCK_LENGTH$1) {
|
|
784
|
+
nextKeystream();
|
|
785
|
+
view.setInt32(offset, view.getInt32(offset) ^ keystream[0]);
|
|
786
|
+
view.setInt32(offset + 4, view.getInt32(offset + 4) ^ keystream[1]);
|
|
787
|
+
view.setInt32(offset + 8, view.getInt32(offset + 8) ^ keystream[2]);
|
|
788
|
+
view.setInt32(offset + 12, view.getInt32(offset + 12) ^ keystream[3]);
|
|
1158
789
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
if (i <= 4 || j < 4) {
|
|
1164
|
-
decKey[j] = tmp;
|
|
1165
|
-
} else {
|
|
1166
|
-
decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
|
|
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;
|
|
1297
|
-
}
|
|
1298
|
-
};
|
|
1299
|
-
|
|
1300
|
-
/** @fileOverview CTR mode implementation.
|
|
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;
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
reset() {
|
|
1330
|
-
this._iv = this._initIv;
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
/** Input some data to calculate.
|
|
1334
|
-
* @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last.
|
|
1335
|
-
*/
|
|
1336
|
-
update(data) {
|
|
1337
|
-
return this.calculate(this._prf, data, this._iv);
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
incWord(word) {
|
|
1341
|
-
if (((word >> 24) & 0xff) === 0xff) { //overflow
|
|
1342
|
-
let b1 = (word >> 16) & 0xff;
|
|
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;
|
|
790
|
+
if (offset < length) {
|
|
791
|
+
nextKeystream();
|
|
792
|
+
for (let indexByte = 0; offset < length; offset++, indexByte++) {
|
|
793
|
+
data[offset] ^= keystream[indexByte >> 2] >>> (24 - 8 * (indexByte & 3));
|
|
1360
794
|
}
|
|
1361
|
-
|
|
1362
|
-
word = 0;
|
|
1363
|
-
word += (b1 << 16);
|
|
1364
|
-
word += (b2 << 8);
|
|
1365
|
-
word += b3;
|
|
1366
|
-
} else {
|
|
1367
|
-
word += (0x01 << 24);
|
|
1368
|
-
}
|
|
1369
|
-
return word;
|
|
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]);
|
|
1376
795
|
}
|
|
1377
796
|
}
|
|
1378
797
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
if (!
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
const e = prf.encrypt(iv);
|
|
1388
|
-
data[i] ^= e[0];
|
|
1389
|
-
data[i + 1] ^= e[1];
|
|
1390
|
-
data[i + 2] ^= e[2];
|
|
1391
|
-
data[i + 3] ^= e[3];
|
|
1392
|
-
}
|
|
1393
|
-
return bitArray.clamp(data, bl);
|
|
1394
|
-
}
|
|
1395
|
-
};
|
|
1396
|
-
|
|
1397
|
-
const misc = {
|
|
1398
|
-
importKey(password) {
|
|
1399
|
-
return new misc.hmacSha1(codec.bytes.toBits(password));
|
|
1400
|
-
},
|
|
1401
|
-
pbkdf2(prf, salt, count, length) {
|
|
1402
|
-
count = count || 10000;
|
|
1403
|
-
if (length < 0 || count < 0) {
|
|
1404
|
-
throw new Error("invalid params to pbkdf2");
|
|
1405
|
-
}
|
|
1406
|
-
const byteLength = ((length >> 5) + 1) << 2;
|
|
1407
|
-
let u, ui, i, j, k;
|
|
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];
|
|
798
|
+
function nextKeystream() {
|
|
799
|
+
counter0 = (counter0 + 1) | 0;
|
|
800
|
+
if (!counter0) {
|
|
801
|
+
counter1 = (counter1 + 1) | 0;
|
|
802
|
+
if (!counter1) {
|
|
803
|
+
counter2 = (counter2 + 1) | 0;
|
|
804
|
+
if (!counter2) {
|
|
805
|
+
counter3 = (counter3 + 1) | 0;
|
|
1419
806
|
}
|
|
1420
807
|
}
|
|
1421
|
-
for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
|
|
1422
|
-
out.setInt32(outLength, u[i]);
|
|
1423
|
-
outLength += 4;
|
|
1424
|
-
}
|
|
1425
808
|
}
|
|
1426
|
-
|
|
809
|
+
let s0 = swapBytes(counter0) ^ roundKeys[0];
|
|
810
|
+
let s1 = swapBytes(counter1) ^ roundKeys[1];
|
|
811
|
+
let s2 = swapBytes(counter2) ^ roundKeys[2];
|
|
812
|
+
let s3 = swapBytes(counter3) ^ roundKeys[3];
|
|
813
|
+
let t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[4];
|
|
814
|
+
let t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[5];
|
|
815
|
+
let t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[6];
|
|
816
|
+
let t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[7];
|
|
817
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[8];
|
|
818
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[9];
|
|
819
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[10];
|
|
820
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[11];
|
|
821
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[12];
|
|
822
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[13];
|
|
823
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[14];
|
|
824
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[15];
|
|
825
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[16];
|
|
826
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[17];
|
|
827
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[18];
|
|
828
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[19];
|
|
829
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[20];
|
|
830
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[21];
|
|
831
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[22];
|
|
832
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[23];
|
|
833
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[24];
|
|
834
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[25];
|
|
835
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[26];
|
|
836
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[27];
|
|
837
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[28];
|
|
838
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[29];
|
|
839
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[30];
|
|
840
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[31];
|
|
841
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[32];
|
|
842
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[33];
|
|
843
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[34];
|
|
844
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[35];
|
|
845
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[36];
|
|
846
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[37];
|
|
847
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[38];
|
|
848
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[39];
|
|
849
|
+
let indexKey = 40;
|
|
850
|
+
if (rounds > 10) {
|
|
851
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[40];
|
|
852
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[41];
|
|
853
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[42];
|
|
854
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[43];
|
|
855
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[44];
|
|
856
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[45];
|
|
857
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[46];
|
|
858
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[47];
|
|
859
|
+
indexKey = 48;
|
|
860
|
+
}
|
|
861
|
+
if (rounds > 12) {
|
|
862
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[48];
|
|
863
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[49];
|
|
864
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[50];
|
|
865
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[51];
|
|
866
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[52];
|
|
867
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[53];
|
|
868
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[54];
|
|
869
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[55];
|
|
870
|
+
indexKey = 56;
|
|
871
|
+
}
|
|
872
|
+
keystream[0] = ((S_BOX[t0 >>> 24] << 24) | (S_BOX[(t1 >>> 16) & 255] << 16) | (S_BOX[(t2 >>> 8) & 255] << 8) | S_BOX[t3 & 255]) ^ roundKeys[indexKey];
|
|
873
|
+
keystream[1] = ((S_BOX[t1 >>> 24] << 24) | (S_BOX[(t2 >>> 16) & 255] << 16) | (S_BOX[(t3 >>> 8) & 255] << 8) | S_BOX[t0 & 255]) ^ roundKeys[indexKey + 1];
|
|
874
|
+
keystream[2] = ((S_BOX[t2 >>> 24] << 24) | (S_BOX[(t3 >>> 16) & 255] << 16) | (S_BOX[(t0 >>> 8) & 255] << 8) | S_BOX[t1 & 255]) ^ roundKeys[indexKey + 2];
|
|
875
|
+
keystream[3] = ((S_BOX[t3 >>> 24] << 24) | (S_BOX[(t0 >>> 16) & 255] << 16) | (S_BOX[(t1 >>> 8) & 255] << 8) | S_BOX[t2 & 255]) ^ roundKeys[indexKey + 3];
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
function pbkdf2(password, salt, iterations, length) {
|
|
880
|
+
const hmac = createHmac(password);
|
|
881
|
+
const result = new Uint8Array(length);
|
|
882
|
+
const block = new Uint8Array(salt.length + 4);
|
|
883
|
+
const blockView = new DataView(block.buffer);
|
|
884
|
+
block.set(salt);
|
|
885
|
+
for (let indexBlock = 1, offset = 0; offset < length; indexBlock++, offset += SHA1_DIGEST_LENGTH) {
|
|
886
|
+
blockView.setUint32(salt.length, indexBlock);
|
|
887
|
+
hmac.update(block, 0, block.length);
|
|
888
|
+
let previous = hmac.digest();
|
|
889
|
+
const output = previous.slice();
|
|
890
|
+
for (let iteration = 1; iteration < iterations; iteration++) {
|
|
891
|
+
hmac.update(previous, 0, SHA1_DIGEST_LENGTH);
|
|
892
|
+
previous = hmac.digest();
|
|
893
|
+
for (let indexByte = 0; indexByte < SHA1_DIGEST_LENGTH; indexByte++) {
|
|
894
|
+
output[indexByte] ^= previous[indexByte];
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
result.set(output.subarray(0, Math.min(SHA1_DIGEST_LENGTH, length - offset)), offset);
|
|
1427
898
|
}
|
|
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
|
-
}
|
|
899
|
+
return result;
|
|
900
|
+
}
|
|
1459
901
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
902
|
+
function createHmac(key) {
|
|
903
|
+
const sha1 = createSha1();
|
|
904
|
+
const innerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
905
|
+
const outerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
906
|
+
if (key.length > SHA1_BLOCK_LENGTH) {
|
|
907
|
+
sha1.update(key, 0, key.length);
|
|
908
|
+
key = sha1.digest();
|
|
1463
909
|
}
|
|
1464
|
-
|
|
1465
|
-
const
|
|
1466
|
-
|
|
1467
|
-
|
|
910
|
+
for (let indexByte = 0; indexByte < SHA1_BLOCK_LENGTH; indexByte++) {
|
|
911
|
+
const keyByte = indexByte < key.length ? key[indexByte] : 0;
|
|
912
|
+
innerKey[indexByte] = keyByte ^ HMAC_INNER_PADDING;
|
|
913
|
+
outerKey[indexByte] = keyByte ^ HMAC_OUTER_PADDING;
|
|
1468
914
|
}
|
|
915
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
916
|
+
return {
|
|
917
|
+
update(data, offset, length) {
|
|
918
|
+
sha1.update(data, offset, length);
|
|
919
|
+
},
|
|
920
|
+
digest() {
|
|
921
|
+
const innerDigest = sha1.digest();
|
|
922
|
+
sha1.update(outerKey, 0, SHA1_BLOCK_LENGTH);
|
|
923
|
+
sha1.update(innerDigest, 0, SHA1_DIGEST_LENGTH);
|
|
924
|
+
const result = sha1.digest();
|
|
925
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
926
|
+
return result;
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
}
|
|
1469
930
|
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
931
|
+
function createSha1() {
|
|
932
|
+
const state = new Int32Array(SHA1_INITIAL_STATE);
|
|
933
|
+
const schedule = new Int32Array(SHA1_SCHEDULE_LENGTH);
|
|
934
|
+
const block = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
935
|
+
const blockView = new DataView(block.buffer);
|
|
936
|
+
const lengthBytes = new Uint8Array(8);
|
|
937
|
+
let blockLength = 0;
|
|
938
|
+
let totalLength = 0;
|
|
939
|
+
return {
|
|
940
|
+
update,
|
|
941
|
+
digest
|
|
942
|
+
};
|
|
1482
943
|
|
|
944
|
+
function update(data, offset, length) {
|
|
945
|
+
const end = offset + length;
|
|
946
|
+
totalLength += length;
|
|
947
|
+
if (blockLength) {
|
|
948
|
+
while (offset < end && blockLength < SHA1_BLOCK_LENGTH) {
|
|
949
|
+
block[blockLength++] = data[offset++];
|
|
950
|
+
}
|
|
951
|
+
if (blockLength == SHA1_BLOCK_LENGTH) {
|
|
952
|
+
compress(blockView, 0);
|
|
953
|
+
blockLength = 0;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
if (offset + SHA1_BLOCK_LENGTH <= end) {
|
|
957
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
958
|
+
for (; offset + SHA1_BLOCK_LENGTH <= end; offset += SHA1_BLOCK_LENGTH) {
|
|
959
|
+
compress(view, offset);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
while (offset < end) {
|
|
963
|
+
block[blockLength++] = data[offset++];
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
function digest() {
|
|
968
|
+
const bits = totalLength * 8;
|
|
969
|
+
const high = Math.floor(bits / 0x100000000);
|
|
970
|
+
const low = bits >>> 0;
|
|
971
|
+
update(SHA1_PADDING, 0, 1);
|
|
972
|
+
while (blockLength != SHA1_LENGTH_OFFSET) {
|
|
973
|
+
update(SHA1_ZERO, 0, 1);
|
|
974
|
+
}
|
|
975
|
+
lengthBytes[0] = high >>> 24;
|
|
976
|
+
lengthBytes[1] = high >>> 16;
|
|
977
|
+
lengthBytes[2] = high >>> 8;
|
|
978
|
+
lengthBytes[3] = high;
|
|
979
|
+
lengthBytes[4] = low >>> 24;
|
|
980
|
+
lengthBytes[5] = low >>> 16;
|
|
981
|
+
lengthBytes[6] = low >>> 8;
|
|
982
|
+
lengthBytes[7] = low;
|
|
983
|
+
update(lengthBytes, 0, 8);
|
|
984
|
+
const result = new Uint8Array(SHA1_DIGEST_LENGTH);
|
|
985
|
+
const resultView = new DataView(result.buffer);
|
|
986
|
+
for (let indexWord = 0; indexWord < state.length; indexWord++) {
|
|
987
|
+
resultView.setInt32(4 * indexWord, state[indexWord]);
|
|
988
|
+
}
|
|
989
|
+
state.set(SHA1_INITIAL_STATE);
|
|
990
|
+
blockLength = 0;
|
|
991
|
+
totalLength = 0;
|
|
1483
992
|
return result;
|
|
1484
993
|
}
|
|
1485
994
|
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
995
|
+
function compress(view, offset) {
|
|
996
|
+
for (let index = 0; index < 16; index++) {
|
|
997
|
+
schedule[index] = view.getInt32(offset + 4 * index);
|
|
998
|
+
}
|
|
999
|
+
let a = state[0];
|
|
1000
|
+
let b = state[1];
|
|
1001
|
+
let c = state[2];
|
|
1002
|
+
let d = state[3];
|
|
1003
|
+
let e = state[4];
|
|
1004
|
+
let t;
|
|
1005
|
+
for (let index = 0; index < 15; index += 5) {
|
|
1006
|
+
e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[index]) | 0;
|
|
1007
|
+
b = (b << 30) | (b >>> 2);
|
|
1008
|
+
d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + schedule[index + 1]) | 0;
|
|
1009
|
+
a = (a << 30) | (a >>> 2);
|
|
1010
|
+
c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + schedule[index + 2]) | 0;
|
|
1011
|
+
e = (e << 30) | (e >>> 2);
|
|
1012
|
+
b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + schedule[index + 3]) | 0;
|
|
1013
|
+
d = (d << 30) | (d >>> 2);
|
|
1014
|
+
a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + schedule[index + 4]) | 0;
|
|
1015
|
+
c = (c << 30) | (c >>> 2);
|
|
1016
|
+
}
|
|
1017
|
+
e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[15]) | 0;
|
|
1018
|
+
b = (b << 30) | (b >>> 2);
|
|
1019
|
+
t = schedule[13] ^ schedule[8] ^ schedule[2] ^ schedule[0];
|
|
1020
|
+
t = (t << 1) | (t >>> 31);
|
|
1021
|
+
schedule[0] = t;
|
|
1022
|
+
d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + t) | 0;
|
|
1023
|
+
a = (a << 30) | (a >>> 2);
|
|
1024
|
+
t = schedule[14] ^ schedule[9] ^ schedule[3] ^ schedule[1];
|
|
1025
|
+
t = (t << 1) | (t >>> 31);
|
|
1026
|
+
schedule[1] = t;
|
|
1027
|
+
c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + t) | 0;
|
|
1028
|
+
e = (e << 30) | (e >>> 2);
|
|
1029
|
+
t = schedule[15] ^ schedule[10] ^ schedule[4] ^ schedule[2];
|
|
1030
|
+
t = (t << 1) | (t >>> 31);
|
|
1031
|
+
schedule[2] = t;
|
|
1032
|
+
b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + t) | 0;
|
|
1033
|
+
d = (d << 30) | (d >>> 2);
|
|
1034
|
+
t = schedule[0] ^ schedule[11] ^ schedule[5] ^ schedule[3];
|
|
1035
|
+
t = (t << 1) | (t >>> 31);
|
|
1036
|
+
schedule[3] = t;
|
|
1037
|
+
a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + t) | 0;
|
|
1038
|
+
c = (c << 30) | (c >>> 2);
|
|
1039
|
+
for (let index = 20; index < 40; index += 5) {
|
|
1040
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1041
|
+
t = (t << 1) | (t >>> 31);
|
|
1042
|
+
schedule[(index) & 15] = t;
|
|
1043
|
+
e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + t) | 0;
|
|
1044
|
+
b = (b << 30) | (b >>> 2);
|
|
1045
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1046
|
+
t = (t << 1) | (t >>> 31);
|
|
1047
|
+
schedule[(index + 1) & 15] = t;
|
|
1048
|
+
d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0x6ED9EBA1 + t) | 0;
|
|
1049
|
+
a = (a << 30) | (a >>> 2);
|
|
1050
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1051
|
+
t = (t << 1) | (t >>> 31);
|
|
1052
|
+
schedule[(index + 2) & 15] = t;
|
|
1053
|
+
c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0x6ED9EBA1 + t) | 0;
|
|
1054
|
+
e = (e << 30) | (e >>> 2);
|
|
1055
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1056
|
+
t = (t << 1) | (t >>> 31);
|
|
1057
|
+
schedule[(index + 3) & 15] = t;
|
|
1058
|
+
b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0x6ED9EBA1 + t) | 0;
|
|
1059
|
+
d = (d << 30) | (d >>> 2);
|
|
1060
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1061
|
+
t = (t << 1) | (t >>> 31);
|
|
1062
|
+
schedule[(index + 4) & 15] = t;
|
|
1063
|
+
a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0x6ED9EBA1 + t) | 0;
|
|
1064
|
+
c = (c << 30) | (c >>> 2);
|
|
1065
|
+
}
|
|
1066
|
+
for (let index = 40; index < 60; index += 5) {
|
|
1067
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1068
|
+
t = (t << 1) | (t >>> 31);
|
|
1069
|
+
schedule[(index) & 15] = t;
|
|
1070
|
+
e = (((a << 5) | (a >>> 27)) + ((b & c) | ((b | c) & d)) + e + 0x8F1BBCDC + t) | 0;
|
|
1071
|
+
b = (b << 30) | (b >>> 2);
|
|
1072
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1073
|
+
t = (t << 1) | (t >>> 31);
|
|
1074
|
+
schedule[(index + 1) & 15] = t;
|
|
1075
|
+
d = (((e << 5) | (e >>> 27)) + ((a & b) | ((a | b) & c)) + d + 0x8F1BBCDC + t) | 0;
|
|
1076
|
+
a = (a << 30) | (a >>> 2);
|
|
1077
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1078
|
+
t = (t << 1) | (t >>> 31);
|
|
1079
|
+
schedule[(index + 2) & 15] = t;
|
|
1080
|
+
c = (((d << 5) | (d >>> 27)) + ((e & a) | ((e | a) & b)) + c + 0x8F1BBCDC + t) | 0;
|
|
1081
|
+
e = (e << 30) | (e >>> 2);
|
|
1082
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1083
|
+
t = (t << 1) | (t >>> 31);
|
|
1084
|
+
schedule[(index + 3) & 15] = t;
|
|
1085
|
+
b = (((c << 5) | (c >>> 27)) + ((d & e) | ((d | e) & a)) + b + 0x8F1BBCDC + t) | 0;
|
|
1086
|
+
d = (d << 30) | (d >>> 2);
|
|
1087
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1088
|
+
t = (t << 1) | (t >>> 31);
|
|
1089
|
+
schedule[(index + 4) & 15] = t;
|
|
1090
|
+
a = (((b << 5) | (b >>> 27)) + ((c & d) | ((c | d) & e)) + a + 0x8F1BBCDC + t) | 0;
|
|
1091
|
+
c = (c << 30) | (c >>> 2);
|
|
1092
|
+
}
|
|
1093
|
+
for (let index = 60; index < 80; index += 5) {
|
|
1094
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1095
|
+
t = (t << 1) | (t >>> 31);
|
|
1096
|
+
schedule[(index) & 15] = t;
|
|
1097
|
+
e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + t) | 0;
|
|
1098
|
+
b = (b << 30) | (b >>> 2);
|
|
1099
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1100
|
+
t = (t << 1) | (t >>> 31);
|
|
1101
|
+
schedule[(index + 1) & 15] = t;
|
|
1102
|
+
d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0xCA62C1D6 + t) | 0;
|
|
1103
|
+
a = (a << 30) | (a >>> 2);
|
|
1104
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1105
|
+
t = (t << 1) | (t >>> 31);
|
|
1106
|
+
schedule[(index + 2) & 15] = t;
|
|
1107
|
+
c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0xCA62C1D6 + t) | 0;
|
|
1108
|
+
e = (e << 30) | (e >>> 2);
|
|
1109
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1110
|
+
t = (t << 1) | (t >>> 31);
|
|
1111
|
+
schedule[(index + 3) & 15] = t;
|
|
1112
|
+
b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0xCA62C1D6 + t) | 0;
|
|
1113
|
+
d = (d << 30) | (d >>> 2);
|
|
1114
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1115
|
+
t = (t << 1) | (t >>> 31);
|
|
1116
|
+
schedule[(index + 4) & 15] = t;
|
|
1117
|
+
a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0xCA62C1D6 + t) | 0;
|
|
1118
|
+
c = (c << 30) | (c >>> 2);
|
|
1119
|
+
}
|
|
1120
|
+
state[0] = (state[0] + a) | 0;
|
|
1121
|
+
state[1] = (state[1] + b) | 0;
|
|
1122
|
+
state[2] = (state[2] + c) | 0;
|
|
1123
|
+
state[3] = (state[3] + d) | 0;
|
|
1124
|
+
state[4] = (state[4] + e) | 0;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
function initTables() {
|
|
1129
|
+
if (!tablesInitialized) {
|
|
1130
|
+
let p = 1;
|
|
1131
|
+
let q = 1;
|
|
1132
|
+
do {
|
|
1133
|
+
p = (p ^ (p << 1) ^ ((p & 0x80) ? 0x1b : 0)) & 255;
|
|
1134
|
+
q = (q ^ (q << 1)) & 255;
|
|
1135
|
+
q = (q ^ (q << 2)) & 255;
|
|
1136
|
+
q = (q ^ (q << 4)) & 255;
|
|
1137
|
+
if (q & 0x80) {
|
|
1138
|
+
q ^= 0x09;
|
|
1139
|
+
}
|
|
1140
|
+
S_BOX[p] = (q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)) ^ 0x63) & 255;
|
|
1141
|
+
} while (p != 1);
|
|
1142
|
+
S_BOX[0] = 0x63;
|
|
1143
|
+
for (let index = 0; index < 256; index++) {
|
|
1144
|
+
const s = S_BOX[index];
|
|
1145
|
+
const s2 = multiplyByTwo(s);
|
|
1146
|
+
const t = (s2 << 24) | (s << 16) | (s << 8) | (s2 ^ s);
|
|
1147
|
+
T0[index] = t;
|
|
1148
|
+
T1[index] = (t >>> 8) | (t << 24);
|
|
1149
|
+
T2[index] = (t >>> 16) | (t << 16);
|
|
1150
|
+
T3[index] = (t >>> 24) | (t << 8);
|
|
1151
|
+
}
|
|
1152
|
+
tablesInitialized = true;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
function expandKey(key, roundKeys) {
|
|
1157
|
+
const keyWords = key.length >> 2;
|
|
1158
|
+
const rounds = keyWords + 6;
|
|
1159
|
+
const total = 4 * (rounds + 1);
|
|
1160
|
+
let roundConstant = 1;
|
|
1161
|
+
for (let index = 0; index < keyWords; index++) {
|
|
1162
|
+
roundKeys[index] = (key[4 * index] << 24) | (key[4 * index + 1] << 16) | (key[4 * index + 2] << 8) | key[4 * index + 3];
|
|
1163
|
+
}
|
|
1164
|
+
for (let index = keyWords; index < total; index++) {
|
|
1165
|
+
let word = roundKeys[index - 1];
|
|
1166
|
+
if (index % keyWords == 0) {
|
|
1167
|
+
word = substituteWord((word << 8) | (word >>> 24)) ^ (roundConstant << 24);
|
|
1168
|
+
roundConstant = multiplyByTwo(roundConstant);
|
|
1169
|
+
} else if (keyWords > 6 && index % keyWords == 4) {
|
|
1170
|
+
word = substituteWord(word);
|
|
1171
|
+
}
|
|
1172
|
+
roundKeys[index] = roundKeys[index - keyWords] ^ word;
|
|
1173
|
+
}
|
|
1174
|
+
return rounds;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
function substituteWord(word) {
|
|
1178
|
+
return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
function swapBytes(value) {
|
|
1182
|
+
return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
function multiplyByTwo(value) {
|
|
1186
|
+
return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
|
|
1187
|
+
}
|
|
1495
1188
|
|
|
1496
1189
|
/*
|
|
1497
1190
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
@@ -1546,8 +1239,8 @@
|
|
|
1546
1239
|
1. Redistributions of source code must retain the above copyright notice,
|
|
1547
1240
|
this list of conditions and the following disclaimer.
|
|
1548
1241
|
|
|
1549
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
1550
|
-
notice, this list of conditions and the following disclaimer in
|
|
1242
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
1243
|
+
notice, this list of conditions and the following disclaimer in
|
|
1551
1244
|
the documentation and/or other materials provided with the distribution.
|
|
1552
1245
|
|
|
1553
1246
|
3. The names of the authors may not be used to endorse or promote products
|
|
@@ -1571,24 +1264,21 @@
|
|
|
1571
1264
|
const PBKDF2_ALGORITHM = { name: "PBKDF2" };
|
|
1572
1265
|
const HASH_ALGORITHM = { name: "HMAC" };
|
|
1573
1266
|
const HASH_FUNCTION = "SHA-1";
|
|
1267
|
+
const PBKDF2_ITERATIONS = 1000;
|
|
1574
1268
|
const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
|
|
1575
|
-
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations:
|
|
1269
|
+
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: PBKDF2_ITERATIONS, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
|
|
1576
1270
|
const DERIVED_BITS_USAGE = ["deriveBits"];
|
|
1577
1271
|
const SALT_LENGTH = [8, 12, 16];
|
|
1578
1272
|
const KEY_LENGTH = [16, 24, 32];
|
|
1579
1273
|
const AUTHENTICATION_CODE_LENGTH = 10;
|
|
1580
|
-
const
|
|
1274
|
+
const PASSWORD_VERIFICATION_LENGTH = 2;
|
|
1581
1275
|
// deno-lint-ignore valid-typeof
|
|
1582
1276
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
1583
1277
|
const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
|
|
1584
1278
|
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
1279
|
|
|
1590
|
-
let
|
|
1591
|
-
let
|
|
1280
|
+
let DERIVE_BITS_SUPPORTED = SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE && typeof subtle.deriveBits == FUNCTION_TYPE;
|
|
1281
|
+
let createEngine = createEngine$1;
|
|
1592
1282
|
|
|
1593
1283
|
class AESDecryptionStream extends TransformStream {
|
|
1594
1284
|
|
|
@@ -1606,9 +1296,10 @@
|
|
|
1606
1296
|
ready
|
|
1607
1297
|
} = aesCrypto;
|
|
1608
1298
|
if (password) {
|
|
1609
|
-
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] +
|
|
1610
|
-
chunk = subarray(chunk, SALT_LENGTH[strength] +
|
|
1299
|
+
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH));
|
|
1300
|
+
chunk = subarray(chunk, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH);
|
|
1611
1301
|
if (checkPasswordOnly) {
|
|
1302
|
+
disposeEngine(aesCrypto);
|
|
1612
1303
|
controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
|
|
1613
1304
|
} else {
|
|
1614
1305
|
resolveReady();
|
|
@@ -1621,23 +1312,16 @@
|
|
|
1621
1312
|
},
|
|
1622
1313
|
async flush(controller) {
|
|
1623
1314
|
const {
|
|
1624
|
-
|
|
1625
|
-
hmac,
|
|
1315
|
+
engine,
|
|
1626
1316
|
pendingInput,
|
|
1627
1317
|
ready
|
|
1628
1318
|
} = this;
|
|
1629
|
-
if (
|
|
1319
|
+
if (engine) {
|
|
1630
1320
|
await ready;
|
|
1631
|
-
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1632
1321
|
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);
|
|
1322
|
+
const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
|
|
1323
|
+
engine.process(decryptedChunkArray, true);
|
|
1324
|
+
const authenticationCode = engine.digest();
|
|
1641
1325
|
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1642
1326
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1643
1327
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
@@ -1647,6 +1331,9 @@
|
|
|
1647
1331
|
}
|
|
1648
1332
|
controller.enqueue(decryptedChunkArray);
|
|
1649
1333
|
}
|
|
1334
|
+
},
|
|
1335
|
+
cancel() {
|
|
1336
|
+
disposeEngine(this);
|
|
1650
1337
|
}
|
|
1651
1338
|
});
|
|
1652
1339
|
}
|
|
@@ -1676,26 +1363,24 @@
|
|
|
1676
1363
|
}
|
|
1677
1364
|
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
1678
1365
|
output.set(preamble, 0);
|
|
1679
|
-
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
1366
|
+
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
|
|
1680
1367
|
},
|
|
1681
1368
|
async flush(controller) {
|
|
1682
1369
|
const {
|
|
1683
|
-
|
|
1684
|
-
hmac,
|
|
1370
|
+
engine,
|
|
1685
1371
|
pendingInput,
|
|
1686
1372
|
ready
|
|
1687
1373
|
} = this;
|
|
1688
|
-
if (
|
|
1374
|
+
if (engine) {
|
|
1689
1375
|
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);
|
|
1376
|
+
const encryptedChunkArray = new Uint8Array(pendingInput);
|
|
1377
|
+
engine.process(encryptedChunkArray, false);
|
|
1378
|
+
const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1697
1379
|
controller.enqueue(concat(encryptedChunkArray, authenticationCode));
|
|
1698
1380
|
}
|
|
1381
|
+
},
|
|
1382
|
+
cancel() {
|
|
1383
|
+
disposeEngine(this);
|
|
1699
1384
|
}
|
|
1700
1385
|
});
|
|
1701
1386
|
}
|
|
@@ -1710,30 +1395,23 @@
|
|
|
1710
1395
|
});
|
|
1711
1396
|
}
|
|
1712
1397
|
|
|
1713
|
-
function append(aesCrypto, input, output, paddingStart, paddingEnd,
|
|
1398
|
+
function append(aesCrypto, input, output, paddingStart, paddingEnd, decrypt) {
|
|
1714
1399
|
const {
|
|
1715
|
-
|
|
1716
|
-
hmac,
|
|
1400
|
+
engine,
|
|
1717
1401
|
pendingInput
|
|
1718
1402
|
} = aesCrypto;
|
|
1719
1403
|
if (pendingInput.length) {
|
|
1720
1404
|
input = concat(pendingInput, input);
|
|
1721
1405
|
}
|
|
1722
1406
|
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);
|
|
1407
|
+
const alignedLength = inputLength - (inputLength % BLOCK_LENGTH);
|
|
1408
|
+
output = expand(output, paddingStart + alignedLength);
|
|
1409
|
+
if (alignedLength) {
|
|
1410
|
+
const chunk = subarray(output, paddingStart, paddingStart + alignedLength);
|
|
1411
|
+
chunk.set(subarray(input, 0, alignedLength));
|
|
1412
|
+
engine.process(chunk, decrypt);
|
|
1413
|
+
}
|
|
1414
|
+
aesCrypto.pendingInput = subarray(input, alignedLength);
|
|
1737
1415
|
return output;
|
|
1738
1416
|
}
|
|
1739
1417
|
|
|
@@ -1741,10 +1419,17 @@
|
|
|
1741
1419
|
const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
|
|
1742
1420
|
const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
|
|
1743
1421
|
if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
|
|
1422
|
+
disposeEngine(decrypt);
|
|
1744
1423
|
throw new Error(ERR_INVALID_PASSWORD);
|
|
1745
1424
|
}
|
|
1746
1425
|
}
|
|
1747
1426
|
|
|
1427
|
+
function disposeEngine({ engine }) {
|
|
1428
|
+
if (engine && engine.dispose) {
|
|
1429
|
+
engine.dispose();
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1748
1433
|
async function createEncryptionKeys(encrypt, strength, password) {
|
|
1749
1434
|
const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength]));
|
|
1750
1435
|
const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
|
|
@@ -1753,48 +1438,22 @@
|
|
|
1753
1438
|
|
|
1754
1439
|
async function createKeys$1(aesCrypto, strength, password, salt) {
|
|
1755
1440
|
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;
|
|
1441
|
+
const keyLength = KEY_LENGTH[strength];
|
|
1442
|
+
const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
|
|
1443
|
+
aesCrypto.engine = createEngine(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
|
|
1444
|
+
return subarray(compositeKey, keyLength * 2);
|
|
1772
1445
|
}
|
|
1773
1446
|
|
|
1774
|
-
async function
|
|
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
|
-
}
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
async function deriveBits(algorithm, baseKey, length) {
|
|
1447
|
+
async function deriveKey(password, salt, length) {
|
|
1788
1448
|
if (DERIVE_BITS_SUPPORTED) {
|
|
1789
1449
|
try {
|
|
1790
|
-
|
|
1450
|
+
const baseKey = await subtle.importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
|
|
1451
|
+
return new Uint8Array(await subtle.deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, length * 8));
|
|
1791
1452
|
} catch {
|
|
1792
1453
|
DERIVE_BITS_SUPPORTED = false;
|
|
1793
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1794
1454
|
}
|
|
1795
|
-
} else {
|
|
1796
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1797
1455
|
}
|
|
1456
|
+
return pbkdf2(password, salt, PBKDF2_ITERATIONS, length);
|
|
1798
1457
|
}
|
|
1799
1458
|
|
|
1800
1459
|
function encodePassword(password, rawPassword) {
|
|
@@ -1818,13 +1477,6 @@
|
|
|
1818
1477
|
return array.subarray(begin, end);
|
|
1819
1478
|
}
|
|
1820
1479
|
|
|
1821
|
-
function fromBits(codecBytes, chunk) {
|
|
1822
|
-
return codecBytes.fromBits(chunk);
|
|
1823
|
-
}
|
|
1824
|
-
function toBits(codecBytes, chunk) {
|
|
1825
|
-
return codecBytes.toBits(chunk);
|
|
1826
|
-
}
|
|
1827
|
-
|
|
1828
1480
|
/*
|
|
1829
1481
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
1830
1482
|
|
|
@@ -2764,11 +2416,18 @@
|
|
|
2764
2416
|
return true;
|
|
2765
2417
|
}
|
|
2766
2418
|
if (FallbackStream) {
|
|
2419
|
+
return await loadModule(config);
|
|
2420
|
+
}
|
|
2421
|
+
return false;
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
async function loadModule(config) {
|
|
2425
|
+
if (initModule) {
|
|
2767
2426
|
try {
|
|
2768
2427
|
await initModule(config);
|
|
2769
2428
|
return true;
|
|
2770
2429
|
} catch {
|
|
2771
|
-
|
|
2430
|
+
// ignored
|
|
2772
2431
|
}
|
|
2773
2432
|
}
|
|
2774
2433
|
return false;
|
|
@@ -2811,27 +2470,29 @@
|
|
|
2811
2470
|
terminate() {
|
|
2812
2471
|
return new Promise(resolve => {
|
|
2813
2472
|
const { worker, busy } = workerData;
|
|
2814
|
-
if (
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2473
|
+
if (busy) {
|
|
2474
|
+
workerData.terminateResolvers = workerData.terminateResolvers || [];
|
|
2475
|
+
workerData.terminateResolvers.push(resolve);
|
|
2476
|
+
} else {
|
|
2477
|
+
if (worker) {
|
|
2818
2478
|
worker.terminate();
|
|
2819
|
-
|
|
2479
|
+
workerData.worker = null;
|
|
2820
2480
|
}
|
|
2821
|
-
workerData.interface = null;
|
|
2822
|
-
} else {
|
|
2823
2481
|
resolve();
|
|
2824
2482
|
}
|
|
2483
|
+
workerData.interface = null;
|
|
2825
2484
|
});
|
|
2826
2485
|
},
|
|
2827
2486
|
onTaskFinished() {
|
|
2828
2487
|
if (workerData.busy) {
|
|
2829
|
-
const {
|
|
2830
|
-
if (
|
|
2831
|
-
workerData.
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2488
|
+
const { terminateResolvers, worker } = workerData;
|
|
2489
|
+
if (terminateResolvers) {
|
|
2490
|
+
workerData.terminateResolvers = null;
|
|
2491
|
+
if (worker) {
|
|
2492
|
+
workerData.terminated = true;
|
|
2493
|
+
worker.terminate();
|
|
2494
|
+
}
|
|
2495
|
+
terminateResolvers.forEach(resolve => resolve());
|
|
2835
2496
|
}
|
|
2836
2497
|
workerData.busy = false;
|
|
2837
2498
|
onTaskFinished(workerData);
|
|
@@ -2887,28 +2548,23 @@
|
|
|
2887
2548
|
}
|
|
2888
2549
|
|
|
2889
2550
|
async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
|
|
2890
|
-
let codecStream, chunkStream;
|
|
2551
|
+
let codecStream, chunkStream, modulePromise;
|
|
2891
2552
|
try {
|
|
2892
2553
|
if (options.compressed && !options.format) {
|
|
2893
2554
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
2894
2555
|
const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
|
|
2895
2556
|
const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
|
|
2896
2557
|
if (!options.useCompressionStream) {
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
} catch {
|
|
2900
|
-
if (!FallbackStream || FallbackStream.requiresModule) {
|
|
2901
|
-
options.useCompressionStream = true;
|
|
2902
|
-
}
|
|
2558
|
+
if (!await moduleLoaded() && (!FallbackStream || FallbackStream.requiresModule)) {
|
|
2559
|
+
options.useCompressionStream = true;
|
|
2903
2560
|
}
|
|
2904
2561
|
} else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
|
|
2905
|
-
|
|
2906
|
-
await initModule(config);
|
|
2907
|
-
} catch {
|
|
2908
|
-
// ignored
|
|
2909
|
-
}
|
|
2562
|
+
await moduleLoaded();
|
|
2910
2563
|
}
|
|
2911
2564
|
}
|
|
2565
|
+
if (options.encrypted && !options.zipCrypto) {
|
|
2566
|
+
await moduleLoaded();
|
|
2567
|
+
}
|
|
2912
2568
|
codecStream = new CodecStream(options, config);
|
|
2913
2569
|
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2914
2570
|
await readable
|
|
@@ -2941,6 +2597,13 @@
|
|
|
2941
2597
|
} finally {
|
|
2942
2598
|
onTaskFinished();
|
|
2943
2599
|
}
|
|
2600
|
+
|
|
2601
|
+
function moduleLoaded() {
|
|
2602
|
+
if (!modulePromise) {
|
|
2603
|
+
modulePromise = loadModule(config);
|
|
2604
|
+
}
|
|
2605
|
+
return modulePromise;
|
|
2606
|
+
}
|
|
2944
2607
|
}
|
|
2945
2608
|
|
|
2946
2609
|
/*
|
|
@@ -4097,16 +3760,14 @@
|
|
|
4097
3760
|
combineSizeEocd
|
|
4098
3761
|
} = httpReader;
|
|
4099
3762
|
if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
|
|
4100
|
-
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -
|
|
3763
|
+
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
|
|
4101
3764
|
const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
|
|
4102
3765
|
if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
|
|
4103
3766
|
throw new Error(ERR_HTTP_RANGE);
|
|
4104
3767
|
} else {
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
httpReader.eocdCache = eocdCache;
|
|
4109
|
-
}
|
|
3768
|
+
let eocdCache;
|
|
3769
|
+
if (combineSizeEocd && response.status == 206) {
|
|
3770
|
+
eocdCache = new Uint8Array(await response.arrayBuffer());
|
|
4110
3771
|
}
|
|
4111
3772
|
setResourceValidators(httpReader, response);
|
|
4112
3773
|
const contentSize = getContentRangeSize(response);
|
|
@@ -4115,6 +3776,9 @@
|
|
|
4115
3776
|
} else {
|
|
4116
3777
|
httpReader.size = contentSize;
|
|
4117
3778
|
}
|
|
3779
|
+
if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
|
|
3780
|
+
httpReader.eocdCache = eocdCache;
|
|
3781
|
+
}
|
|
4118
3782
|
}
|
|
4119
3783
|
} else {
|
|
4120
3784
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
@@ -4130,25 +3794,23 @@
|
|
|
4130
3794
|
options
|
|
4131
3795
|
} = httpReader;
|
|
4132
3796
|
if (useRangeHeader || forceRangeRequests) {
|
|
4133
|
-
if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
|
|
4134
|
-
return eocdCache;
|
|
4135
|
-
}
|
|
4136
3797
|
if (index >= size || length === 0) {
|
|
4137
3798
|
return EMPTY_UINT8_ARRAY;
|
|
4138
3799
|
} else {
|
|
4139
3800
|
if (index + length > size) {
|
|
4140
3801
|
length = size - index;
|
|
4141
3802
|
}
|
|
3803
|
+
if (eocdCache && index >= size - eocdCache.length) {
|
|
3804
|
+
const cacheIndex = index - (size - eocdCache.length);
|
|
3805
|
+
return eocdCache.slice(cacheIndex, cacheIndex + length);
|
|
3806
|
+
}
|
|
4142
3807
|
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
|
|
4143
3808
|
if (response.status != 206) {
|
|
4144
3809
|
throw new Error(ERR_HTTP_RANGE);
|
|
4145
3810
|
}
|
|
4146
|
-
const
|
|
4147
|
-
if (
|
|
4148
|
-
|
|
4149
|
-
if (!Number.isNaN(rangeStart) && rangeStart != index) {
|
|
4150
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4151
|
-
}
|
|
3811
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3812
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
|
|
3813
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4152
3814
|
}
|
|
4153
3815
|
checkResourceValidators(httpReader, response);
|
|
4154
3816
|
setResourceValidators(httpReader, response);
|
|
@@ -4208,12 +3870,9 @@
|
|
|
4208
3870
|
if (response.status != 206) {
|
|
4209
3871
|
throw new Error(ERR_HTTP_RANGE);
|
|
4210
3872
|
}
|
|
4211
|
-
const
|
|
4212
|
-
if (
|
|
4213
|
-
|
|
4214
|
-
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
4215
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4216
|
-
}
|
|
3873
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3874
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
|
|
3875
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4217
3876
|
}
|
|
4218
3877
|
checkResourceValidators(httpReader, response);
|
|
4219
3878
|
setResourceValidators(httpReader, response);
|
|
@@ -4229,6 +3888,16 @@
|
|
|
4229
3888
|
}
|
|
4230
3889
|
}
|
|
4231
3890
|
|
|
3891
|
+
function getContentRangeOffset(response) {
|
|
3892
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3893
|
+
if (contentRangeHeader) {
|
|
3894
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
3895
|
+
if (!Number.isNaN(rangeStart)) {
|
|
3896
|
+
return rangeStart;
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
|
|
4232
3901
|
function getContentRangeSize(response) {
|
|
4233
3902
|
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
4234
3903
|
if (contentRangeHeader) {
|
|
@@ -5009,7 +4678,7 @@
|
|
|
5009
4678
|
Object.assign(this, {
|
|
5010
4679
|
reader: new GenericReader(reader),
|
|
5011
4680
|
options,
|
|
5012
|
-
readRanges: new
|
|
4681
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
5013
4682
|
});
|
|
5014
4683
|
}
|
|
5015
4684
|
|
|
@@ -5654,7 +5323,6 @@
|
|
|
5654
5323
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5655
5324
|
}
|
|
5656
5325
|
const size = compressedSize;
|
|
5657
|
-
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5658
5326
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5659
5327
|
throwIfAborted(signal);
|
|
5660
5328
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -5728,6 +5396,7 @@
|
|
|
5728
5396
|
writer = new GenericWriter(writer);
|
|
5729
5397
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5730
5398
|
({ writable } = writer);
|
|
5399
|
+
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5731
5400
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5732
5401
|
if (writtenSize != outputSize) {
|
|
5733
5402
|
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
@@ -6163,14 +5832,61 @@
|
|
|
6163
5832
|
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
6164
5833
|
fileEntry
|
|
6165
5834
|
};
|
|
6166
|
-
|
|
6167
|
-
|
|
5835
|
+
const { indexes, sortedRanges, pendingRanges } = readRanges;
|
|
5836
|
+
if (!indexes.has(index)) {
|
|
5837
|
+
const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
|
|
5838
|
+
if (overlappingRange) {
|
|
6168
5839
|
const error = new Error(ERR_OVERLAPPING_ENTRY);
|
|
6169
|
-
error.overlappingEntry =
|
|
5840
|
+
error.overlappingEntry = overlappingRange.fileEntry;
|
|
6170
5841
|
throw error;
|
|
6171
5842
|
}
|
|
5843
|
+
indexes.add(index);
|
|
5844
|
+
pendingRanges.push(range);
|
|
5845
|
+
if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
|
|
5846
|
+
pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
|
|
5847
|
+
readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
|
|
5848
|
+
pendingRanges.length = 0;
|
|
5849
|
+
}
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
|
|
5853
|
+
function findOverlappingRange(sortedRanges, range) {
|
|
5854
|
+
let low = 0;
|
|
5855
|
+
let high = sortedRanges.length;
|
|
5856
|
+
while (low < high) {
|
|
5857
|
+
const middle = (low + high) >>> 1;
|
|
5858
|
+
if (sortedRanges[middle].start < range.start) {
|
|
5859
|
+
low = middle + 1;
|
|
5860
|
+
} else {
|
|
5861
|
+
high = middle;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
const previousRange = sortedRanges[low - 1];
|
|
5865
|
+
const nextRange = sortedRanges[low];
|
|
5866
|
+
if (previousRange && rangesOverlap(range, previousRange)) {
|
|
5867
|
+
return previousRange;
|
|
5868
|
+
}
|
|
5869
|
+
if (nextRange && rangesOverlap(range, nextRange)) {
|
|
5870
|
+
return nextRange;
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
|
|
5874
|
+
function rangesOverlap(range, otherRange) {
|
|
5875
|
+
return range.start < otherRange.end && otherRange.start < range.end;
|
|
5876
|
+
}
|
|
5877
|
+
|
|
5878
|
+
function mergeRanges(sortedRanges, pendingRanges) {
|
|
5879
|
+
const mergedRanges = [];
|
|
5880
|
+
let indexSorted = 0;
|
|
5881
|
+
let indexPending = 0;
|
|
5882
|
+
while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
|
|
5883
|
+
if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
|
|
5884
|
+
mergedRanges.push(sortedRanges[indexSorted++]);
|
|
5885
|
+
} else {
|
|
5886
|
+
mergedRanges.push(pendingRanges[indexPending++]);
|
|
5887
|
+
}
|
|
6172
5888
|
}
|
|
6173
|
-
|
|
5889
|
+
return mergedRanges;
|
|
6174
5890
|
}
|
|
6175
5891
|
|
|
6176
5892
|
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
@@ -6748,7 +6464,6 @@
|
|
|
6748
6464
|
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6749
6465
|
rawExtraField,
|
|
6750
6466
|
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6751
|
-
extendedTimestamp: false,
|
|
6752
6467
|
headerArray,
|
|
6753
6468
|
headerView
|
|
6754
6469
|
});
|
|
@@ -7492,7 +7207,7 @@
|
|
|
7492
7207
|
}
|
|
7493
7208
|
}
|
|
7494
7209
|
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7495
|
-
if (emptyEntry &&
|
|
7210
|
+
if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7496
7211
|
dataDescriptor = false;
|
|
7497
7212
|
}
|
|
7498
7213
|
const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
|
|
@@ -9102,7 +8817,7 @@
|
|
|
9102
8817
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
9103
8818
|
*/
|
|
9104
8819
|
|
|
9105
|
-
const VERSION = "2.
|
|
8820
|
+
const VERSION = "2.14.1";
|
|
9106
8821
|
|
|
9107
8822
|
/*
|
|
9108
8823
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -10022,12 +9737,16 @@
|
|
|
10022
9737
|
let directoryEntry = parent;
|
|
10023
9738
|
if (name) {
|
|
10024
9739
|
directoryEntry = parent.getChildByName(name);
|
|
10025
|
-
if (directoryEntry && !directoryEntry.directory) {
|
|
9740
|
+
if (directoryEntry && (!directoryEntry.directory || directoryEntry.data)) {
|
|
10026
9741
|
if (duplicates == DUPLICATES_KEEP_FIRST) {
|
|
10027
9742
|
continue;
|
|
10028
9743
|
} else if (duplicates == DUPLICATES_KEEP_LAST) {
|
|
10029
|
-
|
|
10030
|
-
|
|
9744
|
+
if (directoryEntry.directory) {
|
|
9745
|
+
directoryEntry.data = entry;
|
|
9746
|
+
} else {
|
|
9747
|
+
this.fs.remove(directoryEntry);
|
|
9748
|
+
directoryEntry = UNDEFINED_VALUE;
|
|
9749
|
+
}
|
|
10031
9750
|
} else {
|
|
10032
9751
|
throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
|
|
10033
9752
|
}
|