"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.unwrapKey = exports.wrapKey = exports.decrypt = exports.encrypt = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var util = _interopRequireWildcard(require("js-crypto-env")); var nodeapi = _interopRequireWildcard(require("./nodeapi.js")); var webapi = _interopRequireWildcard(require("./webapi.js")); var _params = _interopRequireDefault(require("./params.js")); /** * aes.js */ /** * Check if the given algorithm spec is valid. * @param {String} name - Name of the specified algorithm like 'AES-GCM'. * @param {Uint8Array} iv - IV byte array if required * @param {Number} tagLength - Authentication tag length if required * @throws {Error} - Throws if UnsupportedAlgorithm, InvalidArguments, InvalidIVLength, or InvalidTagLength. */ var assertAlgorithms = function assertAlgorithms(_ref) { var name = _ref.name, iv = _ref.iv, tagLength = _ref.tagLength; if (Object.keys(_params.default.ciphers).indexOf(name) < 0) throw new Error('UnsupportedAlgorithm'); if (_params.default.ciphers[name].ivLength) { if (!(iv instanceof Uint8Array)) throw new Error('InvalidArguments'); if (iv.byteLength < 2 || iv.byteLength > 16) throw new Error('InvalidIVLength'); if (_params.default.ciphers[name].staticIvLength && _params.default.ciphers[name].ivLength !== iv.byteLength) throw new Error('InvalidIVLength'); } if (_params.default.ciphers[name].tagLength && tagLength) { if (!Number.isInteger(tagLength)) throw new Error('InvalidArguments'); if (tagLength < 4 || tagLength > 16) throw new Error('InvalidTagLength'); } }; /** * Encrypt data with AES * @param {Uint8Array} msg - Message to be encrypted. * @param {Uint8Array} key - The symmetric key used to encrypt the message. * @param {String} [name = 'AES-GCM'] - Name of the specified algorithm like 'AES-GCM'. * @param {Uint8Array} [iv] - Byte array of the initial vector if required. * @param {Uint8Array} [additionalData = new Uint8Array([])] - Byte array of additional data if required. * @param {Number} [tagLength = params.ciphers[name].tagLength] - Authentication tag length if required. * @return {Promise} - Encrypted message. * @throws {Error} - Throws if InvalidArguments, FaildToEncryptWeb/Node, or UnsupportedEnvironment (no webcrypto/nodecrypto). */ var encrypt = /*#__PURE__*/ function () { var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee(msg, key, _ref2) { var _ref2$name, name, iv, _ref2$additionalData, additionalData, tagLength, webCrypto, nodeCrypto; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _ref2$name = _ref2.name, name = _ref2$name === void 0 ? 'AES-GCM' : _ref2$name, iv = _ref2.iv, _ref2$additionalData = _ref2.additionalData, additionalData = _ref2$additionalData === void 0 ? new Uint8Array([]) : _ref2$additionalData, tagLength = _ref2.tagLength; if (!(!(msg instanceof Uint8Array) || !(key instanceof Uint8Array))) { _context.next = 3; break; } throw new Error('InvalidArguments'); case 3: assertAlgorithms({ name: name, iv: iv, tagLength: tagLength }); if (_params.default.ciphers[name].tagLength && !tagLength) tagLength = _params.default.ciphers[name].tagLength; _context.next = 7; return util.getWebCryptoAll(); case 7: webCrypto = _context.sent; _context.next = 10; return util.getNodeCrypto(); case 10: nodeCrypto = _context.sent; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.encrypt === 'function')) { _context.next = 15; break; } return _context.abrupt("return", webapi.encrypt(msg, key, { name: name, iv: iv, additionalData: additionalData, tagLength: tagLength }, webCrypto)); case 15: if (!(typeof nodeCrypto !== 'undefined')) { _context.next = 19; break; } return _context.abrupt("return", nodeapi.encrypt(msg, key, { name: name, iv: iv, additionalData: additionalData, tagLength: tagLength }, nodeCrypto)); case 19: throw new Error('UnsupportedEnvironment'); case 20: case "end": return _context.stop(); } } }, _callee); })); return function encrypt(_x, _x2, _x3) { return _ref3.apply(this, arguments); }; }(); /** * Decrypt data with AES * @param {Uint8Array} data - Byte array of encrypted data. * @param {Uint8Array} key - Byte array of symmetric key to be used for decryption. * @param {String} [name = 'AES-GCM'] - Name of the specified algorithm like 'AES-GCM'. * @param {Uint8Array} [iv] - Byte array of the initial vector if required. * @param {Uint8Array} [additionalData = new Uint8Array([])] - Byte array of additional data if required. * @param {Number} [tagLength = params.ciphers[name].tagLength] - Authentication tag length if required. * @return {Promise} - Decrypted plaintext message. * @throws {Error} - Throws if InvalidArguments, FailedToDecryptWeb/Node, or UnsupportedEnvironment (no webcrypto/nodecrypto). */ exports.encrypt = encrypt; var decrypt = /*#__PURE__*/ function () { var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee2(data, key, _ref4) { var _ref4$name, name, iv, _ref4$additionalData, additionalData, tagLength, webCrypto, nodeCrypto; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _ref4$name = _ref4.name, name = _ref4$name === void 0 ? 'AES-GCM' : _ref4$name, iv = _ref4.iv, _ref4$additionalData = _ref4.additionalData, additionalData = _ref4$additionalData === void 0 ? new Uint8Array([]) : _ref4$additionalData, tagLength = _ref4.tagLength; if (!(!(data instanceof Uint8Array) || !(key instanceof Uint8Array))) { _context2.next = 3; break; } throw new Error('InvalidArguments'); case 3: assertAlgorithms({ name: name, iv: iv, tagLength: tagLength }); if (_params.default.ciphers[name].tagLength && !tagLength) tagLength = _params.default.ciphers[name].tagLength; _context2.next = 7; return util.getWebCryptoAll(); case 7: webCrypto = _context2.sent; _context2.next = 10; return util.getNodeCrypto(); case 10: nodeCrypto = _context2.sent; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.encrypt === 'function')) { _context2.next = 15; break; } return _context2.abrupt("return", webapi.decrypt(data, key, { name: name, iv: iv, additionalData: additionalData, tagLength: tagLength }, webCrypto)); case 15: if (!(typeof nodeCrypto !== 'undefined')) { _context2.next = 19; break; } return _context2.abrupt("return", nodeapi.decrypt(data, key, { name: name, iv: iv, additionalData: additionalData, tagLength: tagLength }, nodeCrypto)); case 19: throw new Error('UnsupportedEnvironment'); case 20: case "end": return _context2.stop(); } } }, _callee2); })); return function decrypt(_x4, _x5, _x6) { return _ref5.apply(this, arguments); }; }(); /** * AES-KW wrapping * @param keyToBeWrapped {Uint8Array} - key bytes to be wrapped * @param wrappingKey {Uint8Array} - wrapping key encryption key * @param name {'AES-KW'} - this is simply for future extension * @return {Promise} - output wrapped key */ exports.decrypt = decrypt; var wrapKey = /*#__PURE__*/ function () { var _ref7 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee3(keyToBeWrapped, wrappingKey, _ref6) { var _ref6$name, name, webCrypto, nodeCrypto, iv; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _ref6$name = _ref6.name, name = _ref6$name === void 0 ? 'AES-KW' : _ref6$name; if (keyToBeWrapped instanceof Uint8Array) { _context3.next = 3; break; } throw new Error('NonUint8ArrayData'); case 3: if (wrappingKey instanceof Uint8Array) { _context3.next = 5; break; } throw new Error('NonUint8ArrayKey'); case 5: if (!(keyToBeWrapped.length % 8 > 0)) { _context3.next = 7; break; } throw new Error('WrappedKeyMustBeMultipleOf8'); case 7: _context3.next = 9; return util.getWebCryptoAll(); case 9: webCrypto = _context3.sent; _context3.next = 12; return util.getNodeCrypto(); case 12: nodeCrypto = _context3.sent; // node crypto iv = _params.default.wrapKeys['AES-KW'].defaultIV; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.wrapKey === 'function')) { _context3.next = 18; break; } return _context3.abrupt("return", webapi.wrapKey(keyToBeWrapped, wrappingKey, { name: name, iv: iv }, webCrypto)); case 18: if (!(typeof nodeCrypto !== 'undefined')) { _context3.next = 22; break; } return _context3.abrupt("return", nodeapi.wrapKey(keyToBeWrapped, wrappingKey, { name: name, iv: iv }, nodeCrypto)); case 22: throw new Error('UnsupportedEnvironment'); case 23: case "end": return _context3.stop(); } } }, _callee3); })); return function wrapKey(_x7, _x8, _x9) { return _ref7.apply(this, arguments); }; }(); /** * AES-KW unwrapping * @param wrappedKey {Uint8Array} - wrapped key bytes * @param wrappingKey {Uint8Array} - wrapping key encryption key * @param name {'AES-KW'} - this is simply for future extension * @return {Promise} - output unwrapped key */ exports.wrapKey = wrapKey; var unwrapKey = /*#__PURE__*/ function () { var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee4(wrappedKey, wrappingKey, _ref8) { var _ref8$name, name, webCrypto, nodeCrypto, iv; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _ref8$name = _ref8.name, name = _ref8$name === void 0 ? 'AES-KW' : _ref8$name; if (wrappedKey instanceof Uint8Array) { _context4.next = 3; break; } throw new Error('NonUint8ArrayData'); case 3: if (wrappingKey instanceof Uint8Array) { _context4.next = 5; break; } throw new Error('NonUint8ArrayKey'); case 5: _context4.next = 7; return util.getWebCryptoAll(); case 7: webCrypto = _context4.sent; _context4.next = 10; return util.getNodeCrypto(); case 10: nodeCrypto = _context4.sent; // node crypto iv = _params.default.wrapKeys['AES-KW'].defaultIV; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.wrapKey === 'function')) { _context4.next = 16; break; } return _context4.abrupt("return", webapi.unwrapKey(wrappedKey, wrappingKey, { name: name, iv: iv }, webCrypto)); case 16: if (!(typeof nodeCrypto !== 'undefined')) { _context4.next = 20; break; } return _context4.abrupt("return", nodeapi.unwrapKey(wrappedKey, wrappingKey, { name: name, iv: iv }, nodeCrypto)); case 20: throw new Error('UnsupportedEnvironment'); case 21: case "end": return _context4.stop(); } } }, _callee4); })); return function unwrapKey(_x10, _x11, _x12) { return _ref9.apply(this, arguments); }; }(); exports.unwrapKey = unwrapKey;