@syncfusion/ej2-pdf
Version:
Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.
367 lines (366 loc) • 13.8 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { _Cipher } from './cipher';
/**
* Simple stream cipher implementation (variant used internally).
*
* @private
*/
var _NormalCipherFour = /** @class */ (function (_super) {
__extends(_NormalCipherFour, _super);
function _NormalCipherFour(key) {
var _this = _super.call(this) || this;
_this._a = 0;
_this._b = 0;
var s = new Uint8Array(256);
for (var i = 0; i < 256; ++i) {
s[i] = i;
}
var keyLength = key.length;
for (var i = 0, j = 0; i < 256; ++i) {
var buffer = s[i];
j = (j + buffer + key[i % keyLength]) & 0xff;
s[i] = s[j];
s[j] = buffer;
}
_this._s = s;
return _this;
}
/**
* Encrypt/decrypt a byte array block using the stream cipher state.
*
* @private
* @param {Uint8Array} data - Input bytes to process.
* @returns {Uint8Array} The processed bytes.
*/
_NormalCipherFour.prototype._encryptBlock = function (data) {
var a = this._a;
var b = this._b;
var s = this._s;
var n = data.length;
var output = new Uint8Array(n);
for (var i = 0; i < n; ++i) {
a = (a + 1) & 0xff;
var first = s[a];
b = (b + first) & 0xff;
var second = s[b];
s[a] = second;
s[b] = first;
output[i] = data[i] ^ s[(first + second) & 0xff];
}
this._a = a;
this._b = b;
return output;
};
/**
* Decrypt a block.
*
* @private
* @param {Uint8Array} data - Input bytes.
* @returns {Uint8Array} The processed bytes.
*/
_NormalCipherFour.prototype._decryptBlock = function (data) {
return this._encryptBlock(data);
};
/**
* Encrypt data.
*
* @private
* @param {Uint8Array} data - Input bytes.
* @returns {Uint8Array} Encrypted bytes.
*/
_NormalCipherFour.prototype._encrypt = function (data) {
return this._encryptBlock(data);
};
return _NormalCipherFour;
}(_Cipher));
export { _NormalCipherFour };
/**
* No-op cipher used when encryption is disabled.
*
* @private
*/
var _NullCipher = /** @class */ (function (_super) {
__extends(_NullCipher, _super);
function _NullCipher() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Return input data unchanged.
*
* @private
* @param {Uint8Array} data - Input bytes.
* @returns {Uint8Array} The same bytes (unchanged).
*/
_NullCipher.prototype._decryptBlock = function (data) {
return data;
};
/**
* Return input data unchanged.
*
* @private
* @param {Uint8Array} data - Input bytes.
* @returns {Uint8Array} The same bytes (unchanged).
*/
_NullCipher.prototype._encrypt = function (data) {
return data;
};
return _NullCipher;
}(_Cipher));
export { _NullCipher };
/**
* RC2-style block cipher wrapper used internally.
*
* @private
*/
var _CipherTwo = /** @class */ (function (_super) {
__extends(_CipherTwo, _super);
function _CipherTwo(key, effectiveKeyBits) {
if (effectiveKeyBits === void 0) { effectiveKeyBits = 64; }
var _this = _super.call(this) || this;
/**
* Cipher block size in bytes.
*
* @private
*/
_this._blockSize = 8;
/**
* Effective key size in bits.
*
* @private
*/
_this._effectiveKeyBits = 64;
if (!(key instanceof Uint8Array) || key.length < 5 || key.length > 128) {
throw new Error('RC2 key must be between 5 and 128 bytes.');
}
_this._key = key;
_this._effectiveKeyBits = effectiveKeyBits;
_this._expandedKey = _this._expandKey(key, _this._effectiveKeyBits);
return _this;
}
/**
* Expand the provided key into the internal RC2 key schedule.
*
* @private
* @param {Uint8Array} key - Key bytes.
* @param {number} bits - Effective key size in bits.
* @returns {Uint16Array} Expanded key schedule as `Uint16Array`.
*/
_CipherTwo.prototype._expandKey = function (key, bits) {
var piTable = [
217, 120, 249, 196, 25, 221, 181, 237, 40, 233, 253, 121, 74, 160, 216, 157,
198, 126, 55, 131, 43, 118, 83, 142, 98, 76, 100, 136, 68, 139, 251, 162,
23, 154, 89, 245, 135, 179, 79, 19, 97, 69, 109, 141, 9, 129, 125, 50,
189, 143, 64, 235, 134, 183, 123, 11, 240, 149, 33, 34, 92, 107, 78, 130,
84, 214, 101, 147, 206, 96, 178, 28, 115, 86, 192, 20, 167, 140, 241, 220,
18, 117, 202, 31, 59, 190, 228, 209, 66, 61, 212, 48, 163, 60, 182, 38,
111, 191, 14, 218, 70, 105, 7, 87, 39, 242, 29, 155, 188, 148, 67, 3,
248, 17, 199, 246, 144, 239, 62, 231, 6, 195, 213, 47, 200, 102, 30, 215,
8, 232, 234, 222, 128, 82, 238, 247, 132, 170, 114, 172, 53, 77, 106, 42,
150, 26, 210, 113, 90, 21, 73, 116, 75, 159, 208, 94, 4, 24, 164, 236,
194, 224, 65, 110, 15, 81, 203, 204, 36, 145, 175, 80, 161, 244, 112, 57,
153, 124, 58, 133, 35, 184, 180, 122, 252, 2, 54, 91, 37, 85, 151, 49,
45, 93, 250, 152, 227, 138, 146, 174, 5, 223, 41, 16, 103, 108, 186, 201,
211, 0, 230, 207, 225, 158, 168, 44, 99, 22, 1, 63, 88, 226, 137, 169,
13, 56, 52, 27, 171, 51, 255, 176, 187, 72, 12, 95, 185, 177, 205, 46,
197, 243, 219, 71, 229, 165, 156, 119, 10, 166, 32, 104, 254, 127, 193, 173
];
var xKey = new Uint8Array(128);
xKey.set(key);
var len = key.length;
if (len < 128) {
var index = 0;
var x_1 = xKey[len - 1];
while (len < 128) {
x_1 = piTable[(x_1 + xKey[index++]) & 0xFF] & 0xFF;
xKey[len++] = x_1;
}
}
var t = (bits + 7) >> 3;
var mask = 0xFF >> (7 & -bits);
var x = piTable[xKey[128 - t] & mask] & 0xFF;
xKey[128 - t] = x;
for (var i = 128 - t - 1; i >= 0; i--) {
x = piTable[x ^ xKey[i + t]] & 0xFF;
xKey[i] = x;
}
var newKey = new Uint16Array(64);
for (var i = 0; i < 64; i++) {
newKey[i] = xKey[2 * i] + (xKey[2 * i + 1] << 8);
}
return newKey;
};
/**
* Rotate a 16-bit value left by `n` bits.
*
* @private
* @param {number} x - The 16 bit value.
* @param {number} n - Number of bits to rotate.
* @returns {number} The rotated 16 bit value.
*/
_CipherTwo.prototype._rotateLeft = function (x, n) {
return ((x << n) | (x >>> (16 - n))) & 0xFFFF;
};
/**
* Rotate a 16-bit value right by `n` bits.
*
* @private
* @param {number} x - The 16 bit value.
* @param {number} n - Number of bits to rotate by.
* @returns {number} The rotated 16 bit value.
*/
_CipherTwo.prototype._rotateRight = function (x, n) {
return ((x >>> n) | (x << (16 - n))) & 0xFFFF;
};
/**
* Encrypt a single RC2 block.
*
* @private
* @param {Uint8Array} block - 8 byte block to encrypt.
* @returns {Uint8Array} Encrypted 8-byte block.
*/
_CipherTwo.prototype._encryptBlock = function (block) {
var R = new Uint16Array(4);
for (var i = 0; i < 4; i++) {
R[i] = block[2 * i] + (block[2 * i + 1] << 8);
}
var j = 0;
for (var round = 0; round < 16; round++) {
R[0] = this._rotateLeft((R[0] + (R[1] & ~R[3]) + (R[2] & R[3]) + this._expandedKey[j++]) & 0xFFFF, 1);
R[1] = this._rotateLeft((R[1] + (R[2] & ~R[0]) + (R[3] & R[0]) + this._expandedKey[j++]) & 0xFFFF, 2);
R[2] = this._rotateLeft((R[2] + (R[3] & ~R[1]) + (R[0] & R[1]) + this._expandedKey[j++]) & 0xFFFF, 3);
R[3] = this._rotateLeft((R[3] + (R[0] & ~R[2]) + (R[1] & R[2]) + this._expandedKey[j++]) & 0xFFFF, 5);
if (round === 4 || round === 10) {
R[0] = (R[0] + this._expandedKey[R[3] & 63]) & 0xFFFF;
R[1] = (R[1] + this._expandedKey[R[0] & 63]) & 0xFFFF;
R[2] = (R[2] + this._expandedKey[R[1] & 63]) & 0xFFFF;
R[3] = (R[3] + this._expandedKey[R[2] & 63]) & 0xFFFF;
}
}
var encrypted = new Uint8Array(8);
for (var i = 0; i < 4; i++) {
encrypted[2 * i] = R[i] & 0xFF;
encrypted[2 * i + 1] = R[i] >>> 8;
}
return encrypted;
};
/**
* Decrypt a single RC2 block.
*
* @private
* @param {Uint8Array} block - 8-byte block to decrypt.
* @returns {Uint8Array} Decrypted 8-byte block.
*/
_CipherTwo.prototype._decryptBlock = function (block) {
var R = new Uint16Array(4);
for (var i = 0; i < 4; i++) {
R[i] = block[2 * i] + (block[2 * i + 1] << 8);
}
var j = 63;
for (var round = 15; round >= 0; round--) {
if (round === 4 || round === 10) {
R[3] = (R[3] - this._expandedKey[R[2] & 63]) & 0xFFFF;
R[2] = (R[2] - this._expandedKey[R[1] & 63]) & 0xFFFF;
R[1] = (R[1] - this._expandedKey[R[0] & 63]) & 0xFFFF;
R[0] = (R[0] - this._expandedKey[R[3] & 63]) & 0xFFFF;
}
R[3] = this._rotateRight(R[3], 5);
R[3] = (R[3] - (R[0] & ~R[2]) - (R[1] & R[2]) - this._expandedKey[j--]) & 0xFFFF;
R[2] = this._rotateRight(R[2], 3);
R[2] = (R[2] - (R[3] & ~R[1]) - (R[0] & R[1]) - this._expandedKey[j--]) & 0xFFFF;
R[1] = this._rotateRight(R[1], 2);
R[1] = (R[1] - (R[2] & ~R[0]) - (R[3] & R[0]) - this._expandedKey[j--]) & 0xFFFF;
R[0] = this._rotateRight(R[0], 1);
R[0] = (R[0] - (R[1] & ~R[3]) - (R[2] & R[3]) - this._expandedKey[j--]) & 0xFFFF;
}
var decrypted = new Uint8Array(8);
for (var i = 0; i < 4; i++) {
decrypted[2 * i] = R[i] & 0xFF;
decrypted[2 * i + 1] = R[i] >>> 8;
}
return decrypted;
};
/**
* Encrypt arbitrary data (pads to block size) and returns encrypted bytes.
*
* @private
* @param {Uint8Array} data - Bytes to encrypt.
* @returns {Uint8Array} Encrypted bytes.
*/
_CipherTwo.prototype._encrypt = function (data) {
var padLength = this._blockSize - (data.length % this._blockSize);
var padded = new Uint8Array(data.length + padLength);
padded.set(data);
padded.fill(padLength, data.length);
var result = [];
for (var i = 0; i < padded.length; i += this._blockSize) {
var block = padded.subarray(i, i + this._blockSize);
result.push(this._encryptBlock(block));
}
var totalLength = result.reduce(function (sum, arr) { return sum + arr.length; }, 0);
var output = new Uint8Array(totalLength);
var offset = 0;
for (var _i = 0, result_1 = result; _i < result_1.length; _i++) {
var chunk = result_1[_i];
output.set(chunk, offset);
offset += chunk.length;
}
return output;
};
/**
* Decrypt data using CBC-like chaining with the provided IV.
*
* @private
* @param {Uint8Array} data - Encrypted bytes.
* @param {Uint8Array} [iv] - Initialization vector; must be `blockSize` bytes if provided.
* @returns {Uint8Array} Decrypted bytes (padding may be removed if valid).
*/
_CipherTwo.prototype._decrypt = function (data, iv) {
var result = [];
var previousBlock = iv;
for (var i = 0; i < data.length; i += this._blockSize) {
var block = data.subarray(i, i + this._blockSize);
var decryptedBlock = this._decryptBlock(block);
for (var j = 0; j < this._blockSize; j++) {
decryptedBlock[j] ^= previousBlock[j];
}
result.push(decryptedBlock);
previousBlock = block;
}
var totalLength = result.reduce(function (sum, arr) { return sum + arr.length; }, 0);
var decrypted = new Uint8Array(totalLength);
var offset = 0;
for (var _i = 0, result_2 = result; _i < result_2.length; _i++) {
var chunk = result_2[_i];
decrypted.set(chunk, offset);
offset += chunk.length;
}
var padLength = decrypted[decrypted.length - 1];
if (padLength > 0 && padLength <= this._blockSize) {
var isValidPadding = true;
for (var i = decrypted.length - padLength; i < decrypted.length; i++) {
if (decrypted[i] !== padLength) {
isValidPadding = false;
break;
}
}
if (isValidPadding) {
return decrypted.subarray(0, decrypted.length - padLength);
}
}
return decrypted;
};
return _CipherTwo;
}(_Cipher));
export { _CipherTwo };