Skip to content

Commit

Permalink
properly check signatures and test for it
Browse files Browse the repository at this point in the history
  • Loading branch information
calvinmetcalf committed Mar 9, 2015
1 parent b78737b commit 48f8881
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 9 deletions.
2 changes: 1 addition & 1 deletion browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Verify.prototype.update = function update (data, enc) {
Verify.prototype.verify = function verifyMethod (key, sig, enc) {
this.end()
var hash = this._hash.digest()
if (typeof sic === 'string')
if (typeof sig === 'string')
sig = new Buffer(sig, enc)

return verify(sig, Buffer.concat([this._tag, hash]), key)
Expand Down
137 changes: 137 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ var test = require('tape')
var fs = require('fs')
var priv1024 = fs.readFileSync(__dirname + '/rsa.1024.priv')
var asn1 = require('parse-asn1/asn1')
var parseKeys = require('parse-asn1')
var crt = require('browserify-rsa')
var crypto = require('crypto')
var rsa1024 = {
private: fs.readFileSync(__dirname + '/rsa.1024.priv'),
public: fs.readFileSync(__dirname + '/rsa.1024.pub')
Expand Down Expand Up @@ -334,3 +337,137 @@ test('kvector works', function (t) {
})
})
})

test('reject invalid sigs', function (t) {
var message = 'a valid message!';
var hash = Buffer.concat([
new Buffer('302d300d06096086480165030402040500041c', 'hex'),
crypto.createHash('sha224').update(message).digest()
])
t.test('I create a valid sig', function (t) {
t.plan(2);
var priv = parseKeys(rsa1024.private)
var len = priv.modulus.byteLength()
var pad = [ 0, 1 ]
while (hash.length + pad.length + 1 < len) {
pad.push(0xff)
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}

var sign = crt(pad, priv)
t.ok(nodeCrypto.createVerify('RSA-SHA224')
.update(message)
.verify(rsa1024.public, sign), 'node accepts it')
t.ok(myCrypto.createVerify('RSA-SHA224').update(message).verify(rsa1024.public, sign), 'I accept it')
})
t.test('invalid leading byte', function (t) {
t.plan(2);
var priv = parseKeys(rsa1024.private)
var len = priv.modulus.byteLength()
var pad = [ 0, 2 ]
while (hash.length + pad.length + 1 < len) {
pad.push(0xff)
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}

var sign = crt(pad, priv)
t.notOk(nodeCrypto.createVerify('RSA-SHA224')
.update(message)
.verify(rsa1024.public, sign), 'node rejects it')
t.notOk(myCrypto.createVerify('RSA-SHA224').update(message).verify(rsa1024.public, sign), 'I reject it')
})

t.test('invalid ending bytes', function (t) {
t.plan(2);
var priv = parseKeys(rsa1024.private)
var len = priv.modulus.byteLength()
var pad = [ 0, 1 ]
while (hash.length + pad.length + 1 < len) {
pad.push(0xff)
}
pad.push(0x02)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}

var sign = crt(pad, priv)
t.notOk(nodeCrypto.createVerify('RSA-SHA224')
.update(message)
.verify(rsa1024.public, sign), 'node rejects it')
t.notOk(myCrypto.createVerify('RSA-SHA224').update(message).verify(rsa1024.public, sign), 'I reject it')
})

t.test('missing f', function (t) {
t.plan(2);
var priv = parseKeys(rsa1024.private)
var len = priv.modulus.byteLength()
var pad = [ 0, 1 ]
while (hash.length + pad.length + 2 < len) {
pad.push(0xff)
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}

var sign = crt(pad, priv)
t.notOk(nodeCrypto.createVerify('RSA-SHA224')
.update(message)
.verify(rsa1024.public, sign), 'node rejects it')
t.notOk(myCrypto.createVerify('RSA-SHA224').update(message).verify(rsa1024.public, sign), 'I reject it')
})

t.test('missing f, extra data', function (t) {
t.plan(2);
var priv = parseKeys(rsa1024.private)
var len = priv.modulus.byteLength()
var pad = [ 0, 1 ]
while (hash.length + pad.length + 2 < len) {
pad.push(0xff)
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}
pad.push(0)
var sign = crt(pad, priv)
t.notOk(nodeCrypto.createVerify('RSA-SHA224')
.update(message)
.verify(rsa1024.public, sign), 'node rejects it')
t.notOk(myCrypto.createVerify('RSA-SHA224').update(message).verify(rsa1024.public, sign), 'I reject it')
})

t.test('in suficent fs', function (t) {
t.plan(2);
var priv = parseKeys(rsa1024.private)
var len = priv.modulus.byteLength()
var pad = [ 0, 1 ]
var i = 7;
while (i--) {
pad.push(0xff)
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}
pad.push(0)
var sign = crt(pad, priv)
t.notOk(nodeCrypto.createVerify('RSA-SHA224')
.update(message)
.verify(rsa1024.public, sign), 'node rejects it')
t.notOk(myCrypto.createVerify('RSA-SHA224').update(message).verify(rsa1024.public, sign), 'I reject it')
})

})
24 changes: 16 additions & 8 deletions verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,38 @@ function verify (sig, hash, key) {
return dsaVerify(sig, hash, pub)
}
var len = pub.modulus.byteLength()
var pad = [ 0, 1 ]
while (hash.length + pad.length + 1 < len) {
var pad = [ 1 ]
var padNum = 0
while (hash.length + pad.length + 2 < len) {
pad.push(0xff)
padNum++
}
pad.push(0x00)
var i = -1
while (++i < hash.length) {
pad.push(hash[i])
}
pad = hash
pad = new Buffer(pad)
var red = BN.mont(pub.modulus)
sig = new BN(sig).toRed(red)

sig = sig.redPow(new BN(pub.publicExponent))

sig = new Buffer(sig.fromRed().toArray())
sig = sig.slice(sig.length - hash.length)
var out = 0
len = sig.length
if (padNum<8) {
out = 1
}
len = Math.min(sig.length, pad.length)
if (sig.length !== pad.length) {
out = 1
}

i = -1
while (++i < len) {
out += (sig[i] ^ hash[i])
out |= (sig[i] ^ pad[i])
}
return !out
return out === 0
}
function ecVerify (sig, hash, pub) {
var curveId = curves[pub.data.algorithm.curve.join('.')]
Expand Down Expand Up @@ -77,4 +85,4 @@ function checkValue (b, q) {
if (b.cmp(q) >= q) {
throw new Error('invalid sig')
}
}
}

0 comments on commit 48f8881

Please sign in to comment.