Implement content verification using detached signatures

This commit is contained in:
Tankred Hase 2014-07-03 14:57:52 +02:00
parent 74959b83b6
commit de3ba18400
5 changed files with 67 additions and 4 deletions

View File

@ -1,7 +1,7 @@
{
"name": "openpgp",
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
"version": "0.7.0",
"version": "0.7.1-dev",
"homepage": "http://openpgpjs.org/",
"engines": {
"node": ">=0.8"

View File

@ -38,7 +38,7 @@ var base64 = require('./base64.js'),
* 5 = PRIVATE KEY BLOCK
*/
function getType(text) {
var reHeader = /^-----BEGIN PGP (MESSAGE, PART \d+\/\d+|MESSAGE, PART \d+|SIGNED MESSAGE|MESSAGE|PUBLIC KEY BLOCK|PRIVATE KEY BLOCK)-----$\n/m;
var reHeader = /^-----BEGIN PGP (MESSAGE, PART \d+\/\d+|MESSAGE, PART \d+|SIGNED MESSAGE|MESSAGE|PUBLIC KEY BLOCK|PRIVATE KEY BLOCK|SIGNATURE)-----$\n/m;
var header = text.match(reHeader);

View File

@ -290,6 +290,22 @@ function readArmored(armoredText) {
return newMessage;
}
/**
* Create a message object from signed content and a detached armored signature.
* @param {String} content An 8 bit ascii string containing e.g. a MIME subtree with text nodes or attachments
* @param {String} detachedSignature The detached ascii armored PGP signarure
*/
function readSignedContent(content, detachedSignature) {
var literalDataPacket = new packet.Literal();
literalDataPacket.setBytes(content, enums.read(enums.literal, enums.literal.binary));
var packetlist = new packet.List();
packetlist.push(literalDataPacket);
var input = armor.decode(detachedSignature).data;
packetlist.read(input);
var newMessage = new Message(packetlist);
return newMessage;
}
/**
* creates new message object from text
* @param {String} text
@ -323,5 +339,6 @@ function fromBinary(bytes) {
exports.Message = Message;
exports.readArmored = readArmored;
exports.readSignedContent = readSignedContent;
exports.fromText = fromText;
exports.fromBinary = fromBinary;

View File

@ -117,7 +117,7 @@ describe("ASCII armor", function() {
['-----BEGIN PGP SIGNED MESSAGE\u2010\u2010\u2010\u2010\u2010\nHash:SHA1\n\nIs this properly-----',
'',
'sign this',
'-----BEGIN PGP SIGNATURE-----',
'-----BEGIN PGP SIGNNATURE-----',
'Version: GnuPG v2.0.22 (GNU/Linux)',
'',
'iJwEAQECAAYFAlMrPj0ACgkQ4IT3RGwgLJfYkQQAgHMQieazCVdfGAfzQM69Egm5',
@ -125,7 +125,7 @@ describe("ASCII armor", function() {
'LQ9DiQUwJMBE8nOwVR7Mpc4kLNngMTNaHAjZaVaDpTCrklPY+TPHIZnu0B6Ur+6t',
'skTzzVXIxMYw8ihbHfk=',
'=e/eA',
'-----END PGP SIGNATURE-----'].join('\n');
'-----END PGP SIGNNATURE-----'].join('\n');
msg = openpgp.cleartext.readArmored.bind(null, msg);
expect(msg).to.throw(Error, /Unknow ASCII armor type/);

View File

@ -590,4 +590,50 @@ describe("Signature", function() {
expect(pubKey.users[0].selfCertifications).to.eql(pubKey2.users[0].selfCertifications);
});
it('Verify a detached signature', function() {
var detachedSig = ['-----BEGIN PGP SIGNATURE-----',
'Version: GnuPG v1.4.13 (Darwin)',
'Comment: GPGTools - https://gpgtools.org',
'Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/',
'',
'iQEcBAEBCgAGBQJTqH5OAAoJENf7k/zfv8I8oFoH/R6EFTw2CYUQoOKSAQstWIHp',
'fVVseLOkFbByUV5eLuGVBNI3DM4GQ6C7dGntKAn34a1iTGcAIZH+fIhaZ2WtNdtA',
'R+Ijn8xDjbF/BWvcTBOaRvgw9b8viPxhkVYa3PioHYz6krt/LmFqFdp/phWZcqR4',
'jzWMX55h4FOw3YBNGiz2NuIg+iGrFRWPYgd8NVUmJKReZHs8C/6HGz7F4/A24k6Y',
'7xms9D6Er+MhspSl+1dlRdHjtXiRqC5Ld1hi2KBKc6YzgOLpVw5l9sffbnH+aRG4',
'dH+2J5U3elqBDK1i3GyG8ixLSB0FGW9+lhYNosZne2xy8SbQKdgsnTBnWSGevP0=',
'=xiih',
'-----END PGP SIGNATURE-----'
].join('\r\n');
var content = ['Content-Type: multipart/mixed;',
' boundary="------------070307080002050009010403"',
'',
'This is a multi-part message in MIME format.',
'--------------070307080002050009010403',
'Content-Type: text/plain; charset=ISO-8859-1',
'Content-Transfer-Encoding: quoted-printable',
'',
'test11',
'',
'--------------070307080002050009010403',
'Content-Type: application/macbinary;',
' name="test.bin"',
'Content-Transfer-Encoding: base64',
'Content-Disposition: attachment;',
' filename="test.bin"',
'',
'dGVzdGF0dGFjaG1lbnQ=',
'--------------070307080002050009010403--',
''
].join('\r\n');
var publicKeyArmored = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: OpenPGP.js v.1.20131116\r\nComment: Whiteout Mail - http://whiteout.io\r\n\r\nxsBNBFKODs4BB/9iOF4THsjQMY+WEpT7ShgKxj4bHzRRaQkqczS4nZvP0U3g\r\nqeqCnbpagyeKXA+bhWFQW4GmXtgAoeD5PXs6AZYrw3tWNxLKu2Oe6Tp9K/XI\r\nxTMQ2wl4qZKDXHvuPsJ7cmgaWqpPyXtxA4zHHS3WrkI/6VzHAcI/y6x4szSB\r\nKgSuhI3hjh3s7TybUC1U6AfoQGx/S7e3WwlCOrK8GTClirN/2mCPRC5wuIft\r\nnkoMfA6jK8d2OPrJ63shy5cgwHOjQg/xuk46dNS7tkvGmbaa+X0PgqSKB+Hf\r\nYPPNS/ylg911DH9qa8BqYU2QpNh9jUKXSF+HbaOM+plWkCSAL7czV+R3ABEB\r\nAAHNLVdoaXRlb3V0IFVzZXIgPHNhZmV3aXRobWUudGVzdHVzZXJAZ21haWwu\r\nY29tPsLAXAQQAQgAEAUCUo4O2gkQ1/uT/N+/wjwAAN2cB/9gFRmAfvEQ2qz+\r\nWubmT2EsSSnjPMxzG4uyykFoa+TaZCWo2Xa2tQghmU103kEkQb1OEjRjpgwJ\r\nYX9Kghnl8DByM686L5AXnRyHP78qRJCLXSXl0AGicboUDp5sovaa4rswQceH\r\nvcdWgZ/mgHTRoiQeJddy9k+H6MPFiyFaVcFwegVsmpc+dCcC8yT+qh8ZIbyG\r\nRJU60PmKKN7LUusP+8DbSv39zCGJCBlVVKyA4MzdF5uM+sqTdXbKzOrT5DGd\r\nCZaox4s+w16Sq1rHzZKFWfQPfKLDB9pyA0ufCVRA3AF6BUi7G3ZqhZiHNhMP\r\nNvE45V/hS1PbZcfPVoUjE2qc1Ix1\r\n=7Wpe\r\n-----END PGP PUBLIC KEY BLOCK-----';
var publicKeys = openpgp.key.readArmored(publicKeyArmored).keys;
var msg = openpgp.message.readSignedContent(content, detachedSig);
var result = msg.verify(publicKeys);
expect(result[0].valid).to.be.true;
});
});