From 8d67af729a7773ee7656d417ce95677f48cd4df6 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Fri, 7 Aug 2020 16:48:44 +0200 Subject: [PATCH] Use higher level functions in key validation tests (#1128) Use `key.keyPacket.validate` instead of `crypto.publicKey.validateParams`, see https://github.com/openpgpjs/openpgpjs/pull/1116#discussion_r447781386. Also, `key.decrypt` now only throws on error, no other value is returned. Also, fix typo (rebase error) that caused tests to fail in Safari for p521. --- src/crypto/public_key/elliptic/ecdsa.js | 4 +- src/key/key.js | 7 +- test/crypto/validate.js | 361 +++++++++++------------- test/general/brainpool.js | 2 +- test/general/ecc_secp256k1.js | 2 +- test/general/key.js | 6 +- test/general/openpgp.js | 91 +++++- test/general/x25519.js | 2 +- 8 files changed, 261 insertions(+), 214 deletions(-) diff --git a/src/crypto/public_key/elliptic/ecdsa.js b/src/crypto/public_key/elliptic/ecdsa.js index f3d166d1..eac5699c 100644 --- a/src/crypto/public_key/elliptic/ecdsa.js +++ b/src/crypto/public_key/elliptic/ecdsa.js @@ -65,7 +65,7 @@ async function sign(oid, hash_algo, message, publicKey, privateKey, hashed) { if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) { throw err; } - util.print_debug_error("Browser did not support signing: " + err.message); + util.printDebugError("Browser did not support signing: " + err.message); } break; } @@ -108,7 +108,7 @@ async function verify(oid, hash_algo, signature, message, publicKey, hashed) { if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) { throw err; } - util.print_debug_error("Browser did not support verifying: " + err.message); + util.printDebugError("Browser did not support verifying: " + err.message); } break; case 'node': diff --git a/src/key/key.js b/src/key/key.js index 61a34142..f0082fe1 100644 --- a/src/key/key.js +++ b/src/key/key.js @@ -166,7 +166,7 @@ class Key { /** * Clones the key object - * @param {type/keyid} deep Whether to clone each packet, in addition to the list of packets + * @param {Boolean} deep Whether to clone each packet, in addition to the list of packets * @returns {Promise} cloned key * @async */ @@ -424,7 +424,6 @@ class Key { * Decrypts all secret key and subkey packets matching keyId * @param {String|Array} passphrases * @param {module:type/keyid} keyId - * @returns {Promise} true if all matching key and subkey packets decrypted successfully * @throws {Error} if any matching key or subkey packets did not decrypt successfully * @async */ @@ -434,7 +433,7 @@ class Key { } passphrases = util.isArray(passphrases) ? passphrases : [passphrases]; - const results = await Promise.all(this.getKeys(keyId).map(async function(key) { + await Promise.all(this.getKeys(keyId).map(async function(key) { let decrypted = false; let error = null; await Promise.all(passphrases.map(async function(passphrase) { @@ -457,8 +456,6 @@ class Key { // The full key should be decrypted and we can validate it all await this.validate(); } - - return results.every(result => result === true); } /** diff --git a/test/crypto/validate.js b/test/crypto/validate.js index 4a9d71da..b19f1766 100644 --- a/test/crypto/validate.js +++ b/test/crypto/validate.js @@ -74,83 +74,122 @@ vqBGKJzmO5q3cECw =X9kJ -----END PGP PRIVATE KEY BLOCK-----`; +function cloneKeyPacket(key) { + const keyPacket = new openpgp.SecretKeyPacket(); + keyPacket.read(key.keyPacket.write()); + return keyPacket; +} + module.exports = () => { describe('EdDSA parameter validation', function() { - let keyParams; + let eddsaKey; before(async () => { - keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.eddsa, null, 'ed25519'); + eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; }); it('EdDSA params should be valid', async function() { - const { oid, Q, seed } = openpgp.crypto.publicKey.elliptic.eddsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.eddsa.validateParams(oid, Q, seed); - expect(valid).to.be.true; + await expect(eddsaKey.keyPacket.validate()).to.not.be.rejected; }); it('detect invalid edDSA Q', async function() { - const { oid, Q, seed } = openpgp.crypto.publicKey.elliptic.eddsa.parseParams(keyParams); + const eddsaKeyPacket = cloneKeyPacket(eddsaKey); + const Q = eddsaKeyPacket.params[1]; + Q.data[0]++; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); - - Q[0]++; - let valid = await openpgp.crypto.publicKey.elliptic.eddsa.validateParams(oid, Q, seed); - expect(valid).to.be.false; - - const infQ = new Uint8Array(Q.length); - valid = await openpgp.crypto.publicKey.elliptic.eddsa.validateParams(oid, infQ, seed); - expect(valid).to.be.false; + const infQ = new Uint8Array(Q.data.length); + eddsaKeyPacket.params[1] = new openpgp.MPI(infQ); + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); describe('ECC curve validation', function() { + let eddsaKey; + let ecdhKey; + let ecdsaKey; + before(async () => { + eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; + ecdhKey = eddsaKey.subKeys[0]; + ecdsaKey = (await openpgp.generateKey({ curve: 'p256', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; + }); + it('EdDSA params are not valid for ECDH', async function() { - const keyParams = await openpgp.crypto.generateParams( - openpgp.enums.publicKey.eddsa, - null, - 'ed25519' - ); - const { oid, Q, seed } = openpgp.crypto.publicKey.elliptic.eddsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.ecdh.validateParams(oid, Q, seed); - expect(valid).to.be.false; + const oid = eddsaKey.keyPacket.params[0]; + const Q = eddsaKey.keyPacket.params[1]; + const seed = eddsaKey.keyPacket.params[2]; + + const ecdhKeyPacket = cloneKeyPacket(ecdhKey); + const ecdhOID = ecdhKeyPacket.params[0]; + + ecdhKeyPacket.params[0] = oid; + await expect(ecdhKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + + ecdhKeyPacket.params[0] = ecdhOID; + ecdhKeyPacket.params[1] = Q; + ecdhKeyPacket.params[3] = seed; + await expect(ecdhKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('EdDSA params are not valid for EcDSA', async function() { - const keyParams = await openpgp.crypto.generateParams( - openpgp.enums.publicKey.eddsa, - null, - 'ed25519' - ); - const { oid, Q, seed } = openpgp.crypto.publicKey.elliptic.eddsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.ecdsa.validateParams(oid, Q, seed); - expect(valid).to.be.false; + const oid = eddsaKey.keyPacket.params[0]; + const Q = eddsaKey.keyPacket.params[1]; + const seed = eddsaKey.keyPacket.params[2]; + + const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey); + const ecdsaOID = ecdsaKeyPacket.params[0]; + ecdsaKeyPacket.params[0] = oid; + await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + + ecdsaKeyPacket.params[0] = ecdsaOID; + ecdsaKeyPacket.params[1] = Q; + ecdsaKeyPacket.params[2] = seed; + await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); - it('x25519 params are not valid for EcDSA', async function() { - const keyParams = await openpgp.crypto.generateParams( - openpgp.enums.publicKey.ecdsa, - null, - 'curve25519' - ); - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.ecdsa.validateParams(oid, Q, d); - expect(valid).to.be.false; + it('ECDH x25519 params are not valid for EcDSA', async function() { + const ecdh25519KeyPacket = ecdhKey.keyPacket; + const oid = ecdh25519KeyPacket.params[0]; + const Q = ecdh25519KeyPacket.params[1]; + const d = ecdh25519KeyPacket.params[3]; + + const ecdsaKeyPacket = cloneKeyPacket(ecdsaKey); + ecdsaKeyPacket.params[0] = oid; + ecdsaKeyPacket.params[1] = Q; + ecdsaKeyPacket.params[2] = d; + await expect(ecdsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('EcDSA params are not valid for EdDSA', async function() { - const keyParams = await openpgp.crypto.generateParams( - openpgp.enums.publicKey.ecdsa, null, 'p256' - ); - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.eddsa.validateParams(oid, Q, d); - expect(valid).to.be.false; + const oid = ecdsaKey.keyPacket.params[0]; + const Q = ecdsaKey.keyPacket.params[1]; + const d = ecdsaKey.keyPacket.params[2]; + + const eddsaKeyPacket = cloneKeyPacket(eddsaKey); + const eddsaOID = eddsaKeyPacket.params[0]; + eddsaKeyPacket.params[0] = oid; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + + eddsaKeyPacket.params[0] = eddsaOID; + eddsaKeyPacket.params[1] = Q; + eddsaKeyPacket.params[2] = d; + await expect(eddsaKeyPacket.validate()).to.be.rejected; }); - it('x25519 params are not valid for EdDSA', async function() { - const keyParams = await openpgp.crypto.generateParams( - openpgp.enums.publicKey.ecdsa, null, 'curve25519' - ); - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.eddsa.validateParams(oid, Q, d); - expect(valid).to.be.false; + it('ECDH x25519 params are not valid for EdDSA', async function() { + const ecdh25519KeyPacket = ecdhKey.keyPacket; + const oid = ecdh25519KeyPacket.params[0]; + const Q = ecdh25519KeyPacket.params[1]; + const d = ecdh25519KeyPacket.params[3]; + + const eddsaKeyPacket = cloneKeyPacket(eddsaKey); + const eddsaOID = eddsaKeyPacket.params[0]; + eddsaKeyPacket.params[0] = oid; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); + + eddsaKeyPacket.params[0] = eddsaOID; + eddsaKeyPacket.params[1] = Q; + eddsaKeyPacket.params[2] = d; + await expect(eddsaKeyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); @@ -158,95 +197,74 @@ module.exports = () => { const curves = ['curve25519', 'p256', 'p384', 'p521', 'secp256k1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1']; curves.forEach(curve => { describe(`ECC ${curve} parameter validation`, () => { - let keyParams; + let ecdsaKey; + let ecdhKey; before(async () => { - // we generate also ecdh params as ecdsa ones since we do not need the kdf params - keyParams = await openpgp.crypto.generateParams( - openpgp.enums.publicKey.ecdsa, null, curve - ); + if (curve !== 'curve25519') { + ecdsaKey = (await openpgp.generateKey({ curve, userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; + ecdhKey = ecdsaKey.subKeys[0]; + } else { + const eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; + ecdhKey = eddsaKey.subKeys[0]; + } }); - if (curve !== 'curve25519') { + if (ecdsaKey) { it(`EcDSA ${curve} params should be valid`, async function() { - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.ecdsa.validateParams(oid, Q, d); - expect(valid).to.be.true; + await expect(ecdsaKey.keyPacket.validate()).to.not.be.rejected; }); it('detect invalid EcDSA Q', async function() { - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); + const keyPacket = cloneKeyPacket(ecdsaKey); + const Q = keyPacket.params[1]; + Q.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); - Q[16]++; - let valid = await openpgp.crypto.publicKey.elliptic.ecdsa.validateParams(oid, Q, d); - expect(valid).to.be.false; - - const infQ = new Uint8Array(Q.length); - valid = await openpgp.crypto.publicKey.elliptic.ecdsa.validateParams(oid, infQ, d); - expect(valid).to.be.false; + const infQ = new Uint8Array(Q.data.length); + keyPacket.params[1] = new openpgp.MPI(infQ); + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); } it(`ECDH ${curve} params should be valid`, async function() { - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); - const valid = await openpgp.crypto.publicKey.elliptic.ecdh.validateParams(oid, Q, d); - expect(valid).to.be.true; + await expect(ecdhKey.keyPacket.validate()).to.not.be.rejected; }); it('detect invalid ECDH Q', async function() { - const { oid, Q, d } = openpgp.crypto.publicKey.elliptic.ecdsa.parseParams(keyParams); + const keyPacket = cloneKeyPacket(ecdhKey); + const Q = keyPacket.params[1]; + Q.data[16]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); - Q[16]++; - let valid = await openpgp.crypto.publicKey.elliptic.ecdh.validateParams(oid, Q, d); - expect(valid).to.be.false; - - const infQ = new Uint8Array(Q.length); - valid = await openpgp.crypto.publicKey.elliptic.ecdh.validateParams(oid, infQ, d); - expect(valid).to.be.false; + const infQ = new Uint8Array(Q.data.length); + keyPacket.params[1] = new openpgp.MPI(infQ); + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); }); describe('RSA parameter validation', function() { - let keyParams; + let rsaKey; before(async () => { - keyParams = await openpgp.crypto.generateParams(openpgp.enums.publicKey.rsaSign, 2048); + rsaKey = (await openpgp.generateKey({ rsaBits: 2048, userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; }); it('generated RSA params are valid', async function() { - const n = keyParams[0].toUint8Array(); - const e = keyParams[1].toUint8Array(); - const d = keyParams[2].toUint8Array(); - const p = keyParams[3].toUint8Array(); - const q = keyParams[4].toUint8Array(); - const u = keyParams[5].toUint8Array(); - const valid = await openpgp.crypto.publicKey.rsa.validateParams(n, e, d, p, q, u); - expect(valid).to.be.true; + await expect(rsaKey.keyPacket.validate()).to.not.be.rejected; }); it('detect invalid RSA n', async function() { - const n = keyParams[0].toUint8Array(); - const e = keyParams[1].toUint8Array(); - const d = keyParams[2].toUint8Array(); - const p = keyParams[3].toUint8Array(); - const q = keyParams[4].toUint8Array(); - const u = keyParams[5].toUint8Array(); - - n[0]++; - const valid = await openpgp.crypto.publicKey.rsa.validateParams(n, e, d, p, q, u); - expect(valid).to.be.false; + const keyPacket = cloneKeyPacket(rsaKey); + const n = keyPacket.params[0]; + n.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('detect invalid RSA e', async function() { - const n = keyParams[0].toUint8Array(); - const e = keyParams[1].toUint8Array(); - const d = keyParams[2].toUint8Array(); - const p = keyParams[3].toUint8Array(); - const q = keyParams[4].toUint8Array(); - const u = keyParams[5].toUint8Array(); - - e[0]++; - const valid = await openpgp.crypto.publicKey.rsa.validateParams(n, e, d, p, q, u); - expect(valid).to.be.false; + const keyPacket = cloneKeyPacket(rsaKey); + const e = keyPacket.params[1]; + e.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); @@ -257,59 +275,34 @@ module.exports = () => { }); it('DSA params should be valid', async function() { - const params = dsaKey.keyPacket.params; - const p = params[0].toUint8Array(); - const q = params[1].toUint8Array(); - const g = params[2].toUint8Array(); - const y = params[3].toUint8Array(); - const x = params[4].toUint8Array(); - const valid = await openpgp.crypto.publicKey.dsa.validateParams(p, q, g, y, x); - expect(valid).to.be.true; + await expect(dsaKey.keyPacket.validate()).to.not.be.rejected; }); it('detect invalid DSA p', async function() { - const params = dsaKey.keyPacket.params; - const p = params[0].toUint8Array(); - const q = params[1].toUint8Array(); - const g = params[2].toUint8Array(); - const y = params[3].toUint8Array(); - const x = params[4].toUint8Array(); - - p[0]++; - const valid = await openpgp.crypto.publicKey.dsa.validateParams(p, q, g, y, x); - - expect(valid).to.be.false; + const keyPacket = cloneKeyPacket(dsaKey); + const p = keyPacket.params[0]; + p.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('detect invalid DSA y', async function() { - const params = dsaKey.keyPacket.params; - const p = params[0].toUint8Array(); - const q = params[1].toUint8Array(); - const g = params[2].toUint8Array(); - const y = params[3].toUint8Array(); - const x = params[4].toUint8Array(); + const keyPacket = cloneKeyPacket(dsaKey); + const y = keyPacket.params[3]; - y[0]++; - const valid = await openpgp.crypto.publicKey.dsa.validateParams(p, q, g, y, x); - - expect(valid).to.be.false; + y.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('detect invalid DSA g', async function() { - const params = dsaKey.keyPacket.params; - const p = params[0].toUint8Array(); - const q = params[1].toUint8Array(); - const g = params[2].toUint8Array(); - const y = params[3].toUint8Array(); - const x = params[4].toUint8Array(); + const keyPacket = cloneKeyPacket(dsaKey); + const g = keyPacket.params[2]; - g[0]++; - let valid = await openpgp.crypto.publicKey.dsa.validateParams(p, q, g, y, x); - expect(valid).to.be.false; + g.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); - const gOne = new Uint8Array([1]); - valid = await openpgp.crypto.publicKey.dsa.validateParams(p, q, gOne, y, x); - expect(valid).to.be.false; + const gOne = new openpgp.MPI(new Uint8Array([1])); + keyPacket.params[2] = gOne; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); @@ -320,70 +313,46 @@ module.exports = () => { }); it('params should be valid', async function() { - const params = egKey.keyPacket.params; - const p = params[0].toUint8Array(); - const g = params[1].toUint8Array(); - const y = params[2].toUint8Array(); - const x = params[3].toUint8Array(); - - const valid = await openpgp.crypto.publicKey.elgamal.validateParams(p, g, y, x); - expect(valid).to.be.true; + await expect(egKey.keyPacket.validate()).to.not.be.rejected; }); it('detect invalid p', async function() { - const params = egKey.keyPacket.params; - const p = params[0].toUint8Array(); - const g = params[1].toUint8Array(); - const y = params[2].toUint8Array(); - const x = params[3].toUint8Array(); - p[0]++; - const valid = await openpgp.crypto.publicKey.elgamal.validateParams(p, g, y, x); - - expect(valid).to.be.false; + const keyPacket = cloneKeyPacket(egKey); + const p = keyPacket.params[0]; + p.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('detect invalid y', async function() { - const params = egKey.keyPacket.params; - const p = params[0].toUint8Array(); - const g = params[1].toUint8Array(); - const y = params[2].toUint8Array(); - const x = params[3].toUint8Array(); - - y[0]++; - const valid = await openpgp.crypto.publicKey.elgamal.validateParams(p, g, y, x); - - expect(valid).to.be.false; + const keyPacket = cloneKeyPacket(egKey); + const y = keyPacket.params[2]; + y.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('detect invalid g', async function() { - const params = egKey.keyPacket.params; - const p = params[0].toUint8Array(); - const g = params[1].toUint8Array(); - const y = params[2].toUint8Array(); - const x = params[3].toUint8Array(); + const keyPacket = cloneKeyPacket(egKey); + const g = keyPacket.params[1]; - g[0]++; - let valid = await openpgp.crypto.publicKey.elgamal.validateParams(p, g, y, x); - expect(valid).to.be.false; + g.data[0]++; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); - const gOne = new Uint8Array([1]); - valid = await openpgp.crypto.publicKey.elgamal.validateParams(p, gOne, y, x); - expect(valid).to.be.false; + const gOne = new openpgp.MPI(new Uint8Array([1])); + keyPacket.params[1] = gOne; + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); it('detect g with small order', async function() { - const params = egKey.keyPacket.params; - const p = params[0].toUint8Array(); - const g = params[1].toUint8Array(); - const y = params[2].toUint8Array(); - const x = params[3].toUint8Array(); + const keyPacket = cloneKeyPacket(egKey); + const p = keyPacket.params[0].toUint8Array(); + const g = keyPacket.params[1].toUint8Array(); const pBN = new BN(p); const gModP = new BN(g).toRed(new BN.red(pBN)); // g**(p-1)/2 has order 2 const gOrd2 = gModP.redPow(pBN.subn(1).shrn(1)); - const valid = await openpgp.crypto.publicKey.elgamal.validateParams(p, gOrd2.toArrayLike(Uint8Array, 'be'), y, x); - expect(valid).to.be.false; + keyPacket.params[1] = new openpgp.MPI(gOrd2.toArrayLike(Uint8Array, 'be')); + await expect(keyPacket.validate()).to.be.rejectedWith('Key is invalid'); }); }); }; diff --git a/test/general/brainpool.js b/test/general/brainpool.js index e5bf8e5a..ae1de43f 100644 --- a/test/general/brainpool.js +++ b/test/general/brainpool.js @@ -184,7 +184,7 @@ EJ4QcD/oQ6x1M/8X/iKQCtxZP8RnlrbH7ExkNON5s5g= const pk = await openpgp.key.readArmored(data[name].priv); expect(pk).to.exist; expect(pk.getKeyId().toHex()).to.equal(data[name].id); - expect(await pk.decrypt(data[name].pass)).to.be.true; + await pk.decrypt(data[name].pass); data[name].priv_key = pk; return pk; } diff --git a/test/general/ecc_secp256k1.js b/test/general/ecc_secp256k1.js index 2877165b..fc0cd31a 100644 --- a/test/general/ecc_secp256k1.js +++ b/test/general/ecc_secp256k1.js @@ -154,7 +154,7 @@ module.exports = () => describe('Elliptic Curve Cryptography for secp256k1 curve const pk = await openpgp.key.readArmored(data[name].priv); expect(pk).to.exist; expect(pk.getKeyId().toHex()).to.equal(data[name].id); - expect(await pk.decrypt(data[name].pass)).to.be.true; + await pk.decrypt(data[name].pass); data[name].priv_key = pk; return pk; } diff --git a/test/general/key.js b/test/general/key.js index cd2bdaaa..c3e8b1b8 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2252,13 +2252,13 @@ function versionSpecificTests() { const armor1 = key.armor(); const armor2 = key.armor(); expect(armor1).to.equal(armor2); - expect(await key.decrypt('passphrase')).to.be.true; + await key.decrypt('passphrase'); expect(key.isDecrypted()).to.be.true; await key.encrypt('new_passphrase'); expect(key.isDecrypted()).to.be.false; - await expect(key.decrypt('passphrase')).to.eventually.be.rejectedWith('Incorrect key passphrase'); + await expect(key.decrypt('passphrase')).to.be.rejectedWith('Incorrect key passphrase'); expect(key.isDecrypted()).to.be.false; - expect(await key.decrypt('new_passphrase')).to.be.true; + await key.decrypt('new_passphrase'); expect(key.isDecrypted()).to.be.true; const armor3 = key.armor(); expect(armor3).to.not.equal(armor1); diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 5fea0f03..105ba282 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -374,6 +374,71 @@ EQr2Mx42THr260IFYp5E/rIA =oA0b -----END PGP PRIVATE KEY BLOCK-----`; +const mismatchingKeyParams = `-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: OpenPGP.js v4.7.0 +Comment: https://openpgpjs.org + +xcMGBF3ey50BCADaTsujZxXLCYBeaGd9qXqHc+oWtQF2BZdYWPvguljrYgrK +WwyoFy8cHaQyi3OTccFXVhFNDG+TgYUG9nk/jvsgOKiu4HugJR5/UPXapBwp +UooVtp9+0ppOJr9GWKeFNXP8tLLFHXSvApnRntbbHeYJoSEa4Ct2suStq/QU +NuO3ov9geiNo+BKIf8btm+urRN1jU2QAh9vkB8m3ZiNJhgR6Yoh5omwASLUz +qPQpuJmfTEnfA9EsaosrrJ2wzvA7enCHdsUFkhsKARCfCqy5sb90PkNXu3Vo +CybN9h0C801wrkYCBo2SW6mscd4I6Dk7FEoAD1bo5MJfGT96H059Ca9TABEB +AAH+CQMIZP38MpAOKygADY2D7fzhN5OxQe3vpprtJeqQ/BZ6g7VOd7Sdic2m +9MTTo/A0XTJxkxf9Rwakcgepm7KwyXE1ntWD9m/XqBzvagTiT4pykvTgm446 +hB/9zileZjp2vmQH+a0Q3X9jXSh0iHQmLTUWGu3Jd/iscGLUGgDPquKNa5Gr +cfjkxf0tG0JjS+mrdR836UOfHvLWbhbrAgrbCuOEC6ziQe+uFgktqWJPTurP +Op4fvFD9hggN+lVVLlFwa5N0gaX6GdQHfsktKw6/WTomdjTfWZi87SCz1sXD +o8Ob/679IjPwvl6gqVlr8iBhpYX3K3NyExRh4DQ2xYhGNtygtyiqSuYYGarm +lieJuRbx+sm6N4nwJgrvPx9h0MzX86X3n6RNZa7SppJQJ4Z7OrObvRbGsbOc +hY97shxWT7I7a9KUcmCxSf49GUsKJ5a9z/GS3QpCLxG0rZ3fDQ0sKEVSv+KP +OJyIiyPyvmlkblJCr83uqrVzJva6/vjZeQa0Wfp2ngh6sE4q+KE+tog0a989 +cuTBZwO2Pl9F9iGVKvL+I/PrBq5UFOk/F3mk8GsS2OuInm5gTcOhIDH6Blhz +WwLZIfNulozA8Ug2A8C0ntIQsL1Ie/1Yr14mdVk7xMuM7bgwQtQ4pAQcVI3e +CqyosP7L05ZQKV3FpI2jm+VxfzqsxqMuLwamrS0dB+Jm0KllwwS+Yr84W68S +v4w258HPRDFDdLveVj3wh7nh/PL4KVXjfR5rz1JNxsgKau/O5ipNcw6CDAQX +5eI3hAl+YfJs8fRPkvVuf3Nzw/Gs82Zvs6iZxgTqSCyJ/QAHmO+riEukblw2 +Y8EIAaq8QV4WYJs/3Ag3v+FY9x3G/Sf+NKXwnAH9mT+3J8k0JFY4tIXmOunB +6nWJReZvW5SVu4j2S3dDCX8pTwIPKok8zQDCwHUEEAEIAB8FAl3ey50GCwkH +CAMCBBUICgIDFgIBAhkBAhsDAh4BAAoJEMNNmgUbCqiXu74IAIzIFeCsco52 +FF2JBf1qffxveLB//lwaAqyAJDFHvrAjmHNFCrwNLmnnP4no7U4P6Zq9aQeK +ZCj9YMxykpO2tArcjSTCUklDjPj2IPe13vg4giiF9hwtlAKhPhrytqjgNwLF +ET/9hFtVWZtwaxx8PXXq8E48yOavSk7smKi+z89NloJH7ePzMzV2GfXe6mtH +qSkzjYJKy72YNvTStay5Tc/bt9zS3jbFv7QtUXRdudcLD0yZC//p3PPrAsaV +uCAPwz3fvKYX9kdWWrj98FvzzMxx3Lvh3zcEPaWLDOHOdJKHU/YxmrO0+Jxo +n9uUuQegJMKuiQ4G785Yo+zPjpTpXMTHwwYEXd7LnQEIAJ8lLko4nvEE3x+5 +M4sFNyIYdYK7qvETu9Sz7AOxbeOWiUY8Na2lDuwAmuYDEQcnax9Kh0D6gp1i +Z86WQwt3uCmLKATahlGolwbn47ztA0Ac8IbbswSr7OJNNJ1byS8h0udmc/SY +WSWVBeGAmj1Bat8X9nOakwskI8Sm44F/vAvZSIIQ7atzUQbSn9LHftfzWbAX +wX6LZGnLVn/E7e/YzULuvry7xmqiH/DmsfLLGn04HkcWeBweVo0QvPCETNgR +MUIL4o84Fo8MQPkPQafUO4uSkFHyixN3YnFwDRHYpn24R3dePLELXUblGANv +mtOubWvAkFhLVg2HkWJN9iwhLs8AEQEAAf4JAwjXnNHwEu9CWQDc+bM3IwYt +SUIwwdt7hT9C2FX3nrCPnzsKwI1jUrZOGe0LMSSIJNf5TyWAw6LNUrjnD4hg +UzIGvgZJDcRl8Ms3LMVaUZMFK/6XE5sdpD7cEgtxY1aGTAitOZ49hClaevnk +RCRqxT2C2A+GqyvIhr1w3i+AD+zYL1ygLiXpKad82Gbk2axJxcH/hljIKlqr +v114iGKMHVnqP5L+hM9am2Qu3M+BMROiE/XG82d8r1oAEpQZEXJNBuKSDtL+ +8256OQW1fSQTqkCSIPGVxejrb3TyeAklyQXtGD39rN2qYZcKecUGc2zB85zi +upoSSYdEfQWoNs/8Z26+17oqKMSl85mWtztz63OEWR7fGfmofiiU+tQw/ndz +cyvxSc/fIih3adJmFrTtX+nI6hbEVeBZCNhHSQE0I0YoQBfuAmAiNzeV1ISV +XgjuKHENPPY2bTZZ4Fxmua/OLE+3/nlIuw3LnfGDflv3HVzLJIzlOi5+t58Z +UMLKesj6Wv1+AW9J1qYEK7/sdpI1LNtde5YRK//gUM6AvvTgcYSWv0FnGYkr +xKFyYCTztOT4NbywTZNtIqVuHkmkV93PkW/lzR5rK7Hk7ec9lBYGcEOwlGAd +27fvkTAYLx5S3Qkce0Um3m36TMJ5sCJnZZJ/U/tETiZoq+fbi0Rh4WMNdHu/ +tdckiovkQtSRIJJT1tLY6DvssPGIh1oTyb2Lj9vw/BVFQkgLrpuSMtnJbStt +cJNpQZfmn2V85Z06qoH/WekQ404xX6+gVw+DetJc2fI4JEKYocUs8R406jRp +iBndPeORg3fw7C4BLavN6bvUF8qNIEfBNm6/gD5nCU1xflm+a/3dLWFH1R1g +tjO+0UCRVN7ExVq0m3hhQS2ETi8t3BbZCliMQ1J4k71GGwdA6e6Pu6Q86m4b +7PrCwF8EGAEIAAkFAl3ey50CGwwACgkQw02aBRsKqJdVvwf/UICpq9O09uuQ +MFKYevMLfEGF896TCe6sKtwpvyU5QX0xlODI554uJhIxUew6HPzafCO9SWfP +tas+15nI43pEc0VEnd31g3pqiKSd+PYolw4NfYI0jrcRabebGlGcprvoj2fD +C/wSMmcnvJkjFzUoDkRX3bMV1C7birw9C1QYOpEj8c0KGIsiVI45sGwFlclD +AxMSJy5Dv9gcVPq6V8fuPw05ODSpbieoIF3d3WuaI39lAZpfuhNaSNAQmzA7 +6os1UTIywR2rDFRWbh2IrviZ9BVkV6NXa9+gT+clr3PsE4XeADacVAa2MZNR +0NubenKyljKtyHyoU+S+TqUyx7gf5A== +=Lj9k +-----END PGP PRIVATE KEY BLOCK----- +`; + const rsaPrivateKeyPKCS1 = `-----BEGIN PGP PRIVATE KEY BLOCK----- xcLYBF7yFJcBCACv2ad3tpfA8agLV+7ZO+7vWAS8f4CgCLsW2fvyIG0X3to9 @@ -662,6 +727,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { let aeadModeVal; let aeadChunkSizeByteVal; let v5KeysVal; + let privateKeyMismatchingParams; beforeEach(async function() { publicKey = await openpgp.key.readArmored(pub_key); @@ -673,6 +739,8 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { publicKey_2038_2045 = privateKey_2038_2045.toPublic(); privateKey_1337 = await openpgp.key.readArmored(priv_key_expires_1337); publicKey_1337 = privateKey_1337.toPublic(); + privateKeyMismatchingParams = await openpgp.key.readArmored(mismatchingKeyParams); + useNativeVal = openpgp.config.useNative; aeadProtectVal = openpgp.config.aeadProtect; aeadModeVal = openpgp.config.aeadMode; @@ -703,8 +771,10 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { await expect(privateKey.decrypt('wrong passphrase')).to.eventually.be.rejectedWith('Incorrect key passphrase'); }); - it('Decrypting key with correct passphrase returns true', async function () { - expect(await privateKey.decrypt(passphrase)).to.be.true; + it('Can decrypt key with correct passphrase', async function () { + expect(privateKey.isDecrypted()).to.be.false; + await privateKey.decrypt(passphrase); + expect(privateKey.isDecrypted()).to.be.true; }); describe('decryptKey', function() { @@ -729,6 +799,17 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { expect(error.message).to.match(/Incorrect key passphrase/); }); }); + + it('should fail for corrupted key', function() { + return openpgp.decryptKey({ + privateKey: privateKeyMismatchingParams, + passphrase: 'userpass' + }).then(function() { + throw new Error('Should not decrypt corrupted key'); + }).catch(function(error){ + expect(error.message).to.match(/Key is invalid/); + }); + }); }); it('Calling decrypt with not decrypted key leads to exception', async function() { @@ -798,7 +879,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { let decryptedPrivateKey; beforeEach(async function() { if (!decryptedPrivateKey) { - expect(await privateKey.decrypt(passphrase)).to.be.true; + await privateKey.decrypt(passphrase); decryptedPrivateKey = privateKey; } privateKey = decryptedPrivateKey; @@ -958,7 +1039,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { let decryptedPrivateKey; beforeEach(async function() { if (!decryptedPrivateKey) { - expect(await privateKey.decrypt(passphrase)).to.be.true; + await privateKey.decrypt(passphrase); decryptedPrivateKey = privateKey; } privateKey = decryptedPrivateKey; @@ -1767,7 +1848,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() { let decryptedPrivateKey; beforeEach(async function() { if (!decryptedPrivateKey) { - expect(await privateKey.decrypt(passphrase)).to.be.true; + await privateKey.decrypt(passphrase); decryptedPrivateKey = privateKey; } privateKey = decryptedPrivateKey; diff --git a/test/general/x25519.js b/test/general/x25519.js index 184ac583..6ca608fc 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -136,7 +136,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr const pk = await openpgp.key.readArmored(data[name].priv); expect(pk).to.exist; expect(pk.getKeyId().toHex()).to.equal(data[name].id); - expect(await pk.decrypt(data[name].pass)).to.be.true; + await pk.decrypt(data[name].pass); data[name].priv_key = pk; return pk; }