Skip to content

Commit

Permalink
test: check ecdsa psychic signature
Browse files Browse the repository at this point in the history
PR-URL: nodejs/node#42863
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Akhil Marsonya <akhil.marsonya27@gmail.com>
  • Loading branch information
panva authored and guangwong committed Oct 10, 2022
1 parent 42f3c4a commit a7fcdf4
Showing 1 changed file with 100 additions and 0 deletions.
100 changes: 100 additions & 0 deletions test/parallel/test-crypto-psychic-signatures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');

const crypto = require('crypto');

// Tests for CVE-2022-21449
// https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/
// Dubbed "Psychic Signatures", these signatures bypassed the ECDSA signature
// verification implementation in Java in 15, 16, 17, and 18. OpenSSL is not
// (and was not) vulnerable so these are a precaution.

const vectors = {
'ieee-p1363': [
Buffer.from('0000000000000000000000000000000000000000000000000000000000000000' +
'0000000000000000000000000000000000000000000000000000000000000000', 'hex'),
Buffer.from('ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551' +
'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551', 'hex'),
],
'der': [
Buffer.from('3046022100' +
'0000000000000000000000000000000000000000000000000000000000000000' +
'022100' +
'0000000000000000000000000000000000000000000000000000000000000000', 'hex'),
Buffer.from('3046022100' +
'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551' +
'022100' +
'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551', 'hex'),
],
};

const keyPair = crypto.generateKeyPairSync('ec', {
namedCurve: 'P-256',
publicKeyEncoding: {
format: 'der',
type: 'spki'
},
});

const data = Buffer.from('Hello!');

for (const [encoding, signatures] of Object.entries(vectors)) {
for (const signature of signatures) {
const key = {
key: keyPair.publicKey,
format: 'der',
type: 'spki',
dsaEncoding: encoding,
};

// one-shot sync
assert.strictEqual(
crypto.verify(
'sha256',
data,
key,
signature,
),
false,
);

// one-shot async
crypto.verify(
'sha256',
data,
key,
signature,
common.mustSucceed((verified) => assert.strictEqual(verified, false)),
);

// stream
assert.strictEqual(
crypto.createVerify('sha256')
.update(data)
.verify(key, signature),
false,
);

// webcrypto
crypto.webcrypto.subtle.importKey(
'spki',
keyPair.publicKey,
{ name: 'ECDSA', namedCurve: 'P-256' },
false,
['verify'],
).then((publicKey) => {
return crypto.webcrypto.subtle.verify(
{ name: 'ECDSA', hash: 'SHA-256' },
publicKey,
signature,
data,
);
}).then(common.mustCall((verified) => {
assert.strictEqual(verified, false);
}));
}
}

0 comments on commit a7fcdf4

Please sign in to comment.