From 95c5e3af0176c6ef67f6b5c7f401273e8b87ac77 Mon Sep 17 00:00:00 2001 From: Sanjana Rajan Date: Sat, 8 Jul 2017 13:25:24 +0200 Subject: [PATCH] use message obj when signing uint8 array --- src/cleartext.js | 71 +++++++++------------------------------ src/encoding/armor.js | 8 ++--- src/openpgp.js | 32 ++++++++++-------- test/general/signature.js | 6 ++-- 4 files changed, 39 insertions(+), 78 deletions(-) diff --git a/src/cleartext.js b/src/cleartext.js index 79e67001..c6e74a33 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -28,29 +28,24 @@ import config from './config'; import packet from './packet'; import enums from './enums.js'; -import util from './util'; import armor from './encoding/armor.js'; -import base64 from './encoding/base64.js'; import * as sigModule from './signature.js'; /** * @class * @classdesc Class that represents an OpenPGP cleartext signed message. * See {@link http://tools.ietf.org/html/rfc4880#section-7} - * @param {String | Uint8Array} content The cleartext of the signed message + * @param {String} text The cleartext of the signed message * @param {module:signature} signature The detached signature or an empty signature if message not yet signed */ -export function CleartextMessage(content, signature) { +export function CleartextMessage(text, signature) { if (!(this instanceof CleartextMessage)) { - return new CleartextMessage(content, signature); - } - if (util.isString(content)) { - // normalize EOL to canonical form - this.text = content.replace(/\r/g, '').replace(/[\t ]+\n/g, "\n").replace(/\n/g,"\r\n"); - } else { - this.bytes = content; + return new CleartextMessage(text, signature); } + // normalize EOL to canonical form + this.text = text.replace(/\r/g, '').replace(/[\t ]+\n/g, "\n").replace(/\n/g,"\r\n"); + if (signature && !(signature instanceof sigModule.Signature)) { throw new Error('Invalid signature input'); } @@ -73,9 +68,10 @@ CleartextMessage.prototype.getSigningKeyIds = function() { /** * Sign the cleartext message * @param {Array} privateKeys private keys with decrypted secret key data for signing + * @return {module:message~CleartextMessage} new cleartext message with signed content */ CleartextMessage.prototype.sign = function(privateKeys) { - this.signature = this.signDetached(privateKeys); + return new CleartextMessage(this.text, this.signDetached(privateKeys)); }; /** @@ -86,11 +82,7 @@ CleartextMessage.prototype.sign = function(privateKeys) { CleartextMessage.prototype.signDetached = function(privateKeys) { var packetlist = new packet.List(); var literalDataPacket = new packet.Literal(); - if (this.text) { - literalDataPacket.setText(this.text); - } else { - literalDataPacket.setBytes(this.bytes, enums.read(enums.literal, enums.literal.binary)); - } + literalDataPacket.setText(this.text); for (var i = 0; i < privateKeys.length; i++) { if (privateKeys[i].isPublic()) { throw new Error('Need private key for signing'); @@ -128,11 +120,7 @@ CleartextMessage.prototype.verifyDetached = function(signature, keys) { var signatureList = signature.packets; var literalDataPacket = new packet.Literal(); // we assume that cleartext signature is generated based on UTF8 cleartext - if (this.text) { - literalDataPacket.setText(this.text); - } else { - literalDataPacket.setBytes(this.bytes, enums.read(enums.literal, enums.literal.binary)); - } + literalDataPacket.setText(this.text); for (var i = 0; i < signatureList.length; i++) { var keyPacket = null; for (var j = 0; j < keys.length; j++) { @@ -158,28 +146,12 @@ CleartextMessage.prototype.verifyDetached = function(signature, keys) { }; /** - * Get cleartext as native JavaScript string + * Get cleartext * @return {String} cleartext of message */ CleartextMessage.prototype.getText = function() { - if (this.text) { - // normalize end of line to \n - return this.text.replace(/\r\n/g,"\n"); - } else { - return util.Uint8Array2str(this.bytes); - } -}; - -/** - * Get cleartext as byte array - * @returns {Uint8Array} A sequence of bytes - */ -CleartextMessage.prototype.getBytes = function() { - if (this.bytes) { - return this.bytes; - } else { - return util.str2Uint8Array(this.text.replace(/\r\n/g,"\n")); - } + // normalize end of line to \n + return this.text.replace(/\r\n/g,"\n"); }; /** @@ -189,14 +161,10 @@ CleartextMessage.prototype.getBytes = function() { CleartextMessage.prototype.armor = function() { var body = { hash: enums.read(enums.hash, config.prefer_hash_algorithm).toUpperCase(), + text: this.text, data: this.signature.packets.write() }; - if (this.text) { - body.text = this.text; - } else { - body.bytes = this.bytes; - } return armor.encode(enums.armor.signed, body); }; @@ -204,11 +172,10 @@ CleartextMessage.prototype.armor = function() { /** * reads an OpenPGP cleartext signed message and returns a CleartextMessage object * @param {String} armoredText text to be parsed - * @param {bool} whether the decoded cleartext message should be returned as a byte array (default is string) * @return {module:cleartext~CleartextMessage} new cleartext message object * @static */ -export function readArmored(armoredText, bytes=false) { +export function readArmored(armoredText) { var input = armor.decode(armoredText); if (input.type !== enums.armor.signed) { throw new Error('No cleartext signed message.'); @@ -217,13 +184,7 @@ export function readArmored(armoredText, bytes=false) { packetlist.read(input.data); verifyHeaders(input.headers, packetlist); var signature = new sigModule.Signature(packetlist); - var content; - if (bytes) { - content = base64.decode(input.content); - } else { - content = input.content.replace(/\n$/, '').replace(/\n/g, "\r\n"); - } - var newMessage = new CleartextMessage(content, signature); + var newMessage = new CleartextMessage(input.text, signature); return newMessage; } diff --git a/src/encoding/armor.js b/src/encoding/armor.js index 1700cd2c..9dcbe891 100644 --- a/src/encoding/armor.js +++ b/src/encoding/armor.js @@ -300,7 +300,7 @@ function dearmor(text) { var sig_sum = splitChecksum(sig.body); result = { - content: msg.body, + text: msg.body.replace(/\n$/, '').replace(/\n/g, "\r\n"), data: base64.decode(sig_sum.body), headers: msg.headers, type: type @@ -353,11 +353,7 @@ function armor(messagetype, body, partindex, parttotal) { case enums.armor.signed: result.push("\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\n"); result.push("Hash: " + body.hash + "\r\n\r\n"); - if (body.text) { - result.push(body.text.replace(/\n-/g, "\n- -")); - } else { - result.push(base64.encode(body.bytes)); - } + result.push(body.text.replace(/\n-/g, "\n- -")); result.push("\r\n-----BEGIN PGP SIGNATURE-----\r\n"); result.push(addheader()); result.push(base64.encode(body.data)); diff --git a/src/openpgp.js b/src/openpgp.js index 19d907a1..5a2a5e5a 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -292,24 +292,29 @@ export function sign({ data, privateKeys, armor=true, detached=false}) { var result = {}; return execute(() => { + var message; - const cleartextMessage = new cleartext.CleartextMessage(data); + if (util.isString(data)) { + message = new cleartext.CleartextMessage(data); + } else { + message = messageLib.fromBinary(data); + } if (detached) { - var signature = cleartextMessage.signDetached(privateKeys); + var signature = message.signDetached(privateKeys); if (armor) { result.signature = signature.armor(); } else { result.signature = signature; } } else { - cleartextMessage.sign(privateKeys); + message = message.sign(privateKeys); } if (armor) { - result.data = cleartextMessage.armor(); + result.data = message.armor(); } else { - result.message = cleartextMessage; + result.message = message; } return result; @@ -326,7 +331,7 @@ export function sign({ data, privateKeys, armor=true, detached=false}) { * @static */ export function verify({ message, publicKeys, signature=null }) { - checkCleartextMessage(message); + checkCleartextOrMessage(message); publicKeys = toArray(publicKeys); if (asyncProxy) { // use web worker if available @@ -335,12 +340,11 @@ export function verify({ message, publicKeys, signature=null }) { var result = {}; return execute(() => { - if (message.text) { + if (cleartext.CleartextMessage.prototype.isPrototypeOf(message)) { result.data = message.getText(); } else { - result.data = message.getBytes(); + result.data = message.getLiteralData(); } - if (signature) { //detached signature result.signatures = message.verifyDetached(signature, publicKeys); @@ -371,7 +375,7 @@ export function verify({ message, publicKeys, signature=null }) { * @static */ export function encryptSessionKey({ data, algorithm, publicKeys, passwords }) { - checkbinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords); + checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords); if (asyncProxy) { // use web worker if available return asyncProxy.delegate('encryptSessionKey', { data, algorithm, publicKeys, passwords }); @@ -421,7 +425,7 @@ function checkString(data, name) { throw new Error('Parameter [' + (name || 'data') + '] must be of type String'); } } -function checkbinary(data, name) { +function checkBinary(data, name) { if (!util.isUint8Array(data)) { throw new Error('Parameter [' + (name || 'data') + '] must be of type Uint8Array'); } @@ -436,9 +440,9 @@ function checkMessage(message) { throw new Error('Parameter [message] needs to be of type Message'); } } -function checkCleartextMessage(message) { - if (!cleartext.CleartextMessage.prototype.isPrototypeOf(message)) { - throw new Error('Parameter [message] needs to be of type CleartextMessage'); +function checkCleartextOrMessage(message) { + if (!cleartext.CleartextMessage.prototype.isPrototypeOf(message) && !messageLib.Message.prototype.isPrototypeOf(message)) { + throw new Error('Parameter [message] needs to be of type Message or CleartextMessage'); } } diff --git a/test/general/signature.js b/test/general/signature.js index 3252d7c7..254ce574 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -554,10 +554,11 @@ describe("Signature", function() { var pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0]; var privKey = openpgp.key.readArmored(priv_key_arm2).keys[0]; privKey.getSigningKeyPacket().decrypt('hello world'); + console.log(pubKey.armor()); openpgp.sign({ privateKeys:[privKey], data:plaintext }).then(function(signed) { - - var csMsg = openpgp.cleartext.readArmored(signed.data, true); + console.log(signed.data); + var csMsg = openpgp.message.readArmored(signed.data); return openpgp.verify({ publicKeys:[pubKey], message:csMsg }); }).then(function(cleartextSig) { @@ -578,7 +579,6 @@ describe("Signature", function() { privKey.getSigningKeyPacket().decrypt('hello world'); openpgp.sign({ privateKeys:[privKey], data:plaintext, armor:false }).then(function(signed) { - var csMsg = signed.message; return openpgp.verify({ publicKeys:[pubKey], message:csMsg });