diff --git a/src/key.js b/src/key.js index 74786e40..3fc308d0 100644 --- a/src/key.js +++ b/src/key.js @@ -916,16 +916,15 @@ function generate(options) { if (options.keyType !== enums.publicKey.rsa_encrypt_sign) { throw new Error('Only RSA Encrypt or Sign supported'); } - if (!options.passphrase) { - throw new Error('Parameter options.passphrase required'); - } var packetlist = new packet.List(); var secretKeyPacket = new packet.SecretKey(); secretKeyPacket.algorithm = enums.read(enums.publicKey, options.keyType); secretKeyPacket.generate(options.numBits); - secretKeyPacket.encrypt(options.passphrase); + if (options.passphrase) { + secretKeyPacket.encrypt(options.passphrase); + } var userIdPacket = new packet.Userid(); userIdPacket.read(options.userId); @@ -960,7 +959,9 @@ function generate(options) { var secretSubkeyPacket = new packet.SecretSubkey(); secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.keyType); secretSubkeyPacket.generate(options.numBits); - secretSubkeyPacket.encrypt(options.passphrase); + if (options.passphrase) { + secretSubkeyPacket.encrypt(options.passphrase); + } dataToSign = {}; dataToSign.key = secretKeyPacket; diff --git a/src/message.js b/src/message.js index 5fd6ffc8..8adacfb1 100644 --- a/src/message.js +++ b/src/message.js @@ -236,16 +236,18 @@ Message.prototype.verify = function(keys) { for (var i = 0; i < signatureList.length; i++) { keyPacket = key.getKeyPacket([signatureList[i].issuerKeyId]); if (keyPacket) { - var verifiedSig = {}; - verifiedSig.keyid = signatureList[i].issuerKeyId; - verifiedSig.valid = signatureList[i].verify(keyPacket, literalDataList[0]); - result.push(verifiedSig); break; } } - if (!keyPacket) { - throw new Error('No matching signature found for specified keys.'); + var verifiedSig = {}; + if (keyPacket) { + verifiedSig.keyid = signatureList[i].issuerKeyId; + verifiedSig.valid = signatureList[i].verify(keyPacket, literalDataList[0]); + } else { + verifiedSig.keyid = key.primaryKey.keyid; + verifiedSig.valid = null; } + result.push(verifiedSig); }); return result; }; diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index f48a7545..be3cc5aa 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -170,10 +170,18 @@ SecretKey.prototype.write = function () { /** Encrypt the payload. By default, we use aes256 and iterated, salted string - * to key specifier + * to key specifier. If the key is in a decrypted state (isDecrypted == true) + * and the passphrase is empty or undefined, the key will be set as not encrypted. + * This can be used to remove passphrase protection after calling decrypt(). * @param {String} passphrase */ SecretKey.prototype.encrypt = function (passphrase) { + if (this.isDecrypted && !passphrase) { + this.encrypted = null; + return; + } else if (!passphrase) { + throw new Error('The key must be decrypted before removing passphrase protection.'); + } var s2k = new type_s2k(), symmetric = 'aes256', diff --git a/test/general/basic.js b/test/general/basic.js index 060b7414..c954b42b 100644 --- a/test/general/basic.js +++ b/test/general/basic.js @@ -84,14 +84,11 @@ describe('Basic', function() { var anotherKey = openpgp.generateKeyPair({numBits: 512, userId: userid, passphrase: passphrase}); var anotherPubKey = openpgp.key.readArmored(anotherKey.publicKeyArmored).keys[0]; - var decrypted; - try { - decrypted = openpgp.decryptAndVerifyMessage(privKey, [anotherPubKey], msg); - } catch(e) { - expect(e).to.exist; - expect(decrypted).to.not.exist; - done(); - } + var decrypted = openpgp.decryptAndVerifyMessage(privKey, [anotherPubKey], msg); + expect(decrypted).to.exist; + expect(decrypted.signatures[0].valid).to.be.null; + expect(decrypted.text).to.equal(message); + done(); }); it('Performance test', function (done) {