Merge pull request #121 from toberndo/devel

devel branch: work on key and message class
This commit is contained in:
Sean Colyer 2013-10-31 19:28:37 -07:00
commit 40701e09ab
21 changed files with 2053 additions and 1391 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
var crypto = require('./crypto');
module.exports = require('./openpgp.js'); module.exports = require('./openpgp.js');
module.exports.key = require('./key.js');
module.exports.message = require('./message.js');
module.exports.util = require('./util'); module.exports.util = require('./util');
module.exports.packet = require('./packet'); module.exports.packet = require('./packet');
module.exports.mpi = require('./type/mpi.js'); module.exports.mpi = require('./type/mpi.js');
@ -9,6 +10,4 @@ module.exports.keyid = require('./type/keyid.js');
module.exports.armor = require('./encoding/armor.js'); module.exports.armor = require('./encoding/armor.js');
module.exports.enums = require('./enums.js'); module.exports.enums = require('./enums.js');
module.exports.config = require('./config'); module.exports.config = require('./config');
module.exports.crypto = require('./crypto');
for (var i in crypto)
module.exports[i] = crypto[i];

View File

@ -17,123 +17,226 @@
var packet = require('./packet'); var packet = require('./packet');
var enums = require('./enums.js'); var enums = require('./enums.js');
var armor = require('./encoding/armor.js');
var config = require('./config');
/** /**
* @class * @class
* @classdesc Class that represents an OpenPGP key. Must contain a master key. * @classdesc Class that represents an OpenPGP key. Must contain a master key.
* @param {packetlist} packetlist [description]
* Can contain additional subkeys, signatures, * Can contain additional subkeys, signatures,
* user ids, user attributes. * user ids, user attributes.
*/ */
module.exports = function key() { function key(packetlist) {
this.packets = new packet.list(); this.packets = packetlist || new packet.list();
/** Returns the primary key (secret or public)
* @returns {openpgp_packet_secret_key|openpgp_packet_public_key|null} */ /**
this.getKey = function() { * Returns the primary key packet (secret or public)
for (var i = 0; i < this.packets.length; i++) * @returns {packet_secret_key|packet_public_key|null}
*/
this.getKeyPacket = function() {
for (var i = 0; i < this.packets.length; i++) {
if (this.packets[i].tag == enums.packet.public_key || if (this.packets[i].tag == enums.packet.public_key ||
this.packets[i].tag == enums.packet.secret_key) this.packets[i].tag == enums.packet.secret_key) {
return this.packets[i]; return this.packets[i];
}
}
return null; return null;
}; }
/** Returns all the private and public subkeys /**
* @returns {openpgp_packet_subkey[]} */ * Returns all the private and public subkey packets
this.getSubkeys = function() { * @returns {[public_subkey|secret_subkey]}
*/
this.getSubkeyPackets = function() {
var subkeys = []; var subkeys = [];
for (var i = 0; i < this.packets.length; i++) for (var i = 0; i < this.packets.length; i++) {
if (this.packets[i].tag == enums.packet.public_subkey || if (this.packets[i].tag == enums.packet.public_subkey ||
this.packets[i].tag == enums.packet.secret_subkey) this.packets[i].tag == enums.packet.secret_subkey) {
subkeys.push(this.packets[i]); subkeys.push(this.packets[i]);
}
}
return subkeys; return subkeys;
}; }
this.getAllKeys = function() { /**
return [this.getKey()].concat(this.getSubkeys()); * Returns all the private and public key and subkey packets
}; * @returns {[public_subkey|secret_subkey|packet_secret_key|packet_public_key]}
*/
this.getAllKeyPackets = function() {
return [this.getKeyPacket()].concat(this.getSubkeyPackets());
}
this.getSigningKey = function() { /**
* Returns key IDs of all key packets
* @returns {[keyid]}
*/
this.getKeyIds = function() {
var keyIds = [];
var keys = this.getAllKeyPackets();
for (var i = 0; i < keys.length; i++) {
keyIds.push(keys[i].getKeyId());
}
return keyIds;
}
var signing = ['rsa_encrypt_sign', 'rsa_sign', 'dsa']; /**
signing = signing.map(function(s) { * Returns key IDs of all key packets in hex
return openpgp.publickey[s]; * @returns {[String]}
*/
this.getKeyIdsHex = function() {
return this.getKeyIds().map(function(keyId) {
return keyId.toHex();
}); });
var keys = this.getAllKeys();
for (var i in keys)
if (signing.indexOf(keys[i].public_algorithm) != -1)
return keys[i];
return null;
};
function getPreferredSignatureHashAlgorithm() {
var pkey = this.getSigningKey();
if (pkey === null) {
util.print_error("private key is for encryption only! Cannot create a signature.");
return null;
}
if (pkey.publicKey.publicKeyAlgorithm == 17) {
var dsa = new DSA();
return dsa.select_hash_algorithm(pkey.publicKey.MPIs[1].toBigInteger()); // q
}
//TODO implement: https://tools.ietf.org/html/rfc4880#section-5.2.3.8
//separate private key preference from digest preferences
return openpgp.config.config.prefer_hash_algorithm;
} }
/** /**
* Finds an encryption key for this key * Returns first key packet which match to an array of key IDs
* @returns null if no encryption key has been found * @param {[keyid]} keyIds
* @return {public_subkey|secret_subkey|packet_secret_key|packet_public_key|null}
*/ */
this.getEncryptionKey = function() { this.getKeyPacketByIds = function(keyIds) {
var keys = this.getAllKeyPackets();
for (var i = 0; i < keys.length; i++) {
var keyId = keys[i].getKeyId();
for (var j = 0; j < keyIds.length; j++) {
if (keyId.equals(keyIds[j])) {
//TODO return only verified keys
return keys[i];
}
}
}
return null;
}
/**
* Returns true if this is a public key
* @return {Boolean}
*/
this.isPublic = function() {
var publicKeyPackets = this.packets.filterByTag(enums.packet.public_key);
return publicKeyPackets.length !== 0 ? true : false;
}
/**
* Returns true if this is a private key
* @return {Boolean}
*/
this.isPrivate = function() {
var privateKeyPackets = this.packets.filterByTag(enums.packet.private_key);
return privateKeyPackets.length !== 0 ? true : false;
}
/**
* Returns first key packet that is available for signing
* @return {public_subkey|secret_subkey|packet_secret_key|packet_public_key|null}
*/
this.getSigningKeyPacket = function() {
var signing = [ enums.publicKey.rsa_encrypt_sign, enums.publicKey.rsa_sign, enums.publicKey.dsa];
signing = signing.map(function(s) {
return enums.read(enums.publicKey, s);
});
var keys = this.getAllKeyPackets();
for (var i = 0; i < keys.length; i++) {
if (signing.indexOf(keys[i].algorithm) !== -1) {
return keys[i];
}
}
return null;
}
/**
* Returns preferred signature hash algorithm of this key
* @return {String}
*/
function getPreferredSignatureHashAlgorithm() {
//TODO implement: https://tools.ietf.org/html/rfc4880#section-5.2.3.8
//separate private key preference from digest preferences
return config.prefer_hash_algorithm;
}
/**
* Returns the first valid encryption key packet for this key
* @returns {public_subkey|secret_subkey|packet_secret_key|packet_public_key|null} key packet or null if no encryption key has been found
*/
this.getEncryptionKeyPacket = function() {
// V4: by convention subkeys are prefered for encryption service // V4: by convention subkeys are prefered for encryption service
// V3: keys MUST NOT have subkeys // V3: keys MUST NOT have subkeys
var isValidSignKey = function(key) { var isValidEncryptionKey = function(key) {
//TODO evaluate key flags: http://tools.ietf.org/html/rfc4880#section-5.2.3.21
return key.algorithm != enums.read(enums.publicKey, enums.publicKey.dsa) && key.algorithm != enums.read(enums.publicKey, return key.algorithm != enums.read(enums.publicKey, enums.publicKey.dsa) && key.algorithm != enums.read(enums.publicKey,
enums.publicKey.rsa_sign); enums.publicKey.rsa_sign);
//TODO verify key //TODO verify key
//&& keys.verifyKey() //&& keys.verifyKey()
}; };
var subKeys = this.getSubkeys();
for (var j = 0; j < subKeys.length; j++) { var subkeys = this.getSubkeyPackets();
if (isValidSignKey(subKeys[j])) {
return subKeys[j]; for (var j = 0; j < subkeys.length; j++) {
if (isValidEncryptionKey(subkeys[j])) {
return subkeys[j];
} }
} }
// if no valid subkey for encryption, use primary key // if no valid subkey for encryption, use primary key
var primaryKey = this.getKey(); var primaryKey = this.getKeyPacket();
if (isValidSignKey(primaryKey)) { if (isValidEncryptionKey(primaryKey)) {
return primaryKey; return primaryKey;
} }
return null; return null;
}; }
/**
* Decrypts all secret key and subkey packets
* @param {String} passphrase
* @return {undefined}
*/
this.decrypt = function(passphrase) { this.decrypt = function(passphrase) {
var keys = this.getAllKeys(); //TODO boolean return value
var keys = this.getAllKeyPackets();
for (var i in keys) for (var i in keys)
if (keys[i].tag == enums.packet.secret_subkey || if (keys[i].tag == enums.packet.secret_subkey ||
keys[i].tag == enums.packet.secret_key) { keys[i].tag == enums.packet.secret_key) {
keys[i].decrypt(passphrase); keys[i].decrypt(passphrase);
} }
};
// TODO need to implement this
function revoke() {
} }
}; // TODO
this.verify = function() {
}
// TODO
this.revoke = function() {
}
}
/**
* reads an OpenPGP armored text and returns a key object
* @param {String} armoredText text to be parsed
* @return {key} new key object
*/
key.readArmored = function(armoredText) {
//TODO how do we want to handle bad text? Exception throwing
//TODO don't accept non-key armored texts
var input = armor.decode(armoredText).openpgp;
var packetlist = new packet.list();
packetlist.read(input);
var newKey = new key(packetlist);
return newKey;
}
module.exports = key;

