Socket
Socket
Sign inDemoInstall

ethers-gcp-kms-signer

Package Overview
Dependencies
226
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.2 to 1.1.4

.github/workflows/release.yml

22

CHANGELOG.md

@@ -0,1 +1,23 @@

## [1.1.4](https://github.com/openlawteam/ethers-gcp-kms-signer/compare/v1.1.3...v1.1.4) (2022-10-31)
### fix
* gh release workflow ([14acd9a](https://github.com/openlawteam/ethers-gcp-kms-signer/commit/14acd9a3ebd47e29f3d4d0e6062902f88c984ed2))
## [1.1.3](https://github.com/openlawteam/ethers-gcp-kms-signer/compare/v1.1.2...v1.1.3) (2022-10-31)
### chore
* bump google kms lib version ([84ea5db](https://github.com/openlawteam/ethers-gcp-kms-signer/commit/84ea5dbcf1751cd59d4095ae836257379dd52352))
* lock ethers lib version ([31c499b](https://github.com/openlawteam/ethers-gcp-kms-signer/commit/31c499b9f317fbd6be055f540a08e2d25cb50abe))
* lock lib version ([26fe9e5](https://github.com/openlawteam/ethers-gcp-kms-signer/commit/26fe9e5b61a516a389b7e72639b7e34524561755))
### fix
* deployment action ([492b400](https://github.com/openlawteam/ethers-gcp-kms-signer/commit/492b40084844ab82aadde3784a96ee29af8ad995))
* github workflows dir ([8371d5a](https://github.com/openlawteam/ethers-gcp-kms-signer/commit/8371d5a1eb8cc1ee0927f7fab2bf6bf79bed7820))
## [1.1.2](https://github.com/openlawteam/ethers-gcp-kms-signer/compare/v1.1.1...v1.1.2) (2022-01-14)

@@ -2,0 +24,0 @@

44

dist/signer.js

@@ -7,44 +7,25 @@ "use strict";

exports.TypedDataVersion = exports.GcpKmsSigner = void 0;
var _dotenv = _interopRequireDefault(require("dotenv"));
var _ethSigUtil = require("@metamask/eth-sig-util");
var _ethers = require("ethers");
var _ethereumjsUtil = require("ethereumjs-util");
var _gcpKmsUtils = require("./util/gcp-kms-utils");
var _signatureUtils = require("./util/signature-utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
_dotenv.default.config();
const TypedDataVersion = _ethSigUtil.SignTypedDataVersion;
exports.TypedDataVersion = TypedDataVersion;
class GcpKmsSigner extends _ethers.ethers.Signer {
constructor(kmsCredentials, provider) {
super();
_defineProperty(this, "kmsCredentials", void 0);
_defineProperty(this, "ethereumAddress", void 0);
_ethers.ethers.utils.defineReadOnly(this, "provider", provider || null);
_ethers.ethers.utils.defineReadOnly(this, "kmsCredentials", kmsCredentials);
}
getAddress() {
var _this = this;
return _asyncToGenerator(function* () {

@@ -55,10 +36,7 @@ if (_this.ethereumAddress === undefined) {

}
return Promise.resolve(_this.ethereumAddress);
})();
}
_signDigest(digestString) {
var _this2 = this;
return _asyncToGenerator(function* () {

@@ -68,6 +46,4 @@ const digestBuffer = Buffer.from(_ethers.ethers.utils.arrayify(digestString));

const ethAddr = yield _this2.getAddress();
const _determineCorrectV = (0, _gcpKmsUtils.determineCorrectV)(digestBuffer, sig.r, sig.s, ethAddr),
v = _determineCorrectV.v;
v = _determineCorrectV.v;
return _ethers.ethers.utils.joinSignature({

@@ -80,6 +56,4 @@ v,

}
signMessage(message) {
var _this3 = this;
return _asyncToGenerator(function* () {

@@ -89,2 +63,3 @@ return _this3._signDigest(_ethers.ethers.utils.hashMessage(message));

}
/**

@@ -112,4 +87,2 @@ * Original implementation takes into account the private key, but here we use the private

*/
signTypedData({

@@ -120,12 +93,8 @@ data,

var _this4 = this;
return _asyncToGenerator(function* () {
(0, _signatureUtils.validateVersion)(version);
if (data === null || data === undefined) {
throw new Error("Missing data parameter");
}
let messageSignature;
if (version === _ethSigUtil.SignTypedDataVersion.V1) {

@@ -135,18 +104,12 @@ messageSignature = _this4._signDigest((0, _ethSigUtil.typedSignatureHash)(data));

const eip712Hash = _ethSigUtil.TypedDataUtils.eip712Hash(data, version);
messageSignature = _this4._signDigest((0, _ethereumjsUtil.bufferToHex)(eip712Hash));
}
return messageSignature;
})();
}
signTransaction(transaction) {
var _this5 = this;
return _asyncToGenerator(function* () {
const unsignedTx = yield _ethers.ethers.utils.resolveProperties(transaction);
const serializedTx = _ethers.ethers.utils.serializeTransaction(unsignedTx);
const transactionSignature = yield _this5._signDigest(_ethers.ethers.utils.keccak256(serializedTx));

@@ -156,9 +119,6 @@ return _ethers.ethers.utils.serializeTransaction(unsignedTx, transactionSignature);

}
connect(provider) {
return new GcpKmsSigner(this.kmsCredentials, provider);
}
}
exports.GcpKmsSigner = GcpKmsSigner;

@@ -12,40 +12,22 @@ "use strict";

exports.sign = sign;
var _ethers = require("ethers");
var _kms = require("@google-cloud/kms");
var asn1 = _interopRequireWildcard(require("asn1.js"));
var _bn = _interopRequireDefault(require("bn.js"));
var _keyEncoder = _interopRequireDefault(require("key-encoder"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
const keyEncoder = new _keyEncoder.default("secp256k1");
const keyEncoder = new _keyEncoder.default("secp256k1");
/* this asn1.js library has some funky things going on */
/* eslint-disable func-names */
const EcdsaSigAsnParse = asn1.define("EcdsaSig", function () {

@@ -60,7 +42,5 @@ // parsing this according to https://tools.ietf.org/html/rfc3279#section-2.2.3

/* eslint-enable func-names */
function sign(_x, _x2) {
return _sign.apply(this, arguments);
}
function _sign() {

@@ -70,12 +50,10 @@ _sign = _asyncToGenerator(function* (digest, kmsCredentials) {

const versionName = kms.cryptoKeyVersionPath(kmsCredentials.projectId, kmsCredentials.locationId, kmsCredentials.keyRingId, kmsCredentials.keyId, kmsCredentials.keyVersion);
const _yield$kms$asymmetric = yield kms.asymmetricSign({
name: versionName,
digest: {
sha256: digest
}
}),
_yield$kms$asymmetric2 = _slicedToArray(_yield$kms$asymmetric, 1),
asymmetricSignResponse = _yield$kms$asymmetric2[0];
name: versionName,
digest: {
sha256: digest
}
}),
_yield$kms$asymmetric2 = _slicedToArray(_yield$kms$asymmetric, 1),
asymmetricSignResponse = _yield$kms$asymmetric2[0];
return asymmetricSignResponse;

@@ -85,3 +63,2 @@ });

}
const getPublicKey = /*#__PURE__*/function () {

@@ -91,16 +68,14 @@ var _ref = _asyncToGenerator(function* (kmsCredentials) {

const versionName = kms.cryptoKeyVersionPath(kmsCredentials.projectId, kmsCredentials.locationId, kmsCredentials.keyRingId, kmsCredentials.keyId, kmsCredentials.keyVersion);
const _yield$kms$getPublicK = yield kms.getPublicKey({
name: versionName
}),
_yield$kms$getPublicK2 = _slicedToArray(_yield$kms$getPublicK, 1),
publicKey = _yield$kms$getPublicK2[0];
name: versionName
}),
_yield$kms$getPublicK2 = _slicedToArray(_yield$kms$getPublicK, 1),
publicKey = _yield$kms$getPublicK2[0];
if (!publicKey || !publicKey.pem) throw new Error(`Can not find key: ${kmsCredentials.keyId}`);
if (!publicKey || !publicKey.pem) throw new Error(`Can not find key: ${kmsCredentials.keyId}`); // GCP KMS returns the public key in pem format,
// GCP KMS returns the public key in pem format,
// so we need to encode it to der format, and return the hex buffer.
const der = keyEncoder.encodePublic(publicKey.pem, "pem", "der");
return Buffer.from(der, "hex");
});
return function getPublicKey(_x3) {

@@ -110,5 +85,3 @@ return _ref.apply(this, arguments);

}();
exports.getPublicKey = getPublicKey;
function getEthereumAddress(publicKey) {

@@ -120,21 +93,20 @@ // The public key here is a hex der ASN1 encoded in a format according to

const res = EcdsaPubKey.decode(publicKey, "der");
const pubKeyBuffer = res.pubKey.data; // The raw format public key starts with a `04` prefix that needs to be removed
const pubKeyBuffer = res.pubKey.data;
// The raw format public key starts with a `04` prefix that needs to be removed
// more info: https://www.oreilly.com/library/view/mastering-ethereum/9781491971932/ch04.html
// const pubStr = publicKey.toString();
const pubFormatted = pubKeyBuffer.slice(1, pubKeyBuffer.length);
const pubFormatted = pubKeyBuffer.slice(1, pubKeyBuffer.length); // keccak256 hash of publicKey
const address = _ethers.ethers.utils.keccak256(pubFormatted); // take last 20 bytes as ethereum address
// keccak256 hash of publicKey
const address = _ethers.ethers.utils.keccak256(pubFormatted);
// take last 20 bytes as ethereum address
const EthAddr = `0x${address.slice(-40)}`;
return EthAddr;
}
function findEthereumSig(signature) {
const decoded = EcdsaSigAsnParse.decode(signature, "der");
const r = decoded.r,
s = decoded.s;
s = decoded.s;
const secp256k1N = new _bn.default("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16); // max value on the curve
const secp256k1halfN = secp256k1N.div(new _bn.default(2)); // half of the curve

@@ -145,3 +117,2 @@ // Because of EIP-2 not all elliptic curve signatures are accepted

// if s is less than half of the curve, we're on the "good" side of the curve, we can just return
return {

@@ -152,15 +123,11 @@ r,

}
function requestKmsSignature(_x4, _x5) {
return _requestKmsSignature.apply(this, arguments);
}
function _requestKmsSignature() {
_requestKmsSignature = _asyncToGenerator(function* (plaintext, kmsCredentials) {
const response = yield sign(plaintext, kmsCredentials);
if (!response || !response.signature) {
throw new Error(`GCP KMS call failed`);
}
return findEthereumSig(response.signature);

@@ -170,3 +137,2 @@ });

}
function recoverPubKeyFromSig(msg, r, s, v) {

@@ -179,3 +145,2 @@ return _ethers.ethers.utils.recoverAddress(`0x${msg.toString("hex")}`, {

}
function determineCorrectV(msg, r, s, expectedEthAddr) {

@@ -188,3 +153,2 @@ // This is the wrapper function to find the right v value

let pubKey = recoverPubKeyFromSig(msg, r, s, v);
if (pubKey.toLowerCase() !== expectedEthAddr.toLowerCase()) {

@@ -196,3 +160,2 @@ // if the pub key for v = 27 does not match

}
return {

@@ -199,0 +162,0 @@ pubKey,

@@ -9,7 +9,4 @@ "use strict";

exports.validateVersion = validateVersion;
var _ethSigUtil = require("@metamask/eth-sig-util");
var _ethereumjsUtil = require("ethereumjs-util");
/**

@@ -26,2 +23,3 @@ * Recover the public key from the given signature and message hash.

}
/**

@@ -34,4 +32,2 @@ * Validate that the given value is a valid version string.

*/
function validateVersion(version, allowedVersions) {

@@ -44,2 +40,3 @@ if (!Object.keys(_ethSigUtil.SignTypedDataVersion).includes(version)) {

}
/**

@@ -56,4 +53,2 @@ * Recover the address of the account that created the given EIP-712

*/
function recoverTypedSignature({

@@ -65,3 +60,2 @@ data,

validateVersion(version);
if (data === null || data === undefined) {

@@ -72,5 +66,3 @@ throw new Error("Missing data parameter");

}
let messageHash;
if (version === _ethSigUtil.SignTypedDataVersion.V1) {

@@ -81,3 +73,2 @@ messageHash = Buffer.from((0, _ethSigUtil.typedSignatureHash)(data));

}
const publicKey = recoverPublicKey(messageHash, signature);

@@ -84,0 +75,0 @@ const sender = (0, _ethereumjsUtil.publicToAddress)(publicKey);

{
"name": "ethers-gcp-kms-signer",
"version": "1.1.2",
"version": "1.1.4",
"description": "An Ethers.js compatible signer that connects to GCP KMS",

@@ -41,11 +41,11 @@ "main": "dist/signer.js",

"dependencies": {
"@google-cloud/kms": "^2.10.0",
"@metamask/eth-sig-util": "^4.0.0",
"asn1.js": "^5.4.1",
"bn.js": "^5.2.0",
"crypto": "^1.0.1",
"@google-cloud/kms": "3.0.1",
"@metamask/eth-sig-util": "4.0.0",
"asn1.js": "5.4.1",
"bn.js": "5.2.0",
"crypto": "1.0.1",
"dotenv": "^10.0.0",
"ethereumjs-util": "^7.1.3",
"ethers": "^5.5.1",
"key-encoder": "^2.0.3"
"ethereumjs-util": "7.1.3",
"ethers": "5.5.1",
"key-encoder": "2.0.3"
},

@@ -52,0 +52,0 @@ "devDependencies": {

@@ -25,5 +25,5 @@ import configs from "dotenv";

describe.skip("Google KMS Signer", () => {
test("should send a signed transaction", async () => {
const provider = ethers.providers.InfuraProvider.getWebSocketProvider("rinkeby", process.env.INFURA_KEY);
describe.skip("sign with Google KMS", () => {
test("should send a signed transaction using KMS signer", async () => {
const provider = ethers.providers.InfuraProvider.getWebSocketProvider("goerli", process.env.INFURA_KEY);

@@ -30,0 +30,0 @@ const signer = new GcpKmsSigner(kmsCredentials).connect(provider);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc