pull out common signature code
This commit is contained in:
parent
38a11d7aaf
commit
b5d19b6f8d
|
@ -29,7 +29,7 @@ import armor from './encoding/armor';
|
||||||
import enums from './enums';
|
import enums from './enums';
|
||||||
import packet from './packet';
|
import packet from './packet';
|
||||||
import { Signature } from './signature';
|
import { Signature } from './signature';
|
||||||
import { createVerificationObjects } from './message';
|
import { createVerificationObjects, createSignaturePackets } from './message';
|
||||||
import { getPreferredHashAlgo } from './key';
|
import { getPreferredHashAlgo } from './key';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,34 +80,10 @@ CleartextMessage.prototype.sign = async function(privateKeys) {
|
||||||
* @return {module:signature~Signature} new detached signature of message content
|
* @return {module:signature~Signature} new detached signature of message content
|
||||||
*/
|
*/
|
||||||
CleartextMessage.prototype.signDetached = async function(privateKeys) {
|
CleartextMessage.prototype.signDetached = async function(privateKeys) {
|
||||||
const packetlist = new packet.List();
|
|
||||||
const literalDataPacket = new packet.Literal();
|
const literalDataPacket = new packet.Literal();
|
||||||
literalDataPacket.setText(this.text);
|
literalDataPacket.setText(this.text);
|
||||||
|
|
||||||
await Promise.all(privateKeys.map(async function(privateKey) {
|
return new Signature(await createSignaturePackets(literalDataPacket, privateKeys));
|
||||||
if (privateKey.isPublic()) {
|
|
||||||
throw new Error('Need private key for signing');
|
|
||||||
}
|
|
||||||
await privateKey.verifyPrimaryUser();
|
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket();
|
|
||||||
if (!signingKeyPacket) {
|
|
||||||
throw new Error('Could not find valid key packet for signing in key ' +
|
|
||||||
privateKey.primaryKey.getKeyId().toHex());
|
|
||||||
}
|
|
||||||
const signaturePacket = new packet.Signature();
|
|
||||||
signaturePacket.signatureType = enums.signature.text;
|
|
||||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
|
||||||
signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
|
|
||||||
if (!signingKeyPacket.isDecrypted) {
|
|
||||||
throw new Error('Private key is not decrypted.');
|
|
||||||
}
|
|
||||||
await signaturePacket.sign(signingKeyPacket, literalDataPacket);
|
|
||||||
return signaturePacket;
|
|
||||||
})).then(signatureList => {
|
|
||||||
signatureList.forEach(signaturePacket => packetlist.push(signaturePacket));
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Signature(packetlist);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -416,25 +416,7 @@ Message.prototype.sign = async function(privateKeys=[], signature=null) {
|
||||||
});
|
});
|
||||||
|
|
||||||
packetlist.push(literalDataPacket);
|
packetlist.push(literalDataPacket);
|
||||||
|
packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature));
|
||||||
await Promise.all(privateKeys.map(async function(privateKey) {
|
|
||||||
const signaturePacket = new packet.Signature();
|
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket();
|
|
||||||
if (!signingKeyPacket.isDecrypted) {
|
|
||||||
throw new Error('Private key is not decrypted.');
|
|
||||||
}
|
|
||||||
signaturePacket.signatureType = signatureType;
|
|
||||||
signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
|
|
||||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
|
||||||
await signaturePacket.sign(signingKeyPacket, literalDataPacket);
|
|
||||||
return signaturePacket;
|
|
||||||
})).then(signatureList => {
|
|
||||||
signatureList.forEach(signaturePacket => packetlist.push(signaturePacket));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (signature) {
|
|
||||||
packetlist.concat(existingSigPacketlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Message(packetlist);
|
return new Message(packetlist);
|
||||||
};
|
};
|
||||||
|
@ -466,24 +448,40 @@ Message.prototype.compress = function(compression) {
|
||||||
* @return {module:signature~Signature} new detached signature of message content
|
* @return {module:signature~Signature} new detached signature of message content
|
||||||
*/
|
*/
|
||||||
Message.prototype.signDetached = async function(privateKeys=[], signature=null) {
|
Message.prototype.signDetached = async function(privateKeys=[], signature=null) {
|
||||||
const packetlist = new packet.List();
|
|
||||||
|
|
||||||
const literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
const literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
||||||
if (!literalDataPacket) {
|
if (!literalDataPacket) {
|
||||||
throw new Error('No literal data packet to sign.');
|
throw new Error('No literal data packet to sign.');
|
||||||
}
|
}
|
||||||
|
return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create signature packets for the message
|
||||||
|
* @param {module:packet/literal} the literal data packet to sign
|
||||||
|
* @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing
|
||||||
|
* @param {Signature} signature (optional) any existing detached signature to append
|
||||||
|
* @return {module:packet/packetlist} list of signature packets
|
||||||
|
*/
|
||||||
|
export async function createSignaturePackets(literalDataPacket, privateKeys, signature=null) {
|
||||||
|
const packetlist = new packet.List();
|
||||||
|
|
||||||
const literalFormat = enums.write(enums.literal, literalDataPacket.format);
|
const literalFormat = enums.write(enums.literal, literalDataPacket.format);
|
||||||
const signatureType = literalFormat === enums.literal.binary ?
|
const signatureType = literalFormat === enums.literal.binary ?
|
||||||
enums.signature.binary : enums.signature.text;
|
enums.signature.binary : enums.signature.text;
|
||||||
|
|
||||||
await Promise.all(privateKeys.map(async function(privateKey) {
|
await Promise.all(privateKeys.map(async function(privateKey) {
|
||||||
const signaturePacket = new packet.Signature();
|
if (privateKey.isPublic()) {
|
||||||
|
throw new Error('Need private key for signing');
|
||||||
|
}
|
||||||
await privateKey.verifyPrimaryUser();
|
await privateKey.verifyPrimaryUser();
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket();
|
const signingKeyPacket = privateKey.getSigningKeyPacket();
|
||||||
|
if (!signingKeyPacket) {
|
||||||
|
throw new Error('Could not find valid key packet for signing in key ' + privateKey.primaryKey.getKeyId().toHex());
|
||||||
|
}
|
||||||
if (!signingKeyPacket.isDecrypted) {
|
if (!signingKeyPacket.isDecrypted) {
|
||||||
throw new Error('Private key is not decrypted.');
|
throw new Error('Private key is not decrypted.');
|
||||||
}
|
}
|
||||||
|
const signaturePacket = new packet.Signature();
|
||||||
signaturePacket.signatureType = signatureType;
|
signaturePacket.signatureType = signatureType;
|
||||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||||
signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
|
signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
|
||||||
|
@ -497,10 +495,8 @@ Message.prototype.signDetached = async function(privateKeys=[], signature=null)
|
||||||
const existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
|
const existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
|
||||||
packetlist.concat(existingSigPacketlist);
|
packetlist.concat(existingSigPacketlist);
|
||||||
}
|
}
|
||||||
|
return packetlist;
|
||||||
return new Signature(packetlist);
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify message signatures
|
* Verify message signatures
|
||||||
|
|
|
@ -1279,7 +1279,7 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
privateKeys: [privateKey.keys[0], privKeyDE]
|
privateKeys: [privateKey.keys[0], privKeyDE]
|
||||||
};
|
};
|
||||||
const verifyOpt = {
|
const verifyOpt = {
|
||||||
publicKeys: publicKey.keys
|
publicKeys: [publicKey.keys[0], privKeyDE.toPublic()]
|
||||||
};
|
};
|
||||||
return openpgp.sign(signOpt).then(function (signed) {
|
return openpgp.sign(signOpt).then(function (signed) {
|
||||||
expect(signed.data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/);
|
expect(signed.data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/);
|
||||||
|
@ -1290,6 +1290,9 @@ describe('OpenPGP.js public api tests', function() {
|
||||||
expect(verified.signatures[0].valid).to.be.true;
|
expect(verified.signatures[0].valid).to.be.true;
|
||||||
expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex());
|
expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex());
|
||||||
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
expect(verified.signatures[0].signature.packets.length).to.equal(1);
|
||||||
|
expect(verified.signatures[1].valid).to.be.true;
|
||||||
|
expect(verified.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex());
|
||||||
|
expect(verified.signatures[1].signature.packets.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user