PSS verify with saltLength: 0 rejects valid signatures
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, node.js
- Domain
- backend, cryptography
Research direction
Start in lib/pss.js at verify, step 11, and check how the salt substring behaves when sLen is zero. Run the reproduction in the issue, then add or run a regression test for an empty salt. Done means forge verifies valid zero-salt RSASSA-PSS signatures while existing PSS verification still passes.
Written by the indexing model from the issue text.
Description
publicKey.verify(..., forge.pss.create({ ..., saltLength: 0 })) returns false for valid RSASSA-PSS signatures with an empty salt, including signatures forge itself produced.
const forge = require('node-forge');
const crypto = require('crypto');
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 });
const pub = forge.pki.publicKeyFromPem(publicKey.export({ type: 'spki', format: 'pem' }));
const prv = forge.pki.privateKeyFromPem(privateKey.export({ type: 'pkcs8', format: 'pem' }));
const pss = () => forge.pss.create({
md: forge.md.sha256.create(),
mgf: forge.mgf.mgf1.create(forge.md.sha256.create()),
saltLength: 0
});
const md = () => { const m = forge.md.sha256.create(); m.update('msg'); return m; };
// signed by OpenSSL, verified by forge
const sigOpenSSL = crypto.sign('sha256', Buffer.from('msg'),
{ key: privateKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 0 });
console.log(pub.verify(md().digest().bytes(), sigOpenSSL.toString('binary'), pss()));
// signed by forge, verified by OpenSSL, then by forge
const sigForge = prv.sign(md(), pss());
console.log(crypto.verify('sha256', Buffer.from('msg'),
{ key: publicKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 0 },
Buffer.from(sigForge, 'binary')));
console.log(pub.verify(md().digest().bytes(), sigForge, pss()));
node repro.js
Actual:
false
true
false
Expected:
true
true
true
Tested with node-forge 1.4.3 (same lib/pss.js as main 01119d6), Node.js v26.13.0.
In lib/pss.js verify, step 11 is var salt = db.substr(-sLen);. For sLen === 0 that is db.substr(-0), which returns all of db instead of '' (RFC 8017 9.1.2 step 11). db.substr(db.length - sLen) works for every sLen.
Credit: https://ucsbplse.github.io/
- Dominant language
- JavaScript
- Stars
- 5.4k
- Forks
- 874
- Avg merge
- 3m
- Merged PRs (30d)
- 6
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from digitalbazaar/forge
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
digitalbazaar/forge#1147 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
digitalbazaar/forge#1146 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 58/100
digitalbazaar/forge#1145 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 48/100
digitalbazaar/forge#1144 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
digitalbazaar/forge#1143 ·
Maintainers usually reply within 1 day
All issues in digitalbazaar/forge
Similar issues
-
stringify escapes leading digits in pseudo-class arguments (:nth-child(1) becomes :nth-child(\31 ))Open
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
getgrav/grav-plugin-form#664 ·
-
bug web-ui
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
jenkinsci/jenkins#27705 · 3 comments ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
maproulette/maproulette-frontend#2978 ·
Maintainers usually reply within 1 day