From ecc38d0c6e1824a8546b18c7701f36cac423649d Mon Sep 17 00:00:00 2001 From: Mahrud Sayrafi Date: Tue, 27 Feb 2018 16:40:28 -0800 Subject: [PATCH] Adds worker tests for NIST P-256 and X25519 --- src/type/ecdh_symkey.js | 4 +- test/general/ecc_nist.js | 73 +++++++++++++++ test/general/x25519.js | 191 +++++++++++++++++++++------------------ 3 files changed, 179 insertions(+), 89 deletions(-) diff --git a/src/type/ecdh_symkey.js b/src/type/ecdh_symkey.js index ed0e9658..dfbf6a35 100644 --- a/src/type/ecdh_symkey.js +++ b/src/type/ecdh_symkey.js @@ -27,7 +27,7 @@ import util from '../util'; /** * @constructor */ -function ECDHSymmetricKey(data) { +export default function ECDHSymmetricKey(data) { if (typeof data === 'undefined') { data = new Uint8Array([]); } else if (util.isString(data)) { @@ -65,5 +65,3 @@ ECDHSymmetricKey.prototype.write = function () { ECDHSymmetricKey.fromClone = function (clone) { return new ECDHSymmetricKey(clone.data); }; - -export default ECDHSymmetricKey; diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js index 2b75c685..38350161 100644 --- a/test/general/ecc_nist.js +++ b/test/general/ecc_nist.js @@ -1,3 +1,5 @@ +/* globals tryTests: true */ + const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../../dist/openpgp'); const chai = require('chai'); @@ -234,4 +236,75 @@ describe('Elliptic Curve Cryptography', function () { expect(key.publicKeyArmored).to.exist; }); }); + + function omnibus() { + it('Omnibus NIST P-256 Test', function () { + const options = { userIds: {name: "Hi", email: "hi@hel.lo"}, curve: "p256" }; + return openpgp.generateKey(options).then(function (firstKey) { + const hi = firstKey.key; + const pubHi = hi.toPublic(); + + const options = { userIds: { name: "Bye", email: "bye@good.bye" }, curve: "p256" }; + return openpgp.generateKey(options).then(function (secondKey) { + const bye = secondKey.key; + const pubBye = bye.toPublic(); + + return Promise.all([ + // Signing message + openpgp.sign( + { data: 'Hi, this is me, Hi!', privateKeys: hi } + ).then(signed => { + const msg = openpgp.cleartext.readArmored(signed.data); + // Verifying signed message + return Promise.all([ + openpgp.verify( + { message: msg, publicKeys: pubHi } + ).then(output => expect(output.signatures[0].valid).to.be.true), + // Verifying detached signature + openpgp.verify( + { message: openpgp.message.fromText('Hi, this is me, Hi!'), + publicKeys: pubHi, + signature: openpgp.signature.readArmored(signed.data) } + ).then(output => expect(output.signatures[0].valid).to.be.true) + ]); + }), + // Encrypting and signing + openpgp.encrypt( + { data: 'Hi, Hi wrote this but only Bye can read it!', + publicKeys: [pubBye], + privateKeys: [hi] } + ).then(encrypted => { + const msg = openpgp.message.readArmored(encrypted.data); + // Decrypting and verifying + return openpgp.decrypt( + { message: msg, + privateKeys: bye, + publicKeys: [pubHi] } + ).then(output => { + expect(output.data).to.equal('Hi, Hi wrote this but only Bye can read it!'); + expect(output.signatures[0].valid).to.be.true; + }); + }) + ]); + }); + }); + }); + } + + omnibus(); + + tryTests('ECC Worker Tests', omnibus, { + if: typeof window !== 'undefined' && window.Worker, + before: function() { + openpgp.initWorker({ path:'../dist/openpgp.worker.js' }); + }, + beforeEach: function() { + openpgp.config.use_native = true; + }, + after: function() { + openpgp.destroyWorker(); + } + }); + + // TODO find test vectors }); diff --git a/test/general/x25519.js b/test/general/x25519.js index ac859525..2e04c1d8 100644 --- a/test/general/x25519.js +++ b/test/general/x25519.js @@ -147,6 +147,8 @@ describe('X25519 Cryptography', function () { done(); }); + // This test is slow because the keys are generated by GPG2, which + // by default chooses a larger number for S2K iterations than we do. it('Load private key', function (done) { load_priv_key('light'); load_priv_key('night'); @@ -217,103 +219,120 @@ describe('X25519 Cryptography', function () { }); }); - // TODO generate, export, then reimport key and validate - it('Omnibus Ed25519/Curve25519 Test', function () { - const options = { - userIds: {name: "Hi", email: "hi@hel.lo"}, - curve: "ed25519" - }; - return openpgp.generateKey(options).then(function (firstKey) { - expect(firstKey).to.exist; - expect(firstKey.privateKeyArmored).to.exist; - expect(firstKey.publicKeyArmored).to.exist; - expect(firstKey.key).to.exist; - expect(firstKey.key.primaryKey).to.exist; - expect(firstKey.key.subKeys).to.have.length(1); - expect(firstKey.key.subKeys[0].subKey).to.exist; - - const hi = firstKey.key; - const primaryKey = hi.primaryKey; - const subKey = hi.subKeys[0].subKey; - expect(primaryKey.params[0].toHex()).to.equal(elliptic.getCurve('ed25519').oid.toHex()); - expect(primaryKey.algorithm).to.equal('eddsa'); - expect(subKey.params[0].toHex()).to.equal(elliptic.getCurve('curve25519').oid.toHex()); - expect(subKey.algorithm).to.equal('ecdh'); - - // Self Certificate is valid - const user = hi.users[0]; - expect(user.selfCertifications[0].verify( - primaryKey, { userid: user.userId, key: primaryKey } - )).to.eventually.be.true; - expect(user.verifyCertificate( - primaryKey, user.selfCertifications[0], [hi.toPublic()] - )).to.eventually.equal(openpgp.enums.keyStatus.valid); - + // TODO export, then reimport key and validate + function omnibus() { + it('Omnibus Ed25519/Curve25519 Test', function () { const options = { - userIds: { name: "Bye", email: "bye@good.bye" }, - curve: "curve25519" + userIds: {name: "Hi", email: "hi@hel.lo"}, + curve: "ed25519" }; - return openpgp.generateKey(options).then(function (secondKey) { - const bye = secondKey.key; - expect(bye.primaryKey.params[0].toHex()).to.equal(elliptic.getCurve('ed25519').oid.toHex()); - expect(bye.primaryKey.algorithm).to.equal('eddsa'); - expect(bye.subKeys[0].subKey.params[0].toHex()).to.equal(elliptic.getCurve('curve25519').oid.toHex()); - expect(bye.subKeys[0].subKey.algorithm).to.equal('ecdh'); + return openpgp.generateKey(options).then(function (firstKey) { + expect(firstKey).to.exist; + expect(firstKey.privateKeyArmored).to.exist; + expect(firstKey.publicKeyArmored).to.exist; + expect(firstKey.key).to.exist; + expect(firstKey.key.primaryKey).to.exist; + expect(firstKey.key.subKeys).to.have.length(1); + expect(firstKey.key.subKeys[0].subKey).to.exist; + + const hi = firstKey.key; + const primaryKey = hi.primaryKey; + const subKey = hi.subKeys[0].subKey; + expect(primaryKey.params[0].toHex()).to.equal(elliptic.getCurve('ed25519').oid.toHex()); + expect(primaryKey.algorithm).to.equal('eddsa'); + expect(subKey.params[0].toHex()).to.equal(elliptic.getCurve('curve25519').oid.toHex()); + expect(subKey.algorithm).to.equal('ecdh'); // Self Certificate is valid - const user = bye.users[0]; + const user = hi.users[0]; expect(user.selfCertifications[0].verify( - bye.primaryKey, { userid: user.userId, key: bye.primaryKey } + primaryKey, { userid: user.userId, key: primaryKey } )).to.eventually.be.true; expect(user.verifyCertificate( - bye.primaryKey, user.selfCertifications[0], [bye.toPublic()] + primaryKey, user.selfCertifications[0], [hi.toPublic()] )).to.eventually.equal(openpgp.enums.keyStatus.valid); - return Promise.all([ - // Hi trusts Bye! - bye.toPublic().signPrimaryUser([hi]).then(trustedBye => { - expect(trustedBye.users[0].otherCertifications[0].verify( - primaryKey, { userid: user.userId, key: bye.toPublic().primaryKey } - )).to.eventually.be.true; - }), - // Signing message - openpgp.sign( - { data: 'Hi, this is me, Hi!', privateKeys: hi } - ).then(signed => { - const msg = openpgp.cleartext.readArmored(signed.data); - // Verifying signed message - return Promise.all([ - openpgp.verify( - { message: msg, publicKeys: hi.toPublic() } - ).then(output => expect(output.signatures[0].valid).to.be.true), - // Verifying detached signature - openpgp.verify( - { message: openpgp.message.fromText('Hi, this is me, Hi!'), - publicKeys: hi.toPublic(), - signature: openpgp.signature.readArmored(signed.data) } - ).then(output => expect(output.signatures[0].valid).to.be.true) - ]); - }), - // Encrypting and signing - openpgp.encrypt( - { data: 'Hi, Hi wrote this but only Bye can read it!', - publicKeys: [bye.toPublic()], - privateKeys: [hi] } - ).then(encrypted => { - const msg = openpgp.message.readArmored(encrypted.data); - // Decrypting and verifying - return openpgp.decrypt( - { message: msg, - privateKeys: bye, - publicKeys: [hi.toPublic()] } - ).then(output => { - expect(output.data).to.equal('Hi, Hi wrote this but only Bye can read it!'); - expect(output.signatures[0].valid).to.be.true; - }); - }) - ]); + const options = { + userIds: { name: "Bye", email: "bye@good.bye" }, + curve: "curve25519" + }; + return openpgp.generateKey(options).then(function (secondKey) { + const bye = secondKey.key; + expect(bye.primaryKey.params[0].toHex()).to.equal(elliptic.getCurve('ed25519').oid.toHex()); + expect(bye.primaryKey.algorithm).to.equal('eddsa'); + expect(bye.subKeys[0].subKey.params[0].toHex()).to.equal(elliptic.getCurve('curve25519').oid.toHex()); + expect(bye.subKeys[0].subKey.algorithm).to.equal('ecdh'); + + // Self Certificate is valid + const user = bye.users[0]; + expect(user.selfCertifications[0].verify( + bye.primaryKey, { userid: user.userId, key: bye.primaryKey } + )).to.eventually.be.true; + expect(user.verifyCertificate( + bye.primaryKey, user.selfCertifications[0], [bye.toPublic()] + )).to.eventually.equal(openpgp.enums.keyStatus.valid); + + return Promise.all([ + // Hi trusts Bye! + bye.toPublic().signPrimaryUser([hi]).then(trustedBye => { + expect(trustedBye.users[0].otherCertifications[0].verify( + primaryKey, { userid: user.userId, key: bye.toPublic().primaryKey } + )).to.eventually.be.true; + }), + // Signing message + openpgp.sign( + { data: 'Hi, this is me, Hi!', privateKeys: hi } + ).then(signed => { + const msg = openpgp.cleartext.readArmored(signed.data); + // Verifying signed message + return Promise.all([ + openpgp.verify( + { message: msg, publicKeys: hi.toPublic() } + ).then(output => expect(output.signatures[0].valid).to.be.true), + // Verifying detached signature + openpgp.verify( + { message: openpgp.message.fromText('Hi, this is me, Hi!'), + publicKeys: hi.toPublic(), + signature: openpgp.signature.readArmored(signed.data) } + ).then(output => expect(output.signatures[0].valid).to.be.true) + ]); + }), + // Encrypting and signing + openpgp.encrypt( + { data: 'Hi, Hi wrote this but only Bye can read it!', + publicKeys: [bye.toPublic()], + privateKeys: [hi] } + ).then(encrypted => { + const msg = openpgp.message.readArmored(encrypted.data); + // Decrypting and verifying + return openpgp.decrypt( + { message: msg, + privateKeys: bye, + publicKeys: [hi.toPublic()] } + ).then(output => { + expect(output.data).to.equal('Hi, Hi wrote this but only Bye can read it!'); + expect(output.signatures[0].valid).to.be.true; + }); + }) + ]); + }); }); }); + } + + omnibus(); + + tryTests('X25519 Worker Tests', omnibus, { + if: typeof window !== 'undefined' && window.Worker, + before: function() { + openpgp.initWorker({ path:'../dist/openpgp.worker.js' }); + }, + beforeEach: function() { + openpgp.config.use_native = true; + }, + after: function() { + openpgp.destroyWorker(); + } }); describe('Ed25519 Test Vectors from RFC8032', function () {