View File

@ -15,36 +15,78 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
var packet = require('./packet');
var enums = require('./enums.js');
var armor = require('./encoding/armor.js');
/** /**
* @class * @class
* @classdesc A generic message containing one or more literal packets. * @classdesc A generic message containing one or more literal packets.
*/ */
function openpgp_message() { function message(packetlist) {
this.packets = new openpgp_packetlist();
this.packets = packetlist || new packet.list();
function generic_decrypt(packets, passphrase) { /**
var sessionkey; * Returns the key IDs of the public keys to which the session key is encrypted
* @return {[keyId]} array of keyid objects
for (var i = 0; i < packets.length; i++) { */
if (packets[i].tag == openpgp_packet.tags.public_key_encrypted_session_key) { this.getKeyIds = function() {
var key = openpgp.keyring.getKeyById(packets[i].public_key_id); var keyIds = [];
var pkESKeyPacketlist = this.packets.filterByType(enums.packet.public_key_encrypted_session_key);
} pkESKeyPacketlist.forEach(function(packet) {
} keyIds.push(packet.publicKeyId);
});
return keyIds;
} }
/** /**
* Decrypts a message and generates user interface message out of the found. * Returns the key IDs in hex of the public keys to which the session key is encrypted
* MDC will be verified as well as message signatures * @return {[String]} keyId provided as string of hex numbers (lowercase)
* @param {openpgp_msg_privatekey} private_key the private the message is encrypted with (corresponding to the session key)
* @param {openpgp_packet_encryptedsessionkey} sessionkey the session key to be used to decrypt the message
* @return {} plaintext of the message or null on error
*/ */
this.decrypt = function(key) { this.getKeyIdsHex = function() {
return this.decryptAndVerifySignature(private_key, sessionkey) return this.getKeyIds().map(function(keyId) {
return keyId.toHex();
});
}
/**
* Decrypts the message
* @param {secret_subkey|packet_secret_key} privateKeyPacket the private key packet (with decrypted secret part) the message is encrypted with (corresponding to the session key)
* @return {[String]} array with plaintext of decrypted messages
*/
this.decrypt = function(privateKeyPacket) {
var decryptedMessages = [];
var pkESKeyPacketlist = this.packets.filterByType(enums.packet.public_key_encrypted_session_key);
for (var i = 0; i < pkESKeyPacketlist.length; i++) {
var pkESKeyPacket = pkESKeyPacketlist[i];
if (pkESKeyPacket.publicKeyId.equals(privateKeyPacket.getKeyId())) {
pkESKeyPacket.decrypt(privateKeyPacket);
var symEncryptedPacketlist = this.packets.filter(function(packet) {
return packet.tag == enums.packet.symmetrically_encrypted || packet.tag == enums.packet.sym_encrypted_integrity_protected;
});
for (var k = 0; k < symEncryptedPacketlist.length; k++) {
var symEncryptedPacket = symEncryptedPacketlist[k];
symEncryptedPacket.decrypt(pkESKeyPacket.sessionKeyAlgorithm, pkESKeyPacket.sessionKey);
for (var l = 0; l < symEncryptedPacket.packets.length; l++) {
var dataPacket = symEncryptedPacket.packets[l];
switch (dataPacket.tag) {
case enums.packet.literal:
decryptedMessages.push(dataPacket.getBytes());
break;
case enums.packet.compressed:
//TODO
break;
default:
//TODO
}
}
}
break;
}
}
return decryptedMessages;
} }
/** /**
@ -124,3 +166,20 @@ function openpgp_message() {
return result; return result;
} }
} }
/**
* reads an OpenPGP armored message and returns a message object
* @param {String} armoredText text to be parsed
* @return {key} new message object
*/
message.readArmored = function(armoredText) {
//TODO how do we want to handle bad text? Exception throwing
//TODO don't accept non-message armored texts
var input = armor.decode(armoredText).openpgp;
var packetlist = new packet.list();
packetlist.read(input);
var newMessage = new message(packetlist);
return newMessage;
}
module.exports = message;

View File

@ -26,7 +26,6 @@ var packet = require('./packet');
var util = require('./util'); var util = require('./util');
var enums = require('./enums.js'); var enums = require('./enums.js');
var crypto = require('./crypto'); var crypto = require('./crypto');
var key = require('./key.js');
var config = require('./config'); var config = require('./config');
/** /**
@ -40,90 +39,64 @@ function _openpgp() {
this.tostring = ""; this.tostring = "";
/** /**
* reads message packets out of an OpenPGP armored text and * encrypts message with keys
* returns an array of message objects * @param {[key]} keys array of keys, used to encrypt the message
* @param {String} armoredText text to be parsed * @param {String} message text message as native JavaScript string
* @return {openpgp_msg_message[]} on error the function * @return {String} encrypted ASCII armored message
* returns null
*/ */
function readArmoredPackets(armoredText) { function encryptMessage(keys, message) {
//TODO how do we want to handle bad text? Exception throwing
var input = armor.decode(armoredText.replace(/\r/g, '')).openpgp;
return readDearmoredPackets(input);
}
/** var messagePacketlist = new packet.list();
* reads message packets out of an OpenPGP armored text and
* returns an array of message objects. Can be called externally or internally.
* External call will parse a de-armored messaged and return messages found.
* Internal will be called to read packets wrapped in other packets (i.e. compressed)
* @param {String} input dearmored text of OpenPGP packets, to be parsed
* @return {openpgp_msg_message[]} on error the function
* returns null
*/
function readDearmoredPackets(input) {
var packetList = new packet.list();
packetList.read(input);
return packetList;
}
//TODO I think longterm we might actually want to just make key a subclass of packetlist
//passphrase is optional, this should work for both public and private
function getKeyFromPacketlist(keyPacketlist, passphrase){
var parsedKey = new key();
parsedKey.packets = keyPacketlist;
parsedKey.decrypt(passphrase);
return parsedKey;
}
function encryptMessage(publicKeys, message) {
var packetList = new packet.list();
var literalDataPacket = new packet.literal();
literalDataPacket.set(message, 'utf8');
//TODO get preferred algo from signature //TODO get preferred algo from signature
var sessionKey = crypto.generateSessionKey(enums.read(enums.symmetric, config.encryption_cipher)); var sessionKey = crypto.generateSessionKey(enums.read(enums.symmetric, config.encryption_cipher));
publicKeys.forEach(function(publicKeyPacketlist) { keys.forEach(function(key) {
var pubKey = new key(); var encryptionKeyPacket = key.getEncryptionKeyPacket();
pubKey.packets = publicKeyPacketlist; if (encryptionKeyPacket) {
var encryptionKey = pubKey.getEncryptionKey();
if (encryptionKey) {
var pkESKeyPacket = new packet.public_key_encrypted_session_key(); var pkESKeyPacket = new packet.public_key_encrypted_session_key();
pkESKeyPacket.publicKeyId = encryptionKey.getKeyId(); pkESKeyPacket.publicKeyId = encryptionKeyPacket.getKeyId();
pkESKeyPacket.publicKeyAlgorithm = encryptionKey.algorithm; pkESKeyPacket.publicKeyAlgorithm = encryptionKeyPacket.algorithm;
pkESKeyPacket.sessionKey = sessionKey; pkESKeyPacket.sessionKey = sessionKey;
//TODO get preferred algo from signature //TODO get preferred algo from signature
pkESKeyPacket.sessionKeyAlgorithm = enums.read(enums.symmetric, config.encryption_cipher); pkESKeyPacket.sessionKeyAlgorithm = enums.read(enums.symmetric, config.encryption_cipher);
pkESKeyPacket.encrypt(encryptionKey); pkESKeyPacket.encrypt(encryptionKeyPacket);
packetList.push(pkESKeyPacket); messagePacketlist.push(pkESKeyPacket);
} }
}); });
var literalDataPacket = new packet.literal();
literalDataPacket.set(message, 'utf8');
var literalDataPacketlist = new packet.list();
literalDataPacketlist.push(literalDataPacket);
var symEncryptedPacket; var symEncryptedPacket;
if (config.integrity_protect) { if (config.integrity_protect) {
symEncryptedPacket = new packet.sym_encrypted_integrity_protected(); symEncryptedPacket = new packet.sym_encrypted_integrity_protected();
} else { } else {
symEncryptedPacket = new packet.symmetrically_encrypted(); symEncryptedPacket = new packet.symmetrically_encrypted();
} }
symEncryptedPacket.packets = literalDataPacket; symEncryptedPacket.packets = literalDataPacketlist;
//TODO get preferred algo from signature //TODO get preferred algo from signature
symEncryptedPacket.encrypt(enums.read(enums.symmetric, config.encryption_cipher), sessionKey); symEncryptedPacket.encrypt(enums.read(enums.symmetric, config.encryption_cipher), sessionKey);
packetList.push(symEncryptedPacket); messagePacketlist.push(symEncryptedPacket);
var armored = armor.encode(enums.armor.message, packetList.write(), config); var armored = armor.encode(enums.armor.message, messagePacketlist.write(), config);
return armored; return armored;
} }
function encryptAndSignMessage(publicKeys, privateKey, message) { function encryptAndSignMessage(publicKeys, privateKey, message) {
} }
function decryptMessage(privateKey, messagePacketlist) { /**
* decrypts message
* @param {secret_subkey|packet_secret_key} privateKeyPacket the private key packet (with decrypted secret part) the message is encrypted with
* @param {message} message the message object with the encrypted data
* @return {String} decrypted message as as native JavaScript string
*/
function decryptMessage(privateKeyPacket, message) {
return message.decrypt(privateKeyPacket);
} }
function decryptAndVerifyMessage(privateKey, publicKeys, messagePacketlist) { function decryptAndVerifyMessage(privateKey, publicKeys, messagePacketlist) {
@ -336,9 +309,8 @@ function _openpgp() {
this.write_signed_message = write_signed_message; this.write_signed_message = write_signed_message;
this.write_signed_and_encrypted_message = write_signed_and_encrypted_message; this.write_signed_and_encrypted_message = write_signed_and_encrypted_message;
this.encryptMessage = encryptMessage; this.encryptMessage = encryptMessage;
this.readArmoredPackets = readArmoredPackets; this.decryptMessage = decryptMessage;
this.readDearmoredPackets = readDearmoredPackets;
this.getKeyFromPacketlist = getKeyFromPacketlist;
} }
module.exports = new _openpgp(); module.exports = new _openpgp();

View File

@ -62,4 +62,38 @@ module.exports = function packetlist() {
this.length++; this.length++;
} }
/**
* Creates a new packetList with all packets that pass the test implemented by the provided function.
*/
this.filter = function(callback) {
var filtered = new packetlist();
for (var i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
filtered.push(this[i]);
}
}
return filtered;
}
/**
* Creates a new packetList with all packets from the given type
*/
this.filterByType = function(packetType) {
return this.filter(function(packet) {
return packet.tag == packetType;
});
}
/**
* Executes the provided callback once for each element
*/
this.forEach = function(callback) {
for (var i = 0; i < this.length; i++) {
callback(this[i]);
}
}
} }

