fork-openpgpjs/test/security/subkey_trust.js
larabr 40542fd08a
Simplify return value of generateKey, reformatKey and revokeKey and add support for binary output (#1345)
- `openpgp.generateKey`, `reformatKey` and `revokeKey` take a new `format`
option, whose possible values are: `'armor', 'binary', 'object'` (default is 
`'armor'`).
- `generateKey` and `reformatKey` now return an object of the form `{
publicKey, privateKey, revocationCertificate }`, where the type of `publicKey`
and `privateKey` depends on `options.format`:
    * if `format: 'armor'` then `privateKey, publicKey` are armored strings;
    * if `format: 'binary'` then `privateKey, publicKey` are `Uint8Array`;
    * if `format: 'object'` then `privateKey, publicKey` are `PrivateKey` and
`PublicKey` objects respectively;
- `revokeKey` now returns `{ publicKey, privateKey }`, where:
    * if a `PrivateKey` is passed as `key` input,  `privateKey, publicKey` are of the
requested format;
    * if a `PublicKey` is passed as `key` input, `publicKey` is of the requested format,
while `privateKey` is `null` (previously, in this case the `privateKey` field
was not defined).

Breaking changes:
- In `revokeKey`, if no `format` option is specified, the returned `publicKey,
privateKey` are armored strings (they used to be objects).
- In `generateKey` and `reformatKey`, the `key` value is no longer returned.
- For all three functions, the `publicKeyArmored` and `privateKeyArmored`
values are no longer returned.
2021-06-24 17:14:39 +02:00

77 lines
2.8 KiB
JavaScript

const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
const { readKey, PublicKey, readCleartextMessage, createCleartextMessage, enums, PacketList, SignaturePacket } = openpgp;
const chai = require('chai');
chai.use(require('chai-as-promised'));
const expect = chai.expect;
async function generateTestData() {
const { privateKey: victimPrivKey } = await openpgp.generateKey({
userIDs: [{ name: 'Victim', email: 'victim@example.com' }],
type: 'rsa',
rsaBits: 2048,
subkeys: [{ sign: true }],
format: 'object'
});
const { privateKey: attackerPrivKey } = await openpgp.generateKey({
userIDs: [{ name: 'Attacker', email: 'attacker@example.com' }],
type: 'rsa',
rsaBits: 2048,
subkeys: [],
sign: false,
format: 'object'
});
const signed = await openpgp.sign({
message: await createCleartextMessage({ text: 'I am batman' }),
signingKeys: victimPrivKey,
armor: true
});
return {
victimPubKey: victimPrivKey.toPublic(),
attackerPrivKey,
signed
};
}
async function testSubkeyTrust() {
// attacker only has his own private key,
// the victim's public key and a signed message
const { victimPubKey, attackerPrivKey, signed } = await generateTestData();
const pktPubVictim = victimPubKey.toPacketList();
const pktPubAttacker = attackerPrivKey.toPublic().toPacketList();
const dataToSign = {
key: attackerPrivKey.toPublic().keyPacket,
bind: pktPubVictim[3] // victim subkey
};
const fakeBindingSignature = new SignaturePacket();
fakeBindingSignature.signatureType = enums.signature.subkeyBinding;
fakeBindingSignature.publicKeyAlgorithm = attackerPrivKey.keyPacket.algorithm;
fakeBindingSignature.hashAlgorithm = enums.hash.sha256;
fakeBindingSignature.keyFlags = [enums.keyFlags.signData];
await fakeBindingSignature.sign(attackerPrivKey.keyPacket, dataToSign);
const newList = new PacketList();
newList.push(
pktPubAttacker[0], // attacker private key
pktPubAttacker[1], // attacker user
pktPubAttacker[2], // attacker self signature
pktPubVictim[3], // victim subkey
fakeBindingSignature // faked key binding
);
let fakeKey = new PublicKey(newList);
fakeKey = await readKey({ armoredKey: await fakeKey.toPublic().armor() });
const verifyAttackerIsBatman = await openpgp.verify({
message: await readCleartextMessage({ cleartextMessage: signed }),
verificationKeys: fakeKey
});
expect(verifyAttackerIsBatman.signatures[0].keyID.equals(victimPubKey.subkeys[0].getKeyID())).to.be.true;
expect(verifyAttackerIsBatman.signatures[0].valid).to.be.false;
expect(verifyAttackerIsBatman.signatures[0].error).to.match(/Could not find valid signing key packet/);
}
module.exports = () => it('Does not trust subkeys without Primary Key Binding Signature', testSubkeyTrust);