Decouple signature type from data packet type
Instead of creating a text signature for text packets and a binary signature for binary packets, we determine the signature type based on whether a String or Uint8Array was originally passed. This is useful for the new MIME data packet type (implemented in the next commit) which you can pass in either format. This also partly revertsa22c9e4
. Instead of canonicalizing the literal data packet, we canonicalize the data when signing. This fixes a hypothetical case where an uncanonicalized text packet has both a text and a binary signature. This also partly revertsc28f7ad
. GPG does not strip trailing whitespace when creating text signatures of literal data packets.
This commit is contained in:
parent
2f849063f9
commit
3b81088aaf
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user