Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80540 views
1
'use strict'
2
// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js
3
var parseKeys = require('parse-asn1')
4
var elliptic = require('elliptic')
5
var curves = require('./curves')
6
var BN = require('bn.js')
7
module.exports = verify
8
9
function verify (sig, hash, key, signType) {
10
var pub = parseKeys(key)
11
if (pub.type === 'ec') {
12
if (signType !== 'ecdsa') {
13
throw new Error('wrong public key type')
14
}
15
return ecVerify(sig, hash, pub)
16
} else if (pub.type === 'dsa') {
17
if (signType !== 'dsa') {
18
throw new Error('wrong public key type')
19
}
20
return dsaVerify(sig, hash, pub)
21
} else {
22
if (signType !== 'rsa') {
23
throw new Error('wrong public key type')
24
}
25
}
26
var len = pub.modulus.byteLength()
27
var pad = [ 1 ]
28
var padNum = 0
29
while (hash.length + pad.length + 2 < len) {
30
pad.push(0xff)
31
padNum++
32
}
33
pad.push(0x00)
34
var i = -1
35
while (++i < hash.length) {
36
pad.push(hash[i])
37
}
38
pad = new Buffer(pad)
39
var red = BN.mont(pub.modulus)
40
sig = new BN(sig).toRed(red)
41
42
sig = sig.redPow(new BN(pub.publicExponent))
43
44
sig = new Buffer(sig.fromRed().toArray())
45
var out = 0
46
if (padNum < 8) {
47
out = 1
48
}
49
len = Math.min(sig.length, pad.length)
50
if (sig.length !== pad.length) {
51
out = 1
52
}
53
54
i = -1
55
while (++i < len) {
56
out |= (sig[i] ^ pad[i])
57
}
58
return out === 0
59
}
60
function ecVerify (sig, hash, pub) {
61
var curveId = curves[pub.data.algorithm.curve.join('.')]
62
if (!curveId)
63
throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.'))
64
65
var curve = new elliptic.ec(curveId)
66
67
var pubkey = pub.data.subjectPrivateKey.data
68
return curve.verify(hash, sig, pubkey)
69
}
70
function dsaVerify (sig, hash, pub) {
71
var p = pub.data.p
72
var q = pub.data.q
73
var g = pub.data.g
74
var y = pub.data.pub_key
75
var unpacked = parseKeys.signature.decode(sig, 'der')
76
var s = unpacked.s
77
var r = unpacked.r
78
checkValue(s, q)
79
checkValue(r, q)
80
var montq = BN.mont(q)
81
var montp = BN.mont(p)
82
var w = s.invm(q)
83
var v = g.toRed(montp)
84
.redPow(new BN(hash).mul(w).mod(q))
85
.fromRed()
86
.mul(
87
y.toRed(montp)
88
.redPow(r.mul(w).mod(q))
89
.fromRed()
90
).mod(p).mod(q)
91
return !v.cmp(r)
92
}
93
function checkValue (b, q) {
94
if (b.cmpn(0) <= 0) {
95
throw new Error('invalid sig')
96
}
97
if (b.cmp(q) >= q) {
98
throw new Error('invalid sig')
99
}
100
}
101
102