line_push/node_modules/js-crypto-aes/dist/webapi.js
2022-07-21 03:28:35 +00:00

501 lines
15 KiB
JavaScript

"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.decrypt = exports.encrypt = exports.unwrapKey = exports.wrapKey = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
/**
* webapi.js
*/
/**
* WebCrypto KeyWrapping function simply uses encrypt function.
* @param keyToBeWrapped {Uint8Array} - plaintext key
* @param wrappingKey {Uint8Array} - wrapping key
* @param name {string} - 'AES-KW'
* @param iv {Uint8Array} - default is '0xA6A6A6A6A6A6A6A6'
* @param nodeCrypto {Object} - crypto.subtle object
* @return {Uint8Array} - Unwrapped Key
*/
var wrapKey =
/*#__PURE__*/
function () {
var _ref2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee(keyToBeWrapped, wrappingKey, _ref, webCrypto) {
var _ref$name, name, iv, kek, cek, data;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_ref$name = _ref.name, name = _ref$name === void 0 ? 'AES-KW' : _ref$name, iv = _ref.iv;
if (!(typeof window.msCrypto === 'undefined')) {
_context.next = 20;
break;
}
_context.prev = 2;
_context.next = 5;
return webCrypto.importKey('raw', wrappingKey, {
name: name
}, false, ['wrapKey', 'unwrapKey']);
case 5:
kek = _context.sent;
_context.next = 8;
return webCrypto.importKey('raw', keyToBeWrapped, {
name: name
}, true, ['wrapKey', 'unwrapKey']);
case 8:
cek = _context.sent;
_context.next = 11;
return webCrypto.wrapKey('raw', cek, kek, {
name: name,
iv: iv
});
case 11:
data = _context.sent;
return _context.abrupt("return", new Uint8Array(data));
case 15:
_context.prev = 15;
_context.t0 = _context["catch"](2);
throw new Error("WebCrypto_FailedToWrapKey - ".concat(_context.t0.message));
case 18:
_context.next = 21;
break;
case 20:
throw new Error('ThrowAwayIeAsap');
case 21:
case "end":
return _context.stop();
}
}
}, _callee, null, [[2, 15]]);
}));
return function wrapKey(_x, _x2, _x3, _x4) {
return _ref2.apply(this, arguments);
};
}();
/**
* WebCrypto KeyUnwrapping function as well as keyWrapping
* @param wrappedKey {Uint8Array} - Wrapped key
* @param unwrappingKey {Uint8Array} - Key used for wrapping
* @param name {string} - 'AES-KW'
* @param iv {Uint8Array} - default is '0xA6A6A6A6A6A6A6A6'
* @param nodeCrypto {Object} - crypto.subtle object
* @return {Uint8Array} - Unwrapped Key
*/
exports.wrapKey = wrapKey;
var unwrapKey =
/*#__PURE__*/
function () {
var _ref4 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(wrappedKey, unwrappingKey, _ref3, webCrypto) {
var _ref3$name, name, iv, kek, cek;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_ref3$name = _ref3.name, name = _ref3$name === void 0 ? 'AES-KW' : _ref3$name, iv = _ref3.iv;
if (!(typeof window.msCrypto === 'undefined')) {
_context2.next = 21;
break;
}
_context2.prev = 2;
_context2.next = 5;
return webCrypto.importKey('raw', unwrappingKey, {
name: name
}, false, ['wrapKey', 'unwrapKey']);
case 5:
kek = _context2.sent;
_context2.next = 8;
return webCrypto.unwrapKey('raw', wrappedKey, kek, {
name: name,
iv: iv
}, {
name: 'AES-GCM'
}, true, ['encrypt', 'decrypt']);
case 8:
cek = _context2.sent;
_context2.t0 = Uint8Array;
_context2.next = 12;
return webCrypto.exportKey('raw', cek);
case 12:
_context2.t1 = _context2.sent;
return _context2.abrupt("return", new _context2.t0(_context2.t1));
case 16:
_context2.prev = 16;
_context2.t2 = _context2["catch"](2);
throw new Error("WebCrypto_FailedToUnwrapKey - ".concat(_context2.t2.message));
case 19:
_context2.next = 22;
break;
case 21:
throw new Error('ThrowAwayMsIeAsap');
case 22:
case "end":
return _context2.stop();
}
}
}, _callee2, null, [[2, 16]]);
}));
return function unwrapKey(_x5, _x6, _x7, _x8) {
return _ref4.apply(this, arguments);
};
}();
/**
* Encrypt data through AES of WebCrypto API.
* @param {Uint8Array} msg - Plaintext message to be encrypted.
* @param {Uint8Array} key - Byte array of symmetric key.
* @param {String} name - Name of AES algorithm like 'AES-GCM'.
* @param {Uint8Array} [iv] - Byte array of initial vector if required.
* @param {Uint8Array} [additionalData] - Byte array of additional data if required.
* @param {Number} [tagLength] - Authentication tag length if required.
* @param {Object} webCrypto - WebCrypto object, i.e., window.crypto.subtle or window.msCrypto.subtle
* @return {Promise<Uint8Array>} - Encrypted data byte array.
* @throws {Error} - Throws if UnsupportedCipher.
*/
exports.unwrapKey = unwrapKey;
var encrypt =
/*#__PURE__*/
function () {
var _ref6 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(msg, key, _ref5, webCrypto) {
var _ref5$name, name, iv, additionalData, tagLength, encryptionConfig, sessionKeyObj, data, _sessionKeyObj, encryptedObj, _data;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_ref5$name = _ref5.name, name = _ref5$name === void 0 ? 'AES-GCM' : _ref5$name, iv = _ref5.iv, additionalData = _ref5.additionalData, tagLength = _ref5.tagLength;
encryptionConfig = setCipherParams({
name: name,
iv: iv,
additionalData: additionalData,
tagLength: tagLength
});
if (!(typeof window.msCrypto === 'undefined')) {
_context3.next = 18;
break;
}
_context3.prev = 3;
_context3.next = 6;
return webCrypto.importKey('raw', key, encryptionConfig, false, ['encrypt', 'decrypt']);
case 6:
sessionKeyObj = _context3.sent;
_context3.next = 9;
return webCrypto.encrypt(encryptionConfig, sessionKeyObj, msg);
case 9:
data = _context3.sent;
return _context3.abrupt("return", new Uint8Array(data));
case 13:
_context3.prev = 13;
_context3.t0 = _context3["catch"](3);
throw new Error("WebCrypto_EncryptionFailure: ".concat(_context3.t0.message));
case 16:
_context3.next = 38;
break;
case 18:
_context3.prev = 18;
_context3.next = 21;
return msImportKey('raw', key, encryptionConfig, false, ['encrypt', 'decrypt'], webCrypto);
case 21:
_sessionKeyObj = _context3.sent;
_context3.next = 24;
return msEncrypt(encryptionConfig, _sessionKeyObj, msg, webCrypto);
case 24:
encryptedObj = _context3.sent;
if (!(name === 'AES-GCM')) {
_context3.next = 32;
break;
}
_data = new Uint8Array(encryptedObj.ciphertext.byteLength + encryptedObj.tag.byteLength);
_data.set(new Uint8Array(encryptedObj.ciphertext));
_data.set(new Uint8Array(encryptedObj.tag), encryptedObj.ciphertext.byteLength);
return _context3.abrupt("return", _data);
case 32:
return _context3.abrupt("return", new Uint8Array(encryptedObj));
case 33:
_context3.next = 38;
break;
case 35:
_context3.prev = 35;
_context3.t1 = _context3["catch"](18);
throw new Error("ThrowAwayMsIeAsap: ".concat(_context3.t1.message));
case 38:
case "end":
return _context3.stop();
}
}
}, _callee3, null, [[3, 13], [18, 35]]);
}));
return function encrypt(_x9, _x10, _x11, _x12) {
return _ref6.apply(this, arguments);
};
}();
/**
* Decrypt data through AES of WebCrypto API.
* @param {Uint8Array} data - Encrypted message to be decrypted.
* @param {Uint8Array} key - Byte array of symmetric key.
* @param {String} name - Name of AES algorithm like 'AES-GCM'.
* @param {Uint8Array} [iv] - Byte array of initial vector if required.
* @param {Uint8Array} [additionalData] - Byte array of additional data if required.
* @param {Number} [tagLength] - Authentication tag length if required.
* @param {Object} webCrypto - WebCrypto object, i.e., window.crypto.subtle or window.msCrypto.subtle
* @return {Promise<Uint8Array>} - Decrypted plaintext message.
* @throws {Error} - Throws if UnsupportedCipher or DecryptionFailure.
*/
exports.encrypt = encrypt;
var decrypt =
/*#__PURE__*/
function () {
var _ref8 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4(data, key, _ref7, webCrypto) {
var name, iv, additionalData, tagLength, decryptionConfig, sessionKeyObj, msg, _sessionKeyObj2, _msg, ciphertext, tag;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
name = _ref7.name, iv = _ref7.iv, additionalData = _ref7.additionalData, tagLength = _ref7.tagLength;
decryptionConfig = setCipherParams({
name: name,
iv: iv,
additionalData: additionalData,
tagLength: tagLength
});
if (window.msCrypto) {
_context4.next = 18;
break;
}
_context4.prev = 3;
_context4.next = 6;
return webCrypto.importKey('raw', key, decryptionConfig, false, ['encrypt', 'decrypt']);
case 6:
sessionKeyObj = _context4.sent;
_context4.next = 9;
return webCrypto.decrypt(decryptionConfig, sessionKeyObj, data);
case 9:
msg = _context4.sent;
return _context4.abrupt("return", new Uint8Array(msg));
case 13:
_context4.prev = 13;
_context4.t0 = _context4["catch"](3);
throw new Error("WebCrypto_DecryptionFailure: ".concat(_context4.t0.message));
case 16:
_context4.next = 39;
break;
case 18:
_context4.prev = 18;
_context4.next = 21;
return msImportKey('raw', key, decryptionConfig, false, ['encrypt', 'decrypt'], webCrypto);
case 21:
_sessionKeyObj2 = _context4.sent;
if (!(name === 'AES-GCM')) {
_context4.next = 30;
break;
}
ciphertext = data.slice(0, data.length - tagLength);
tag = data.slice(data.length - tagLength, data.length);
_context4.next = 27;
return msDecrypt(Object.assign(decryptionConfig, {
tag: tag
}), _sessionKeyObj2, ciphertext, webCrypto);
case 27:
_msg = _context4.sent;
_context4.next = 33;
break;
case 30:
_context4.next = 32;
return msDecrypt(decryptionConfig, _sessionKeyObj2, data, webCrypto);
case 32:
_msg = _context4.sent;
case 33:
return _context4.abrupt("return", new Uint8Array(_msg));
case 36:
_context4.prev = 36;
_context4.t1 = _context4["catch"](18);
throw new Error("ThrowAwayMsIeAsap: ".concat(_context4.t1.message));
case 39:
case "end":
return _context4.stop();
}
}
}, _callee4, null, [[3, 13], [18, 36]]);
}));
return function decrypt(_x13, _x14, _x15, _x16) {
return _ref8.apply(this, arguments);
};
}();
/**
* Set params for encryption algorithms.
* @param {String} name - Name of AES algorithm like 'AES-GCM'.
* @param {Uint8Array} [iv] - Byte array of initial vector if required.
* @param {Uint8Array} [additionalData] - Byte array of additional data if required.
* @param {Number} [tagLength] - Authentication tag length if required.
*/
exports.decrypt = decrypt;
var setCipherParams = function setCipherParams(_ref9) {
var name = _ref9.name,
iv = _ref9.iv,
additionalData = _ref9.additionalData,
tagLength = _ref9.tagLength;
var alg = {};
switch (name) {
case 'AES-GCM':
{
Object.assign(alg, {
name: name,
iv: iv,
tagLength: tagLength * 8
});
Object.assign(alg, additionalData.length > 0 ? {
additionalData: additionalData
} : {});
break;
}
case 'AES-CBC':
{
alg.name = name;
alg.iv = iv;
break;
}
case 'AES-CTR':
{
if (iv.length === 0 || iv.length > 16) throw new Error('InvalidIVLength');
alg.name = name;
alg.counter = new Uint8Array(16);
alg.counter.set(iv);
alg.counter[15] += 1;
alg.length = 128; // todo: this might be (16 - iv.length) * 8.
break;
}
}
return alg;
}; // function definitions for IE
var msImportKey = function msImportKey(type, key, alg, ext, use, webCrypto) {
return new Promise(function (resolve, reject) {
var op = webCrypto.importKey(type, key, alg, ext, use);
op.oncomplete = function (evt) {
resolve(evt.target.result);
};
op.onerror = function () {
reject('KeyImportingFailed');
};
});
};
var msEncrypt = function msEncrypt(alg, key, msg, webCrypto) {
return new Promise(function (resolve, reject) {
var op = webCrypto.encrypt(alg, key, msg);
op.oncomplete = function (evt) {
resolve(evt.target.result);
};
op.onerror = function () {
reject('EncryptionFailure');
};
});
};
var msDecrypt = function msDecrypt(alg, key, data, webCrypto) {
return new Promise(function (resolve, reject) {
var op = webCrypto.decrypt(alg, key, data);
op.oncomplete = function (evt) {
resolve(evt.target.result);
};
op.onerror = function () {
reject('DecryptionFailure');
};
});
};