single-file-core 1.5.129 → 1.6.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/core/helper.js +27 -1
- package/core/index.js +34 -21
- package/core/infobar.js +7 -7
- package/core/lib/processor-helper-inline.js +1 -1
- package/core/lib/processor-helper.js +1 -1
- package/package.json +1 -1
- package/processors/compression/compression.js +2 -1
- package/processors/frame-tree/content/content-frame-tree.js +1 -1
- package/processors/hooks/content/content-hooks-frames-web.js +48 -38
- package/processors/hooks/content/content-hooks-frames.js +28 -27
- package/processors/lazy/content/content-lazy-loader.js +10 -10
- package/single-file.js +10 -9
- package/test/capture/canonical-link.js +50 -0
- package/test/capture/common.js +1 -0
- package/test/capture/deferred-content-options.js +71 -0
- package/test/capture/dom.js +13 -1
- package/test/capture/maff-metadata.js +205 -0
- package/test/capture/script-uri-sanitization.js +82 -0
- package/test/sfz-harness/pages-archive.js +5 -2
- package/vendor/zip/z-worker.js +1 -1
- package/vendor/zip/zip.js +707 -951
- package/vendor/zip/zip.min.js +1 -1
- package/zip-build/package-lock.json +4 -4
- package/zip-build/package.json +1 -1
- package/zip-build/reserved-property-names.json +4 -0
- package/zip-build/rollup.config.js +1 -1
package/vendor/zip/zip.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker, setTimeout, clearTimeout } = typeof globalThis !== 'undefined' ? globalThis :
|
|
1
|
+
const { Array, Object, String, Number, BigInt, Math, Date, Map, Set, Response, URL, Error, Uint8Array, Uint16Array, Uint32Array, DataView, Blob, Promise, TextEncoder, TextDecoder, crypto, btoa, TransformStream, ReadableStream, WritableStream, CompressionStream, DecompressionStream, navigator, Worker, setTimeout, clearTimeout } = typeof globalThis !== 'undefined' ? globalThis : self;
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
@@ -566,7 +566,7 @@ for (let n = 0; n < 256; n++) {
|
|
|
566
566
|
T[k][n] = (previous >>> 8) ^ T[0][previous & 0xFF];
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
|
-
const [T0, T1, T2, T3, T4, T5, T6, T7] = T;
|
|
569
|
+
const [T0$1, T1$1, T2$1, T3$1, T4, T5, T6, T7] = T;
|
|
570
570
|
|
|
571
571
|
class Crc32 {
|
|
572
572
|
|
|
@@ -588,12 +588,12 @@ class Crc32 {
|
|
|
588
588
|
const a = crc ^ view.getInt32(offset, true);
|
|
589
589
|
const b = view.getInt32(offset + 4, true);
|
|
590
590
|
crc = T7[a & 0xFF] ^ T6[(a >>> 8) & 0xFF] ^ T5[(a >>> 16) & 0xFF] ^ T4[(a >>> 24) & 0xFF] ^
|
|
591
|
-
T3[b & 0xFF] ^ T2[(b >>> 8) & 0xFF] ^ T1[(b >>> 16) & 0xFF] ^ T0[(b >>> 24) & 0xFF];
|
|
591
|
+
T3$1[b & 0xFF] ^ T2$1[(b >>> 8) & 0xFF] ^ T1$1[(b >>> 16) & 0xFF] ^ T0$1[(b >>> 24) & 0xFF];
|
|
592
592
|
}
|
|
593
593
|
}
|
|
594
594
|
// Remaining tail (and non-typed inputs) byte-at-a-time with the base table.
|
|
595
595
|
for (; offset < length; offset++) {
|
|
596
|
-
crc = (crc >>> 8) ^ T0[(crc ^ data[offset]) & 0xFF];
|
|
596
|
+
crc = (crc >>> 8) ^ T0$1[(crc ^ data[offset]) & 0xFF];
|
|
597
597
|
}
|
|
598
598
|
this.crc = crc;
|
|
599
599
|
}
|
|
@@ -697,794 +697,487 @@ function encodeText(value) {
|
|
|
697
697
|
}
|
|
698
698
|
}
|
|
699
699
|
|
|
700
|
-
// Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
|
|
701
|
-
|
|
702
|
-
// deno-lint-ignore-file no-this-alias
|
|
703
|
-
|
|
704
700
|
/*
|
|
705
|
-
|
|
706
|
-
* license or under the GNU GPL, version 2.0.
|
|
707
|
-
*/
|
|
708
|
-
|
|
709
|
-
/** @fileOverview Javascript cryptography implementation.
|
|
710
|
-
*
|
|
711
|
-
* Crush to remove comments, shorten variable names and
|
|
712
|
-
* generally reduce transmission size.
|
|
713
|
-
*
|
|
714
|
-
* @author Emily Stark
|
|
715
|
-
* @author Mike Hamburg
|
|
716
|
-
* @author Dan Boneh
|
|
717
|
-
*/
|
|
718
|
-
|
|
719
|
-
/*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
|
|
720
|
-
|
|
721
|
-
/** @fileOverview Arrays of bits, encoded as arrays of Numbers.
|
|
722
|
-
*
|
|
723
|
-
* @author Emily Stark
|
|
724
|
-
* @author Mike Hamburg
|
|
725
|
-
* @author Dan Boneh
|
|
726
|
-
*/
|
|
727
|
-
|
|
728
|
-
/**
|
|
729
|
-
* Arrays of bits, encoded as arrays of Numbers.
|
|
730
|
-
* @namespace
|
|
731
|
-
* @description
|
|
732
|
-
* <p>
|
|
733
|
-
* These objects are the currency accepted by SJCL's crypto functions.
|
|
734
|
-
* </p>
|
|
735
|
-
*
|
|
736
|
-
* <p>
|
|
737
|
-
* Most of our crypto primitives operate on arrays of 4-byte words internally,
|
|
738
|
-
* but many of them can take arguments that are not a multiple of 4 bytes.
|
|
739
|
-
* This library encodes arrays of bits (whose size need not be a multiple of 8
|
|
740
|
-
* bits) as arrays of 32-bit words. The bits are packed, big-endian, into an
|
|
741
|
-
* array of words, 32 bits at a time. Since the words are double-precision
|
|
742
|
-
* floating point numbers, they fit some extra data. We use this (in a private,
|
|
743
|
-
* possibly-changing manner) to encode the number of bits actually present
|
|
744
|
-
* in the last word of the array.
|
|
745
|
-
* </p>
|
|
746
|
-
*
|
|
747
|
-
* <p>
|
|
748
|
-
* Because bitwise ops clear this out-of-band data, these arrays can be passed
|
|
749
|
-
* to ciphers like AES which want arrays of words.
|
|
750
|
-
* </p>
|
|
751
|
-
*/
|
|
752
|
-
const bitArray = {
|
|
753
|
-
/**
|
|
754
|
-
* Concatenate two bit arrays.
|
|
755
|
-
* @param {bitArray} a1 The first array.
|
|
756
|
-
* @param {bitArray} a2 The second array.
|
|
757
|
-
* @return {bitArray} The concatenation of a1 and a2.
|
|
758
|
-
*/
|
|
759
|
-
concat(a1, a2) {
|
|
760
|
-
if (a1.length === 0 || a2.length === 0) {
|
|
761
|
-
return a1.concat(a2);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
const last = a1[a1.length - 1], shift = bitArray.getPartial(last);
|
|
765
|
-
if (shift === 32) {
|
|
766
|
-
return a1.concat(a2);
|
|
767
|
-
} else {
|
|
768
|
-
return bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1));
|
|
769
|
-
}
|
|
770
|
-
},
|
|
771
|
-
|
|
772
|
-
/**
|
|
773
|
-
* Find the length of an array of bits.
|
|
774
|
-
* @param {bitArray} a The array.
|
|
775
|
-
* @return {Number} The length of a, in bits.
|
|
776
|
-
*/
|
|
777
|
-
bitLength(a) {
|
|
778
|
-
const l = a.length;
|
|
779
|
-
if (l === 0) {
|
|
780
|
-
return 0;
|
|
781
|
-
}
|
|
782
|
-
const x = a[l - 1];
|
|
783
|
-
return (l - 1) * 32 + bitArray.getPartial(x);
|
|
784
|
-
},
|
|
785
|
-
|
|
786
|
-
/**
|
|
787
|
-
* Truncate an array.
|
|
788
|
-
* @param {bitArray} a The array.
|
|
789
|
-
* @param {Number} len The length to truncate to, in bits.
|
|
790
|
-
* @return {bitArray} A new array, truncated to len bits.
|
|
791
|
-
*/
|
|
792
|
-
clamp(a, len) {
|
|
793
|
-
if (a.length * 32 < len) {
|
|
794
|
-
return a;
|
|
795
|
-
}
|
|
796
|
-
a = a.slice(0, Math.ceil(len / 32));
|
|
797
|
-
const l = a.length;
|
|
798
|
-
len = len & 31;
|
|
799
|
-
if (l > 0 && len) {
|
|
800
|
-
a[l - 1] = bitArray.partial(len, a[l - 1] & 0x80000000 >> (len - 1), 1);
|
|
801
|
-
}
|
|
802
|
-
return a;
|
|
803
|
-
},
|
|
804
|
-
|
|
805
|
-
/**
|
|
806
|
-
* Make a partial word for a bit array.
|
|
807
|
-
* @param {Number} len The number of bits in the word.
|
|
808
|
-
* @param {Number} x The bits.
|
|
809
|
-
* @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
|
|
810
|
-
* @return {Number} The partial word.
|
|
811
|
-
*/
|
|
812
|
-
partial(len, x, _end) {
|
|
813
|
-
if (len === 32) {
|
|
814
|
-
return x;
|
|
815
|
-
}
|
|
816
|
-
return (_end ? x | 0 : x << (32 - len)) + len * 0x10000000000;
|
|
817
|
-
},
|
|
701
|
+
Copyright (c) 2026 Gildas Lormeau. All rights reserved.
|
|
818
702
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
* @param {Number} x The partial word.
|
|
822
|
-
* @return {Number} The number of bits used by the partial word.
|
|
823
|
-
*/
|
|
824
|
-
getPartial(x) {
|
|
825
|
-
return Math.round(x / 0x10000000000) || 32;
|
|
826
|
-
},
|
|
703
|
+
Redistribution and use in source and binary forms, with or without
|
|
704
|
+
modification, are permitted provided that the following conditions are met:
|
|
827
705
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
* @param {Number} shift The number of bits to shift.
|
|
831
|
-
* @param {Number} [carry=0] A byte to carry in
|
|
832
|
-
* @param {bitArray} [out=[]] An array to prepend to the output.
|
|
833
|
-
* @private
|
|
834
|
-
*/
|
|
835
|
-
_shiftRight(a, shift, carry, out) {
|
|
836
|
-
if (out === undefined) {
|
|
837
|
-
out = [];
|
|
838
|
-
}
|
|
706
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
707
|
+
this list of conditions and the following disclaimer.
|
|
839
708
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
if (shift === 0) {
|
|
845
|
-
return out.concat(a);
|
|
846
|
-
}
|
|
709
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
710
|
+
notice, this list of conditions and the following disclaimer in
|
|
711
|
+
the documentation and/or other materials provided with the distribution.
|
|
847
712
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
carry = a[i] << (32 - shift);
|
|
851
|
-
}
|
|
852
|
-
const last2 = a.length ? a[a.length - 1] : 0;
|
|
853
|
-
const shift2 = bitArray.getPartial(last2);
|
|
854
|
-
out.push(bitArray.partial(shift + shift2 & 31, (shift + shift2 > 32) ? carry : out.pop(), 1));
|
|
855
|
-
return out;
|
|
856
|
-
}
|
|
857
|
-
};
|
|
713
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
714
|
+
derived from this software without specific prior written permission.
|
|
858
715
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
716
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
717
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
718
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
719
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
720
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
721
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
722
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
723
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
724
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
725
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
864
726
|
*/
|
|
865
727
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
728
|
+
const BLOCK_LENGTH$1 = 16;
|
|
729
|
+
const ROUND_KEYS_LENGTH = 60;
|
|
730
|
+
const SHA1_BLOCK_LENGTH = 64;
|
|
731
|
+
const SHA1_DIGEST_LENGTH = 20;
|
|
732
|
+
const SHA1_SCHEDULE_LENGTH = 16;
|
|
733
|
+
const SHA1_LENGTH_OFFSET = 56;
|
|
734
|
+
const SHA1_PADDING = new Uint8Array([0x80]);
|
|
735
|
+
const SHA1_ZERO = new Uint8Array(1);
|
|
736
|
+
const SHA1_INITIAL_STATE = new Int32Array([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
|
|
737
|
+
const HMAC_INNER_PADDING = 0x36;
|
|
738
|
+
const HMAC_OUTER_PADDING = 0x5c;
|
|
739
|
+
const S_BOX = new Uint8Array(256);
|
|
740
|
+
const T0 = new Int32Array(256);
|
|
741
|
+
const T1 = new Int32Array(256);
|
|
742
|
+
const T2 = new Int32Array(256);
|
|
743
|
+
const T3 = new Int32Array(256);
|
|
744
|
+
|
|
745
|
+
let tablesInitialized = false;
|
|
746
|
+
|
|
747
|
+
function createEngine$1(key, authenticationKey) {
|
|
748
|
+
initTables();
|
|
749
|
+
const roundKeys = new Int32Array(ROUND_KEYS_LENGTH);
|
|
750
|
+
const rounds = expandKey(key, roundKeys);
|
|
751
|
+
const keystream = new Int32Array(BLOCK_LENGTH$1 / 4);
|
|
752
|
+
const hmac = createHmac(authenticationKey);
|
|
753
|
+
let counter0 = 0;
|
|
754
|
+
let counter1 = 0;
|
|
755
|
+
let counter2 = 0;
|
|
756
|
+
let counter3 = 0;
|
|
757
|
+
return {
|
|
758
|
+
process(data, decrypt) {
|
|
759
|
+
if (decrypt) {
|
|
760
|
+
hmac.update(data, 0, data.length);
|
|
898
761
|
}
|
|
899
|
-
|
|
900
|
-
|
|
762
|
+
encrypt(data);
|
|
763
|
+
if (!decrypt) {
|
|
764
|
+
hmac.update(data, 0, data.length);
|
|
901
765
|
}
|
|
902
|
-
|
|
766
|
+
},
|
|
767
|
+
digest() {
|
|
768
|
+
return hmac.digest();
|
|
903
769
|
}
|
|
904
|
-
}
|
|
905
|
-
};
|
|
906
|
-
|
|
907
|
-
const hash = {};
|
|
908
|
-
|
|
909
|
-
/**
|
|
910
|
-
* Context for a SHA-1 operation in progress.
|
|
911
|
-
* @constructor
|
|
912
|
-
*/
|
|
913
|
-
hash.sha1 = class {
|
|
914
|
-
constructor(hash) {
|
|
915
|
-
const sha1 = this;
|
|
916
|
-
/**
|
|
917
|
-
* The hash's block size, in bits.
|
|
918
|
-
* @constant
|
|
919
|
-
*/
|
|
920
|
-
sha1.blockSize = 512;
|
|
921
|
-
/**
|
|
922
|
-
* The SHA-1 initialization vector.
|
|
923
|
-
* @private
|
|
924
|
-
*/
|
|
925
|
-
sha1._init = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0];
|
|
926
|
-
/**
|
|
927
|
-
* The SHA-1 hash key.
|
|
928
|
-
* @private
|
|
929
|
-
*/
|
|
930
|
-
sha1._key = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6];
|
|
931
|
-
if (hash) {
|
|
932
|
-
sha1._h = hash._h.slice(0);
|
|
933
|
-
sha1._buffer = hash._buffer.slice(0);
|
|
934
|
-
sha1._length = hash._length;
|
|
935
|
-
} else {
|
|
936
|
-
sha1.reset();
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
/**
|
|
941
|
-
* Reset the hash state.
|
|
942
|
-
* @return this
|
|
943
|
-
*/
|
|
944
|
-
reset() {
|
|
945
|
-
const sha1 = this;
|
|
946
|
-
sha1._h = sha1._init.slice(0);
|
|
947
|
-
sha1._buffer = [];
|
|
948
|
-
sha1._length = 0;
|
|
949
|
-
return sha1;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
/**
|
|
953
|
-
* Input several words to the hash.
|
|
954
|
-
* @param {bitArray|String} data the data to hash.
|
|
955
|
-
* @return this
|
|
956
|
-
*/
|
|
957
|
-
update(data) {
|
|
958
|
-
const sha1 = this;
|
|
959
|
-
if (typeof data === "string") {
|
|
960
|
-
data = codec.utf8String.toBits(data);
|
|
961
|
-
}
|
|
962
|
-
const b = sha1._buffer = bitArray.concat(sha1._buffer, data);
|
|
963
|
-
const ol = sha1._length;
|
|
964
|
-
const nl = sha1._length = ol + bitArray.bitLength(data);
|
|
965
|
-
if (nl > 9007199254740991) {
|
|
966
|
-
throw new Error("Cannot hash more than 2^53 - 1 bits");
|
|
967
|
-
}
|
|
968
|
-
const c = new Uint32Array(b);
|
|
969
|
-
let j = 0;
|
|
970
|
-
for (let i = sha1.blockSize + ol - ((sha1.blockSize + ol) & (sha1.blockSize - 1)); i <= nl;
|
|
971
|
-
i += sha1.blockSize) {
|
|
972
|
-
sha1._block(c.subarray(16 * j, 16 * (j + 1)));
|
|
973
|
-
j += 1;
|
|
974
|
-
}
|
|
975
|
-
b.splice(0, 16 * j);
|
|
976
|
-
return sha1;
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
/**
|
|
980
|
-
* Complete hashing and output the hash value.
|
|
981
|
-
* @return {bitArray} The hash value, an array of 5 big-endian words. TODO
|
|
982
|
-
*/
|
|
983
|
-
finalize() {
|
|
984
|
-
const sha1 = this;
|
|
985
|
-
let b = sha1._buffer;
|
|
986
|
-
const h = sha1._h;
|
|
987
|
-
|
|
988
|
-
// Round out and push the buffer
|
|
989
|
-
b = bitArray.concat(b, [bitArray.partial(1, 1)]);
|
|
990
|
-
// Round out the buffer to a multiple of 16 words, less the 2 length words.
|
|
991
|
-
for (let i = b.length + 2; i & 15; i++) {
|
|
992
|
-
b.push(0);
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
// append the length
|
|
996
|
-
b.push(Math.floor(sha1._length / 0x100000000));
|
|
997
|
-
b.push(sha1._length | 0);
|
|
998
|
-
|
|
999
|
-
while (b.length) {
|
|
1000
|
-
sha1._block(b.splice(0, 16));
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
sha1.reset();
|
|
1004
|
-
return h;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
/**
|
|
1008
|
-
* The SHA-1 logical functions f(0), f(1), ..., f(79).
|
|
1009
|
-
* @private
|
|
1010
|
-
*/
|
|
1011
|
-
_f(t, b, c, d) {
|
|
1012
|
-
if (t <= 19) {
|
|
1013
|
-
return (b & c) | (~b & d);
|
|
1014
|
-
} else if (t <= 39) {
|
|
1015
|
-
return b ^ c ^ d;
|
|
1016
|
-
} else if (t <= 59) {
|
|
1017
|
-
return (b & c) | (b & d) | (c & d);
|
|
1018
|
-
} else if (t <= 79) {
|
|
1019
|
-
return b ^ c ^ d;
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
/**
|
|
1024
|
-
* Circular left-shift operator.
|
|
1025
|
-
* @private
|
|
1026
|
-
*/
|
|
1027
|
-
_S(n, x) {
|
|
1028
|
-
return (x << n) | (x >>> 32 - n);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
/**
|
|
1032
|
-
* Perform one cycle of SHA-1.
|
|
1033
|
-
* @param {Uint32Array|bitArray} words one block of words.
|
|
1034
|
-
* @private
|
|
1035
|
-
*/
|
|
1036
|
-
_block(words) {
|
|
1037
|
-
const sha1 = this;
|
|
1038
|
-
const h = sha1._h;
|
|
1039
|
-
// When words is passed to _block, it has 16 elements. SHA1 _block
|
|
1040
|
-
// function extends words with new elements (at the end there are 80 elements).
|
|
1041
|
-
// The problem is that if we use Uint32Array instead of Array,
|
|
1042
|
-
// the length of Uint32Array cannot be changed. Thus, we replace words with a
|
|
1043
|
-
// normal Array here.
|
|
1044
|
-
const w = Array(80); // do not use Uint32Array here as the instantiation is slower
|
|
1045
|
-
for (let j = 0; j < 16; j++) {
|
|
1046
|
-
w[j] = words[j];
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
let a = h[0];
|
|
1050
|
-
let b = h[1];
|
|
1051
|
-
let c = h[2];
|
|
1052
|
-
let d = h[3];
|
|
1053
|
-
let e = h[4];
|
|
1054
|
-
|
|
1055
|
-
for (let t = 0; t <= 79; t++) {
|
|
1056
|
-
if (t >= 16) {
|
|
1057
|
-
w[t] = sha1._S(1, w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
|
|
1058
|
-
}
|
|
1059
|
-
const tmp = (sha1._S(5, a) + sha1._f(t, b, c, d) + e + w[t] +
|
|
1060
|
-
sha1._key[Math.floor(t / 20)]) | 0;
|
|
1061
|
-
e = d;
|
|
1062
|
-
d = c;
|
|
1063
|
-
c = sha1._S(30, b);
|
|
1064
|
-
b = a;
|
|
1065
|
-
a = tmp;
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
h[0] = (h[0] + a) | 0;
|
|
1069
|
-
h[1] = (h[1] + b) | 0;
|
|
1070
|
-
h[2] = (h[2] + c) | 0;
|
|
1071
|
-
h[3] = (h[3] + d) | 0;
|
|
1072
|
-
h[4] = (h[4] + e) | 0;
|
|
1073
|
-
}
|
|
1074
|
-
};
|
|
1075
|
-
|
|
1076
|
-
/** @fileOverview Low-level AES implementation.
|
|
1077
|
-
*
|
|
1078
|
-
* This file contains a low-level implementation of AES, optimized for
|
|
1079
|
-
* size and for efficiency on several browsers. It is based on
|
|
1080
|
-
* OpenSSL's aes_core.c, a public-domain implementation by Vincent
|
|
1081
|
-
* Rijmen, Antoon Bosselaers and Paulo Barreto.
|
|
1082
|
-
*
|
|
1083
|
-
* An older version of this implementation is available in the public
|
|
1084
|
-
* domain, but this one is (c) Emily Stark, Mike Hamburg, Dan Boneh,
|
|
1085
|
-
* Stanford University 2008-2010 and BSD-licensed for liability
|
|
1086
|
-
* reasons.
|
|
1087
|
-
*
|
|
1088
|
-
* @author Emily Stark
|
|
1089
|
-
* @author Mike Hamburg
|
|
1090
|
-
* @author Dan Boneh
|
|
1091
|
-
*/
|
|
1092
|
-
|
|
1093
|
-
const cipher = {};
|
|
1094
|
-
|
|
1095
|
-
/**
|
|
1096
|
-
* Schedule out an AES key for both encryption and decryption. This
|
|
1097
|
-
* is a low-level class. Use a cipher mode to do bulk encryption.
|
|
1098
|
-
*
|
|
1099
|
-
* @constructor
|
|
1100
|
-
* @param {Array} key The key as an array of 4, 6 or 8 words.
|
|
1101
|
-
*/
|
|
1102
|
-
cipher.aes = class {
|
|
1103
|
-
constructor(key) {
|
|
1104
|
-
/**
|
|
1105
|
-
* The expanded S-box and inverse S-box tables. These will be computed
|
|
1106
|
-
* on the client so that we don't have to send them down the wire.
|
|
1107
|
-
*
|
|
1108
|
-
* There are two tables, _tables[0] is for encryption and
|
|
1109
|
-
* _tables[1] is for decryption.
|
|
1110
|
-
*
|
|
1111
|
-
* The first 4 sub-tables are the expanded S-box with MixColumns. The
|
|
1112
|
-
* last (_tables[01][4]) is the S-box itself.
|
|
1113
|
-
*
|
|
1114
|
-
* @private
|
|
1115
|
-
*/
|
|
1116
|
-
const aes = this;
|
|
1117
|
-
aes._tables = [[[], [], [], [], []], [[], [], [], [], []]];
|
|
1118
|
-
|
|
1119
|
-
if (!aes._tables[0][0][0]) {
|
|
1120
|
-
aes._precompute();
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
const sbox = aes._tables[0][4];
|
|
1124
|
-
const decTable = aes._tables[1];
|
|
1125
|
-
const keyLen = key.length;
|
|
1126
|
-
|
|
1127
|
-
let i, encKey, decKey, rcon = 1;
|
|
1128
|
-
|
|
1129
|
-
if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
|
|
1130
|
-
throw new Error("invalid aes key size");
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
aes._key = [encKey = key.slice(0), decKey = []];
|
|
1134
|
-
|
|
1135
|
-
// schedule encryption keys
|
|
1136
|
-
for (i = keyLen; i < 4 * keyLen + 28; i++) {
|
|
1137
|
-
let tmp = encKey[i - 1];
|
|
1138
|
-
|
|
1139
|
-
// apply sbox
|
|
1140
|
-
if (i % keyLen === 0 || (keyLen === 8 && i % keyLen === 4)) {
|
|
1141
|
-
tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
|
|
1142
|
-
|
|
1143
|
-
// shift rows and add rcon
|
|
1144
|
-
if (i % keyLen === 0) {
|
|
1145
|
-
tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
|
|
1146
|
-
rcon = rcon << 1 ^ (rcon >> 7) * 283;
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
770
|
+
};
|
|
1149
771
|
|
|
1150
|
-
|
|
772
|
+
function encrypt(data) {
|
|
773
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
774
|
+
const length = data.length;
|
|
775
|
+
let offset = 0;
|
|
776
|
+
for (; offset + BLOCK_LENGTH$1 <= length; offset += BLOCK_LENGTH$1) {
|
|
777
|
+
nextKeystream();
|
|
778
|
+
view.setInt32(offset, view.getInt32(offset) ^ keystream[0]);
|
|
779
|
+
view.setInt32(offset + 4, view.getInt32(offset + 4) ^ keystream[1]);
|
|
780
|
+
view.setInt32(offset + 8, view.getInt32(offset + 8) ^ keystream[2]);
|
|
781
|
+
view.setInt32(offset + 12, view.getInt32(offset + 12) ^ keystream[3]);
|
|
1151
782
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
if (i <= 4 || j < 4) {
|
|
1157
|
-
decKey[j] = tmp;
|
|
1158
|
-
} else {
|
|
1159
|
-
decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
|
|
1160
|
-
decTable[1][sbox[tmp >> 16 & 255]] ^
|
|
1161
|
-
decTable[2][sbox[tmp >> 8 & 255]] ^
|
|
1162
|
-
decTable[3][sbox[tmp & 255]];
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
// public
|
|
1167
|
-
/* Something like this might appear here eventually
|
|
1168
|
-
name: "AES",
|
|
1169
|
-
blockSize: 4,
|
|
1170
|
-
keySizes: [4,6,8],
|
|
1171
|
-
*/
|
|
1172
|
-
|
|
1173
|
-
/**
|
|
1174
|
-
* Encrypt an array of 4 big-endian words.
|
|
1175
|
-
* @param {Array} data The plaintext.
|
|
1176
|
-
* @return {Array} The ciphertext.
|
|
1177
|
-
*/
|
|
1178
|
-
encrypt(data) {
|
|
1179
|
-
return this._crypt(data, 0);
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
/**
|
|
1183
|
-
* Decrypt an array of 4 big-endian words.
|
|
1184
|
-
* @param {Array} data The ciphertext.
|
|
1185
|
-
* @return {Array} The plaintext.
|
|
1186
|
-
*/
|
|
1187
|
-
decrypt(data) {
|
|
1188
|
-
return this._crypt(data, 1);
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
/**
|
|
1192
|
-
* Expand the S-box tables.
|
|
1193
|
-
*
|
|
1194
|
-
* @private
|
|
1195
|
-
*/
|
|
1196
|
-
_precompute() {
|
|
1197
|
-
const encTable = this._tables[0];
|
|
1198
|
-
const decTable = this._tables[1];
|
|
1199
|
-
const sbox = encTable[4];
|
|
1200
|
-
const sboxInv = decTable[4];
|
|
1201
|
-
const d = [];
|
|
1202
|
-
const th = [];
|
|
1203
|
-
let xInv, x2, x4, x8;
|
|
1204
|
-
|
|
1205
|
-
// Compute double and third tables
|
|
1206
|
-
for (let i = 0; i < 256; i++) {
|
|
1207
|
-
th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
for (let x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
|
|
1211
|
-
// Compute sbox
|
|
1212
|
-
let s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
|
|
1213
|
-
s = s >> 8 ^ s & 255 ^ 99;
|
|
1214
|
-
sbox[x] = s;
|
|
1215
|
-
sboxInv[s] = x;
|
|
1216
|
-
|
|
1217
|
-
// Compute MixColumns
|
|
1218
|
-
x8 = d[x4 = d[x2 = d[x]]];
|
|
1219
|
-
let tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
|
|
1220
|
-
let tEnc = d[s] * 0x101 ^ s * 0x1010100;
|
|
1221
|
-
|
|
1222
|
-
for (let i = 0; i < 4; i++) {
|
|
1223
|
-
encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
|
|
1224
|
-
decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
// Compactify. Considerable speedup on Firefox.
|
|
1229
|
-
for (let i = 0; i < 5; i++) {
|
|
1230
|
-
encTable[i] = encTable[i].slice(0);
|
|
1231
|
-
decTable[i] = decTable[i].slice(0);
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
/**
|
|
1236
|
-
* Encryption and decryption core.
|
|
1237
|
-
* @param {Array} input Four words to be encrypted or decrypted.
|
|
1238
|
-
* @param dir The direction, 0 for encrypt and 1 for decrypt.
|
|
1239
|
-
* @return {Array} The four encrypted or decrypted words.
|
|
1240
|
-
* @private
|
|
1241
|
-
*/
|
|
1242
|
-
_crypt(input, dir) {
|
|
1243
|
-
if (input.length !== 4) {
|
|
1244
|
-
throw new Error("invalid aes block size");
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
const key = this._key[dir];
|
|
1248
|
-
|
|
1249
|
-
const nInnerRounds = key.length / 4 - 2;
|
|
1250
|
-
const out = [0, 0, 0, 0];
|
|
1251
|
-
const table = this._tables[dir];
|
|
1252
|
-
|
|
1253
|
-
// load up the tables
|
|
1254
|
-
const t0 = table[0];
|
|
1255
|
-
const t1 = table[1];
|
|
1256
|
-
const t2 = table[2];
|
|
1257
|
-
const t3 = table[3];
|
|
1258
|
-
const sbox = table[4];
|
|
1259
|
-
|
|
1260
|
-
// state variables a,b,c,d are loaded with pre-whitened data
|
|
1261
|
-
let a = input[0] ^ key[0];
|
|
1262
|
-
let b = input[dir ? 3 : 1] ^ key[1];
|
|
1263
|
-
let c = input[2] ^ key[2];
|
|
1264
|
-
let d = input[dir ? 1 : 3] ^ key[3];
|
|
1265
|
-
let kIndex = 4;
|
|
1266
|
-
let a2, b2, c2;
|
|
1267
|
-
|
|
1268
|
-
// Inner rounds. Cribbed from OpenSSL.
|
|
1269
|
-
for (let i = 0; i < nInnerRounds; i++) {
|
|
1270
|
-
a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
|
|
1271
|
-
b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
|
|
1272
|
-
c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
|
|
1273
|
-
d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
|
|
1274
|
-
kIndex += 4;
|
|
1275
|
-
a = a2; b = b2; c = c2;
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
// Last round.
|
|
1279
|
-
for (let i = 0; i < 4; i++) {
|
|
1280
|
-
out[dir ? 3 & -i : i] =
|
|
1281
|
-
sbox[a >>> 24] << 24 ^
|
|
1282
|
-
sbox[b >> 16 & 255] << 16 ^
|
|
1283
|
-
sbox[c >> 8 & 255] << 8 ^
|
|
1284
|
-
sbox[d & 255] ^
|
|
1285
|
-
key[kIndex++];
|
|
1286
|
-
a2 = a; a = b; b = c; c = d; d = a2;
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
return out;
|
|
1290
|
-
}
|
|
1291
|
-
};
|
|
1292
|
-
|
|
1293
|
-
/** @fileOverview CTR mode implementation.
|
|
1294
|
-
*
|
|
1295
|
-
* Special thanks to Roy Nicholson for pointing out a bug in our
|
|
1296
|
-
* implementation.
|
|
1297
|
-
*
|
|
1298
|
-
* @author Emily Stark
|
|
1299
|
-
* @author Mike Hamburg
|
|
1300
|
-
* @author Dan Boneh
|
|
1301
|
-
*/
|
|
1302
|
-
|
|
1303
|
-
/** Brian Gladman's CTR Mode.
|
|
1304
|
-
* @constructor
|
|
1305
|
-
* @param {Object} _prf The aes instance to generate key.
|
|
1306
|
-
* @param {bitArray} _iv The iv for ctr mode, it must be 128 bits.
|
|
1307
|
-
*/
|
|
1308
|
-
|
|
1309
|
-
const mode = {};
|
|
1310
|
-
|
|
1311
|
-
/**
|
|
1312
|
-
* Brian Gladman's CTR Mode.
|
|
1313
|
-
* @namespace
|
|
1314
|
-
*/
|
|
1315
|
-
mode.ctrGladman = class {
|
|
1316
|
-
constructor(prf, iv) {
|
|
1317
|
-
this._prf = prf;
|
|
1318
|
-
this._initIv = iv;
|
|
1319
|
-
this._iv = iv;
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
reset() {
|
|
1323
|
-
this._iv = this._initIv;
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
/** Input some data to calculate.
|
|
1327
|
-
* @param {bitArray} data the data to process, it must be intergral multiple of 128 bits unless it's the last.
|
|
1328
|
-
*/
|
|
1329
|
-
update(data) {
|
|
1330
|
-
return this.calculate(this._prf, data, this._iv);
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
incWord(word) {
|
|
1334
|
-
if (((word >> 24) & 0xff) === 0xff) { //overflow
|
|
1335
|
-
let b1 = (word >> 16) & 0xff;
|
|
1336
|
-
let b2 = (word >> 8) & 0xff;
|
|
1337
|
-
let b3 = word & 0xff;
|
|
1338
|
-
|
|
1339
|
-
if (b1 === 0xff) { // overflow b1
|
|
1340
|
-
b1 = 0;
|
|
1341
|
-
if (b2 === 0xff) {
|
|
1342
|
-
b2 = 0;
|
|
1343
|
-
if (b3 === 0xff) {
|
|
1344
|
-
b3 = 0;
|
|
1345
|
-
} else {
|
|
1346
|
-
++b3;
|
|
1347
|
-
}
|
|
1348
|
-
} else {
|
|
1349
|
-
++b2;
|
|
1350
|
-
}
|
|
1351
|
-
} else {
|
|
1352
|
-
++b1;
|
|
783
|
+
if (offset < length) {
|
|
784
|
+
nextKeystream();
|
|
785
|
+
for (let indexByte = 0; offset < length; offset++, indexByte++) {
|
|
786
|
+
data[offset] ^= keystream[indexByte >> 2] >>> (24 - 8 * (indexByte & 3));
|
|
1353
787
|
}
|
|
1354
|
-
|
|
1355
|
-
word = 0;
|
|
1356
|
-
word += (b1 << 16);
|
|
1357
|
-
word += (b2 << 8);
|
|
1358
|
-
word += b3;
|
|
1359
|
-
} else {
|
|
1360
|
-
word += (0x01 << 24);
|
|
1361
|
-
}
|
|
1362
|
-
return word;
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
incCounter(counter) {
|
|
1366
|
-
if ((counter[0] = this.incWord(counter[0])) === 0) {
|
|
1367
|
-
// encr_data in fileenc.c from Dr Brian Gladman's counts only with DWORD j < 8
|
|
1368
|
-
counter[1] = this.incWord(counter[1]);
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
calculate(prf, data, iv) {
|
|
1373
|
-
let l;
|
|
1374
|
-
if (!(l = data.length)) {
|
|
1375
|
-
return [];
|
|
1376
|
-
}
|
|
1377
|
-
const bl = bitArray.bitLength(data);
|
|
1378
|
-
for (let i = 0; i < l; i += 4) {
|
|
1379
|
-
this.incCounter(iv);
|
|
1380
|
-
const e = prf.encrypt(iv);
|
|
1381
|
-
data[i] ^= e[0];
|
|
1382
|
-
data[i + 1] ^= e[1];
|
|
1383
|
-
data[i + 2] ^= e[2];
|
|
1384
|
-
data[i + 3] ^= e[3];
|
|
1385
788
|
}
|
|
1386
|
-
return bitArray.clamp(data, bl);
|
|
1387
789
|
}
|
|
1388
|
-
};
|
|
1389
790
|
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
}
|
|
1399
|
-
const byteLength = ((length >> 5) + 1) << 2;
|
|
1400
|
-
let u, ui, i, j, k;
|
|
1401
|
-
const arrayBuffer = new ArrayBuffer(byteLength);
|
|
1402
|
-
const out = new DataView(arrayBuffer);
|
|
1403
|
-
let outLength = 0;
|
|
1404
|
-
const b = bitArray;
|
|
1405
|
-
salt = codec.bytes.toBits(salt);
|
|
1406
|
-
for (k = 1; outLength < (byteLength || 1); k++) {
|
|
1407
|
-
u = ui = prf.encrypt(b.concat(salt, [k]));
|
|
1408
|
-
for (i = 1; i < count; i++) {
|
|
1409
|
-
ui = prf.encrypt(ui);
|
|
1410
|
-
for (j = 0; j < ui.length; j++) {
|
|
1411
|
-
u[j] ^= ui[j];
|
|
791
|
+
function nextKeystream() {
|
|
792
|
+
counter0 = (counter0 + 1) | 0;
|
|
793
|
+
if (!counter0) {
|
|
794
|
+
counter1 = (counter1 + 1) | 0;
|
|
795
|
+
if (!counter1) {
|
|
796
|
+
counter2 = (counter2 + 1) | 0;
|
|
797
|
+
if (!counter2) {
|
|
798
|
+
counter3 = (counter3 + 1) | 0;
|
|
1412
799
|
}
|
|
1413
800
|
}
|
|
1414
|
-
for (i = 0; outLength < (byteLength || 1) && i < u.length; i++) {
|
|
1415
|
-
out.setInt32(outLength, u[i]);
|
|
1416
|
-
outLength += 4;
|
|
1417
|
-
}
|
|
1418
801
|
}
|
|
1419
|
-
|
|
802
|
+
let s0 = swapBytes(counter0) ^ roundKeys[0];
|
|
803
|
+
let s1 = swapBytes(counter1) ^ roundKeys[1];
|
|
804
|
+
let s2 = swapBytes(counter2) ^ roundKeys[2];
|
|
805
|
+
let s3 = swapBytes(counter3) ^ roundKeys[3];
|
|
806
|
+
let t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[4];
|
|
807
|
+
let t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[5];
|
|
808
|
+
let t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[6];
|
|
809
|
+
let t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[7];
|
|
810
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[8];
|
|
811
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[9];
|
|
812
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[10];
|
|
813
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[11];
|
|
814
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[12];
|
|
815
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[13];
|
|
816
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[14];
|
|
817
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[15];
|
|
818
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[16];
|
|
819
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[17];
|
|
820
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[18];
|
|
821
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[19];
|
|
822
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[20];
|
|
823
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[21];
|
|
824
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[22];
|
|
825
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[23];
|
|
826
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[24];
|
|
827
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[25];
|
|
828
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[26];
|
|
829
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[27];
|
|
830
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[28];
|
|
831
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[29];
|
|
832
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[30];
|
|
833
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[31];
|
|
834
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[32];
|
|
835
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[33];
|
|
836
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[34];
|
|
837
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[35];
|
|
838
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[36];
|
|
839
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[37];
|
|
840
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[38];
|
|
841
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[39];
|
|
842
|
+
let indexKey = 40;
|
|
843
|
+
if (rounds > 10) {
|
|
844
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[40];
|
|
845
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[41];
|
|
846
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[42];
|
|
847
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[43];
|
|
848
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[44];
|
|
849
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[45];
|
|
850
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[46];
|
|
851
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[47];
|
|
852
|
+
indexKey = 48;
|
|
853
|
+
}
|
|
854
|
+
if (rounds > 12) {
|
|
855
|
+
s0 = T0[t0 >>> 24] ^ T1[(t1 >>> 16) & 255] ^ T2[(t2 >>> 8) & 255] ^ T3[t3 & 255] ^ roundKeys[48];
|
|
856
|
+
s1 = T0[t1 >>> 24] ^ T1[(t2 >>> 16) & 255] ^ T2[(t3 >>> 8) & 255] ^ T3[t0 & 255] ^ roundKeys[49];
|
|
857
|
+
s2 = T0[t2 >>> 24] ^ T1[(t3 >>> 16) & 255] ^ T2[(t0 >>> 8) & 255] ^ T3[t1 & 255] ^ roundKeys[50];
|
|
858
|
+
s3 = T0[t3 >>> 24] ^ T1[(t0 >>> 16) & 255] ^ T2[(t1 >>> 8) & 255] ^ T3[t2 & 255] ^ roundKeys[51];
|
|
859
|
+
t0 = T0[s0 >>> 24] ^ T1[(s1 >>> 16) & 255] ^ T2[(s2 >>> 8) & 255] ^ T3[s3 & 255] ^ roundKeys[52];
|
|
860
|
+
t1 = T0[s1 >>> 24] ^ T1[(s2 >>> 16) & 255] ^ T2[(s3 >>> 8) & 255] ^ T3[s0 & 255] ^ roundKeys[53];
|
|
861
|
+
t2 = T0[s2 >>> 24] ^ T1[(s3 >>> 16) & 255] ^ T2[(s0 >>> 8) & 255] ^ T3[s1 & 255] ^ roundKeys[54];
|
|
862
|
+
t3 = T0[s3 >>> 24] ^ T1[(s0 >>> 16) & 255] ^ T2[(s1 >>> 8) & 255] ^ T3[s2 & 255] ^ roundKeys[55];
|
|
863
|
+
indexKey = 56;
|
|
864
|
+
}
|
|
865
|
+
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];
|
|
866
|
+
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];
|
|
867
|
+
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];
|
|
868
|
+
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];
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function pbkdf2(password, salt, iterations, length) {
|
|
873
|
+
const hmac = createHmac(password);
|
|
874
|
+
const result = new Uint8Array(length);
|
|
875
|
+
const block = new Uint8Array(salt.length + 4);
|
|
876
|
+
const blockView = new DataView(block.buffer);
|
|
877
|
+
block.set(salt);
|
|
878
|
+
for (let indexBlock = 1, offset = 0; offset < length; indexBlock++, offset += SHA1_DIGEST_LENGTH) {
|
|
879
|
+
blockView.setUint32(salt.length, indexBlock);
|
|
880
|
+
hmac.update(block, 0, block.length);
|
|
881
|
+
let previous = hmac.digest();
|
|
882
|
+
const output = previous.slice();
|
|
883
|
+
for (let iteration = 1; iteration < iterations; iteration++) {
|
|
884
|
+
hmac.update(previous, 0, SHA1_DIGEST_LENGTH);
|
|
885
|
+
previous = hmac.digest();
|
|
886
|
+
for (let indexByte = 0; indexByte < SHA1_DIGEST_LENGTH; indexByte++) {
|
|
887
|
+
output[indexByte] ^= previous[indexByte];
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
result.set(output.subarray(0, Math.min(SHA1_DIGEST_LENGTH, length - offset)), offset);
|
|
1420
891
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
/** @fileOverview HMAC implementation.
|
|
1424
|
-
*
|
|
1425
|
-
* @author Emily Stark
|
|
1426
|
-
* @author Mike Hamburg
|
|
1427
|
-
* @author Dan Boneh
|
|
1428
|
-
*/
|
|
1429
|
-
|
|
1430
|
-
/** HMAC with the specified hash function.
|
|
1431
|
-
* @constructor
|
|
1432
|
-
* @param {bitArray} key the key for HMAC.
|
|
1433
|
-
* @param {Object} [Hash=hash.sha1] The hash function to use.
|
|
1434
|
-
*/
|
|
1435
|
-
misc.hmacSha1 = class {
|
|
1436
|
-
|
|
1437
|
-
constructor(key) {
|
|
1438
|
-
const hmac = this;
|
|
1439
|
-
const Hash = hmac._hash = hash.sha1;
|
|
1440
|
-
const exKey = [[], []];
|
|
1441
|
-
hmac._baseHash = [new Hash(), new Hash()];
|
|
1442
|
-
const bs = hmac._baseHash[0].blockSize / 32;
|
|
1443
|
-
|
|
1444
|
-
if (key.length > bs) {
|
|
1445
|
-
key = new Hash().update(key).finalize();
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
for (let i = 0; i < bs; i++) {
|
|
1449
|
-
exKey[0][i] = key[i] ^ 0x36363636;
|
|
1450
|
-
exKey[1][i] = key[i] ^ 0x5C5C5C5C;
|
|
1451
|
-
}
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
1452
894
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
hmac._updated = false;
|
|
895
|
+
function createHmac(key) {
|
|
896
|
+
const sha1 = createSha1();
|
|
897
|
+
const innerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
898
|
+
const outerKey = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
899
|
+
if (key.length > SHA1_BLOCK_LENGTH) {
|
|
900
|
+
sha1.update(key, 0, key.length);
|
|
901
|
+
key = sha1.digest();
|
|
1461
902
|
}
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
hmac._resultHash.update(data);
|
|
903
|
+
for (let indexByte = 0; indexByte < SHA1_BLOCK_LENGTH; indexByte++) {
|
|
904
|
+
const keyByte = indexByte < key.length ? key[indexByte] : 0;
|
|
905
|
+
innerKey[indexByte] = keyByte ^ HMAC_INNER_PADDING;
|
|
906
|
+
outerKey[indexByte] = keyByte ^ HMAC_OUTER_PADDING;
|
|
1467
907
|
}
|
|
908
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
909
|
+
return {
|
|
910
|
+
update(data, offset, length) {
|
|
911
|
+
sha1.update(data, offset, length);
|
|
912
|
+
},
|
|
913
|
+
digest() {
|
|
914
|
+
const innerDigest = sha1.digest();
|
|
915
|
+
sha1.update(outerKey, 0, SHA1_BLOCK_LENGTH);
|
|
916
|
+
sha1.update(innerDigest, 0, SHA1_DIGEST_LENGTH);
|
|
917
|
+
const result = sha1.digest();
|
|
918
|
+
sha1.update(innerKey, 0, SHA1_BLOCK_LENGTH);
|
|
919
|
+
return result;
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
}
|
|
1468
923
|
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
924
|
+
function createSha1() {
|
|
925
|
+
const state = new Int32Array(SHA1_INITIAL_STATE);
|
|
926
|
+
const schedule = new Int32Array(SHA1_SCHEDULE_LENGTH);
|
|
927
|
+
const block = new Uint8Array(SHA1_BLOCK_LENGTH);
|
|
928
|
+
const blockView = new DataView(block.buffer);
|
|
929
|
+
const lengthBytes = new Uint8Array(8);
|
|
930
|
+
let blockLength = 0;
|
|
931
|
+
let totalLength = 0;
|
|
932
|
+
return {
|
|
933
|
+
update,
|
|
934
|
+
digest
|
|
935
|
+
};
|
|
1475
936
|
|
|
937
|
+
function update(data, offset, length) {
|
|
938
|
+
const end = offset + length;
|
|
939
|
+
totalLength += length;
|
|
940
|
+
if (blockLength) {
|
|
941
|
+
while (offset < end && blockLength < SHA1_BLOCK_LENGTH) {
|
|
942
|
+
block[blockLength++] = data[offset++];
|
|
943
|
+
}
|
|
944
|
+
if (blockLength == SHA1_BLOCK_LENGTH) {
|
|
945
|
+
compress(blockView, 0);
|
|
946
|
+
blockLength = 0;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
if (offset + SHA1_BLOCK_LENGTH <= end) {
|
|
950
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
951
|
+
for (; offset + SHA1_BLOCK_LENGTH <= end; offset += SHA1_BLOCK_LENGTH) {
|
|
952
|
+
compress(view, offset);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
while (offset < end) {
|
|
956
|
+
block[blockLength++] = data[offset++];
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
function digest() {
|
|
961
|
+
const bits = totalLength * 8;
|
|
962
|
+
const high = Math.floor(bits / 0x100000000);
|
|
963
|
+
const low = bits >>> 0;
|
|
964
|
+
update(SHA1_PADDING, 0, 1);
|
|
965
|
+
while (blockLength != SHA1_LENGTH_OFFSET) {
|
|
966
|
+
update(SHA1_ZERO, 0, 1);
|
|
967
|
+
}
|
|
968
|
+
lengthBytes[0] = high >>> 24;
|
|
969
|
+
lengthBytes[1] = high >>> 16;
|
|
970
|
+
lengthBytes[2] = high >>> 8;
|
|
971
|
+
lengthBytes[3] = high;
|
|
972
|
+
lengthBytes[4] = low >>> 24;
|
|
973
|
+
lengthBytes[5] = low >>> 16;
|
|
974
|
+
lengthBytes[6] = low >>> 8;
|
|
975
|
+
lengthBytes[7] = low;
|
|
976
|
+
update(lengthBytes, 0, 8);
|
|
977
|
+
const result = new Uint8Array(SHA1_DIGEST_LENGTH);
|
|
978
|
+
const resultView = new DataView(result.buffer);
|
|
979
|
+
for (let indexWord = 0; indexWord < state.length; indexWord++) {
|
|
980
|
+
resultView.setInt32(4 * indexWord, state[indexWord]);
|
|
981
|
+
}
|
|
982
|
+
state.set(SHA1_INITIAL_STATE);
|
|
983
|
+
blockLength = 0;
|
|
984
|
+
totalLength = 0;
|
|
1476
985
|
return result;
|
|
1477
986
|
}
|
|
1478
987
|
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
988
|
+
function compress(view, offset) {
|
|
989
|
+
for (let index = 0; index < 16; index++) {
|
|
990
|
+
schedule[index] = view.getInt32(offset + 4 * index);
|
|
991
|
+
}
|
|
992
|
+
let a = state[0];
|
|
993
|
+
let b = state[1];
|
|
994
|
+
let c = state[2];
|
|
995
|
+
let d = state[3];
|
|
996
|
+
let e = state[4];
|
|
997
|
+
let t;
|
|
998
|
+
for (let index = 0; index < 15; index += 5) {
|
|
999
|
+
e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[index]) | 0;
|
|
1000
|
+
b = (b << 30) | (b >>> 2);
|
|
1001
|
+
d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + schedule[index + 1]) | 0;
|
|
1002
|
+
a = (a << 30) | (a >>> 2);
|
|
1003
|
+
c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + schedule[index + 2]) | 0;
|
|
1004
|
+
e = (e << 30) | (e >>> 2);
|
|
1005
|
+
b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + schedule[index + 3]) | 0;
|
|
1006
|
+
d = (d << 30) | (d >>> 2);
|
|
1007
|
+
a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + schedule[index + 4]) | 0;
|
|
1008
|
+
c = (c << 30) | (c >>> 2);
|
|
1009
|
+
}
|
|
1010
|
+
e = (((a << 5) | (a >>> 27)) + (((c ^ d) & b) ^ d) + e + 0x5A827999 + schedule[15]) | 0;
|
|
1011
|
+
b = (b << 30) | (b >>> 2);
|
|
1012
|
+
t = schedule[13] ^ schedule[8] ^ schedule[2] ^ schedule[0];
|
|
1013
|
+
t = (t << 1) | (t >>> 31);
|
|
1014
|
+
schedule[0] = t;
|
|
1015
|
+
d = (((e << 5) | (e >>> 27)) + (((b ^ c) & a) ^ c) + d + 0x5A827999 + t) | 0;
|
|
1016
|
+
a = (a << 30) | (a >>> 2);
|
|
1017
|
+
t = schedule[14] ^ schedule[9] ^ schedule[3] ^ schedule[1];
|
|
1018
|
+
t = (t << 1) | (t >>> 31);
|
|
1019
|
+
schedule[1] = t;
|
|
1020
|
+
c = (((d << 5) | (d >>> 27)) + (((a ^ b) & e) ^ b) + c + 0x5A827999 + t) | 0;
|
|
1021
|
+
e = (e << 30) | (e >>> 2);
|
|
1022
|
+
t = schedule[15] ^ schedule[10] ^ schedule[4] ^ schedule[2];
|
|
1023
|
+
t = (t << 1) | (t >>> 31);
|
|
1024
|
+
schedule[2] = t;
|
|
1025
|
+
b = (((c << 5) | (c >>> 27)) + (((e ^ a) & d) ^ a) + b + 0x5A827999 + t) | 0;
|
|
1026
|
+
d = (d << 30) | (d >>> 2);
|
|
1027
|
+
t = schedule[0] ^ schedule[11] ^ schedule[5] ^ schedule[3];
|
|
1028
|
+
t = (t << 1) | (t >>> 31);
|
|
1029
|
+
schedule[3] = t;
|
|
1030
|
+
a = (((b << 5) | (b >>> 27)) + (((d ^ e) & c) ^ e) + a + 0x5A827999 + t) | 0;
|
|
1031
|
+
c = (c << 30) | (c >>> 2);
|
|
1032
|
+
for (let index = 20; index < 40; index += 5) {
|
|
1033
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1034
|
+
t = (t << 1) | (t >>> 31);
|
|
1035
|
+
schedule[(index) & 15] = t;
|
|
1036
|
+
e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0x6ED9EBA1 + t) | 0;
|
|
1037
|
+
b = (b << 30) | (b >>> 2);
|
|
1038
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1039
|
+
t = (t << 1) | (t >>> 31);
|
|
1040
|
+
schedule[(index + 1) & 15] = t;
|
|
1041
|
+
d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0x6ED9EBA1 + t) | 0;
|
|
1042
|
+
a = (a << 30) | (a >>> 2);
|
|
1043
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1044
|
+
t = (t << 1) | (t >>> 31);
|
|
1045
|
+
schedule[(index + 2) & 15] = t;
|
|
1046
|
+
c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0x6ED9EBA1 + t) | 0;
|
|
1047
|
+
e = (e << 30) | (e >>> 2);
|
|
1048
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1049
|
+
t = (t << 1) | (t >>> 31);
|
|
1050
|
+
schedule[(index + 3) & 15] = t;
|
|
1051
|
+
b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0x6ED9EBA1 + t) | 0;
|
|
1052
|
+
d = (d << 30) | (d >>> 2);
|
|
1053
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1054
|
+
t = (t << 1) | (t >>> 31);
|
|
1055
|
+
schedule[(index + 4) & 15] = t;
|
|
1056
|
+
a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0x6ED9EBA1 + t) | 0;
|
|
1057
|
+
c = (c << 30) | (c >>> 2);
|
|
1058
|
+
}
|
|
1059
|
+
for (let index = 40; index < 60; index += 5) {
|
|
1060
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1061
|
+
t = (t << 1) | (t >>> 31);
|
|
1062
|
+
schedule[(index) & 15] = t;
|
|
1063
|
+
e = (((a << 5) | (a >>> 27)) + ((b & c) | ((b | c) & d)) + e + 0x8F1BBCDC + t) | 0;
|
|
1064
|
+
b = (b << 30) | (b >>> 2);
|
|
1065
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1066
|
+
t = (t << 1) | (t >>> 31);
|
|
1067
|
+
schedule[(index + 1) & 15] = t;
|
|
1068
|
+
d = (((e << 5) | (e >>> 27)) + ((a & b) | ((a | b) & c)) + d + 0x8F1BBCDC + t) | 0;
|
|
1069
|
+
a = (a << 30) | (a >>> 2);
|
|
1070
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1071
|
+
t = (t << 1) | (t >>> 31);
|
|
1072
|
+
schedule[(index + 2) & 15] = t;
|
|
1073
|
+
c = (((d << 5) | (d >>> 27)) + ((e & a) | ((e | a) & b)) + c + 0x8F1BBCDC + t) | 0;
|
|
1074
|
+
e = (e << 30) | (e >>> 2);
|
|
1075
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1076
|
+
t = (t << 1) | (t >>> 31);
|
|
1077
|
+
schedule[(index + 3) & 15] = t;
|
|
1078
|
+
b = (((c << 5) | (c >>> 27)) + ((d & e) | ((d | e) & a)) + b + 0x8F1BBCDC + t) | 0;
|
|
1079
|
+
d = (d << 30) | (d >>> 2);
|
|
1080
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1081
|
+
t = (t << 1) | (t >>> 31);
|
|
1082
|
+
schedule[(index + 4) & 15] = t;
|
|
1083
|
+
a = (((b << 5) | (b >>> 27)) + ((c & d) | ((c | d) & e)) + a + 0x8F1BBCDC + t) | 0;
|
|
1084
|
+
c = (c << 30) | (c >>> 2);
|
|
1085
|
+
}
|
|
1086
|
+
for (let index = 60; index < 80; index += 5) {
|
|
1087
|
+
t = schedule[(index - 3) & 15] ^ schedule[(index - 8) & 15] ^ schedule[(index - 14) & 15] ^ schedule[(index) & 15];
|
|
1088
|
+
t = (t << 1) | (t >>> 31);
|
|
1089
|
+
schedule[(index) & 15] = t;
|
|
1090
|
+
e = (((a << 5) | (a >>> 27)) + (b ^ c ^ d) + e + 0xCA62C1D6 + t) | 0;
|
|
1091
|
+
b = (b << 30) | (b >>> 2);
|
|
1092
|
+
t = schedule[(index - 2) & 15] ^ schedule[(index - 7) & 15] ^ schedule[(index - 13) & 15] ^ schedule[(index + 1) & 15];
|
|
1093
|
+
t = (t << 1) | (t >>> 31);
|
|
1094
|
+
schedule[(index + 1) & 15] = t;
|
|
1095
|
+
d = (((e << 5) | (e >>> 27)) + (a ^ b ^ c) + d + 0xCA62C1D6 + t) | 0;
|
|
1096
|
+
a = (a << 30) | (a >>> 2);
|
|
1097
|
+
t = schedule[(index - 1) & 15] ^ schedule[(index - 6) & 15] ^ schedule[(index - 12) & 15] ^ schedule[(index + 2) & 15];
|
|
1098
|
+
t = (t << 1) | (t >>> 31);
|
|
1099
|
+
schedule[(index + 2) & 15] = t;
|
|
1100
|
+
c = (((d << 5) | (d >>> 27)) + (e ^ a ^ b) + c + 0xCA62C1D6 + t) | 0;
|
|
1101
|
+
e = (e << 30) | (e >>> 2);
|
|
1102
|
+
t = schedule[(index) & 15] ^ schedule[(index - 5) & 15] ^ schedule[(index - 11) & 15] ^ schedule[(index + 3) & 15];
|
|
1103
|
+
t = (t << 1) | (t >>> 31);
|
|
1104
|
+
schedule[(index + 3) & 15] = t;
|
|
1105
|
+
b = (((c << 5) | (c >>> 27)) + (d ^ e ^ a) + b + 0xCA62C1D6 + t) | 0;
|
|
1106
|
+
d = (d << 30) | (d >>> 2);
|
|
1107
|
+
t = schedule[(index + 1) & 15] ^ schedule[(index - 4) & 15] ^ schedule[(index - 10) & 15] ^ schedule[(index + 4) & 15];
|
|
1108
|
+
t = (t << 1) | (t >>> 31);
|
|
1109
|
+
schedule[(index + 4) & 15] = t;
|
|
1110
|
+
a = (((b << 5) | (b >>> 27)) + (c ^ d ^ e) + a + 0xCA62C1D6 + t) | 0;
|
|
1111
|
+
c = (c << 30) | (c >>> 2);
|
|
1112
|
+
}
|
|
1113
|
+
state[0] = (state[0] + a) | 0;
|
|
1114
|
+
state[1] = (state[1] + b) | 0;
|
|
1115
|
+
state[2] = (state[2] + c) | 0;
|
|
1116
|
+
state[3] = (state[3] + d) | 0;
|
|
1117
|
+
state[4] = (state[4] + e) | 0;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
function initTables() {
|
|
1122
|
+
if (!tablesInitialized) {
|
|
1123
|
+
let p = 1;
|
|
1124
|
+
let q = 1;
|
|
1125
|
+
do {
|
|
1126
|
+
p = (p ^ (p << 1) ^ ((p & 0x80) ? 0x1b : 0)) & 255;
|
|
1127
|
+
q = (q ^ (q << 1)) & 255;
|
|
1128
|
+
q = (q ^ (q << 2)) & 255;
|
|
1129
|
+
q = (q ^ (q << 4)) & 255;
|
|
1130
|
+
if (q & 0x80) {
|
|
1131
|
+
q ^= 0x09;
|
|
1132
|
+
}
|
|
1133
|
+
S_BOX[p] = (q ^ ((q << 1) | (q >> 7)) ^ ((q << 2) | (q >> 6)) ^ ((q << 3) | (q >> 5)) ^ ((q << 4) | (q >> 4)) ^ 0x63) & 255;
|
|
1134
|
+
} while (p != 1);
|
|
1135
|
+
S_BOX[0] = 0x63;
|
|
1136
|
+
for (let index = 0; index < 256; index++) {
|
|
1137
|
+
const s = S_BOX[index];
|
|
1138
|
+
const s2 = multiplyByTwo(s);
|
|
1139
|
+
const t = (s2 << 24) | (s << 16) | (s << 8) | (s2 ^ s);
|
|
1140
|
+
T0[index] = t;
|
|
1141
|
+
T1[index] = (t >>> 8) | (t << 24);
|
|
1142
|
+
T2[index] = (t >>> 16) | (t << 16);
|
|
1143
|
+
T3[index] = (t >>> 24) | (t << 8);
|
|
1144
|
+
}
|
|
1145
|
+
tablesInitialized = true;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
function expandKey(key, roundKeys) {
|
|
1150
|
+
const keyWords = key.length >> 2;
|
|
1151
|
+
const rounds = keyWords + 6;
|
|
1152
|
+
const total = 4 * (rounds + 1);
|
|
1153
|
+
let roundConstant = 1;
|
|
1154
|
+
for (let index = 0; index < keyWords; index++) {
|
|
1155
|
+
roundKeys[index] = (key[4 * index] << 24) | (key[4 * index + 1] << 16) | (key[4 * index + 2] << 8) | key[4 * index + 3];
|
|
1156
|
+
}
|
|
1157
|
+
for (let index = keyWords; index < total; index++) {
|
|
1158
|
+
let word = roundKeys[index - 1];
|
|
1159
|
+
if (index % keyWords == 0) {
|
|
1160
|
+
word = substituteWord((word << 8) | (word >>> 24)) ^ (roundConstant << 24);
|
|
1161
|
+
roundConstant = multiplyByTwo(roundConstant);
|
|
1162
|
+
} else if (keyWords > 6 && index % keyWords == 4) {
|
|
1163
|
+
word = substituteWord(word);
|
|
1164
|
+
}
|
|
1165
|
+
roundKeys[index] = roundKeys[index - keyWords] ^ word;
|
|
1166
|
+
}
|
|
1167
|
+
return rounds;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
function substituteWord(word) {
|
|
1171
|
+
return (S_BOX[word >>> 24] << 24) | (S_BOX[(word >>> 16) & 255] << 16) | (S_BOX[(word >>> 8) & 255] << 8) | S_BOX[word & 255];
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
function swapBytes(value) {
|
|
1175
|
+
return (value << 24) | ((value & 0xff00) << 8) | ((value >>> 8) & 0xff00) | (value >>> 24);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
function multiplyByTwo(value) {
|
|
1179
|
+
return ((value << 1) ^ ((value >> 7) * 0x1b)) & 255;
|
|
1180
|
+
}
|
|
1488
1181
|
|
|
1489
1182
|
/*
|
|
1490
1183
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
@@ -1539,8 +1232,8 @@ function getRandomValues(array) {
|
|
|
1539
1232
|
1. Redistributions of source code must retain the above copyright notice,
|
|
1540
1233
|
this list of conditions and the following disclaimer.
|
|
1541
1234
|
|
|
1542
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
1543
|
-
notice, this list of conditions and the following disclaimer in
|
|
1235
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
1236
|
+
notice, this list of conditions and the following disclaimer in
|
|
1544
1237
|
the documentation and/or other materials provided with the distribution.
|
|
1545
1238
|
|
|
1546
1239
|
3. The names of the authors may not be used to endorse or promote products
|
|
@@ -1564,24 +1257,21 @@ const RAW_FORMAT = "raw";
|
|
|
1564
1257
|
const PBKDF2_ALGORITHM = { name: "PBKDF2" };
|
|
1565
1258
|
const HASH_ALGORITHM = { name: "HMAC" };
|
|
1566
1259
|
const HASH_FUNCTION = "SHA-1";
|
|
1260
|
+
const PBKDF2_ITERATIONS = 1000;
|
|
1567
1261
|
const BASE_KEY_ALGORITHM = Object.assign({ hash: HASH_ALGORITHM }, PBKDF2_ALGORITHM);
|
|
1568
|
-
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations:
|
|
1262
|
+
const DERIVED_BITS_ALGORITHM = Object.assign({ iterations: PBKDF2_ITERATIONS, hash: { name: HASH_FUNCTION } }, PBKDF2_ALGORITHM);
|
|
1569
1263
|
const DERIVED_BITS_USAGE = ["deriveBits"];
|
|
1570
1264
|
const SALT_LENGTH = [8, 12, 16];
|
|
1571
1265
|
const KEY_LENGTH = [16, 24, 32];
|
|
1572
1266
|
const AUTHENTICATION_CODE_LENGTH = 10;
|
|
1573
|
-
const
|
|
1267
|
+
const PASSWORD_VERIFICATION_LENGTH = 2;
|
|
1574
1268
|
// deno-lint-ignore valid-typeof
|
|
1575
1269
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
1576
1270
|
const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
|
|
1577
1271
|
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
|
|
1578
|
-
const codecBytes = codec.bytes;
|
|
1579
|
-
const Aes = cipher.aes;
|
|
1580
|
-
const CtrGladman = mode.ctrGladman;
|
|
1581
|
-
const HmacSha1 = misc.hmacSha1;
|
|
1582
1272
|
|
|
1583
|
-
let
|
|
1584
|
-
let
|
|
1273
|
+
let DERIVE_BITS_SUPPORTED = SUBTLE_API_SUPPORTED && typeof subtle.importKey == FUNCTION_TYPE && typeof subtle.deriveBits == FUNCTION_TYPE;
|
|
1274
|
+
let createEngine = createEngine$1;
|
|
1585
1275
|
|
|
1586
1276
|
class AESDecryptionStream extends TransformStream {
|
|
1587
1277
|
|
|
@@ -1599,9 +1289,10 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1599
1289
|
ready
|
|
1600
1290
|
} = aesCrypto;
|
|
1601
1291
|
if (password) {
|
|
1602
|
-
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] +
|
|
1603
|
-
chunk = subarray(chunk, SALT_LENGTH[strength] +
|
|
1292
|
+
await createDecryptionKeys(aesCrypto, strength, password, subarray(chunk, 0, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH));
|
|
1293
|
+
chunk = subarray(chunk, SALT_LENGTH[strength] + PASSWORD_VERIFICATION_LENGTH);
|
|
1604
1294
|
if (checkPasswordOnly) {
|
|
1295
|
+
disposeEngine(aesCrypto);
|
|
1605
1296
|
controller.error(new Error(ERR_ABORT_CHECK_PASSWORD));
|
|
1606
1297
|
} else {
|
|
1607
1298
|
resolveReady();
|
|
@@ -1614,23 +1305,16 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1614
1305
|
},
|
|
1615
1306
|
async flush(controller) {
|
|
1616
1307
|
const {
|
|
1617
|
-
|
|
1618
|
-
hmac,
|
|
1308
|
+
engine,
|
|
1619
1309
|
pendingInput,
|
|
1620
1310
|
ready
|
|
1621
1311
|
} = this;
|
|
1622
|
-
if (
|
|
1312
|
+
if (engine) {
|
|
1623
1313
|
await ready;
|
|
1624
|
-
const chunkToDecrypt = subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1625
1314
|
const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
hmac.update(encryptedChunk);
|
|
1630
|
-
const decryptedChunk = ctr.update(encryptedChunk);
|
|
1631
|
-
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
1632
|
-
}
|
|
1633
|
-
const authenticationCode = subarray(fromBits(codecBytes, hmac.digest()), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1315
|
+
const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
|
|
1316
|
+
engine.process(decryptedChunkArray, true);
|
|
1317
|
+
const authenticationCode = engine.digest();
|
|
1634
1318
|
let invalidAuthenticationCode = pendingInput.length < AUTHENTICATION_CODE_LENGTH ? 1 : 0;
|
|
1635
1319
|
for (let indexByte = 0; indexByte < AUTHENTICATION_CODE_LENGTH; indexByte++) {
|
|
1636
1320
|
invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
|
|
@@ -1640,6 +1324,9 @@ class AESDecryptionStream extends TransformStream {
|
|
|
1640
1324
|
}
|
|
1641
1325
|
controller.enqueue(decryptedChunkArray);
|
|
1642
1326
|
}
|
|
1327
|
+
},
|
|
1328
|
+
cancel() {
|
|
1329
|
+
disposeEngine(this);
|
|
1643
1330
|
}
|
|
1644
1331
|
});
|
|
1645
1332
|
}
|
|
@@ -1669,26 +1356,24 @@ class AESEncryptionStream extends TransformStream {
|
|
|
1669
1356
|
}
|
|
1670
1357
|
const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
|
|
1671
1358
|
output.set(preamble, 0);
|
|
1672
|
-
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0));
|
|
1359
|
+
controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
|
|
1673
1360
|
},
|
|
1674
1361
|
async flush(controller) {
|
|
1675
1362
|
const {
|
|
1676
|
-
|
|
1677
|
-
hmac,
|
|
1363
|
+
engine,
|
|
1678
1364
|
pendingInput,
|
|
1679
1365
|
ready
|
|
1680
1366
|
} = this;
|
|
1681
|
-
if (
|
|
1367
|
+
if (engine) {
|
|
1682
1368
|
await ready;
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
hmac.update(encryptedChunk);
|
|
1687
|
-
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
1688
|
-
}
|
|
1689
|
-
const authenticationCode = fromBits(codecBytes, hmac.digest()).slice(0, AUTHENTICATION_CODE_LENGTH);
|
|
1369
|
+
const encryptedChunkArray = new Uint8Array(pendingInput);
|
|
1370
|
+
engine.process(encryptedChunkArray, false);
|
|
1371
|
+
const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
|
|
1690
1372
|
controller.enqueue(concat(encryptedChunkArray, authenticationCode));
|
|
1691
1373
|
}
|
|
1374
|
+
},
|
|
1375
|
+
cancel() {
|
|
1376
|
+
disposeEngine(this);
|
|
1692
1377
|
}
|
|
1693
1378
|
});
|
|
1694
1379
|
}
|
|
@@ -1703,30 +1388,23 @@ function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
|
|
|
1703
1388
|
});
|
|
1704
1389
|
}
|
|
1705
1390
|
|
|
1706
|
-
function append(aesCrypto, input, output, paddingStart, paddingEnd,
|
|
1391
|
+
function append(aesCrypto, input, output, paddingStart, paddingEnd, decrypt) {
|
|
1707
1392
|
const {
|
|
1708
|
-
|
|
1709
|
-
hmac,
|
|
1393
|
+
engine,
|
|
1710
1394
|
pendingInput
|
|
1711
1395
|
} = aesCrypto;
|
|
1712
1396
|
if (pendingInput.length) {
|
|
1713
1397
|
input = concat(pendingInput, input);
|
|
1714
1398
|
}
|
|
1715
1399
|
const inputLength = input.length - paddingEnd;
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
const
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
if (!verifyAuthenticationCode) {
|
|
1725
|
-
hmac.update(outputChunk);
|
|
1726
|
-
}
|
|
1727
|
-
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
1728
|
-
}
|
|
1729
|
-
aesCrypto.pendingInput = subarray(input, offset);
|
|
1400
|
+
const alignedLength = inputLength - (inputLength % BLOCK_LENGTH);
|
|
1401
|
+
output = expand(output, paddingStart + alignedLength);
|
|
1402
|
+
if (alignedLength) {
|
|
1403
|
+
const chunk = subarray(output, paddingStart, paddingStart + alignedLength);
|
|
1404
|
+
chunk.set(subarray(input, 0, alignedLength));
|
|
1405
|
+
engine.process(chunk, decrypt);
|
|
1406
|
+
}
|
|
1407
|
+
aesCrypto.pendingInput = subarray(input, alignedLength);
|
|
1730
1408
|
return output;
|
|
1731
1409
|
}
|
|
1732
1410
|
|
|
@@ -1734,10 +1412,17 @@ async function createDecryptionKeys(decrypt, strength, password, preamble) {
|
|
|
1734
1412
|
const passwordVerificationKey = await createKeys$1(decrypt, strength, password, subarray(preamble, 0, SALT_LENGTH[strength]));
|
|
1735
1413
|
const passwordVerification = subarray(preamble, SALT_LENGTH[strength]);
|
|
1736
1414
|
if (passwordVerificationKey[0] != passwordVerification[0] || passwordVerificationKey[1] != passwordVerification[1]) {
|
|
1415
|
+
disposeEngine(decrypt);
|
|
1737
1416
|
throw new Error(ERR_INVALID_PASSWORD);
|
|
1738
1417
|
}
|
|
1739
1418
|
}
|
|
1740
1419
|
|
|
1420
|
+
function disposeEngine({ engine }) {
|
|
1421
|
+
if (engine && engine.dispose) {
|
|
1422
|
+
engine.dispose();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1741
1426
|
async function createEncryptionKeys(encrypt, strength, password) {
|
|
1742
1427
|
const salt = getRandomValues(new Uint8Array(SALT_LENGTH[strength]));
|
|
1743
1428
|
const passwordVerification = await createKeys$1(encrypt, strength, password, salt);
|
|
@@ -1746,48 +1431,22 @@ async function createEncryptionKeys(encrypt, strength, password) {
|
|
|
1746
1431
|
|
|
1747
1432
|
async function createKeys$1(aesCrypto, strength, password, salt) {
|
|
1748
1433
|
aesCrypto.password = null;
|
|
1749
|
-
const
|
|
1750
|
-
const
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
const authentication = toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[strength], KEY_LENGTH[strength] * 2));
|
|
1754
|
-
const passwordVerification = subarray(compositeKey, KEY_LENGTH[strength] * 2);
|
|
1755
|
-
Object.assign(aesCrypto, {
|
|
1756
|
-
keys: {
|
|
1757
|
-
key,
|
|
1758
|
-
authentication,
|
|
1759
|
-
passwordVerification
|
|
1760
|
-
},
|
|
1761
|
-
ctr: new CtrGladman(new Aes(key), Array.from(COUNTER_DEFAULT_VALUE)),
|
|
1762
|
-
hmac: new HmacSha1(authentication)
|
|
1763
|
-
});
|
|
1764
|
-
return passwordVerification;
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
async function importKey(format, password, algorithm, extractable, keyUsages) {
|
|
1768
|
-
if (IMPORT_KEY_SUPPORTED) {
|
|
1769
|
-
try {
|
|
1770
|
-
return await subtle.importKey(format, password, algorithm, extractable, keyUsages);
|
|
1771
|
-
} catch {
|
|
1772
|
-
IMPORT_KEY_SUPPORTED = false;
|
|
1773
|
-
return misc.importKey(password);
|
|
1774
|
-
}
|
|
1775
|
-
} else {
|
|
1776
|
-
return misc.importKey(password);
|
|
1777
|
-
}
|
|
1434
|
+
const keyLength = KEY_LENGTH[strength];
|
|
1435
|
+
const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
|
|
1436
|
+
aesCrypto.engine = createEngine(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
|
|
1437
|
+
return subarray(compositeKey, keyLength * 2);
|
|
1778
1438
|
}
|
|
1779
1439
|
|
|
1780
|
-
async function
|
|
1440
|
+
async function deriveKey(password, salt, length) {
|
|
1781
1441
|
if (DERIVE_BITS_SUPPORTED) {
|
|
1782
1442
|
try {
|
|
1783
|
-
|
|
1443
|
+
const baseKey = await subtle.importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
|
|
1444
|
+
return new Uint8Array(await subtle.deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, length * 8));
|
|
1784
1445
|
} catch {
|
|
1785
1446
|
DERIVE_BITS_SUPPORTED = false;
|
|
1786
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1787
1447
|
}
|
|
1788
|
-
} else {
|
|
1789
|
-
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
1790
1448
|
}
|
|
1449
|
+
return pbkdf2(password, salt, PBKDF2_ITERATIONS, length);
|
|
1791
1450
|
}
|
|
1792
1451
|
|
|
1793
1452
|
function encodePassword(password, rawPassword) {
|
|
@@ -1811,13 +1470,6 @@ function subarray(array, begin, end) {
|
|
|
1811
1470
|
return array.subarray(begin, end);
|
|
1812
1471
|
}
|
|
1813
1472
|
|
|
1814
|
-
function fromBits(codecBytes, chunk) {
|
|
1815
|
-
return codecBytes.fromBits(chunk);
|
|
1816
|
-
}
|
|
1817
|
-
function toBits(codecBytes, chunk) {
|
|
1818
|
-
return codecBytes.toBits(chunk);
|
|
1819
|
-
}
|
|
1820
|
-
|
|
1821
1473
|
/*
|
|
1822
1474
|
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
1823
1475
|
|
|
@@ -2210,8 +1862,8 @@ class DeflateStream extends TransformStream {
|
|
|
2210
1862
|
let crc32Stream, encryptionStream, gzipCrc32Stream;
|
|
2211
1863
|
let readable = super.readable;
|
|
2212
1864
|
const codecStreams = format && getCodecStreams(format);
|
|
2213
|
-
const
|
|
2214
|
-
|
|
1865
|
+
const GzipCompressionStream = getGzipCompressionStream(useCompressionStream, CompressionStream, CompressionStreamFallback);
|
|
1866
|
+
const useGzipCrc32 = computeCrc32 && compressed && !deflate64 && !codecStreams && (!encrypted || zipCrypto) && Boolean(GzipCompressionStream);
|
|
2215
1867
|
if ((!encrypted || zipCrypto) && computeCrc32 && !useGzipCrc32) {
|
|
2216
1868
|
crc32Stream = new Crc32Stream();
|
|
2217
1869
|
readable = pipeThrough(readable, crc32Stream);
|
|
@@ -2221,7 +1873,7 @@ class DeflateStream extends TransformStream {
|
|
|
2221
1873
|
readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.CompressionStream, format, { level, chunkSize, compressionMethod, uncompressedSize: inputSize }));
|
|
2222
1874
|
} else if (useGzipCrc32) {
|
|
2223
1875
|
gzipCrc32Stream = new GzipToRawDeflateStream();
|
|
2224
|
-
readable = pipeThroughBackpressured(readable, new
|
|
1876
|
+
readable = pipeThroughBackpressured(readable, new GzipCompressionStream(FORMAT_GZIP, { level, chunkSize }));
|
|
2225
1877
|
readable = pipeThrough(readable, gzipCrc32Stream);
|
|
2226
1878
|
} else {
|
|
2227
1879
|
try {
|
|
@@ -2295,8 +1947,7 @@ class GzipToRawDeflateStream extends TransformStream {
|
|
|
2295
1947
|
}
|
|
2296
1948
|
}
|
|
2297
1949
|
|
|
2298
|
-
function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize) {
|
|
2299
|
-
const crc32 = new Crc32();
|
|
1950
|
+
function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
|
|
2300
1951
|
let outputLength = 0;
|
|
2301
1952
|
let inputDone = false;
|
|
2302
1953
|
let watchdogTimeout;
|
|
@@ -2370,7 +2021,7 @@ class InflateStream extends TransformStream {
|
|
|
2370
2021
|
constructor(options, { chunkSize, DecompressionStreamFallback, DecompressionStream }) {
|
|
2371
2022
|
super({});
|
|
2372
2023
|
const { zipCrypto, encrypted, checkCrc32, crc32, compressed, useCompressionStream, deflate64, format, compressionMethod, rawBitFlag, outputSize } = options;
|
|
2373
|
-
let crc32Stream, decryptionStream;
|
|
2024
|
+
let crc32Stream, decryptionStream, gzipCrc32;
|
|
2374
2025
|
let readable = super.readable;
|
|
2375
2026
|
if (encrypted) {
|
|
2376
2027
|
if (zipCrypto) {
|
|
@@ -2397,19 +2048,20 @@ class InflateStream extends TransformStream {
|
|
|
2397
2048
|
} catch {
|
|
2398
2049
|
throw error;
|
|
2399
2050
|
}
|
|
2400
|
-
|
|
2051
|
+
gzipCrc32 = new Crc32();
|
|
2052
|
+
readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, gzipCrc32);
|
|
2401
2053
|
}
|
|
2402
2054
|
}
|
|
2403
2055
|
readable = mapInflateStreamError(readable);
|
|
2404
2056
|
}
|
|
2405
|
-
if (checkCrc32) {
|
|
2057
|
+
if (checkCrc32 && !gzipCrc32) {
|
|
2406
2058
|
crc32Stream = new Crc32Stream();
|
|
2407
2059
|
readable = pipeThrough(readable, crc32Stream);
|
|
2408
2060
|
}
|
|
2409
2061
|
setReadable(this, readable, () => {
|
|
2410
2062
|
if (checkCrc32) {
|
|
2411
|
-
const
|
|
2412
|
-
if (crc32 !=
|
|
2063
|
+
const computedCrc32 = gzipCrc32 ? gzipCrc32.get() >>> 0 : new DataView(crc32Stream.value.buffer).getUint32(0, false);
|
|
2064
|
+
if (crc32 != computedCrc32) {
|
|
2413
2065
|
throw new Error(ERR_INVALID_CRC32);
|
|
2414
2066
|
}
|
|
2415
2067
|
}
|
|
@@ -2465,6 +2117,14 @@ function createCodecStream(CodecStreamClass, format, options) {
|
|
|
2465
2117
|
return new CodecStreamClass(format, options);
|
|
2466
2118
|
}
|
|
2467
2119
|
|
|
2120
|
+
function getGzipCompressionStream(useCompressionStream, CompressionStreamNative, CompressionStreamFallback) {
|
|
2121
|
+
if (useCompressionStream && CompressionStreamNative) {
|
|
2122
|
+
return CompressionStreamNative;
|
|
2123
|
+
} else if (CompressionStreamFallback && CompressionStreamFallback.requiresModule) {
|
|
2124
|
+
return CompressionStreamFallback;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2468
2128
|
function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
|
|
2469
2129
|
const Stream = useCompressionStream && CompressionStreamNative ?
|
|
2470
2130
|
CompressionStreamNative :
|
|
@@ -2757,11 +2417,18 @@ async function supportsDeflate(config) {
|
|
|
2757
2417
|
return true;
|
|
2758
2418
|
}
|
|
2759
2419
|
if (FallbackStream) {
|
|
2420
|
+
return await loadModule(config);
|
|
2421
|
+
}
|
|
2422
|
+
return false;
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
async function loadModule(config) {
|
|
2426
|
+
if (initModule) {
|
|
2760
2427
|
try {
|
|
2761
2428
|
await initModule(config);
|
|
2762
2429
|
return true;
|
|
2763
2430
|
} catch {
|
|
2764
|
-
|
|
2431
|
+
// ignored
|
|
2765
2432
|
}
|
|
2766
2433
|
}
|
|
2767
2434
|
return false;
|
|
@@ -2804,30 +2471,34 @@ class CodecWorker {
|
|
|
2804
2471
|
terminate() {
|
|
2805
2472
|
return new Promise(resolve => {
|
|
2806
2473
|
const { worker, busy } = workerData;
|
|
2807
|
-
if (
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2474
|
+
if (busy) {
|
|
2475
|
+
workerData.terminateResolvers = workerData.terminateResolvers || [];
|
|
2476
|
+
workerData.terminateResolvers.push(resolve);
|
|
2477
|
+
} else {
|
|
2478
|
+
if (worker) {
|
|
2811
2479
|
worker.terminate();
|
|
2812
|
-
|
|
2480
|
+
workerData.worker = null;
|
|
2813
2481
|
}
|
|
2814
|
-
workerData.interface = null;
|
|
2815
|
-
} else {
|
|
2816
2482
|
resolve();
|
|
2817
2483
|
}
|
|
2484
|
+
workerData.interface = null;
|
|
2818
2485
|
});
|
|
2819
2486
|
},
|
|
2820
2487
|
onTaskFinished() {
|
|
2821
2488
|
if (workerData.busy) {
|
|
2822
|
-
const {
|
|
2823
|
-
if (
|
|
2824
|
-
workerData.
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2489
|
+
const { terminateResolvers, worker } = workerData;
|
|
2490
|
+
if (terminateResolvers) {
|
|
2491
|
+
workerData.terminateResolvers = null;
|
|
2492
|
+
if (worker) {
|
|
2493
|
+
workerData.terminated = true;
|
|
2494
|
+
worker.terminate();
|
|
2495
|
+
}
|
|
2828
2496
|
}
|
|
2829
2497
|
workerData.busy = false;
|
|
2830
|
-
onTaskFinished(workerData);
|
|
2498
|
+
const pendingTasks = onTaskFinished(workerData);
|
|
2499
|
+
if (terminateResolvers) {
|
|
2500
|
+
terminateResolvers.forEach(resolve => resolve(pendingTasks));
|
|
2501
|
+
}
|
|
2831
2502
|
}
|
|
2832
2503
|
}
|
|
2833
2504
|
});
|
|
@@ -2880,28 +2551,23 @@ function createWorkerInterface(workerData, config) {
|
|
|
2880
2551
|
}
|
|
2881
2552
|
|
|
2882
2553
|
async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
|
|
2883
|
-
let codecStream, chunkStream;
|
|
2554
|
+
let codecStream, chunkStream, modulePromise;
|
|
2884
2555
|
try {
|
|
2885
2556
|
if (options.compressed && !options.format) {
|
|
2886
2557
|
const deflate = options.codecType.startsWith(CODEC_DEFLATE);
|
|
2887
2558
|
const FallbackStream = deflate ? config.CompressionStreamFallback : config.DecompressionStreamFallback;
|
|
2888
2559
|
const NativeStream = deflate ? config.CompressionStream : config.DecompressionStream;
|
|
2889
2560
|
if (!options.useCompressionStream) {
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
} catch {
|
|
2893
|
-
if (!FallbackStream || FallbackStream.requiresModule) {
|
|
2894
|
-
options.useCompressionStream = true;
|
|
2895
|
-
}
|
|
2561
|
+
if (!await moduleLoaded() && (!FallbackStream || FallbackStream.requiresModule)) {
|
|
2562
|
+
options.useCompressionStream = true;
|
|
2896
2563
|
}
|
|
2897
2564
|
} else if (FallbackStream && FallbackStream.requiresModule && !supportsDeflateRaw(NativeStream)) {
|
|
2898
|
-
|
|
2899
|
-
await initModule(config);
|
|
2900
|
-
} catch {
|
|
2901
|
-
// ignored
|
|
2902
|
-
}
|
|
2565
|
+
await moduleLoaded();
|
|
2903
2566
|
}
|
|
2904
2567
|
}
|
|
2568
|
+
if (options.encrypted && !options.zipCrypto) {
|
|
2569
|
+
await moduleLoaded();
|
|
2570
|
+
}
|
|
2905
2571
|
codecStream = new CodecStream(options, config);
|
|
2906
2572
|
chunkStream = new ChunkStream(getChunkSize(config));
|
|
2907
2573
|
await readable
|
|
@@ -2934,6 +2600,13 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
|
|
|
2934
2600
|
} finally {
|
|
2935
2601
|
onTaskFinished();
|
|
2936
2602
|
}
|
|
2603
|
+
|
|
2604
|
+
function moduleLoaded() {
|
|
2605
|
+
if (!modulePromise) {
|
|
2606
|
+
modulePromise = loadModule(config);
|
|
2607
|
+
}
|
|
2608
|
+
return modulePromise;
|
|
2609
|
+
}
|
|
2937
2610
|
}
|
|
2938
2611
|
|
|
2939
2612
|
/*
|
|
@@ -3510,7 +3183,10 @@ async function runWorker(stream, workerOptions) {
|
|
|
3510
3183
|
|
|
3511
3184
|
function onTaskFinished(workerData) {
|
|
3512
3185
|
clearStarvationTimeout();
|
|
3513
|
-
if (
|
|
3186
|
+
if (workerData.terminated) {
|
|
3187
|
+
workerData.terminated = false;
|
|
3188
|
+
return runPendingRequestsInline();
|
|
3189
|
+
} else if (pendingRequests.length) {
|
|
3514
3190
|
const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
|
|
3515
3191
|
resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
|
|
3516
3192
|
armStarvationTimeout();
|
|
@@ -3548,12 +3224,26 @@ function onWorkerStarvation() {
|
|
|
3548
3224
|
starvationTimeout = null;
|
|
3549
3225
|
if (pendingRequests.length) {
|
|
3550
3226
|
const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
|
|
3551
|
-
|
|
3552
|
-
resolve(new CodecWorker({}, stream, inlineWorkerOptions, onInlineTaskFinished));
|
|
3227
|
+
resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), onInlineTaskFinished));
|
|
3553
3228
|
armStarvationTimeout();
|
|
3554
3229
|
}
|
|
3555
3230
|
}
|
|
3556
3231
|
|
|
3232
|
+
function runPendingRequestsInline() {
|
|
3233
|
+
const tasks = pendingRequests.splice(0).map(({ resolve, stream, workerOptions }) => new Promise(resolveTask => {
|
|
3234
|
+
resolve(new CodecWorker({}, stream, getInlineWorkerOptions(workerOptions), () => {
|
|
3235
|
+
onInlineTaskFinished();
|
|
3236
|
+
resolveTask();
|
|
3237
|
+
}));
|
|
3238
|
+
}));
|
|
3239
|
+
clearStarvationTimeout();
|
|
3240
|
+
return Promise.all(tasks);
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
function getInlineWorkerOptions(workerOptions) {
|
|
3244
|
+
return Object.assign({}, workerOptions, { useWebWorkers: false, workerURI: UNDEFINED_VALUE, createWorker: UNDEFINED_VALUE });
|
|
3245
|
+
}
|
|
3246
|
+
|
|
3557
3247
|
function onInlineTaskFinished() {
|
|
3558
3248
|
clearStarvationTimeout();
|
|
3559
3249
|
armStarvationTimeout();
|
|
@@ -3563,18 +3253,14 @@ function terminateWorker(workerData, workerOptions) {
|
|
|
3563
3253
|
const { config } = workerOptions;
|
|
3564
3254
|
const { terminateWorkerTimeout } = config;
|
|
3565
3255
|
if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
// ignored
|
|
3575
|
-
}
|
|
3576
|
-
}, terminateWorkerTimeout);
|
|
3577
|
-
}
|
|
3256
|
+
workerData.terminateTimeout = setTimeout(async () => {
|
|
3257
|
+
pool = pool.filter(data => data != workerData);
|
|
3258
|
+
try {
|
|
3259
|
+
await workerData.terminate();
|
|
3260
|
+
} catch {
|
|
3261
|
+
// ignored
|
|
3262
|
+
}
|
|
3263
|
+
}, terminateWorkerTimeout);
|
|
3578
3264
|
}
|
|
3579
3265
|
}
|
|
3580
3266
|
|
|
@@ -3587,10 +3273,13 @@ function clearTerminateTimeout(workerData) {
|
|
|
3587
3273
|
}
|
|
3588
3274
|
|
|
3589
3275
|
async function terminateWorkers() {
|
|
3590
|
-
await Promise.allSettled(
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3276
|
+
await Promise.allSettled([
|
|
3277
|
+
runPendingRequestsInline(),
|
|
3278
|
+
...pool.map(workerData => {
|
|
3279
|
+
clearTerminateTimeout(workerData);
|
|
3280
|
+
return workerData.terminate();
|
|
3281
|
+
})
|
|
3282
|
+
]);
|
|
3594
3283
|
resetWebWorkerSupport();
|
|
3595
3284
|
}
|
|
3596
3285
|
|
|
@@ -3665,6 +3354,19 @@ function decodeText(value, encoding) {
|
|
|
3665
3354
|
return decode(value, encoding, true);
|
|
3666
3355
|
}
|
|
3667
3356
|
|
|
3357
|
+
function isUTF8Text(value) {
|
|
3358
|
+
if (value.some(byte => byte > 0x7f)) {
|
|
3359
|
+
try {
|
|
3360
|
+
new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
3361
|
+
return true;
|
|
3362
|
+
} catch {
|
|
3363
|
+
return false;
|
|
3364
|
+
}
|
|
3365
|
+
} else {
|
|
3366
|
+
return false;
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
|
|
3668
3370
|
function decodeTextRemovingBOM(value, encoding) {
|
|
3669
3371
|
return decode(value, encoding, false);
|
|
3670
3372
|
}
|
|
@@ -4070,16 +3772,14 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
4070
3772
|
combineSizeEocd
|
|
4071
3773
|
} = httpReader;
|
|
4072
3774
|
if (isHttpFamily(url) && (useRangeHeader || forceRangeRequests) && (typeof preventHeadRequest == UNDEFINED_TYPE || preventHeadRequest)) {
|
|
4073
|
-
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -
|
|
3775
|
+
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, combineSizeEocd ? -65557 : undefined));
|
|
4074
3776
|
const acceptRanges = response.headers.get(HTTP_HEADER_ACCEPT_RANGES);
|
|
4075
3777
|
if (!forceRangeRequests && (!acceptRanges || acceptRanges.toLowerCase() != HTTP_RANGE_UNIT)) {
|
|
4076
3778
|
throw new Error(ERR_HTTP_RANGE);
|
|
4077
3779
|
} else {
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
httpReader.eocdCache = eocdCache;
|
|
4082
|
-
}
|
|
3780
|
+
let eocdCache;
|
|
3781
|
+
if (combineSizeEocd && response.status == 206) {
|
|
3782
|
+
eocdCache = new Uint8Array(await response.arrayBuffer());
|
|
4083
3783
|
}
|
|
4084
3784
|
setResourceValidators(httpReader, response);
|
|
4085
3785
|
const contentSize = getContentRangeSize(response);
|
|
@@ -4088,6 +3788,9 @@ async function initHttpReader(httpReader, sendRequest, getRequestData) {
|
|
|
4088
3788
|
} else {
|
|
4089
3789
|
httpReader.size = contentSize;
|
|
4090
3790
|
}
|
|
3791
|
+
if (eocdCache && eocdCache.length && getContentRangeOffset(response) === httpReader.size - eocdCache.length) {
|
|
3792
|
+
httpReader.eocdCache = eocdCache;
|
|
3793
|
+
}
|
|
4091
3794
|
}
|
|
4092
3795
|
} else {
|
|
4093
3796
|
await getContentLength(httpReader, sendRequest, getRequestData);
|
|
@@ -4103,25 +3806,23 @@ async function readUint8ArrayHttpReader(httpReader, index, length, sendRequest,
|
|
|
4103
3806
|
options
|
|
4104
3807
|
} = httpReader;
|
|
4105
3808
|
if (useRangeHeader || forceRangeRequests) {
|
|
4106
|
-
if (eocdCache && index == size - END_OF_CENTRAL_DIR_LENGTH && length == END_OF_CENTRAL_DIR_LENGTH) {
|
|
4107
|
-
return eocdCache;
|
|
4108
|
-
}
|
|
4109
3809
|
if (index >= size || length === 0) {
|
|
4110
3810
|
return EMPTY_UINT8_ARRAY;
|
|
4111
3811
|
} else {
|
|
4112
3812
|
if (index + length > size) {
|
|
4113
3813
|
length = size - index;
|
|
4114
3814
|
}
|
|
3815
|
+
if (eocdCache && index >= size - eocdCache.length) {
|
|
3816
|
+
const cacheIndex = index - (size - eocdCache.length);
|
|
3817
|
+
return eocdCache.slice(cacheIndex, cacheIndex + length);
|
|
3818
|
+
}
|
|
4115
3819
|
const response = await sendRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, index, length));
|
|
4116
3820
|
if (response.status != 206) {
|
|
4117
3821
|
throw new Error(ERR_HTTP_RANGE);
|
|
4118
3822
|
}
|
|
4119
|
-
const
|
|
4120
|
-
if (
|
|
4121
|
-
|
|
4122
|
-
if (!Number.isNaN(rangeStart) && rangeStart != index) {
|
|
4123
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4124
|
-
}
|
|
3823
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3824
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != index) {
|
|
3825
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4125
3826
|
}
|
|
4126
3827
|
checkResourceValidators(httpReader, response);
|
|
4127
3828
|
setResourceValidators(httpReader, response);
|
|
@@ -4181,12 +3882,9 @@ function createRangeReadable(httpReader, offset, size) {
|
|
|
4181
3882
|
if (response.status != 206) {
|
|
4182
3883
|
throw new Error(ERR_HTTP_RANGE);
|
|
4183
3884
|
}
|
|
4184
|
-
const
|
|
4185
|
-
if (
|
|
4186
|
-
|
|
4187
|
-
if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
|
|
4188
|
-
throw new Error(ERR_HTTP_RANGE);
|
|
4189
|
-
}
|
|
3885
|
+
const rangeStart = getContentRangeOffset(response);
|
|
3886
|
+
if (rangeStart !== UNDEFINED_VALUE && rangeStart != windowOffset) {
|
|
3887
|
+
throw new Error(ERR_HTTP_RANGE);
|
|
4190
3888
|
}
|
|
4191
3889
|
checkResourceValidators(httpReader, response);
|
|
4192
3890
|
setResourceValidators(httpReader, response);
|
|
@@ -4202,6 +3900,16 @@ function createRangeReadable(httpReader, offset, size) {
|
|
|
4202
3900
|
}
|
|
4203
3901
|
}
|
|
4204
3902
|
|
|
3903
|
+
function getContentRangeOffset(response) {
|
|
3904
|
+
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
3905
|
+
if (contentRangeHeader) {
|
|
3906
|
+
const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
|
|
3907
|
+
if (!Number.isNaN(rangeStart)) {
|
|
3908
|
+
return rangeStart;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
|
|
4205
3913
|
function getContentRangeSize(response) {
|
|
4206
3914
|
const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
|
|
4207
3915
|
if (contentRangeHeader) {
|
|
@@ -4948,6 +4656,7 @@ const WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD = "mismatched loca
|
|
|
4948
4656
|
const WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES = "mismatched local file header (crc32 or sizes)";
|
|
4949
4657
|
const MAX_KNOWN_VERSION = 63;
|
|
4950
4658
|
const DRIVE_LETTER_REGEXP = /^[a-zA-Z]:/;
|
|
4659
|
+
const PARENT_DIRECTORY_REGEXP = /(^|[\\/])\.\.([\\/]|$)/;
|
|
4951
4660
|
const CHARSET_UTF8 = "utf-8";
|
|
4952
4661
|
const PROPERTY_NAME_UTF8_SUFFIX = "UTF8";
|
|
4953
4662
|
const CHARSET_CP437 = "cp437";
|
|
@@ -4982,7 +4691,7 @@ class ZipReader {
|
|
|
4982
4691
|
Object.assign(this, {
|
|
4983
4692
|
reader: new GenericReader(reader),
|
|
4984
4693
|
options,
|
|
4985
|
-
readRanges: new
|
|
4694
|
+
readRanges: { indexes: new Set(), sortedRanges: [], pendingRanges: [] }
|
|
4986
4695
|
});
|
|
4987
4696
|
}
|
|
4988
4697
|
|
|
@@ -5200,12 +4909,13 @@ class ZipReader {
|
|
|
5200
4909
|
const versionMadeBy = getUint16$1(directoryView, offset + 4);
|
|
5201
4910
|
const msDosCompatible = versionMadeBy >> 8 == 0;
|
|
5202
4911
|
const unixCompatible = versionMadeBy >> 8 == 3;
|
|
5203
|
-
const rawFilename = directoryArray.subarray(filenameOffset, extraFieldOffset);
|
|
5204
4912
|
const commentLength = getUint16$1(directoryView, offset + 32);
|
|
5205
4913
|
const endOffset = commentOffset + commentLength;
|
|
5206
|
-
const
|
|
5207
|
-
const
|
|
5208
|
-
const
|
|
4914
|
+
const rawEntryData = new Uint8Array(directoryArray.subarray(filenameOffset, endOffset));
|
|
4915
|
+
const rawFilename = rawEntryData.subarray(0, fileEntry.filenameLength);
|
|
4916
|
+
const rawComment = rawEntryData.subarray(fileEntry.filenameLength + fileEntry.extraFieldLength);
|
|
4917
|
+
const filenameUTF8 = languageEncodingFlag || (!filenameEncoding && isUTF8Text(rawFilename));
|
|
4918
|
+
const commentUTF8 = languageEncodingFlag || (!commentEncoding && isUTF8Text(rawComment));
|
|
5209
4919
|
const externalFileAttributes = getUint32$1(directoryView, offset + 38);
|
|
5210
4920
|
const msdosAttributesRaw = externalFileAttributes & MAX_8_BITS;
|
|
5211
4921
|
const msdosAttributes = {
|
|
@@ -5256,7 +4966,7 @@ class ZipReader {
|
|
|
5256
4966
|
rawFilename,
|
|
5257
4967
|
filenameUTF8,
|
|
5258
4968
|
commentUTF8,
|
|
5259
|
-
rawExtraField:
|
|
4969
|
+
rawExtraField: rawEntryData.subarray(fileEntry.filenameLength, fileEntry.filenameLength + fileEntry.extraFieldLength),
|
|
5260
4970
|
rawComment,
|
|
5261
4971
|
filename,
|
|
5262
4972
|
comment
|
|
@@ -5627,7 +5337,6 @@ class ZipEntry {
|
|
|
5627
5337
|
throw new Error(ERR_ENTRY_DATA_OUT_OF_BOUNDS);
|
|
5628
5338
|
}
|
|
5629
5339
|
const size = compressedSize;
|
|
5630
|
-
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5631
5340
|
const signal = checkSignalOption(getOptionValue$1(zipEntry, options, OPTION_SIGNAL));
|
|
5632
5341
|
throwIfAborted(signal);
|
|
5633
5342
|
let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
|
|
@@ -5701,6 +5410,7 @@ class ZipEntry {
|
|
|
5701
5410
|
writer = new GenericWriter(writer);
|
|
5702
5411
|
await initStream(writer, getDecodableOutputSize(outputSize, compressedSize, compressed));
|
|
5703
5412
|
({ writable } = writer);
|
|
5413
|
+
const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
|
|
5704
5414
|
const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
|
|
5705
5415
|
if (writtenSize != outputSize) {
|
|
5706
5416
|
throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
|
|
@@ -5764,7 +5474,7 @@ function readDigitalSignature(signatureRecordArray) {
|
|
|
5764
5474
|
if (getUint32$1(signatureRecordView, 0) == DIGITAL_SIGNATURE_RECORD_SIGNATURE) {
|
|
5765
5475
|
const signatureDataLength = getUint16$1(signatureRecordView, 4);
|
|
5766
5476
|
if (6 + signatureDataLength <= signatureRecordArray.length) {
|
|
5767
|
-
return signatureRecordArray.subarray(6, 6 + signatureDataLength);
|
|
5477
|
+
return new Uint8Array(signatureRecordArray.subarray(6, 6 + signatureDataLength));
|
|
5768
5478
|
}
|
|
5769
5479
|
}
|
|
5770
5480
|
}
|
|
@@ -6136,14 +5846,61 @@ async function detectOverlappingEntry({
|
|
|
6136
5846
|
end: dataOffset + compressedSize + dataDescriptorLength,
|
|
6137
5847
|
fileEntry
|
|
6138
5848
|
};
|
|
6139
|
-
|
|
6140
|
-
|
|
5849
|
+
const { indexes, sortedRanges, pendingRanges } = readRanges;
|
|
5850
|
+
if (!indexes.has(index)) {
|
|
5851
|
+
const overlappingRange = findOverlappingRange(sortedRanges, range) || pendingRanges.find(otherRange => rangesOverlap(range, otherRange));
|
|
5852
|
+
if (overlappingRange) {
|
|
6141
5853
|
const error = new Error(ERR_OVERLAPPING_ENTRY);
|
|
6142
|
-
error.overlappingEntry =
|
|
5854
|
+
error.overlappingEntry = overlappingRange.fileEntry;
|
|
6143
5855
|
throw error;
|
|
6144
5856
|
}
|
|
5857
|
+
indexes.add(index);
|
|
5858
|
+
pendingRanges.push(range);
|
|
5859
|
+
if (pendingRanges.length * pendingRanges.length > sortedRanges.length) {
|
|
5860
|
+
pendingRanges.sort((range, otherRange) => range.start - otherRange.start);
|
|
5861
|
+
readRanges.sortedRanges = mergeRanges(sortedRanges, pendingRanges);
|
|
5862
|
+
pendingRanges.length = 0;
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
}
|
|
5866
|
+
|
|
5867
|
+
function findOverlappingRange(sortedRanges, range) {
|
|
5868
|
+
let low = 0;
|
|
5869
|
+
let high = sortedRanges.length;
|
|
5870
|
+
while (low < high) {
|
|
5871
|
+
const middle = (low + high) >>> 1;
|
|
5872
|
+
if (sortedRanges[middle].start < range.start) {
|
|
5873
|
+
low = middle + 1;
|
|
5874
|
+
} else {
|
|
5875
|
+
high = middle;
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
const previousRange = sortedRanges[low - 1];
|
|
5879
|
+
const nextRange = sortedRanges[low];
|
|
5880
|
+
if (previousRange && rangesOverlap(range, previousRange)) {
|
|
5881
|
+
return previousRange;
|
|
5882
|
+
}
|
|
5883
|
+
if (nextRange && rangesOverlap(range, nextRange)) {
|
|
5884
|
+
return nextRange;
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
|
|
5888
|
+
function rangesOverlap(range, otherRange) {
|
|
5889
|
+
return range.start < otherRange.end && otherRange.start < range.end;
|
|
5890
|
+
}
|
|
5891
|
+
|
|
5892
|
+
function mergeRanges(sortedRanges, pendingRanges) {
|
|
5893
|
+
const mergedRanges = [];
|
|
5894
|
+
let indexSorted = 0;
|
|
5895
|
+
let indexPending = 0;
|
|
5896
|
+
while (indexSorted < sortedRanges.length || indexPending < pendingRanges.length) {
|
|
5897
|
+
if (indexPending == pendingRanges.length || (indexSorted < sortedRanges.length && sortedRanges[indexSorted].start < pendingRanges[indexPending].start)) {
|
|
5898
|
+
mergedRanges.push(sortedRanges[indexSorted++]);
|
|
5899
|
+
} else {
|
|
5900
|
+
mergedRanges.push(pendingRanges[indexPending++]);
|
|
5901
|
+
}
|
|
6145
5902
|
}
|
|
6146
|
-
|
|
5903
|
+
return mergedRanges;
|
|
6147
5904
|
}
|
|
6148
5905
|
|
|
6149
5906
|
function readDataDescriptor(dataDescriptorView, offset, extraFieldZip64) {
|
|
@@ -6240,10 +5997,10 @@ function isUnsafeFilename(filename, filenameValidation) {
|
|
|
6240
5997
|
if (pathParts.length > 1 && pathParts[pathParts.length - 1] === "") {
|
|
6241
5998
|
pathParts.pop();
|
|
6242
5999
|
}
|
|
6243
|
-
if (
|
|
6000
|
+
if (PARENT_DIRECTORY_REGEXP.test(filename) || filename.startsWith("/") || filename.startsWith("\\") || DRIVE_LETTER_REGEXP.test(filename)) {
|
|
6244
6001
|
return true;
|
|
6245
6002
|
}
|
|
6246
|
-
return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes(""));
|
|
6003
|
+
return filenameValidation == STRICTNESS_STRICT && (pathParts.includes(".") || pathParts.includes("") || filename.includes("\0"));
|
|
6247
6004
|
}
|
|
6248
6005
|
|
|
6249
6006
|
function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
|
|
@@ -6329,7 +6086,7 @@ async function* scanEndOfCentralDirectory(reader, scanLength) {
|
|
|
6329
6086
|
}
|
|
6330
6087
|
|
|
6331
6088
|
function getEndOfCentralDirectoryInfo(scanArray, indexByte, offset) {
|
|
6332
|
-
return { offset, buffer: scanArray.
|
|
6089
|
+
return { offset, buffer: new Uint8Array(scanArray.subarray(indexByte, indexByte + END_OF_CENTRAL_DIR_LENGTH)).buffer };
|
|
6333
6090
|
}
|
|
6334
6091
|
|
|
6335
6092
|
async function getCentralDirectoryReachability(reader, view, anchoredOffset, indexByte, offset, size, remoteProbeBudget) {
|
|
@@ -6721,7 +6478,6 @@ class ZipWriter {
|
|
|
6721
6478
|
rawExtraFieldUnix: EMPTY_UINT8_ARRAY,
|
|
6722
6479
|
rawExtraField,
|
|
6723
6480
|
rawCentralExtraField: EMPTY_UINT8_ARRAY,
|
|
6724
|
-
extendedTimestamp: false,
|
|
6725
6481
|
headerArray,
|
|
6726
6482
|
headerView
|
|
6727
6483
|
});
|
|
@@ -7465,7 +7221,7 @@ function resolveEntrySizes(zipWriter, hasContent, contentSize, metadata, options
|
|
|
7465
7221
|
}
|
|
7466
7222
|
}
|
|
7467
7223
|
const emptyEntry = !encryptedEntry && (!hasContent || (contentSize === 0 && !passThroughCompression)) && !isCompressed(compressionMethod, level);
|
|
7468
|
-
if (emptyEntry &&
|
|
7224
|
+
if (emptyEntry && getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR) === UNDEFINED_VALUE) {
|
|
7469
7225
|
dataDescriptor = false;
|
|
7470
7226
|
}
|
|
7471
7227
|
const zip64UncompressedSize = zip64Enabled || unknownSize || uncompressedSize >= MAX_32_BITS;
|
|
@@ -8977,7 +8733,7 @@ function formatSupported(StreamClass, format) {
|
|
|
8977
8733
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8978
8734
|
*/
|
|
8979
8735
|
|
|
8980
|
-
const VERSION = "2.
|
|
8736
|
+
const VERSION = "2.15.0";
|
|
8981
8737
|
|
|
8982
8738
|
/*
|
|
8983
8739
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|