1 | const { sign: signOneShot, verify: verifyOneShot, createSign, createVerify, getCurves } = require('crypto')
|
2 |
|
3 | const { derToJose, joseToDer } = require('../help/ecdsa_signatures')
|
4 | const { KEYOBJECT } = require('../help/consts')
|
5 | const resolveNodeAlg = require('../help/node_alg')
|
6 | const { asInput } = require('../help/key_object')
|
7 | const { dsaEncodingSupported } = require('../help/runtime_support')
|
8 | const { name: secp256k1 } = require('../jwk/key/secp256k1_crv')
|
9 |
|
10 | let sign, verify
|
11 |
|
12 | if (dsaEncodingSupported) {
|
13 | sign = (jwaAlg, nodeAlg, { [KEYOBJECT]: keyObject }, payload) => {
|
14 | if (typeof payload === 'string') {
|
15 | payload = Buffer.from(payload)
|
16 | }
|
17 | return signOneShot(nodeAlg, payload, { key: asInput(keyObject, false), dsaEncoding: 'ieee-p1363' })
|
18 | }
|
19 | verify = (jwaAlg, nodeAlg, { [KEYOBJECT]: keyObject }, payload, signature) => {
|
20 | try {
|
21 | return verifyOneShot(nodeAlg, payload, { key: asInput(keyObject, true), dsaEncoding: 'ieee-p1363' }, signature)
|
22 | } catch (err) {
|
23 | return false
|
24 | }
|
25 | }
|
26 | } else {
|
27 | sign = (jwaAlg, nodeAlg, { [KEYOBJECT]: keyObject }, payload) => {
|
28 | return derToJose(createSign(nodeAlg).update(payload).sign(asInput(keyObject, false)), jwaAlg)
|
29 | }
|
30 | verify = (jwaAlg, nodeAlg, { [KEYOBJECT]: keyObject }, payload, signature) => {
|
31 | try {
|
32 | return createVerify(nodeAlg).update(payload).verify(asInput(keyObject, true), joseToDer(signature, jwaAlg))
|
33 | } catch (err) {
|
34 | return false
|
35 | }
|
36 | }
|
37 | }
|
38 |
|
39 | const crvToAlg = (crv) => {
|
40 | switch (crv) {
|
41 | case 'P-256':
|
42 | return 'ES256'
|
43 | case secp256k1:
|
44 | return 'ES256K'
|
45 | case 'P-384':
|
46 | return 'ES384'
|
47 | case 'P-521':
|
48 | return 'ES512'
|
49 | }
|
50 | }
|
51 |
|
52 | module.exports = (JWA, JWK) => {
|
53 | const algs = []
|
54 |
|
55 | if (getCurves().includes('prime256v1')) {
|
56 | algs.push('ES256')
|
57 | }
|
58 |
|
59 | if (getCurves().includes('secp256k1')) {
|
60 | algs.push('ES256K')
|
61 | }
|
62 |
|
63 | if (getCurves().includes('secp384r1')) {
|
64 | algs.push('ES384')
|
65 | }
|
66 |
|
67 | if (getCurves().includes('secp521r1')) {
|
68 | algs.push('ES512')
|
69 | }
|
70 |
|
71 | algs.forEach((jwaAlg) => {
|
72 | const nodeAlg = resolveNodeAlg(jwaAlg)
|
73 | JWA.sign.set(jwaAlg, sign.bind(undefined, jwaAlg, nodeAlg))
|
74 | JWA.verify.set(jwaAlg, verify.bind(undefined, jwaAlg, nodeAlg))
|
75 | JWK.EC.sign[jwaAlg] = key => key.private && JWK.EC.verify[jwaAlg](key)
|
76 | JWK.EC.verify[jwaAlg] = key => (key.use === 'sig' || key.use === undefined) && crvToAlg(key.crv) === jwaAlg
|
77 | })
|
78 | }
|