diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 94c0aba1..0a4e2b24 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -295,7 +295,7 @@ Pool.prototype.startServer = function startServer() { this.server.on('connection', function(socket) { self._addLeech(socket); - }) + }); this.server.on('listening', function() { var data = self.server.address(); diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 3c113fbd..6ea3fcc6 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -304,6 +304,11 @@ script.checksig = function checksig(msg, sig, key) { sig = sig.slice(0, -1); + // Attempt to normalize the signature + // length before passing to elliptic. + // https://github.com/indutny/elliptic/issues/78 + sig = script.normalizeDER(sig); + // Use a try catch in case there are // any uncaught errors for bad inputs in verify(). try { @@ -311,6 +316,11 @@ script.checksig = function checksig(msg, sig, key) { } catch (e) { utils.debug('Elliptic threw during verification:'); utils.debug(e.stack + ''); + utils.debug({ + msg: utils.toHex(msg), + sig: utils.toHex(sig), + key: utils.toHex(key) + }); return false; } }; @@ -340,6 +350,56 @@ script.sign = function sign(msg, key, type) { return sig; }; +script.normalizeDER = function normalizeDER(signature) { + var data, p, len, rlen, slen; + + if (Buffer.isBuffer(signature)) + signature = Array.prototype.slice.call(signature); + else if (typeof signature === 'string') + signature = utils.toArray(signature, 'hex'); + + data = signature.slice(); + p = { place: 0 }; + + if (data[p.place++] !== 0x30) + return signature; + + len = getLength(data, p); + + if (data.length > len + p.place) + data = data.slice(0, len + p.place); + + if (data[p.place++] !== 0x02) + return signature; + + rlen = getLength(data, p); + p.place += rlen; + + if (data[p.place++] !== 0x02) + return signature; + + slen = getLength(data, p); + if (data.length > slen + p.place) + data = data.slice(0, slen + p.place); + + return data; +}; + +function getLength(buf, p) { + var initial = buf[p.place++]; + if (!(initial & 0x80)) { + return initial; + } + var octetLen = initial & 0xf; + var val = 0; + for (var i = 0, off = p.place; i < octetLen; i++, off++) { + val <<= 8; + val |= buf[off]; + } + p.place = off; + return val; +} + script._next = function _next(to, s, pc) { var depth = 0; var o;