Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorFilip Skokan <panva.ip@gmail.com>2022-04-27 12:29:32 +0300
committerGitHub <noreply@github.com>2022-04-27 12:29:32 +0300
commit8d0f49c09355647f711eb14ec3a22471dbd056b3 (patch)
treeb5a917a810cdb2816ae09d1b1812d6364900e0d2 /test
parent69467fb023b75d35eb51a8e9cb7fed6d0dc957e4 (diff)
test: check ecdsa psychic signature
PR-URL: https://github.com/nodejs/node/pull/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>
Diffstat (limited to 'test')
-rw-r--r--test/parallel/test-crypto-psychic-signatures.js100
1 files changed, 100 insertions, 0 deletions
diff --git a/test/parallel/test-crypto-psychic-signatures.js b/test/parallel/test-crypto-psychic-signatures.js
new file mode 100644
index 00000000000..b8e1207b5c8
--- /dev/null
+++ b/test/parallel/test-crypto-psychic-signatures.js
@@ -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);
+ }));
+ }
+}