diff --git a/src/message.js b/src/message.js index aca0de85..c2feb5f5 100644 --- a/src/message.js +++ b/src/message.js @@ -216,7 +216,7 @@ Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) { */ Message.prototype.getLiteralData = function() { const literal = this.packets.findPacket(enums.packet.literal); - return (literal && literal.data) || null; + return (literal && literal.getBytes()) || null; }; /** @@ -395,8 +395,8 @@ Message.prototype.sign = async function(privateKeys=[], signature=null, date=new let i; let existingSigPacketlist; - const literalFormat = enums.write(enums.literal, literalDataPacket.format); - const signatureType = literalFormat === enums.literal.binary ? + // If data packet was created from Uint8Array, use binary, otherwise use text + const signatureType = literalDataPacket.text === null ? enums.signature.binary : enums.signature.text; if (signature) { @@ -491,8 +491,8 @@ Message.prototype.signDetached = async function(privateKeys=[], signature=null, export async function createSignaturePackets(literalDataPacket, privateKeys, signature=null, date=new Date()) { const packetlist = new packet.List(); - const literalFormat = enums.write(enums.literal, literalDataPacket.format); - const signatureType = literalFormat === enums.literal.binary ? + // If data packet was created from Uint8Array, use binary, otherwise use text + const signatureType = literalDataPacket.text === null ? enums.signature.binary : enums.signature.text; await Promise.all(privateKeys.map(async function(privateKey) { @@ -581,15 +581,9 @@ export async function createVerificationObjects(signatureList, literalDataList, } })); - // If this is a text signature, canonicalize line endings of the data - const literalDataPacket = literalDataList[0]; - if (signature.signatureType === enums.signature.text) { - literalDataPacket.setText(literalDataPacket.getText()); - } - const verifiedSig = { keyid: signature.issuerKeyId, - valid: keyPacket ? await signature.verify(keyPacket, literalDataPacket) : null + valid: keyPacket ? await signature.verify(keyPacket, literalDataList[0]) : null }; const packetlist = new packet.List(); diff --git a/src/packet/literal.js b/src/packet/literal.js index 0a6f8bee..8fdd99a1 100644 --- a/src/packet/literal.js +++ b/src/packet/literal.js @@ -37,7 +37,8 @@ function Literal(date=new Date()) { this.tag = enums.packet.literal; this.format = 'utf8'; // default format for literal data packets this.date = util.normalizeDate(date); - this.data = new Uint8Array(0); // literal data representation + this.text = null; // textual data representation + this.data = null; // literal data representation this.filename = 'msg.txt'; } @@ -45,13 +46,12 @@ function Literal(date=new Date()) { * Set the packet data to a javascript native string, end of line * will be normalized to \r\n and by default text is converted to UTF8 * @param {String} text Any native javascript string + * @param {utf8|binary|text} format (optional) The format of the string of bytes */ -Literal.prototype.setText = function(text) { - // normalize EOL to \r\n - text = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/[ \t]+\n/g, "\n").replace(/\n/g, "\r\n"); - this.format = 'utf8'; - // encode UTF8 - this.data = util.str_to_Uint8Array(util.encode_utf8(text)); +Literal.prototype.setText = function(text, format='utf8') { + this.format = format; + this.text = text; + this.data = null; }; /** @@ -60,10 +60,14 @@ Literal.prototype.setText = function(text) { * @returns {String} literal data as text */ Literal.prototype.getText = function() { + if (this.text !== null) { + return this.text; + } // decode UTF8 const text = util.decode_utf8(util.Uint8Array_to_str(this.data)); // normalize EOL to \n - return text.replace(/\r\n/g, '\n'); + this.text = text.replace(/\r\n/g, '\n'); + return this.text; }; /** @@ -74,6 +78,7 @@ Literal.prototype.getText = function() { Literal.prototype.setBytes = function(bytes, format) { this.format = format; this.data = bytes; + this.text = null; }; @@ -82,6 +87,14 @@ Literal.prototype.setBytes = function(bytes, format) { * @returns {Uint8Array} A sequence of bytes */ Literal.prototype.getBytes = function() { + if (this.data !== null) { + return this.data; + } + + // normalize EOL to \r\n + const text = this.text.replace(/\r\n/g, '\n').replace(/\r/g, '\n').replace(/\n/g, '\r\n'); + // encode UTF8 + this.data = util.str_to_Uint8Array(util.encode_utf8(text)); return this.data; }; diff --git a/src/packet/signature.js b/src/packet/signature.js index e3210e01..936a1520 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -551,9 +551,15 @@ Signature.prototype.toSign = function (type, data) { switch (type) { case t.binary: - case t.text: return data.getBytes(); + case t.text: { + let text = data.getText(); + // normalize EOL to \r\n + text = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n').replace(/\n/g, '\r\n'); + // encode UTF8 + return util.str_to_Uint8Array(util.encode_utf8(text)); + } case t.standalone: return new Uint8Array(0);