Merge pull request #559 from openpgpjs/sign_byte_arrays

Sign Uint8 arrays
This commit is contained in:
Bart Butler 2017-07-12 19:45:53 -07:00 committed by GitHub
commit d737f65ccc
4 changed files with 71 additions and 18 deletions

View File

@ -67,9 +67,10 @@ CleartextMessage.prototype.getSigningKeyIds = function() {
/**
* Sign the cleartext message
* @param {Array<module:key~Key>} 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));
};
/**

View File

@ -273,7 +273,7 @@ export function decrypt({ message, privateKey, publicKeys, sessionKey, password,
/**
* Signs a cleartext message.
* @param {String} data cleartext input to be signed
* @param {String | Uint8Array} data cleartext input to be signed
* @param {Key|Array<Key>} privateKeys array of keys or single key with decrypted secret key data to sign cleartext
* @param {Boolean} armor (optional) if the return value should be ascii armored or the message object
* @param {Boolean} detached (optional) if the return value should contain a detached signature
@ -283,7 +283,7 @@ export function decrypt({ message, privateKey, publicKeys, sessionKey, password,
* @static
*/
export function sign({ data, privateKeys, armor=true, detached=false}) {
checkString(data);
checkData(data);
privateKeys = toArray(privateKeys);
if (asyncProxy) { // use web worker if available
@ -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,8 +340,11 @@ export function verify({ message, publicKeys, signature=null }) {
var result = {};
return execute(() => {
result.data = message.getText();
if (cleartext.CleartextMessage.prototype.isPrototypeOf(message)) {
result.data = message.getText();
} else {
result.data = message.getLiteralData();
}
if (signature) {
//detached signature
result.signatures = message.verifyDetached(signature, publicKeys);
@ -367,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 });
@ -417,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');
}
@ -432,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');
}
}

View File

@ -226,7 +226,7 @@ Signature.prototype.sign = function (key, data) {
var trailer = this.calculateTrailer();
var toHash = null
var toHash = null;
switch (this.version) {
case 3:

View File

@ -527,7 +527,7 @@ describe("Signature", function() {
});
});
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same cleartext and valid signatures', function(done) {
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same string cleartext and valid signatures', function(done) {
var plaintext = 'short message\nnext line\n한국어/조선말';
var pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0];
var privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
@ -549,6 +549,50 @@ describe("Signature", function() {
});
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - armored', function(done) {
var plaintext = openpgp.util.str2Uint8Array('short message\nnext line\n한국어/조선말');
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) {
console.log(signed.data);
var csMsg = openpgp.message.readArmored(signed.data);
return openpgp.verify({ publicKeys:[pubKey], message:csMsg });
}).then(function(cleartextSig) {
expect(cleartextSig).to.exist;
expect(cleartextSig.data).to.deep.equal(plaintext);
expect(cleartextSig.signatures).to.have.length(1);
expect(cleartextSig.signatures[0].valid).to.be.true;
expect(cleartextSig.signatures[0].signature.packets.length).to.equal(1);
done();
});
});
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - not armored', function(done) {
var plaintext = openpgp.util.str2Uint8Array('short message\nnext line\n한국어/조선말');
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');
openpgp.sign({ privateKeys:[privKey], data:plaintext, armor:false }).then(function(signed) {
var csMsg = signed.message;
return openpgp.verify({ publicKeys:[pubKey], message:csMsg });
}).then(function(cleartextSig) {
expect(cleartextSig).to.exist;
expect(cleartextSig.data).to.deep.equal(plaintext);
expect(cleartextSig.signatures).to.have.length(1);
expect(cleartextSig.signatures[0].valid).to.be.true;
expect(cleartextSig.signatures[0].signature.packets.length).to.equal(1);
done();
});
});
it('Verify primary key revocation signature', function(done) {
var pubKey = openpgp.key.readArmored(pub_revoked).keys[0];