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
120
src/message.js
120
src/message.js
|
@ -20,6 +20,7 @@ var enums = require('./enums.js');
|
||||||
var armor = require('./encoding/armor.js');
|
var armor = require('./encoding/armor.js');
|
||||||
var config = require('./config');
|
var config = require('./config');
|
||||||
var crypto = require('./crypto');
|
var crypto = require('./crypto');
|
||||||
|
var util = require('./util');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
|
@ -31,7 +32,7 @@ function message(packetlist) {
|
||||||
this.packets = packetlist || new packet.list();
|
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
|
* @return {[keyId]} array of keyid objects
|
||||||
*/
|
*/
|
||||||
this.getEncryptionKeyIds = function() {
|
this.getEncryptionKeyIds = function() {
|
||||||
|
@ -43,6 +44,28 @@ function message(packetlist) {
|
||||||
return keyIds;
|
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
|
* Decrypt the message
|
||||||
* @param {key} privateKey private key with decrypted secret data
|
* @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
|
* Get literal data that is the body of the message
|
||||||
* @return {String|null} literal body of the message as string
|
* @return {String|null} literal body of the message as string
|
||||||
*/
|
*/
|
||||||
this.getLiteral = function() {
|
this.getLiteralData = function() {
|
||||||
var literal = this.packets.findPacket(enums.packet.literal);
|
var literal = this.packets.findPacket(enums.packet.literal);
|
||||||
return literal && literal.data || null;
|
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
|
* Encrypt the message
|
||||||
* @param {[key]} keys array of keys, used to 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)
|
* Sign the message (the literal data packet of the message)
|
||||||
* @param {key} privateKey private key with decrypted secret key data for signing
|
* @param {[key]} privateKey private keys with decrypted secret key data for signing
|
||||||
* @return {[message]} new message with encrypted content
|
* @return {message} new message with signed content
|
||||||
*/
|
*/
|
||||||
this.sign = function(privateKey) {
|
this.sign = function(privateKeys) {
|
||||||
|
|
||||||
var packetlist = new packet.list();
|
var packetlist = new packet.list();
|
||||||
|
|
||||||
|
var literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
||||||
|
if (!literalDataPacket) throw new Error('No literal data packet to sign.');
|
||||||
|
|
||||||
|
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();
|
var onePassSig = new packet.one_pass_signature();
|
||||||
onePassSig.type = enums.signature.text;
|
onePassSig.type = signatureType;
|
||||||
//TODO get preferred hashg algo from signature
|
//TODO get preferred hashg algo from key signature
|
||||||
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
|
onePassSig.hashAlgorithm = config.prefer_hash_algorithm;
|
||||||
var signingKeyPacket = privateKey.getSigningKeyPacket();
|
var signingKeyPacket = privateKeys[i].getSigningKeyPacket();
|
||||||
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||||
onePassSig.signingKeyId = signingKeyPacket.getKeyId();
|
onePassSig.signingKeyId = signingKeyPacket.getKeyId();
|
||||||
packetlist.push(onePassSig);
|
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);
|
packetlist.push(literalDataPacket);
|
||||||
|
|
||||||
|
for (var i = privateKeys.length - 1; i >= 0; i--) {
|
||||||
var signaturePacket = new packet.signature();
|
var signaturePacket = new packet.signature();
|
||||||
signaturePacket.signatureType = enums.signature.text;
|
signaturePacket.signatureType = signatureType;
|
||||||
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
signaturePacket.hashAlgorithm = config.prefer_hash_algorithm;
|
||||||
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
|
||||||
if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.');
|
if (!signingKeyPacket.isDecrypted) throw new Error('Private key is not decrypted.');
|
||||||
signaturePacket.sign(signingKeyPacket, literalDataPacket);
|
signaturePacket.sign(signingKeyPacket, literalDataPacket);
|
||||||
packetlist.push(signaturePacket);
|
packetlist.push(signaturePacket);
|
||||||
|
}
|
||||||
|
|
||||||
return new message(packetlist);
|
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.
|
* Decrypts a message and generates user interface message out of the found.
|
||||||
* MDC will be verified as well as message signatures
|
* MDC will be verified as well as message signatures
|
||||||
|
|
|
@ -38,7 +38,7 @@ var message = require('./message.js');
|
||||||
function _openpgp() {
|
function _openpgp() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* encrypts message text with keys
|
* Encrypts message text with keys
|
||||||
* @param {[key]} keys array of keys, used to encrypt the message
|
* @param {[key]} keys array of keys, used to encrypt the message
|
||||||
* @param {String} text message as native JavaScript string
|
* @param {String} text message as native JavaScript string
|
||||||
* @return {String} encrypted ASCII armored message
|
* @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]} publicKeys array of keys, used to encrypt the message
|
||||||
* @param {key} privateKey private key with decrypted secret key data for signing
|
* @param {key} privateKey private key with decrypted secret key data for signing
|
||||||
* @param {String} text message as native JavaScript string
|
* @param {String} text message as native JavaScript string
|
||||||
|
@ -59,14 +59,14 @@ function _openpgp() {
|
||||||
*/
|
*/
|
||||||
function signAndEncryptMessage(publicKeys, privateKey, text) {
|
function signAndEncryptMessage(publicKeys, privateKey, text) {
|
||||||
var msg = message.fromText(text);
|
var msg = message.fromText(text);
|
||||||
msg = msg.sign(privateKey);
|
msg = msg.sign([privateKey]);
|
||||||
msg = msg.encrypt(publicKeys);
|
msg = msg.encrypt(publicKeys);
|
||||||
var armored = armor.encode(enums.armor.message, msg.packets.write());
|
var armored = armor.encode(enums.armor.message, msg.packets.write());
|
||||||
return armored;
|
return armored;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* decrypts message
|
* Decrypts message
|
||||||
* @param {key} privateKey private key with decrypted secret key data
|
* @param {key} privateKey private key with decrypted secret key data
|
||||||
* @param {message} message the message object with the encrypted data
|
* @param {message} message the message object with the encrypted data
|
||||||
* @return {String|null} decrypted message as as native JavaScript string
|
* @return {String|null} decrypted message as as native JavaScript string
|
||||||
|
@ -74,11 +74,27 @@ function _openpgp() {
|
||||||
*/
|
*/
|
||||||
function decryptMessage(privateKey, message) {
|
function decryptMessage(privateKey, message) {
|
||||||
message = message.decrypt(privateKey);
|
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) {
|
function verifyMessage(publicKeys, messagePacketlist) {
|
||||||
|
@ -286,6 +302,7 @@ function _openpgp() {
|
||||||
this.generateKeyPair = generateKeyPair;
|
this.generateKeyPair = generateKeyPair;
|
||||||
this.write_signed_message = write_signed_message;
|
this.write_signed_message = write_signed_message;
|
||||||
this.signAndEncryptMessage = signAndEncryptMessage;
|
this.signAndEncryptMessage = signAndEncryptMessage;
|
||||||
|
this.decryptAndVerifyMessage = decryptAndVerifyMessage
|
||||||
this.encryptMessage = encryptMessage;
|
this.encryptMessage = encryptMessage;
|
||||||
this.decryptMessage = decryptMessage;
|
this.decryptMessage = decryptMessage;
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ module.exports = function packetlist() {
|
||||||
* writing to packetlist[i] directly will result in an error.
|
* writing to packetlist[i] directly will result in an error.
|
||||||
*/
|
*/
|
||||||
this.push = function(packet) {
|
this.push = function(packet) {
|
||||||
packet.packets = new packetlist();
|
packet.packets = packet.packets || new packetlist();
|
||||||
|
|
||||||
this[this.length] = packet;
|
this[this.length] = packet;
|
||||||
this.length++;
|
this.length++;
|
||||||
|
|
|
@ -122,25 +122,20 @@ module.exports = function packet_signature() {
|
||||||
this.publicKeyAlgorithm = bytes[i++].charCodeAt();
|
this.publicKeyAlgorithm = bytes[i++].charCodeAt();
|
||||||
this.hashAlgorithm = bytes[i++].charCodeAt();
|
this.hashAlgorithm = bytes[i++].charCodeAt();
|
||||||
|
|
||||||
|
function subpackets(bytes) {
|
||||||
function subpackets(bytes, signed) {
|
// Two-octet scalar octet count for following subpacket data.
|
||||||
// Two-octet scalar octet count for following hashed subpacket
|
|
||||||
// data.
|
|
||||||
var subpacket_length = util.readNumber(
|
var subpacket_length = util.readNumber(
|
||||||
bytes.substr(0, 2));
|
bytes.substr(0, 2));
|
||||||
|
|
||||||
var i = 2;
|
var i = 2;
|
||||||
|
|
||||||
// Hashed subpacket data set (zero or more subpackets)
|
// subpacket data set (zero or more subpackets)
|
||||||
var subpacked_read = 0;
|
var subpacked_read = 0;
|
||||||
while (i < 2 + subpacket_length) {
|
while (i < 2 + subpacket_length) {
|
||||||
|
|
||||||
var len = packet.readSimpleLength(bytes.substr(i));
|
var len = packet.readSimpleLength(bytes.substr(i));
|
||||||
i += len.offset;
|
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;
|
i += len.len;
|
||||||
|
@ -149,6 +144,7 @@ module.exports = function packet_signature() {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hashed subpackets
|
||||||
i += subpackets.call(this, bytes.substr(i), true);
|
i += subpackets.call(this, bytes.substr(i), true);
|
||||||
|
|
||||||
// A V4 signature hashes the packet body
|
// A V4 signature hashes the packet body
|
||||||
|
@ -159,6 +155,7 @@ module.exports = function packet_signature() {
|
||||||
// subpacket body.
|
// subpacket body.
|
||||||
this.signatureData = bytes.substr(0, i);
|
this.signatureData = bytes.substr(0, i);
|
||||||
|
|
||||||
|
// unhashed subpackets
|
||||||
i += subpackets.call(this, bytes.substr(i), false);
|
i += subpackets.call(this, bytes.substr(i), false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -582,8 +579,8 @@ module.exports = function packet_signature() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* verifys the signature packet. Note: not signature types are implemented
|
* verifys the signature packet. Note: not signature types are implemented
|
||||||
* @param {String} data data which on the signature applies
|
* @param {String|Object} data data which on the signature applies
|
||||||
* @param {openpgp_msg_privatekey} key the public key to verify the signature
|
* @param {public_subkey|packet_public_key} key the public key to verify the signature
|
||||||
* @return {boolean} True if message is verified, else false.
|
* @return {boolean} True if message is verified, else false.
|
||||||
*/
|
*/
|
||||||
this.verify = function(key, data) {
|
this.verify = function(key, data) {
|
||||||
|
|
|
@ -137,6 +137,38 @@ unit.register("Signature testing", function() {
|
||||||
'=h/aX',
|
'=h/aX',
|
||||||
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
|
'-----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 tests = [function() {
|
||||||
var priv_key = openpgp.key.readArmored(priv_key_arm1).packets;
|
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;
|
var pub_key = openpgp.key.readArmored(pub_key_arm2).packets;
|
||||||
sMsg[0].packets[2].verify(pub_key[3], sMsg[0].packets[1]);
|
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);
|
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 = [];
|
var results = [];
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<!-- unit test -->
|
<!-- unit test -->
|
||||||
<script type="text/javascript" src="test-bundle.js"></script>
|
<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