Add verify method to message class and other improvements. Implement openpgp.decryptAndVerifyMessage. Allow parsing of unhashed signature subpackets.
This commit is contained in:
parent
b0ea97ec28
commit
c2a79368dc
File diff suppressed because one or more lines are too long
144
src/message.js
144
src/message.js
|
@ -20,6 +20,7 @@ var enums = require('./enums.js');
|
|||
var armor = require('./encoding/armor.js');
|
||||
var config = require('./config');
|
||||
var crypto = require('./crypto');
|
||||
var util = require('./util');
|
||||
|
||||
/**
|
||||
* @class
|
||||
|
@ -31,7 +32,7 @@ function message(packetlist) {
|
|||
this.packets = packetlist || new packet.list();
|
||||
|
||||
/**
|
||||
* Returns the key IDs of the public keys to which the session key is encrypted
|
||||
* Returns the key IDs of the keys to which the session key is encrypted
|
||||
* @return {[keyId]} array of keyid objects
|
||||
*/
|
||||
this.getEncryptionKeyIds = function() {
|
||||
|
@ -43,6 +44,28 @@ function message(packetlist) {
|
|||
return keyIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key IDs of the keys that signed the message
|
||||
* @return {[keyId]} array of keyid objects
|
||||
*/
|
||||
this.getSigningKeyIds = function() {
|
||||
var keyIds = [];
|
||||
var msg = this.unwrapCompressed();
|
||||
// search for one pass signatures
|
||||
var onePassSigList = msg.packets.filterByTag(enums.packet.one_pass_signature);
|
||||
onePassSigList.forEach(function(packet) {
|
||||
keyIds.push(packet.signingKeyId);
|
||||
});
|
||||
// if nothing found look for signature packets
|
||||
if (!keyIds.length) {
|
||||
var signatureList = msg.packets.filterByTag(enums.packet.signature);
|
||||
signatureList.forEach(function(packet) {
|
||||
keyIds.push(packet.issuerKeyId);
|
||||
});
|
||||
}
|
||||
return keyIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt the message
|
||||
* @param {key} privateKey private key with decrypted secret data
|
||||
|
@ -79,11 +102,30 @@ function message(packetlist) {
|
|||
* Get literal data that is the body of the message
|
||||
* @return {String|null} literal body of the message as string
|
||||
*/
|
||||
this.getLiteral = function() {
|
||||
this.getLiteralData = function() {
|
||||
var literal = this.packets.findPacket(enums.packet.literal);
|
||||
return literal && literal.data || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get literal data as text
|
||||
* @return {String|null} literal body of the message interpreted as text
|
||||
*/
|
||||
this.getText = function() {
|
||||
var literal = this.packets.findPacket(enums.packet.literal);
|
||||
if (literal) {
|
||||
var data = literal.data;
|
||||
if (literal.format == enums.read(enums.literal, enums.literal.binary)
|
||||
|| literal.format == enums.read(enums.literal, enums.literal.text)) {
|
||||
// text in a literal packet with format 'binary' or 'text' could be utf8, therefore decode
|
||||
data = util.decode_utf8(data);
|
||||
}
|
||||
return data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the message
|
||||
* @param {[key]} keys array of keys, used to encrypt the message
|
||||
|
@ -121,37 +163,93 @@ function message(packetlist) {
|
|||
|
||||
/**
|
||||
* Sign the message (the literal data packet of the message)
|
||||
* @param {key} privateKey private key with decrypted secret key data for signing
|
||||
* @return {[message]} new message with encrypted content
|
||||
* @param {[key]} privateKey private keys with decrypted secret key data for signing
|
||||
* @return {message} new message with signed content
|
||||
*/
|
||||
this.sign = function(privateKey) {
|
||||
this.sign = function(privateKeys) {
|
||||
|
||||
var packetlist = new packet.list();
|
||||
|
||||
var onePassSig = new packet.one_pass_signature();
|
||||
onePassSig.type = enums.signature.text;
|
||||
//TODO get preferred hashg algo from signature
|
||||
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
|
||||
var signingKeyPacket = privateKey.getSigningKeyPacket();
|
||||
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||
onePassSig.signingKeyId = signingKeyPacket.getKeyId();
|
||||
packetlist.push(onePassSig);
|
||||
|
||||
|
||||
var literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
||||
if (!literalDataPacket) throw new Error('No literal data packet to sign.');
|
||||
packetlist.push(literalDataPacket);
|
||||
|
||||
var literalFormat = enums.write(enums.literal, literalDataPacket.format);
|
||||
var signatureType = literalFormat == enums.literal.binary
|
||||
? enums.signature.binary : enums.signature.text;
|
||||
|
||||
for (var i = 0; i < privateKeys.length; i++) {
|
||||
var onePassSig = new packet.one_pass_signature();
|
||||
onePassSig.type = signatureType;
|
||||
//TODO get preferred hashg algo from key signature
|
||||
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
|
||||
var signingKeyPacket = privateKeys[i].getSigningKeyPacket();
|
||||
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||
onePassSig.signingKeyId = signingKeyPacket.getKeyId();
|
||||
packetlist.push(onePassSig);
|
||||
}
|
||||
|
||||
var signaturePacket = new packet.signature();
|
||||
signaturePacket.signatureType = enums.signature.text;
|
||||
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||
if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.');
|
||||
signaturePacket.sign(signingKeyPacket, literalDataPacket);
|
||||
packetlist.push(signaturePacket);
|
||||
packetlist.push(literalDataPacket);
|
||||
|
||||
for (var i = privateKeys.length - 1; i >= 0; i--) {
|
||||
var signaturePacket = new packet.signature();
|
||||
signaturePacket.signatureType = signatureType;
|
||||
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||
if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.');
|
||||
signaturePacket.sign(signingKeyPacket, literalDataPacket);
|
||||
packetlist.push(signaturePacket);
|
||||
}
|
||||
|
||||
return new message(packetlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify message signatures
|
||||
* @param {[key]} publicKeys public keys to verify signatures
|
||||
* @return {[{'keyid': keyid, 'valid': Boolean}]} list of signer's keyid and validity of signature
|
||||
*/
|
||||
this.verify = function(publicKeys) {
|
||||
var result = [];
|
||||
var msg = this.unwrapCompressed();
|
||||
var literalDataList = msg.packets.filterByTag(enums.packet.literal);
|
||||
if (literalDataList.length !== 1) throw new Error('Can only verify message with one literal data packet.');
|
||||
var signatureList = msg.packets.filterByTag(enums.packet.signature);
|
||||
publicKeys.forEach(function(pubKey) {
|
||||
for (var i = 0; i < signatureList.length; i++) {
|
||||
var publicKeyPacket = pubKey.getPublicKeyPacket([signatureList[i].issuerKeyId]);
|
||||
if (publicKeyPacket) {
|
||||
var verifiedSig = {};
|
||||
verifiedSig.keyid = signatureList[i].issuerKeyId;
|
||||
verifiedSig.status = signatureList[i].verify(publicKeyPacket, literalDataList[0]);
|
||||
result.push(verifiedSig);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap compressed message
|
||||
* @return {message} message Content of compressed message
|
||||
*/
|
||||
this.unwrapCompressed = function() {
|
||||
var compressed = this.packets.filterByTag(enums.packet.compressed);
|
||||
if (compressed.length) {
|
||||
return new message(compressed[0].packets);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ASCII armored text of message
|
||||
* @return {String} ASCII armor
|
||||
*/
|
||||
this.armor = function() {
|
||||
return armor.encode(enums.armor.message, this.packets.write());
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a message and generates user interface message out of the found.
|
||||
* MDC will be verified as well as message signatures
|
||||
|
|
|
@ -38,7 +38,7 @@ var message = require('./message.js');
|
|||
function _openpgp() {
|
||||
|
||||
/**
|
||||
* encrypts message text with keys
|
||||
* Encrypts message text with keys
|
||||
* @param {[key]} keys array of keys, used to encrypt the message
|
||||
* @param {String} text message as native JavaScript string
|
||||
* @return {String} encrypted ASCII armored message
|
||||
|
@ -51,7 +51,7 @@ function _openpgp() {
|
|||
}
|
||||
|
||||
/**
|
||||
* signs message text and encrypts it
|
||||
* Signs message text and encrypts it
|
||||
* @param {[key]} publicKeys array of keys, used to encrypt the message
|
||||
* @param {key} privateKey private key with decrypted secret key data for signing
|
||||
* @param {String} text message as native JavaScript string
|
||||
|
@ -59,14 +59,14 @@ function _openpgp() {
|
|||
*/
|
||||
function signAndEncryptMessage(publicKeys, privateKey, text) {
|
||||
var msg = message.fromText(text);
|
||||
msg = msg.sign(privateKey);
|
||||
msg = msg.sign([privateKey]);
|
||||
msg = msg.encrypt(publicKeys);
|
||||
var armored = armor.encode(enums.armor.message, msg.packets.write());
|
||||
return armored;
|
||||
}
|
||||
|
||||
/**
|
||||
* decrypts message
|
||||
* Decrypts message
|
||||
* @param {key} privateKey private key with decrypted secret key data
|
||||
* @param {message} message the message object with the encrypted data
|
||||
* @return {String|null} decrypted message as as native JavaScript string
|
||||
|
@ -74,11 +74,27 @@ function _openpgp() {
|
|||
*/
|
||||
function decryptMessage(privateKey, message) {
|
||||
message = message.decrypt(privateKey);
|
||||
return message.getLiteral();
|
||||
return message.getText();
|
||||
}
|
||||
|
||||
function decryptAndVerifyMessage(privateKey, publicKeys, messagePacketlist) {
|
||||
|
||||
/**
|
||||
* Decrypts message and verifies signatures
|
||||
* @param {key} privateKey private key with decrypted secret key data
|
||||
* @param {[key]} publicKeys public keys to verify signatures
|
||||
* @param {message} message the message object with signed and encrypted data
|
||||
* @return {{'text': String, signatures: [{'keyid': keyid, 'status': Boolean}]}}
|
||||
* decrypted message as as native JavaScript string
|
||||
* with verified signatures or null if no literal data found
|
||||
*/
|
||||
function decryptAndVerifyMessage(privateKey, publicKeys, message) {
|
||||
var result = {};
|
||||
message = message.decrypt(privateKey);
|
||||
result.text = message.getText();
|
||||
if (result.text) {
|
||||
result.signatures = message.verify(publicKeys);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function verifyMessage(publicKeys, messagePacketlist) {
|
||||
|
@ -286,6 +302,7 @@ function _openpgp() {
|
|||
this.generateKeyPair = generateKeyPair;
|
||||
this.write_signed_message = write_signed_message;
|
||||
this.signAndEncryptMessage = signAndEncryptMessage;
|
||||
this.decryptAndVerifyMessage = decryptAndVerifyMessage
|
||||
this.encryptMessage = encryptMessage;
|
||||
this.decryptMessage = decryptMessage;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ module.exports = function packetlist() {
|
|||
* writing to packetlist[i] directly will result in an error.
|
||||
*/
|
||||
this.push = function(packet) {
|
||||
packet.packets = new packetlist();
|
||||
packet.packets = packet.packets || new packetlist();
|
||||
|
||||
this[this.length] = packet;
|
||||
this.length++;
|
||||
|
|
|
@ -122,26 +122,21 @@ module.exports = function packet_signature() {
|
|||
this.publicKeyAlgorithm = bytes[i++].charCodeAt();
|
||||
this.hashAlgorithm = bytes[i++].charCodeAt();
|
||||
|
||||
|
||||
function subpackets(bytes, signed) {
|
||||
// Two-octet scalar octet count for following hashed subpacket
|
||||
// data.
|
||||
function subpackets(bytes) {
|
||||
// Two-octet scalar octet count for following subpacket data.
|
||||
var subpacket_length = util.readNumber(
|
||||
bytes.substr(0, 2));
|
||||
|
||||
var i = 2;
|
||||
|
||||
// Hashed subpacket data set (zero or more subpackets)
|
||||
// subpacket data set (zero or more subpackets)
|
||||
var subpacked_read = 0;
|
||||
while (i < 2 + subpacket_length) {
|
||||
|
||||
var len = packet.readSimpleLength(bytes.substr(i));
|
||||
i += len.offset;
|
||||
|
||||
// Since it is trivial to add data to the unhashed portion of
|
||||
// the packet we simply ignore all unauthenticated data.
|
||||
if (signed)
|
||||
this.read_sub_packet(bytes.substr(i, len.len));
|
||||
this.read_sub_packet(bytes.substr(i, len.len));
|
||||
|
||||
i += len.len;
|
||||
}
|
||||
|
@ -149,6 +144,7 @@ module.exports = function packet_signature() {
|
|||
return i;
|
||||
}
|
||||
|
||||
// hashed subpackets
|
||||
i += subpackets.call(this, bytes.substr(i), true);
|
||||
|
||||
// A V4 signature hashes the packet body
|
||||
|
@ -159,6 +155,7 @@ module.exports = function packet_signature() {
|
|||
// subpacket body.
|
||||
this.signatureData = bytes.substr(0, i);
|
||||
|
||||
// unhashed subpackets
|
||||
i += subpackets.call(this, bytes.substr(i), false);
|
||||
|
||||
break;
|
||||
|
@ -582,8 +579,8 @@ module.exports = function packet_signature() {
|
|||
|
||||
/**
|
||||
* verifys the signature packet. Note: not signature types are implemented
|
||||
* @param {String} data data which on the signature applies
|
||||
* @param {openpgp_msg_privatekey} key the public key to verify the signature
|
||||
* @param {String|Object} data data which on the signature applies
|
||||
* @param {public_subkey|packet_public_key} key the public key to verify the signature
|
||||
* @return {boolean} True if message is verified, else false.
|
||||
*/
|
||||
this.verify = function(key, data) {
|
||||
|
|
|
@ -137,6 +137,38 @@ unit.register("Signature testing", function() {
|
|||
'=h/aX',
|
||||
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
||||
|
||||
var pub_key_arm3 =
|
||||
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
|
||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||
'',
|
||||
'mQENBFKV0FUBCACtZliApy01KBGbGNB36YGH4lpr+5KoqF1I8A5IT0YeNjyGisOk',
|
||||
'WsDsUzOqaNvgzQ82I3MY/jQV5rLBhH/6LiRmCA16WkKcqBrHfNGIxJ+Q+ofVBHUb',
|
||||
'aS9ClXYI88j747QgWzirnLuEA0GfilRZcewII1pDA/G7+m1HwV4qHsPataYLeboq',
|
||||
'hPA3h1EVVQFMAcwlqjOuS8+weHQRfNVRGQdRMm6H7166PseDVRUHdkJpVaKFhptg',
|
||||
'rDoNI0lO+UujdqeF1o5tVZ0j/s7RbyBvdLTXNuBbcpq93ceSWuJPZmi1XztQXKYe',
|
||||
'y0f+ltgVtZDEc7TGV5WDX9erRECCcA3+s7J3ABEBAAG0G0pTIENyeXB0byA8ZGlm',
|
||||
'ZmllQGhvbWUub3JnPokBPwQTAQIAKQUCUpXQVQIbAwUJCWYBgAcLCQgHAwIBBhUI',
|
||||
'AgkKCwQWAgMBAh4BAheAAAoJENvyI+hwU030yRAIAKX/mGEgi/miqasbbQoyK/CS',
|
||||
'a7sRxgZwOWQLdi2xxpE5V4W4HJIDNLJs5vGpRN4mmcNK2fmJAh74w0PskmVgJEhP',
|
||||
'dFJ14UC3fFPq5nbqkBl7hU0tDP5jZxo9ruQZfDOWpHKxOCz5guYJ0CW97bz4fChZ',
|
||||
'NFDyfU7VsJQwRIoViVcMCipP0fVZQkIhhwpzQpmVmN8E0a6jWezTZv1YpMdlzbEf',
|
||||
'H79l3StaOh9/Un9CkIyqEWdYiKvIYms9nENyehN7r/OKYN3SW+qlt5GaL+ws+N1w',
|
||||
'6kEZjPFwnsr+Y4A3oHcAwXq7nfOz71USojSmmo8pgdN8je16CP98vw3/k6TncLS5',
|
||||
'AQ0EUpXQVQEIAMEjHMeqg7B04FliUFWr/8C6sJDb492MlGAWgghIbnuJfXAnUGdN',
|
||||
'oAzn0S+n93Y/qHbW6YcjHD4/G+kK3MuxthAFqcVjdHZQXK0rkhXO/u1co7v1cdtk',
|
||||
'OTEcyOpyLXolM/1S2UYImhrml7YulTHMnWVja7xu6QIRso+7HBFT/u9D47L/xXrX',
|
||||
'MzXFVZfBtVY+yoeTrOY3OX9cBMOAu0kuN9eT18Yv2yi6XMzP3iONVHtl6HfFrAA7',
|
||||
'kAtx4ne0jgAPWZ+a8hMy59on2ZFs/AvSpJtSc1kw/vMTWkyVP1Ky20vAPHQ6Ej5q',
|
||||
'1NGJ/JbcFgolvEeI/3uDueLjj4SdSIbLOXMAEQEAAYkBJQQYAQIADwUCUpXQVQIb',
|
||||
'DAUJCWYBgAAKCRDb8iPocFNN9NLkB/wO4iRxia0zf4Kw2RLVZG8qcuo3Bw9UTXYY',
|
||||
'lI0AutoLNnSURMLLCq6rcJ0BCXGj/2iZ0NBxZq3t5vbRh6uUv+hpiSxK1nF7AheN',
|
||||
'4aAAzhbWx0UDTF04ebG/neE4uDklRIJLhif6+Bwu+EUeTlGbDj7fqGSsNe8g92w7',
|
||||
'1e41rF/9CMoOswrKgIjXAou3aexogWcHvKY2D+1q9exORe1rIa1+sUGl5PG2wsEs',
|
||||
'znN6qtN5gMlGY1ofWDY+I02gO4qzaZ/FxRZfittCw7v5dmQYKot9qRi2Kx3Fvw+h',
|
||||
'ivFBpC4TWgppFBnJJnAsFXZJQcejMW4nEmOViRQXY8N8PepQmgsu',
|
||||
'=ummy',
|
||||
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
||||
|
||||
|
||||
var tests = [function() {
|
||||
var priv_key = openpgp.key.readArmored(priv_key_arm1).packets;
|
||||
|
@ -229,6 +261,103 @@ unit.register("Signature testing", function() {
|
|||
var pub_key = openpgp.key.readArmored(pub_key_arm2).packets;
|
||||
sMsg[0].packets[2].verify(pub_key[3], sMsg[0].packets[1]);
|
||||
return new unit.result("Verify V3 signature. Hash: MD5. PK: RSA. Signature Type: 0x01 (text document)", sMsg[0].packets[2].verified);
|
||||
}, function() {
|
||||
|
||||
var msg_armor =
|
||||
['-----BEGIN PGP MESSAGE-----',
|
||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||
'',
|
||||
'hIwD4IT3RGwgLJcBBADEBdm+GEW7IV1K/Bykg0nB0WYO08ai7/8/+Y/O9xu6RiU0',
|
||||
'q7/jWuKms7kSjw9gxMCjf2dGnAuT4Cg505Kj5WfeBuHh618ovO8qo4h0qHyp1/y3',
|
||||
'o1P0IXPAb+LGJOeO7DyM9Xp2AOBiIKOVWzFTg+MBZOc+XZEVx3FioHfm9SSDudLA',
|
||||
'WAEkDakCG6MRFj/7SmOiV8mQKH+YPMKT69eDZW7hjINabrpM2pdRU7c9lC7CMUBx',
|
||||
'Vj7wZsQBMASSC8f2rhpGA2iKvYMsmW3g9R1xkvj1MXWftSPUS4jeNTAgEwvvF6Af',
|
||||
'cP+OYSXKlTbwfEr73ES2O3/IFE9sHRjPqWaxWuv4DDQ5YfIxE54C1aE8Aq5/QaIH',
|
||||
'v38TUSia0yEMCc/tJd58DikkT07AF162tcx9Ro0ZjhudyuvUyXIfPfxA+XWR2pdz',
|
||||
'ifxyV4zia9RvaCUY8vXGM+gQJ3NNXx2LkZA3kWUEyxFVL1Vl/XUQY0M6U+uccSk4',
|
||||
'eMXm6eyEWDcj0lBRckqKoKo1w/uan11jPuHsnRz6jO9DsuKEz79UDgI=',
|
||||
'=cFi7',
|
||||
'-----END PGP MESSAGE-----'].join('\n');
|
||||
|
||||
var plaintext = 'short message\nnext line\n한국어/조선말';
|
||||
var esMsg = openpgp.message.readArmored(msg_armor);
|
||||
var pubKey = openpgp.key.readArmored(pub_key_arm2);
|
||||
var privKey = openpgp.key.readArmored(priv_key_arm2);
|
||||
|
||||
var keyids = esMsg.getEncryptionKeyIds();
|
||||
privKey.decryptKeyPacket(keyids, 'hello world');
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg);
|
||||
var verified = decrypted.text == plaintext && decrypted.signatures[0].status;
|
||||
|
||||
return new unit.result("Verify signature of signed and encrypted message from GPG2 with openpgp.decryptAndVerifyMessage", verified);
|
||||
}, function() {
|
||||
|
||||
var msg_armor =
|
||||
['-----BEGIN PGP MESSAGE-----',
|
||||
'Version: Encryption Desktop 10.3.0 (Build 9307)',
|
||||
'Charset: utf-8',
|
||||
'',
|
||||
'qANQR1DBjAPghPdEbCAslwED/2S4oNvCjO5TdLUMMUuVOQc8fi6c5XIBu7Y09fEX',
|
||||
'Jm/UrkDHVgmPojLGBDF0CYENNZOVrNfpahY7A3r4HPzGucBzCO1uxuUIKjhtNAAM',
|
||||
'mjD939ernjooOZrM6xDuRaX8adG0LSxpNaVJGxXd/EdlmKDJbYDI6aJ5INrUxzAR',
|
||||
'DAqw0sBSAXgRWgiH6IIiAo5y5WFEDEN9sGStaEQT2wd32kX73M4iZuMt/GM2agiB',
|
||||
'sWb7yLcNHiJ/3OnTfDg9+T543kFq9FlwFbwqygO/wm9e/kgMBq0ZsFOfV+GRtXep',
|
||||
'3qNbJsmzGvdqiUHb/+hkdE191jaSVcO/zaMW4N0Vc1IwIEhZ8I9+9bKwusdVhHT5',
|
||||
'MySnhIogv+0Ilag/aY+UiCt+Zcie69T7Eix48fC/VVW5w3INf1T2CMmDm5ZLZFRN',
|
||||
'oyqzb9Vsgu1gS7SCb6qTbnbV9PlSyU4wJB6siX8hz/U0urokT5se3uYRjiV0KbkA',
|
||||
'zl1/r/wCrmwX4Gl9VN9+33cQgYZAlJLsRw8N82GhbVweZS8qwv24GQ==',
|
||||
'=nx90',
|
||||
'-----END PGP MESSAGE-----'].join('\n');
|
||||
|
||||
var plaintext = 'short message\nnext line\n한국어/조선말\n\n';
|
||||
var esMsg = openpgp.message.readArmored(msg_armor);
|
||||
var pubKey = openpgp.key.readArmored(pub_key_arm2);
|
||||
var privKey = openpgp.key.readArmored(priv_key_arm2);
|
||||
|
||||
var keyids = esMsg.getEncryptionKeyIds();
|
||||
privKey.decryptKeyPacket(keyids, 'hello world');
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg);
|
||||
var verified = decrypted.text == plaintext && decrypted.signatures[0].status;
|
||||
|
||||
return new unit.result("Verify signature of signed and encrypted message from PGP 10.3.0 with openpgp.decryptAndVerifyMessage", verified);
|
||||
}, function() {
|
||||
|
||||
var msg_armor =
|
||||
['-----BEGIN PGP MESSAGE-----',
|
||||
'Version: GnuPG v2.0.19 (GNU/Linux)',
|
||||
'',
|
||||
'owGbwMvMwMF4+5Pyi4Jg3y8ME8DcBy3fXXIUdKYzrjFNYilJrSgJmsXDXJyRX1Si',
|
||||
'kJtaXJyYnsqVBxRVyMnMS+V6O3XOq61r30zbov9m4YY3LQteL5/QMYeFgZGDgY2V',
|
||||
'CaSRgYtTAGZiYxYLwySbQk07ptZel6gmjrKyBWsyWdkOG3oscLBdIpXXfDdb6fNv',
|
||||
'8ULN5L1ed+xNo79P2dBotWud6vn7e9dtLJ7o12PunnvEz8gyyvP4/As/los0xsnZ',
|
||||
'H+8ublrhvGtLxJUZuUKZO6QdHq2Nepuw8OrfiMXPBDQXXpV2q11Ze+rD3lndgv/C',
|
||||
'bJQNOhll0J0H839jFvt/16m20h/ZmDoWqJywapnypjdIjcXr+7rJFess40yenV7Q',
|
||||
'2LSu/EX6Aq29x+dv+GPUMfuhTNE3viWWUR4PD6T7XfmdViUwmSf8fkRNUn/t3a2n',
|
||||
'cq46Xr36seCor/OLp0atSZwHrjx2SU5zPLheZn+zw/0d1/YZnD7AEeP9s/Cuycyv',
|
||||
'CZ5HZNKufvB8fsh+dfdSXW0GfqkPfxk36Vw8ufpjaoZDyt2nxxg/6D4KS3UvZzv3',
|
||||
'axdLZ9yd0OJNZv4P501If24W4vTGz6nI7Ser8Yd2PiOvE5MWMT0wLZQ+zPX1sv0/',
|
||||
's8PvkyWmVM0O0fB/ZSHovHNNPffDg/rWhzOmXQ9/7vTn477F+aWm5sYzJ75/BQA=',
|
||||
'=+L0S',
|
||||
'-----END PGP MESSAGE-----'].join('\n');
|
||||
|
||||
var plaintext = 'short message\nnext line\n한국어/조선말';
|
||||
var sMsg = openpgp.message.readArmored(msg_armor);
|
||||
var pubKey2 = openpgp.key.readArmored(pub_key_arm2);
|
||||
var pubKey3 = openpgp.key.readArmored(pub_key_arm3);
|
||||
|
||||
var keyids = sMsg.getSigningKeyIds();
|
||||
|
||||
var verified = pubKey2.getPublicKeyPacket(keyids) && pubKey3.getPublicKeyPacket(keyids);
|
||||
|
||||
verified = verified && sMsg.getText() == plaintext;
|
||||
|
||||
var verifiedSig = sMsg.verify([pubKey2, pubKey3]);
|
||||
|
||||
verified = verified && verifiedSig[0].status && verifiedSig[1].status;
|
||||
|
||||
return new unit.result("Verify signed message with two one pass signatures", verified);
|
||||
}];
|
||||
|
||||
var results = [];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!-- unit test -->
|
||||
<script type="text/javascript" src="test-bundle.js"></script>
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user