Remove duplicate tests

Many tests would run for every encryption mode, or for both V4 and V5 keys,
without there being any difference between the different test runs.

`grunt coverage` before and after this commit reports almost identical
statistics, providing some confidence that no code coverage was lost.
This commit is contained in:
Daniel Huigens 2018-07-27 17:18:35 +02:00
parent 225f586970
commit 67b067b1da
2 changed files with 1814 additions and 1791 deletions

View File

@ -6,40 +6,6 @@ chai.use(require('chai-as-promised'));
const { expect } = chai; const { expect } = chai;
describe('Key', function() {
let rsaGenStub;
let rsaGenValue = openpgp.crypto.publicKey.rsa.generate(openpgp.util.getWebCryptoAll() ? 2048 : 512, "10001");
beforeEach(function() {
rsaGenStub = stub(openpgp.crypto.publicKey.rsa, 'generate');
rsaGenStub.returns(rsaGenValue);
});
afterEach(function() {
rsaGenStub.restore();
});
describe('V4', tests);
describe('V5', function() {
let aead_protectVal;
let aead_protect_versionVal;
beforeEach(function() {
aead_protectVal = openpgp.config.aead_protect;
aead_protect_versionVal = openpgp.config.aead_protect_version;
openpgp.config.aead_protect = true;
openpgp.config.aead_protect_version = 4;
});
afterEach(function() {
openpgp.config.aead_protect = aead_protectVal;
openpgp.config.aead_protect_version = aead_protect_versionVal;
});
tests();
});
});
function tests() {
const priv_key_arm2 = const priv_key_arm2 =
['-----BEGIN PGP PRIVATE KEY BLOCK-----', ['-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG v2.0.19 (GNU/Linux)', 'Version: GnuPG v2.0.19 (GNU/Linux)',
@ -821,15 +787,6 @@ zoGJ6s48HcP591pN93uAitCcYcinY2ZslmdiCXw+zbeoX4spNrV4T4CYxBjNQdIa
'-----END PGP PRIVATE KEY BLOCK-----' '-----END PGP PRIVATE KEY BLOCK-----'
].join('\n'); ].join('\n');
it('Parsing armored text with RSA key and ECC subkey', async function() {
openpgp.config.tolerant = true;
const pubKeys = await openpgp.key.readArmored(rsa_ecc_pub);
expect(pubKeys).to.exist;
expect(pubKeys.err).to.not.exist;
expect(pubKeys.keys).to.have.length(1);
expect(pubKeys.keys[0].getKeyId().toHex()).to.equal('b8e4105cc9dedc77');
});
const multi_uid_key = const multi_uid_key =
['-----BEGIN PGP PUBLIC KEY BLOCK-----', ['-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v1', 'Version: GnuPG v1',
@ -1264,6 +1221,462 @@ t/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU=
=C0fJ =C0fJ
-----END PGP PRIVATE KEY BLOCK-----`; -----END PGP PRIVATE KEY BLOCK-----`;
function versionSpecificTests() {
it('Preferences of generated key', function() {
const testPref = function(key) {
// key flags
const keyFlags = openpgp.enums.keyFlags;
expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.certify_keys).to.equal(keyFlags.certify_keys);
expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.sign_data).to.equal(keyFlags.sign_data);
expect(key.subKeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encrypt_communication).to.equal(keyFlags.encrypt_communication);
expect(key.subKeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encrypt_storage).to.equal(keyFlags.encrypt_storage);
const sym = openpgp.enums.symmetric;
expect(key.users[0].selfCertifications[0].preferredSymmetricAlgorithms).to.eql([sym.aes256, sym.aes128, sym.aes192, sym.cast5, sym.tripledes]);
if (openpgp.config.aead_protect && openpgp.config.aead_protect_version === 4) {
const aead = openpgp.enums.aead;
expect(key.users[0].selfCertifications[0].preferredAeadAlgorithms).to.eql([aead.eax, aead.ocb]);
}
const hash = openpgp.enums.hash;
expect(key.users[0].selfCertifications[0].preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512, hash.sha1]);
const compr = openpgp.enums.compression;
expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.zlib, compr.zip]);
expect(key.users[0].selfCertifications[0].features).to.eql(openpgp.config.aead_protect && openpgp.config.aead_protect_version === 4 ? [7] : [1]);
};
const opt = {numBits: 512, userIds: 'test <a@b.com>', passphrase: 'hello'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(async function(key) {
testPref(key.key);
testPref((await openpgp.key.readArmored(key.publicKeyArmored)).keys[0]);
});
});
it('Generated key is not unlocked by default', function() {
const opt = {numBits: 512, userIds: 'test <a@b.com>', passphrase: '123'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
let key;
return openpgp.generateKey(opt).then(function(newKey) {
key = newKey.key;
return openpgp.message.fromText('hello').encrypt([key]);
}).then(function(msg) {
return msg.message.decrypt([key]);
}).catch(function(err) {
expect(err.message).to.equal('Private key is not decrypted.');
});
});
it('Generate key - single userid', function() {
const userId = { name: 'test', email: 'a@b.com', comment: 'test comment' };
const opt = {numBits: 512, userIds: userId, passphrase: '123'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
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('test <a@b.com> (test comment)');
expect(key.users[0].userId.name).to.equal(userId.name);
expect(key.users[0].userId.email).to.equal(userId.email);
expect(key.users[0].userId.comment).to.equal(userId.comment);
});
});
it('Generate key - setting date to the past', function() {
const past = new Date(0);
const opt = {
numBits: 512,
userIds: { name: 'Test User', email: 'text@example.com' },
passphrase: 'secret',
date: past
};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(newKey) {
expect(newKey.key).to.exist;
expect(+newKey.key.getCreationTime()).to.equal(+past);
expect(+newKey.key.subKeys[0].getCreationTime()).to.equal(+past);
expect(+newKey.key.subKeys[0].bindingSignatures[0].created).to.equal(+past);
});
})
it('Generate key - multi userid', function() {
const userId1 = 'test <a@b.com>';
const userId2 = 'test <b@c.com>';
const opt = {numBits: 512, userIds: [userId1, userId2], passphrase: '123'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(key) {
key = key.key;
expect(key.users.length).to.equal(2);
expect(key.users[0].userId.userid).to.equal(userId1);
expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true;
expect(key.users[1].userId.userid).to.equal(userId2);
expect(key.users[1].selfCertifications[0].isPrimaryUserID).to.be.null;
});
});
it('Generate key - two subkeys with default values', function() {
const userId = 'test <a@b.com>';
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].getAlgorithmInfo().algorithm).to.equal('ecdh');
expect(key.subKeys[1].getAlgorithmInfo().algorithm).to.equal('ecdh');
});
});
it('Generate key - one signing subkey', function() {
const userId = 'test <a@b.com>';
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].getAlgorithmInfo().algorithm).to.equal('ecdh');
expect(key.subKeys[1].getAlgorithmInfo().algorithm).to.equal('eddsa');
});
});
it('Generate key - override main key options for subkey', function() {
const userId = 'test <a@b.com>';
const opt = {numBits: 512, userIds: [userId], passphrase: '123', subkeys:[{curve: 'curve25519'}]};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
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.getAlgorithmInfo().algorithm).to.equal('rsa_encrypt_sign');
expect(key.subKeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh');
});
});
it('Encrypt key with new passphrase', async function() {
const userId = 'test <a@b.com>';
const opt = {numBits: 512, userIds: userId, passphrase: 'passphrase'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
const key = (await openpgp.generateKey(opt)).key;
const armor1 = key.armor();
const armor2 = key.armor();
expect(armor1).to.equal(armor2);
expect(await key.decrypt('passphrase')).to.be.true;
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');
expect(key.isDecrypted()).to.be.false;
expect(await key.decrypt('new_passphrase')).to.be.true;
expect(key.isDecrypted()).to.be.true;
const armor3 = key.armor();
expect(armor3).to.not.equal(armor1);
});
it('Generate key - ensure keyExpirationTime works', function() {
const expect_delta = 365 * 24 * 60 * 60;
const userId = 'test <a@b.com>';
const opt = {numBits: 512, userIds: userId, passphrase: '123', keyExpirationTime: expect_delta};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(async function(key) {
key = key.key;
const expiration = await key.getExpirationTime();
expect(expiration).to.exist;
const actual_delta = (new Date(expiration) - new Date()) / 1000;
expect(Math.abs(actual_delta - expect_delta)).to.be.below(60);
const subKeyExpiration = await key.subKeys[0].getExpirationTime();
expect(subKeyExpiration).to.exist;
const actual_subKeyDelta = (new Date(subKeyExpiration) - new Date()) / 1000;
expect(Math.abs(actual_subKeyDelta - expect_delta)).to.be.below(60);
});
});
it('Sign and verify key - primary user', async function() {
let publicKey = (await openpgp.key.readArmored(pub_sig_test)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signPrimaryUser([privateKey]);
const signatures = await publicKey.verifyPrimaryUser([privateKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(2);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.true;
});
it('Sign key and verify with wrong key - primary user', async function() {
let publicKey = (await openpgp.key.readArmored(pub_sig_test)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
const wrongKey = (await openpgp.key.readArmored(wrong_key)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signPrimaryUser([privateKey]);
const signatures = await publicKey.verifyPrimaryUser([wrongKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(2);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.null;
});
it('Sign and verify key - all users', async function() {
let publicKey = (await openpgp.key.readArmored(multi_uid_key)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signAllUsers([privateKey]);
const signatures = await publicKey.verifyAllUsers([privateKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(4);
expect(signatures[0].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.true;
expect(signatures[2].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[2].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[2].valid).to.be.null;
expect(signatures[3].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[3].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[3].valid).to.be.true;
});
it('Sign key and verify with wrong key - all users', async function() {
let publicKey = (await openpgp.key.readArmored(multi_uid_key)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
const wrongKey = (await openpgp.key.readArmored(wrong_key)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signAllUsers([privateKey]);
const signatures = await publicKey.verifyAllUsers([wrongKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(4);
expect(signatures[0].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.null;
expect(signatures[2].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[2].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[2].valid).to.be.null;
expect(signatures[3].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[3].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[3].valid).to.be.null;
});
it('Reformat key without passphrase', function() {
const userId1 = 'test1 <a@b.com>';
const userId2 = 'test2 <b@a.com>';
const opt = {numBits: 512, userIds: userId1};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
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(userId1);
expect(key.isDecrypted()).to.be.true;
opt.privateKey = key;
opt.userIds = userId2;
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(1);
expect(newKey.users[0].userId.userid).to.equal(userId2);
expect(newKey.isDecrypted()).to.be.true;
});
});
});
it('Reformat key with no subkey with passphrase', async function() {
const userId = 'test1 <a@b.com>';
const keys = (await openpgp.key.readArmored(key_without_subkey)).keys;
const opt = {privateKey: keys[0], userIds: [userId], passphrase: "test"};
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(1);
expect(newKey.users[0].userId.userid).to.equal(userId);
expect(newKey.isDecrypted()).to.be.false;
});
});
it('Reformat key with two subkeys with passphrase', function() {
const userId1 = 'test <a@b.com>';
const userId2 = 'test <b@c.com>';
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.getCreationTime()).to.equal(+now);
expect(+newKey.subKeys[0].getCreationTime()).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', async function() {
const userId = 'test1 <a@b.com>';
const keys = (await openpgp.key.readArmored(key_without_subkey)).keys;
const opt = {privateKey: keys[0], userIds: [userId]};
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(1);
expect(newKey.users[0].userId.userid).to.equal(userId);
expect(newKey.isDecrypted()).to.be.true;
return openpgp.sign({message: openpgp.cleartext.fromText('hello'), privateKeys: newKey, armor: true}).then(async function(signed) {
return openpgp.verify(
{message: await openpgp.cleartext.readArmored(signed.data), publicKeys: newKey.toPublic()}
).then(async function(verified) {
expect(verified.signatures[0].valid).to.be.true;
const newSigningKey = await newKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(newSigningKey.getKeyId().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1);
});
});
});
});
it('Reformat and encrypt key', function() {
const userId1 = 'test1 <a@b.com>';
const userId2 = 'test2 <b@c.com>';
const userId3 = 'test3 <c@d.com>';
const opt = {numBits: 512, userIds: userId1};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(key) {
key = key.key;
opt.privateKey = key;
opt.userIds = [userId2, userId3];
opt.passphrase = '123';
return openpgp.reformatKey(opt).then(async function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(2);
expect(newKey.users[0].userId.userid).to.equal(userId2);
expect(newKey.isDecrypted()).to.be.false;
await newKey.decrypt('123');
expect(newKey.isDecrypted()).to.be.true;
});
});
});
it('Sign and encrypt with reformatted key', function() {
const userId1 = 'test1 <a@b.com>';
const userId2 = 'test2 <b@a.com>';
const opt = {numBits: 512, userIds: userId1};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(key) {
key = key.key;
opt.privateKey = key;
opt.userIds = userId2;
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
return openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: newKey.toPublic(), privateKeys: newKey, armor: true}).then(async function(encrypted) {
return openpgp.decrypt({message: await openpgp.message.readArmored(encrypted.data), privateKeys: newKey, publicKeys: newKey.toPublic()}).then(function(decrypted) {
expect(decrypted.data).to.equal('hello');
expect(decrypted.signatures[0].valid).to.be.true;
});
});
});
});
});
it('Reject with user-friendly error when reformatting encrypted key', function() {
const opt = {numBits: 512, userIds: 'test1 <a@b.com>', passphrase: '1234'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(original) {
return openpgp.reformatKey({privateKey: original.key, userIds: 'test2 <b@a.com>', passphrase: '1234'}).then(function() {
throw new Error('reformatKey should result in error when key not decrypted');
}).catch(function(error) {
expect(error.message).to.equal('Error reformatting keypair: Key not decrypted');
});
});
});
it('Revoke generated key with revocation certificate', function() {
const opt = {numBits: 512, userIds: 'test1 <a@b.com>', passphrase: '1234'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(original) {
return openpgp.revokeKey({key: original.key.toPublic(), revocationCertificate: original.revocationCertificate}).then(function(revKey) {
revKey = revKey.publicKey;
expect(revKey.revocationSignatures[0].reasonForRevocationFlag).to.equal(openpgp.enums.reasonForRevocation.no_reason);
expect(revKey.revocationSignatures[0].reasonForRevocationString).to.equal('');
return revKey.verifyPrimaryKey().then(function(status) {
expect(status).to.equal(openpgp.enums.keyStatus.revoked);
});
});
});
});
it('Revoke generated key with private key', function() {
const opt = {numBits: 512, userIds: 'test1 <a@b.com>', passphrase: '1234'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(async function(original) {
await original.key.decrypt('1234');
return openpgp.revokeKey({key: original.key, reasonForRevocation: {string: 'Testing key revocation'}}).then(function(revKey) {
revKey = revKey.publicKey;
expect(revKey.revocationSignatures[0].reasonForRevocationFlag).to.equal(openpgp.enums.reasonForRevocation.no_reason);
expect(revKey.revocationSignatures[0].reasonForRevocationString).to.equal('Testing key revocation');
return revKey.verifyPrimaryKey().then(function(status) {
expect(status).to.equal(openpgp.enums.keyStatus.revoked);
});
});
});
});
}
describe('Key', function() {
let rsaGenStub;
let rsaGenValue = openpgp.crypto.publicKey.rsa.generate(openpgp.util.getWebCryptoAll() ? 2048 : 512, "10001");
beforeEach(function() {
rsaGenStub = stub(openpgp.crypto.publicKey.rsa, 'generate');
rsaGenStub.returns(rsaGenValue);
});
afterEach(function() {
rsaGenStub.restore();
});
describe('V4', versionSpecificTests);
describe('V5', function() {
let aead_protectVal;
let aead_protect_versionVal;
beforeEach(function() {
aead_protectVal = openpgp.config.aead_protect;
aead_protect_versionVal = openpgp.config.aead_protect_version;
openpgp.config.aead_protect = true;
openpgp.config.aead_protect_version = 4;
});
afterEach(function() {
openpgp.config.aead_protect = aead_protectVal;
openpgp.config.aead_protect_version = aead_protect_versionVal;
});
versionSpecificTests();
});
it('Parsing armored text with RSA key and ECC subkey', async function() {
openpgp.config.tolerant = true;
const pubKeys = await openpgp.key.readArmored(rsa_ecc_pub);
expect(pubKeys).to.exist;
expect(pubKeys.err).to.not.exist;
expect(pubKeys.keys).to.have.length(1);
expect(pubKeys.keys[0].getKeyId().toHex()).to.equal('b8e4105cc9dedc77');
});
it('Parsing armored text with two keys', async function() { it('Parsing armored text with two keys', async function() {
const pubKeys = await openpgp.key.readArmored(twoKeys); const pubKeys = await openpgp.key.readArmored(twoKeys);
@ -1659,34 +2072,6 @@ t/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU=
expect(supported).to.be.false; expect(supported).to.be.false;
}); });
it('Preferences of generated key', function() {
const testPref = function(key) {
// key flags
const keyFlags = openpgp.enums.keyFlags;
expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.certify_keys).to.equal(keyFlags.certify_keys);
expect(key.users[0].selfCertifications[0].keyFlags[0] & keyFlags.sign_data).to.equal(keyFlags.sign_data);
expect(key.subKeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encrypt_communication).to.equal(keyFlags.encrypt_communication);
expect(key.subKeys[0].bindingSignatures[0].keyFlags[0] & keyFlags.encrypt_storage).to.equal(keyFlags.encrypt_storage);
const sym = openpgp.enums.symmetric;
expect(key.users[0].selfCertifications[0].preferredSymmetricAlgorithms).to.eql([sym.aes256, sym.aes128, sym.aes192, sym.cast5, sym.tripledes]);
if (openpgp.config.aead_protect && openpgp.config.aead_protect_version === 4) {
const aead = openpgp.enums.aead;
expect(key.users[0].selfCertifications[0].preferredAeadAlgorithms).to.eql([aead.eax, aead.ocb]);
}
const hash = openpgp.enums.hash;
expect(key.users[0].selfCertifications[0].preferredHashAlgorithms).to.eql([hash.sha256, hash.sha512, hash.sha1]);
const compr = openpgp.enums.compression;
expect(key.users[0].selfCertifications[0].preferredCompressionAlgorithms).to.eql([compr.zlib, compr.zip]);
expect(key.users[0].selfCertifications[0].features).to.eql(openpgp.config.aead_protect && openpgp.config.aead_protect_version === 4 ? [7] : [1]);
};
const opt = {numBits: 512, userIds: 'test <a@b.com>', passphrase: 'hello'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(async function(key) {
testPref(key.key);
testPref((await openpgp.key.readArmored(key.publicKeyArmored)).keys[0]);
});
});
it('User attribute packet read & write', async function() { it('User attribute packet read & write', async function() {
const key = (await openpgp.key.readArmored(user_attr_key)).keys[0]; const key = (await openpgp.key.readArmored(user_attr_key)).keys[0];
const key2 = (await openpgp.key.readArmored(key.armor())).keys[0]; const key2 = (await openpgp.key.readArmored(key.armor())).keys[0];
@ -1722,229 +2107,6 @@ VYGdb3eNlV8CfoEC
expect(primUser).to.be.null; expect(primUser).to.be.null;
}); });
it('Generated key is not unlocked by default', function() {
const opt = {numBits: 512, userIds: 'test <a@b.com>', passphrase: '123'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
let key;
return openpgp.generateKey(opt).then(function(newKey) {
key = newKey.key;
return openpgp.message.fromText('hello').encrypt([key]);
}).then(function(msg) {
return msg.message.decrypt([key]);
}).catch(function(err) {
expect(err.message).to.equal('Private key is not decrypted.');
});
});
it('Generate key - single userid', function() {
const userId = { name: 'test', email: 'a@b.com', comment: 'test comment' };
const opt = {numBits: 512, userIds: userId, passphrase: '123'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
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('test <a@b.com> (test comment)');
expect(key.users[0].userId.name).to.equal(userId.name);
expect(key.users[0].userId.email).to.equal(userId.email);
expect(key.users[0].userId.comment).to.equal(userId.comment);
});
});
it('Generate key - setting date to the past', function() {
const past = new Date(0);
const opt = {
numBits: 512,
userIds: { name: 'Test User', email: 'text@example.com' },
passphrase: 'secret',
date: past
};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(newKey) {
expect(newKey.key).to.exist;
expect(+newKey.key.getCreationTime()).to.equal(+past);
expect(+newKey.key.subKeys[0].getCreationTime()).to.equal(+past);
expect(+newKey.key.subKeys[0].bindingSignatures[0].created).to.equal(+past);
});
})
it('Generate key - multi userid', function() {
const userId1 = 'test <a@b.com>';
const userId2 = 'test <b@c.com>';
const opt = {numBits: 512, userIds: [userId1, userId2], passphrase: '123'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(key) {
key = key.key;
expect(key.users.length).to.equal(2);
expect(key.users[0].userId.userid).to.equal(userId1);
expect(key.users[0].selfCertifications[0].isPrimaryUserID).to.be.true;
expect(key.users[1].userId.userid).to.equal(userId2);
expect(key.users[1].selfCertifications[0].isPrimaryUserID).to.be.null;
});
});
it('Generate key - two subkeys with default values', function() {
const userId = 'test <a@b.com>';
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].getAlgorithmInfo().algorithm).to.equal('ecdh');
expect(key.subKeys[1].getAlgorithmInfo().algorithm).to.equal('ecdh');
});
});
it('Generate key - one signing subkey', function() {
const userId = 'test <a@b.com>';
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].getAlgorithmInfo().algorithm).to.equal('ecdh');
expect(key.subKeys[1].getAlgorithmInfo().algorithm).to.equal('eddsa');
});
});
it('Generate key - override main key options for subkey', function() {
const userId = 'test <a@b.com>';
const opt = {numBits: 512, userIds: [userId], passphrase: '123', subkeys:[{curve: 'curve25519'}]};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
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.getAlgorithmInfo().algorithm).to.equal('rsa_encrypt_sign');
expect(key.subKeys[0].getAlgorithmInfo().algorithm).to.equal('ecdh');
});
});
it('Encrypt key with new passphrase', async function() {
const userId = 'test <a@b.com>';
const opt = {numBits: 512, userIds: userId, passphrase: 'passphrase'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
const key = (await openpgp.generateKey(opt)).key;
const armor1 = key.armor();
const armor2 = key.armor();
expect(armor1).to.equal(armor2);
expect(await key.decrypt('passphrase')).to.be.true;
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');
expect(key.isDecrypted()).to.be.false;
expect(await key.decrypt('new_passphrase')).to.be.true;
expect(key.isDecrypted()).to.be.true;
const armor3 = key.armor();
expect(armor3).to.not.equal(armor1);
});
it('Generate key - ensure keyExpirationTime works', function() {
const expect_delta = 365 * 24 * 60 * 60;
const userId = 'test <a@b.com>';
const opt = {numBits: 512, userIds: userId, passphrase: '123', keyExpirationTime: expect_delta};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(async function(key) {
key = key.key;
const expiration = await key.getExpirationTime();
expect(expiration).to.exist;
const actual_delta = (new Date(expiration) - new Date()) / 1000;
expect(Math.abs(actual_delta - expect_delta)).to.be.below(60);
const subKeyExpiration = await key.subKeys[0].getExpirationTime();
expect(subKeyExpiration).to.exist;
const actual_subKeyDelta = (new Date(subKeyExpiration) - new Date()) / 1000;
expect(Math.abs(actual_subKeyDelta - expect_delta)).to.be.below(60);
});
});
it('Sign and verify key - primary user', async function() {
let publicKey = (await openpgp.key.readArmored(pub_sig_test)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signPrimaryUser([privateKey]);
const signatures = await publicKey.verifyPrimaryUser([privateKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(2);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.true;
});
it('Sign key and verify with wrong key - primary user', async function() {
let publicKey = (await openpgp.key.readArmored(pub_sig_test)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
const wrongKey = (await openpgp.key.readArmored(wrong_key)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signPrimaryUser([privateKey]);
const signatures = await publicKey.verifyPrimaryUser([wrongKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(2);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.null;
});
it('Sign and verify key - all users', async function() {
let publicKey = (await openpgp.key.readArmored(multi_uid_key)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signAllUsers([privateKey]);
const signatures = await publicKey.verifyAllUsers([privateKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(4);
expect(signatures[0].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.true;
expect(signatures[2].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[2].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[2].valid).to.be.null;
expect(signatures[3].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[3].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[3].valid).to.be.true;
});
it('Sign key and verify with wrong key - all users', async function() {
let publicKey = (await openpgp.key.readArmored(multi_uid_key)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
const wrongKey = (await openpgp.key.readArmored(wrong_key)).keys[0];
await privateKey.decrypt('hello world');
publicKey = await publicKey.signAllUsers([privateKey]);
const signatures = await publicKey.verifyAllUsers([wrongKey]);
const publicSigningKey = await publicKey.getSigningKey();
const privateSigningKey = await privateKey.getSigningKey();
expect(signatures.length).to.equal(4);
expect(signatures[0].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[0].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[0].valid).to.be.null;
expect(signatures[1].userid).to.equal(publicKey.users[0].userId.userid);
expect(signatures[1].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[1].valid).to.be.null;
expect(signatures[2].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[2].keyid.toHex()).to.equal(publicSigningKey.getKeyId().toHex());
expect(signatures[2].valid).to.be.null;
expect(signatures[3].userid).to.equal(publicKey.users[1].userId.userid);
expect(signatures[3].keyid.toHex()).to.equal(privateSigningKey.getKeyId().toHex());
expect(signatures[3].valid).to.be.null;
});
it('Encrypt - latest created user', async function() { it('Encrypt - latest created user', async function() {
let publicKey = (await openpgp.key.readArmored(multi_uid_key)).keys[0]; let publicKey = (await openpgp.key.readArmored(multi_uid_key)).keys[0];
const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0]; const privateKey = (await openpgp.key.readArmored(priv_key_rsa)).keys[0];
@ -2000,138 +2162,6 @@ VYGdb3eNlV8CfoEC
await expect(openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, fromUserId: {name: 'Not Test McTestington', email: 'test@example.com'}, detached: true, armor: false})).to.be.rejectedWith('Could not find user that matches that user ID'); await expect(openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, fromUserId: {name: 'Not Test McTestington', email: 'test@example.com'}, detached: true, armor: false})).to.be.rejectedWith('Could not find user that matches that user ID');
}); });
it('Reformat key without passphrase', function() {
const userId1 = 'test1 <a@b.com>';
const userId2 = 'test2 <b@a.com>';
const opt = {numBits: 512, userIds: userId1};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
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(userId1);
expect(key.isDecrypted()).to.be.true;
opt.privateKey = key;
opt.userIds = userId2;
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(1);
expect(newKey.users[0].userId.userid).to.equal(userId2);
expect(newKey.isDecrypted()).to.be.true;
});
});
});
it('Reformat key with no subkey with passphrase', async function() {
const userId = 'test1 <a@b.com>';
const keys = (await openpgp.key.readArmored(key_without_subkey)).keys;
const opt = {privateKey: keys[0], userIds: [userId], passphrase: "test"};
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(1);
expect(newKey.users[0].userId.userid).to.equal(userId);
expect(newKey.isDecrypted()).to.be.false;
});
});
it('Reformat key with two subkeys with passphrase', function() {
const userId1 = 'test <a@b.com>';
const userId2 = 'test <b@c.com>';
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.getCreationTime()).to.equal(+now);
expect(+newKey.subKeys[0].getCreationTime()).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', async function() {
const userId = 'test1 <a@b.com>';
const keys = (await openpgp.key.readArmored(key_without_subkey)).keys;
const opt = {privateKey: keys[0], userIds: [userId]};
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(1);
expect(newKey.users[0].userId.userid).to.equal(userId);
expect(newKey.isDecrypted()).to.be.true;
return openpgp.sign({message: openpgp.cleartext.fromText('hello'), privateKeys: newKey, armor: true}).then(async function(signed) {
return openpgp.verify(
{message: await openpgp.cleartext.readArmored(signed.data), publicKeys: newKey.toPublic()}
).then(async function(verified) {
expect(verified.signatures[0].valid).to.be.true;
const newSigningKey = await newKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(newSigningKey.getKeyId().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1);
});
});
});
});
it('Reformat and encrypt key', function() {
const userId1 = 'test1 <a@b.com>';
const userId2 = 'test2 <b@c.com>';
const userId3 = 'test3 <c@d.com>';
const opt = {numBits: 512, userIds: userId1};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(key) {
key = key.key;
opt.privateKey = key;
opt.userIds = [userId2, userId3];
opt.passphrase = '123';
return openpgp.reformatKey(opt).then(async function(newKey) {
newKey = newKey.key;
expect(newKey.users.length).to.equal(2);
expect(newKey.users[0].userId.userid).to.equal(userId2);
expect(newKey.isDecrypted()).to.be.false;
await newKey.decrypt('123');
expect(newKey.isDecrypted()).to.be.true;
});
});
});
it('Sign and encrypt with reformatted key', function() {
const userId1 = 'test1 <a@b.com>';
const userId2 = 'test2 <b@a.com>';
const opt = {numBits: 512, userIds: userId1};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(key) {
key = key.key;
opt.privateKey = key;
opt.userIds = userId2;
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
return openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: newKey.toPublic(), privateKeys: newKey, armor: true}).then(async function(encrypted) {
return openpgp.decrypt({message: await openpgp.message.readArmored(encrypted.data), privateKeys: newKey, publicKeys: newKey.toPublic()}).then(function(decrypted) {
expect(decrypted.data).to.equal('hello');
expect(decrypted.signatures[0].valid).to.be.true;
});
});
});
});
});
it('Reject with user-friendly error when reformatting encrypted key', function() {
const opt = {numBits: 512, userIds: 'test1 <a@b.com>', passphrase: '1234'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(original) {
return openpgp.reformatKey({privateKey: original.key, userIds: 'test2 <b@a.com>', passphrase: '1234'}).then(function() {
throw new Error('reformatKey should result in error when key not decrypted');
}).catch(function(error) {
expect(error.message).to.equal('Error reformatting keypair: Key not decrypted');
});
});
});
it('Find a valid subkey binding signature among many invalid ones', async function() { it('Find a valid subkey binding signature among many invalid ones', async function() {
const key = (await openpgp.key.readArmored(valid_binding_sig_among_many_expired_sigs_pub)).keys[0]; const key = (await openpgp.key.readArmored(valid_binding_sig_among_many_expired_sigs_pub)).keys[0];
expect(await key.getEncryptionKey()).to.not.be.null; expect(await key.getEncryptionKey()).to.not.be.null;
@ -2160,37 +2190,6 @@ VYGdb3eNlV8CfoEC
}); });
}); });
it('Revoke generated key with revocation certificate', function() {
const opt = {numBits: 512, userIds: 'test1 <a@b.com>', passphrase: '1234'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(function(original) {
return openpgp.revokeKey({key: original.key.toPublic(), revocationCertificate: original.revocationCertificate}).then(function(revKey) {
revKey = revKey.publicKey;
expect(revKey.revocationSignatures[0].reasonForRevocationFlag).to.equal(openpgp.enums.reasonForRevocation.no_reason);
expect(revKey.revocationSignatures[0].reasonForRevocationString).to.equal('');
return revKey.verifyPrimaryKey().then(function(status) {
expect(status).to.equal(openpgp.enums.keyStatus.revoked);
});
});
});
});
it('Revoke generated key with private key', function() {
const opt = {numBits: 512, userIds: 'test1 <a@b.com>', passphrase: '1234'};
if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys
return openpgp.generateKey(opt).then(async function(original) {
await original.key.decrypt('1234');
return openpgp.revokeKey({key: original.key, reasonForRevocation: {string: 'Testing key revocation'}}).then(function(revKey) {
revKey = revKey.publicKey;
expect(revKey.revocationSignatures[0].reasonForRevocationFlag).to.equal(openpgp.enums.reasonForRevocation.no_reason);
expect(revKey.revocationSignatures[0].reasonForRevocationString).to.equal('Testing key revocation');
return revKey.verifyPrimaryKey().then(function(status) {
expect(status).to.equal(openpgp.enums.keyStatus.revoked);
});
});
});
});
it('Merge key with another key with non-ID user attributes', async function() { it('Merge key with another key with non-ID user attributes', async function() {
const key = (await openpgp.key.readArmored(mergeKey1)).keys[0]; const key = (await openpgp.key.readArmored(mergeKey1)).keys[0];
const updateKey = (await openpgp.key.readArmored(mergeKey2)).keys[0]; const updateKey = (await openpgp.key.readArmored(mergeKey2)).keys[0];
@ -2204,4 +2203,4 @@ VYGdb3eNlV8CfoEC
expect(key.users[1].userId).to.be.null; expect(key.users[1].userId).to.be.null;
}); });
}); });
} });

