From beb78e822764ac73b307e20199d87d2f920aed8c Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Fri, 22 Sep 2023 08:59:33 +0200 Subject: [PATCH] fix: normalize case before hash verification --- src/verifications.js | 45 ++++++++++++++++++++++++++++++++++++-- test/verifications.test.js | 6 +++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/verifications.js b/src/verifications.js index 7b682ce..f54d04c 100644 --- a/src/verifications.js +++ b/src/verifications.js @@ -89,7 +89,7 @@ const containsProof = async (data, params) => { if (parseInt(match[0].split('$')[2]) > 12) continue const hashPromise = bcryptVerify({ - password: fingerprintURI, + password: fingerprintURI.toLowerCase(), hash: match[0] }) .then(result => result) @@ -102,6 +102,28 @@ const containsProof = async (data, params) => { } catch (err) { result = false } + + // Accept mixed-case fingerprints until deadline + if (!result) { + try { + // Patch until promise.race properly works on WASM + if (parseInt(match[0].split('$')[2]) > 12) continue + + const hashPromise = bcryptVerify({ + password: fingerprintURI, + hash: match[0] + }) + .then(result => result) + .catch(_ => false) + + result = await Promise.race([hashPromise, timeoutPromise]).then((result) => { + clearTimeout(timeoutHandle) + return result + }) + } catch (err) { + result = false + } + } break case 'argon2': @@ -110,7 +132,7 @@ const containsProof = async (data, params) => { case 'argon2id': try { const hashPromise = argon2Verify({ - password: fingerprintURI, + password: fingerprintURI.toLowerCase(), hash: match[0] }) .then(result => result) @@ -123,6 +145,25 @@ const containsProof = async (data, params) => { } catch (err) { result = false } + + // Accept mixed-case fingerprints until deadline + if (!result) { + try { + const hashPromise = argon2Verify({ + password: fingerprintURI, + hash: match[0] + }) + .then(result => result) + .catch(_ => false) + + result = await Promise.race([hashPromise, timeoutPromise]).then((result) => { + clearTimeout(timeoutHandle) + return result + }) + } catch (err) { + result = false + } + } break default: diff --git a/test/verifications.test.js b/test/verifications.test.js index 77cfd48..7b2abc8 100644 --- a/test/verifications.test.js +++ b/test/verifications.test.js @@ -50,6 +50,8 @@ describe('verifications.run', () => { it('should verify a plaintext proof', async () => { const result = await verifications.run(plaintextCorrectProofData, claimData, fingerprint) expect(result.result).to.be.true + const result2 = await verifications.run(plaintextCorrectProofData, claimData, fingerprint.toUpperCase()) + expect(result2.result).to.be.true }) // issue #22 it('should handle a plaintext proof with whitespace', async () => { @@ -63,6 +65,8 @@ describe('verifications.run', () => { it('should verify a argon2-hashed proof', async () => { const result = await verifications.run(argon2CorrectProofData, claimData, fingerprint) expect(result.result).to.be.true + const result2 = await verifications.run(argon2CorrectProofData, claimData, fingerprint.toUpperCase()) + expect(result2.result).to.be.true }) it('should reject a wrong argon2-hashed proof', async () => { const result = await verifications.run(argon2IncorrectProofData, claimData, fingerprint) @@ -71,6 +75,8 @@ describe('verifications.run', () => { it('should verify a bcrypt-hashed proof', async () => { const result = await verifications.run(bcryptCorrectProofData, claimData, fingerprint) expect(result.result).to.be.true + const result2 = await verifications.run(bcryptCorrectProofData, claimData, fingerprint.toUpperCase()) + expect(result2.result).to.be.true }) it('should reject a wrong bcrypt-hashed proof', async () => { const result = await verifications.run(bcryptIncorrectProofData, claimData, fingerprint)