/** * @file GOST 34.10-2012 signature function with 1024/512 bits digest * @version 1.76 * @copyright 2014-2016, Rudolf Nickolaev. All rights reserved. */ /* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ import GostRandom from './gostRandom'; import GostCipher from './gostCipher'; import GostDigest from './gostDigest'; import GostSign from './gostSign'; /* * Engine definition base on normalized algorithm identifier * */ // var root = {}; // Define engine function defineEngine(method, algorithm) { if (!algorithm) throw new (root.SyntaxError || Error)('Algorithm not defined'); if (!algorithm.name) throw new (root.SyntaxError || Error)('Algorithm name not defined'); var name = algorithm.name, mode = algorithm.mode; if ((name === 'GOST 28147' || name === 'GOST R 34.12' || name === 'RC2') && (method === 'generateKey' || (mode === 'MAC' && (method === 'sign' || method === 'verify')) || ((mode === 'KW' || mode === 'MASK') && (method === 'wrapKey' || method === 'unwrapKey')) || ((!mode || mode === 'ES') && (method === 'encrypt' || method === 'decrypt')))) { return 'GostCipher'; } else if ((name === 'GOST R 34.11' || name === 'SHA') && (method === 'digest' || (mode === 'HMAC' && (method === 'sign' || method === 'verify' || method === 'generateKey')) || ((mode === 'KDF' || mode === 'PBKDF2' || mode === 'PFXKDF' || mode === 'CPKDF') && (method === 'deriveKey' || method === 'deriveBits' || method === 'generateKey')))) { return 'GostDigest'; } else if (name === 'GOST R 34.10' && (method === 'generateKey' || ((!mode || mode === 'SIGN') && (method === 'sign' || method === 'verify')) || (mode === 'MASK' && (method === 'wrapKey' || method === 'unwrapKey')) || (mode === 'DH' && (method === 'deriveKey' || method === 'deriveBits')))) { return 'GostSign'; } else throw new (root.NotSupportedError || Error)('Algorithm ' + name + '-' + mode + ' is not valid for ' + method); } // /** * Object implements dedicated Web Workers and provide a simple way to create * and run GOST cryptographic algorithms in background thread. * * Object provide interface to GOST low-level cryptogric classes: * * @namespace gostEngine */ var gostEngine = { /** * gostEngine.execute(algorithm, method, args) Entry point to execution * all low-level GOST cryptographic methods * * * * @memberOf gostEngine * @param {AlgorithmIndentifier} algorithm Algorithm identifier * @param {string} method Crypto method for execution * @param {Array} args Method arguments (keys, data, additional parameters) * @returns {(CryptoOperationData|Key|KeyPair|boolean)} Result of method execution */ execute: function (algorithm, method, args) // { // Define engine for GOST algorithms var engine = defineEngine(method, algorithm); // Create cipher var cipher = this['get' + engine](algorithm); // Execute method return cipher[method].apply(cipher, args); }, // /** * gostEngine.getGostCipher(algorithm) returns GOST 28147 / GOST R 34.12 cipher instance

* * GOST 28147-89 / GOST R 34.12-15 Encryption Algorithm

* When keys and initialization vectors are converted to/from byte arrays, * little-endian byte order is assumed.

* * Normalized algorithm identifier common parameters: * * * * Supported algorithms, modes and parameters: * * * * Supported paramters values: * * * * @memberOf gostEngine * @param {AlgorithmIndentifier} algorithm Algorithm identifier * @returns {GostCipher} Instance of GostCipher */ getGostCipher: function (algorithm) // { return new (GostCipher || (GostCipher = root.GostCipher))(algorithm); }, // /** * gostEngine.getGostDigest(algorithm) returns GOST R 34.11 cipher instance

* * Normalized algorithm identifier common parameters: * * * * Supported algorithms, modes and parameters: * * * * @memberOf gostEngine * @param {AlgorithmIndentifier} algorithm Algorithm identifier * @returns {GostDigest} Instance of GostDigest */ getGostDigest: function (algorithm) // { return new (GostDigest || (GostDigest = root.GostDigest))(algorithm); }, // /** * gostEngine.getGostSign(algorithm) returns GOST R 34.10 cipher instance

* * Normalized algorithm identifier common parameters: * * * * Supported algorithms, modes and parameters: * * * * @memberOf gostEngine * @param {AlgorithmIndentifier} algorithm Algorithm identifier * @returns {GostSign} Instance of GostSign */ getGostSign: function (algorithm) // { return new (GostSign || (GostSign = root.GostSign))(algorithm); } // }; /* * Worker method execution * */ // // Worker for gostCripto method execution if (root.importScripts) { /** * Method called when {@link SubtleCrypto} calls its own postMessage() * method with data parameter: algorithm, method and arg.
* Call method execute and postMessage() results to onmessage event handler * in the main process.
* If error occured onerror event handler executed in main process. * * @memberOf gostEngine * @name onmessage * @param {MessageEvent} event Message event with data {algorithm, method, args} */ root.onmessage = function (event) { try { postMessage({ id: event.data.id, result: gostEngine.execute(event.data.algorithm, event.data.method, event.data.args)}); } catch (e) { postMessage({ id: event.data.id, error: e.message }); } }; } else { // Load dependens var baseUrl = '', nameSuffix = ''; // Try to define from DOM model if (typeof document !== 'undefined') { (function () { var regs = /^(.*)gostCrypto(.*)\.js$/i; var list = document.querySelectorAll('script'); for (var i = 0, n = list.length; i < n; i++) { var value = list[i].getAttribute('src'); var test = regs.exec(value); if (test) { baseUrl = test[1]; nameSuffix = test[2]; } } })(); } // Local importScripts procedure for include dependens var importScripts = function () { for (var i = 0, n = arguments.length; i < n; i++) { var name = arguments[i].split('.'), src = baseUrl + name[0] + nameSuffix + '.' + name[1]; var el = document.querySelector('script[src="' + src + '"]'); if (!el) { el = document.createElement('script'); el.setAttribute('src', src); document.head.appendChild(el); } } }; // Import engines if (!GostRandom) importScripts('gostRandom.js'); if (!GostCipher) importScripts('gostCipher.js'); if (!GostDigest) importScripts('gostDigest.js'); if (!GostSign) importScripts('gostSign.js'); } //
export default gostEngine;