283 lines
8.6 KiB
JavaScript
283 lines
8.6 KiB
JavaScript
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2024
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
(function(window, undefined) {
|
|
|
|
function CHashWorker(message, callback)
|
|
{
|
|
this.message = message;
|
|
this.callback = callback;
|
|
|
|
this.useWasm = false;
|
|
var webAsmObj = window["WebAssembly"];
|
|
if (typeof webAsmObj === "object")
|
|
{
|
|
if (typeof webAsmObj["Memory"] === "function")
|
|
{
|
|
if ((typeof webAsmObj["instantiateStreaming"] === "function") || (typeof webAsmObj["instantiate"] === "function"))
|
|
this.useWasm = true;
|
|
}
|
|
}
|
|
|
|
this.enginePath = "./../../../../sdkjs/common/hash/hash/";
|
|
this.worker = null;
|
|
|
|
this.stop = function()
|
|
{
|
|
if (!this.worker)
|
|
return;
|
|
|
|
try
|
|
{
|
|
if (this.worker.port)
|
|
this.worker.port.close();
|
|
else if (this.worker.terminate)
|
|
this.worker.terminate();
|
|
}
|
|
catch (err)
|
|
{
|
|
}
|
|
|
|
this.worker = null;
|
|
};
|
|
|
|
this.restart = function()
|
|
{
|
|
this.stop();
|
|
|
|
var worker_src = this.useWasm ? "engine.js" : "engine_ie.js";
|
|
worker_src = this.enginePath + worker_src;
|
|
|
|
this.worker = new Worker(worker_src);
|
|
|
|
var _t = this;
|
|
|
|
// обрабатываем ошибку, чтобы он не влиял на работу редактора
|
|
// и если ошибка из wasm модуля - то просто попробуем js версию - и рестартанем
|
|
this.worker.onerror = function(e) {
|
|
|
|
e && e.preventDefault && e.preventDefault();
|
|
e && e.stopPropagation && e.stopPropagation();
|
|
|
|
if (_t.useWasm)
|
|
{
|
|
_t.useWasm = false;
|
|
_t.restart();
|
|
}
|
|
};
|
|
|
|
this._start(this.worker);
|
|
};
|
|
|
|
this.oncommand = function(message)
|
|
{
|
|
if (message && message["hashValue"] !== undefined)
|
|
{
|
|
if (this.callback)
|
|
this.callback.call(window, message["hashValue"]);
|
|
this.stop();
|
|
}
|
|
};
|
|
|
|
this._start = function(_port)
|
|
{
|
|
var _worker = this;
|
|
|
|
_port.onmessage = function(message) {
|
|
_worker.oncommand && _worker.oncommand(message.data);
|
|
};
|
|
_port.postMessage({ "type" : "hash", "value" : this.message });
|
|
};
|
|
|
|
this.restart();
|
|
}
|
|
|
|
var currentHashWorker = null;
|
|
|
|
window['AscCommon'] = window['AscCommon'] || {};
|
|
var AscCommon = window['AscCommon'];
|
|
|
|
window['AscCommon'].calculateProtectHash = function(args, callback) {
|
|
if (window["NATIVE_EDITOR_ENJINE"])
|
|
{
|
|
if (!AscCommon.hashEngine) {
|
|
/** @suppress {checkVars} */
|
|
AscCommon.hashEngine = CreateEmbedObject("CHashEmbed");
|
|
}
|
|
|
|
let retArray = [];
|
|
for (var i = 0, len = args.length; i < len; i++)
|
|
{
|
|
retArray.push(AscCommon.Base64.encode(AscCommon.hashEngine["hash2"](args[i].password, args[i].salt, args[i].spinCount, args[i].alg)));
|
|
}
|
|
|
|
callback(retArray);
|
|
return;
|
|
}
|
|
|
|
var sendedData = [];
|
|
for (var i = 0, len = args.length; i < len; i++)
|
|
{
|
|
sendedData.push({
|
|
"password" : args[i].password,
|
|
"salt" : args[i].salt,
|
|
"spinCount" : args[i].spinCount,
|
|
"alg" : args[i].alg
|
|
});
|
|
}
|
|
|
|
currentHashWorker = new CHashWorker(sendedData, callback);
|
|
};
|
|
|
|
window['AscCommon'].prepareWordPassword = function(password) {
|
|
|
|
let _highOrderWords = [[0xE1, 0xF0], [0x1D, 0x0F], [0xCC, 0x9C], [0x84, 0xC0], [0x11, 0x0C], [0x0E, 0x10], [0xF1, 0xCE], [0x31, 0x3E], [0x18, 0x72], [0xE1, 0x39],
|
|
[0xD4, 0x0F], [0x84, 0xF9], [0x28, 0x0C], [0xA9, 0x6A], [0x4E, 0xC3]];
|
|
|
|
let _encryptionMatrix = [[[0xAE, 0xFC], [0x4D, 0xD9], [0x9B, 0xB2], [0x27, 0x45], [0x4E, 0x8A], [0x9D, 0x14], [0x2A, 0x09]],
|
|
[[0x7B, 0x61], [0xF6, 0xC2], [0xFD, 0xA5], [0xEB, 0x6B], [0xC6, 0xF7], [0x9D, 0xCF], [0x2B, 0xBF]],
|
|
[[0x45, 0x63], [0x8A, 0xC6], [0x05, 0xAD], [0x0B, 0x5A], [0x16, 0xB4], [0x2D, 0x68], [0x5A, 0xD0]],
|
|
[[0x03, 0x75], [0x06, 0xEA], [0x0D, 0xD4], [0x1B, 0xA8], [0x37, 0x50], [0x6E, 0xA0], [0xDD, 0x40]],
|
|
[[0xD8, 0x49], [0xA0, 0xB3], [0x51, 0x47], [0xA2, 0x8E], [0x55, 0x3D], [0xAA, 0x7A], [0x44, 0xD5]],
|
|
[[0x6F, 0x45], [0xDE, 0x8A], [0xAD, 0x35], [0x4A, 0x4B], [0x94, 0x96], [0x39, 0x0D], [0x72, 0x1A]],
|
|
[[0xEB, 0x23], [0xC6, 0x67], [0x9C, 0xEF], [0x29, 0xFF], [0x53, 0xFE], [0xA7, 0xFC], [0x5F, 0xD9]],
|
|
[[0x47, 0xD3], [0x8F, 0xA6], [0x0F, 0x6D], [0x1E, 0xDA], [0x3D, 0xB4], [0x7B, 0x68], [0xF6, 0xD0]],
|
|
[[0xB8, 0x61], [0x60, 0xE3], [0xC1, 0xC6], [0x93, 0xAD], [0x37, 0x7B], [0x6E, 0xF6], [0xDD, 0xEC]],
|
|
[[0x45, 0xA0], [0x8B, 0x40], [0x06, 0xA1], [0x0D, 0x42], [0x1A, 0x84], [0x35, 0x08], [0x6A, 0x10]],
|
|
[[0xAA, 0x51], [0x44, 0x83], [0x89, 0x06], [0x02, 0x2D], [0x04, 0x5A], [0x08, 0xB4], [0x11, 0x68]],
|
|
[[0x76, 0xB4], [0xED, 0x68], [0xCA, 0xF1], [0x85, 0xC3], [0x1B, 0xA7], [0x37, 0x4E], [0x6E, 0x9C]],
|
|
[[0x37, 0x30], [0x6E, 0x60], [0xDC, 0xC0], [0xA9, 0xA1], [0x43, 0x63], [0x86, 0xC6], [0x1D, 0xAD]],
|
|
[[0x33, 0x31], [0x66, 0x62], [0xCC, 0xC4], [0x89, 0xA9], [0x03, 0x73], [0x06, 0xE6], [0x0D, 0xCC]],
|
|
[[0x10, 0x21], [0x20, 0x42], [0x40, 0x84], [0x81, 0x08], [0x12, 0x31], [0x24, 0x62], [0x48, 0xC4]]];
|
|
|
|
let byteToBits = function (byte) {
|
|
let bitsArr = [];
|
|
for (let i = 0; i < 8; i++) {
|
|
let bit = byte & (1 << i) ? 1 : 0;
|
|
bitsArr.push(bit);
|
|
}
|
|
return bitsArr;
|
|
};
|
|
|
|
let splitByHighLowBytes = function (val) {
|
|
return [(val & 0xff00) >> 8, val & 0x00ff];
|
|
};
|
|
|
|
let getHexStr = function (arr) {
|
|
let res = "";
|
|
for (let i = 0; i < arr.length; i++) {
|
|
res += AscCommon.ByteToHex(arr[i]);
|
|
}
|
|
return res;
|
|
};
|
|
|
|
let getUnionBytes = function (byte1, byte2) {
|
|
return ((byte1 << 8) | byte2);
|
|
};
|
|
|
|
if (password == null) {
|
|
return null;
|
|
}
|
|
|
|
let passwordBytes = AscCommon.Utf8.encode(password);
|
|
|
|
let maxPasswordLength = 15;
|
|
passwordBytes = passwordBytes.slice(0, maxPasswordLength);
|
|
let passwordLength = passwordBytes.length;
|
|
|
|
//high word
|
|
let highOrderWord = [0x00, 0x00];
|
|
if (passwordLength > 0) {
|
|
highOrderWord = _highOrderWords[passwordLength - 1];
|
|
}
|
|
for (var i = 0; i < passwordLength; i++) {
|
|
let passwordByte = passwordBytes[i];
|
|
let encryptionMatrixIndex = i + (_encryptionMatrix.length - passwordLength);
|
|
|
|
let bitArray = byteToBits(passwordByte);
|
|
|
|
for (let j = 0; j < _encryptionMatrix[0].length; j++) {
|
|
let isSet = bitArray[j];
|
|
|
|
if (isSet) {
|
|
for (let k = 0; k < _encryptionMatrix[0][0].length; k++) {
|
|
highOrderWord[k] = highOrderWord[k] ^ _encryptionMatrix[encryptionMatrixIndex][j][k];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!highOrderWord) {
|
|
return null;
|
|
}
|
|
|
|
//low word
|
|
let lowOrderSequence = 0x00;
|
|
let sequence1 = 0x01;
|
|
let sequence7FFF = 0x7FFF;
|
|
for (let i = passwordLength - 1; i >= 0; i--) {
|
|
let passwordByte = passwordBytes[i];
|
|
lowOrderSequence = (((lowOrderSequence >> 14) & sequence1) | ((lowOrderSequence << 1) & sequence7FFF)) ^ passwordByte;
|
|
}
|
|
lowOrderSequence = (((lowOrderSequence >> 14) & sequence1) | ((lowOrderSequence << 1) & sequence7FFF)) ^ passwordLength ^ getUnionBytes(0xCE, 0x4B);
|
|
|
|
let lowOrderWord = splitByHighLowBytes(lowOrderSequence);
|
|
if (!lowOrderWord) {
|
|
return null;
|
|
}
|
|
|
|
//full word
|
|
let fullWord = highOrderWord.concat(lowOrderWord);
|
|
fullWord = fullWord && fullWord.reverse();
|
|
if (!fullWord) {
|
|
return null;
|
|
}
|
|
|
|
return getHexStr(fullWord);
|
|
};
|
|
|
|
window['AscCommon'].HashAlgs = {
|
|
MD2 : 0,
|
|
MD4 : 1,
|
|
MD5 : 2,
|
|
RMD160 : 3,
|
|
SHA1 : 4,
|
|
SHA256 : 5,
|
|
SHA384 : 6,
|
|
SHA512 : 7,
|
|
WHIRLPOOL : 8
|
|
};
|
|
|
|
})(window);
|