View File

@ -15,6 +15,8 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
var util = require('../util');
/** /**
* @class * @class
* @classdesc Implementation of type key id (RFC4880 3.3) * @classdesc Implementation of type key id (RFC4880 3.3)
@ -24,10 +26,16 @@
formed. formed.
*/ */
module.exports = function keyid() { module.exports = function keyid() {
var bytes = '';
for (var i = 0; i < 8; i++) // initialize keyid with 0x0000000000000000
bytes += String.fromCharCode(0); var strArray = [];
var zero = String.fromCharCode(0);
for (var i = 0; i < 8; i++) {
strArray[i] = zero;
}
this.bytes = strArray.join('');
/** /**
* Parsing method for a key id * Parsing method for a key id
* @param {String} input Input to read the key id from * @param {String} input Input to read the key id from
@ -42,4 +50,12 @@ module.exports = function keyid() {
this.write = function() { this.write = function() {
return this.bytes; return this.bytes;
} }
this.toHex = function() {
return util.hexstrdump(this.bytes);
}
this.equals = function(keyid) {
return this.bytes == keyid.bytes;
}
}; };

View File

@ -140,7 +140,11 @@ var Util = function() {
* @return {String} A native javascript string * @return {String} A native javascript string
*/ */
this.decode_utf8 = function(utf8) { this.decode_utf8 = function(utf8) {
return decodeURIComponent(escape(utf8)); try {
return decodeURIComponent(escape(utf8));
} catch (e) {
return utf8;
}
}; };
var str2bin = function(str, result) { var str2bin = function(str, result) {

View File

@ -7,7 +7,7 @@ unit.register("AES Rijndael cipher test with test vectors from ecb_tbl.txt", fun
var result = new Array(); var result = new Array();
function test_aes(input, key, output) { function test_aes(input, key, output) {
var aes = new openpgp.cipher.aes128(util.bin2str(key)); var aes = new openpgp.crypto.cipher.aes128(util.bin2str(key));
var result = util.bin2str(aes.encrypt(input)); var result = util.bin2str(aes.encrypt(input));

View File

@ -3,11 +3,11 @@ var unit = require('../../unit.js');
unit.register("Blowfish cipher test with test vectors from http://www.schneier.com/code/vectors.txt", function() { unit.register("Blowfish cipher test with test vectors from http://www.schneier.com/code/vectors.txt", function() {
var openpgp = require('../../../'), var openpgp = require('../../../'),
util = openpgp.util, util = openpgp.util,
BFencrypt = openpgp.cipher.blowfish; BFencrypt = openpgp.crypto.cipher.blowfish;
var result = []; var result = [];
function test_bf(input, key, output) { function test_bf(input, key, output) {
var blowfish = new openpgp.cipher.blowfish(util.bin2str(key)); var blowfish = new openpgp.crypto.cipher.blowfish(util.bin2str(key));
var result = util.bin2str(blowfish.encrypt(input)); var result = util.bin2str(blowfish.encrypt(input));
return (util.hexstrdump(result) == util.hexstrdump(util.bin2str(output))); return (util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)));

View File

@ -6,7 +6,7 @@ unit.register("CAST-128 cipher test with test vectors from RFC2144", function()
var result = []; var result = [];
function test_cast(input, key, output) { function test_cast(input, key, output) {
var cast5 = new openpgp.cipher.cast5(util.bin2str(key)); var cast5 = new openpgp.crypto.cipher.cast5(util.bin2str(key));
var result = util.bin2str(cast5.encrypt(input)); var result = util.bin2str(cast5.encrypt(input));
return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output));

View File

@ -1,33 +1,33 @@
var unit = require('../../unit.js'); var unit = require('../../unit.js');
unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf", function() { unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf", function() {
var openpgp = require('../../../'), var openpgp = require('../../../'),
util = openpgp.util; util = openpgp.util;
var result = []; var result = [];
var key = util.bin2str([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]); var key = util.bin2str([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]);
var testvectors = [[[0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00]], var testvectors = [[[0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00]],
[[0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19]], [[0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19]],
[[0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA]], [[0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA]],
[[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F]], [[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F]],
[[0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56]], [[0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56]],
[[0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF]], [[0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF]],
[[0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F]], [[0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F]],
[[0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60]], [[0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60]],
[[0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00],[0xD9,0x03,0x1B,0x02,0x71,0xBD,0x5A,0x0A]], [[0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00],[0xD9,0x03,0x1B,0x02,0x71,0xBD,0x5A,0x0A]],
[[0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00],[0x42,0x42,0x50,0xB3,0x7C,0x3D,0xD9,0x51]], [[0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00],[0x42,0x42,0x50,0xB3,0x7C,0x3D,0xD9,0x51]],
[[0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00],[0xB8,0x06,0x1B,0x7E,0xCD,0x9A,0x21,0xE5]], [[0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00],[0xB8,0x06,0x1B,0x7E,0xCD,0x9A,0x21,0xE5]],
[[0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00],[0xF1,0x5D,0x0F,0x28,0x6B,0x65,0xBD,0x28]], [[0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00],[0xF1,0x5D,0x0F,0x28,0x6B,0x65,0xBD,0x28]],
[[0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00],[0xAD,0xD0,0xCC,0x8D,0x6E,0x5D,0xEB,0xA1]], [[0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00],[0xAD,0xD0,0xCC,0x8D,0x6E,0x5D,0xEB,0xA1]],
[[0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00],[0xE6,0xD5,0xF8,0x27,0x52,0xAD,0x63,0xD1]], [[0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00],[0xE6,0xD5,0xF8,0x27,0x52,0xAD,0x63,0xD1]],
[[0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00],[0xEC,0xBF,0xE3,0xBD,0x3F,0x59,0x1A,0x5E]], [[0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00],[0xEC,0xBF,0xE3,0xBD,0x3F,0x59,0x1A,0x5E]],
[[0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00],[0xF3,0x56,0x83,0x43,0x79,0xD1,0x65,0xCD]], [[0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00],[0xF3,0x56,0x83,0x43,0x79,0xD1,0x65,0xCD]],
[[0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00],[0x2B,0x9F,0x98,0x2F,0x20,0x03,0x7F,0xA9]], [[0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00],[0x2B,0x9F,0x98,0x2F,0x20,0x03,0x7F,0xA9]],
[[0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00],[0x88,0x9D,0xE0,0x68,0xA1,0x6F,0x0B,0xE6]], [[0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00],[0x88,0x9D,0xE0,0x68,0xA1,0x6F,0x0B,0xE6]],
[[0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00],[0xE1,0x9E,0x27,0x5D,0x84,0x6A,0x12,0x98]], [[0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00],[0xE1,0x9E,0x27,0x5D,0x84,0x6A,0x12,0x98]],
[[0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00],[0x32,0x9A,0x8E,0xD5,0x23,0xD7,0x1A,0xEC]], [[0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00],[0x32,0x9A,0x8E,0xD5,0x23,0xD7,0x1A,0xEC]],
[[0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00],[0xE7,0xFC,0xE2,0x25,0x57,0xD2,0x3C,0x97]], [[0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00],[0xE7,0xFC,0xE2,0x25,0x57,0xD2,0x3C,0x97]],
[[0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00],[0x12,0xA9,0xF5,0x81,0x7F,0xF2,0xD6,0x5D]], [[0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00],[0x12,0xA9,0xF5,0x81,0x7F,0xF2,0xD6,0x5D]],
[[0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00],[0xA4,0x84,0xC3,0xAD,0x38,0xDC,0x9C,0x19]], [[0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00],[0xA4,0x84,0xC3,0xAD,0x38,0xDC,0x9C,0x19]],
[[0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00],[0xFB,0xE0,0x0A,0x8A,0x1E,0xF8,0xAD,0x72]], [[0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00],[0xFB,0xE0,0x0A,0x8A,0x1E,0xF8,0xAD,0x72]],
[[0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00],[0x75,0x0D,0x07,0x94,0x07,0x52,0x13,0x63]], [[0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00],[0x75,0x0D,0x07,0x94,0x07,0x52,0x13,0x63]],
@ -70,38 +70,38 @@ unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.ni
[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04],[0xD2,0xFD,0x88,0x67,0xD5,0x0D,0x2D,0xFE]], [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04],[0xD2,0xFD,0x88,0x67,0xD5,0x0D,0x2D,0xFE]],
[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02],[0x06,0xE7,0xEA,0x22,0xCE,0x92,0x70,0x8F]], [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02],[0x06,0xE7,0xEA,0x22,0xCE,0x92,0x70,0x8F]],
[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x16,0x6B,0x40,0xB4,0x4A,0xBA,0x4B,0xD6]]]; [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x16,0x6B,0x40,0xB4,0x4A,0xBA,0x4B,0xD6]]];
var res = true; var res = true;
var j = 0; var j = 0;
for (var i = 0; i < testvectors.length; i++) { for (var i = 0; i < testvectors.length; i++) {
var des = new openpgp.cipher.des(key); var des = new openpgp.crypto.cipher.des(key);
var encr = util.bin2str(des.encrypt(testvectors[i][0], key)); var encr = util.bin2str(des.encrypt(testvectors[i][0], key));
var res2 = encr == util.bin2str(testvectors[i][1]); var res2 = encr == util.bin2str(testvectors[i][1]);
res &= res2; res &= res2;
if (!res2) { if (!res2) {
result[j] = new unit.result("Testing vector with block " + result[j] = new unit.result("Testing vector with block " +
util.hexidump(testvectors[i][0]) + util.hexidump(testvectors[i][0]) +
" and key " + util.hexstrdump(key) + " and key " + util.hexstrdump(key) +
" should be " + util.hexidump(testvectors[i][1]) + " != " + " should be " + util.hexidump(testvectors[i][1]) + " != " +
util.hexidump(encr), util.hexidump(encr),
false); false);
j++; j++;
} }
} }
if (res) { if (res) {
result[j] = new unit.result("All 3DES EDE test vectors completed", true); result[j] = new unit.result("All 3DES EDE test vectors completed", true);
} }
return result; return result;
}); });
unit.register("DES encrypt/decrypt padding tests", function () { unit.register("DES encrypt/decrypt padding tests", function () {
var openpgp = require('../../../'), var openpgp = require('../../../'),
util = openpgp.util; util = openpgp.util;
var result = []; var result = [];
var key = util.bin2str([0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]); var key = util.bin2str([0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF]);
var testvectors = new Array(); var testvectors = new Array();
@ -130,7 +130,7 @@ unit.register("DES encrypt/decrypt padding tests", function () {
[[0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D], [0xCA, 0x59, 0x61, 0x3A, 0x83, 0x23, 0x26, 0xDD]], [[0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D], [0xCA, 0x59, 0x61, 0x3A, 0x83, 0x23, 0x26, 0xDD]],
[[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], [0x83, 0x25, 0x79, 0x06, 0x54, 0xA4, 0x44, 0xD9]]]; [[0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F], [0x83, 0x25, 0x79, 0x06, 0x54, 0xA4, 0x44, 0xD9]]];
var des = new openpgp.cipher.originalDes(key); var des = new openpgp.crypto.cipher.originalDes(key);
var res = true; var res = true;
var j = 0; var j = 0;

View File

@ -5,7 +5,7 @@ unit.register("Twofish test with test vectors from http://www.schneier.com/code/
util = openpgp.util; util = openpgp.util;
function TFencrypt(block, key) { function TFencrypt(block, key) {
var tf = new openpgp.cipher.twofish(key); var tf = new openpgp.crypto.cipher.twofish(key);
return tf.encrypt(block); return tf.encrypt(block);
} }

View File

@ -3,7 +3,7 @@ var unit = require('../../unit.js');
unit.register("MD5 test with test vectors from RFC 1321", function() { unit.register("MD5 test with test vectors from RFC 1321", function() {
var openpgp = require('../../../'), var openpgp = require('../../../'),
util = openpgp.util, util = openpgp.util,
MD5 = openpgp.hash.md5; MD5 = openpgp.crypto.hash.md5;
var result = new Array(); var result = new Array();
result[0] = new unit.result("MD5 (\"\") = d41d8cd98f00b204e9800998ecf8427e", result[0] = new unit.result("MD5 (\"\") = d41d8cd98f00b204e9800998ecf8427e",

View File

@ -4,7 +4,7 @@ unit.register("RIPE-MD 160 bits test with test vectors from http://homes.esat.ku
var openpgp = require('../../../'), var openpgp = require('../../../'),
util = openpgp.util, util = openpgp.util,
RMDstring = openpgp.hash.ripemd; RMDstring = openpgp.crypto.hash.ripemd;
var result = new Array(); var result = new Array();
result[0] = new unit.result("RMDstring (\"\") = 9c1185a5c5e9fc54612808977ee8f548b2258d31", result[0] = new unit.result("RMDstring (\"\") = 9c1185a5c5e9fc54612808977ee8f548b2258d31",

View File

@ -4,7 +4,7 @@ var unit = require('../../unit.js');
unit.register("SHA* test with test vectors from NIST FIPS 180-2", function() { unit.register("SHA* test with test vectors from NIST FIPS 180-2", function() {
var openpgp = require('../../../'), var openpgp = require('../../../'),
util = openpgp.util, util = openpgp.util,
hash = openpgp.hash; hash = openpgp.crypto.hash;
var result = new Array(); var result = new Array();

View File

@ -225,14 +225,14 @@ unit.register("Functional testing of openpgp.crypto.* methods", function() {
//Originally we passed public and secret MPI separately, now they are joined. Is this what we want to do long term? //Originally we passed public and secret MPI separately, now they are joined. Is this what we want to do long term?
// RSA // RSA
var RSAsignedData = openpgp.signature.sign(2, 1, RSApubMPIs.concat(RSAsecMPIs), "foobar"); var RSAsignedData = openpgp.crypto.signature.sign(2, 1, RSApubMPIs.concat(RSAsecMPIs), "foobar");
var RSAsignedDataMPI = new openpgp.mpi(); var RSAsignedDataMPI = new openpgp.mpi();
RSAsignedDataMPI.read(RSAsignedData); RSAsignedDataMPI.read(RSAsignedData);
result[0] = new unit.result("Testing RSA Sign and Verify", result[0] = new unit.result("Testing RSA Sign and Verify",
openpgp.signature.verify(1, 2, [RSAsignedDataMPI], RSApubMPIs, "foobar")); openpgp.crypto.signature.verify(1, 2, [RSAsignedDataMPI], RSApubMPIs, "foobar"));
// DSA // DSA
var DSAsignedData = openpgp.signature.sign(2, 17, DSApubMPIs.concat(DSAsecMPIs), "foobar"); var DSAsignedData = openpgp.crypto.signature.sign(2, 17, DSApubMPIs.concat(DSAsecMPIs), "foobar");
var DSAmsgMPIs = []; var DSAmsgMPIs = [];
DSAmsgMPIs[0] = new openpgp.mpi(); DSAmsgMPIs[0] = new openpgp.mpi();
@ -240,31 +240,31 @@ unit.register("Functional testing of openpgp.crypto.* methods", function() {
DSAmsgMPIs[0].read(DSAsignedData.substring(0,34)); DSAmsgMPIs[0].read(DSAsignedData.substring(0,34));
DSAmsgMPIs[1].read(DSAsignedData.substring(34,68)); DSAmsgMPIs[1].read(DSAsignedData.substring(34,68));
result[1] = new unit.result("Testing DSA Sign and Verify", result[1] = new unit.result("Testing DSA Sign and Verify",
openpgp.signature.verify(17, 2, DSAmsgMPIs, DSApubMPIs, "foobar")); openpgp.crypto.signature.verify(17, 2, DSAmsgMPIs, DSApubMPIs, "foobar"));
var symmAlgo = "aes256"; // AES256 var symmAlgo = "aes256"; // AES256
var symmKey = openpgp.generateSessionKey(symmAlgo); var symmKey = openpgp.crypto.generateSessionKey(symmAlgo);
var symmencDataOCFB = openpgp.cfb.encrypt(openpgp.getPrefixRandom(symmAlgo), symmAlgo, "foobarfoobar1234567890", symmKey, true); var symmencDataOCFB = openpgp.crypto.cfb.encrypt(openpgp.crypto.getPrefixRandom(symmAlgo), symmAlgo, "foobarfoobar1234567890", symmKey, true);
var symmencDataCFB = openpgp.cfb.encrypt(openpgp.getPrefixRandom(symmAlgo), symmAlgo, "foobarfoobar1234567890", symmKey, false); var symmencDataCFB = openpgp.crypto.cfb.encrypt(openpgp.crypto.getPrefixRandom(symmAlgo), symmAlgo, "foobarfoobar1234567890", symmKey, false);
result[2] = new unit.result("Testing symmetric encrypt and decrypt with OpenPGP CFB resync", result[2] = new unit.result("Testing symmetric encrypt and decrypt with OpenPGP CFB resync",
openpgp.cfb.decrypt(symmAlgo,symmKey,symmencDataOCFB,true) == "foobarfoobar1234567890"); openpgp.crypto.cfb.decrypt(symmAlgo,symmKey,symmencDataOCFB,true) == "foobarfoobar1234567890");
result[3] = new unit.result("Testing symmetric encrypt and decrypt without OpenPGP CFB resync (used in modification detection code \"MDC\" packets)", result[3] = new unit.result("Testing symmetric encrypt and decrypt without OpenPGP CFB resync (used in modification detection code \"MDC\" packets)",
openpgp.cfb.decrypt(symmAlgo,symmKey,symmencDataCFB,false) == "foobarfoobar1234567890"); openpgp.crypto.cfb.decrypt(symmAlgo,symmKey,symmencDataCFB,false) == "foobarfoobar1234567890");
var RSAUnencryptedData = new openpgp.mpi(); var RSAUnencryptedData = new openpgp.mpi();
RSAUnencryptedData.fromBytes(openpgp.pkcs1.eme.encode(symmKey, RSApubMPIs[0].byteLength())); RSAUnencryptedData.fromBytes(openpgp.crypto.pkcs1.eme.encode(symmKey, RSApubMPIs[0].byteLength()));
var RSAEncryptedData = openpgp.publicKeyEncrypt("rsa_encrypt_sign", RSApubMPIs, RSAUnencryptedData); var RSAEncryptedData = openpgp.crypto.publicKeyEncrypt("rsa_encrypt_sign", RSApubMPIs, RSAUnencryptedData);
result[4] = new unit.result("Testing asymmetric encrypt and decrypt using RSA with eme_pkcs1 padding", result[4] = new unit.result("Testing asymmetric encrypt and decrypt using RSA with eme_pkcs1 padding",
openpgp.pkcs1.eme.decode(openpgp.publicKeyDecrypt("rsa_encrypt_sign", RSApubMPIs.concat(RSAsecMPIs), RSAEncryptedData).write().substring(2), RSApubMPIs[0].byteLength()) == symmKey); openpgp.crypto.pkcs1.eme.decode(openpgp.crypto.publicKeyDecrypt("rsa_encrypt_sign", RSApubMPIs.concat(RSAsecMPIs), RSAEncryptedData).write().substring(2), RSApubMPIs[0].byteLength()) == symmKey);
var ElgamalUnencryptedData = new openpgp.mpi(); var ElgamalUnencryptedData = new openpgp.mpi();
ElgamalUnencryptedData.fromBytes(openpgp.pkcs1.eme.encode(symmKey, ElgamalpubMPIs[0].byteLength())); ElgamalUnencryptedData.fromBytes(openpgp.crypto.pkcs1.eme.encode(symmKey, ElgamalpubMPIs[0].byteLength()));
var ElgamalEncryptedData = openpgp.publicKeyEncrypt("elgamal", ElgamalpubMPIs, ElgamalUnencryptedData); var ElgamalEncryptedData = openpgp.crypto.publicKeyEncrypt("elgamal", ElgamalpubMPIs, ElgamalUnencryptedData);
result[5] = new unit.result("Testing asymmetric encrypt and decrypt using Elgamal with eme_pkcs1 padding", result[5] = new unit.result("Testing asymmetric encrypt and decrypt using Elgamal with eme_pkcs1 padding",
openpgp.pkcs1.eme.decode(openpgp.publicKeyDecrypt("elgamal", ElgamalpubMPIs.concat(ElgamalsecMPIs), ElgamalEncryptedData).write().substring(2), ElgamalpubMPIs[0].byteLength()) == symmKey); openpgp.crypto.pkcs1.eme.decode(openpgp.crypto.publicKeyDecrypt("elgamal", ElgamalpubMPIs.concat(ElgamalsecMPIs), ElgamalEncryptedData).write().substring(2), ElgamalpubMPIs[0].byteLength()) == symmKey);
return result; return result;
}); });

View File

@ -2,9 +2,9 @@ var unit = require('../unit.js');
unit.register("Testing of binary signature checking", function() { unit.register("Testing of binary signature checking", function() {
var openpgp = require('../../'); var openpgp = require('../../');
var keyring = require('../../src/openpgp.keyring.js'); var keyring = require('../../src/keyring.js');
var result = []; var result = [];
var priv_key = openpgp.readArmoredPackets([ var priv_key = openpgp.key.readArmored([
'-----BEGIN PGP PRIVATE KEY BLOCK-----', '-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -32,8 +32,8 @@ unit.register("Testing of binary signature checking", function() {
'AKC8omYPPomN1E/UJFfXdLDIMi5LoA==', 'AKC8omYPPomN1E/UJFfXdLDIMi5LoA==',
'=LSrW', '=LSrW',
'-----END PGP PRIVATE KEY BLOCK-----' '-----END PGP PRIVATE KEY BLOCK-----'
].join("\n")); ].join("\n")).packets;
var pub_key = openpgp.readArmoredPackets( var pub_key = openpgp.key.readArmored(
[ '-----BEGIN PGP PUBLIC KEY BLOCK-----', [ '-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -51,8 +51,8 @@ unit.register("Testing of binary signature checking", function() {
'EplqEakMckCtikEnpxYe', 'EplqEakMckCtikEnpxYe',
'=b2Ln', '=b2Ln',
'-----END PGP PUBLIC KEY BLOCK-----' '-----END PGP PUBLIC KEY BLOCK-----'
].join("\n")); ].join("\n")).packets;
var msg = openpgp.readArmoredPackets([ var msg = openpgp.message.readArmored([
'-----BEGIN PGP MESSAGE-----', '-----BEGIN PGP MESSAGE-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -68,7 +68,7 @@ unit.register("Testing of binary signature checking", function() {
'aOU=', 'aOU=',
'=4iGt', '=4iGt',
'-----END PGP MESSAGE-----' '-----END PGP MESSAGE-----'
].join("\n")); ].join("\n")).packets;
//TODO need both? //TODO need both?
priv_key[0].decrypt("abcd"); priv_key[0].decrypt("abcd");
priv_key[3].decrypt("abcd"); priv_key[3].decrypt("abcd");
@ -80,7 +80,7 @@ unit.register("Testing of binary signature checking", function() {
// exercises the GnuPG s2k type 1001 extension: // exercises the GnuPG s2k type 1001 extension:
// the secrets on the primary key have been stripped. // the secrets on the primary key have been stripped.
var priv_key_gnupg_ext = openpgp.readArmoredPackets([ var priv_key_gnupg_ext = openpgp.key.readArmored([
'-----BEGIN PGP PRIVATE KEY BLOCK-----', '-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -107,7 +107,7 @@ unit.register("Testing of binary signature checking", function() {
'iY3UT9QkV9d0sMgyLkug', 'iY3UT9QkV9d0sMgyLkug',
'=GQsY', '=GQsY',
'-----END PGP PRIVATE KEY BLOCK-----', '-----END PGP PRIVATE KEY BLOCK-----',
].join("\n")); ].join("\n")).packets;
priv_key_gnupg_ext[3].decrypt("abcd"); priv_key_gnupg_ext[3].decrypt("abcd");
msg[0].decrypt(priv_key_gnupg_ext[3]); msg[0].decrypt(priv_key_gnupg_ext[3]);
msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
@ -149,7 +149,7 @@ unit.register("Testing of binary signature checking", function() {
'-----END PGP PUBLIC KEY BLOCK-----' '-----END PGP PUBLIC KEY BLOCK-----'
].join("\n")); ].join("\n"));
var msg2 = openpgp.readArmoredPackets([ var msg2 = openpgp.message.readArmored([
'-----BEGIN PGP MESSAGE-----', '-----BEGIN PGP MESSAGE-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -158,7 +158,7 @@ unit.register("Testing of binary signature checking", function() {
'AJ9zh4zsK4GIPuEu81YPNmHsju7DYg==', 'AJ9zh4zsK4GIPuEu81YPNmHsju7DYg==',
'=WaSx', '=WaSx',
'-----END PGP MESSAGE-----' '-----END PGP MESSAGE-----'
].join("\n")); ].join("\n")).packets;
var packetlists = keyring.getPacketlistsForKeyId(msg2[0].signingKeyId.write()); var packetlists = keyring.getPacketlistsForKeyId(msg2[0].signingKeyId.write());
var pubKey = packetlists[0]; var pubKey = packetlists[0];
msg2[2].verify(pubKey[3], msg2[1]); msg2[2].verify(pubKey[3], msg2[1]);

View File

@ -1,8 +1,7 @@
var unit = require('../unit.js'); var unit = require('../unit.js');
unit.register("Encryption/decryption", function() { unit.register("Key generation/encryption/decryption", function() {
var openpgp = require('../../'); var openpgp = require('../../');
var keyring = require('../../src/openpgp.keyring.js');
var result = []; var result = [];
var testHelper = function(passphrase, userid, message) { var testHelper = function(passphrase, userid, message) {
var key = openpgp.generateKeyPair(openpgp.enums.publicKey.rsa_encrypt_sign, 512, var key = openpgp.generateKeyPair(openpgp.enums.publicKey.rsa_encrypt_sign, 512,
@ -12,46 +11,31 @@ unit.register("Encryption/decryption", function() {
+ 'userid: ' + userid + '\n' + 'userid: ' + userid + '\n'
+ 'message: ' + message; + 'message: ' + message;
var keyPacketlist = openpgp.readArmoredPackets(key);
debugger; debugger;
var privKey = openpgp.getKeyFromPacketlist(keyPacketlist, passphrase); var privKey = openpgp.key.readArmored(key);
var encrypted = openpgp.encryptMessage(keyPacketlist, message); var encrypted = openpgp.encryptMessage([privKey], message);
openpgp.keyring.importPublicKey(key.publicKeyArmored); var msg = openpgp.message.readArmored(encrypted);
var msg = openpgp.read_message(encrypted);
var keymat = null;
var sesskey = null;
// Find the private (sub)key for the session key of the message // Find the private (sub)key for the session key of the message
for (var i = 0; i< msg[0].sessionKeys.length; i++) { var privKeyPacket = privKey.getKeyPacketByIds(msg.getKeyIds());
if (priv_key.privateKeyPacket.publicKey.getKeyId().write() == msg[0].sessionKeys[i].keyId.bytes) {
keymat = { key: priv_key, keymaterial: priv_key.privateKeyPacket}; if (!privKeyPacket) {
sesskey = msg[0].sessionKeys[i]; return new unit.result("No private key found!" + info, false);
break;
}
for (var j = 0; j < priv_key.subKeys.length; j++) {
if (priv_key.subKeys[j].publicKey.getKeyId().write() == msg[0].sessionKeys[i].keyId.bytes) {
keymat = { key: priv_key, keymaterial: priv_key.subKeys[j]};
sesskey = msg[0].sessionKeys[i];
break;
}
}
} }
var decrypted = ''; try {
if (keymat !== null) { if (!privKeyPacket.decrypt(passphrase)) {
if (!keymat.keymaterial.decryptSecretMPIs(passphrase)) { return new unit.result("Password for secrect key was incorrect!" + info, false);
return new test_result("Password for secrect key was incorrect!",
+ info, false);
} }
} catch (e) {
decrypted = msg[0].decrypt(keymat, sesskey); return new unit.result("Exception on decrypt of private key packet!" + info, false);
} else {
return new test_result("No private key found!" + info, false);
} }
return new test_result(message + ' == ' + decrypted + info, message == decrypted);
var decrypted = msg.decrypt(privKeyPacket)[0];
return new unit.result(message + ' == ' + decrypted + info, message == decrypted);
}; };
result.push(testHelper('password', 'Test McTestington <test@example.com>', 'hello world')); result.push(testHelper('password', 'Test McTestington <test@example.com>', 'hello world'));
@ -60,3 +44,111 @@ unit.register("Encryption/decryption", function() {
return result; return result;
}); });
unit.register("Encryption/decryption", function() {
var openpgp = require('../../');
var result = [];
var pub_key =
['-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v2.0.19 (GNU/Linux)',
'Type: RSA/RSA',
'',
'mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+',
'fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5',
'GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0',
'JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS',
'YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6',
'AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki',
'Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf',
'9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa',
'JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag',
'Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr',
'woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb',
'LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA',
'SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP',
'GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2',
'bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X',
'W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD',
'AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY',
'hz3tYjKhoFTKEIq3y3Pp',
'=h/aX',
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
var priv_key =
['-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG v2.0.19 (GNU/Linux)',
'Type: RSA/RSA',
'Pwd: hello world',
'',
'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',
'=lw5e',
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
var armored =
['-----BEGIN PGP MESSAGE-----',
'Version: OpenPGP.js VERSION',
'Comment: http://openpgpjs.org',
'',
'wYwD4IT3RGwgLJcBA/wN8H9qUvsJwsarDOcsczk1L9Iif47jy+3vF6LcpSgA',
'DfKSARWvatyakvEJmuCNfcpzS8NUPnFA51p0VWmI7FnYG5LkPVUIHb4sN07G',
'9PeqhaayZIeNVvS6DoYuxiTG2sbDmyrv6MMSLivs7VcTAN6L7XXJRI2IumOS',
'x2WFgYNKANJFAQmen4R4IGf9nZDI7NJ4QHUlK1GENgLix9RzMK+Cri6p9Gx5',
'4MDV23jgCBWrUHfFYximgcXiUk0NfpVD3x6chcnKUKJv',
'=Eaix',
'-----END PGP MESSAGE-----'].join('\n');
var plaintext = 'short message';
var key = openpgp.key.readArmored(pub_key);
var encrypted = openpgp.encryptMessage([key], plaintext);
var message = openpgp.message.readArmored(encrypted);
var privKey = openpgp.key.readArmored(priv_key);
var privKeyPacket = privKey.getKeyPacketByIds(message.getKeyIds());
privKeyPacket.decrypt('hello world');
var decrypted = openpgp.decryptMessage(privKeyPacket, message);
result[0] = new unit.result('Encrypt plain text and afterwards decrypt leads to same result', plaintext == decrypted);
return result;
});

File diff suppressed because one or more lines are too long