View File

@ -654,6 +654,53 @@ describe('OpenPGP.js public api tests', function() {
openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteVal; openpgp.config.aead_chunk_size_byte = aead_chunk_size_byteVal;
}); });
it('Configuration', function() {
openpgp.config.show_version = false;
openpgp.config.commentstring = 'different';
if (openpgp.getWorker()) { // init again to trigger config event
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
}
return openpgp.encrypt({ publicKeys:publicKey.keys, message:openpgp.message.fromText(plaintext) }).then(function(encrypted) {
expect(encrypted.data).to.exist;
expect(encrypted.data).not.to.match(/^Version:/);
expect(encrypted.data).to.match(/Comment: different/);
});
});
it('Test multiple workers', async function() {
openpgp.config.show_version = false;
openpgp.config.commentstring = 'different';
if (!openpgp.getWorker()) {
return;
}
const { workers } = openpgp.getWorker();
try {
await privateKey.keys[0].decrypt(passphrase)
openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 2});
const workerTest = (_, index) => {
const plaintext = input.createSomeMessage() + index;
return openpgp.encrypt({
publicKeys: publicKey.keys,
data: plaintext
}).then(function (encrypted) {
expect(encrypted.data).to.exist;
expect(encrypted.data).not.to.match(/^Version:/);
expect(encrypted.data).to.match(/Comment: different/);
return openpgp.decrypt({
privateKeys: privateKey.keys[0],
message: openpgp.message.readArmored(encrypted.data)
});
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
});
};
await Promise.all(Array(10).fill(null).map(workerTest));
} finally {
openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 1 });
}
});
it('Decrypting key with wrong passphrase rejected', async function () { it('Decrypting key with wrong passphrase rejected', async function () {
await expect(privateKey.keys[0].decrypt('wrong passphrase')).to.eventually.be.rejectedWith('Incorrect key passphrase'); await expect(privateKey.keys[0].decrypt('wrong passphrase')).to.eventually.be.rejectedWith('Incorrect key passphrase');
}); });
@ -662,6 +709,43 @@ describe('OpenPGP.js public api tests', function() {
expect(await privateKey.keys[0].decrypt(passphrase)).to.be.true; expect(await privateKey.keys[0].decrypt(passphrase)).to.be.true;
}); });
describe('decryptKey', function() {
it('should work for correct passphrase', function() {
return openpgp.decryptKey({
privateKey: privateKey.keys[0],
passphrase: passphrase
}).then(function(unlocked){
expect(unlocked.key.getKeyId().toHex()).to.equal(privateKey.keys[0].getKeyId().toHex());
expect(unlocked.key.isDecrypted()).to.be.true;
});
});
it('should fail for incorrect passphrase', function() {
return openpgp.decryptKey({
privateKey: privateKey.keys[0],
passphrase: 'incorrect'
}).catch(function(error){
expect(error.message).to.match(/Incorrect key passphrase/);
});
});
});
it('Calling decrypt with not decrypted key leads to exception', function() {
const encOpt = {
message: openpgp.message.fromText(plaintext),
publicKeys: publicKey.keys
};
const decOpt = {
privateKeys: privateKey.keys[0]
};
return openpgp.encrypt(encOpt).then(async function(encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).catch(function(error) {
expect(error.message).to.match(/not decrypted/);
});
});
tryTests('CFB mode (asm.js)', tests, { tryTests('CFB mode (asm.js)', tests, {
if: !(typeof window !== 'undefined' && window.Worker), if: !(typeof window !== 'undefined' && window.Worker),
beforeEach: function() { beforeEach: function() {
@ -730,90 +814,6 @@ describe('OpenPGP.js public api tests', function() {
}); });
function tests() { function tests() {
it('Configuration', function() {
openpgp.config.show_version = false;
openpgp.config.commentstring = 'different';
if (openpgp.getWorker()) { // init again to trigger config event
openpgp.initWorker({ path:'../dist/openpgp.worker.js' });
}
return openpgp.encrypt({ publicKeys:publicKey.keys, message:openpgp.message.fromText(plaintext) }).then(function(encrypted) {
expect(encrypted.data).to.exist;
expect(encrypted.data).not.to.match(/^Version:/);
expect(encrypted.data).to.match(/Comment: different/);
});
});
it('Test multiple workers', async function() {
openpgp.config.show_version = false;
openpgp.config.commentstring = 'different';
if (!openpgp.getWorker()) {
return;
}
const { workers } = openpgp.getWorker();
try {
await privateKey.keys[0].decrypt(passphrase)
openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 2});
const workerTest = (_, index) => {
const plaintext = input.createSomeMessage() + index;
return openpgp.encrypt({
publicKeys: publicKey.keys,
data: plaintext
}).then(function (encrypted) {
expect(encrypted.data).to.exist;
expect(encrypted.data).not.to.match(/^Version:/);
expect(encrypted.data).to.match(/Comment: different/);
return openpgp.decrypt({
privateKeys: privateKey.keys[0],
message: openpgp.message.readArmored(encrypted.data)
});
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
});
};
await Promise.all(Array(10).fill(null).map(workerTest));
} finally {
openpgp.initWorker({path: '../dist/openpgp.worker.js', workers, n: 1 });
}
});
it('Calling decrypt with not decrypted key leads to exception', function() {
const encOpt = {
message: openpgp.message.fromText(plaintext),
publicKeys: publicKey.keys
};
const decOpt = {
privateKeys: privateKey.keys[0]
};
return openpgp.encrypt(encOpt).then(async function(encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).catch(function(error) {
expect(error.message).to.match(/not decrypted/);
});
});
describe('decryptKey', function() {
it('should work for correct passphrase', function() {
return openpgp.decryptKey({
privateKey: privateKey.keys[0],
passphrase: passphrase
}).then(function(unlocked){
expect(unlocked.key.getKeyId().toHex()).to.equal(privateKey.keys[0].getKeyId().toHex());
expect(unlocked.key.isDecrypted()).to.be.true;
});
});
it('should fail for incorrect passphrase', function() {
return openpgp.decryptKey({
privateKey: privateKey.keys[0],
passphrase: 'incorrect'
}).catch(function(error){
expect(error.message).to.match(/Incorrect key passphrase/);
});
});
});
describe('encryptSessionKey, decryptSessionKeys', function() { describe('encryptSessionKey, decryptSessionKeys', function() {
const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]); const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]);
@ -1538,6 +1538,265 @@ describe('OpenPGP.js public api tests', function() {
expect(decrypted.signatures[1].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].signature.packets.length).to.equal(1);
}); });
}); });
});
describe('ELG / DSA encrypt, decrypt, sign, verify', function() {
it('round trip test', async function () {
const pubKeyDE = (await openpgp.key.readArmored(pub_key_de)).keys[0];
const privKeyDE = (await openpgp.key.readArmored(priv_key_de)).keys[0];
await privKeyDE.decrypt(passphrase);
pubKeyDE.users[0].selfCertifications[0].features = [7]; // Monkey-patch AEAD feature flag
return openpgp.encrypt({
publicKeys: pubKeyDE,
privateKeys: privKeyDE,
message: openpgp.message.fromText(plaintext)
}).then(async function (encrypted) {
return openpgp.decrypt({
privateKeys: privKeyDE,
publicKeys: pubKeyDE,
message: await openpgp.message.readArmored(encrypted.data)
});
}).then(async function (decrypted) {
expect(decrypted.data).to.exist;
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privKeyDE.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
});
});
});
describe("3DES decrypt", function() {
const pgp_msg =
['-----BEGIN PGP MESSAGE-----',
'Version: GnuPG/MacGPG2 v2.0.19 (Darwin)',
'Comment: GPGTools - https://gpgtools.org',
'',
'hIwDBU4Dycfvp2EBA/9tuhQgOrcATcm2PRmIOcs6q947YhlsBTZZdVJDfVjkKlyM',
'M0yE+lnNplWb041Cpfkkl6IvorKQd2iPbAkOL0IXwmVN41l+PvVgMcuFvvzetehG',
'Ca0/VEYOaTZRNqyr9FIzcnVy1I/PaWT3iqVAYa+G8TEA5Dh9RLfsx8ZA9UNIaNI+',
'ASm9aZ3H6FerNhm8RezDY5vRn6xw3o/wH5YEBvV2BEmmFKZ2BlqFQxqChr8UNwd1',
'Ieebnq0HtBPE8YU/L0U=',
'=JyIa',
'-----END PGP MESSAGE-----'].join('\n');
const priv_key =
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG/MacGPG2 v2.0.19 (Darwin)',
'Comment: GPGTools - https://gpgtools.org',
'',
'lQH+BFLqLegBBAC/rN3g30Jrcpx5lTb7Kxe+ZfS7ppOIoBjjN+qcOh81cJJVS5dT',
'UGcDsm2tCLVS3P2dGaYhfU9fsoSq/wK/tXsdoWXvXdjHbbueyi1kTZqlnyT190UE',
'vmDxH0yqquvUaf7+CNXC0T6l9gGS9p0x7xNydWRb7zeK1wIsYI+dRGQmzQARAQAB',
'/gMDArgQHMknurQXy0Pho3Nsdu6zCUNXuplvaSXruefKsQn6eexGPnecNTT2iy5N',
'70EK371D7GcNhhLsn8roUcj1Hi3kR14wXW7lcQBy9RRbbglIJXIqKJ8ywBEO8BaQ',
'b0plL+w5A9EvX0BQc4d53MTqySh6POsEDOxPzH4D/JWbaozfmc4LfGDqH1gl7ebY',
'iu81vnBuuskjpz8rxRI81MldJEIObrTE2x46DF7AmS6L6u/Qz3AAmZd89p5INCdx',
'DemxzuMKpC3wSgdgSSKHHTKiNOMxiRd5mFH5v1KVcEG/TyXFlmah7RwA4rA4fjeo',
'OpnbVWp6ciUniRvgLaCMMbmolAoho9zaLbPzCQVQ8F7gkrjnnPm4MKA+AUXmjt7t',
'VrrYkyTp1pxLZyUWX9+aKoxEO9OIDz7p9Mh02BZ/tznQ7U+IV2bcNhwrL6LPk4Mb',
'J4YF/cLVxFVVma88GSFikSjPf30AUty5nBQFtbFGqnPctCF0aHJvd2F3YXkgPHRo',
'cm93YXdheUBleGFtcGxlLmNvbT6IuAQTAQIAIgUCUuot6AIbAwYLCQgHAwIGFQgC',
'CQoLBBYCAwECHgECF4AACgkQkk2hoj5duD/HZQP/ZXJ8PSlA1oj1NW97ccT0LiNH',
'WzxPPoH9a/qGQYg61jp+aTa0C5hlYY/GgeFpiZlpwVUtlkZYfslXJqbCcp3os4xt',
'kiukDbPnq2Y41wNVxXrDw6KbOjohbhzeRUh8txbkiXGiwHtHBSJsPMntN6cB3vn3',
'08eE69vOiHPQfowa2CmdAf4EUuot6AEEAOQpNjkcTUo14JQ2o+mrpxj5yXbGtZKh',
'D8Ll+aZZrIDIa44p9KlQ3aFzPxdmFBiBX57m1nQukr58FQ5Y/FuQ1dKYc3M8QdZL',
'vCKDC8D9ZJf13iwUjYkfn/e/bDqCS2piyd63zI0xDJo+s2bXCIJxgrhbOqFDeFd6',
'4W8PfBOvUuRjABEBAAH+AwMCuBAcySe6tBfLV0P5MbBesR3Ifu/ppjzLoXKhwkqm',
'PXf09taLcRfUHeMbPjboj2P2m2UOnSrbXK9qsDQ8XOMtdsEWGLWpmiqnMlkiOchv',
'MsNRYpZ67iX3JVdxNuhs5+g5bdP1PNVbKiTzx73u1h0SS93IJp1jFj50/kyGl1Eq',
'tkr0TWe5uXCh6cSZDPwhto0a12GeDHehdTw6Yq4KoZHccneHhN9ySFy0DZOeULIi',
'Y61qtR0io52T7w69fBe9Q5/d5SwpwWKMpCTOqvvzdHX7JmeFtV+2vRVilIif7AfP',
'AD+OjQ/OhMu3jYO+XNhm3raPT2tIBsBdl2UiHOnj4AUNuLuUJeVghtz4Qt6dvjyz',
'PlBvSF+ESqALjM8IqnG15FX4LmEDFrFcfNCsnmeyZ2nr1h2mV5jOON0EmBtCyhCt',
'D/Ivi4/SZk+tBVhsBI+7ZECZYDJzZQnyPDsUv31MU4OwdWi7FhzHvDj/0bhYY7+I',
'nwQYAQIACQUCUuot6AIbDAAKCRCSTaGiPl24PwYAA/sGIHvCKWP5+4ZlBHuOdbP9',
'9v3PXFCm61qFEL0DTSq7NgBcuf0ASRElRI3wIKlfkwaiSzVPfNLiMTexdc7XaiTz',
'CHaOn1Xl2gmYTq2KiJkgtLuwptYU1iSj7vvSHKy0+nYIckOZB4pRCOjknT08O4ZJ',
'22q10ausyQXoOxXfDWVwKA==',
'=IkKW',
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
it('Decrypt message', async function() {
const privKey = (await openpgp.key.readArmored(priv_key)).keys[0];
await privKey.decrypt('1234');
const message = await openpgp.message.readArmored(pgp_msg);
return openpgp.decrypt({ privateKeys:privKey, message:message }).then(function(decrypted) {
expect(decrypted.data).to.equal('hello 3des\n');
expect(decrypted.signatures.length).to.equal(0);
});
});
});
describe('AES encrypt, decrypt', function() {
it('should encrypt and decrypt with one password', function () {
const encOpt = {
message: openpgp.message.fromText(plaintext),
passwords: password1
};
const decOpt = {
passwords: password1
};
return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should encrypt and decrypt with two passwords', function () {
const encOpt = {
message: openpgp.message.fromText(plaintext),
passwords: [password1, password2]
};
const decOpt = {
passwords: password2
};
return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should decrypt with two passwords message which GPG fails on', async function () {
const decOpt = {
message: await openpgp.message.readArmored(twoPasswordGPGFail),
passwords: password2
};
return openpgp.decrypt(decOpt).then(function (decrypted) {
expect(decrypted.data).to.equal('short message\nnext line\n한국어/조선말');
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should encrypt and decrypt with password and not ascii armor', function () {
const encOpt = {
message: openpgp.message.fromText(plaintext),
passwords: password1,
armor: false
};
const decOpt = {
passwords: password1
};
return openpgp.encrypt(encOpt).then(function (encrypted) {
decOpt.message = encrypted.message;
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should encrypt and decrypt with binary data and transferable objects', function () {
openpgp.config.zero_copy = true; // activate transferable objects
const encOpt = {
message: openpgp.message.fromBinary(new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01])),
passwords: password1,
armor: false
};
const decOpt = {
passwords: password1,
format: 'binary'
};
return openpgp.encrypt(encOpt).then(function (encrypted) {
decOpt.message = encrypted.message;
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
if (openpgp.getWorker()) {
expect(encOpt.message.packets[0].data.byteLength).to.equal(0); // transferred buffer should be empty
}
expect(decrypted.data).to.deep.equal(new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01]));
expect(decrypted.signatures.length).to.equal(0);
});
});
});
describe('Encrypt, decrypt with compression', function() {
withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) {
it('should encrypt and decrypt with one password', function () {
const encOpt = modifyCompressionEncryptOptions({
message: openpgp.message.fromText(plaintext),
passwords: password1
});
const decOpt = {
passwords: password1
};
return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
verifyCompressionDecrypted(decrypted);
});
});
it('Streaming encrypt and decrypt small message roundtrip', async function() {
let plaintext = [];
let i = 0;
const data = new ReadableStream({
async pull(controller) {
if (i++ < 4) {
let randomBytes = await openpgp.crypto.random.getRandomBytes(10);
controller.enqueue(randomBytes);
plaintext.push(randomBytes);
} else {
controller.close();
}
}
});
const encrypted = await openpgp.encrypt(modifyCompressionEncryptOptions({
message: openpgp.message.fromBinary(data),
passwords: ['test'],
}));
const msgAsciiArmored = encrypted.data;
const message = await openpgp.message.readArmored(msgAsciiArmored);
const decrypted = await openpgp.decrypt({
passwords: ['test'],
message,
format: 'binary'
});
expect(openpgp.util.isStream(decrypted.data)).to.equal('web');
expect(await openpgp.stream.readToEnd(decrypted.data)).to.deep.equal(openpgp.util.concatUint8Array(plaintext));
});
});
});
}
describe('AES / RSA sign, verify', function() {
const wrong_pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n' +
'Version: OpenPGP.js v0.9.0\r\n' +
'Comment: Hoodiecrow - https://hoodiecrow.com\r\n' +
'\r\n' +
'xk0EUlhMvAEB/2MZtCUOAYvyLFjDp3OBMGn3Ev8FwjzyPbIF0JUw+L7y2XR5\r\n' +
'RVGvbK88unV3cU/1tOYdNsXI6pSp/Ztjyv7vbBUAEQEAAc0pV2hpdGVvdXQg\r\n' +
'VXNlciA8d2hpdGVvdXQudGVzdEB0LW9ubGluZS5kZT7CXAQQAQgAEAUCUlhM\r\n' +
'vQkQ9vYOm0LN/0wAAAW4Af9C+kYW1AvNWmivdtr0M0iYCUjM9DNOQH1fcvXq\r\n' +
'IiN602mWrkd8jcEzLsW5IUNzVPLhrFIuKyBDTpLnC07Loce1\r\n' +
'=6XMW\r\n' +
'-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n';
let decryptedPrivateKey;
beforeEach(async function() {
if (!decryptedPrivateKey) {
expect(await privateKey.keys[0].decrypt(passphrase)).to.be.true;
decryptedPrivateKey = privateKey;
}
privateKey = decryptedPrivateKey;
});
it('should sign and verify cleartext data', function () { it('should sign and verify cleartext data', function () {
const message = openpgp.cleartext.fromText(plaintext); const message = openpgp.cleartext.fromText(plaintext);
@ -1988,240 +2247,7 @@ describe('OpenPGP.js public api tests', function() {
}); });
}); });
}); });
});
describe('ELG / DSA encrypt, decrypt, sign, verify', function() {
it('round trip test', async function () {
const pubKeyDE = (await openpgp.key.readArmored(pub_key_de)).keys[0];
const privKeyDE = (await openpgp.key.readArmored(priv_key_de)).keys[0];
await privKeyDE.decrypt(passphrase);
pubKeyDE.users[0].selfCertifications[0].features = [7]; // Monkey-patch AEAD feature flag
return openpgp.encrypt({
publicKeys: pubKeyDE,
privateKeys: privKeyDE,
message: openpgp.message.fromText(plaintext)
}).then(async function (encrypted) {
return openpgp.decrypt({
privateKeys: privKeyDE,
publicKeys: pubKeyDE,
message: await openpgp.message.readArmored(encrypted.data)
});
}).then(async function (decrypted) {
expect(decrypted.data).to.exist;
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privKeyDE.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
});
});
});
describe("3DES decrypt", function() {
const pgp_msg =
['-----BEGIN PGP MESSAGE-----',
'Version: GnuPG/MacGPG2 v2.0.19 (Darwin)',
'Comment: GPGTools - https://gpgtools.org',
'',
'hIwDBU4Dycfvp2EBA/9tuhQgOrcATcm2PRmIOcs6q947YhlsBTZZdVJDfVjkKlyM',
'M0yE+lnNplWb041Cpfkkl6IvorKQd2iPbAkOL0IXwmVN41l+PvVgMcuFvvzetehG',
'Ca0/VEYOaTZRNqyr9FIzcnVy1I/PaWT3iqVAYa+G8TEA5Dh9RLfsx8ZA9UNIaNI+',
'ASm9aZ3H6FerNhm8RezDY5vRn6xw3o/wH5YEBvV2BEmmFKZ2BlqFQxqChr8UNwd1',
'Ieebnq0HtBPE8YU/L0U=',
'=JyIa',
'-----END PGP MESSAGE-----'].join('\n');
const priv_key =
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG/MacGPG2 v2.0.19 (Darwin)',
'Comment: GPGTools - https://gpgtools.org',
'',
'lQH+BFLqLegBBAC/rN3g30Jrcpx5lTb7Kxe+ZfS7ppOIoBjjN+qcOh81cJJVS5dT',
'UGcDsm2tCLVS3P2dGaYhfU9fsoSq/wK/tXsdoWXvXdjHbbueyi1kTZqlnyT190UE',
'vmDxH0yqquvUaf7+CNXC0T6l9gGS9p0x7xNydWRb7zeK1wIsYI+dRGQmzQARAQAB',
'/gMDArgQHMknurQXy0Pho3Nsdu6zCUNXuplvaSXruefKsQn6eexGPnecNTT2iy5N',
'70EK371D7GcNhhLsn8roUcj1Hi3kR14wXW7lcQBy9RRbbglIJXIqKJ8ywBEO8BaQ',
'b0plL+w5A9EvX0BQc4d53MTqySh6POsEDOxPzH4D/JWbaozfmc4LfGDqH1gl7ebY',
'iu81vnBuuskjpz8rxRI81MldJEIObrTE2x46DF7AmS6L6u/Qz3AAmZd89p5INCdx',
'DemxzuMKpC3wSgdgSSKHHTKiNOMxiRd5mFH5v1KVcEG/TyXFlmah7RwA4rA4fjeo',
'OpnbVWp6ciUniRvgLaCMMbmolAoho9zaLbPzCQVQ8F7gkrjnnPm4MKA+AUXmjt7t',
'VrrYkyTp1pxLZyUWX9+aKoxEO9OIDz7p9Mh02BZ/tznQ7U+IV2bcNhwrL6LPk4Mb',
'J4YF/cLVxFVVma88GSFikSjPf30AUty5nBQFtbFGqnPctCF0aHJvd2F3YXkgPHRo',
'cm93YXdheUBleGFtcGxlLmNvbT6IuAQTAQIAIgUCUuot6AIbAwYLCQgHAwIGFQgC',
'CQoLBBYCAwECHgECF4AACgkQkk2hoj5duD/HZQP/ZXJ8PSlA1oj1NW97ccT0LiNH',
'WzxPPoH9a/qGQYg61jp+aTa0C5hlYY/GgeFpiZlpwVUtlkZYfslXJqbCcp3os4xt',
'kiukDbPnq2Y41wNVxXrDw6KbOjohbhzeRUh8txbkiXGiwHtHBSJsPMntN6cB3vn3',
'08eE69vOiHPQfowa2CmdAf4EUuot6AEEAOQpNjkcTUo14JQ2o+mrpxj5yXbGtZKh',
'D8Ll+aZZrIDIa44p9KlQ3aFzPxdmFBiBX57m1nQukr58FQ5Y/FuQ1dKYc3M8QdZL',
'vCKDC8D9ZJf13iwUjYkfn/e/bDqCS2piyd63zI0xDJo+s2bXCIJxgrhbOqFDeFd6',
'4W8PfBOvUuRjABEBAAH+AwMCuBAcySe6tBfLV0P5MbBesR3Ifu/ppjzLoXKhwkqm',
'PXf09taLcRfUHeMbPjboj2P2m2UOnSrbXK9qsDQ8XOMtdsEWGLWpmiqnMlkiOchv',
'MsNRYpZ67iX3JVdxNuhs5+g5bdP1PNVbKiTzx73u1h0SS93IJp1jFj50/kyGl1Eq',
'tkr0TWe5uXCh6cSZDPwhto0a12GeDHehdTw6Yq4KoZHccneHhN9ySFy0DZOeULIi',
'Y61qtR0io52T7w69fBe9Q5/d5SwpwWKMpCTOqvvzdHX7JmeFtV+2vRVilIif7AfP',
'AD+OjQ/OhMu3jYO+XNhm3raPT2tIBsBdl2UiHOnj4AUNuLuUJeVghtz4Qt6dvjyz',
'PlBvSF+ESqALjM8IqnG15FX4LmEDFrFcfNCsnmeyZ2nr1h2mV5jOON0EmBtCyhCt',
'D/Ivi4/SZk+tBVhsBI+7ZECZYDJzZQnyPDsUv31MU4OwdWi7FhzHvDj/0bhYY7+I',
'nwQYAQIACQUCUuot6AIbDAAKCRCSTaGiPl24PwYAA/sGIHvCKWP5+4ZlBHuOdbP9',
'9v3PXFCm61qFEL0DTSq7NgBcuf0ASRElRI3wIKlfkwaiSzVPfNLiMTexdc7XaiTz',
'CHaOn1Xl2gmYTq2KiJkgtLuwptYU1iSj7vvSHKy0+nYIckOZB4pRCOjknT08O4ZJ',
'22q10ausyQXoOxXfDWVwKA==',
'=IkKW',
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
it('Decrypt message', async function() {
const privKey = (await openpgp.key.readArmored(priv_key)).keys[0];
await privKey.decrypt('1234');
const message = await openpgp.message.readArmored(pgp_msg);
return openpgp.decrypt({ privateKeys:privKey, message:message }).then(function(decrypted) {
expect(decrypted.data).to.equal('hello 3des\n');
expect(decrypted.signatures.length).to.equal(0);
});
});
});
describe('AES encrypt, decrypt', function() {
it('should encrypt and decrypt with one password', function () {
const encOpt = {
message: openpgp.message.fromText(plaintext),
passwords: password1
};
const decOpt = {
passwords: password1
};
return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should encrypt and decrypt with two passwords', function () {
const encOpt = {
message: openpgp.message.fromText(plaintext),
passwords: [password1, password2]
};
const decOpt = {
passwords: password2
};
return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should decrypt with two passwords message which GPG fails on', async function () {
const decOpt = {
message: await openpgp.message.readArmored(twoPasswordGPGFail),
passwords: password2
};
return openpgp.decrypt(decOpt).then(function (decrypted) {
expect(decrypted.data).to.equal('short message\nnext line\n한국어/조선말');
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should encrypt and decrypt with password and not ascii armor', function () {
const encOpt = {
message: openpgp.message.fromText(plaintext),
passwords: password1,
armor: false
};
const decOpt = {
passwords: password1
};
return openpgp.encrypt(encOpt).then(function (encrypted) {
decOpt.message = encrypted.message;
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
});
});
it('should encrypt and decrypt with binary data and transferable objects', function () {
openpgp.config.zero_copy = true; // activate transferable objects
const encOpt = {
message: openpgp.message.fromBinary(new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01])),
passwords: password1,
armor: false
};
const decOpt = {
passwords: password1,
format: 'binary'
};
return openpgp.encrypt(encOpt).then(function (encrypted) {
decOpt.message = encrypted.message;
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
if (openpgp.getWorker()) {
expect(encOpt.message.packets[0].data.byteLength).to.equal(0); // transferred buffer should be empty
}
expect(decrypted.data).to.deep.equal(new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01]));
expect(decrypted.signatures.length).to.equal(0);
});
});
});
describe('Encrypt, decrypt with compression', function() {
withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) {
it('should encrypt and decrypt with one password', function () {
const encOpt = modifyCompressionEncryptOptions({
message: openpgp.message.fromText(plaintext),
passwords: password1
});
const decOpt = {
passwords: password1
};
return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.message.readArmored(encrypted.data);
return openpgp.decrypt(decOpt);
}).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures.length).to.equal(0);
verifyCompressionDecrypted(decrypted);
});
});
it('Streaming encrypt and decrypt small message roundtrip', async function() {
let plaintext = [];
let i = 0;
const data = new ReadableStream({
async pull(controller) {
if (i++ < 4) {
let randomBytes = await openpgp.crypto.random.getRandomBytes(10);
controller.enqueue(randomBytes);
plaintext.push(randomBytes);
} else {
controller.close();
}
}
});
const encrypted = await openpgp.encrypt(modifyCompressionEncryptOptions({
message: openpgp.message.fromBinary(data),
passwords: ['test'],
}));
const msgAsciiArmored = encrypted.data;
const message = await openpgp.message.readArmored(msgAsciiArmored);
const decrypted = await openpgp.decrypt({
passwords: ['test'],
message,
format: 'binary'
});
expect(openpgp.util.isStream(decrypted.data)).to.equal('web');
expect(await openpgp.stream.readToEnd(decrypted.data)).to.deep.equal(openpgp.util.concatUint8Array(plaintext));
});
});
}); });
describe('Errors', function() { describe('Errors', function() {
@ -2241,8 +2267,6 @@ describe('OpenPGP.js public api tests', function() {
}); });
}
}); });
}); });