"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.deriveSecret = exports.verify = exports.sign = exports.generateKey = 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 webapi = _interopRequireWildcard(require("./webapi.js")); var nodeapi = _interopRequireWildcard(require("./nodeapi.js")); var purejs = _interopRequireWildcard(require("./purejs.js")); /** * ec.js */ /** * Generate elliptic curve cryptography public/private key pair. Generated keys are in JWK. * @param {String} [namedCurve='P-256'] - Name of curve like 'P-256'. * @return {Promise<{publicKey: JsonWebKey, privateKey: JsonWebKey }>} - The generated keys. * @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works. */ var generateKey = /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee() { var namedCurve, webCrypto, nodeCrypto, native, errMsg, keyPair, _args = arguments; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: namedCurve = _args.length > 0 && _args[0] !== undefined ? _args[0] : 'P-256'; webCrypto = util.getWebCrypto(); // web crypto api nodeCrypto = util.getNodeCrypto(); // implementation on node.js native = true; keyPair = {}; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.generateKey === 'function' && typeof webCrypto.exportKey === 'function')) { _context.next = 11; break; } _context.next = 8; return webapi.generateKey(namedCurve, webCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 8: keyPair = _context.sent; _context.next = 18; break; case 11: if (!(typeof nodeCrypto !== 'undefined')) { _context.next = 17; break; } _context.next = 14; return nodeapi.generateKey(namedCurve, nodeCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 14: keyPair = _context.sent; _context.next = 18; break; case 17: native = false; case 18: if (!(native === false)) { _context.next = 22; break; } _context.next = 21; return purejs.generateKey(namedCurve).catch(function (e) { errMsg = "".concat(errMsg, " => ").concat(e.message); throw new Error("UnsupportedEnvironment: ".concat(errMsg)); }); case 21: keyPair = _context.sent; case 22: return _context.abrupt("return", keyPair); case 23: case "end": return _context.stop(); } } }, _callee); })); return function generateKey() { return _ref.apply(this, arguments); }; }(); /** * Sign message with ECDSA. * @param {Uint8Array} msg - Byte array of message to be signed. * @param {JsonWebKey} privateJwk - Private key object in JWK format. * @param {String} [hash='SHA-256'] - Name of hash algorithm used in singing, like 'SHA-256'. * @param {String} [signatureFormat='raw'] - Signature format. 'raw' indicates the purely raw byte array of signature. It can also take 'der', and then the output is ASN.1 DER formatted. * @return {Promise} - Output signature byte array in raw or der format. * @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works. */ exports.generateKey = generateKey; var sign = /*#__PURE__*/ function () { var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee2(msg, privateJwk) { var hash, signatureFormat, webCrypto, nodeCrypto, native, errMsg, signature, _args2 = arguments; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: hash = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : 'SHA-256'; signatureFormat = _args2.length > 3 && _args2[3] !== undefined ? _args2[3] : 'raw'; if (!(signatureFormat !== 'raw' && signatureFormat !== 'der')) { _context2.next = 4; break; } throw new Error('InvalidSignatureFormat'); case 4: webCrypto = util.getWebCrypto(); // web crypto api nodeCrypto = util.getNodeCrypto(); // implementation on node.js native = true; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.sign === 'function')) { _context2.next = 13; break; } _context2.next = 10; return webapi.sign(msg, privateJwk, hash, signatureFormat, webCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 10: signature = _context2.sent; _context2.next = 20; break; case 13: if (!(typeof nodeCrypto !== 'undefined')) { _context2.next = 19; break; } _context2.next = 16; return nodeapi.sign(msg, privateJwk, hash, signatureFormat, nodeCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 16: signature = _context2.sent; _context2.next = 20; break; case 19: native = false; case 20: if (!(native === false)) { _context2.next = 24; break; } _context2.next = 23; return purejs.sign(msg, privateJwk, hash, signatureFormat).catch(function (e) { errMsg = "".concat(errMsg, " => ").concat(e.message); throw new Error("UnsupportedEnvironment: ".concat(errMsg)); }); case 23: signature = _context2.sent; case 24: return _context2.abrupt("return", signature); case 25: case "end": return _context2.stop(); } } }, _callee2); })); return function sign(_x, _x2) { return _ref2.apply(this, arguments); }; }(); /** * Verify signature with ECDSA. * @param {Uint8Array} msg - Byte array of message that have been signed. * @param {Uint8Array} signature - Byte array of signature for the given message. * @param {JsonWebKey} publicJwk - Public key object in JWK format. * @param {String} [hash='SHA-256'] - Name of hash algorithm used in singing, like 'SHA-256'. * @param {String} [signatureFormat='raw'] - Signature format. 'raw' indicates the purely raw byte array of signature. It can also take 'der', and then the input must be in ASN.1 DER format. * @return {Promise} - The result of verification. * @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works. */ exports.sign = sign; var verify = /*#__PURE__*/ function () { var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee3(msg, signature, publicJwk) { var hash, signatureFormat, webCrypto, nodeCrypto, native, errMsg, valid, _args3 = arguments; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: hash = _args3.length > 3 && _args3[3] !== undefined ? _args3[3] : 'SHA-256'; signatureFormat = _args3.length > 4 && _args3[4] !== undefined ? _args3[4] : 'raw'; if (!(signatureFormat !== 'raw' && signatureFormat !== 'der')) { _context3.next = 4; break; } throw new Error('InvalidSignatureFormat'); case 4: webCrypto = util.getWebCrypto(); // web crypto api nodeCrypto = util.getNodeCrypto(); // implementation on node.js native = true; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.verify === 'function')) { _context3.next = 13; break; } _context3.next = 10; return webapi.verify(msg, signature, publicJwk, hash, signatureFormat, webCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 10: valid = _context3.sent; _context3.next = 20; break; case 13: if (!(typeof nodeCrypto !== 'undefined')) { _context3.next = 19; break; } _context3.next = 16; return nodeapi.verify(msg, signature, publicJwk, hash, signatureFormat, nodeCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 16: valid = _context3.sent; _context3.next = 20; break; case 19: native = false; case 20: if (!(native === false)) { _context3.next = 24; break; } _context3.next = 23; return purejs.verify(msg, signature, publicJwk, hash, signatureFormat).catch(function (e) { errMsg = "".concat(errMsg, " => ").concat(e.message); throw new Error("UnsupportedEnvironment: ".concat(errMsg)); }); case 23: valid = _context3.sent; case 24: return _context3.abrupt("return", valid); case 25: case "end": return _context3.stop(); } } }, _callee3); })); return function verify(_x3, _x4, _x5) { return _ref3.apply(this, arguments); }; }(); /** * ECDH: Elliptic Curve Diffie-Hellman Key Exchange, which derives shared secret from my private key and destination's public key. * **NOTE** We SHOULD NOT use the derived secret as an encryption key directly. * We should employ an appropriate key derivation procedure like HKDF to use the secret for symmetric key encryption. * @param {JsonWebKey} publicJwk - Remote public key object in JWK format. * @param {JsonWebKey} privateJwk - Local (my) private key object in JWK format. * @return {Promise} - The derived master secret via ECDH. * @throws {Error} - Throws if UnsupportedEnvironment, i.e., neither WebCrypto, NodeCrypto, nor PureJS codes works. */ exports.verify = verify; var deriveSecret = /*#__PURE__*/ function () { var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee4(publicJwk, privateJwk) { var webCrypto, nodeCrypto, native, errMsg, secret; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: if (!(publicJwk.crv !== privateJwk.crv)) { _context4.next = 2; break; } throw new Error('UnmatchedCurveName'); case 2: webCrypto = util.getWebCrypto(); // web crypto api nodeCrypto = util.getNodeCrypto(); // implementation on node.js native = true; if (!(typeof webCrypto !== 'undefined' && typeof webCrypto.importKey === 'function' && typeof webCrypto.deriveBits === 'function')) { _context4.next = 11; break; } _context4.next = 8; return webapi.deriveSecret(publicJwk, privateJwk, webCrypto).catch(function (e) { errMsg = e.message; native = false; }); case 8: secret = _context4.sent; _context4.next = 12; break; case 11: if (typeof nodeCrypto !== 'undefined') { // for node try { secret = nodeapi.deriveSecret(publicJwk, privateJwk, nodeCrypto); } catch (e) { errMsg = e.message; native = false; } } else native = false; case 12: if (!(native === false)) { _context4.next = 23; break; } _context4.prev = 13; _context4.next = 16; return purejs.deriveSecret(publicJwk, privateJwk); case 16: secret = _context4.sent; _context4.next = 23; break; case 19: _context4.prev = 19; _context4.t0 = _context4["catch"](13); errMsg = "".concat(errMsg, " => ").concat(_context4.t0.message); throw new Error("UnsupportedEnvironment: ".concat(errMsg)); case 23: return _context4.abrupt("return", secret); case 24: case "end": return _context4.stop(); } } }, _callee4, null, [[13, 19]]); })); return function deriveSecret(_x6, _x7) { return _ref4.apply(this, arguments); }; }(); exports.deriveSecret = deriveSecret;