allow signature as input in high level encrypt

This commit is contained in:
Sanjana Rajan 2017-03-22 17:04:21 -07:00
parent 83d40d29ed
commit 79160abcc9
2 changed files with 41 additions and 14 deletions

View File

@ -104,12 +104,12 @@ Message.prototype.decrypt = function(privateKey, sessionKey, password) {
enums.packet.symEncryptedIntegrityProtected, enums.packet.symEncryptedIntegrityProtected,
enums.packet.symEncryptedAEADProtected enums.packet.symEncryptedAEADProtected
); );
if (symEncryptedPacketlist.length === 0) { if (symEncryptedPacketlist.length === 0) {
return; return;
} }
const symEncryptedPacket = symEncryptedPacketlist[0]; const symEncryptedPacket = symEncryptedPacketlist[0];
return symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data).then(() => { return symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data).then(() => {
const resultMsg = new Message(symEncryptedPacket.packets); const resultMsg = new Message(symEncryptedPacket.packets);
symEncryptedPacket.packets = new packet.List(); // remove packets after decryption symEncryptedPacket.packets = new packet.List(); // remove packets after decryption
@ -292,10 +292,11 @@ export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords) {
/** /**
* Sign the message (the literal data packet of the message) * Sign the message (the literal data packet of the message)
* @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing * @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing
* @return {module:message~Message} new message with signed content * @param {Signature} signature (optional) any existing detached signature to add to the message
* @return {module:message~Message} new message with signed content
*/ */
Message.prototype.sign = function(privateKeys) { Message.prototype.sign = function(privateKeys=[], signature=null) {
var packetlist = new packet.List(); var packetlist = new packet.List();
@ -307,12 +308,27 @@ Message.prototype.sign = function(privateKeys) {
var literalFormat = enums.write(enums.literal, literalDataPacket.format); var literalFormat = enums.write(enums.literal, literalDataPacket.format);
var signatureType = literalFormat === enums.literal.binary ? var signatureType = literalFormat === enums.literal.binary ?
enums.signature.binary : enums.signature.text; enums.signature.binary : enums.signature.text;
var i, signingKeyPacket; var i, signingKeyPacket, existingSigPacketlist, onePassSig;
if (signature) {
existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
if (existingSigPacketlist.length) {
for (i = existingSigPacketlist.length - 1; i >= 0; i--) {
var sigPacket = existingSigPacketlist[i];
onePassSig = new packet.OnePassSignature();
onePassSig.type = signatureType;
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
onePassSig.publicKeyAlgorithm = sigPacket.publicKeyAlgorithm;
onePassSig.signingKeyId = sigPacket.issuerKeyId;
packetlist.push(onePassSig);
}
}
}
for (i = 0; i < privateKeys.length; i++) { for (i = 0; i < privateKeys.length; i++) {
if (privateKeys[i].isPublic()) { if (privateKeys[i].isPublic()) {
throw new Error('Need private key for signing'); throw new Error('Need private key for signing');
} }
var onePassSig = new packet.OnePassSignature(); onePassSig = new packet.OnePassSignature();
onePassSig.type = signatureType; onePassSig.type = signatureType;
//TODO get preferred hashg algo from key signature //TODO get preferred hashg algo from key signature
onePassSig.hashAlgorithm = config.prefer_hash_algorithm; onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
@ -341,16 +357,19 @@ Message.prototype.sign = function(privateKeys) {
signaturePacket.sign(signingKeyPacket, literalDataPacket); signaturePacket.sign(signingKeyPacket, literalDataPacket);
packetlist.push(signaturePacket); packetlist.push(signaturePacket);
} }
if (signature) {
packetlist.concat(existingSigPacketlist);
}
return new Message(packetlist); return new Message(packetlist);
}; };
/** /**
* Create a detached signature for the message (the literal data packet of the message) * Create a detached signature for the message (the literal data packet of the message)
* @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing * @param {Array<module:key~Key>} privateKey private keys with decrypted secret key data for signing
* @param {Signature} signature (optional) any existing detached signature
* @return {module:signature~Signature} new detached signature of message content * @return {module:signature~Signature} new detached signature of message content
*/ */
Message.prototype.signDetached = function(privateKeys) { Message.prototype.signDetached = function(privateKeys=[], signature=null) {
var packetlist = new packet.List(); var packetlist = new packet.List();
@ -375,6 +394,10 @@ Message.prototype.signDetached = function(privateKeys) {
signaturePacket.sign(signingKeyPacket, literalDataPacket); signaturePacket.sign(signingKeyPacket, literalDataPacket);
packetlist.push(signaturePacket); packetlist.push(signaturePacket);
} }
if (signature) {
var existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
packetlist.concat(existingSigPacketlist);
}
return new sigModule.Signature(packetlist); return new sigModule.Signature(packetlist);
}; };

View File

@ -180,12 +180,13 @@ export function decryptKey({ privateKey, passphrase }) {
* @param {String} filename (optional) a filename for the literal data packet * @param {String} filename (optional) a filename for the literal data packet
* @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects * @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects
* @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object) * @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object)
* @param {Signature} signatureInput (optional) a detached signature to add to the encrypted message
* @return {Promise<Object>} encrypted (and optionally signed message) in the form: * @return {Promise<Object>} encrypted (and optionally signed message) in the form:
* {data: ASCII armored message if 'armor' is true, * {data: ASCII armored message if 'armor' is true,
* message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true} * message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true}
* @static * @static
*/ */
export function encrypt({ data, publicKeys, privateKeys, passwords, filename, armor=true, detached=false }) { export function encrypt({ data, publicKeys, privateKeys, passwords, filename, armor=true, detached=false, signatureInput=null }) {
checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords);
if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
@ -195,16 +196,19 @@ export function encrypt({ data, publicKeys, privateKeys, passwords, filename, ar
return Promise.resolve().then(() => { return Promise.resolve().then(() => {
let message = createMessage(data, filename); let message = createMessage(data, filename);
if (privateKeys) { // sign the message only if private keys are specified if (!privateKeys) {
privateKeys = [];
}
if (privateKeys.length || signatureInput) { // sign the message only if private keys or signatureInput is specified
if (detached) { if (detached) {
var signature = message.signDetached(privateKeys); var signature = message.signDetached(privateKeys, signatureInput);
if (armor) { if (armor) {
result.signature = signature.armor(); result.signature = signature.armor();
} else { } else {
result.signature = signature; result.signature = signature;
} }
} else { } else {
message = message.sign(privateKeys); message = message.sign(privateKeys, signatureInput);
} }
} }
return message.encrypt(publicKeys, passwords); return message.encrypt(publicKeys, passwords);
@ -243,6 +247,7 @@ export function decrypt({ message, privateKey, publicKeys, sessionKey, password,
return message.decrypt(privateKey, sessionKey, password).then(message => { return message.decrypt(privateKey, sessionKey, password).then(message => {
const result = parseMessage(message, format); const result = parseMessage(message, format);
if (result.data) { // verify if (result.data) { // verify
if (!publicKeys) { if (!publicKeys) {
publicKeys = []; publicKeys = [];
@ -281,7 +286,6 @@ export function decrypt({ message, privateKey, publicKeys, sessionKey, password,
export function sign({ data, privateKeys, armor=true, detached=false}) { export function sign({ data, privateKeys, armor=true, detached=false}) {
checkString(data); checkString(data);
privateKeys = toArray(privateKeys); privateKeys = toArray(privateKeys);
if (asyncProxy) { // use web worker if available if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('sign', { data, privateKeys, armor, detached }); return asyncProxy.delegate('sign', { data, privateKeys, armor, detached });
} }