diff --git a/lib/elliptic/ec/signature.js b/lib/elliptic/ec/signature.js index 2cb6b49..539df6a 100644 --- a/lib/elliptic/ec/signature.js +++ b/lib/elliptic/ec/signature.js @@ -32,11 +32,24 @@ function getLength(buf, p) { return initial; } var octetLen = initial & 0xf; + + // Indefinite length or overflow + if (octetLen === 0 || octetLen > 4) { + return false; + } + var val = 0; for (var i = 0, off = p.place; i < octetLen; i++, off++) { val <<= 8; val |= buf[off]; + val >>>= 0; } + + // Leading zeroes + if (val <= 0x7f) { + return false; + } + p.place = off; return val; } @@ -60,6 +73,9 @@ Signature.prototype._importDER = function _importDER(data, enc) { return false; } var len = getLength(data, p); + if (len === false) { + return false; + } if ((len + p.place) !== data.length) { return false; } @@ -67,21 +83,37 @@ Signature.prototype._importDER = function _importDER(data, enc) { return false; } var rlen = getLength(data, p); + if (rlen === false) { + return false; + } var r = data.slice(p.place, rlen + p.place); p.place += rlen; if (data[p.place++] !== 0x02) { return false; } var slen = getLength(data, p); + if (slen === false) { + return false; + } if (data.length !== slen + p.place) { return false; } var s = data.slice(p.place, slen + p.place); - if (r[0] === 0 && (r[1] & 0x80)) { - r = r.slice(1); + if (r[0] === 0) { + if (r[1] & 0x80) { + r = r.slice(1); + } else { + // Leading zeroes + return false; + } } - if (s[0] === 0 && (s[1] & 0x80)) { - s = s.slice(1); + if (s[0] === 0) { + if (s[1] & 0x80) { + s = s.slice(1); + } else { + // Leading zeroes + return false; + } } this.r = new BN(r);