From e4bd27ce2f7336851d89f378b749abef144e1f1a Mon Sep 17 00:00:00 2001 From: Sanjana Rajan Date: Sun, 15 Apr 2018 12:38:36 -0700 Subject: [PATCH] tests --- src/key.js | 28 +++++++++--------- test/general/key.js | 64 ++++++++++++++++++++++++++++++++++++++++- test/general/openpgp.js | 34 +++++++--------------- 3 files changed, 87 insertions(+), 39 deletions(-) diff --git a/src/key.js b/src/key.js index 8fdebd7c..83246c8f 100644 --- a/src/key.js +++ b/src/key.js @@ -1101,7 +1101,7 @@ export function readArmored(armoredText) { * @param {String} options.passphrase The passphrase used to encrypt the resulting private key * @param {Number} [options.keyExpirationTime=0] * The number of seconds after the key creation time that the key expires - * @param {String} curve (optional) elliptic curve for ECC keys: + * @param {String} curve (optional) elliptic curve for ECC keys * @param {Date} date Override the creation date of the key and the key signatures * @param {Array} subkeys (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}] * sign parameter defaults to false, and indicates whether the subkey should sign rather than encrypt @@ -1110,13 +1110,13 @@ export function readArmored(armoredText) { * @static */ export async function generate(options) { - + options.sign = true; // primary key is always a signing key options = sanitizeKeyOptions(options); options.subkeys = options.subkeys.map(function(subkey, index) { return sanitizeKeyOptions(options.subkeys[index], options); }); let promises = [generateSecretKey(options)]; promises = promises.concat(options.subkeys.map(generateSecretSubkey)); - return Promise.all(promises).then(packets => wrapKeyObject(packets, options)); + return Promise.all(promises).then(packets => wrapKeyObject(packets[0], packets.slice(1), options)); function sanitizeKeyOptions(options, subkeyDefaults={}) { options.curve = options.curve || subkeyDefaults.curve; @@ -1134,17 +1134,18 @@ export async function generate(options) { throw new Error('Not valid curve.'); } if (options.curve === enums.curve.ed25519 || options.curve === enums.curve.curve25519) { - if (!subkeyDefaults.algorithm || options.sign) { - options.algorithm = options.algorithm || enums.publicKey.eddsa; + if (options.sign) { + options.algorithm = enums.publicKey.eddsa; options.curve = enums.curve.ed25519; } else { - options.algorithm = options.algorithm || enums.publicKey.ecdh; + options.algorithm = enums.publicKey.ecdh; options.curve = enums.curve.curve25519; } } else { - options.algorithm = options.algorithm || (!subkeyDefaults.algorithm ? enums.publicKey.ecdsa : enums.publicKey.ecdh); - if (options.algorithm !== enums.publicKey.ecdh && options.algorithm !== enums.publicKey.ecdsa) { - throw new Error('Invalid algorithm for curve'); + if (options.sign) { + options.algorithm = enums.publicKey.ecdsa; + } else { + options.algorithm = enums.publicKey.ecdh; } } } else if (options.numBits) { @@ -1225,9 +1226,9 @@ export async function reformat(options) { options.subkeys = options.subkeys.map(function(subkey, index) { return sanitizeKeyOptions(options.subkeys[index], options); }); - return wrapKeyObject([secretKeyPacket].concat(secretSubkeyPackets), options); + return wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options); - function sanitizeKeyOptions(options, subkeyDefaults={}) { + function sanitizeKeyOptions(options, subkeyDefaults={}) { options.keyExpirationTime = options.keyExpirationTime || subkeyDefaults.keyExpirationTime; options.passphrase = util.isString(options.passphrase) ? options.passphrase : subkeyDefaults.passphrase; options.date = options.date || subkeyDefaults.date; @@ -1236,9 +1237,7 @@ export async function reformat(options) { } } -async function wrapKeyObject(packets, options) { - const secretKeyPacket = packets[0]; - const secretSubkeyPackets = packets.slice(1); +async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options) { // set passphrase protection if (options.passphrase) { await secretKeyPacket.encrypt(options.passphrase); @@ -1293,7 +1292,6 @@ async function wrapKeyObject(packets, options) { signaturePacket.keyExpirationTime = options.keyExpirationTime; signaturePacket.keyNeverExpires = false; } - await signaturePacket.sign(secretKeyPacket, dataToSign); return { userIdPacket, signaturePacket }; diff --git a/test/general/key.js b/test/general/key.js index 425962a6..e9d09db5 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -1081,7 +1081,6 @@ describe('Key', function() { const opt = { userIds: { name: 'Test User', email: 'text@example.com' }, passphrase: 'secret', - unlocked: true, date: past }; @@ -1108,6 +1107,47 @@ describe('Key', function() { }); }); + it('Generate key - two subkeys with default values', function() { + const userId = 'test '; + const opt = {curve: 'curve25519', userIds: [userId], passphrase: '123', subkeys:[{},{}]}; + return openpgp.generateKey(opt).then(function(key) { + key = key.key; + expect(key.users.length).to.equal(1); + expect(key.users[0].userId.userid).to.equal(userId); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.subKeys).to.have.lengthOf(2); + expect(key.subKeys[0].subKey.algorithm).to.equal('ecdh'); + expect(key.subKeys[1].subKey.algorithm).to.equal('ecdh'); + }); + }); + + it('Generate key - one signing subkey', function() { + const userId = 'test '; + const opt = {curve: 'curve25519', userIds: [userId], passphrase: '123', subkeys:[{}, {sign: true}]}; + return openpgp.generateKey(opt).then(function(key) { + key = key.key; + expect(key.users.length).to.equal(1); + expect(key.users[0].userId.userid).to.equal(userId); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.subKeys).to.have.lengthOf(2); + expect(key.subKeys[0].subKey.algorithm).to.equal('ecdh'); + expect(key.subKeys[1].subKey.algorithm).to.equal('eddsa'); + }); + }); + + it('Generate key - override main key options for subkey', function() { + const userId = 'test '; + const opt = {numBits: 2048, userIds: [userId], passphrase: '123', subkeys:[{curve: 'curve25519'}]}; + return openpgp.generateKey(opt).then(function(key) { + key = key.key; + expect(key.users.length).to.equal(1); + expect(key.users[0].userId.userid).to.equal(userId); + expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true; + expect(key.primaryKey.algorithm).to.equal('rsa_encrypt_sign'); + expect(key.subKeys[0].subKey.algorithm).to.equal('ecdh'); + }); + }); + it('Encrypt key with new passphrase', async function() { const userId = 'test '; const opt = {numBits: 512, userIds: userId, passphrase: 'passphrase'}; @@ -1261,6 +1301,28 @@ describe('Key', function() { }); }); + it('Reformat key with two subkeys with passphrase', function() { + const userId1 = 'test '; + const userId2 = 'test '; + const now = openpgp.util.normalizeDate(new Date()); + const before = openpgp.util.normalizeDate(new Date(0)); + const opt1 = {curve: 'curve25519', userIds: [userId1], date: now}; + return openpgp.generateKey(opt1).then(function(newKey) { + newKey = newKey.key; + expect(newKey.users[0].userId.userid).to.equal(userId1); + expect(+newKey.primaryKey.created).to.equal(+now); + expect(+newKey.subKeys[0].subKey.created).to.equal(+now); + expect(+newKey.subKeys[0].bindingSignatures[0].created).to.equal(+now); + const opt2 = {privateKey: newKey, userIds: [userId2], date: before}; + return openpgp.reformatKey(opt2).then(function(refKey) { + refKey = refKey.key; + expect(refKey.users.length).to.equal(1); + expect(refKey.users[0].userId.userid).to.equal(userId2); + expect(+refKey.subKeys[0].bindingSignatures[0].created).to.equal(+before); + }); + }); + }); + it('Reformat key with no subkey without passphrase', function() { const userId = 'test1 '; const keys = openpgp.key.readArmored(key_without_subkey).keys; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 2ff92576..59901a86 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -483,22 +483,22 @@ describe('OpenPGP.js public api tests', function() { }); it('should have default params set', function() { - const now = new Date(); + const now = openpgp.util.normalizeDate(new Date()); const opt = { userIds: { name: 'Test User', email: 'text@example.com' }, passphrase: 'secret', - unlocked: true, - date: now + date: now, + subkeys: [] }; return openpgp.generateKey(opt).then(function(newKey) { expect(keyGenStub.withArgs({ userIds: ['Test User '], passphrase: 'secret', numBits: 2048, - unlocked: true, keyExpirationTime: 0, curve: "", - date: now + date: now, + subkeys: [], }).calledOnce).to.be.true; expect(newKey.key).to.exist; expect(newKey.privateKeyArmored).to.exist; @@ -506,23 +506,6 @@ describe('OpenPGP.js public api tests', function() { }); }); - it('should work for no params', function() { - const now = new Date(); - - return openpgp.generateKey({date: now}).then(function(newKey) { - expect(keyGenStub.withArgs({ - userIds: [], - passphrase: undefined, - numBits: 2048, - unlocked: false, - keyExpirationTime: 0, - curve: "", - date: now - }).calledOnce).to.be.true; - expect(newKey.key).to.exist; - }); - }); - it('should delegate to async proxy', function() { const workerStub = { postMessage: function() {} @@ -533,7 +516,12 @@ describe('OpenPGP.js public api tests', function() { const proxyGenStub = stub(openpgp.getWorker(), 'delegate'); getWebCryptoAllStub.returns(); - openpgp.generateKey(); + const opt = { + userIds: { name: 'Test User', email: 'text@example.com' }, + passphrase: 'secret', + subkeys: [] + }; + openpgp.generateKey(opt); expect(proxyGenStub.calledOnce).to.be.true; expect(keyGenStub.calledOnce).to.be.false; });