Skip to content

Commit

Permalink
fix: use correct salt length for RSASSA-PSS
Browse files Browse the repository at this point in the history
https://tools.ietf.org/html/rfc7518 section 3.5 states that the size of
the salt value is the same size as the hash function output.

This is to accomodate that requirement and achieve interop with other
conform implementations. This also prompted enforcing the proper key
sizes.
  • Loading branch information
panva committed Mar 16, 2019
1 parent cc70c5d commit e936d54
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 20 deletions.
1 change: 1 addition & 0 deletions lib/jwa/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const JWA = {
require('./hmac')(JWA)
require('./ecdsa')(JWA)
require('./rsassa')(JWA)
require('./rsassa_pss')(JWA)

// encrypt, decrypt
require('./aes_cbc_hmac_sha2')(JWA)
Expand Down
28 changes: 8 additions & 20 deletions lib/jwa/rsassa.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,39 @@
const { strict: assert } = require('assert')
const { createSign, createVerify, constants } = require('crypto')
const { createSign, createVerify } = require('crypto')

const { KEYOBJECT } = require('../help/symbols')

const resolveNodeAlg = (alg) => {
switch (alg) {
case 'PS256':
case 'RS256':
return 'RSA-SHA256'
case 'PS384':
case 'RS384':
return 'RSA-SHA384'
case 'PS512':
case 'RS512':
return 'RSA-SHA512'
}
}

const resolvePadding = (alg) => {
if (alg.startsWith('RS')) {
return constants.RSA_PKCS1_PADDING
}

return constants.RSA_PKCS1_PSS_PADDING
}

const sign = (nodeAlg, padding, { [KEYOBJECT]: keyObject }, payload) => {
const sign = (nodeAlg, { [KEYOBJECT]: keyObject }, payload) => {
const sign = createSign(nodeAlg)
sign.update(payload)
return sign.sign({ key: keyObject, padding })
return sign.sign(keyObject)
}

const verify = (nodeAlg, padding, { [KEYOBJECT]: keyObject }, payload, signature) => {
const verify = (nodeAlg, { [KEYOBJECT]: keyObject }, payload, signature) => {
const verify = createVerify(nodeAlg)
verify.update(payload)
return verify.verify({ key: keyObject, padding }, signature)
return verify.verify(keyObject, signature)
}

module.exports = (JWA) => {
['PS256', 'PS384', 'PS512', 'RS256', 'RS384', 'RS512'].forEach((jwaAlg) => {
['RS256', 'RS384', 'RS512'].forEach((jwaAlg) => {
const nodeAlg = resolveNodeAlg(jwaAlg)
const padding = resolvePadding(jwaAlg)

assert(!JWA.sign.has(jwaAlg), `sign alg ${jwaAlg} already registered`)
assert(!JWA.verify.has(jwaAlg), `verify alg ${jwaAlg} already registered`)

JWA.sign.set(jwaAlg, sign.bind(undefined, nodeAlg, padding))
JWA.verify.set(jwaAlg, verify.bind(undefined, nodeAlg, padding))
JWA.sign.set(jwaAlg, sign.bind(undefined, nodeAlg))
JWA.verify.set(jwaAlg, verify.bind(undefined, nodeAlg))
})
}
49 changes: 49 additions & 0 deletions lib/jwa/rsassa_pss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const { strict: assert } = require('assert')
const { createSign, createVerify, constants } = require('crypto')

const { KEYOBJECT } = require('../help/symbols')

const resolveNodeAlg = (alg) => {
switch (alg) {
case 'PS256':
return 'RSA-SHA256'
case 'PS384':
return 'RSA-SHA384'
case 'PS512':
return 'RSA-SHA512'
}
}

const sign = (nodeAlg, { [KEYOBJECT]: keyObject, length }, payload) => {
const sign = createSign(nodeAlg)
sign.update(payload)

return sign.sign({
key: keyObject,
padding: constants.RSA_PKCS1_PSS_PADDING,
saltLength: constants.RSA_PSS_SALTLEN_DIGEST
})
}

const verify = (nodeAlg, { [KEYOBJECT]: keyObject, length }, payload, signature) => {
const verify = createVerify(nodeAlg)
verify.update(payload)

return verify.verify({
key: keyObject,
padding: constants.RSA_PKCS1_PSS_PADDING,
saltLength: constants.RSA_PSS_SALTLEN_DIGEST
}, signature)
}

module.exports = (JWA) => {
['PS256', 'PS384', 'PS512'].forEach((jwaAlg) => {
const nodeAlg = resolveNodeAlg(jwaAlg)

assert(!JWA.sign.has(jwaAlg), `sign alg ${jwaAlg} already registered`)
assert(!JWA.verify.has(jwaAlg), `verify alg ${jwaAlg} already registered`)

JWA.sign.set(jwaAlg, sign.bind(undefined, nodeAlg))
JWA.verify.set(jwaAlg, verify.bind(undefined, nodeAlg))
})
}

0 comments on commit e936d54

Please sign in to comment.